equate/src/main.c

407 lines
12 KiB
C

#include <Elementary.h>
#ifndef ELM_LIB_QUICKLAUNCH
#include <Ecore_Getopt.h>
#include "Equate.h"
#include "calc.h"
#define EQUATE_WIDTH 170
#define EQUATE_HEIGHT 275
#define EQUATE_TEXT_SCALE 1.6
static Evas_Object *win, *table;
static Evas_Object *readout;
static const struct
{
const char *keyname;
int op;
} _keymap[] = {
{"KP_0", NUM_0},
{"0", NUM_0},
{"KP_1", NUM_1},
{"1", NUM_1},
{"KP_2", NUM_2},
{"2", NUM_2},
{"KP_3", NUM_3},
{"3", NUM_3},
{"KP_4", NUM_4},
{"4", NUM_4},
{"KP_5", NUM_5},
{"5", NUM_5},
{"KP_6", NUM_6},
{"6", NUM_6},
{"KP_7", NUM_7},
{"7", NUM_7},
{"KP_8", NUM_8},
{"8", NUM_8},
{"KP_9", NUM_9},
{"9", NUM_9},
{"KP_Divide", OP_DIV},
{"KP_Multiply", OP_MUT},
{"KP_Subtract", OP_SUB},
{"KP_Add", OP_ADD},
{"plus", OP_ADD},
{"minus", OP_SUB},
{"asterisk", OP_MUT},
{"slash", OP_DIV},
{"KP_Enter", OP_EQU},
{"Return", OP_EQU},
{"equal", OP_EQU},
{"BackSpace", OP_CLR},
{"Escape", OP_CLR},
{"period", OP_DEC},
{"KP_Decimal", OP_DEC},
{"comma", OP_DEC},
{"parenleft", OP_OBRAK},
{"parenright", OP_CBRAK},
NULL
};
#define COPYRIGHT "Copyright © 2004-2016 Andy Williams <andy@andyilliams.me>, \nNicolas Aguirre <aguirre.nicolas@gmail.com> \nand various contributors (see AUTHORS)."
static void
_button_cb(void *data, Evas_Object * o EINA_UNUSED,
void *event_info EINA_UNUSED)
{
int val = 0;
if (data)
{
double result;
char buf[BUFLEN];
val = (int)(uintptr_t)data;
switch (val)
{
case EQ_EXIT:
elm_exit();
break;
case OP_CLR:
equate_clear();
break;
case OP_DIV:
equate_append("/");
break;
case OP_MUT:
equate_append("*");
break;
case OP_ADD:
equate_append("+");
break;
case OP_SUB:
equate_append("-");
break;
case OP_EQU:
snprintf(buf, BUFLEN, "%.10g", equate_eval());
elm_object_text_set(readout, buf);
return;
break;
case OP_DEC:
equate_append(".");
break;
case OP_OBRAK:
equate_append("(");
break;
case OP_CBRAK:
equate_append(")");
break;
case OP_SIN:
equate_append("sin");
break;
case OP_COS:
equate_append("cos");
break;
case OP_TAN:
equate_append("tan");
break;
case OP_ROOT:
equate_append("sqrt");
break;
case OP_POW:
equate_append("^");
break;
case OP_LOG:
equate_append("log");
break;
case OP_LN:
equate_append("ln");
break;
case OP_EXP:
equate_append("exp");
break;
case NUM_0:
equate_append("0");
break;
case NUM_1:
equate_append("1");
break;
case NUM_2:
equate_append("2");
break;
case NUM_3:
equate_append("3");
break;
case NUM_4:
equate_append("4");
break;
case NUM_5:
equate_append("5");
break;
case NUM_6:
equate_append("6");
break;
case NUM_7:
equate_append("7");
break;
case NUM_8:
equate_append("8");
break;
case NUM_9:
equate_append("9");
break;
default:
E(1, "Unknown edje signal operator %d", val);
break;
/* etc */
}
elm_object_text_set(readout, equate_string_get());
}
}
static void
_create_button(Evas_Object *table, const char *text, int op, int x, int y,
int w)
{
Evas_Object *button;
button = elm_button_add(table);
evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(button, text);
evas_object_smart_callback_add(button, "clicked", _button_cb, (void *)(uintptr_t)op);
elm_table_pack(table, button, x, y, w, 2);
evas_object_show(button);
}
static void
_create_buttons(Evas_Object *o)
{
/** Equate Operations **/
/* OP_CLR - Clear Display */
_create_button(o, "C", OP_CLR, 3, 5, 1);
/* OP_DIV - Division Operator */
_create_button(o, "/", OP_DIV, 3, 3, 1);
/* OP_MUT - Mutplication Operator */
_create_button(o, "*", OP_MUT, 2, 3, 1);
/* OP_ADD - Addition Operator */
_create_button(o, "+", OP_ADD, 0, 3, 1);
/* OP_SUB - Subtraction Operator */
_create_button(o, "-", OP_SUB, 1, 3, 1);
/* OP_EQU - Equals Operator */
_create_button(o, "=", OP_EQU, 2, 11, 2);
/* OP_DEC - Decimal Operator */
_create_button(o, ".", OP_DEC, 1, 11, 1);
/* OP_SIN - Sin of x in degrees */
// edje_object_signal_callback_add(o, "OP_SIN", "*", _signal_cb,
// (void *) OP_SIN);
/* OP_COS - Cos of x in degree */
// edje_object_signal_callback_add(o, "OP_COS", "*", _signal_cb,
// (void *) OP_COS);
/* OP_TAN - Tan of x in degrees */
// edje_object_signal_callback_add(o, "OP_TAN", "*", _signal_cb,
// (void *) OP_TAN);
/* OP_ROOT - The square root of x */
// edje_object_signal_callback_add(o, "OP_ROOT", "*", _signal_cb,
// (void *) OP_ROOT);
/* OP_POW - Raise x to the y power */
// edje_object_signal_callback_add(o, "OP_POW", "*", _signal_cb,
// (void *) OP_POW);
/* OP_LOG - Logarithm */
// edje_object_signal_callback_add(o, "OP_LOG", "*", _signal_cb,
// (void *) OP_LOG);
/* OP_LN - the natural logarithm */
// edje_object_signal_callback_add(o, "OP_LN", "*", _signal_cb, (void *) OP_LN);
/* OP_EXP - e to the x */
// edje_object_signal_callback_add(o, "OP_EXP", "*", _signal_cb,
// (void *) OP_EXP);
/* OP_OBRAK - open bracket */
_create_button(o, "(", OP_OBRAK, 3, 7, 1);
/* OP_CBRAK - close bracket */
_create_button(o, ")", OP_CBRAK, 3, 9, 1);
/** Equate Numbers **/
_create_button(o, "7", NUM_7, 0, 5, 1);
_create_button(o, "8", NUM_8, 1, 5, 1);
_create_button(o, "9", NUM_9, 2, 5, 1);
_create_button(o, "4", NUM_4, 0, 7, 1);
_create_button(o, "5", NUM_5, 1, 7, 1);
_create_button(o, "6", NUM_6, 2, 7, 1);
_create_button(o, "1", NUM_1, 0, 9, 1);
_create_button(o, "2", NUM_2, 1, 9, 1);
_create_button(o, "3", NUM_3, 2, 9, 1);
_create_button(o, "0", NUM_0, 0, 11, 1);
/* NUM_PI - 3.14159 */
// edje_object_signal_callback_add(o, "NUM_PI", "*", _signal_cb, (void *) NUM_PI);
}
static Eina_Bool
_key_down_cb(void *data, int type, void *event)
{
Ecore_Event_Key *ev = event;
int i;
for (i = 0; _keymap[i].keyname; i++)
{
if (!strcmp(_keymap[i].keyname, ev->key))
{
_button_cb((void*)(uintptr_t)_keymap[i].op, NULL, NULL);
}
}
return EINA_TRUE;
}
static void
_resize_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Coord w, h;
double relative_scale;
evas_object_geometry_get(win, NULL, NULL, &w, &h);
relative_scale = ((double) h / EQUATE_HEIGHT);
elm_object_scale_set(table, EQUATE_TEXT_SCALE * relative_scale);
evas_object_resize(table, w, h);
}
static void
_create_gui(void)
{
Evas_Object *scroller, *bg;
win = elm_win_add(NULL, "equate", ELM_WIN_BASIC);
elm_win_title_set(win, "Equate");
elm_win_autodel_set(win, EINA_TRUE);
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
bg = elm_bg_add(win);
evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_win_resize_object_add(win, bg);
evas_object_show(bg);
table = elm_table_add(win);
elm_table_homogeneous_set(table, EINA_TRUE);
evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_move(table, 0, 0);
evas_object_resize(table, EQUATE_WIDTH * elm_config_scale_get(),
EQUATE_HEIGHT * elm_config_scale_get());
evas_object_show(table);
ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_down_cb, NULL);
elm_object_scale_set(table, EQUATE_TEXT_SCALE);
evas_object_show(win);
evas_object_resize(win, EQUATE_WIDTH * elm_config_scale_get(),
EQUATE_HEIGHT * elm_config_scale_get());
evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _resize_cb, NULL);
readout = elm_label_add(table);
elm_object_scale_set(readout, 2 * EQUATE_TEXT_SCALE);
evas_object_size_hint_weight_set(readout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(readout, 1.0, EVAS_HINT_FILL);
evas_object_show(readout);
scroller = elm_scroller_add(table);
elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
elm_scroller_gravity_set(scroller, 1.0, 1.0);
elm_object_scale_set(scroller, 1.0);
evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_content_set(scroller, readout);
elm_table_pack(table, scroller, 0, 0, 4, 3);
evas_object_show(scroller);
_create_buttons(table);
}
static const Ecore_Getopt optdesc = {
"equate",
"%prog [options]",
PACKAGE_VERSION,
COPYRIGHT,
"TODO check license",
"A calculator written with Enlightenment Foundation Libraries",
EINA_TRUE,
{
ECORE_GETOPT_STORE_DEF_STR('e', "eval", "Evaluate expression and print result",
NULL),
// ECORE_GETOPT_LICENSE('L', "license"),
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
ECORE_GETOPT_VERSION('V', "version"),
ECORE_GETOPT_HELP('h', "help"),
ECORE_GETOPT_SENTINEL
}
};
EAPI_MAIN int
elm_main(int argc, char **argv)
{
int args;
Eina_Bool quit_option = EINA_FALSE;
char *eval_option = NULL;
Ecore_Getopt_Value values[] = {
ECORE_GETOPT_VALUE_STR(eval_option),
// ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_NONE
};
args = ecore_getopt_parse(&optdesc, values, argc, argv);
if (args < 0)
{
EINA_LOG_CRIT("Could not parse arguments.");
return 1;
}
else if (eval_option)
{
double result;
equate_append(eval_option);
result = equate_eval();
if (equate_ok())
printf("%.10g\n", result);
return !equate_ok();
}
else if (quit_option)
{
return 0;
}
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
elm_app_compile_bin_dir_set(PACKAGE_BIN_DIR);
elm_app_compile_data_dir_set(PACKAGE_DATA_DIR);
elm_app_info_set(elm_main, "equate", "images/equate.png");
math_init();
_create_gui();
elm_run();
elm_shutdown();
return 0;
}
#endif
ELM_MAIN()