yakov pushed a commit to branch master. http://git.enlightenment.org/tools/erigo.git/commit/?id=c0e9fe63d6130400f50d0d8e946d554e45a37b64
commit c0e9fe63d6130400f50d0d8e946d554e45a37b64 Author: Yakov Goldberg <yako...@samsung.com> Date: Sun Jan 24 13:30:21 2016 +0200 Add Simple view support to Property View Now Property view has two represenation modes: Expert and Simlple. Expert shows all widget properties grouped by class in inheritace sequence. Simple mode shows only pre-definded commonly used properties grouped by categories. Set of properties and its handlers in Simple view can be modified in config file. --- data/config/CMakeLists.txt | 1 + data/config/simple_op_db.txt | 367 ++++++++++++++++++++ src/bin/gui/CMakeLists.txt | 1 + src/bin/gui/editor.c | 57 +++ src/bin/gui/egui_layout.json | 784 +++++++++++++++++++++++------------------- src/bin/gui/egui_logic.c | 13 +- src/bin/gui/prop_layout.c | 38 +- src/bin/gui/props_helper.c | 12 + src/bin/gui/props_helper.h | 6 + src/bin/gui/propview.c | 37 +- src/bin/gui/propview.h | 2 +- src/bin/gui/simple_propview.c | 600 ++++++++++++++++++++++++++++++++ src/bin/gui/simple_propview.h | 14 + src/lib/CMakeLists.txt | 1 + src/lib/database.c | 250 ++++++++++++++ src/lib/database.h | 78 +++++ src/lib/desc_simple_parser.c | 757 ++++++++++++++++++++++++++++++++++++++++ src/lib/desc_simple_parser.h | 28 ++ src/lib/gui_widget.c | 11 + src/lib/gui_widget.h | 3 + src/lib/test_simple_op.txt | 7 + 21 files changed, 2665 insertions(+), 402 deletions(-) diff --git a/data/config/CMakeLists.txt b/data/config/CMakeLists.txt index 4696272..720b5f1 100644 --- a/data/config/CMakeLists.txt +++ b/data/config/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8.1) LIST(APPEND CONFIG_FILES func_names.json black_list.json + simple_op_db.txt egui_all.eo ) #always copy config files into build directory, so egui_cmd will be able to generate egui_auto diff --git a/data/config/simple_op_db.txt b/data/config/simple_op_db.txt new file mode 100644 index 0000000..9a3d33d --- /dev/null +++ b/data/config/simple_op_db.txt @@ -0,0 +1,367 @@ +UI_Component_Specification.Visible { + Elm.Widget.visible; +} + +UI_Component_Specification.Disabled { + none Elm.Box, Elm.Image, Elm.Icon, Elm.Bg; + Elm.Widget.disabled; +} + +Component_Specific_Properties.Autodel { + Elm.Win.autodel; +} + +Component_Specific_Properties.Title { + Elm.Win.title; +} + +Component_Specific_Properties.Type { + Elm.Win.type; +} + +Component_Specific_Properties.Maximized { + Elm.Win.maximized; +} + +UI_Component_Specification.Text { + Elm.Widget.part_text(NULL, %1) for Elm.Button, Elm.Check, Elm.Label, Elm.Entry, Elm.Frame, Elm.Bubble, Elm.Fileselector_Entry, Elm.Fileselector_Button, Elm.Hoversel; + none Elm.Box, Elm.Table, Elm.Image, Elm.Icon, Elm.Toolbar, Elm.Slider, Elm.Win, Elm.Panes, Elm.Progressbar, Elm.Bg, Elm.Calendar, Elm.Clock, Elm.Fileselector, Elm.Separator, Elm.Colorselector, Elm.Dayselector, Elm.Actionslider, Elm.Naviframe; + Elm.Widget.part_text; +} + +UI_Component_Specification.Style { + none Elm.Toolbar, Elm.Table, Elm.Entry, Elm.Bg, Elm.Win, Elm.Panes, Elm.Image, Elm.Icon, Elm.Frame, Elm.Calendar, Elm.Clock, Elm.Bubble, Elm.Fileselector, Elm.Fileselector_Entry, Elm.Fileselector_Button, Elm.Hoversel, Elm.Separator, Elm.Colorselector, Elm.Dayselector, Elm.Actionslider, Elm.Naviframe; + Elm.Widget.style; +} + +Component_Specific_Properties.Autorepeat { + none Elm.Fileselector_Button, Elm.Hoversel; + Elm.Button.autorepeat; +} + +Component_Specific_Properties.Autorepeat_Initial_Timeout { + none Elm.Fileselector_Button, Elm.Hoversel; + Elm.Button.autorepeat_initial_timeout; +} + +Component_Specific_Properties.Autorepeat_Gap_Timeout { + none Elm.Fileselector_Button, Elm.Hoversel; + Elm.Button.autorepeat_gap_timeout; +} + +Component_Specific_Properties.UI_Component_Specification.Horizontal { + Elm.Box.horizontal; + Elm.Toolbar.horizontal; + Elm.Slider.horizontal; + Elm.Panes.horizontal; + Elm.Progressbar.horizontal; + Elm.Hoversel.horizontal; + Elm.Separator.horizontal; +} + +Component_Specific_Properties.Hover_Parent { + Elm.Hoversel.hover_parent; +} + +Component_Specific_Properties.Auto_Update { + Elm.Hoversel.auto_update; +} + +Component_Specific_Properties.Fixed { + Elm.Panes.fixed; +} + +Component_Specific_Properties.Right_Size { + Elm.Panes.content_right_size; +} + +Component_Specific_Properties.Homogeneous { + Elm.Box.homogeneous; + Elm.Table.homogeneous; + Elm.Toolbar.homogeneous; +} + +Component_Specific_Properties.Padding { + Elm.Box.padding; + Elm.Table.padding; +} + +Component_Specific_Properties.Image_Path { + Efl.File.file(%0, NULL) for Elm.Image, Elm.Icon, Elm.Entry, Elm.Bg; +} +Component_Specific_Properties.No_Scale { + none Elm.Icon; + Elm.Image.no_scale; +} + +Component_Specific_Properties.Resizable { + none Elm.Icon; + Elm.Image.resizable; +} + +Component_Specific_Properties.Orientation { + none Elm.Icon; + Efl.Image.orientation; +} + +Component_Specific_Properties.Aspect_Fixed { + none Elm.Icon; + Elm.Image.aspect_fixed; +} + +Component_Specific_Properties.Fill_Inside { + none Elm.Icon; + Elm.Image.fill_inside; +} + +Component_Specific_Properties.Standard { + Elm.Icon.standard; +} + +Component_Specific_Properties.Order_Lookup { + Elm.Icon.order_lookup; +} + +Component_Specific_Properties.Shrink_Mode { + Elm.Toolbar.shrink_mode; +} + +Component_Specific_Properties.Select_Mode { + Elm.Toolbar.select_mode; +} + +Component_Specific_Properties.Icon_Size { + Elm.Toolbar.icon_size; +} + +Component_Specific_Properties.Icon_Order_Lookup { + Elm.Toolbar.icon_order_lookup; +} + +Component_Specific_Properties.Single_Line { + Elm.Entry.single_line; +} + +Component_Specific_Properties.Password { + Elm.Entry.password; +} + +Component_Specific_Properties.Editable { + Elm.Entry.editable; +} + +Component_Specific_Properties.Context_Menu_Disabled { + Elm.Entry.context_menu_disabled; +} + +Component_Specific_Properties.Scrollable { + Elm.Entry.scrollable; +} + +Component_Specific_Properties.Tect_Format { + Elm.Entry.file_text_format; +} + +Component_Specific_Properties.Wrap_Type { + Elm.Label.line_wrap; +} + +Component_Specific_Properties.Wrap_Width { + Elm.Label.wrap_width; +} + +Component_Specific_Properties.Ellipsis { + Elm.Label.ellipsis; +} + +Component_Specific_Properties.Option { + Elm.Bg.option; +} + +Component_Specific_Properties.Load_Size { + Elm.Bg.load_size; +} + +Component_Specific_Properties.Indicator_Format { + Elm.Slider.indicator_format; +} + +Component_Specific_Properties.Min_Max { + Elm.Slider.min_max; +} + +Component_Specific_Properties.Value { + Elm.Slider.value; + Elm.Progressbar.value; +} + +Component_Specific_Properties.Step { + Elm.Slider.step; +} + +Component_Specific_Properties.Show_Indicator { + Elm.Slider.indicator_show; +} + +Component_Specific_Properties.Span_Size { + Elm.Progressbar.span_size; +} + +Component_Specific_Properties.Inverted { + Elm.Progressbar.inverted; +} + +Component_Specific_Properties.Collapse { + Elm.Frame.collapse; +} + +Component_Specific_Properties.Autocollapse { + Elm.Frame.autocollapse; +} + +Component_Specific_Properties.First_Day_Of_Week { + Elm.Calendar.first_day_of_week; +} + +Component_Specific_Properties.Selectable { + Elm.Calendar.selectable; +} + +Component_Specific_Properties.Interval { + Elm.Calendar.interval; +} + +Component_Specific_Properties.Select_Mode { + Elm.Calendar.select_mode; +} + +Component_Specific_Properties.Min_Max_Year { + Elm.Calendar.min_max_year; +} + +Component_Specific_Properties.Show_Am_Pm { + Elm.Clock.show_am_pm; +} + +Component_Specific_Properties.First_Interval { + Elm.Clock.first_interval; +} + +Component_Specific_Properties.Show_Seconds { + Elm.Clock.show_seconds; +} + +Component_Specific_Properties.Edit { + Elm.Clock.edit; +} + +Component_Specific_Properties.Pause { + Elm.Clock.pause; +} + +Component_Specific_Properties.Time { + Elm.Clock.time; +} + +Component_Specific_Properties.Edit_Mode { + Elm.Clock.edit_mode; +} + +Component_Specific_Properties.Pos { + Elm.Bubble.pos; +} + +Component_Specific_Properties.Event_Enabled { + Elm.Naviframe.event_enabled; +} + +Component_Specific_Properties.Preserve_On_Pop { + Elm.Naviframe.content_preserve_on_pop; +} + +Component_Specific_Properties.Prev_Btn_Auto_Pushed { + Elm.Naviframe.prev_btn_auto_pushed; +} + +Component_Specific_Properties.Buttons_Ok_Cancel { + Elm.Fileselector.buttons_ok_cancel; +} + +Component_Specific_Properties.Inwin_Mode { + Elm.Fileselector_Button.inwin_mode; + Elm.Fileselector_Entry.inwin_mode; +} + +Component_Specific_Properties.Window_Size { + Elm.Fileselector_Button.window_size; + Elm.Fileselector_Entry.window_size; +} + +Component_Specific_Properties.Window_Title { + Elm.Fileselector_Button.window_title; + Elm.Fileselector_Entry.window_title; +} + +Component_Specific_Properties.Folder_Only { + Elm.Interface_Fileselector.folder_only; +} + +Component_Specific_Properties.Hidden_Visible { + Elm.Interface_Fileselector.hidden_visible; +} + +Component_Specific_Properties.Sort_Method { + Elm.Interface_Fileselector.sort_method; +} +Component_Specific_Properties.Multi_Select { + Elm.Interface_Fileselector.multi_select; +} +Component_Specific_Properties.Expandable { + Elm.Interface_Fileselector.expandable; +} +Component_Specific_Properties.Mode { + Elm.Interface_Fileselector.mode; + Elm.Colorselector.mode; +} +Component_Specific_Properties.Is_Save { + Elm.Interface_Fileselector.is_save; +} +Component_Specific_Properties.Color_Value { + Elm.Colorselector.color; +} +Component_Specific_Properties.Palette_Name { + Elm.Colorselector.palette_name; +} + +Component_Specific_Properties.Week_Start { + Elm.Dayselector.week_start; +} + +Component_Specific_Properties.Weekend_Start { + Elm.Dayselector.weekend_start; +} + +Component_Specific_Properties.Indicator_Pos { + Elm.Actionslider.indicator_pos; +} + +Component_Specific_Properties.Magnet_Pos { + Elm.Actionslider.magnet_pos; +} +Component_Specific_Properties.Enabled_Pos { + Elm.Actionslider.enabled_pos; +} + +Alingment.Weight_Hint { + Evas.Object.size_hint_weight; +} + +Alingment.Align_Hint as Slider(0.0, 1.0, 0.1) { + Evas.Object.size_hint_align; +} + +UI_Component_Specification.Color as Color { + Elm.Bg.color; + none Elm.Box, Elm.Table, Elm.Win, Elm.Panes, Elm.Icon, Elm.Image, Elm.Separator; + Efl.Gfx.Base.color; +} diff --git a/src/bin/gui/CMakeLists.txt b/src/bin/gui/CMakeLists.txt index 8b17ca7..6a0b530 100644 --- a/src/bin/gui/CMakeLists.txt +++ b/src/bin/gui/CMakeLists.txt @@ -59,6 +59,7 @@ add_executable(${TARGET} props_helper.c objtree.c propview.c + simple_propview.c cbview.c descview.c contentview.c diff --git a/src/bin/gui/editor.c b/src/bin/gui/editor.c index 7379ca7..0ee48c6 100644 --- a/src/bin/gui/editor.c +++ b/src/bin/gui/editor.c @@ -11,6 +11,7 @@ #include "contentview.h" #include "itemview.h" #include "propview.h" +#include "simple_propview.h" #include "cbview.h" #include "key_bindings.h" #include "settings.h" @@ -3455,6 +3456,10 @@ _prop_update_from_propview_int(void *data EINA_UNUSED, Eo *obj, const Eo_Event_D /* Get data for changed field. */ pfd = eo_key_data_get(obj, _STR_EDITOR); op = pfd->it_data->op_desc; + /* For Simple_Prop_View */ + if (!op) + op = original_op_desc_get(pfd->it_data->orig_op_desc); + wdg = pfd->it_data->wdg; prop = (Gui_Widget_Property *)pfd->it_data->prop; idx = pfd->par_idx; @@ -3518,6 +3523,19 @@ _prop_update_from_propview_int(void *data EINA_UNUSED, Eo *obj, const Eo_Event_D state = elm_obj_check_state_get(obj); gui_value_bool_set(val, state); } + if (kl == ELM_SLIDER_CLASS) + { + double num = elm_obj_slider_value_get(obj); + Param_Default_Value *def_val = NULL; + def_val = eo_key_data_get(obj, _DEFAULT_VALUE); + if (def_val) + { + num = atof(param_default_value_get(def_val)); + gui_value_double_set(val, num); + eo_key_data_del(obj, _DEFAULT_VALUE); + } + gui_value_double_set(val, num); + } if (kl == ELM_HOVERSEL_CLASS) { const char *new_enum_value = NULL; @@ -3663,6 +3681,44 @@ end: return EO_CALLBACK_CONTINUE; } +static Eina_Bool +_default_hover_selected_cb(void *data, const Eo_Event *event) +{ + const char *choosen_value = elm_object_item_part_text_get(event->event_info, NULL); + Eo *handler = data; + Par_Field_Data *pfd = NULL; + pfd = eo_key_data_get(handler, _STR_EDITOR); + const Op_Desc *op = pfd->it_data->op_desc; + if (!op) op = original_op_desc_get(pfd->it_data->orig_op_desc); + Eina_List *def_vals = (Eina_List *) op_param_desc_default_values_list_get(db_op_desc_nth_param_desc_get(op, pfd->par_idx)); + if (def_vals) + { + Param_Default_Value *def_val; + Eina_List *itr; + EINA_LIST_FOREACH(def_vals, itr, def_val) + { + if (!strcmp(choosen_value, param_default_value_name_get(def_val))) + { + if (eo_class_get(handler) == ELM_ENTRY_CLASS) + { + elm_obj_widget_part_text_set(handler, NULL, param_default_value_get(def_val)); + } + else if (eo_class_get(handler) == ELM_SLIDER_CLASS) + { + elm_obj_slider_value_set(handler, atof(param_default_value_get(def_val))); + eo_key_data_set(handler, _DEFAULT_VALUE, def_val); + } + break; + } + } + } + Eo_Event *tmp_event = calloc(1, sizeof(Eo_Event)); + tmp_event->obj = handler; + _prop_update_from_propview(NULL, tmp_event); + free(tmp_event); + return EO_CALLBACK_CONTINUE; +} + /* Callback to dissmiss "Drop Property" ctxpopup */ static void _ctxpopup_dismissed(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) @@ -4940,6 +4996,7 @@ editor_init(GuiLogicCbs *_guilogic_cbs) PropViewCbs *prop_cbs = propview_cbs_get(); prop_cbs->property_update_cb_func = _prop_update_from_propview; prop_cbs->property_ctx_menu_cb_func = _prop_ctx_menu_cb_func; + prop_cbs->default_hover_selected_cb_func = _default_hover_selected_cb; ContentViewCbs *content_cbs = contentview_cbs_get(); content_cbs->content_delete_cb_func = _content_del_from_propview; diff --git a/src/bin/gui/egui_layout.json b/src/bin/gui/egui_layout.json index 0143077..148b562 100644 --- a/src/bin/gui/egui_layout.json +++ b/src/bin/gui/egui_layout.json @@ -3,6 +3,7 @@ "Settings": { "project":"egui_layout", + "basedir":".", "start_points":["main_win"] }, "Resources": @@ -42,7 +43,8 @@ "_custom_theme_del_button_clicked":"_custom_theme_del_button_clicked", "_theme_selector_hover_selected_cb":"_theme_selector_hover_selected_cb", "_rmview_toolbar_clicked":"_rmview_toolbar_clicked", - "_canvas_resize_cb":"_canvas_resize_cb" + "_canvas_resize_cb":"_canvas_resize_cb", + "_expert_simple_mode_toggle_changed":"_expert_simple_mode_toggle_changed" }, "Edjes": { @@ -428,7 +430,7 @@ }, "Properties": { - "Elm.Toolbar.horizontal":[true], + "Elm.Widget.style":["item_horizontal"], "Elm.Toolbar.shrink_mode":["ELM_TOOLBAR_SHRINK_MENU"], "Elm.Toolbar.select_mode":["ELM_OBJECT_SELECT_MODE_ALWAYS"], "Elm.Toolbar.icon_size":[16], @@ -698,6 +700,27 @@ "Efl.Gfx.Base.visible":[true] } }, + "settings_table": + { + "Desc": + { + "parent":"settings_win", + "class":"Elm.Table" + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[70, 60] + }, + "Contains": + { + "settings_toolbar":[0, 0, 1, 1], + "project_settings_box":[0, 1, 1, 1], + "erigo_settings_box":[0, 1, 1, 1], + "settings_buttons_box":[0, 2, 1, 1] + } + }, "settings_toolbar": { "Desc": @@ -736,29 +759,6 @@ } } }, - "project_settings_table": - { - "Desc": - { - "parent":"project_settings_box", - "class":"Elm.Table", - "public":true - }, - "Properties": - { - "Efl.Gfx.Base.visible":[true], - "Elm.Table.padding":[6, 7], - "Evas.Object.size_hint_align":[-1, -1], - "Evas.Object.size_hint_weight":[1, 1] - }, - "Contains": - { - "project_name_label":[0, 0, 1, 1], - "project_name_entry":[1, 0, 1, 1], - "start_points_label":[0, 2, 1, 1], - "start_points_genlist":[0, 3, 2, 2] - } - }, "settings_buttons_box": { "Desc": @@ -795,6 +795,45 @@ "clicked":["Invoke", "_settings_apply_button_clicked", null] } }, + "project_settings_box": + { + "Desc": + { + "parent":"settings_table", + "class":"Elm.Box", + "public":true + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Evas.Object.size_hint_align":[-1, -1] + }, + "Contains":["project_settings_table"] + }, + "project_settings_table": + { + "Desc": + { + "parent":"project_settings_box", + "class":"Elm.Table", + "public":true + }, + "Properties": + { + "Efl.Gfx.Base.visible":[true], + "Elm.Table.padding":[6, 7], + "Evas.Object.size_hint_align":[-1, -1], + "Evas.Object.size_hint_weight":[1, 1] + }, + "Contains": + { + "project_name_label":[0, 0, 1, 1], + "project_name_entry":[1, 0, 1, 1], + "start_points_label":[0, 2, 1, 1], + "start_points_genlist":[0, 3, 2, 2] + } + }, "project_name_label": { "Desc": @@ -858,6 +897,113 @@ "Efl.Gfx.Base.visible":[true] } }, + "erigo_settings_box": + { + "Desc": + { + "parent":"settings_table", + "class":"Elm.Box", + "public":true + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Evas.Object.size_hint_align":[-1, -1] + }, + "Contains":["erigo_settings_table"] + }, + "erigo_settings_table": + { + "Desc": + { + "parent":"erigo_settings_box", + "class":"Elm.Table" + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[70, 60], + "Evas.Object.size_hint_align":[-1, -1] + }, + "Contains": + { + "custom_themes_genlist":[0, 1, 1, 1], + "custom_theme_buttons":[0, 0, 1, 1] + } + }, + "custom_themes_genlist": + { + "Desc": + { + "parent":"erigo_settings_table", + "class":"Elm.Genlist", + "public":true + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[70, 60], + "Evas.Object.size_hint_align":[-1, -1] + } + }, + "custom_theme_buttons": + { + "Desc": + { + "parent":"erigo_settings_table", + "class":"Elm.Box" + }, + "Properties": + { + "Efl.Gfx.Base.visible":[true], + "Evas.Object.size_hint_weight":[1, 0], + "Elm.Box.horizontal":[true], + "Evas.Object.size_hint_align":[-1, 0] + }, + "Contains":["cutom_theme_fs_bt", "custom_theme_del_bt"] + }, + "cutom_theme_fs_bt": + { + "Desc": + { + "parent":"custom_theme_buttons", + "class":"Elm.Button", + "public":true + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[73, 30], + "Elm.Widget.part_text":[null, "Add"] + }, + "Callbacks": + { + "clicked":["Invoke", "_custom_theme_add_button_clicked", null] + } + }, + "custom_theme_del_bt": + { + "Desc": + { + "parent":"custom_theme_buttons", + "class":"Elm.Button" + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[73, 30], + "Elm.Widget.part_text":[null, "Delete"] + }, + "Callbacks": + { + "clicked":["Invoke", "_custom_theme_del_button_clicked", null] + } + }, "main_win": { "Desc": @@ -1047,7 +1193,7 @@ }, "Properties": { - "Elm.Toolbar.horizontal":[true], + "Elm.Widget.style":["item_horizontal"], "Elm.Toolbar.select_mode":["ELM_OBJECT_SELECT_MODE_DEFAULT"], "Elm.Toolbar.shrink_mode":["ELM_TOOLBAR_SHRINK_NONE"], "Evas.Object.size_hint_weight":[1, 0], @@ -1072,44 +1218,44 @@ }, "Contains":["left_panes"] }, - "left_pane_layout": + "left_panes": { "Desc": { - "parent":"left_panes", - "class":"Elm.Layout" + "parent":"hor_box", + "class":"Elm.Panes", + "public":true }, "Properties": { "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.File.file":["panes_layout", "elm/layout/panes/pane"] + "Evas.Object.size_hint_align":[-1, -1], + "Elm.Panes.content_right_size":[0.83], + "Efl.Gfx.Base.visible":[true] }, "Contains": { - "left_pane_bg":["erigo.swallow.bg"], - "left_panel_box":["erigo.swallow.content"] + "left_pane_layout":["left"], + "right_panes":["right"] } }, - "left_panes": + "left_pane_layout": { "Desc": { - "parent":"hor_box", - "class":"Elm.Panes", - "public":true + "parent":"left_panes", + "class":"Elm.Layout" }, "Properties": { "Evas.Object.size_hint_weight":[1, 1], - "Evas.Object.size_hint_align":[-1, -1], - "Elm.Panes.content_right_size":[0.83], - "Efl.Gfx.Base.visible":[true] + "Efl.Gfx.Base.visible":[true], + "Efl.File.file":["panes_layout", "elm/layout/panes/pane"] }, "Contains": { - "left_pane_layout":["left"], - "right_panes":["right"] + "left_pane_bg":["erigo.swallow.bg"], + "left_panel_box":["erigo.swallow.content"] } }, "left_pane_bg": @@ -1451,96 +1597,135 @@ "Efl.Gfx.Base.visible":[true] } }, - "right_panes": + "theme_selector_box": { "Desc": { - "parent":"left_panes", - "class":"Elm.Panes", - "public":true + "parent":"left_panel_box", + "class":"Elm.Box" }, "Properties": { - "Evas.Object.size_hint_weight":[1, 1], - "Evas.Object.size_hint_align":[1, -1], - "Elm.Panes.content_right_size":[0.20], - "Efl.Gfx.Base.visible":[true] + "Efl.Gfx.Base.visible":[true], + "Elm.Box.horizontal":[true], + "Evas.Object.size_hint_align":[-1, 0], + "Evas.Object.size_hint_weight":[1, 0] }, - "Contains": - { - "right_pane_layout":["right"], - "canvas_scroller":["left"] - } + "Contains":["theme_selector_label", "theme_selector_hoversel", "zoom_label"] }, - "canvas_scroller": + "theme_selector_label": { "Desc": { - "parent":"right_panes", - "class":"Elm.Scroller", - "public":true + "parent":"theme_selector_box", + "class":"Elm.Label" }, "Properties": { "Evas.Object.size_hint_weight":[1, 1], - "Evas.Object.size_hint_align":[-1, -1], - "Elm.Interface_Scrollable.bounce_allow":[false, false], - "Efl.Gfx.Base.visible":[true] - }, - "Callbacks": + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[60, 30], + "Elm.Widget.part_text":[null, "Select Theme:"] + } + }, + "theme_selector_hoversel": + { + "Desc": { - "resize":["Invoke", "_canvas_resize_cb", null] + "parent":"theme_selector_box", + "class":"Elm.Hoversel", + "public":true }, - "Contains": + "Properties": { - "canvas_grid":[null] + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[73, 30], + "Elm.Widget.part_text":[null, "default"], + "Elm.Hoversel.hover_parent":["hor_box"] + }, + "Callbacks": + { + "selected":["Invoke", "_theme_selector_hover_selected_cb", null] } }, - "canvas_grid": + "zoom_label": { "Desc": { - "parent":"canvas_scroller", - "class":"Elm.Grid", + "parent":"theme_selector_box", + "class":"Elm.Label", "public":true }, "Properties": { "Evas.Object.size_hint_weight":[0, 0], - "Evas.Object.size_hint_align":[0, 0], - "Elm.Grid.size":[1000, 1000], - "Evas.Object.size_hint_min":[1, 1], - "Efl.Gfx.Base.visible":[true] + "Evas.Object.size_hint_align":[1, 0], + "Efl.Gfx.Base.visible":[true], + "Elm.Widget.part_text":[null, "100%"] } }, - "right_pane_bg": + "right_panes": { "Desc": { - "parent":"right_pane_layout", - "class":"Elm.Bg" + "parent":"left_panes", + "class":"Elm.Panes", + "public":true }, "Properties": { "Evas.Object.size_hint_weight":[1, 1], + "Evas.Object.size_hint_align":[1, -1], + "Elm.Panes.content_right_size":[0.20], "Efl.Gfx.Base.visible":[true] + }, + "Contains": + { + "right_pane_layout":["right"], + "canvas_scroller":["left"] } }, - "right_panel_box": + "canvas_scroller": { "Desc": { - "parent":"right_pane_layout", - "class":"Elm.Box", + "parent":"right_panes", + "class":"Elm.Scroller", "public":true }, "Properties": { "Evas.Object.size_hint_weight":[1, 1], "Evas.Object.size_hint_align":[-1, -1], + "Elm.Interface_Scrollable.bounce_allow":[false, false], "Efl.Gfx.Base.visible":[true] }, - "Contains":["right_panes_internal"] + "Callbacks": + { + "resize":["Invoke", "_canvas_resize_cb", null] + }, + "Contains": + { + "canvas_grid":[null] + } + }, + "canvas_grid": + { + "Desc": + { + "parent":"canvas_scroller", + "class":"Elm.Grid", + "public":true + }, + "Properties": + { + "Evas.Object.size_hint_weight":[0, 0], + "Evas.Object.size_hint_align":[0, 0], + "Elm.Grid.size":[1000, 1000], + "Evas.Object.size_hint_min":[1, 1], + "Efl.Gfx.Base.visible":[true] + } }, "right_pane_layout": { @@ -1563,6 +1748,35 @@ "right_panel_box":["erigo.swallow.content"] } }, + "right_pane_bg": + { + "Desc": + { + "parent":"right_pane_layout", + "class":"Elm.Bg" + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true] + } + }, + "right_panel_box": + { + "Desc": + { + "parent":"right_pane_layout", + "class":"Elm.Box", + "public":true + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Evas.Object.size_hint_align":[-1, -1], + "Efl.Gfx.Base.visible":[true] + }, + "Contains":["right_panes_internal"] + }, "right_panes_internal": { "Desc": @@ -1739,6 +1953,27 @@ "Efl.Gfx.Base.visible":[true] } }, + "propsview_toggle": + { + "Desc": + { + "parent":"propsview_table", + "class":"Elm.Check", + "public":true + }, + "Properties": + { + "Elm.Widget.style":["toggle"], + "Evas.Object.size_hint_weight":[1, 0], + "Evas.Object.size_hint_align":[0.50, 0], + "Elm.Widget.part_text":["on", "Simple Mode"], + "Elm.Widget.part_text":["off", "Expert Mode"] + }, + "Callbacks": + { + "changed":["Invoke", "_expert_simple_mode_toggle_changed", null] + } + }, "properties_list": { "Desc": @@ -1753,6 +1988,40 @@ "Evas.Object.size_hint_align":[-1, -1] } }, + "simple_properties_scroll": + { + "Desc": + { + "parent":"propsview_table", + "class":"Elm.Scroller", + "public":true + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Evas.Object.size_hint_align":[-1, -1], + "Elm.Interface_Scrollable.bounce_allow":[false, true] + }, + "Contains": + { + "simple_properties_box":[null] + } + }, + "simple_properties_box": + { + "Desc": + { + "parent":"simple_properties_scroll", + "class":"Elm.Box", + "public":true + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 0], + "Evas.Object.size_hint_align":[-1, 0], + "Efl.Gfx.Base.visible":[true] + } + }, "description_list": { "Desc": @@ -1890,6 +2159,21 @@ "callbacksview_up_btn_icon":[null] } }, + "callbacksview_up_btn_icon": + { + "Desc": + { + "parent":"callbacksview_up_btn", + "class":"Elm.Icon" + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[40, 40], + "Efl.File.file":["move_up_icon", null] + } + }, "callbacksview_down_btn": { "Desc": @@ -1911,6 +2195,21 @@ "callbacksview_down_btn_icon":[null] } }, + "callbacksview_down_btn_icon": + { + "Desc": + { + "parent":"callbacksview_down_btn", + "class":"Elm.Icon" + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[40, 40], + "Efl.File.file":["move_down_icon", null] + } + }, "callbacksview_del_btn": { "Desc": @@ -2016,6 +2315,21 @@ "contentview_down_btn_icon":[null] } }, + "contentview_down_btn_icon": + { + "Desc": + { + "parent":"contentview_down_btn", + "class":"Elm.Icon" + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[40, 40], + "Efl.File.file":["move_down_icon", null] + } + }, "contentview_up_btn": { "Desc": @@ -2037,6 +2351,21 @@ "contentview_up_btn_icon":[null] } }, + "contentview_up_btn_icon": + { + "Desc": + { + "parent":"contentview_up_btn", + "class":"Elm.Icon" + }, + "Properties": + { + "Evas.Object.size_hint_weight":[1, 1], + "Efl.Gfx.Base.visible":[true], + "Efl.Gfx.Base.size":[40, 40], + "Efl.File.file":["move_up_icon", null] + } + }, "itemview_box": { "Desc": @@ -2176,32 +2505,11 @@ "itemview_up_btn_icon":[null] } }, - "itemview_down_btn": - { - "Desc": - { - "parent":"itemview_buttons_box", - "class":"Elm.Button" - }, - "Properties": - { - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[73, 30] - }, - "Callbacks": - { - "clicked":["Invoke", "_itemview_down_btn_clicked", null] - }, - "Contains": - { - "itemview_down_btn_icon":[null] - } - }, - "contentview_up_btn_icon": + "itemview_up_btn_icon": { "Desc": { - "parent":"contentview_up_btn", + "parent":"itemview_up_btn", "class":"Elm.Icon" }, "Properties": @@ -2212,64 +2520,25 @@ "Efl.File.file":["move_up_icon", null] } }, - "contentview_down_btn_icon": - { - "Desc": - { - "parent":"contentview_down_btn", - "class":"Elm.Icon" - }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[40, 40], - "Efl.File.file":["move_down_icon", null] - } - }, - "callbacksview_up_btn_icon": + "itemview_down_btn": { "Desc": { - "parent":"callbacksview_up_btn", - "class":"Elm.Icon" + "parent":"itemview_buttons_box", + "class":"Elm.Button" }, "Properties": { - "Evas.Object.size_hint_weight":[1, 1], "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[40, 40], - "Efl.File.file":["move_up_icon", null] - } - }, - "callbacksview_down_btn_icon": - { - "Desc": - { - "parent":"callbacksview_down_btn", - "class":"Elm.Icon" + "Efl.Gfx.Base.size":[73, 30] }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[40, 40], - "Efl.File.file":["move_down_icon", null] - } - }, - "itemview_up_btn_icon": - { - "Desc": + "Callbacks": { - "parent":"itemview_up_btn", - "class":"Elm.Icon" + "clicked":["Invoke", "_itemview_down_btn_clicked", null] }, - "Properties": + "Contains": { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[40, 40], - "Efl.File.file":["move_up_icon", null] + "itemview_down_btn_icon":[null] } }, "itemview_down_btn_icon": @@ -2287,222 +2556,11 @@ "Efl.File.file":["move_down_icon", null] } }, - "project_settings_box": - { - "Desc": - { - "parent":"settings_table", - "class":"Elm.Box", - "public":true - }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Evas.Object.size_hint_align":[-1, -1] - }, - "Contains":["project_settings_table"] - }, - "settings_table": - { - "Desc": - { - "parent":"settings_win", - "class":"Elm.Table" - }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[70, 60] - }, - "Contains": - { - "settings_toolbar":[0, 0, 1, 1], - "project_settings_box":[0, 1, 1, 1], - "erigo_settings_box":[0, 1, 1, 1], - "settings_buttons_box":[0, 2, 1, 1] - } - }, - "erigo_settings_box": - { - "Desc": - { - "parent":"settings_table", - "class":"Elm.Box", - "public":true - }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Evas.Object.size_hint_align":[-1, -1] - }, - "Contains":["erigo_settings_table"] - }, - "erigo_settings_table": - { - "Desc": - { - "parent":"erigo_settings_box", - "class":"Elm.Table" - }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[70, 60], - "Evas.Object.size_hint_align":[-1, -1] - }, - "Contains": - { - "custom_themes_genlist":[0, 1, 1, 1], - "custom_theme_buttons":[0, 0, 1, 1] - } - }, - "custom_themes_genlist": - { - "Desc": - { - "parent":"erigo_settings_table", - "class":"Elm.Genlist", - "public":true - }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[70, 60], - "Evas.Object.size_hint_align":[-1, -1] - } - }, - "cutom_theme_fs_bt": - { - "Desc": - { - "parent":"custom_theme_buttons", - "class":"Elm.Button", - "public":true - }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[73, 30], - "Elm.Widget.part_text":[null, "Add"] - }, - "Callbacks": - { - "clicked":["Invoke", "_custom_theme_add_button_clicked", null] - } - }, - "custom_theme_buttons": - { - "Desc": - { - "parent":"erigo_settings_table", - "class":"Elm.Box" - }, - "Properties": - { - "Efl.Gfx.Base.visible":[true], - "Evas.Object.size_hint_weight":[1, 0], - "Elm.Box.horizontal":[true], - "Evas.Object.size_hint_align":[-1, 0] - }, - "Contains":["cutom_theme_fs_bt", "custom_theme_del_bt"] - }, - "custom_theme_del_bt": - { - "Desc": - { - "parent":"custom_theme_buttons", - "class":"Elm.Button" - }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[73, 30], - "Elm.Widget.part_text":[null, "Delete"] - }, - "Callbacks": - { - "clicked":["Invoke", "_custom_theme_del_button_clicked", null] - } - }, - "theme_selector_box": - { - "Desc": - { - "parent":"left_panel_box", - "class":"Elm.Box" - }, - "Properties": - { - "Efl.Gfx.Base.visible":[true], - "Elm.Box.horizontal":[true], - "Evas.Object.size_hint_align":[-1, 0], - "Evas.Object.size_hint_weight":[1, 0] - }, - "Contains":["theme_selector_label", "theme_selector_hoversel", "zoom_label"] - }, - "theme_selector_label": - { - "Desc": - { - "parent":"theme_selector_box", - "class":"Elm.Label" - }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[60, 30], - "Elm.Widget.part_text":[null, "Select Theme:"] - } - }, - "theme_selector_hoversel": - { - "Desc": - { - "parent":"theme_selector_box", - "class":"Elm.Hoversel", - "public":true - }, - "Properties": - { - "Evas.Object.size_hint_weight":[1, 1], - "Efl.Gfx.Base.visible":[true], - "Efl.Gfx.Base.size":[73, 30], - "Elm.Widget.part_text":[null, "default"], - "Elm.Hoversel.hover_parent":["hor_box"] - }, - "Callbacks": - { - "selected":["Invoke", "_theme_selector_hover_selected_cb", null] - } - }, - "zoom_label": - { - "Desc": - { - "parent":"theme_selector_box", - "class":"Elm.Label", - "public":true - }, - "Properties": - { - "Evas.Object.size_hint_weight":[0, 0], - "Evas.Object.size_hint_align":[1, 0], - "Efl.Gfx.Base.visible":[true], - "Elm.Widget.part_text":[null, "100%"] - } - }, "naviframe_part": { "Desc": { + "parent":null, "class":"Elm.Box", "public":true }, diff --git a/src/bin/gui/egui_logic.c b/src/bin/gui/egui_logic.c index 7b58aa1..d77e0c1 100644 --- a/src/bin/gui/egui_logic.c +++ b/src/bin/gui/egui_logic.c @@ -896,7 +896,7 @@ _toolbar_simulate_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info if (!gui_context_start_points_get(ctx)) { - popup_show(g_main_wdgs->main_win->main_win, "Error", "Start point is not defined. Open \"Settings\" to define.", NULL, + popup_show(g_main_wdgs->main_win->main_win, "Error", "Start point is not defined. Open \"Settings\" to define.", NULL, NULL, POPUP_OK_BUTTON, NULL, NULL); return; } @@ -1140,11 +1140,12 @@ egui_start(const char *filename) evas_object_smart_callback_add(g_main_wdgs->main_win->main_win, "delete,request", _main_win_del_cb, NULL); _egui_project_open(filename); elm_obj_table_pack(g_main_wdgs->main_win->objtree_table, g_main_wdgs->main_win->objtree_list, 0, 1, 1, 1); - elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->description_list, 0, 2, 1, 1); - elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->properties_list, 0, 2, 1, 1); - elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->callbacksview_box, 0, 2, 1, 1); - elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->itemview_box, 0, 2, 1, 1); - elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->contentview_box, 0, 2, 1, 1); + elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->description_list, 0, 3, 1, 1); + elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->properties_list, 0, 3, 1, 1); + elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->simple_properties_scroll, 0, 3, 1, 1); + elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->callbacksview_box, 0, 3, 1, 1); + elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->itemview_box, 0, 3, 1, 1); + elm_obj_table_pack(g_main_wdgs->main_win->propsview_table, g_main_wdgs->main_win->contentview_box, 0, 3, 1, 1); elm_obj_box_pack_end(g_main_wdgs->main_win->left_panel_box, g_main_wdgs->main_win->fctr_scroll); } diff --git a/src/bin/gui/prop_layout.c b/src/bin/gui/prop_layout.c index f98c833..a12ae1b 100644 --- a/src/bin/gui/prop_layout.c +++ b/src/bin/gui/prop_layout.c @@ -6,6 +6,7 @@ #include "egui_logic_private.h" #include "propview.h" +#include "simple_propview.h" #include "contentview.h" #include "descview.h" #include "cbview.h" @@ -65,6 +66,29 @@ _class_item_del(void *data, Evas_Object *obj EINA_UNUSED) free(cl); } +Eina_Bool +_expert_simple_mode_toggle_changed(void *data EINA_UNUSED, const Eo_Event *event EINA_UNUSED) +{ + Eo *obj = event->obj; + Eina_Bool state = elm_obj_check_state_get(obj); + Egui_Layout_Widgets *g = egui_layout_gui_get(); + const Gui_Context *ctx = _active_context_get(); + if (!ctx) return EINA_TRUE; + const Gui_Widget *wdg = gui_context_data_get(ctx, SELECTED_WDG); + if (state) + { + efl_gfx_visible_set(g->main_win->simple_properties_scroll, EINA_TRUE); + efl_gfx_visible_set(g->main_win->properties_list, EINA_FALSE); + simple_propview_build(wdg); + } + else + { + efl_gfx_visible_set(g->main_win->simple_properties_scroll, EINA_FALSE); + efl_gfx_visible_set(g->main_win->properties_list, EINA_TRUE); + propview_build(wdg); + } + return EINA_TRUE; +} /* This callback is called in the end of propview_build() * in order to switch between scrollbox for properties * and genlist for items. */ @@ -81,6 +105,8 @@ _proplayout_build_post_cb(const Gui_Widget *wdg, It_Data_Type new_type) } case PROPERTY_TYPE: { + efl_gfx_visible_set(g->main_win->propsview_toggle, EINA_FALSE); + elm_obj_table_unpack(g->main_win->propsview_table, g->main_win->propsview_toggle); break; } case CALLBACK_TYPE: @@ -108,11 +134,11 @@ _proplayout_build_post_cb(const Gui_Widget *wdg, It_Data_Type new_type) /* Setting view according to new selected toolbar's item. */ efl_gfx_visible_set(g->main_win->contentview_box, EINA_FALSE); efl_gfx_visible_set(g->main_win->properties_list, EINA_FALSE); + efl_gfx_visible_set(g->main_win->simple_properties_scroll, EINA_FALSE); efl_gfx_visible_set(g->main_win->itemview_box, EINA_FALSE); efl_gfx_visible_set(g->main_win->callbacksview_box, EINA_FALSE); efl_gfx_visible_set(g->main_win->description_list, EINA_FALSE); - elm_obj_box_unpack(g->main_win->itemview_box, g->main_win->itemview_buttons_box); efl_gfx_visible_set(g->main_win->itemview_buttons_box, EINA_FALSE); @@ -125,7 +151,13 @@ _proplayout_build_post_cb(const Gui_Widget *wdg, It_Data_Type new_type) } case PROPERTY_TYPE: { - efl_gfx_visible_set(g->main_win->properties_list, EINA_TRUE); + efl_gfx_visible_set(g->main_win->propsview_toggle, EINA_TRUE); + elm_obj_table_pack(g->main_win->propsview_table, g->main_win->propsview_toggle, 0, 2, 1, 1); + /* Call expert/simple view callback in order to show proper view. */ + Eo_Event *tmp_event = calloc(1, sizeof(Eo_Event)); + tmp_event->obj = g->main_win->propsview_toggle; + _expert_simple_mode_toggle_changed(NULL, tmp_event); + free(tmp_event); break; } case CALLBACK_TYPE: @@ -324,6 +356,7 @@ proplayout_init() descview_init(); contentview_init(); propview_init(); + simple_propview_init(); itemview_init(); settingsview_init(); @@ -350,6 +383,7 @@ proplayout_shutdown() cbview_shutdown(); descview_shutdown(); contentview_shutdown(); + simple_propview_shutdown(); propview_shutdown(); itemview_shutdown(); diff --git a/src/bin/gui/props_helper.c b/src/bin/gui/props_helper.c index 2de1c23..7809e8f 100644 --- a/src/bin/gui/props_helper.c +++ b/src/bin/gui/props_helper.c @@ -259,6 +259,18 @@ props_entry_add(Eo *box, const char *str, Gui_Type type) return en; } +Eo* +props_colorselector_add(Eo *box) +{ + Eo *cs = eo_add(ELM_COLORSELECTOR_CLASS, box); + evas_obj_size_hint_weight_set(cs, EVAS_HINT_EXPAND, 0.0); + evas_obj_size_hint_align_set(cs, EVAS_HINT_FILL, 0.5); + efl_gfx_visible_set(cs, EINA_TRUE); + + elm_obj_box_pack_end(box, cs); + return cs; +} + Eo * props_label_add(Eo *box, const char *str) { diff --git a/src/bin/gui/props_helper.h b/src/bin/gui/props_helper.h index d9b8a96..ba22775 100644 --- a/src/bin/gui/props_helper.h +++ b/src/bin/gui/props_helper.h @@ -26,6 +26,7 @@ }) #define _STR_EDITOR "editor" +#define _DEFAULT_VALUE "__default_value__" typedef enum { @@ -53,7 +54,9 @@ typedef struct { /* This Op_Desc is needed when we want to create empty property or content. */ /* For both: property and container. */ + Simple_Op_Handler_Type input_handler_type; const Op_Desc *op_desc; + const Original_Op_Desc *orig_op_desc; const Gui_Widget_Property *prop; /* Index of content in container. */ int idx; @@ -101,6 +104,9 @@ props_toggle_add(Eo *box, Eina_Bool state); Eo * props_button_add(Eo *box, char *text); +Eo* +props_colorselector_add(Eo *box); + /* Only one list (or none) should be provided. */ Eo * props_hoversel_enums_add(Eo *box, Eo *hover_parent, const char *default_val, const Eina_List *enums_lst, const Eina_List *defaults_lst); diff --git a/src/bin/gui/propview.c b/src/bin/gui/propview.c index b5cbd08..0a66301 100644 --- a/src/bin/gui/propview.c +++ b/src/bin/gui/propview.c @@ -33,35 +33,6 @@ PropViewCbs *propview_cbs_get() return _view_cbs; } -static Eina_Bool -_default_hover_selected_cb(void *data, const Eo_Event *event) -{ - const char *choosen_value = elm_object_item_part_text_get(event->event_info, NULL); - Eo *entry = data; - Par_Field_Data *pfd = NULL; - pfd = eo_key_data_get(entry, _STR_EDITOR); - const Op_Desc *op = pfd->it_data->op_desc; - Eina_List *def_vals = (Eina_List *) op_param_desc_default_values_list_get(db_op_desc_nth_param_desc_get(op, pfd->par_idx)); - if (def_vals) - { - Param_Default_Value *def_val; - Eina_List *itr; - EINA_LIST_FOREACH(def_vals, itr, def_val) - { - if (!strcmp(choosen_value, param_default_value_name_get(def_val))) - { - elm_obj_widget_part_text_set(entry, NULL, param_default_value_get(def_val)); - break; - } - } - } - Eo_Event *event_tmp = calloc(1, sizeof(Eo_Event)); - event_tmp->obj = entry; - _view_cbs->property_update_cb_func(NULL, event_tmp); - free(event_tmp); - return EO_CALLBACK_CONTINUE; -} - /* This will be called when hoversel item is selected. * If "Add resource..." item was selected, oper Resource Manager*/ static Eina_Bool @@ -150,7 +121,7 @@ _property_item_content_get(It_Data *it_data) if (def_vals) { Eo *hover = props_hoversel_enums_add(box, elm_widget_top_get(box), "...", NULL, def_vals); - eo_event_callback_add(hover, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, _default_hover_selected_cb, obj); + eo_event_callback_add(hover, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, _view_cbs->default_hover_selected_cb_func, obj); } } } @@ -239,6 +210,12 @@ _prop_item_content_get(void *data, Evas_Object *obj EINA_UNUSED, const char *par return it_box; } +Evas_Object * +prop_item_content_get(It_Data *data) +{ + return _prop_item_content_get(data, NULL, NULL); +} + static void _prop_item_del(void *data, Evas_Object *obj EINA_UNUSED) { diff --git a/src/bin/gui/propview.h b/src/bin/gui/propview.h index 739f0c4..1116da0 100644 --- a/src/bin/gui/propview.h +++ b/src/bin/gui/propview.h @@ -1,4 +1,3 @@ - #ifndef _PROPVIEW_H #define _PROPVIEW_H @@ -10,6 +9,7 @@ typedef struct { Eina_Bool (*property_update_cb_func)(void *data, const Eo_Event *event); Eina_Bool (*property_ctx_menu_cb_func)(void *data, const Eo_Event *event); + Eina_Bool (*default_hover_selected_cb_func)(void *data, const Eo_Event *event); } PropViewCbs; PropViewCbs * diff --git a/src/bin/gui/simple_propview.c b/src/bin/gui/simple_propview.c new file mode 100644 index 0000000..c9e7d07 --- /dev/null +++ b/src/bin/gui/simple_propview.c @@ -0,0 +1,600 @@ +#include <Elementary.h> +#include "props_helper.h" +#include "egui_log.h" +#include "gui_widget.h" +#include "propview.h" +#include "simple_propview.h" +#include "egui_logic_private.h" +#include "ffi_glue.h" +#include "rmview.h" +#include "popup.h" + +#include "elm_widget_container.h" + +#define __SECTION_NAME "__section_name__" + +static Eo *_simple_properties_box; + +static PropViewCbs *_simple_propview_cbs = NULL; + +static Eina_Bool +_pfd_free_cb(void *pfd, const Eo_Event *event EINA_UNUSED) +{ + free(pfd); + return EINA_TRUE; +} + +static Eina_Bool +_it_data_free_cb(void *data, const Eo_Event *event EINA_UNUSED) +{ + _it_data_free(data); + return EINA_TRUE; +} + +static Eina_Bool +_hover_selected_cb(void *data EINA_UNUSED, const Eo_Event *event) +{ + Eo *obj = event->obj; + void *event_info = event->event_info; + const char *choosen_value = elm_object_item_part_text_get(event_info, NULL); + if (!strcmp(choosen_value, PROP_HOVERSEL_ADD_RESOURCE_VALUE)) + { + const Egui_Layout_Widgets *g_main_wdgs = egui_layout_gui_get(); + rm_win_set(egui_layout_rm_win_create(g_main_wdgs->main_win->main_win)); + rm_win_post_configure(); + } + else + { + Eo_Event *tmp_event = calloc(1, sizeof(Eo_Event)); + tmp_event->obj = obj; + tmp_event->event_info = event_info; + _simple_propview_cbs->property_update_cb_func(NULL, event); + free(tmp_event); + } + return EO_CALLBACK_CONTINUE; +} + +static Eina_Bool +_slider_drag_stop_cb(void *data EINA_UNUSED, const Eo_Event *event) +{ + double num = elm_obj_slider_value_get(event->obj); + num = (round(num * 10))/10; + elm_obj_slider_value_set(event->obj, num); + + Eo_Event *tmp_event = calloc(1, sizeof(Eo_Event)); + tmp_event->obj = event->obj; + _simple_propview_cbs->property_update_cb_func(NULL, tmp_event); + free(tmp_event); + + return EO_CALLBACK_CONTINUE; +} + +void +simple_propview_init() +{ + Egui_Layout_Widgets *g = egui_layout_gui_get(); + _simple_properties_box = g->main_win->simple_properties_box; + _simple_propview_cbs = propview_cbs_get(); +} + +void +simple_propview_shutdown() +{ +} + +typedef struct +{ + int r, g, b, a; + It_Data *it_data; + Eo *button; + Eo *rect; +} Prop_Change_Data; + +static Eina_Bool +_colorselector_changed_cb(void *data, const Eo_Event *event) +{ + Prop_Change_Data *pcd = data; + elm_obj_colorselector_color_get(event->obj, &pcd->r, &pcd->g, &pcd->b, &pcd->a); + efl_gfx_color_set(pcd->rect, pcd->r, pcd->g, pcd->b, pcd->a); + return EO_CALLBACK_CONTINUE; +} + +static Eo * +_popup_colorselector_get(void *data, Eo *popup) +{ + Prop_Change_Data *pcd = data; + + Eo *bx = eo_add(ELM_BOX_CLASS, popup); + evas_obj_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_obj_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL); + efl_gfx_visible_set(bx, EINA_TRUE); + + Eo *re = eo_add(EVAS_RECTANGLE_CLASS, popup); + evas_obj_size_hint_min_set(re, 1, ELM_SCALE_SIZE(100)); + evas_obj_size_hint_align_set(re, EVAS_HINT_FILL, EVAS_HINT_FILL); + efl_gfx_visible_set(re, EINA_TRUE); + elm_box_pack_end(bx, re); + pcd->rect = re; + efl_gfx_color_set(pcd->rect, pcd->r, pcd->g, pcd->b, pcd->a); + + Eo *cs = eo_add(ELM_COLORSELECTOR_CLASS, popup); + efl_gfx_visible_set(cs, EINA_TRUE); + + elm_obj_colorselector_color_set(cs, pcd->r, pcd->g, pcd->b, pcd->a); + evas_obj_size_hint_weight_set(cs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_obj_size_hint_align_set(cs, EVAS_HINT_FILL, EVAS_HINT_FILL); + eo_event_callback_add(cs, ELM_COLORSELECTOR_EVENT_CHANGED, _colorselector_changed_cb, pcd); + + elm_box_pack_end(bx, cs); + return bx; +} + +/* Callback called when Ok or Cancel button is pressed. */ +static void +_color_change_popup_cb(Popup_Button_Type button_type, void *data) +{ + Prop_Change_Data *pcd = data; + if (button_type == POPUP_OK_BUTTON) + { + efl_gfx_color_set(pcd->button, pcd->r, pcd->g, pcd->b, pcd->a); + It_Data *it_data = pcd->it_data; + + const Gui_Widget *wdg = it_data->wdg; + Gui_Widget_Property *prop = NULL, *old_property = NULL; + Gui_Value *val = NULL; + Gui_Context *ctx = _active_context_get(); + + prop = (Gui_Widget_Property *) it_data->prop; + /* propdata box, change its color then value changed from default. */ + Eo *box = it_data->box; + + /* Save old property to be able to add it to UndoRedo stack. */ + old_property = prop; + /* Every time value is changed, crete new property. */ + prop = prop_copy(prop); + + val = prop_value_nth_get(prop, 0); + gui_value_int_set(val, pcd->r); + val = prop_value_nth_get(prop, 1); + gui_value_int_set(val, pcd->g); + val = prop_value_nth_get(prop, 2); + gui_value_int_set(val, pcd->b); + val = prop_value_nth_get(prop, 3); + gui_value_int_set(val, pcd->a); + + if (prop_wdg_get(old_property)) + { + memento_command_add(wdg_eid_get(wdg), MEMENTO_PROPERTY, old_property, prop); + memento_focused_widget_add(wdg_eid_get(wdg)); + wdg_prop_remove((Gui_Widget *) wdg, old_property); + } + /* If not, this prop is default property which was fetched from _ffi_eo_do, don't need to save it, + * but need to make it white. + * This happens only when value is changed for the first time. */ + else + { + efl_gfx_color_set(box, 255, 255, 255, 255); + prop_ref(old_property); + prop_unref(old_property); + old_property = NULL; + memento_command_add(wdg_eid_get(wdg), MEMENTO_PROPERTY, old_property, prop); + memento_focused_widget_add(wdg_eid_get(wdg)); + } + + /* Assign new prop to widget */ + wdg_prop_add((Gui_Widget *) wdg, prop); + /* Save new prop in item. */ + it_data->prop = prop; + context_memento_finalize(ctx); + } + free(pcd); +} + +static Eina_Bool +_csb_clicked_cb(void *data, const Eo_Event *event) +{ + const Egui_Layout_Widgets *g_main_wdgs = egui_layout_gui_get(); + + It_Data *it_data = data; + const Gui_Widget_Property *prop = it_data->prop; + int r = 255, g = 255, b = 255, a = 255; + if (prop) + { + r = INT_GET(prop_value_nth_get(prop, 0)); + g = INT_GET(prop_value_nth_get(prop, 1)); + b = INT_GET(prop_value_nth_get(prop, 2)); + a = INT_GET(prop_value_nth_get(prop, 3)); + } + + Prop_Change_Data *pcd = calloc(1, sizeof(Prop_Change_Data)); + pcd->r = r; + pcd->g = g; + pcd->b = b; + pcd->a = a; + pcd->it_data = it_data; + pcd->button = event->obj; + + popup_show(g_main_wdgs->main_win->main_win, NULL, NULL, _popup_colorselector_get, pcd, POPUP_OK_BUTTON | POPUP_CANCEL_BUTTON, _color_change_popup_cb, pcd); + return EO_CALLBACK_CONTINUE; +} + +static void +_simple_property_handler_get(Eo *box, It_Data *it_data, const char *name) +{ + it_data->box = box; + + //const Original_Op_Desc *orig_op_desc = it_data->orig_op_desc; + //const Op_Desc *op = original_op_desc_get(orig_op_desc); + + props_label_add(box, name); + + if (it_data->input_handler_type == SIMPLE_OP_HANDLER_COLORSELECTOR) + { + int r = 255, g = 255, b = 255, a = 255; + const Gui_Widget_Property *prop = it_data->prop; + if (prop) + { + r = INT_GET(prop_value_nth_get(prop, 0)); + g = INT_GET(prop_value_nth_get(prop, 1)); + b = INT_GET(prop_value_nth_get(prop, 2)); + a = INT_GET(prop_value_nth_get(prop, 3)); + } + + Eo *re = eo_add(EVAS_RECTANGLE_CLASS, box); + evas_obj_size_hint_weight_set(re, EVAS_HINT_EXPAND, 0); + evas_obj_size_hint_align_set(re, EVAS_HINT_FILL, EVAS_HINT_FILL); + efl_gfx_color_set(re, r, g, b, a); + efl_gfx_visible_set(re, EINA_TRUE); + eo_event_callback_add(re, EVAS_OBJECT_EVENT_MOUSE_UP, _csb_clicked_cb, it_data); + elm_box_pack_end(box, re); + } + else if (it_data->input_handler_type == SIMPLE_OP_HANDLER_SLIDER) + { + unsigned int count, i; + const Gui_Widget_Property *prop = it_data->prop; + const Op_Desc *op = prop_op_desc_get(prop); + count = db_op_desc_param_number_get(op); + + for (i = 0; i < count; i++) + { + double val = DOUBLE_GET(prop_value_nth_get(prop, i)); + + const Simple_View_Slider_Data *sd = original_op_data_get(it_data->orig_op_desc); + + Eo *sldr = eo_add(ELM_SLIDER_CLASS, box); + efl_gfx_visible_set(sldr, EINA_TRUE); + evas_obj_size_hint_weight_set(sldr, EVAS_HINT_EXPAND, 1); + evas_obj_size_hint_align_set(sldr, EVAS_HINT_FILL, -1); + elm_obj_slider_indicator_show_set(sldr, EINA_TRUE); + elm_obj_slider_indicator_format_set(sldr, "%1.1f"); + elm_obj_slider_unit_format_set(sldr, "%1.1f"); + elm_obj_slider_min_max_set(sldr, sd->min, sd->max); + elm_obj_slider_step_set(sldr, sd->step); + elm_obj_slider_value_set(sldr, val); + + eo_event_callback_add(sldr, ELM_SLIDER_EVENT_SLIDER_DRAG_STOP, _slider_drag_stop_cb, NULL); + elm_box_pack_end(box, sldr); + + Par_Field_Data *pfd = calloc (1, sizeof(Par_Field_Data)); + pfd->it_data = it_data; + pfd->par_idx = i; + + eo_key_data_set(sldr, _STR_EDITOR, pfd); + eo_event_callback_add(sldr, EO_BASE_EVENT_DEL, _pfd_free_cb, pfd); + + const char *tooltip_text = op_param_desc_name_get(db_op_desc_nth_param_desc_get(op, pfd->par_idx)); + elm_object_tooltip_text_set(sldr, tooltip_text); + + + Eina_List *def_vals = (Eina_List *) op_param_desc_default_values_list_get(db_op_desc_nth_param_desc_get(op, i)); + if (def_vals) + { + Eo *hover = props_hoversel_enums_add(box, elm_widget_top_get(box), "...", NULL, def_vals); + eo_event_callback_add(hover, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, _simple_propview_cbs->default_hover_selected_cb_func, sldr); + } + } + } +} + +static void +_property_item_content_get(Eo *box, It_Data *it_data, const char *name) +{ + it_data->box = box; + + const Original_Op_Desc *orig_op_desc = it_data->orig_op_desc; + const Op_Desc *op = original_op_desc_get(orig_op_desc); + const Gui_Widget_Property *prop = it_data->prop; + /* Add label with op name. */ + props_label_add(box, name); + + unsigned int count, i; + count = db_op_desc_param_number_get(op); + + const Eina_List *param_mapping_list = original_op_mapping_array_get(orig_op_desc); + + for (i = 0; i < count; i++) + { + /* Get value, for which we want to build field. + * If it is NULL, field will be build, for nth value in Op_Desc*/ + Gui_Value *value = ((prop && prop_value_get(prop)) ? prop_value_nth_get(prop, i) : NULL); + /* Checking mapping array. If value is not IDX, means this is constant and we don't show edit field. */ + if (param_mapping_list) + { + Gui_Value *mapping_value = eina_list_nth(param_mapping_list, i); + if (gui_value_type_get(mapping_value) != GUI_TYPE_IDX) + { + /* If mapping_value is not IDX(i.e constant) and property value is not equal, + * box mus be disabled. */ + if (gui_value_cmp(value, mapping_value)) + { + elm_obj_widget_disabled_set(box, EINA_TRUE); + efl_gfx_color_set(box, 180, 180, 180, 255); + } + continue; + } + } + Eo *obj = props_value_add(box, it_data->wdg, value, op, i); + if (obj) + { + Par_Field_Data *pfd = calloc (1, sizeof(Par_Field_Data)); + pfd->it_data = it_data; + pfd->par_idx = i; + + eo_key_data_set(obj, _STR_EDITOR, pfd); + eo_event_callback_add(obj, EO_BASE_EVENT_DEL, _pfd_free_cb, pfd); + + const char *tooltip_text = op_param_desc_name_get(db_op_desc_nth_param_desc_get(op, pfd->par_idx)); + elm_object_tooltip_text_set(obj, tooltip_text); + + if (eo_isa(obj, ELM_HOVERSEL_CLASS)) + { + /* pass box as a data, in order to change its color then value changed from default. */ + eo_event_callback_add(obj, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, _hover_selected_cb, NULL); + } + else if (eo_isa(obj, ELM_CHECK_CLASS)) + { + /* pass box as a data, in order to change its color then value changed from default. */ + eo_event_callback_add(obj, ELM_CHECK_EVENT_CHANGED, _simple_propview_cbs->property_update_cb_func, NULL); + } + else if (eo_isa(obj, ELM_ENTRY_CLASS)) + { + /*FIXME: decide how to handle CHANGE ON ACTIVATE*/ + /* pass box as a data, in order to change its color then value changed from default. */ + eo_event_callback_add(obj, ELM_ENTRY_EVENT_CHANGED_USER, _simple_propview_cbs->property_update_cb_func, NULL); + + /* If there are default values, add Hoversel. */ + Eina_List *def_vals = (Eina_List *) op_param_desc_default_values_list_get(db_op_desc_nth_param_desc_get(op, i)); + if (def_vals) + { + Eo *hover = props_hoversel_enums_add(box, elm_widget_top_get(box), "...", NULL, def_vals); + eo_event_callback_add(hover, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, _simple_propview_cbs->default_hover_selected_cb_func, obj); + } + } + } + else + { + /* + ERR("Can't create field for %dnth parameter in \"%s\", \ + probably this parameter is NULL pointer", i + 1, db_op_desc_op_name_get(op)); + */ + } + } +} + +static Eo * +_simple_prop_item_content_get(It_Data *data, const char *simple_op_name) +{ + It_Data *it_data = data; + const Op_Desc *op_desc = original_op_desc_get(it_data->orig_op_desc); + + if (!it_data->prop) + { + it_data->prop = prop_create_for_op(op_desc); + const Gui_Context *ctx = _active_context_get(); + Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(ctx); + + /* Check if get function is implemented for this property. */ + Eolian_Function_Type func_type = db_op_desc_type_get(op_desc); + const Eolian_Class *f_klass = eolian_class_get_by_name(db_op_desc_class_name_get(op_desc)); + const Eolian_Class *w_klass = eolian_class_get_by_name(wdg_class_name_get(it_data->wdg)); + + const char *func_name = db_op_desc_op_name_get(op_desc); + + const Eolian_Function *func_id = eolian_class_function_get_by_name(f_klass, func_name, func_type); + Eina_Bool ret = eolian_function_is_implemented(func_id, func_type, w_klass); + if (ret) + { + manager_widget_property_get(session, it_data->wdg, it_data->prop); + } + else + { + ERR("Func: \"%s::%s\" was not implemented for class \"%s\"", eolian_class_name_get(f_klass), + func_name, + eolian_class_name_get(w_klass)); + } + } + + Evas_Object * it_box = NULL; + it_box = eo_add(ELM_BOX_CLASS, _simple_properties_box); + efl_gfx_visible_set(it_box, EINA_TRUE); + elm_obj_box_horizontal_set(it_box, EINA_TRUE); + elm_obj_box_padding_set(it_box, 5, 0); + evas_obj_size_hint_weight_set(it_box, EVAS_HINT_EXPAND, 0); + evas_obj_size_hint_align_set(it_box, EVAS_HINT_FILL, 0); + + if (it_data->input_handler_type == SIMPLE_OP_HANDLER_REGULAR) + { + _property_item_content_get(it_box, it_data, simple_op_name); + } + else + { + _simple_property_handler_get(it_box, it_data, simple_op_name); + } + + Eo *prop_menu_button = props_button_add(it_box, NULL); + evas_obj_size_hint_align_set(prop_menu_button, 1, 0); + evas_obj_size_hint_weight_set(prop_menu_button, 0.01, 0); + eo_key_data_set(prop_menu_button, _STR_EDITOR, it_data); + eo_event_callback_add(prop_menu_button, EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED, _simple_propview_cbs->property_ctx_menu_cb_func, NULL); + + Eo *ic = eo_add(ELM_ICON_CLASS, it_box); + efl_file_set(ic, EGUI_LAYOUT_IMAGES_PATH"/icon_prop_menu2.png", NULL); + elm_obj_container_content_set(prop_menu_button, "icon", ic); + + if (!prop_wdg_get(it_data->prop)) + efl_gfx_color_set(it_box, 150, 150, 150, 255); + else + efl_gfx_color_set(it_box, 255, 255, 255, 255); + + return it_box; +} + +Original_Op_Desc* +gui_widget_original_desc_by_simple_get(const Gui_Widget *wdg, Simple_Op_Desc *simple_op_desc) +{ + Original_Op_Desc *ret = NULL; + + const Eina_List *orig_op_desc_list, *itr1, *itr2; + Original_Op_Desc *orig_op_desc; + Eina_Stringshare *wdg_class_name = wdg_class_name_get(wdg), *class_name; + + orig_op_desc_list = simple_op_desc_original_ops_list_get(simple_op_desc); + Eina_Bool inherits = EINA_FALSE; + + const Op_Desc *op_desc = NULL; + EINA_LIST_FOREACH(orig_op_desc_list, itr1, orig_op_desc) + { + const Eina_List *class_list = original_op_classes_list_get(orig_op_desc); + op_desc = original_op_desc_get(orig_op_desc); + /* If op_desc == NULL, this is black list case*/ + if (!op_desc) + { + if (!class_list) return ret; + EINA_LIST_FOREACH(class_list, itr2, class_name) + { + if (class_name == wdg_class_name) + return ret; + } + } + if ((inherits = eo_class_inherits_from(wdg_class_name, db_op_desc_class_name_get(op_desc)))) + { + Eina_Bool found_in_list = EINA_FALSE; + /* If class_list is not NULL, look for class name in it. + * If class_list is NULL - this means this is default op*/ + if (class_list) + { + EINA_LIST_FOREACH(class_list, itr2, class_name) + { + if (class_name == wdg_class_name) + { + found_in_list = EINA_TRUE; + break; + } + } + } + else + { + found_in_list = EINA_TRUE; + } + + if (found_in_list) + { + ret = orig_op_desc; + break; + } + } + } + + return ret; +} + +void +simple_propview_build(const Gui_Widget *wdg) +{ + const Eina_List *simple_op_desc_list, *itr1; + Simple_Op_Desc *simple_op_desc; + const Original_Op_Desc *orig_op_desc; + + elm_obj_box_clear(_simple_properties_box); + + simple_op_desc_list = simple_op_desc_list_get(); + EINA_LIST_FOREACH(simple_op_desc_list, itr1, simple_op_desc) + { + if (!simple_op_desc_section_name_get(simple_op_desc)) + { + simple_op_desc_section_name_set(simple_op_desc, "Others"); + } + + Simple_Op_Handler_Type input_handler_type = simple_op_desc_input_handler_type_get(simple_op_desc); + + if ((orig_op_desc = gui_widget_original_desc_by_simple_get(wdg, simple_op_desc))) + { + Eina_Stringshare *section_name = simple_op_desc_section_name_get(simple_op_desc); + const Op_Desc *op_desc = original_op_desc_get(orig_op_desc); + + Eina_List *pitems = NULL, *itr2; + Eina_List *wdg_prop_lst = wdg_prop_list_get(wdg); + Gui_Widget_Property *prop; + + // Find which class properties are in widget. Can be more than one. + EINA_LIST_FOREACH(wdg_prop_lst, itr2, prop) + if (prop_op_desc_get(prop) == op_desc) pitems = eina_list_append(pitems, prop); + + // If none found, its a default one + if (!eina_list_count(pitems)) pitems = eina_list_append(pitems, NULL); + + // Looking for a section with desired name + Eo *section_frame = NULL, *sect_itr; + Eina_Bool section_not_found = EINA_TRUE; + Eina_List *sections = elm_obj_box_children_get(_simple_properties_box); + EINA_LIST_FREE(sections, sect_itr) + { + if (section_not_found) + { + if (eo_key_data_get(sect_itr, __SECTION_NAME) == section_name) + { + section_frame = sect_itr; + section_not_found = EINA_FALSE; + } + } + } + + Eo *section_box = NULL; + if (!section_frame) + { + section_frame = eo_add(ELM_FRAME_CLASS, _simple_properties_box); + evas_obj_size_hint_weight_set(section_frame, EVAS_HINT_EXPAND, 0); + evas_obj_size_hint_align_set(section_frame, EVAS_HINT_FILL, 0); + efl_gfx_visible_set(section_frame, EINA_TRUE); + eo_key_data_set(section_frame, __SECTION_NAME, section_name); + elm_obj_widget_part_text_set(section_frame, NULL, section_name); + elm_obj_box_pack_end(_simple_properties_box, section_frame); + elm_obj_frame_autocollapse_set(section_frame, EINA_TRUE); + + section_box = eo_add(ELM_BOX_CLASS, section_frame); + evas_obj_size_hint_weight_set(section_box, EVAS_HINT_EXPAND, 0); + evas_obj_size_hint_align_set(section_box, EVAS_HINT_FILL, 0); + efl_gfx_visible_set(section_box, EINA_TRUE); + + elm_obj_container_content_set(section_frame, NULL, section_box); + } + else + { + section_box = elm_obj_container_content_get(section_frame, NULL); + } + + EINA_LIST_FREE(pitems, prop) + { + It_Data *it_data = IT_DATA_BUILD(PROPERTY_TYPE, wdg); + it_data->orig_op_desc = orig_op_desc; + it_data->prop = prop; + it_data->input_handler_type = input_handler_type; + Eo *prop_box = _simple_prop_item_content_get(it_data, simple_op_desc_name_get(simple_op_desc)); + eo_event_callback_add(prop_box, EO_BASE_EVENT_DEL, _it_data_free_cb, it_data); + //elm_obj_box_pack_end(_simple_properties_box, prop_box); + elm_obj_box_pack_end(section_box, prop_box); + } + } + } +} + diff --git a/src/bin/gui/simple_propview.h b/src/bin/gui/simple_propview.h new file mode 100644 index 0000000..8b6bc94 --- /dev/null +++ b/src/bin/gui/simple_propview.h @@ -0,0 +1,14 @@ +#ifndef _SIMPLE_PROPVIEW_H +#define _SIMPLE_PROPVIEW_H + +#include <Eo.h> + +void +simple_propview_init(); + +void +simple_propview_shutdown(); + +void +simple_propview_build(const Gui_Widget *wdg); +#endif diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 2591e1b..88c874e 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -12,6 +12,7 @@ LIST(APPEND GUI_PARSER_CC_SOURCES plugin_C.c undoredo.c updater.c + desc_simple_parser.c ) LIST(APPEND ESPION_CC_SOURCES diff --git a/src/lib/database.c b/src/lib/database.c index eb227ce..8de7cda 100644 --- a/src/lib/database.c +++ b/src/lib/database.c @@ -19,6 +19,8 @@ #include "elm_interface_atspi_accessible.eo.h" #include "elm_interface_atspi_window.eo.h" +#include "desc_simple_parser.h" + static int _db_log_dom = -1; static Eina_Bool _db_init_count = 0; @@ -45,6 +47,33 @@ struct _Op_Desc Eina_Bool is_constructor; }; +/* Simple op description: + * - input handler type; + * - list of original op descriptions with mapping rules*/ +struct _Simple_Op_Desc +{ + Eina_Stringshare *section_name; + Eina_Stringshare *simple_op_name; + Simple_Op_Handler_Type input_handler_type; + Eina_List *original_op_desc; + + /* Info about additional settings on handler. + * Like min, max, step, etc + * Actually it must be implemented in Original_Op_Desc per parameter. */ + void *data; + void (*_data_free_cb)(void *data); +}; + +struct _Original_Op_Desc +{ + Op_Desc *op_desc; + Eina_List *params_mapping_array; /* Parameters mapping array - list of Gui_Value */ + Eina_List *classes; /* List of classes this op_desc active for. List of Eina_Stringshare */ + + /* Pointer to data in Simple op desc. */ + const void *data; +}; + struct _Container_Desc { Op_Desc *_op_pack; @@ -96,6 +125,8 @@ static Eina_Hash *enum_table = NULL; /* ["ENUM_NAME"]->[{1}] */ static Eina_Hash *enum_types_table = NULL; /* ["Elm_Win_Type"]->[ELM_WIN_BASIC, ELM_WIN_DIALOG_BASIC, ..] */ static Eina_Hash *container_table = NULL; /* Hash ["Elm_Box"]-> struct describing container */ +static Eina_List *simple_op_list = NULL; /* List ["color"]-> struct describing mapping of simple into real property */ + static char *gui_type_names[] = { "GUI_TYPE_ZERO", @@ -1228,6 +1259,8 @@ db_init(const char *db_path, const char *all_eo_path, const char *black_list) eina_hash_free(typedef_table); + simple_op_parser_db_init(PACKAGE_DATA_DIR"/config/simple_op_db.txt"); + return EINA_TRUE; } @@ -1237,6 +1270,12 @@ db_shutdown() if (--_db_init_count > 0) return EINA_TRUE; + Simple_Op_Desc *s_op_desc; + EINA_LIST_FREE(simple_op_list, s_op_desc) + { + simple_op_desc_del(s_op_desc); + } + eina_hash_free(cl_table); eina_hash_free(enum_table); eina_hash_free(enum_types_table); @@ -1625,3 +1664,214 @@ db_op_desc_is_constructor(const Op_Desc *op_desc) { return (op_desc ? op_desc->is_constructor : EINA_FALSE); } + +static Simple_Op_Desc * +_simple_op_desc_find(const char *_simple_op_name) +{ + Eina_List *itr; + Simple_Op_Desc *ret = NULL, *s_op_desc; + Eina_Stringshare *simple_op_name; + + char *_simple_op_name_lower = strdup(_simple_op_name); + //eina_str_tolower(&_simple_op_name_lower); + simple_op_name = eina_stringshare_add(_simple_op_name_lower); + + EINA_LIST_FOREACH(simple_op_list, itr, s_op_desc) + { + if (simple_op_name == s_op_desc->simple_op_name) + { + ret = s_op_desc; + break; + } + } + + free(_simple_op_name_lower); + eina_stringshare_del(simple_op_name); + return ret; +} + +/* Get list of all Simple Op Descs in order it was added, + * t.e. database order. */ +const Eina_List * +simple_op_desc_list_get() +{ + return simple_op_list; +} + +/* Returns Simple_Op_Desc for op_name. + * If op description doesn't exist it will be created + * for lower cased name. */ +Simple_Op_Desc * +simple_op_desc_get(const char *_simple_op_name) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(_simple_op_name, NULL); + Simple_Op_Desc *ret = NULL; + + ret = _simple_op_desc_find(_simple_op_name); + + if (!ret) + { + char *_simple_op_name_lower = strdup(_simple_op_name); + //eina_str_tolower(&_simple_op_name_lower); + + ret = calloc(1, sizeof(Simple_Op_Desc)); + ret->simple_op_name = eina_stringshare_add(_simple_op_name_lower); + simple_op_list = eina_list_append(simple_op_list, ret); + + free(_simple_op_name_lower); + } + return ret; +} + +static void +_simple_op_desc_data_set(Simple_Op_Desc *simple_op_desc, void *data, void (*_data_free_cb)(void *data)) +{ + EINA_SAFETY_ON_NULL_RETURN(simple_op_desc); + simple_op_desc->data = data; + simple_op_desc->_data_free_cb = _data_free_cb; +} + +void * +simple_op_desc_data_get(Simple_Op_Desc *simple_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(simple_op_desc, NULL); + return simple_op_desc->data; +} + +static void +_simple_op_desc_data_del(Simple_Op_Desc *simple_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN(simple_op_desc); + if (simple_op_desc->data && simple_op_desc->_data_free_cb) + { + simple_op_desc->_data_free_cb(simple_op_desc->data); + } + simple_op_desc->data = NULL; + simple_op_desc->_data_free_cb = NULL; +} + +/* Delete Simple_Op_Desc */ +void +simple_op_desc_del(Simple_Op_Desc *s_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN(s_op_desc); + Eina_Stringshare *class_name; + Original_Op_Desc *o_op_desc; + + EINA_LIST_FREE(s_op_desc->original_op_desc, o_op_desc) + { + EINA_LIST_FREE(o_op_desc->classes, class_name) + { + eina_stringshare_del(class_name); + } + + Gui_Value *gui_value; + EINA_LIST_FREE(o_op_desc->params_mapping_array, gui_value) + { + gui_value_type_set(gui_value, GUI_TYPE_SINT); + gui_value_del(gui_value); + } + free(o_op_desc); + } + + eina_stringshare_del(s_op_desc->section_name); + eina_stringshare_del(s_op_desc->simple_op_name); + _simple_op_desc_data_del(s_op_desc); + free(s_op_desc); +} + +/* Set input handler type for current Simple Op*/ +void +simple_op_desc_input_handler_type_set(Simple_Op_Desc *simple_op_desc, Simple_Op_Handler_Type input_handler_type) +{ + EINA_SAFETY_ON_NULL_RETURN(simple_op_desc); + simple_op_desc->input_handler_type = input_handler_type; + + _simple_op_desc_data_del(simple_op_desc); + if (input_handler_type == SIMPLE_OP_HANDLER_SLIDER) + { + Simple_View_Slider_Data *p = calloc (1, sizeof(Simple_View_Slider_Data)); + _simple_op_desc_data_set(simple_op_desc, p, free); + } +} + +/* Get input handler type for current Simple Op*/ +Simple_Op_Handler_Type +simple_op_desc_input_handler_type_get(Simple_Op_Desc *simple_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(simple_op_desc, SIMPLE_OP_HANDLER_NONE); + return simple_op_desc->input_handler_type; +} + +/* Get list of original ops from Simple Op Desc */ +const Eina_List * +simple_op_desc_original_ops_list_get(Simple_Op_Desc *simple_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(simple_op_desc, NULL); + return simple_op_desc->original_op_desc; +} + +/* Set section name from Simple Op Desc */ +void +simple_op_desc_section_name_set(Simple_Op_Desc *simple_op_desc, const char *name) +{ + EINA_SAFETY_ON_NULL_RETURN(simple_op_desc); + eina_stringshare_del(simple_op_desc->section_name); + simple_op_desc->section_name = eina_stringshare_add(name); +} + +/* Get section name from Simple Op Desc */ +Eina_Stringshare* +simple_op_desc_section_name_get(Simple_Op_Desc *simple_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(simple_op_desc, NULL); + return simple_op_desc->section_name; +} + +/* Get simple op name from Simple Op Desc */ +Eina_Stringshare* +simple_op_desc_name_get(Simple_Op_Desc *simple_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(simple_op_desc, NULL); + return simple_op_desc->simple_op_name; +} + +/* Push original op data into simple op descriptor */ +void +simple_op_desc_data_push(Simple_Op_Desc *simple_op_desc, Op_Desc *_op_desc, Eina_List *params_mapping_array, Eina_List *classes) +{ + Original_Op_Desc *o_op_desc = calloc(1, sizeof(Original_Op_Desc)); + o_op_desc->op_desc = _op_desc; + o_op_desc->params_mapping_array = params_mapping_array; + o_op_desc->classes = classes; + o_op_desc->data = simple_op_desc->data; + simple_op_desc->original_op_desc = eina_list_append(simple_op_desc->original_op_desc, o_op_desc); +} + +const Op_Desc* +original_op_desc_get(const Original_Op_Desc *original_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(original_op_desc, NULL); + return original_op_desc->op_desc; +} + +const void* +original_op_data_get(const Original_Op_Desc *original_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(original_op_desc, NULL); + return original_op_desc->data; +} + +const Eina_List* +original_op_mapping_array_get(const Original_Op_Desc *original_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(original_op_desc, NULL); + return original_op_desc->params_mapping_array; +} + +const Eina_List* +original_op_classes_list_get(const Original_Op_Desc *original_op_desc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(original_op_desc, NULL); + return original_op_desc->classes; +} diff --git a/src/lib/database.h b/src/lib/database.h index 0e683c8..525db9c 100644 --- a/src/lib/database.h +++ b/src/lib/database.h @@ -54,6 +54,19 @@ typedef enum _Gui_Type GUI_TYPE_NONE } Gui_Type; +/* GUI_TYPE_IDX is int which is used in simple database, + * but no in FFI/eo_do infrastructure*/ +#define GUI_TYPE_IDX GUI_TYPE_NONE + 1 + +/* Input field type in Simple view*/ +typedef enum _Simple_Op_Handler_Type +{ + SIMPLE_OP_HANDLER_REGULAR, + SIMPLE_OP_HANDLER_COLORSELECTOR, + SIMPLE_OP_HANDLER_SLIDER, + SIMPLE_OP_HANDLER_NONE +} Simple_Op_Handler_Type; + typedef enum _Gui_Cb_Type { GUI_CB_USER, @@ -78,8 +91,17 @@ typedef struct char *value; /* Value for default value, t.e. -1.0 in case of EVAS_HINT_FILL */ } Param_Default_Value; +typedef struct +{ + double min; + double max; + double step; +} Simple_View_Slider_Data; + typedef struct _Op_Desc Op_Desc; typedef struct _Container_Desc Container_Desc; +typedef struct _Simple_Op_Desc Simple_Op_Desc; +typedef struct _Original_Op_Desc Original_Op_Desc; #define DB_DEF_PUBLIC "public" #define DB_DEF_PARENT "parent" #define DB_DEF_CLASS "class" @@ -298,4 +320,60 @@ db_op_desc_type_get(const Op_Desc *op_desc); Eina_Bool db_op_desc_is_constructor(const Op_Desc *op_desc); +/* Get list of all Simple Op Descs in order it was added, + * t.e. database order. */ +const Eina_List * +simple_op_desc_list_get(); + +/* Get section name from Simple Op Desc */ +Eina_Stringshare* +simple_op_desc_section_name_get(Simple_Op_Desc *simple_op_desc); + +/* Set section name from Simple Op Desc */ +void +simple_op_desc_section_name_set(Simple_Op_Desc *simple_op_desc, const char *name); + +/* Get simple op name from Simple Op Desc */ +Eina_Stringshare* +simple_op_desc_name_get(Simple_Op_Desc *simple_op_desc); + +/* Returns Simple_Op_Desc for op_name. + * If op description doesn't exist it will be created + * for lower cased name. */ +Simple_Op_Desc * +simple_op_desc_get(const char *_simple_op_name); + +/* Set input handler type for current Simple Op */ +void +simple_op_desc_input_handler_type_set(Simple_Op_Desc *simple_op_desc, Simple_Op_Handler_Type input_handler_type); + +/* Get input handler type for current Simple Op */ +Simple_Op_Handler_Type +simple_op_desc_input_handler_type_get(Simple_Op_Desc *simple_op_desc); + +const Eina_List * +simple_op_desc_original_ops_list_get(Simple_Op_Desc *simple_op_desc); + +/* Push original op data into simple op descriptor */ +void +simple_op_desc_data_push(Simple_Op_Desc *simple_op_desc, Op_Desc *_op_desc, Eina_List *params_mapping_array, Eina_List *classes); + +/* Delete Simple_Op_Desc */ +void +simple_op_desc_del(Simple_Op_Desc *s_op_desc); + +void * +simple_op_desc_data_get(Simple_Op_Desc *simple_op_desc); + +const Op_Desc* +original_op_desc_get(const Original_Op_Desc *original_op_desc); + +const void* +original_op_data_get(const Original_Op_Desc *original_op_desc); + +const Eina_List* +original_op_mapping_array_get(const Original_Op_Desc *original_op_desc); + +const Eina_List* +original_op_classes_list_get(const Original_Op_Desc *original_op_desc); #endif diff --git a/src/lib/desc_simple_parser.c b/src/lib/desc_simple_parser.c new file mode 100644 index 0000000..0e821e1 --- /dev/null +++ b/src/lib/desc_simple_parser.c @@ -0,0 +1,757 @@ +#include <Eina.h> +#include <unistd.h> +#include "desc_simple_parser.h" +#include "egui_log.h" +#include "database.h" +#include "gui_widget.h" + +#define DEBUG_PRINT 0 + +#if DEBUG_PRINT +#define DEBUG(msg, ...) printf((msg), ##__VA_ARGS__) +#else +#define DEBUG(msg, ...) do {} while(0); +#endif + +static struct _Ctx +{ + struct + { + const char *file; /* the input file to read UNUSED */ + FILE *fp; /* File descriptor handle */ + size_t file_size; /* File size UNUSED */ + char buf[30000]; /* read chunk buffer */ + size_t buf_size; /* size of read chunk */ + size_t buf_off; /* offset of the start of buffer in the file */ + size_t cur_pos; /* offset in file */ + } file_buf; + + enum + { + CTX_STATUS_NONE = 0, + CTX_STATUS_FILE_START = 1, + CTX_STATUS_FILE_DONE = 1 << 2, + CTX_STATUS_FILE_ERROR = 1 << 3, + CTX_STATUS_SYNTAX_ERROR = 1 << 4, + /* TODO: maybe more error types */ + } status; + + char *buf; + size_t pos; + char cur_char; + +} _ctx; + +/* Simple_Op Parse data */ +typedef struct _Handle_Type_Entry +{ + char *str; + Simple_Op_Handler_Type type; +} Handle_Type_Entry; + +Handle_Type_Entry _table_handlers[] = +{ + {"Regular", SIMPLE_OP_HANDLER_REGULAR}, + {"Color", SIMPLE_OP_HANDLER_COLORSELECTOR}, + {"Slider", SIMPLE_OP_HANDLER_SLIDER}, + { NULL, 0 } +}; + +static Simple_Op_Handler_Type +_parse_handler_str_to_type(const char *str) +{ + Simple_Op_Handler_Type type = SIMPLE_OP_HANDLER_NONE; + Handle_Type_Entry *pos = _table_handlers; + + while (pos->str) + { + if (!strncmp(pos->str, str, strlen(pos->str))) + { + type = pos->type; + break; + } + pos++; + } + + return type; +} + +static void +_buf_read_file(void) +{ + _ctx.file_buf.buf_size = fread(_ctx.file_buf.buf, 1, sizeof(_ctx.file_buf.buf), _ctx.file_buf.fp); + if (_ctx.file_buf.buf_size == 0) + { + _ctx.status = CTX_STATUS_FILE_DONE; + } + _ctx.buf = _ctx.file_buf.buf; + _ctx.pos = 0; +} + +static void +_open_file(const char *filename) +{ + FILE *fp; + + if (!filename) + { + ERR("No input file specified"); + _ctx.status = CTX_STATUS_FILE_ERROR; + return; + } + + + fp = fopen(filename, "r"); + if (!fp) + { + printf("Can not open file: \"%s\".\n", filename); + _ctx.status = CTX_STATUS_FILE_ERROR; + return; + } + + _ctx.file_buf.fp = fp; + _ctx.status = CTX_STATUS_FILE_START; + _buf_read_file(); +} + +static void +_ctxt_cleanup(void) +{ + /* TODO: cleanup _ctxt */ + if (_ctx.file_buf.fp) + { + fclose(_ctx.file_buf.fp); + _ctx.file_buf.fp = NULL; + } +} + +/* Parse code */ + +#define CUR_CHAR (_ctx.buf[_ctx.pos]) +#define CUR_OFF (_ctx.buf + _ctx.pos) +#define IGNORE(x) ((x) && (((x) == ' ') || ((x) == '\n'))) +#define ALPHA(x) ((((x) >= 'A') && ((x) <= 'Z')) || (((x) >= 'a') && ((x) <= 'z'))) +#define ALPHA_CLASS(x) (ALPHA(x) || ((x) == '.')) +#define NUM(x) (((x) >= '0') && ((x) <= '9')) +#define ANUM(x) (ALPHA(x) || (((x) >= '0') && ((x) <= '9'))) + +#define SHORT_SIZE 128 + +static void +_error_syntax_unknown_token(void) +{ + ERR("Syntax error: Unexpected character \"%c\". Aborting.", CUR_CHAR); + _ctx.status = CTX_STATUS_SYNTAX_ERROR; +} + +static void +_skip_ignores(void) +{ + while (IGNORE(CUR_CHAR)) + { + _ctx.pos++; + } +} + +static Eina_Bool +_is_alpha(char c) +{ + return ALPHA(c); +} + +static Eina_Bool +_is_anum(char c) +{ + return ANUM(c); +} + +static Eina_Bool +_is_num(char c) +{ + return NUM(c); +} + +static char * +_next_pat(Eina_Bool (*cmp)(char c), const char *extra) +{ + size_t pos; + size_t len; + char c; + char *ret = NULL; + + _skip_ignores(); + pos = _ctx.pos; + while ((c = _ctx.buf[pos])) + { + if (cmp(c) || strchr(extra, c)) + { + pos++; + } + else + { + break; + } + } + len = pos - _ctx.pos; + if (len > 0) ret = strndup(_ctx.buf + _ctx.pos, len); + _ctx.pos = pos; + + return ret; +} + +static char * +_next_word(const char *extra) +{ + size_t len; + char *str; + + len = strlen(extra) + 1; // for the "_" + str = calloc(1, len + 1); + strcat(str, "_"); + strcat(str, extra); + char *ret = _next_pat(_is_alpha, str); + free(str); + return ret; +} + +static Eina_Bool +_next_token(const char *str) +{ + size_t len = strlen(str); + size_t pos = _ctx.pos; + while(IGNORE(_ctx.buf[pos])) + { + pos++; + } + if (!strncmp(_ctx.buf + pos, str, len)) + { + _ctx.pos = pos; + _ctx.pos += len; + return EINA_TRUE; + } + return EINA_FALSE; +} + +static Eina_Bool +_next_keyword(const char *str) +{ + size_t len = strlen(str); + size_t pos = _ctx.pos; + + if (!IGNORE(CUR_CHAR)) + return EINA_FALSE; + + while(IGNORE(_ctx.buf[pos])) + { + pos++; + } + + if (!strncmp(_ctx.buf + pos, str, len) && IGNORE(_ctx.buf[pos + len])) + { + _ctx.pos = pos; + _ctx.pos += len + 1; + return EINA_TRUE; + } + return EINA_FALSE; +} + +static char * +_parse_string() +{ + char *start, *off; + + start = _ctx.buf + _ctx.pos; + + while ((off = &_ctx.buf[_ctx.pos++]) && *off) + { + if (*off == '\"') + { + return strndup(start, off - start); + } + } + + _error_syntax_unknown_token(); + + return NULL; +} + +static Eina_Bool +_is_str_num(const char *str) +{ + if (!str) return EINA_FALSE; + char c; + while ((c = *(str++))) + { + if (!NUM(c)) return EINA_FALSE; + } + return EINA_TRUE; +} + +static Eina_Bool +_is_str_alpha(const char *str) +{ + if (!str) return EINA_FALSE; + char c; + while ((c = *(str++))) + { + if (!ALPHA(c)) return EINA_FALSE; + } + return EINA_TRUE; +} + +static Gui_Value * +_parse_gui_idx(const char *str) +{ + Gui_Value *val; + val = _gui_value_new(); + gui_value_int_set(val, atoi(str)); + gui_value_type_set(val, GUI_TYPE_IDX); + return val; +} + +static Gui_Value * +_parse_gui_value(Op_Desc *od, size_t idx, const char *str, Eina_Bool is_lstr) +{ + Gui_Value *val = NULL; + Gui_Type type; + + val = _gui_value_new(); + type = db_op_desc_nth_par_type_get(od, idx); + switch (type) + { + case GUI_TYPE_SINT: + { + if (!_is_str_num(str)) + { + _error_syntax_unknown_token(); + goto end; + } + gui_value_int_set(val, atoi(str)); + break; + } + case GUI_TYPE_BOOL: + { + gui_value_bool_set(val, EINA_FALSE); + break; + } + case GUI_TYPE_DOUBLE: + { + gui_value_double_set(val, 0); + break; + } + case GUI_TYPE_ENUM: + { + if (!_is_str_alpha(str)) + { + _error_syntax_unknown_token(); + goto end; + } + gui_value_enum_set(val, NULL); + break; + } + case GUI_TYPE_STRING: + { + if (is_lstr) + { + gui_value_string_set(val, str); + } + else if (!strcmp("NULL", str)) + { + gui_value_string_set(val, NULL); + } + else + { + _error_syntax_unknown_token(); + goto end; + } + break; + } + case GUI_TYPE_FILE: + case GUI_TYPE_THEME: + case GUI_TYPE_OBJECT: + case GUI_TYPE_CB: + case GUI_TYPE_OBJECT_ITEM: + { + gui_value_name_id_set(val, type, 0); + break; + } + case GUI_TYPE_VOID: + { + gui_value_pointer_set(val, type, NULL); + break; + } + default: + ERR("%s: switch default for type: %s", + db_op_desc_op_name_get(od), db_gui_type_name_get(type)); + } +end: + if ((_ctx.status >= CTX_STATUS_FILE_ERROR)) + { + if (val) + { + free(val); + val = NULL; + } + } + return val; +} + +static Eina_List * +_parse_org_op_values(Op_Desc *od) +{ + Eina_List *ret = NULL; + Eina_Bool empty = EINA_FALSE; + size_t idx = 0; + + while (_ctx.status < CTX_STATUS_FILE_ERROR) + { + Gui_Value *val = NULL; + if (_next_token("%")) + { + char *str = _next_pat(_is_num, ""); + if (!str) + { + _error_syntax_unknown_token(); + goto end; + } + DEBUG("Parsing index value: %s\n", str); + val = _parse_gui_idx(str); + free(str); + } + else + { + char *str = NULL; + Eina_Bool is_lstr = EINA_FALSE; + + if (_next_token("\"")) + { + str = _parse_string(); + is_lstr = EINA_TRUE; + } + else + { + str = _next_pat(_is_anum, ""); + } + if (str) + { + DEBUG("Parsing gui value: %s, idx: %zu, literal string? %d\n", + str, idx, is_lstr); + val = _parse_gui_value(od, (unsigned long) idx, str, is_lstr); + } + if (!str) + { + if (empty) /* implies we had one pass due to "," */ + { + _error_syntax_unknown_token(); + } + empty = EINA_TRUE; + } + free(str); + } + + ret = eina_list_append(ret, val); + + if (_next_token(")")) + { + goto end; + } + else if (!empty && !_next_token(",")) + { + _error_syntax_unknown_token(); + } + idx++; + } +end: + return ret; +} + +static Eina_List * +_parse_org_op_classes(void) +{ + Eina_List *classes = NULL; + char *str; + while ((str = _next_word("."))) + { + classes = eina_list_append(classes, eina_stringshare_add(str)); + free(str); + if (!_next_token(",")) + break; + } + return classes; +} + +static Op_Desc * +_op_desc_get(const char *prop_full) +{ + Op_Desc *ret = NULL; + char *off, *class, *prop; + + off = strrchr(prop_full, '.'); + if (off && (off > prop_full)) + { + class = strndup(prop_full, (off - prop_full)); + prop = strdup(off + 1); + + ret = db_mro_op_desc_get(class, NULL, prop); + free(class); + free(prop); + } + return ret; +} + +#if DEBUG_PRINT +static void +_print_list_of_str(Eina_List *list) +{ + Eina_List *i; + char *s; + + printf("Listing contents\n"); + + EINA_LIST_FOREACH(list, i, s) + { + printf(" -> %s\n", s); + } +} +#endif + +static Eina_List * +_parse_none_classes(void) +{ + Eina_Bool cont = EINA_TRUE; + char *str; + Eina_List *classes = NULL; + + while (cont && (str = _next_word("."))) + { + classes = eina_list_append(classes, eina_stringshare_add(str)); + free(str); + if (!_next_token(",")) + { + cont = EINA_FALSE; + } + } + if (!_next_token(";")) + { + _error_syntax_unknown_token(); + } + + return classes; +} + +static void +_parse_org_op(Simple_Op_Desc *sop) +{ + char *str; + Op_Desc *od = NULL; + Eina_List *none_classes = NULL; + Eina_List *classes = NULL; + Eina_List *values = NULL; + + if (_next_keyword("none")) + { + none_classes = _parse_none_classes(); + simple_op_desc_data_push(sop, NULL, NULL, none_classes); +#if DEBUG_PRINT + printf("Black list set to sop %p:\n", sop); + _print_list_of_str(none_classes); +#endif + } + + str = _next_word("."); + if (str) + { + DEBUG("Creating original description: %s\n", str); + od = _op_desc_get(str); + free(str); + if (_next_token("(")) + { + values = _parse_org_op_values(od); + } + } + else + { + _error_syntax_unknown_token(); + goto end; + } + + if (_next_keyword("for")) + { + classes = _parse_org_op_classes(); +#if DEBUG_PRINT + DEBUG("Op_Desc applied to classes:\n"); + _print_list_of_str(classes); +#endif + } + + if (!_next_token(";")) + { + _error_syntax_unknown_token(); + } +end: + if (od) + { + simple_op_desc_data_push(sop, od, values, classes); + } +} + +static void +_parse_org_ops(Simple_Op_Desc *sop) +{ + while (_ctx.status < CTX_STATUS_FILE_ERROR) + { + if (_next_token("}")) + return; + + _parse_org_op(sop); + } +} + +static void +_parse_simple_op_desc(void) +{ + char *str; + Simple_Op_Desc *sop; + Simple_Op_Handler_Type type = SIMPLE_OP_HANDLER_REGULAR; + + str = _next_word("."); + if (!str) + { + _error_syntax_unknown_token(); + return; + } + + char *p = NULL, *section_name = NULL; + const char *simple_op_name = str; + if ((p = strchr(str, '.'))) + { + simple_op_name = p + 1; + section_name = strndup(str, p - str); + p = section_name; + while (*p) + { + if (*p == '_') *p = ' '; + p++; + } + } + + sop = simple_op_desc_get(simple_op_name); + simple_op_desc_section_name_set(sop, section_name); + DEBUG("Handling Simple Op %p (%s)\n", sop, simple_op_name); + free(str); + + if (_next_keyword("as")) + { + str = _next_word("_"); + if (!str) + { + _error_syntax_unknown_token(); + return; + } + type = _parse_handler_str_to_type(str); + free(str); + } + simple_op_desc_input_handler_type_set(sop, type); + if (type == SIMPLE_OP_HANDLER_SLIDER) + { + if (_next_token("(")) + { + double min = 0.0, max = 0.0, step = 0.0; + char *s = _next_pat(_is_num, "."); + if (!str) + { + _error_syntax_unknown_token(); + return; + } + min = atof(s); + free(s); + + if (!_next_token(",")) return; + s = _next_pat(_is_num, "."); + if (!str) + { + _error_syntax_unknown_token(); + return; + } + max = atof(s); + free(s); + + if (!_next_token(",")) return; + s = _next_pat(_is_num, "."); + if (!str) + { + _error_syntax_unknown_token(); + return; + } + step = atof(s); + free(s); + if (!_next_token(")")) return; + Simple_View_Slider_Data *sd = simple_op_desc_data_get(sop); + sd->min = min; + sd->max = max; + sd->step = step; + } + } + if (_next_token("{")) + { + _parse_org_ops(sop); + } + else + { + _error_syntax_unknown_token(); + } +} + +static void +_parse_next(void) +{ + while (_ctx.status < CTX_STATUS_FILE_ERROR) + { + _skip_ignores(); + if (!CUR_CHAR) + { + _ctx.status = CTX_STATUS_FILE_DONE; + return; + } + if ALPHA(CUR_CHAR) + { + _parse_simple_op_desc(); + } + else if (IGNORE(CUR_CHAR)) + { + _ctx.pos++; + } + else + { + _error_syntax_unknown_token(); + } + } +} + +/* Scan functions */ +static void +_parse_all(void) +{ + while (_ctx.status < CTX_STATUS_FILE_DONE) + { + _parse_next(); + } +} + +Eina_Bool +simple_op_parser_db_init(const char *path) +{ + memset(&_ctx, 0, sizeof(_ctx)); + _open_file(path); + + if (_ctx.status >= CTX_STATUS_FILE_ERROR) + { + goto end; + } + + _parse_all(); + +end: + _ctxt_cleanup(); + return EINA_TRUE; +} diff --git a/src/lib/desc_simple_parser.h b/src/lib/desc_simple_parser.h new file mode 100644 index 0000000..89bc7fd --- /dev/null +++ b/src/lib/desc_simple_parser.h @@ -0,0 +1,28 @@ +#ifndef DESC_SIMPLE_PARSER_H_ +#define DESC_SIMPLE_PARSER_H_ + +#include <Eina.h> + +/* This is a parser for simple descriptions for Erigo. + * + * A database entry of a Simple_Op_Desc: + * + * Simple_Op_Desc + * { + * List [ op_desc1, op_desc2 ], + * ViewData + * } + */ + +/* Populates a given database with given Description input file. + * @p path the simple of description input file to parse */ +Eina_Bool simple_op_parser_db_init(const char *path); + +/* Does cleanup and frees up data */ +void simple_op_parser_free(void); + +#if 1 +void simple_op_parser_file_test(void); +#endif + +#endif //DESC_SIMPLE_PARSER_H_ diff --git a/src/lib/gui_widget.c b/src/lib/gui_widget.c index fe3f95d..7cd4359 100644 --- a/src/lib/gui_widget.c +++ b/src/lib/gui_widget.c @@ -3063,6 +3063,17 @@ _gui_value_new() return val; } +int +_gui_value_idx_get(const Gui_Value *_val) +{ + int ret; + Gui_Value *val = GUI_VALUE(_val); + gui_value_type_set(val, GUI_TYPE_SINT); + ret = INT_GET(val); + gui_value_type_set(val, GUI_TYPE_IDX); + return ret; +} + Gui_Value * gui_value_copy(const Gui_Value *val_source) { diff --git a/src/lib/gui_widget.h b/src/lib/gui_widget.h index 133eea8..72c69f9 100644 --- a/src/lib/gui_widget.h +++ b/src/lib/gui_widget.h @@ -748,6 +748,9 @@ cb_modify(Gui_Widget_Callback *cb, const char *type, Eid *action_id); Gui_Value * _gui_value_new(); +int +_gui_value_idx_get(const Gui_Value *_val); + Gui_Value * gui_value_copy(const Gui_Value *gui_value); diff --git a/src/lib/test_simple_op.txt b/src/lib/test_simple_op.txt new file mode 100644 index 0000000..308dcfc --- /dev/null +++ b/src/lib/test_simple_op.txt @@ -0,0 +1,7 @@ + MyClass as Regular { + none Elm.Box; + Elm.Bg.color for Elm.Bg, Elm.Widget; + Efl.Gfx.Base.color(%1, %3, %2) for Evas.Object; + Elm.Widget.part_text(NULL, "hello", %1) for Elm.Entry; + Efl.Gfx.Base.size; + } --