2019-10-23 04:39:47 -07:00
|
|
|
|
#define EFL_BETA_API_SUPPORT 1
|
|
|
|
|
|
|
|
|
|
#include <Elementary.h>
|
|
|
|
|
#include <Efl_Ui.h>
|
|
|
|
|
// Temporary workaround until Unified Text stops using Legacy classes internally
|
|
|
|
|
#include <efl_ui_text.eo.h>
|
|
|
|
|
#include <efl_text_interactive.eo.h>
|
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
static Efl_Ui_Text *_screen = NULL; // Text widget showing current value
|
|
|
|
|
static int _prev_value = 0; // Value introduced before an operation (first operand
|
|
|
|
|
static int _curr_value = 0; // Value currently being introduced (second operand)
|
|
|
|
|
static char _operation = '='; // Last operation button pressed
|
|
|
|
|
static Eina_Bool _must_overwrite = EINA_FALSE; // Whether next number must be appended to current input
|
|
|
|
|
// or overwrite it
|
2019-10-23 04:39:47 -07:00
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// Quits the application
|
2019-10-23 04:39:47 -07:00
|
|
|
|
static void
|
|
|
|
|
_gui_quit_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
efl_exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// Performs "operation" on "currValue" and "prevValue" and leaves result in "currValue"
|
2019-10-23 04:39:47 -07:00
|
|
|
|
static void
|
|
|
|
|
_operate()
|
|
|
|
|
{
|
|
|
|
|
switch (_operation)
|
|
|
|
|
{
|
|
|
|
|
case '+':
|
|
|
|
|
_curr_value += _prev_value;
|
|
|
|
|
break;
|
|
|
|
|
case '-':
|
|
|
|
|
_curr_value = _prev_value - _curr_value;
|
|
|
|
|
break;
|
|
|
|
|
case '*':
|
|
|
|
|
_curr_value *= _prev_value;
|
|
|
|
|
break;
|
|
|
|
|
case '/':
|
|
|
|
|
_curr_value = _prev_value / _curr_value;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// Called every time a button is pressed
|
2019-10-23 04:39:47 -07:00
|
|
|
|
static void
|
|
|
|
|
_button_pressed_cb(void *data, const Efl_Event *event EINA_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
char button = ((const char *)data)[0];
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// If it is a number, append it to current input (or replace it)
|
2019-10-23 04:39:47 -07:00
|
|
|
|
if (button >= '0' && button <= '9')
|
|
|
|
|
{
|
|
|
|
|
char str[2] = { button, '\0' };
|
|
|
|
|
if (_must_overwrite)
|
|
|
|
|
{
|
|
|
|
|
efl_text_set(_screen, "");
|
|
|
|
|
_must_overwrite = EINA_FALSE;
|
|
|
|
|
}
|
|
|
|
|
Efl_Text_Cursor_Cursor *cursor = efl_text_cursor_get(_screen, EFL_TEXT_CURSOR_GET_TYPE_MAIN);
|
|
|
|
|
efl_text_cursor_text_insert(_screen, cursor, str);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
char str[32] = "";
|
|
|
|
|
switch (button)
|
|
|
|
|
{
|
|
|
|
|
case 'C':
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// Clear current input
|
2019-10-23 04:39:47 -07:00
|
|
|
|
efl_text_set(_screen, "0");
|
|
|
|
|
break;
|
|
|
|
|
case '+':
|
|
|
|
|
case '-':
|
|
|
|
|
case '*':
|
|
|
|
|
case '/':
|
|
|
|
|
case '=':
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// If there was a pending operation, perform it
|
2019-10-23 04:39:47 -07:00
|
|
|
|
if (_operation != '=')
|
|
|
|
|
{
|
|
|
|
|
_operate();
|
|
|
|
|
snprintf(str, sizeof(str), "%d", _curr_value);
|
|
|
|
|
efl_text_set(_screen, str);
|
|
|
|
|
}
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// Store this operation
|
2019-10-23 04:39:47 -07:00
|
|
|
|
_operation = button;
|
|
|
|
|
_must_overwrite = EINA_TRUE;
|
|
|
|
|
_prev_value = _curr_value;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// Called every time the content of the screen changes
|
|
|
|
|
// We use it to sanitize input (remove heading zeros, for example)
|
|
|
|
|
// This makes more sense when the Text widget is editable, since the user
|
|
|
|
|
// is free to type anything.
|
2019-10-23 04:39:47 -07:00
|
|
|
|
static void
|
|
|
|
|
_screen_changed_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
char _text[32] = "";
|
|
|
|
|
const char *str = efl_text_get(_screen);
|
|
|
|
|
int d;
|
|
|
|
|
if ((strcmp(str, "") == 0) || (strcmp(str, "-") == 0))
|
|
|
|
|
{
|
|
|
|
|
snprintf(_text, sizeof(_text), "0");
|
|
|
|
|
}
|
|
|
|
|
else if (sscanf(str, "%d", &d) == 1)
|
|
|
|
|
{
|
|
|
|
|
snprintf(_text, sizeof(_text), "%d", d);
|
|
|
|
|
_curr_value = d;
|
|
|
|
|
}
|
|
|
|
|
if (strncmp(_text, str, sizeof(_text)))
|
|
|
|
|
{
|
|
|
|
|
efl_text_set(_screen, _text);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// Creates an Efl.Ui.Button and positions it in the given position inside the table
|
|
|
|
|
// The button text is colored with "r, g, b"
|
|
|
|
|
// "text" is what is drawn on the button, which might be a multi-byte unicode string.
|
|
|
|
|
// "command" is a single-char id for the button.
|
2019-10-23 04:39:47 -07:00
|
|
|
|
static void
|
|
|
|
|
_button_add(Efl_Ui_Table *table, const char *text, const char *command, int posx, int posy, int r, int g, int b)
|
|
|
|
|
{
|
|
|
|
|
Efl_Ui_Button *button =
|
|
|
|
|
efl_add(EFL_UI_BUTTON_CLASS, table,
|
|
|
|
|
efl_pack_table(table, efl_added, posx, posy, 1, 1),
|
|
|
|
|
efl_event_callback_add(efl_added, EFL_INPUT_EVENT_CLICKED, _button_pressed_cb, command));
|
|
|
|
|
// Buttons can only have simple text (no font, styles or markup) but can swallow
|
|
|
|
|
// any other object we want.
|
|
|
|
|
// Therefore we create a more complex Efl_Ui_Text object and use it as content for the button.
|
|
|
|
|
Efl_Ui_Text *label =
|
|
|
|
|
efl_add(EFL_UI_TEXT_CLASS, button,
|
|
|
|
|
efl_text_interactive_editable_set(efl_added, EINA_FALSE),
|
|
|
|
|
efl_text_halign_set(efl_added, 0.5),
|
|
|
|
|
efl_text_valign_set(efl_added, 0.5),
|
|
|
|
|
efl_gfx_color_set(efl_added, r, g, b, 255),
|
|
|
|
|
efl_text_set(efl_added, text));
|
|
|
|
|
efl_text_font_set(label, "Sans", 36);
|
|
|
|
|
efl_content_set(button, label);
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// Creates the UI
|
2019-10-23 04:39:47 -07:00
|
|
|
|
static void
|
|
|
|
|
_gui_setup()
|
|
|
|
|
{
|
|
|
|
|
Eo *win, *table;
|
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// The window
|
2019-10-23 04:39:47 -07:00
|
|
|
|
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
|
|
|
|
|
efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
|
|
|
|
|
efl_text_set(efl_added, "EFL Calculator"),
|
|
|
|
|
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
|
|
|
|
|
|
|
|
|
|
// when the user clicks "close" on a window there is a request to delete
|
|
|
|
|
efl_event_callback_add(win, EFL_UI_WIN_EVENT_DELETE_REQUEST, _gui_quit_cb, NULL);
|
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// The table is the main layout
|
2019-10-23 04:39:47 -07:00
|
|
|
|
table = efl_add(EFL_UI_TABLE_CLASS, win,
|
|
|
|
|
efl_content_set(win, efl_added),
|
|
|
|
|
efl_pack_table_size_set(efl_added, 4, 5),
|
|
|
|
|
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(300, 400)));
|
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// Create all buttons using the _button_add helper
|
2019-10-23 04:39:47 -07:00
|
|
|
|
_button_add(table, "1", "1", 0, 3, 255, 255, 255);
|
|
|
|
|
_button_add(table, "2", "2", 1, 3, 255, 255, 255);
|
|
|
|
|
_button_add(table, "3", "3", 2, 3, 255, 255, 255);
|
|
|
|
|
_button_add(table, "4", "4", 0, 2, 255, 255, 255);
|
|
|
|
|
_button_add(table, "5", "5", 1, 2, 255, 255, 255);
|
|
|
|
|
_button_add(table, "6", "6", 2, 2, 255, 255, 255);
|
|
|
|
|
_button_add(table, "7", "7", 0, 1, 255, 255, 255);
|
|
|
|
|
_button_add(table, "8", "8", 1, 1, 255, 255, 255);
|
|
|
|
|
_button_add(table, "9", "9", 2, 1, 255, 255, 255);
|
|
|
|
|
_button_add(table, "0", "0", 1, 4, 255, 255, 255);
|
|
|
|
|
_button_add(table, "+", "+", 3, 1, 128, 128, 128);
|
|
|
|
|
_button_add(table, "−", "-", 3, 2, 128, 128, 128);
|
|
|
|
|
_button_add(table, "×", "*", 3, 3, 128, 128, 128);
|
|
|
|
|
_button_add(table, "÷", "/", 3, 4, 128, 128, 128);
|
|
|
|
|
_button_add(table, "=", "=", 2, 4, 128, 128, 128);
|
|
|
|
|
_button_add(table, "C", "C", 0, 4, 0, 0, 0);
|
|
|
|
|
|
2019-10-24 03:44:25 -07:00
|
|
|
|
// Create a big Efl.Ui.Text screen to display the current input
|
2019-10-23 04:39:47 -07:00
|
|
|
|
_screen = efl_add(EFL_UI_TEXT_CLASS, table,
|
|
|
|
|
efl_text_set(efl_added, "0"),
|
|
|
|
|
efl_text_multiline_set(efl_added, EINA_FALSE),
|
|
|
|
|
efl_text_interactive_editable_set(efl_added, EINA_FALSE),
|
|
|
|
|
efl_text_interactive_selection_allowed_set(efl_added, EINA_FALSE),
|
|
|
|
|
efl_pack_table(table, efl_added, 0, 0, 4, 1),
|
|
|
|
|
efl_text_halign_set(efl_added, 0.9),
|
|
|
|
|
efl_text_valign_set(efl_added, 0.5),
|
|
|
|
|
efl_text_effect_type_set(efl_added, EFL_TEXT_STYLE_EFFECT_TYPE_GLOW),
|
|
|
|
|
efl_text_glow_color_set(efl_added, 128, 128, 128, 128),
|
|
|
|
|
efl_event_callback_add(efl_added, EFL_UI_TEXT_EVENT_CHANGED,
|
|
|
|
|
_screen_changed_cb, NULL));
|
|
|
|
|
efl_text_font_set(_screen, "Sans", 48);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EAPI_MAIN void
|
|
|
|
|
efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
_gui_setup();
|
|
|
|
|
}
|
|
|
|
|
EFL_MAIN()
|
|
|
|
|
|