summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYakov Goldberg <yakov.g@samsung.com>2015-01-07 15:35:13 +0200
committerYakov Goldberg <yakov.g@samsung.com>2015-01-07 15:35:13 +0200
commit0e9ce97b2008ab3416bdb6b5351f56e372946080 (patch)
treecaf459639a477c61e1ee9561bbe05c33834fbf14
parent2a66f400847cedcb70b8dd762b6b74ce934c032d (diff)
parent99ae9f22153166f9a51e713aeb557aa10edc56b1 (diff)
Merge branch 'develop'
-rw-r--r--AUTHORS2
-rw-r--r--CMakeLists.txt1
-rw-r--r--COPYING25
-rw-r--r--README482
-rw-r--r--TODO165
-rw-r--r--data/config/CMakeLists.txt1
-rw-r--r--data/config/egui_all.eo3
-rw-r--r--data/config/func_names.json171
-rw-r--r--data/images/CMakeLists.txt6
-rw-r--r--data/images/enventor_icon.pngbin0 -> 67812 bytes
-rw-r--r--data/images/erigo_icon.pngbin0 -> 5151 bytes
-rw-r--r--data/images/factory_layout.pngbin0 -> 1359 bytes
-rw-r--r--data/images/factory_naviframe.pngbin0 -> 8234 bytes
-rw-r--r--data/images/factory_toolbar.pngbin0 -> 18994 bytes
-rw-r--r--data/images/table_cell_border.pngbin0 -> 1033 bytes
-rw-r--r--examples/example.egui (renamed from examples/example.json)109
-rw-r--r--examples/logo.pngbin0 -> 81162 bytes
-rw-r--r--examples/main.c8
-rw-r--r--src/bin/CMakeLists.txt9
-rw-r--r--src/bin/egui_gui/CMakeLists.txt107
-rw-r--r--src/bin/egui_gui/cbview.c804
-rw-r--r--src/bin/egui_gui/cbview.h17
-rw-r--r--src/bin/egui_gui/contentview.c274
-rw-r--r--src/bin/egui_gui/contentview.h27
-rw-r--r--src/bin/egui_gui/descview.c126
-rw-r--r--src/bin/egui_gui/descview.h14
-rw-r--r--src/bin/egui_gui/dnd.c512
-rw-r--r--src/bin/egui_gui/dnd.h43
-rw-r--r--src/bin/egui_gui/editor.c3865
-rw-r--r--src/bin/egui_gui/egui_layout.json1054
-rw-r--r--src/bin/egui_gui/egui_layout_c.src1312
-rw-r--r--src/bin/egui_gui/egui_layout_h.src94
-rw-r--r--src/bin/egui_gui/egui_logic.c952
-rw-r--r--src/bin/egui_gui/egui_logic.h9
-rw-r--r--src/bin/egui_gui/egui_logic_private.h16
-rw-r--r--src/bin/egui_gui/itemview.c179
-rw-r--r--src/bin/egui_gui/itemview.h22
-rw-r--r--src/bin/egui_gui/key_bindings.c135
-rw-r--r--src/bin/egui_gui/key_bindings.h15
-rw-r--r--src/bin/egui_gui/objtree.c426
-rw-r--r--src/bin/egui_gui/objtree.h12
-rw-r--r--src/bin/egui_gui/prop_layout.c337
-rw-r--r--src/bin/egui_gui/prop_layout.h22
-rw-r--r--src/bin/egui_gui/props_helper.c389
-rw-r--r--src/bin/egui_gui/props_helper.h104
-rw-r--r--src/bin/egui_gui/propview.c975
-rw-r--r--src/bin/egui_gui/propview.h20
-rw-r--r--src/bin/egui_gui/propview_data.h77
-rw-r--r--src/bin/egui_gui/rmview.c419
-rw-r--r--src/bin/egui_gui/rmview.h7
-rw-r--r--src/bin/egui_gui/seqview.c557
-rw-r--r--src/bin/egui_gui/seqview.h14
-rw-r--r--src/bin/egui_gui/settings_view.c128
-rw-r--r--src/bin/egui_gui/settings_view.h9
-rw-r--r--src/bin/main.c12
-rw-r--r--src/lib/CMakeLists.txt23
-rw-r--r--src/lib/cxx_generator.eo16
-rw-r--r--src/lib/database.c262
-rw-r--r--src/lib/database.h30
-rw-r--r--src/lib/eina_json.c24
-rw-r--r--src/lib/ffi_abstraction.c95
-rw-r--r--src/lib/ffi_abstraction.h13
-rw-r--r--src/lib/ffi_glue.c176
-rw-r--r--src/lib/ffi_glue.h10
-rw-r--r--src/lib/generator.c2283
-rw-r--r--src/lib/generator.h25
-rw-r--r--src/lib/generator_interface.eo70
-rw-r--r--src/lib/gui_parser.c627
-rw-r--r--src/lib/gui_widget.c2475
-rw-r--r--src/lib/gui_widget.h671
-rw-r--r--src/lib/json_generator.c605
-rw-r--r--src/lib/json_generator.h8
-rw-r--r--src/lib/plugin_C.c3
-rw-r--r--src/lib/simulator.c199
-rw-r--r--src/lib/undoredo.c406
-rw-r--r--src/lib/undoredo.h71
76 files changed, 13286 insertions, 8873 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..de81c97
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
1Yakov Goldberg <yakov.goldberg@gmail.com>
2Daniel Zaoui <daniel.zaoui@yahoo.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ce9136f..be6c0a3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,6 +25,7 @@ find_package(Eo REQUIRED)
25find_package(Eolian REQUIRED) 25find_package(Eolian REQUIRED)
26find_package(Ecore REQUIRED) 26find_package(Ecore REQUIRED)
27find_package(Evas REQUIRED) 27find_package(Evas REQUIRED)
28find_package(Edje REQUIRED)
28find_package(Elementary REQUIRED) 29find_package(Elementary REQUIRED)
29find_package(Ffi REQUIRED) 30find_package(Ffi REQUIRED)
30 31
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..981ed1f
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,25 @@
1Copyright notice for Erigo:
2
3Copyright (C) 2013-2015 Yakov Goldberg and various contributors (see AUTHORS)
4
5All rights reserved.
6
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions are met:
9
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
17INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README b/README
index 87aad52..8412eec 100644
--- a/README
+++ b/README
@@ -1,245 +1,239 @@
1Aim: 1[Erigo v0.9]
2 Create user-friendly efl gui builder. 2
3 3[Links to read]
4Functions: 4 https://phab.enlightenment.org/w/projects/gui_builder/
5 * Building Gui from scratch 5 http://yakov-g.blogspot.co.il/2013/04/egui-efl-gui-builder.html
6 * Emulate gui behavior without compilation 6
7 * Code generating with embedded json comments (or separate file with json) 7
8 8[Erigo - EFL GUI Builder]
9Features: 9
10 * Values validation (size >= 0) (should we make it in settings per widget) 10 Introducing Erigo (v.0.9) - the EFL gui builder.
11 * Integration with edje for theming 11It enables you easily create user interface for your application.
12 * Undo/redo management 12You can easily build multi-windowed application, simulate its behavior without compiling,
13 * Source code generation 13generate sources in different languages (currently C).
14 * Creating library of user's widgets, customize widgets 14
15 * Animations 15[Demo videos]
16 16
17Views / Functions / To remember: 17 https://www.youtube.com/watch?v=54lH4St9-8g
18 * Views: 18 https://www.youtube.com/watch?v=Y4RAKYKB-68
19 - Canvas 19
20 - Widgets view - displays set of available widgets 20[Compiling and installing]
21 - The Object Inspector - displays a hierarchical list of all the objects on the form 21 [Source Download]
22 that is currently being edited. 22 https://git.enlightenment.org/devs/yakov/egui.git/
23 - The Property Editor. Properties in hierarchical order. 23
24 24 [Dependencies]
25 * Tab order - change focus with pressing Tab 25 Mandatory:
26 * Copy/paste/cut/delete/clone + shortcuts 26 - CMake
27 * Find/replace/refactor (change name) + shortcuts 27 - FFI LIbrary (Ubuntu: sudo apt-get install libffi6 libffi6-dbg libffi-dev)
28 * Layouts / containers 28
29 * Translations 29 Non-Mandatory:
30 * Target device (layouts/resoltion/thumb size/available controls) 30 - Graphviz (Version > 2.35.00) - show application's graph.
31 * Callbacks for basic visual actions: "open/close..." 31
32 * Working modes: 32 [Building]
33 - GUI designer emulation/generation 33 $ cd egui
34 - Emulation without compilation (CLI) 34 $ mkdir build
35 - Export to another languages (CLI) 35 $ cd build
36 36 $ cmake ..
37 37 $ make
38JSON example 38
39 39 [Installing]
40/** 40 (run from "build" directory)
41 * @egui 41
42 * { 42 [Using Erigo]
43 * "win": { 43 [Command line]
44 * "parent" : "NULL", 44
45 * "class" : "ELM_OBJ_WIN_CLASS", 45 Start:
46 * "constructor" : ["elm_obj_win_constructor", "bg", 0], 46 $ ./src/bin/egui ../examples/example.egui
47 * "name" : "window", 47
48 * "title" : "window!!", 48 Simulation:
49 * "autodel" : 1, 49 $ ./src/bin/egui -s [Desktop/Phone/Tablet] ../examples/example.egui
50 * "size" : [320, 320], 50
51 * "visibility" : 1 51 Export to C ("filename.c" and "filename.h" will be generated):
52 * } 52 $ ./src/bin/egui -e c -o filename ../examples/example.egui
53 * } 53
54 * @!egui 54 Export to JSON ("filename" generated):
55 */ 55 $ ./src/bin/egui -e json -o filename ../examples/example.egui
56 56
57Issues / questions / internal design: 57 [User Interface]
58 * How to integrate callbacks 58 Top - Actions Toolbar:
59 59 - Project (New, Open, Save, Save As, Export, Close).
60 60 - Resource manager (Project's Resources - Images, Edge files, Callbacks, Strings).
61******************************************************************* 61 - Settings (Project's Settings - Project name, enter points, paths).
62**************** Blog article ************************************* 62 - Edit (Undo, Redo, Reload context).
63******************************************************************* 63 - View - show/hide, change view of windows.
64http://yakov-g.blogspot.co.il/2013/04/egui-efl-gui-builder.html 64 - Simulate - run application simulation on different targets.
65 65 - Graph - show application's graph.
66Gui Builder first example. 66 Left:
67 67 - Widgets factory - Drag`n`Drop supported
68 68 Right:
69We want to create Gui_Bulder which will implement all main gui creator's functionality and also will support 69 - Objects Tree View;
70simulation and generation modes from command line. 70 - Properties view with Description, Properties, Callbacks and Content tabs.
71 71 Center - Main canvas.
72Here I'm going to describe how we are going to do this. 72
73 73 [Resource manager]
74So let's start.. 74 Resource Manager allows you to add such resources as images, edge files,
75 75 callbacks and strings, assign alias name and later use in application design.
76Main idea is that we don't want to have large hard-to-read resource file. 76 In order to add resource, switch to desired tab, fill in fields at the bottom,
77We want to put json comments right into c file. (Anyway we can put all the comments into separate file) 77 when it is possible you can use file selection dialog (press "..."). In the end press "Add Resource" button.
78 78 In order to edit resouce: change desired fields and press "Save" button.
79/* @egui 79 To delete resource: press "del" button.
80{ 80
81 "main_win": 81 [Project Settings]
82 { 82 Set Project name - used in structure's, function's, variable's names in generated code.
83 "Desc": 83 Set Images prefix name: - give the name of define which will provide prefix path for app's images.
84 { 84 Set Start Points - define main objects which will be created on application start.
85 "parent":null, 85
86 "class":"Elm_Win", 86 [Object tree view]
87 "public":true, 87 Objtree shows items with it's children.
88 "type":"widget" 88 Search string allows to filter widgets by name.
89 }, 89
90 "Properties": 90 [Property View]
91 { 91 Property view provides detailed information about widgets.
92 "constructor":["elm_obj_win_constructor"], 92 It contains four tabs: Description, Properties, Callbacks, Content.
93 "elm_obj_win_constructor":[null, "ELM_WIN_BASIC"], 93 Search string allows to filter properties by name and fields contain popup hints - just put mouse over it.
94 "title":["Egui is Cool! - Autogenerated"], 94
95 "autodel":[true], 95 Description tab contains following fields: class name (can not be changed), name, public property.
96 "size":[1000, 650], 96 When widget is marked as "public" it will be accessible in generated code.
97 "resize_object_add":["main_bg"], 97
98 "resize_object_add":["main_box"], 98 Properties tab shows properties grouped by class in inheritance order.
99 "visibility":[true] 99 Properties colored in grey are properties, which were not changed by user and they show default values,
100 } 100 whereas properties colored in white were changed by user.
101 } 101 They can be dropped by clicking "Menu" button and choosing "Drop Property".
102 } 102 Some properties such as ("Size Hint Weight", "Size Hint Align") have predefined(aliased) set of values,
103@!egui */ 103 which can be accessed by pressing on "..." button next to property value.
104 main_win = eo_add_custom(ELM_OBJ_WIN_CLASS, NULL, elm_obj_win_constructor(NULL, ELM_WIN_BASIC)); 104
105 eo_unref(main_win); 105 Callbacks tab shows callbacks supported by widget. The list is sorted by inheritance order.
106 pub_widgets.main_win = main_win; 106 Callbacks can be assigned with next actions: "Modify", "Create", "Invoke".
107 eo_do(main_win, elm_obj_win_title_set("Egui is Cool!")); 107
108 eo_do(main_win, elm_obj_win_autodel_set(EINA_TRUE)); 108 "Modify" - this action changes a property of desired object.
109 eo_do(main_win, evas_obj_size_set(1000, 650)); 109 First you choose "Modify" action, then you choose an object - one of the widgets defined in the project.
110 eo_do(main_win, elm_obj_win_resize_object_add(main_bg)); 110 Then you can choose a property from the list of supported and finally fill in values.
111 eo_do(main_win, elm_obj_win_resize_object_add(main_box)); 111
112 eo_do(main_win, evas_obj_visibility_set(EINA_TRUE)); 112 "Create" - this action allows to invoke creation of one of main objects.
113 113 After you choose "Create", choose main object to create and it's parent.
114 In this example, "main_win" is widgets, 114 Example: You have two main object: "Window 1" and "Window 2". "Window 1" is created when application is launched.
115 "parent", "public", "size" etc - are properties 115 You want "Window 2" to be created when "Button" is clicked in "Window 1".
116 116 You need to open "Callbacks" tab for "Button" object. Extend class "Evas.CLickable_Interface",
117 Different properties can be seen in json. 117 for "clicked" event choose "Create", select "Window 2" as first parameter and leave the second parameter empty,
118 Some of them are shorter names of well-known evas/elementary functions, 118 because we want "Window 2" to be created next to "Window 1" (parent is NULL).
119 some are for internal builder needs. 119
120 like "public" - means that this widget should be accessible from outside. 120 "Invoke" - this action allows you to invoke user callback. User callback must be registered in Resource Manager.
121 121
122 As soon as there is such data, it's possible to parse json, save data and later simulate 122 Content tab - allows to manage content according to class of selected windget.
123 current gui's behavior or generate sources in desired language. 123 Erigo defines following types of containers:
124 124 - Pack containers: Box, Table.
125 125 - Resize object containers: Window.
126 How do we get such names of properties? 126 - Part containers: (according to "part_content_set" function): Button, Check, Radio, Actionslider, Clock,
127 Gui Builder is based on Eo (EFL object oriented model). 127 Dayseelctor, Calendar, Colorselector, Bubble, Entry, Flip, Layout
128 Currently each Evas object or Elementary widget are implemented using Eo. 128 - Item containers (Item widgets): Menu, Diskselector, Ctxpopup, Toolbar, Naviframe.
129 So widget's class name also provided in json. 129 Content view contains different control elements depending on type of selected widget.
130 130
131 During simulation and source code generation proper function is fetched from 131 [Graph view]
132 internal Gui Builders database according to property name and widget's class name. 132 Erigo allows you to build graph of your application. Press "Graph" button to open Graph View window.
133 133
134 What is internal Gui Builder's database? 134 [Project menu]
135 We have a script which searches for all data (functions, parameters, types, etc) 135
136 of all classes in provided paths. (all Elementary widgets, etc). 136 "New Project" - create new project.
137 Only needed data(based on gui_db.in) will be selected and database for Gui Builder 137 Click "New Project" menu item to open "New Project" dialog.
138 will be generated. 138 Type in project name, select project folder or type new folder name. Click "Ok".
139 139 Project file will be created in selected folder.
140 Currently "gui_db.in" looks like this. 140 For project name "New Project" project file will be created with name "new_project".
141 141
142 ************************************************************ 142 "Save" - save project file. Also "Ctrl + S" key combination can be usde.
143 gui_db.in 143
144 ************************************************************ 144 "Save As" - save project file as.
145 OPERATIONS = 145 Click "Save As" menu item to save project in different file. In opened dialog select folder and enter file name.
146 evas_obj_color,set:color_set: 146 Click "Ok."
147 evas_obj_size_set:size_set: 147 Also "Ctrl + Shift + S" key combination can be used.
148 evas_obj_position,set:position_set: 148
149 evas_obj_size_hint_weight,set:size_hint_weight_set 149 "Export" - option allows you to generate C source code.
150 evas_obj_visibility_set:visibility_set 150 Click "Export" choose folder and enter "filename". "filename.c" and "filename.h" files will be generated.
151 elm_obj_bg_color_set:bg_color_set 151
152 elm_obj_win_title_set:title_set 152 Close project - closes current project.
153 elm_obj_win,autodel_set:autodel_set 153
154 elm_obj_win_resize_object_add:resize_object_add 154 [Editing]
155 elm_wdg_part_text_set: part_text_set 155 Erigo supports all conventional ways of editing in gui builders: drag and drop, moving and resizing,
156 elm_obj_win_constructor: 156 properties and containers editing.
157 elm_obj_container_content_set:content_set 157
158 ; 158 Select object by clicking it on canvas or by selecting it in Object View.
159 159 When object is selected green border is drawn around it. Now you can open Property view to review and change property's values,
160 CLASSES = 160 manage callbacks and containers. Object can be resized by dragging border's markers.
161 elm_win , 161 If object is packed into container, changing it's size/position may not have effect.
162 elm_button, 162
163 elm_bg, 163 Objects can be dragged and dropped around canvas. It can be dragged from factory to canvas, between containers,
164 elm_label, 164 between windows, from window to canvas(object becomes main) and from canvas to window(object stops being main).
165 elm_bubble, 165
166 ; 166 Erigo also supports undo/redo functionality. You can either use Undo/Redo buttons, or shortcuts "Ctrl + z", "Ctrl + Shift + z"
167 ************************************************************ 167
168 168 [Main Objects]
169 169 All objects which are located directly on canvas are main. Generally they are windows, but any other object also can be main.
170 CLASSES - literally widgets which will be known by Gui Builder. 170 It is useful when you want to have custom snippet which can be used in different places around the project.
171 OPERATIONS - functions which will be searched by script and mapped into Gui Builder property. 171 You build it as a main object and invoke its creation using "Create" action.
172 172
173 For example: "evas_obj_color,set:color_set" looks for every function, 173 [Using Edje]
174 which has parts "evas_obj_color" and "set" and stores it's data into hash. 174 You can use Edje objects in your project. It can be either compiled edj object or raw edc file.
175 175 If you use compiled edj object simply add it as a resource and use in "File" property.
176 In this case "evas_object_color_set" will be found in "Evas_Obj" class. 176 If you want to use raw edc file, add all its objects into your project's folder into consequent dirs: "images", "sounds", "fonts", "data".
177 Data about this func will be stored in a hash with key "class + property" {"Evas_Obj", "color_set"}. 177 In order to edit edc file you can start Enventor right from Resource Manager. When you save the changes, edc file will be automatically compiled and reloaded.
178 178
179 another example: 179 [Simulation]
180 Rule "_multi_select_set":"multi" 180 This feature allows you to test application behaviour without compiling.
181 will find two functions: "elm_obj_genlist_multi_select_set", "elm_obj_gengrid_multi_select_set" 181 Go to "Simulate->Create a new session..." submenu in toolbar and select target, which you want to run simulation on.
182 and store it into {"elm_genlist", "multi"} and {"elm_gengrid", "multi"}. 182 To finish simulation close all simulated windows or select "Simulation->Name of simulation->Kill".
183 When simulating, this property will be dispatched correctrly as soon as 183
184 "multi" belongs to classes in separate hierarchies. 184 [Key Shortcuts]
185 185 Following key shortcuts are currently available in Erigo.
186 But name clashes in the same hierarchy should be avoided. 186 "Crtl + z" - Undo.
187 for example: 187 "Crtl + Shift + z" - Redo.
188 "evas_obj_color_set" and "elm_obj_bg_color_set" both can be mapped into property "color_set". 188 "Ctrl + s" - Save.
189 Dispatch will work correctly, because functions belong to different classes, but user will have to remember, that 189 "Ctrl + Shift + s" - Save as.
190 "color_set" in backgroud widget receives three parameters and other widgets - four. 190 "Delete" - delete widget.
191 191
192 There can be other issues, and it's planned to use interfaces in such cases. 192 [Usecases]
193 193 [Creating new project - Add Window, Background, Box, Button]
194 194 Start Erigo with
195 Also, according to this database, widget's available properties will be displayed in "Property Inspector" of builder. 195 $ ./src/bin/erigo
196 196 Click "Project->New Project".
197 Checkout Egui: 197 Type in "Project Name", choose project folder and click "Ok". New project is created.
198 > git clone git://git.enlightenment.org/devs/yakov/egui.git 198
199 199 Drag "Window" widget from Factory to main canvas. Drag "Background" widget to Window.
200 Mandatory Requirements: 200 Select "Window" widget and open "Content" tab in Property view.
201 FFI library: 201 Set "Background" as Window's content. Background will be set as window's resize object.
202 In order to install it in Ubuntu: 202
203 > sudo apt-get install libffi6 libffi6-dbg libffi-dev 203 Drag "Box" widget to Window. Select "Window" widget and open "Content" tab in Property view.
204 204 Set "Box" as Window's content. Box will be set as window's resize object.
205 Non-mandatory requirements: 205
206 In order to be able to generate application's graph, which shows relations between 206 Drag and drop "Button" widget into the Box.
207 widgets, sequences and callbacks, Graphviz library (version > 2.35.00) is needed. 207 That's it!
208 208
209 In order to install it in Ubuntu: 209 [Adding image as a resource and apply it to background.]
210 > sudo apt-get install libgraphviz-dev libgvc6 210 Open "Resource manager" and switch to Images tab.
211 211 Fill in fields in the bottom: type in alias name,
212 Build: 212 press "..." button and select image file.
213 > cd egui 213 Press "Add resource" button. Close "Resource manager".
214 > mkdir build 214 Select background widget in you project. Open "Property" tab.
215 > cd build 215 Find "File" property in Efl.File subclass and select desired alias in dropdown list.
216 > cmake .. 216
217 > make 217 [Adding menu (or any itemed widget)]
218 Should be compiled without errors. 218 It will be shown on example of window's main menu. Each window widget has main menu, but it is not visible if has no items.
219 219 Select main menu in Object View and open Content tab in Property View.
220 Run simulation: 220 Tab has following buttons:
221 > ./src/bin/egui -f ../examples/example.c -s 221 "Add Item" - add new item after selected item.
222 222 "Add Subitem" - add subitem for selected item.
223 To see how this application look like on Phone or Tablet: 223 "Add Separator" - add separator after selected item
224 > ./src/bin/egui -f ../examples/example.c -s -t Tablet 224 "Delete Item" - not hard to guess :)
225 225 Add as many items as you need and set needed values. Put mouse over edit field in order to see tooltip.
226 Generate source code: 226
227 > ./src/bin/egui -f ../examples/example.c -e c -o new 227 [Working with edje]
228 - new.c and new.h will be generated in current dir 228 Add window widget on the canvas. Add layout to window and set it as window's resize object.
229 229 Add edje resource through Resource Manager. Open layout's "File" property and assign edje with needed part name.
230 Run simulation on newly generated file: 230
231 > ./src/bin/egui -f new.c -s 231 [Technical notes]
232 232 Current version is 0.9.
233 Run Gui Builder and open file: 233 ToDo:
234 > ./src/bin/egui -f new.c 234 - install script;
235 235 - fix drag and drop errors;
236 236 - add testing;
237 Also suggest name for this application, 237 - widgets multiselection and copy/paste;
238 We were thinking about "eline." 238 - cosmetics.
239
240 Waiting for your comments. :)
241
242
243
244
245 239
diff --git a/TODO b/TODO
index a357ed9..e6fc7c2 100644
--- a/TODO
+++ b/TODO
@@ -1,13 +1,9 @@
1Features: 1Features:
2-------- 2--------
3-1 User callbacks: 3User callbacks:
4 - add entries / user data has to be represented with a hoversel for the type + value 4- add entries / user data has to be represented with a hoversel for the type + value
5 - return value of the callback has to be an integer; condition can test the value and act differently 5
6 -1 0 and 1 accepted 6Containers generic support: box, menus...
7 -2 more values/nesting conditions
8-1 Containers generic support: box, menus...
9 - add support for opposite func for each packing operation
10
11 Issue: Menu container 7 Issue: Menu container
12 - need to avoid reloading of genlist, when adding item. 8 - need to avoid reloading of genlist, when adding item.
13 - maybe add manager_wdg_reload, which reloads eo without deleting wdg from objtree 9 - maybe add manager_wdg_reload, which reloads eo without deleting wdg from objtree
@@ -26,31 +22,15 @@ Features:
26 22
27 Need to add flag, which will forbid do content_set on NULL part. 23 Need to add flag, which will forbid do content_set on NULL part.
28 24
29 25Deletion by the user - have to register callback to set:
30-1 Deletion by the user - have to register callback to set:
31 - public widgets pointers as NULL in generator. 26 - public widgets pointers as NULL in generator.
32 - Eo pointers to NULL in simulator. 27 - Eo pointers to NULL in simulator.
33-1 Factory: add all the widgets / DnD 28
34-2 Espion: support parameters whose types can be double and defines 29Factory: add all the widgets
35-1 Resources manager: 30
36 - use it for images/edj/translations
37 - DB has to indicate property expects ResourceId and not filepath
38-2 When create new project, choose project type: desktop or mobile and depending on it provide usual window's menu or some mobile? 31-2 When create new project, choose project type: desktop or mobile and depending on it provide usual window's menu or some mobile?
39-1 Generator: 32
40 -1 come back on all the generation process 33Resource paths
41 -1 EFL++
42 -2 JS
43- Integration with:
44 -2 Eolian library:
45 - Egui invokes Eolian to determine if a property is a method or a property
46 - If property, request the Eo1/Eo2 get op id to retrieve info from the object
47 -2 Espion:
48 - via network (option in espion and in egui application importer menu)
49 - establish a protocol between them
50-2 Snippets
51- Support Edje files inside resources
52 - e.g IMAGE edje/group
53 - bg_file_set could take the resource (without group)
54- Need to add in project settings the local/installed path to the images (or something like that) 34- Need to add in project settings the local/installed path to the images (or something like that)
55 35
56Fixes: 36Fixes:
@@ -60,82 +40,44 @@ Fixes:
60 - Resize sub-windows according to application resolution 40 - Resize sub-windows according to application resolution
61 - Don't propagate events when selecting widget 41 - Don't propagate events when selecting widget
62- refactor _callbacks_expand (propview.c) 42- refactor _callbacks_expand (propview.c)
43- add Undo/Redo when resizing with dragging
44- Check resizing of main objects in different modes: dragging, from propview and other (if they exist)
45- Add memento when resizing/moving objects
46- fix propview (create property and change item from grey to white) when dragging
47- Add reordering (enable Up/Down buttons) for Table, because several objects can be packed into the same cell,
48 so we want to set one lower, and other upper
63 49
64Improvements: 50Improvements:
65------------ 51------------
66- Prettify the UI 52- Prettify the UI
67- stringshare 53- stringshare
68- need to think how handle _prop_new_value, which is outside of gui_widget 54- need to think how handle _prop_new_value, which is outside of gui_widget
69- wdg, cb, action, seq: ptr->id...
70- Have to improve the egui UI 55- Have to improve the egui UI
71 - goal: give an identity to egui -> recognizable just by the UI 56 - goal: give an identity to egui -> recognizable just by the UI
72 - theme: edc files proper to the application 57 - theme: edc files proper to the application
73 - entries to improve: min size... 58 - entries to improve: min size...
74- When DnD widget around canvas, bind it around objects.
75- add scroll_bars to layout windows, if actual size is larger than frame 59- add scroll_bars to layout windows, if actual size is larger than frame
76- DnD widget from one box to another; content_set, etc. 60- DnD widget from one box to another; content_set, etc.
77- _action_dep_resolve uses active_context_get() because there is no another way to find widget. 61- _action_dep_resolve uses active_context_get() because there is no another way to find widget.
78 62
79- Draw border around box and other containers, to see its size.
80- think about dependency in action's property
81- A lot of logs to add, it will help us to debug 63- A lot of logs to add, it will help us to debug
82 64
83Open issues:
84-----------
85- How to handle functions located in private H files?
86
87Known EFL bugs: 65Known EFL bugs:
88-------------- 66--------------
89- button: if size_set will be before part_text_set, text will be ellipsed!!! need some fixes in recalculation 67- button: if size_set will be before part_text_set, text will be ellipsed!!! need some fixes in recalculation
90- Sequence add: force panel show because RETURN key is propagated to panel
91- Hoversel with a lot of elements prevent access to those not displayed on the screen 68- Hoversel with a lot of elements prevent access to those not displayed on the screen
92 69
93Future: 70Future:
94------ 71------
95- Link to Eolian to retrieve description of functions (popup)
96- Generator: source files in different formats 72- Generator: source files in different formats
97- 3D representation of the exploded window: 73- 3D representation of the exploded window:
98 - shows every widget-layer of the win (win, containers, basic) created by the user 74 - shows every widget-layer of the win (win, containers, basic) created by the user
99- Evas objects 75- Evas objects
100- undo/redo: to implement this, we need to keep opposite operation for each method: like pack_end -> unpack
101 Moreover, if method receives several objects as parameters, we need to know, which parameter is subject and which is object.
102 T.e. pack_before(box, but2, but1) -> unpack(box, box2), here we need to remember, that oppossite for pack_before method (unpack)
103 must work with 1st parameter of pack_before, t.e. box2.
104- Recording scenario usable for automated tests and Tizen PLM issues:
105 - via espion or simulator? in simulator, button to record & run
106 - can we use Exactness?
107 - do we need to associate the scenario to an app?
108- Screenshot feature: 76- Screenshot feature:
109 - for tests, demos 77 - for tests, demos
110 - one jpeg per window 78 - one jpeg per window
111 - Exactness? 79 - Exactness?
112 80
113Miscellaneous:
114-------------
115- New code generation way (have to think if it can be better than now):
116 - User invokes application generation
117 - Context generation:
118 - Sequence BigBang generation:
119 - Prototype in buffer
120 - Check actions
121 - If action == create, check wdg created:
122 - yes? just generate call function to create the wdg in buffer.
123 - no? invoke wdg code generation and then do as yes
124 - Prototype in buffer
125 - Generate wdg creation code in buffer
126 - Walk on properties
127 - if dependence on not yet created widget, delay it
128 - otherwise generate property code
129 - Walk on callbacks
130 - if sequence already exists, just generate the callback add code into the buffer
131 - otherwise, invoke action generation.
132 - Check no delayed properties
133 - Walk on children and check existence
134 - yes? just generate call function to create the child in buffer.
135 - no? invoke child code generation and then do as yes
136 - Insert the buffer into the global context buffer
137 - If action == modif or user, just generate code into buffer.
138
139Add Instructions file: 81Add Instructions file:
140--------------------- 82---------------------
141- Install GraphViz: 83- Install GraphViz:
@@ -145,9 +87,74 @@ sudo apt-get install libgraphviz4
145sudo apt-get install libgraphviz-dev 87sudo apt-get install libgraphviz-dev
146 88
147 89
148- project settings: add some define -DMYAPPDATA, which will be used ads path to files (images) 90========== Undo / Redo ==========
149 so user will set this define in time of compilation 91
92struct Gui_Memento
93{
94 const Gui_Widget *wdg;
95 const Gui_Widget_Property *old_property;
96 const Gui_Widget_Property *new_property;
97 const Eina_List *old_containees_list;
98 const Eina_List *new_containees_list;
99};
100
1011. Stack, possible to do undo/redo. If after undo new action was made, drop redo items.
102
103stack item holds old/new property or old/new content list for undo/redo.
104Before/after operation need to save old/new property into this item.
105
106Stack
107--- item1 ---
108old: color(128)
109new: color(256)
110--- item2 ---
111old: size(10)
112new: size(20)
113--- item3 ---
114old: pack(obj1)
115new: pack(obj2)
116--- item4 ---
117
118Usual operation, doing something:
119 Before calling eo_do():
120 - create new Memento in stack
121 - save OLD_STATE
122 After eo_do():
123 - save NEW_STATE
124
125 Pointer points to current item.
126
127Undo:
128 Call eo_do() on OLD_STATE.
129 Move pointer to the previous item
130
131Redo:
132 Move pointer to the next item
133 Call eo_do() on NEW_STATE
134
1352. Delete widget
136 - Mark widget as pre_deleted (make it's ID - 0).
137 - Add pre_deleted flag to some place.
138 - Add code which checks if widget is pre_deleted, so don't do pack/ don't show in objtree.
139
140
141================================================
142
143 The window would be created outside of the GUI.
144 - Generation:
145 - Sequences: set their priority for cb_add as low, so when developer
146 adds his own callback from the code, he can easily cancel the next cbs
147 (i.e sequence).
148 - Create functions for every main object (wins, boxes) and add
149 parent as argument. The GUI structure will be specific to the main object.
150 - "GUI" cannot be the type of the struct.
151
152- Scroller in workspace: useful when you have many app windows. Add a
153 grid instead of the E bg.
154
155- Resource manager/strings: alias will be generated as macros
156 - Add alias and string. alias must be in capital letters.
157 - In entry..., use $alias to access it
158 - During generation, "#define ALIAS "string" and use ALIAS where it
159 has to.
150 160
151- func_json - redesining, read as json and use instead of db_dynamic
152- fill property view by calling get funcs for properties. Somehow mark if property wase changed by user or default is used
153- Add bubble over entries, which require Enter press
diff --git a/data/config/CMakeLists.txt b/data/config/CMakeLists.txt
index 023fccb..92faf77 100644
--- a/data/config/CMakeLists.txt
+++ b/data/config/CMakeLists.txt
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 2.8.1)
2 2
3LIST(APPEND CONFIG_FILES 3LIST(APPEND CONFIG_FILES
4 func_names.json 4 func_names.json
5 egui_all.eo
5 ) 6 )
6#always copy config files into build directory, so egui_cmd will be able to generate egui_auto 7#always copy config files into build directory, so egui_cmd will be able to generate egui_auto
7foreach (f ${CONFIG_FILES}) 8foreach (f ${CONFIG_FILES})
diff --git a/data/config/egui_all.eo b/data/config/egui_all.eo
new file mode 100644
index 0000000..ce89010
--- /dev/null
+++ b/data/config/egui_all.eo
@@ -0,0 +1,3 @@
1class EGUI_ALL (Elm_Win, Elm_Bg, Elm_Box, Elm_Table, Elm_Menu, Elm_Diskselector, Elm_Ctxpopup, Elm_Actionslider, Elm_Bubble, Elm_Button, Elm_Calendar, Elm_Check, Elm_Radio, Elm_Clock, Elm_Colorselector, Elm_Image, Elm_Icon, Elm_Label, Elm_Entry, Elm_Flip, Elm_Genlist, Elm_Gengrid, Elm_Dayselector, Elm_Toolbar, Elm_Layout, Elm_Scroller, Elm_Panes, Elm_Fileselector_Entry, Elm_Fileselector, Elm_Frame, Elm_Grid, Elm_Panel, Elm_Separator, Elm_Hoversel, Evas.Image, Elm_Naviframe)
2{
3}
diff --git a/data/config/func_names.json b/data/config/func_names.json
index c545231..9c11b73 100644
--- a/data/config/func_names.json
+++ b/data/config/func_names.json
@@ -1,4 +1,114 @@
1{ 1{
2 "DEFAULTS":
3 {
4 "Elm_Win":
5 {
6 "Evas.Object.size":[150, 100]
7 },
8 "Elm_Button":
9 {
10 "Elm_Widget.part_text":[null, "Button"],
11 "Evas.Object.size":[73, 30]
12 },
13 "Elm_Box":
14 {
15 "Evas.Object.size_hint_align":[-1.0, -1.0]
16 },
17 "Elm_Label":
18 {
19 "Elm_Widget.part_text":[null, "Label"],
20 "Evas.Object.size":[60, 30]
21 },
22 "Elm_Check":
23 {
24 "Elm_Widget.part_text":[null, "Check"],
25 "Evas.Object.size":[60, 30]
26 },
27 "Elm_Radio":
28 {
29 "Elm_Widget.part_text":[null, "Radio"],
30 "Evas.Object.size":[60, 30]
31 },
32 "Elm_Icon":
33 {
34 "Evas.Object.size":[40, 40]
35 },
36 "Elm_Image":
37 {
38 "Evas.Object.size":[40, 40]
39 },
40 "Elm_Actionslider":
41 {
42 "Elm_Widget.part_text":[null, "ActionSlider"],
43 "Evas.Object.size":[60, 30]
44 },
45 "Elm_Clock":
46 {
47 "Evas.Object.size":[40, 40]
48 },
49 "Elm_Dayselector":
50 {
51 "Evas.Object.size":[60, 45]
52 },
53 "Elm_Calendar":
54 {
55 "Evas.Object.size":[60, 45]
56 },
57 "Elm_Bubble":
58 {
59 "Evas.Object.size":[60, 45]
60 },
61 "Elm_Colorselector":
62 {
63 "Evas.Object.size":[60, 45]
64 },
65 "Elm_Entry":
66 {
67 "Elm_Widget.part_text":[null, "Entry"],
68 "Evas.Object.size":[60, 30]
69 },
70 "Elm_Flip":
71 {
72 "Evas.Object.size":[60, 30]
73 },
74 "Elm_Genlist":
75 {
76 "Evas.Object.size":[70, 60]
77 },
78 "Elm_Gengrid":
79 {
80 "Evas.Object.size":[70, 60]
81 },
82 "Elm_Table":
83 {
84 "Evas.Object.size":[70, 60]
85 },
86 "Elm_Menu":
87 {
88 "Evas.Object.size":[60, 30]
89 },
90 "Elm_Diskselector":
91 {
92 "Evas.Object.size":[60, 50]
93 },
94 "Elm_Ctxpopup":
95 {
96 "Evas.Object.size":[60, 40]
97 },
98 "Elm_Toolbar":
99 {
100 "Evas.Object.size":[60, 30]
101 },
102 "Elm_Naviframe":
103 {
104 "Evas.Object.size":[70, 60]
105 },
106 "Evas.Object":
107 {
108 "Evas.Object.size_hint_weight":[1.0, 1.0],
109 "Evas.Object.visibility":[true]
110 }
111 },
2 "OPERATIONS" : 112 "OPERATIONS" :
3 [ 113 [
4 { 114 {
@@ -46,15 +156,20 @@
46 "display_name" : "Visibility" 156 "display_name" : "Visibility"
47 }, 157 },
48 { 158 {
159 "class" : "Evas.Object",
160 "name" : "layer",
161 "display_name" : "Layer"
162 },
163 {
49 "class" : "Elm_Bg", 164 "class" : "Elm_Bg",
50 "name" : "color", 165 "name" : "color",
51 "display_name" : "Bg Color" 166 "display_name" : "Bg Color"
52 }, 167 },
53 { 168 {
54 "class" : "Elm_Bg", 169 "class" : "Efl.File",
55 "name" : "file", 170 "name" : "file",
56 "param" : [0, "GUI_TYPE_IMAGE"], 171 "param" : [0, "GUI_TYPE_FILE"],
57 "display_name" : "Bg File" 172 "display_name" : "File"
58 }, 173 },
59 { 174 {
60 "class" : "Elm_Win", 175 "class" : "Elm_Win",
@@ -74,7 +189,8 @@
74 { 189 {
75 "class" : "Elm_Win", 190 "class" : "Elm_Win",
76 "name" : "resize_object_add", 191 "name" : "resize_object_add",
77 "display_name" : "Resize Object" 192 "display_name" : "Resize Object",
193 "container_behavior_data":["OBJ_CONTAINER", "CONTAINER_PACK"]
78 }, 194 },
79 { 195 {
80 "class" : "Elm_Win", 196 "class" : "Elm_Win",
@@ -87,6 +203,11 @@
87 "display_name" : "Focus Highlight Enabled" 203 "display_name" : "Focus Highlight Enabled"
88 }, 204 },
89 { 205 {
206 "class" : "Elm_Win",
207 "name" : "icon_object",
208 "display_name" : "Icon"
209 },
210 {
90 "class" : "Elm_Widget", 211 "class" : "Elm_Widget",
91 "name" : "style", 212 "name" : "style",
92 "display_name" : "Style" 213 "display_name" : "Style"
@@ -196,12 +317,6 @@
196 }, 317 },
197 { 318 {
198 "class" : "Elm_Image", 319 "class" : "Elm_Image",
199 "name" : "file",
200 "param" : [0, "GUI_TYPE_IMAGE"],
201 "display_name" : "Image File"
202 },
203 {
204 "class" : "Elm_Image",
205 "name" : "resizable", 320 "name" : "resizable",
206 "display_name" : "Resizable" 321 "display_name" : "Resizable"
207 }, 322 },
@@ -322,11 +437,6 @@
322 "display_name" : "Padding" 437 "display_name" : "Padding"
323 }, 438 },
324 { 439 {
325 "class" : "Elm_Win",
326 "name" : "focus_highlight_enabled",
327 "display_name" : "Focus Highlight Enabled"
328 },
329 {
330 "class" : "Elm_Separator", 440 "class" : "Elm_Separator",
331 "name" : "horizontal", 441 "name" : "horizontal",
332 "display_name" : "Horizontal" 442 "display_name" : "Horizontal"
@@ -337,11 +447,6 @@
337 "display_name" : "Flip Go" 447 "display_name" : "Flip Go"
338 }, 448 },
339 { 449 {
340 "class" : "Elm_Layout",
341 "name" : "file",
342 "display_name" : "Layout File"
343 },
344 {
345 "class" : "Elm_Toolbar", 450 "class" : "Elm_Toolbar",
346 "name" : "shrink_mode", 451 "name" : "shrink_mode",
347 "display_name" : "Shrink Mode" 452 "display_name" : "Shrink Mode"
@@ -357,9 +462,35 @@
357 "display_name" : "Icon Size" 462 "display_name" : "Icon Size"
358 }, 463 },
359 { 464 {
465 "class" : "Elm_Toolbar",
466 "name" : "item_append",
467 "container_behavior_data":["ITEM_CONTAINER", "CONTAINER_PACK"]
468 },
469 {
360 "class" : "Elm_Hoversel", 470 "class" : "Elm_Hoversel",
361 "name" : "hover_parent", 471 "name" : "hover_parent",
362 "display_name" : "Hover Parent" 472 "display_name" : "Hover Parent"
473 },
474 {
475 "class" : "Elm_Naviframe",
476 "name" : "item_push",
477 "display_name" : "Item push",
478 "container_behavior_data":["ITEM_CONTAINER", "CONTAINER_PACK"]
479 },
480 {
481 "class" : "Elm_Naviframe",
482 "name" : "event_enabled",
483 "display_name" : "Event enabled"
484 },
485 {
486 "class" : "Elm_Naviframe",
487 "name" : "content_preserve_on_pop",
488 "display_name" : "Preserve on pop"
489 },
490 {
491 "class" : "Elm_Naviframe",
492 "name" : "prev_btn_auto_pushed",
493 "display_name" : "Prev button auto-pushed"
363 } 494 }
364 ] 495 ]
365} 496}
diff --git a/data/images/CMakeLists.txt b/data/images/CMakeLists.txt
index 28cebb4..c03c40f 100644
--- a/data/images/CMakeLists.txt
+++ b/data/images/CMakeLists.txt
@@ -24,6 +24,9 @@ LIST(APPEND FACTORY_IMAGES
24 factory_menu.png 24 factory_menu.png
25 factory_diskselector.png 25 factory_diskselector.png
26 factory_ctxpopup.png 26 factory_ctxpopup.png
27 factory_toolbar.png
28 factory_layout.png
29 factory_naviframe.png
27 resize_red.png 30 resize_red.png
28 canvas_bg.jpg 31 canvas_bg.jpg
29 icon_up_arrow.png 32 icon_up_arrow.png
@@ -32,6 +35,9 @@ LIST(APPEND FACTORY_IMAGES
32 icon_autoscroll.png 35 icon_autoscroll.png
33 icon_prop_menu.png 36 icon_prop_menu.png
34 icon_prop_menu2.png 37 icon_prop_menu2.png
38 erigo_icon.png
39 enventor_icon.png
40 table_cell_border.png
35 ) 41 )
36 42
37if (${EGUI_IS_RELEASE}) 43if (${EGUI_IS_RELEASE})
diff --git a/data/images/enventor_icon.png b/data/images/enventor_icon.png
new file mode 100644
index 0000000..af8fd2f
--- /dev/null
+++ b/data/images/enventor_icon.png
Binary files differ
diff --git a/data/images/erigo_icon.png b/data/images/erigo_icon.png
new file mode 100644
index 0000000..ab410cb
--- /dev/null
+++ b/data/images/erigo_icon.png
Binary files differ
diff --git a/data/images/factory_layout.png b/data/images/factory_layout.png
new file mode 100644
index 0000000..7541956
--- /dev/null
+++ b/data/images/factory_layout.png
Binary files differ
diff --git a/data/images/factory_naviframe.png b/data/images/factory_naviframe.png
new file mode 100644
index 0000000..047452a
--- /dev/null
+++ b/data/images/factory_naviframe.png
Binary files differ
diff --git a/data/images/factory_toolbar.png b/data/images/factory_toolbar.png
new file mode 100644
index 0000000..3fc13d8
--- /dev/null
+++ b/data/images/factory_toolbar.png
Binary files differ
diff --git a/data/images/table_cell_border.png b/data/images/table_cell_border.png
new file mode 100644
index 0000000..f6d97dd
--- /dev/null
+++ b/data/images/table_cell_border.png
Binary files differ
diff --git a/examples/example.json b/examples/example.egui
index e71ac99..07061ee 100644
--- a/examples/example.json
+++ b/examples/example.egui
@@ -1,66 +1,16 @@
1{ 1{
2 "Resources": 2 "JSON_Version":"2",
3 {
4 "Sequences":["BigBang", "button_show", "button_hide", "table_show", "table_hide"]
5 },
6 "Settings": 3 "Settings":
7 { 4 {
8 "Settings": 5 "project":"new_project",
9 { 6 "images_prefix":"",
10 "project":"new_project" 7 "start_points":["elm_win1"]
11 }
12 }, 8 },
13 "Sequences": 9 "Resources":
14 { 10 {
15 "button_show": 11 "Images":
16 {
17 "Desc":
18 {
19 },
20 "Actions":
21 {
22 "Modification":["elm_button1", "Evas.Object.visibility", [true]]
23 }
24 },
25 "button_hide":
26 {
27 "Desc":
28 {
29 },
30 "Actions":
31 {
32 "Modification":["elm_button1", "Evas.Object.visibility", [false]]
33 }
34 },
35 "table_show":
36 {
37 "Desc":
38 {
39 },
40 "Actions":
41 {
42 "Modification":["elm_table1", "Evas.Object.visibility", [true]]
43 }
44 },
45 "table_hide":
46 {
47 "Desc":
48 {
49 },
50 "Actions":
51 {
52 "Modification":["elm_table1", "Evas.Object.visibility", [false]]
53 }
54 },
55 "BigBang":
56 { 12 {
57 "Desc": 13 "logo":"/home/yakov/egui/examples/logo.png"
58 {
59 },
60 "Actions":
61 {
62 "Creation":"elm_win1"
63 }
64 } 14 }
65 }, 15 },
66 "Widgets": 16 "Widgets":
@@ -78,10 +28,9 @@
78 "Elm_Win.constructor":[null, "ELM_WIN_BASIC"], 28 "Elm_Win.constructor":[null, "ELM_WIN_BASIC"],
79 "Evas.Object.size":[514, 665], 29 "Evas.Object.size":[514, 665],
80 "Elm_Win.title":["elm_win1"], 30 "Elm_Win.title":["elm_win1"],
81 "Elm_Win.resize_object_add":["elm_bg1"],
82 "Elm_Win.resize_object_add":["elm_box1"],
83 "Elm_Win.autodel":[true] 31 "Elm_Win.autodel":[true]
84 } 32 },
33 "Contains":["elm_bg1", "elm_box1"]
85 }, 34 },
86 "elm_win1_main_menu": 35 "elm_win1_main_menu":
87 { 36 {
@@ -90,8 +39,6 @@
90 "parent":"elm_win1", 39 "parent":"elm_win1",
91 "class":"Elm_Menu" 40 "class":"Elm_Menu"
92 }, 41 },
93 "Properties":
94 {},
95 "Items": 42 "Items":
96 { 43 {
97 "elm_win1_main_menu_it0": 44 "elm_win1_main_menu_it0":
@@ -107,14 +54,14 @@
107 "type":"regular", 54 "type":"regular",
108 "icon":"fileopen", 55 "icon":"fileopen",
109 "label":"Show", 56 "label":"Show",
110 "callback":"button_show" 57 "callback":null
111 }, 58 },
112 "elm_win1_main_menu_it3": 59 "elm_win1_main_menu_it3":
113 { 60 {
114 "type":"regular", 61 "type":"regular",
115 "icon":"list-add", 62 "icon":"list-add",
116 "label":"Hide", 63 "label":"Hide",
117 "callback":"button_hide" 64 "callback":null
118 } 65 }
119 } 66 }
120 }, 67 },
@@ -131,14 +78,14 @@
131 "type":"regular", 78 "type":"regular",
132 "icon":"search", 79 "icon":"search",
133 "label":"Show", 80 "label":"Show",
134 "callback":"table_show" 81 "callback":null
135 }, 82 },
136 "elm_win1_main_menu_it5": 83 "elm_win1_main_menu_it5":
137 { 84 {
138 "type":"regular", 85 "type":"regular",
139 "icon":"fileopen", 86 "icon":"fileopen",
140 "label":"Hide", 87 "label":"Hide",
141 "callback":"table_hide" 88 "callback":null
142 } 89 }
143 } 90 }
144 } 91 }
@@ -205,7 +152,8 @@
205 "Contains": 152 "Contains":
206 { 153 {
207 "elm_button2":[0, 0, 1, 1], 154 "elm_button2":[0, 0, 1, 1],
208 "elm_button3":[1, 1, 1, 1] 155 "elm_button3":[1, 1, 1, 1],
156 "elm_image1":[1, 0, 1, 1]
209 } 157 }
210 }, 158 },
211 "elm_button2": 159 "elm_button2":
@@ -221,6 +169,10 @@
221 "Elm_Widget.part_text":[null, "elm_button2"], 169 "Elm_Widget.part_text":[null, "elm_button2"],
222 "Evas.Object.size_hint_weight":[1, 1], 170 "Evas.Object.size_hint_weight":[1, 1],
223 "Evas.Object.color":[0, 255, 0, 255] 171 "Evas.Object.color":[0, 255, 0, 255]
172 },
173 "Callbacks":
174 {
175 "clicked":["Modify", "elm_button1", "Evas.Object.visibility", [false]]
224 } 176 }
225 }, 177 },
226 "elm_button3": 178 "elm_button3":
@@ -236,7 +188,28 @@
236 "Elm_Widget.part_text":[null, "elm_button3"], 188 "Elm_Widget.part_text":[null, "elm_button3"],
237 "Evas.Object.size_hint_weight":[1, 1], 189 "Evas.Object.size_hint_weight":[1, 1],
238 "Evas.Object.color":[255, 255, 0, 255] 190 "Evas.Object.color":[255, 255, 0, 255]
191 },
192 "Callbacks":
193 {
194 "clicked":["Modify", "elm_button1", "Evas.Object.visibility", [true]]
195 }
196 },
197 "elm_image1":
198 {
199 "Desc":
200 {
201 "parent":"elm_table1",
202 "class":"Elm_Image"
203 },
204 "Properties":
205 {
206 "Elm_Widget.part_text":[null, "elm_image1"],
207 "Evas.Object.size_hint_weight":[1, 1],
208 "Evas.Object.visibility":[true],
209 "Efl.File.file":["logo", null],
210 "Evas.Object.size":[40, 40],
211 "Evas.Object.size_hint_align":[-1, -1]
239 } 212 }
240 } 213 }
241 } 214 }
242 } 215 } \ No newline at end of file
diff --git a/examples/logo.png b/examples/logo.png
new file mode 100644
index 0000000..7dbae67
--- /dev/null
+++ b/examples/logo.png
Binary files differ
diff --git a/examples/main.c b/examples/main.c
index 8809490..137ba40 100644
--- a/examples/main.c
+++ b/examples/main.c
@@ -12,9 +12,9 @@ Eina_Bool
12_bt_clicked(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description *desc, void *event_info) 12_bt_clicked(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description *desc, void *event_info)
13{ 13{
14 printf("my click \n"); 14 printf("my click \n");
15 eo_do(obj, elm_wdg_part_text_set(NULL, "Y")); 15 //eo_do(obj, elm_wdg_part_text_set(NULL, "Y"));
16 eo_do(obj, elm_wdg_part_text_set(NULL, "Ya")); 16 //eo_do(obj, elm_wdg_part_text_set(NULL, "Ya"));
17 eo_do(obj, elm_wdg_part_text_set(NULL, "Yak")); 17 //eo_do(obj, elm_wdg_part_text_set(NULL, "Yak"));
18 return EO_CALLBACK_CONTINUE; 18 return EO_CALLBACK_CONTINUE;
19} 19}
20 20
@@ -26,7 +26,7 @@ elm_main(int arg, char **argv)
26{ 26{
27 GUI *g; 27 GUI *g;
28 28
29 g = get_gui(); 29 g = project_name_gui_get();
30 elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); 30 elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
31 elm_run(); 31 elm_run();
32 elm_shutdown(); 32 elm_shutdown();
diff --git a/src/bin/CMakeLists.txt b/src/bin/CMakeLists.txt
index 20ea8cc..5b239bb 100644
--- a/src/bin/CMakeLists.txt
+++ b/src/bin/CMakeLists.txt
@@ -6,11 +6,11 @@ include_directories (${CMAKE_SOURCE_DIR}/src/bin/egui_gui)
6link_directories (${CMAKE_SOURCE_DIR}/src/lib) 6link_directories (${CMAKE_SOURCE_DIR}/src/lib)
7link_directories (${PC_LIBELEMENTARY_LIBRARY_DIRS}) 7link_directories (${PC_LIBELEMENTARY_LIBRARY_DIRS})
8 8
9set(TARGET egui_cmd) 9set(TARGET erigo_cmd)
10 10
11add_executable(${TARGET} main.c) 11add_executable(${TARGET} main.c)
12 12
13# this puts "/build_dir/data/config" path to egui_cmd 13# this puts "/build_dir/data/config" path to erigo_cmd
14set_property(TARGET ${TARGET} 14set_property(TARGET ${TARGET}
15 PROPERTY COMPILE_DEFINITIONS PACKAGE_DATA_DIR="${CMAKE_BINARY_DIR}/data") 15 PROPERTY COMPILE_DEFINITIONS PACKAGE_DATA_DIR="${CMAKE_BINARY_DIR}/data")
16include_directories( 16include_directories(
@@ -31,10 +31,9 @@ target_link_libraries (${TARGET}
31 pthread 31 pthread
32 ) 32 )
33 33
34# Save current dir because we want to know path to soutce file to build egui 34# Save current dir because we want to know path to soutce file to build erigo
35SET(EGUI_BINARY_SRC ${CMAKE_CURRENT_LIST_DIR}) 35SET(EGUI_BINARY_SRC ${CMAKE_CURRENT_LIST_DIR})
36# Save build path of egui_cmd, because we want to copy egui to the same folder 36# Save build path of erigo_cmd, because we want to copy egui to the same folder
37SET(EGUI_BINARY_BLD ${CMAKE_CURRENT_BINARY_DIR}) 37SET(EGUI_BINARY_BLD ${CMAKE_CURRENT_BINARY_DIR})
38 38
39add_subdirectory(egui_gui) 39add_subdirectory(egui_gui)
40#add_subdirectory(egui_auto)
diff --git a/src/bin/egui_gui/CMakeLists.txt b/src/bin/egui_gui/CMakeLists.txt
index 823c9cf..b784c9c 100644
--- a/src/bin/egui_gui/CMakeLists.txt
+++ b/src/bin/egui_gui/CMakeLists.txt
@@ -2,6 +2,11 @@ set(CMAKE_BUILD_TYPE Debug)
2 2
3find_package(Gvc QUIET) 3find_package(Gvc QUIET)
4find_package(CGraph QUIET) 4find_package(CGraph QUIET)
5find_program(ENVENTOR NAMES enventor)
6
7if (ENVENTOR)
8 add_definitions(-DHAVE_ENVENTOR)
9endif(ENVENTOR)
5 10
6if (GVC_FOUND AND CGRAPH_FOUND) 11if (GVC_FOUND AND CGRAPH_FOUND)
7 add_definitions(-DHAVE_GRAPHVIZ) 12 add_definitions(-DHAVE_GRAPHVIZ)
@@ -18,6 +23,7 @@ if (${EGUI_IS_RELEASE})
18 set(PACKAGE_IMAGES_DIR_DEFINITION PACKAGE_DATA_IMAGES="${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME_LOWER}/images") 23 set(PACKAGE_IMAGES_DIR_DEFINITION PACKAGE_DATA_IMAGES="${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME_LOWER}/images")
19elseif (NOT ${EGUI_IS_RELEASE}) 24elseif (NOT ${EGUI_IS_RELEASE})
20 set(PACKAGE_DATA_DIR_DEFINITION PACKAGE_DATA_DIR="${CMAKE_BINARY_DIR}/data") 25 set(PACKAGE_DATA_DIR_DEFINITION PACKAGE_DATA_DIR="${CMAKE_BINARY_DIR}/data")
26 set(PACKAGE_IMAGES_DIR_DEFINITION PACKAGE_DATA_IMAGES="${CMAKE_BINARY_DIR}/data/images")
21endif(${EGUI_IS_RELEASE}) 27endif(${EGUI_IS_RELEASE})
22 28
23#add -DGUI_MODE to build gui executable 29#add -DGUI_MODE to build gui executable
@@ -27,38 +33,25 @@ include_directories(
27 ${EINA_INCLUDE_DIRS} 33 ${EINA_INCLUDE_DIRS}
28 ${ECORE_INCLUDE_DIRS} 34 ${ECORE_INCLUDE_DIRS}
29 ${EVAS_INCLUDE_DIRS} 35 ${EVAS_INCLUDE_DIRS}
36 ${EDJE_INCLUDE_DIRS}
30 ${ELEMENTARY_INCLUDE_DIRS} 37 ${ELEMENTARY_INCLUDE_DIRS}
31 ${GVC_INCLUDE_DIRS} 38 ${GVC_INCLUDE_DIRS}
32 ${CGRAPH_INCLUDE_DIRS} 39 ${CGRAPH_INCLUDE_DIRS}
33 ) 40 )
34 41
35############################ 42include_directories(${CMAKE_CURRENT_BINARY_DIR})
36# building our stable egui
37# by copying files
38############################
39
40add_custom_target(delete_files
41 COMMENT "Deleting previously autogenerated \"egui_layout.c/h files\""
42 COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/egui_layout.*
43 )
44
45add_custom_target (generate_egui_layout_files
46 COMMENT "Copying egui_layout.c/h"
47 COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/egui_layout_c.src egui_layout.c
48 COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/egui_layout_h.src egui_layout.h
49 )
50 43
51add_custom_target (generate_egui_layout_files2 44add_custom_command(
45 OUTPUT egui_layout.c egui_layout.h
46 DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/egui_layout.json ${EGUI_BINARY_BLD}/erigo_cmd
52 COMMENT "Generating gui layout from JSON" 47 COMMENT "Generating gui layout from JSON"
53 COMMAND ${EGUI_BINARY_BLD}/egui_cmd -e c -o ./egui_layout ${CMAKE_CURRENT_SOURCE_DIR}/egui_layout.json 48 COMMAND ${EGUI_BINARY_BLD}/erigo_cmd -e c -o ./egui_layout ${CMAKE_CURRENT_SOURCE_DIR}/egui_layout.json
54 ) 49 )
55include_directories(${CMAKE_CURRENT_BINARY_DIR})
56# egui_layout.c/h files do not exist, so # OUTPUT files are listed in order to make CMake think,
57# that they will be generated.
58# Actually this command will never be called, because these files will be generated before by
59# "generate_egui_layout_files" targets.
60 50
61set(TARGET egui) 51############################
52# building egui using generated files
53############################
54set(TARGET erigo)
62 55
63add_executable(${TARGET} 56add_executable(${TARGET}
64 ${EGUI_BINARY_SRC}/main.c 57 ${EGUI_BINARY_SRC}/main.c
@@ -67,19 +60,19 @@ add_executable(${TARGET}
67 props_helper.c 60 props_helper.c
68 objtree.c 61 objtree.c
69 propview.c 62 propview.c
63 cbview.c
64 descview.c
65 contentview.c
66 prop_layout.c
70 itemview.c 67 itemview.c
71 seqview.c
72 rmview.c 68 rmview.c
73 settings_view.c 69 settings_view.c
74 editor.c 70 editor.c
75 ) 71 dnd.c
76add_custom_command( 72 key_bindings.c
77 OUTPUT egui_layout.c egui_layout.h
78 COMMENT "This message should not appear"
79 ) 73 )
80 74
81add_dependencies(generate_egui_layout_files delete_files) 75add_dependencies(${TARGET} erigo_cmd)
82add_dependencies(${TARGET} generate_egui_layout_files)
83 76
84set_property(TARGET ${TARGET} 77set_property(TARGET ${TARGET}
85 PROPERTY COMPILE_DEFINITIONS ${PACKAGE_DATA_DIR_DEFINITION} ${PACKAGE_IMAGES_DIR_DEFINITION}) 78 PROPERTY COMPILE_DEFINITIONS ${PACKAGE_DATA_DIR_DEFINITION} ${PACKAGE_IMAGES_DIR_DEFINITION})
@@ -89,68 +82,20 @@ target_link_libraries (${TARGET}
89 ${EINA_LIBRARIES} 82 ${EINA_LIBRARIES}
90 ${ECORE_LIBRARIES} 83 ${ECORE_LIBRARIES}
91 ${EVAS_LIBRARIES} 84 ${EVAS_LIBRARIES}
85 ${EDJE_LIBRARIES}
92 ${ELEMENTARY_LIBRARIES} 86 ${ELEMENTARY_LIBRARIES}
93 ${GVC_LIBRARIES} 87 ${GVC_LIBRARIES}
94 ${CGRAPH_LIBRARIES} 88 ${CGRAPH_LIBRARIES}
95 ecore_file 89 ecore_file
90 efl
96 pthread 91 pthread
97 ) 92 )
98 93
99#copy egui from /build/egui_gui/ to /build 94#copy egui from /build/egui_gui/ to /build
100add_custom_command (TARGET ${TARGET} 95add_custom_command (TARGET ${TARGET}
101 POST_BUILD 96 POST_BUILD
102 COMMENT "Post: Copying egui into usual build dir" 97 COMMENT "Post: Copying erigo into usual build dir"
103 COMMAND ${CMAKE_COMMAND} -E copy ${TARGET} ${EGUI_BINARY_BLD}/${TARGET} 98 COMMAND ${CMAKE_COMMAND} -E copy ${TARGET} ${EGUI_BINARY_BLD}/${TARGET}
104 #delete generated files
105 COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/egui_layout.*
106 ) 99 )
107 100
108install(TARGETS ${TARGET} DESTINATION bin) 101install(TARGETS ${TARGET} DESTINATION bin)
109
110############################
111# building our experimantal egui
112# by generating files
113############################
114set(TARGET2 egui_auto)
115
116add_executable(${TARGET2}
117 ${EGUI_BINARY_SRC}/main.c
118 egui_layout.c
119 egui_logic.c
120 props_helper.c
121 objtree.c
122 propview.c
123 itemview.c
124 seqview.c
125 rmview.c
126 settings_view.c
127 editor.c)
128
129# add this dependency to force build one after another,
130# in order to delete and generate files in proper order
131add_dependencies(generate_egui_layout_files2 delete_files)
132add_dependencies(generate_egui_layout_files2 egui_cmd)
133add_dependencies(generate_egui_layout_files2 egui)
134add_dependencies(${TARGET2} generate_egui_layout_files2)
135
136set_property(TARGET ${TARGET2}
137 PROPERTY COMPILE_DEFINITIONS ${PACKAGE_DATA_DIR_DEFINITION} ${PACKAGE_IMAGES_DIR_DEFINITION})
138
139target_link_libraries (${TARGET2}
140 guiparser
141 ${EINA_LIBRARIES}
142 ${ECORE_LIBRARIES}
143 ${EVAS_LIBRARIES}
144 ${ELEMENTARY_LIBRARIES}
145 ${GVC_LIBRARIES}
146 ${CGRAPH_LIBRARIES}
147 ecore_file
148 pthread
149 )
150
151#copy egui_auto from /build/egui_gui/tmp to /build
152add_custom_command (TARGET ${TARGET2}
153 POST_BUILD
154 COMMENT "Post: Copying egui_auto into usual build dir"
155 COMMAND ${CMAKE_COMMAND} -E copy ${TARGET2} ${EGUI_BINARY_BLD}/${TARGET2}
156 )
diff --git a/src/bin/egui_gui/cbview.c b/src/bin/egui_gui/cbview.c
new file mode 100644
index 0000000..da878fc
--- /dev/null
+++ b/src/bin/egui_gui/cbview.c
@@ -0,0 +1,804 @@
1
2#include <Elementary.h>
3#include <Eolian.h>
4
5#include "ffi_glue.h"
6#include "egui_log.h"
7#include "props_helper.h"
8#include "egui_logic_private.h"
9#include "cbview.h"
10
11#include "elm_widget_container.h"
12
13#define CACHE_CALLBACKS "CALLBACKS"
14
15static Elm_Genlist_Item_Class *_itc_cb = NULL;
16
17extern Elm_Genlist_Item_Class *_itc_class;
18extern Elm_Genlist_Item_Class *_itc_notfound;
19
20static Eo *cb_list = NULL;
21static Eo *propview_table = NULL;
22
23/* Hash table to keep the list of expanded classes */
24static Eina_Hash *expanded_classes = NULL;
25
26void
27cbview_item_selected_set(Eid *cb_eid)
28{
29 Elm_Object_Item *it = elm_genlist_first_item_get(cb_list);
30 for (; it; it = elm_genlist_item_next_get(it))
31 {
32 if (elm_genlist_item_item_class_get(it) != _itc_cb)
33 continue;
34
35 It_Data *it_data = elm_object_item_data_get(it);
36 if (cb_eid_get(it_data->cb) == cb_eid)
37 {
38 elm_genlist_item_selected_set(it, EINA_TRUE);
39 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
40 break;
41 }
42 }
43}
44
45static Eina_Bool
46_action_type_changed(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *event EINA_UNUSED, void *event_info)
47{
48 It_Data *it_data = data;
49 Gui_Widget_Callback *cb = it_data->cb;
50 Gui_Widget *wdg = (Gui_Widget *) it_data->wdg;
51 Gui_Context *ctx = (Gui_Context *) wdg_context_get(wdg);
52
53 Eid *action_id = cb_action_id_get(cb);
54 Gui_Action *new_action;
55 Gui_Action *old_action = action_get(action_id);
56 const char *type_as_string = elm_object_item_part_text_get(event_info, NULL);
57
58 if (!action_id)
59 {
60 new_action = action_new(ctx);
61 action_id = action_eid_get(new_action);
62 cb = cb_new_full(ctx, cb_type_get(cb), action_id);
63 const Callback_Container *cc_old = wdg_cb_container_get(wdg);
64 Callback_Container *cc_new = cc_old?cb_container_copy(cc_old):cb_container_new();
65 cb_container_cb_add(cc_new, cb);
66 Gui_Memento *memento = gui_memento_new(wdg_eid_get(wdg), MEMENTO_CALLBACK_ADD_DEL, (void *)cc_old, cc_new);
67 gui_context_memento_add(ctx, memento);
68
69 wdg_cb_container_unset(wdg);
70 wdg_cb_container_set(wdg, cc_new);
71 }
72 else
73 {
74 new_action = action_copy(action_id);
75 Gui_Memento *memento = gui_memento_new(action_id, MEMENTO_ACTION, old_action, new_action);
76 action_set(action_id, new_action);
77 gui_context_memento_add(ctx, memento);
78 }
79
80 Action_Type action_type = action_type_get_from_string(type_as_string);
81 switch (action_type)
82 {
83 case CREATION_ACTION:
84 {
85 action_creation_set(new_action, 0, NULL);
86 break;
87 }
88 case MODIF_ACTION:
89 {
90 action_modif_set(new_action, 0, NULL);
91 break;
92 }
93 case USER_ACTION:
94 {
95 action_user_set(new_action, 0, NULL);
96 break;
97 }
98 default: break;
99 }
100
101 cbview_build(it_data->wdg);
102 cbview_item_selected_set(cb_eid_get(cb));
103
104 return EO_CALLBACK_CONTINUE;
105}
106
107static void
108_action_wdg_selected(void *data, Eo *obj EINA_UNUSED, void *event_info)
109{
110 It_Data *it_data = data;
111 Gui_Widget_Callback *cb = it_data->cb;
112 Gui_Widget *wdg = (Gui_Widget *) it_data->wdg;
113 Gui_Context *ctx = (Gui_Context *) wdg_context_get(wdg);
114
115 Eid *action_id = cb_action_id_get(cb);
116 Gui_Action *action = action_get(action_id);
117 if (action)
118 {
119 Gui_Action *new_action = action_copy(action_id);
120 Gui_Memento *memento = gui_memento_new(action_id, MEMENTO_ACTION, action, new_action);
121 action_set(action_id, new_action);
122 gui_context_memento_add(ctx, memento);
123
124 const char *wdg_name = elm_object_item_part_text_get(event_info, NULL);
125 Eid *wdg_id = gui_context_eid_get_by_name(ctx, wdg_name);
126
127 Action_Type act_type = action_type_get(new_action);
128
129 if (act_type == CREATION_ACTION) action_creation_set(new_action, wdg_id, NULL);
130 if (act_type == MODIF_ACTION) action_modif_set(new_action, wdg_id, NULL);
131 }
132
133 cbview_build(it_data->wdg);
134 cbview_item_selected_set(cb_eid_get(cb));
135}
136
137static Eina_Bool
138_action_parent_selected(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
139{
140 It_Data *it_data = data;
141 Gui_Widget_Callback *cb = it_data->cb;
142 Gui_Widget *wdg = (Gui_Widget *) it_data->wdg;
143 Gui_Context *ctx = (Gui_Context *) wdg_context_get(wdg);
144
145 Eid *action_id = cb_action_id_get(cb);
146 Gui_Action *action = action_get(action_id);
147 if (action)
148 {
149 Gui_Action *new_action = action_copy(action_id);
150 Gui_Memento *memento = gui_memento_new(action_id, MEMENTO_ACTION, action, new_action);
151 action_set(action_id, new_action);
152 gui_context_memento_add(ctx, memento);
153
154 const char *parent_name = elm_object_item_part_text_get(event_info, NULL);
155 Eid *parent_id = gui_context_eid_get_by_name(ctx, parent_name);
156 action_creation_set(new_action, action_widget_id_get(new_action), parent_id);
157 }
158
159 cbview_build(it_data->wdg);
160 cbview_item_selected_set(cb_eid_get(cb));
161 return EO_CALLBACK_CONTINUE;
162}
163
164static Eina_Bool
165_action_user_cb_selected(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
166{
167 It_Data *it_data = data;
168 Gui_Widget_Callback *cb = it_data->cb;
169 Gui_Widget *wdg = (Gui_Widget *) it_data->wdg;
170 Gui_Context *ctx = (Gui_Context *) wdg_context_get(wdg);
171
172 Eid *action_id = cb_action_id_get(cb);
173 Gui_Action *action = action_get(action_id);
174 if (action)
175 {
176 Gui_Action *new_action = action_copy(action_id);
177 Gui_Memento *memento = gui_memento_new(action_id, MEMENTO_ACTION, action, new_action);
178 action_set(action_id, new_action);
179 gui_context_memento_add(ctx, memento);
180
181 const char *cb_name = elm_object_item_part_text_get(event_info, NULL);
182 Eid *cb_id = gui_context_eid_get_by_name(ctx, cb_name);
183 action_user_set(new_action, cb_id, NULL);
184 }
185
186 cbview_build(it_data->wdg);
187 cbview_item_selected_set(cb_eid_get(cb));
188 return EO_CALLBACK_CONTINUE;
189}
190
191static Eina_Bool
192_action_prop_selected(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
193{
194 It_Data *it_data = data;
195 Gui_Widget_Callback *cb = it_data->cb;
196 Gui_Context *ctx = (Gui_Context *) wdg_context_get(it_data->wdg);
197
198 Eid *action_id = cb_action_id_get(cb);
199 Gui_Action *action = action_get(action_id);
200 if (action)
201 {
202 const char *prop_name = elm_object_item_part_text_get(event_info, NULL);
203 char prop_namespace[PATH_MAX] = {'\0'};
204 unsigned int elements_count = 0;
205 char **_split_ret = NULL;
206
207 /* Splitting property name, because it can be: Evas.Object.visibility*/
208 _split_ret = eina_str_split_full(prop_name, CLASS_PROP_DELIMETER, 0, &elements_count);
209 /* If elements_count > 1, split succeeded, so save prop_namespace and prop_name,
210 * overwise property name only. */
211 if (elements_count == 1)
212 {
213 prop_name = _split_ret[0];
214 }
215 else
216 {
217 const char *func_name = _split_ret[elements_count - 1];
218 strncpy(prop_namespace, prop_name, strstr(prop_name, func_name) - prop_name - 1);
219 prop_name = _split_ret[elements_count - 1];
220 }
221
222 Eid *wdg_id = action_widget_id_get(action);
223
224 Gui_Widget *wdg = wdg_id ? wdg_get(wdg_id) : NULL;
225 Op_Desc *op = db_mro_op_desc_get(wdg_class_name_get(wdg), prop_namespace, prop_name);
226 Gui_Widget_Property *prop = prop_create_for_op(op);
227
228 Gui_Action *new_action = action_copy(action_id);
229 Gui_Memento *memento = gui_memento_new(action_id, MEMENTO_ACTION, action, new_action);
230 gui_context_memento_add(ctx, memento);
231
232 action_modif_set(new_action, wdg_id, prop);
233 action_set(action_id, new_action);
234
235 free(_split_ret[0]);
236 free(_split_ret);
237
238 cbview_build(it_data->wdg);
239 cbview_item_selected_set(cb_eid_get(cb));
240 }
241 return EO_CALLBACK_CONTINUE;
242}
243
244static Eina_Bool
245_action_item_selected(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
246{
247 It_Data *it_data = data;
248 Gui_Widget_Callback *cb = it_data->cb;
249 Gui_Context *ctx = (Gui_Context *) wdg_context_get(it_data->wdg);
250
251 Eid *action_id = cb_action_id_get(cb);
252 Gui_Action *action = action_get(action_id);
253
254 Gui_Widget_Property *prop = action_property_get(action);
255 if (!prop)
256 {
257 ERR("no property");
258 return EO_CALLBACK_CONTINUE;
259 }
260
261 Gui_Widget_Property *new_prop = prop_copy(prop);
262 /* Get value which need to be changed.*/
263 Gui_Value *val = prop_value_nth_get(new_prop, 0);
264
265 const char *new_item_name = elm_object_item_part_text_get(event_info, NULL);
266 /* Set selected string on hover */
267 elm_object_text_set(obj, new_item_name);
268 Eid *new_name_id = gui_context_eid_get_by_name(ctx, new_item_name);
269 gui_value_name_id_set(val, GUI_TYPE_OBJECT_ITEM, new_name_id);
270
271 Eid *wdg_id = action_widget_id_get(action);
272 Gui_Action *new_action = action_copy(action_id);
273 Gui_Memento *memento = gui_memento_new(action_id, MEMENTO_ACTION, action, new_action);
274 gui_context_memento_add(ctx, memento);
275
276 action_modif_set(new_action, wdg_id, new_prop);
277 action_set(action_id, new_action);
278 return EO_CALLBACK_CONTINUE;
279}
280
281static void
282_action_prop_update(void *data, Eo *obj, void *event_info)
283{
284 unsigned int par_idx = (unsigned int) (uintptr_t) data;
285 It_Data *it_data = eo_do(obj, eo_key_data_get("cb_it_data"));
286 Gui_Widget_Callback *cb = it_data->cb;
287 Gui_Context *ctx = (Gui_Context *) wdg_context_get(it_data->wdg);
288
289 Eid *action_id = cb_action_id_get(cb);
290 Gui_Action *action = action_get(action_id);
291 const Eo_Class *kl = eo_class_get(obj);
292 const Op_Desc *op;
293 Gui_Widget_Property *prop;
294 Gui_Value *val;
295
296 /* Get data for changed field. */
297
298 prop = action_property_get(action);
299 if (!prop)
300 {
301 ERR("no property");
302 return;
303 }
304 op = prop_op_desc_get(prop);
305
306 Gui_Widget_Property *new_prop = prop_copy(prop);
307 /* Get value which need to be changed.*/
308 val = prop_value_nth_get(new_prop, par_idx);
309
310 /* Get new value from edit field.
311 * And update Gui_Value with new value. */
312 Gui_Type type = db_op_desc_nth_par_type_get(op, par_idx);
313 if (kl == ELM_ENTRY_CLASS)
314 {
315 const char *entry_data = elm_entry_entry_get(obj);
316 if (type == GUI_TYPE_STRING)
317 {
318 /* FIXME: part_text_set can receive NULL as parameter.
319 * But because of this, I can't write "null"*/
320 gui_value_string_free(val);
321 if (!strcmp(entry_data, "null"))
322 {
323 gui_value_string_set(val, NULL);
324 }
325 else
326 {
327 gui_value_string_set(val, strdup(entry_data));
328 }
329 }
330 else if (type == GUI_TYPE_SINT)
331 {
332 int number = atoi(entry_data);
333 gui_value_int_set(val, number);
334 }
335 else if (type == GUI_TYPE_DOUBLE)
336 {
337 double number = atof(entry_data);
338 gui_value_double_set(val, number);
339 }
340 }
341 if (kl == ELM_CHECK_CLASS)
342 {
343 Eina_Bool state = eo_do(obj, elm_obj_check_state_get());
344 gui_value_bool_set(val, state);
345 }
346 if (kl == ELM_HOVERSEL_CLASS)
347 {
348 const char *new_enum_value = elm_object_item_part_text_get(event_info, NULL);
349 /* Set selected string on hover */
350 elm_object_text_set(obj, new_enum_value);
351 /* Get new value depending on type of edit field.
352 * And update value. */
353 if (type == GUI_TYPE_ENUM)
354 {
355 gui_value_string_free(val);
356 gui_value_enum_set(val, strdup(new_enum_value));
357 }
358 else if (type == GUI_TYPE_OBJECT)
359 {
360 Eid *eid = EID_ID_GET(val);
361 Eid *new_name_id = gui_context_eid_get_by_name(ctx, new_enum_value);
362 Gui_Widget *cur_param_wdg = eid?wdg_get(eid):NULL;
363 Gui_Widget *new_param_wdg = new_name_id?wdg_get(new_name_id):NULL;
364 /* GUI_TYPE_OBJECT ops depend on other widgets, check that widget exists.
365 * or new one not equal old one.*/
366 if ((!new_param_wdg) || (cur_param_wdg == new_param_wdg))
367 {
368 /* Need to ref/unref to delete the never referenced prop */
369 prop_ref(new_prop);
370 prop_unref(new_prop);
371 return;
372 }
373 gui_value_name_id_set(val, type, new_name_id);
374 }
375 else if (type == GUI_TYPE_FILE)
376 {
377 if (!strcmp(new_enum_value, PROP_HOVERSEL_NONE_VALUE))
378 {
379 gui_value_name_id_set(val, type, 0);
380 }
381 else
382 {
383 Eid *new_id = gui_context_eid_get_by_name(_active_context_get(), new_enum_value);
384 gui_value_name_id_set(val, type, new_id);
385 }
386 }
387 }
388 Eid *wdg_id = action_widget_id_get(action);
389 Gui_Action *new_action = action_copy(action_id);
390 Gui_Memento *memento = gui_memento_new(action_id, MEMENTO_ACTION, action, new_action);
391 gui_context_memento_add(ctx, memento);
392
393 action_modif_set(new_action, wdg_id, new_prop);
394 action_set(action_id, new_action);
395}
396
397static void
398_callbacks_classname_table_expand(const Gui_Widget *wdg, const char *classname, Elm_Object_Item *parent)
399{
400 const Eolian_Class *class = eolian_class_get_by_name(classname);
401 Eina_Iterator *events = eolian_class_events_get(class);
402 Eolian_Event *event;
403
404 const char *filter = _filter_string_get();
405
406 EINA_ITERATOR_FOREACH(events, event)
407 {
408 const char *event_name = eolian_event_name_get(event);
409
410 // If filter is on and no match, dont add to property list
411 if (filter && !_str_nocase_prefix(event_name, filter))
412 continue;
413
414 const Eina_List *wgdcbs = wdg_cb_list_get(wdg), *l;
415 Eina_List *items = NULL;
416 Gui_Widget_Callback *cb;
417
418 Eid *eid;
419 EINA_LIST_FOREACH(wgdcbs, l, eid)
420 {
421 cb = cb_get_from_id(eid);
422 if (!strcmp(event_name, cb_type_get(cb)))
423 {
424 Eid *act_id = cb_action_id_get(cb);
425 const Gui_Action *action = action_get(act_id);
426 if (action) items = eina_list_append(items, cb);
427 }
428 }
429
430 cb = cb_new(event_name, NULL);
431 items = eina_list_append(items, cb);
432
433 EINA_LIST_FOREACH(items, l, cb)
434 {
435 It_Data *it_data = IT_DATA_BUILD(CALLBACK_TYPE, wdg);
436 cb_ref(cb);
437 it_data->cb = cb;
438 elm_genlist_item_append(cb_list, _itc_cb, it_data, parent,
439 ELM_GENLIST_ITEM_NONE, NULL, NULL);
440 }
441 eina_list_free(items);
442 }
443 eina_iterator_free(events);
444}
445
446static void
447_callbacks_expanded_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info)
448{
449 Elm_Object_Item *glit = event_info;
450 Classname_Data *cl = elm_object_item_data_get(glit);
451 eina_hash_set(expanded_classes, cl->classname, (void *)1);
452 _callbacks_classname_table_expand(cl->wdg, cl->classname, glit);
453}
454
455static void
456_callbacks_contracted_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info)
457{
458 Elm_Object_Item *glit = event_info;
459 Classname_Data *cl = elm_object_item_data_get(glit);
460 eina_hash_del_by_key(expanded_classes, cl->classname);
461 elm_genlist_item_subitems_clear(glit);
462}
463
464static void
465_item_del(void *data, Evas_Object *obj EINA_UNUSED)
466{
467 It_Data *it_data = data;
468 cb_unref(it_data->cb);
469
470 Egui_Layout_Cb_Item_Widgets *wdgs = it_data->cb_wdgs;
471 // Make box cache ready. Remove the callback event.
472 eo_do(wdgs->cb_action_t_hsel, eo_event_callback_del(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED,
473 _action_type_changed, it_data));
474 evas_object_smart_callback_del_full(wdgs->cb_wdgs_hsel, "selected", _action_wdg_selected, it_data);
475 eo_do(wdgs->cb_item, elm_obj_box_unpack_all());
476
477 Eo *dyn_obj;
478 EINA_LIST_FREE(it_data->cb_dyn_objs, dyn_obj) eo_del(dyn_obj);
479
480 _mempool_cache_data_put(CACHE_CALLBACKS, wdgs->cb_item);
481 _it_data_free(it_data);
482}
483
484static void
485_wdgs_struct_free(void *wdgs)
486{
487 free(wdgs);
488}
489
490static Evas_Object *
491_item_content_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
492{
493 It_Data *it_data = data;
494 const char *default_val = NULL;
495
496 // Genlist can call content get without calling delete first
497 // so in that case just return what it already has.
498 if (it_data->cb_wdgs) return it_data->cb_wdgs->cb_item;
499
500 Eid *eid = cb_action_id_get(it_data->cb);
501 const Gui_Action *action = action_get(eid);
502
503 Egui_Layout_Cb_Item_Widgets *wdgs;
504 Eo *cb_item_box = _mempool_cache_data_get(CACHE_CALLBACKS);
505
506 if (!cb_item_box)
507 {
508 wdgs = egui_layout_cb_item_create(propview_table);
509 eo_do(wdgs->cb_item, eo_key_data_set("cb_item_wdgs", wdgs, _wdgs_struct_free));
510 elm_hoversel_item_add(wdgs->cb_action_t_hsel, "Create", NULL, ELM_ICON_NONE, NULL, NULL);
511 elm_hoversel_item_add(wdgs->cb_action_t_hsel, "Modify", NULL, ELM_ICON_NONE, NULL, NULL);
512 elm_hoversel_item_add(wdgs->cb_action_t_hsel, "Invoke", NULL, ELM_ICON_NONE, NULL, NULL);
513 elm_hoversel_hover_parent_set(wdgs->cb_action_t_hsel, elm_widget_top_get(propview_table));
514 elm_object_tooltip_text_set(wdgs->cb_action_t_hsel, "Action type");
515 eo_ref(wdgs->cb_item);
516 }
517 else
518 {
519 wdgs = eo_do(cb_item_box, eo_key_data_get("cb_item_wdgs"));
520 }
521
522 eo_do(wdgs->cb_label, elm_obj_widget_part_text_set(NULL, cb_type_get(it_data->cb)));
523
524 if (action) default_val = action_type_get_as_string(action);
525 if (!default_val) default_val = " --- ";
526 eo_do(wdgs->cb_action_t_hsel, elm_obj_widget_part_text_set(NULL, default_val));
527 eo_do(wdgs->cb_action_t_hsel, eo_event_callback_add(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED,
528 _action_type_changed, it_data));
529
530 eo_do(wdgs->cb_item,
531 elm_obj_box_pack_end(wdgs->cb_label),
532 elm_obj_box_pack_end(wdgs->cb_action_t_hsel));
533
534 if (action)
535 {
536 Action_Type atype = action_type_get(action);
537 if (atype == CREATION_ACTION || atype == MODIF_ACTION)
538 {
539 Eid *wdg_id = action_widget_id_get(action);
540 const char *wdg_name = NULL;
541 if (wdg_id) wdg_name = eid_name_get(wdg_id);
542 if (!wdg_name) wdg_name = PROP_HOVERSEL_NONE_VALUE;
543 eo_do(wdgs->cb_wdgs_hsel, elm_obj_hoversel_clear());
544 if (atype == CREATION_ACTION)
545 {
546 Eo *objects_hs = props_hoversel_objects_add(wdgs->cb_item, wdgs->cb_wdgs_hsel, elm_widget_top_get(cb_list), wdg_name, gui_context_main_widgets_get(wdg_context_get(it_data->wdg)), NULL);
547 elm_object_tooltip_text_set(objects_hs, "Object to create");
548 Eid *parent_id = action_creation_parent_get(action);
549 const char *parent_name = (parent_id ? eid_name_get(parent_id) : NULL);
550 Eo *parents_hs = props_hoversel_objects_add(wdgs->cb_item, NULL, elm_widget_top_get(cb_list), parent_name, gui_context_wdg_list_get(wdg_context_get(it_data->wdg)), NULL);
551 eo_do(parents_hs, eo_event_callback_add(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, _action_parent_selected, it_data));
552 elm_object_tooltip_text_set(parents_hs, "Parent");
553 it_data->cb_dyn_objs = eina_list_append(it_data->cb_dyn_objs, parents_hs);
554 }
555 else
556 {
557 Eo *user_cb_hs = props_hoversel_objects_add(wdgs->cb_item, wdgs->cb_wdgs_hsel, elm_widget_top_get(cb_list), wdg_name, gui_context_wdg_list_get(wdg_context_get(it_data->wdg)), NULL);
558 elm_object_tooltip_text_set(user_cb_hs, "Object to modify");
559 }
560 evas_object_smart_callback_add(wdgs->cb_wdgs_hsel, "selected", _action_wdg_selected, it_data);
561 }
562 if (atype == MODIF_ACTION)
563 {
564 Eid *wdg_id = action_widget_id_get(action);
565 Gui_Widget *wdg = wdg_get(wdg_id);
566 Eo *props_hover = props_hoversel_object_ops_add(wdgs->cb_item, elm_widget_top_get(cb_list), " --- ", wdg);
567 elm_object_tooltip_text_set(props_hover, "Property to modify");
568 it_data->cb_dyn_objs = eina_list_append(it_data->cb_dyn_objs, props_hover);
569 eo_do(props_hover, eo_event_callback_add(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, _action_prop_selected, it_data));
570 const Gui_Widget_Property *prop = action_property_get(action);
571 if (prop)
572 {
573 const Op_Desc *op = prop_op_desc_get(prop);
574 eo_do(props_hover, elm_obj_widget_part_text_set(NULL, db_op_desc_op_name_full_get(op)));
575
576 /* We show the item name for pack operations. The info of the items are in the contents window. */
577 if (db_op_desc_container_type_get(op) == ITEM_CONTAINER &&
578 db_op_desc_container_behavior_get(op) == CONTAINER_PACK)
579 {
580 Gui_Value *val = prop_value_nth_get(prop, 0);
581 if (val)
582 {
583 const Eina_List *items_list = item_container_item_subitems_get(wdg_item_container_root_get(wdg));
584 Eid *cur_item = EID_ID_GET(val);
585 const char *cur_item_name = eid_name_get(cur_item)?:" --- ";
586 Eo *items_hover = props_hoversel_objects_add(wdgs->cb_item, NULL, elm_widget_top_get(cb_list), cur_item_name, items_list, NULL);
587 it_data->cb_dyn_objs = eina_list_append(it_data->cb_dyn_objs, items_hover);
588 eo_do(items_hover, eo_event_callback_add(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, _action_item_selected, it_data));
589 }
590 }
591 else
592 {
593 unsigned int count, i;
594 count = db_op_desc_param_number_get(op);
595
596 for (i = 0; i < count; i++)
597 {
598 void *pi = (void *) (uintptr_t) i;
599 Gui_Value *value = ((prop && prop_value_get(prop)) ? prop_value_nth_get(prop, i) : NULL);
600 Eo *new_obj = props_value_add(wdgs->cb_item, wdg, value, op, i);
601 it_data->cb_dyn_objs = eina_list_append(it_data->cb_dyn_objs, new_obj);
602 if (new_obj)
603 {
604 const char *tooltip_text = op_param_desc_name_get(db_op_desc_nth_param_desc_get(op, i));
605 elm_object_tooltip_text_set(new_obj, tooltip_text);
606 eo_do(new_obj, eo_key_data_set("cb_it_data", it_data, NULL));
607 if (eo_isa(new_obj, ELM_HOVERSEL_CLASS))
608 evas_object_smart_callback_add(new_obj, "selected", _action_prop_update, pi);
609 else
610 evas_object_smart_callback_add(new_obj, "changed", _action_prop_update, pi);
611 }
612 else
613 return NULL;
614 }
615 }
616 }
617 }
618 if (atype == USER_ACTION)
619 {
620 Eid *cb_id = action_user_cb_id_get(action);
621 const char *cb_name = (cb_id ? eid_name_get(cb_id) : NULL);
622 Eo *cbs_hs = props_hoversel_resources_add(wdgs->cb_item, NULL, elm_widget_top_get(cb_list), cb_name, wdg_context_get(it_data->wdg), RESOURCE_EO_CALLBACK);
623 eo_do(cbs_hs, eo_event_callback_add(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, _action_user_cb_selected, it_data));
624 elm_object_tooltip_text_set(cbs_hs, "User callback");
625 it_data->cb_dyn_objs = eina_list_append(it_data->cb_dyn_objs, cbs_hs);
626 }
627 }
628
629 it_data->cb_wdgs = wdgs;
630 return wdgs->cb_item;
631}
632
633void
634cbview_build(const Gui_Widget *wdg)
635{
636 eo_do(cb_list, elm_obj_genlist_clear());
637
638 Eina_List *classes = eo_class_mro_get(wdg_class_name_get(wdg));
639 const char *classname;
640 Elm_Object_Item *glit = NULL;
641
642 const char *filter = _filter_string_get();
643
644 EINA_LIST_FREE(classes, classname)
645 {
646 const Eolian_Class *class = eolian_class_get_by_name(classname);
647 Eina_Iterator *events = eolian_class_events_get(class);
648 if (events)
649 {
650 if (filter)
651 {
652 _callbacks_classname_table_expand(wdg, classname, NULL);
653 }
654 else
655 {
656 Classname_Data *cl = calloc(1, sizeof(Classname_Data));
657 cl->classname = strdup(classname);
658 cl->wdg = wdg;
659 glit = elm_genlist_item_append(cb_list, _itc_class, cl,
660 NULL, ELM_GENLIST_ITEM_TREE, NULL,
661 NULL);
662 if (eina_hash_find(expanded_classes, classname))
663 elm_genlist_item_expanded_set(glit, EINA_TRUE);
664 }
665 }
666 eina_iterator_free(events);
667 }
668 //if filter search found nothing, yield an appropriate message to callbacks list
669 if (filter && !elm_genlist_items_count(cb_list))
670 elm_genlist_item_append(cb_list, _itc_notfound, NULL, NULL,
671 ELM_GENLIST_ITEM_NONE, NULL, NULL);
672}
673
674static void
675_expand_request_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info)
676{
677 Elm_Object_Item *glit = event_info;
678 Classname_Data *cl = elm_object_item_data_get(glit);
679 eina_hash_set(expanded_classes, cl->classname, (void *)1);
680 elm_genlist_item_expanded_set(glit, EINA_TRUE);
681}
682
683static void
684_contract_request_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info)
685{
686 Elm_Object_Item *glit = event_info;
687 Classname_Data *cl = elm_object_item_data_get(glit);
688 eina_hash_del_by_key(expanded_classes, cl->classname);
689 elm_genlist_item_expanded_set(glit, EINA_FALSE);
690}
691
692static void
693_selected_callback_move(int dir)
694{
695 Elm_Object_Item *sel = elm_genlist_selected_item_get(cb_list);
696 if ((sel) && (elm_genlist_item_item_class_get(sel) == _itc_cb))
697 {
698 It_Data *it_data = elm_object_item_data_get(sel);
699 if (cb_action_id_get(it_data->cb))
700 {
701 const Callback_Container *cc_old;
702 Callback_Container *cc_new;
703
704 Gui_Widget_Callback *cb = it_data->cb;
705 const Gui_Widget *wdg = it_data->wdg;
706 cc_old = wdg_cb_container_get(wdg);
707 cc_new = cb_container_copy(cc_old);
708 if (cb_container_cb_move(cc_new, cb, dir))
709 {
710 Gui_Memento *memento = gui_memento_new(wdg_eid_get(wdg), MEMENTO_CALLBACK_ADD_DEL, (void *)cc_old, cc_new);
711 gui_context_memento_add((Gui_Context *) wdg_context_get(wdg), memento);
712
713 wdg_cb_container_unset((Gui_Widget *) wdg);
714 wdg_cb_container_set((Gui_Widget *) wdg, cc_new);
715
716 cbview_build(wdg);
717 cbview_item_selected_set(cb_eid_get(cb));
718 }
719 /* If nothing wasn't move, delete Callback_Container */
720 else
721 {
722 /* Since it was never referenced, it has to be ref and then unref to be deleted */
723 cb_container_ref(cc_new);
724 cb_container_unref(cc_new);
725 }
726 }
727 }
728}
729
730Eina_Bool
731_callbacksview_up_btn_clicked(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
732{
733 _selected_callback_move(-1);
734 return EO_CALLBACK_CONTINUE;
735}
736
737Eina_Bool
738_callbacksview_down_btn_clicked(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
739{
740 _selected_callback_move(1);
741 return EO_CALLBACK_CONTINUE;
742}
743
744Eina_Bool
745_callbacksview_del_btn_clicked(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
746{
747 Elm_Object_Item *sel = elm_genlist_selected_item_get(cb_list);
748 if ((sel) && (elm_genlist_item_item_class_get(sel) == _itc_cb))
749 {
750 It_Data *it_data = elm_object_item_data_get(sel);
751 const Callback_Container *cc_old;
752 Callback_Container *cc_new;
753
754 Gui_Widget_Callback *cb = it_data->cb;
755 const Gui_Widget *wdg = it_data->wdg;
756 cc_old = wdg_cb_container_get(wdg);
757 cc_new = cb_container_copy(cc_old);
758 cb_container_cb_remove(cc_new, cb);
759 Gui_Memento *memento = gui_memento_new(wdg_eid_get(wdg), MEMENTO_CALLBACK_ADD_DEL, (void *)cc_old, cc_new);
760 gui_context_memento_add((Gui_Context *) wdg_context_get(wdg), memento);
761
762 wdg_cb_container_unset((Gui_Widget *) wdg);
763 wdg_cb_container_set((Gui_Widget *) wdg, cc_new);
764
765 cbview_build(wdg);
766 cbview_item_selected_set(cb_eid_get(cb));
767 }
768 return EO_CALLBACK_CONTINUE;
769}
770
771void
772cbview_init()
773{
774 Egui_Layout_Widgets *g = egui_layout_gui_get();
775
776 if (!_itc_cb)
777 {
778 _itc_cb = elm_genlist_item_class_new();
779 _itc_cb->item_style = "full";
780 _itc_cb->func.content_get = _item_content_get;
781 _itc_cb->func.del = _item_del;
782 }
783 cb_list = g->main_win->callbacksview_list;
784 propview_table = g->main_win->propsview_table;
785
786 evas_object_smart_callback_add(cb_list, "expand,request", _expand_request_cb, NULL);
787 evas_object_smart_callback_add(cb_list, "contract,request", _contract_request_cb, NULL);
788 evas_object_smart_callback_add(cb_list, "expanded", _callbacks_expanded_cb, NULL);
789 evas_object_smart_callback_add(cb_list, "contracted", _callbacks_contracted_cb, NULL);
790
791 expanded_classes = eina_hash_string_superfast_new(NULL);
792}
793
794void
795cbview_shutdown()
796{
797 eo_do(cb_list, elm_obj_genlist_clear());
798 cb_list = NULL;
799
800 elm_genlist_item_class_free(_itc_cb);
801 _itc_cb = NULL;
802
803 eina_hash_free(expanded_classes);
804}
diff --git a/src/bin/egui_gui/cbview.h b/src/bin/egui_gui/cbview.h
new file mode 100644
index 0000000..1fd2ac9
--- /dev/null
+++ b/src/bin/egui_gui/cbview.h
@@ -0,0 +1,17 @@
1
2#ifndef _CBVIEW_H
3#define _CBVIEW_H
4
5void
6cbview_init(void);
7
8void
9cbview_build(const Gui_Widget *wdg);
10
11void
12cbview_shutdown(void);
13
14void
15cbview_item_selected_set(Eid *cb_eid);
16
17#endif
diff --git a/src/bin/egui_gui/contentview.c b/src/bin/egui_gui/contentview.c
new file mode 100644
index 0000000..ed11cc8
--- /dev/null
+++ b/src/bin/egui_gui/contentview.c
@@ -0,0 +1,274 @@
1#include <Elementary.h>
2#include <Eolian.h>
3
4#include "ffi_glue.h"
5#include "egui_log.h"
6#include "props_helper.h"
7#include "egui_logic_private.h"
8
9#include "contentview.h"
10
11#include "elm_widget_container.h"
12
13static Elm_Genlist_Item_Class *_itc_ctn = NULL;
14
15static Eo *ctn_list = NULL;
16
17static ContentViewCbs *_contentview_cbs = NULL;
18
19ContentViewCbs *
20contentview_cbs_get()
21{
22 if (!_contentview_cbs) _contentview_cbs = calloc(1, sizeof(*_contentview_cbs));
23 return _contentview_cbs;
24}
25
26static Evas_Object *
27_content_item_content_get(It_Data *it_data)
28{
29 const Gui_Widget *wdg = it_data->wdg;
30
31 unsigned int count, i;
32 count = db_op_desc_param_number_get(it_data->op_desc);
33
34 Eo *box = eo_add(ELM_BOX_CLASS, ctn_list);
35 eo_do(box, evas_obj_visibility_set(EINA_TRUE),
36 elm_obj_box_horizontal_set(EINA_TRUE),
37 elm_obj_box_padding_set(5, 0),
38 evas_obj_size_hint_weight_set(EVAS_HINT_EXPAND, 0),
39 evas_obj_size_hint_align_set(EVAS_HINT_FILL, 0)
40 );
41
42 it_data->box = box;
43
44 for (i = 0; i < count; i++)
45 {
46 /* Get value, for which we want to build field.
47 * If it is NULL, field will be build, for nth value in Op_Desc */
48 Gui_Value *val = ((it_data->prop) ? prop_value_nth_get(it_data->prop, i) : NULL);
49 Eo *obj = props_value_add(box, wdg, val, it_data->op_desc, i);
50 if (obj)
51 {
52 Par_Field_Data *pfd = calloc (1, sizeof(Par_Field_Data));
53 pfd->it_data = it_data;
54 pfd->par_idx = i;
55
56 eo_do(obj, eo_key_data_set(_STR_EDITOR, pfd, free));
57 const char *tooltip_text = op_param_desc_name_get(db_op_desc_nth_param_desc_get(it_data->op_desc, i));
58 elm_object_tooltip_text_set(obj, tooltip_text);
59
60 if (eo_isa(obj, ELM_HOVERSEL_CLASS))
61 {
62 eo_do(obj, eo_event_callback_add(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED,
63 _contentview_cbs->content_change_cb_func, NULL));
64 eo_do(obj, evas_obj_size_hint_weight_set(0, EVAS_HINT_EXPAND),
65 evas_obj_size_hint_align_set(0, EVAS_HINT_FILL));
66 }
67 else
68 {
69 eo_do(obj, eo_event_callback_add(ELM_ENTRY_EVENT_ACTIVATED, _contentview_cbs->content_change_cb_func, NULL));
70 }
71 }
72 else
73 {
74 ERR("Can't create field for %dnth parameter in \"%s\", \
75 probably this parameter is NULL pointer", i + 1, db_op_desc_op_name_get(it_data->op_desc));
76 }
77 }
78 return box;
79}
80
81void
82contentview_build(const Gui_Widget *wdg)
83{
84 Eina_List *ctn_items = NULL;
85 Eina_List *l;
86 int i = 0;
87 Object_Container_Item *ci;
88 It_Data *it_data;
89
90 eo_do(ctn_list, elm_obj_genlist_clear());
91
92 const char *wdg_name = wdg_obj_container_class_name_get(wdg);
93 Eina_Bool isbox = (wdg_name &&
94 (!strcmp(wdg_name, DB_DEF_BOX_CLASS) ||
95 !strcmp(wdg_name, DB_DEF_WIN_CLASS)));
96
97 Egui_Layout_Widgets *g = egui_layout_gui_get();
98 elm_object_disabled_set(g->main_win->contentview_down_btn, !isbox);
99 elm_object_disabled_set(g->main_win->contentview_up_btn, !isbox);
100
101 Eina_List *items_lst = wdg_obj_container_contents_list_get(wdg);
102
103 EINA_LIST_FOREACH(items_lst, l, ci)
104 {
105 Eid *item_id = obj_container_item_eid_get(ci);
106 if (IS_ID_VALID(item_id) && !wdg_get(item_id)) continue;
107
108 Gui_Widget_Property *prop = obj_container_item_prop_get(ci);
109 it_data = IT_DATA_BUILD(CONTENT_TYPE, wdg);
110 it_data->idx = i;
111 it_data->prop = prop;
112 it_data->op_desc = (Op_Desc *) prop_op_desc_get(prop);
113 i++;
114
115 ctn_items = eina_list_append(ctn_items, it_data);
116 }
117
118 /* Add empty fields. */
119 const char *wdg_class_name = wdg_class_name_get(wdg);
120 const char *name;
121 /* Add empty field for each type of container. */
122 EINA_LIST_FOREACH(db_class_inherit_containers_list_get(wdg_class_name), l, name)
123 {
124 const Op_Desc *op_desc = db_container_desc_op_desc_get(db_container_desc_get(name), CONTAINER_PACK);
125 it_data = IT_DATA_BUILD(CONTENT_TYPE, wdg);
126 it_data->idx = i;
127 it_data->op_desc = op_desc;
128 it_data->prop = NULL;
129
130 ctn_items = eina_list_append(ctn_items, it_data);
131 }
132
133 EINA_LIST_FREE(ctn_items, it_data)
134 elm_genlist_item_append(ctn_list, _itc_ctn, it_data, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
135}
136
137static void
138_content_select_item(const Gui_Widget_Property *prop)
139{
140 Elm_Object_Item *it = elm_genlist_first_item_get(ctn_list);
141 for (; it; it = elm_genlist_item_next_get(it))
142 {
143 It_Data *it_data = elm_object_item_data_get(it);
144 if (it_data->prop == prop)
145 {
146 elm_genlist_item_selected_set(it, EINA_TRUE);
147 break;
148 }
149 }
150}
151
152Eina_Bool
153_contentview_del_btn_clicked(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description *desc, void *event_info)
154{
155 const Gui_Widget_Property *prev_prop = NULL;
156
157 Elm_Object_Item *glit = elm_genlist_selected_item_get(ctn_list);
158 if (!glit) return EO_CALLBACK_CONTINUE;
159
160 It_Data *it_data = elm_object_item_data_get(glit);
161 intptr_t idx = (intptr_t) it_data->idx;
162
163 it_data = elm_object_item_data_get(elm_genlist_item_next_get(glit));
164 if (it_data) prev_prop = it_data->prop;
165 if (!prev_prop)
166 {
167 it_data = elm_object_item_data_get(elm_genlist_item_prev_get(glit));
168 if (it_data) prev_prop = it_data->prop;
169 }
170
171 Eina_Bool ret = _contentview_cbs->content_delete_cb_func((void *)idx, obj, desc, event_info);
172 if (prev_prop) _content_select_item(prev_prop);
173
174 return ret;
175}
176
177Eina_Bool
178_contentview_up_btn_clicked(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description *desc, void *event_info EINA_UNUSED)
179{
180 Elm_Object_Item *glit = elm_genlist_selected_item_get(ctn_list);
181 if (!glit) return EO_CALLBACK_CONTINUE;
182
183 It_Data *it_data = elm_object_item_data_get(glit);
184 const Gui_Widget_Property *prev_prop = it_data->prop;
185 intptr_t idx = it_data->idx;
186
187 Eina_Bool ret = _contentview_cbs->content_reorder_cb_func((void *)idx, obj, desc, (void *)(intptr_t)UP);
188 _content_select_item(prev_prop);
189
190 return ret;
191}
192
193Eina_Bool
194_contentview_down_btn_clicked(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description *desc, void *event_info EINA_UNUSED)
195{
196 Elm_Object_Item *glit = elm_genlist_selected_item_get(ctn_list);
197 if (!glit) return EO_CALLBACK_CONTINUE;
198
199 It_Data *it_data = elm_object_item_data_get(glit);
200 const Gui_Widget_Property *prev_prop = it_data->prop;
201 intptr_t idx = it_data->idx;
202
203 Eina_Bool ret = _contentview_cbs->content_reorder_cb_func((void *)idx, obj, desc, (void *)(intptr_t)DOWN);
204 _content_select_item(prev_prop);
205
206 return ret;
207}
208
209static void
210_contents_item_del(void *data, Evas_Object *obj EINA_UNUSED)
211{
212 It_Data *it_data = data;
213
214 if (it_data->prop)
215 {
216 const char *fullname = db_op_desc_op_name_full_get(it_data->op_desc);
217 _mempool_cache_data_put(fullname, it_data->box);
218 }
219
220 _it_data_free(it_data);
221}
222
223static Evas_Object *
224_contents_item_content_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
225{
226 It_Data *it_data = data;
227
228 if (!it_data->prop) return _content_item_content_get(it_data);
229
230 if (it_data->box) return it_data->box;
231
232 const char *fullname = db_op_desc_op_name_full_get(it_data->op_desc);
233
234 Evas_Object * it_box = _mempool_cache_data_get(fullname);
235
236 if (!it_box)
237 {
238 it_box = _content_item_content_get(it_data);
239 eo_ref(it_box);
240 }
241 else
242 {
243 it_data->box = it_box;
244 _prop_field_update(it_data->prop, it_box, it_data);
245 }
246
247 return it_box;
248}
249
250void
251contentview_init(void)
252{
253 Egui_Layout_Widgets *g = egui_layout_gui_get();
254
255 ctn_list = g->main_win->contentview_list;
256
257 if (!_itc_ctn)
258 {
259 _itc_ctn = elm_genlist_item_class_new();
260 _itc_ctn->item_style = "full";
261 _itc_ctn->func.content_get = _contents_item_content_get;
262 _itc_ctn->func.del = _contents_item_del;
263 }
264}
265
266void
267contentview_shutdown(void)
268{
269 elm_genlist_item_class_free(_itc_ctn);
270 _itc_ctn = NULL;
271
272 eo_do(ctn_list, elm_obj_genlist_clear());
273 ctn_list = NULL;
274}
diff --git a/src/bin/egui_gui/contentview.h b/src/bin/egui_gui/contentview.h
new file mode 100644
index 0000000..82cb343
--- /dev/null
+++ b/src/bin/egui_gui/contentview.h
@@ -0,0 +1,27 @@
1
2#ifndef _CONTENTVIEW_H
3#define _CONTENTVIEW_H
4
5#include <Eo.h>
6#include "gui_widget.h"
7
8typedef struct
9{
10 Eina_Bool (*content_delete_cb_func)(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
11 Eina_Bool (*content_reorder_cb_func)(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
12 Eina_Bool (*content_change_cb_func)(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
13} ContentViewCbs;
14
15void
16contentview_init(void);
17
18void
19contentview_build(const Gui_Widget *wdg);
20
21void
22contentview_shutdown(void);
23
24ContentViewCbs *
25contentview_cbs_get();
26
27#endif
diff --git a/src/bin/egui_gui/descview.c b/src/bin/egui_gui/descview.c
new file mode 100644
index 0000000..caeeb06
--- /dev/null
+++ b/src/bin/egui_gui/descview.c
@@ -0,0 +1,126 @@
1#include <Elementary.h>
2#include <Eolian.h>
3
4#include "ffi_glue.h"
5#include "egui_log.h"
6#include "props_helper.h"
7#include "egui_logic_private.h"
8#include "descview.h"
9
10#include "elm_widget_container.h"
11
12static Elm_Genlist_Item_Class *_itc_desc = NULL;
13static Eo *desc_list = NULL;
14
15// Used to loop in _description_build function
16static char *descs[] = { DB_DEF_NAME, DB_DEF_CLASS, DB_DEF_PUBLIC, NULL };
17
18void
19descview_build(const Gui_Widget *wdg)
20{
21 eo_do(desc_list, elm_obj_genlist_clear());
22
23 int i;
24 for (i = 0; descs[i]; i++)
25 {
26 It_Data *it_data = IT_DATA_BUILD(DESCRIPTION_TYPE, wdg);
27 it_data->desc = descs[i];
28 elm_genlist_item_append(desc_list, _itc_desc, it_data, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
29 }
30}
31
32static Eina_Bool
33_wdg_public_change_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
34{
35 Eina_Bool state;
36 eo_do(obj, state = elm_obj_check_state_get());
37 wdg_public_set(data, state);
38
39 return EO_CALLBACK_CONTINUE;
40}
41
42static Eina_Bool
43_wdg_name_change_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
44{
45 Gui_Widget *wdg = data;
46 const char *str = NULL;
47 eo_do(obj, str = elm_obj_widget_part_text_get(NULL));
48 widget_name_change(wdg, str);
49
50 return EO_CALLBACK_CONTINUE;
51}
52
53static Evas_Object *
54_description_item_content_get(It_Data *it_data)
55{
56 Evas_Object *box = eo_add(ELM_BOX_CLASS, desc_list);
57 eo_do(box, evas_obj_visibility_set(EINA_TRUE),
58 elm_obj_box_horizontal_set(EINA_TRUE),
59 elm_obj_box_padding_set(5, 0),
60 evas_obj_size_hint_weight_set(EVAS_HINT_EXPAND, 0),
61 evas_obj_size_hint_align_set(EVAS_HINT_FILL, 0)
62 );
63
64 it_data->box = box;
65
66 Eo *label = eo_add(ELM_LABEL_CLASS, box);
67 eo_do(label, evas_obj_visibility_set(EINA_TRUE),
68 elm_obj_widget_part_text_set(NULL, it_data->desc));
69 eo_do(box, elm_obj_box_pack_end(label));
70
71 if (!strcmp(it_data->desc, DB_DEF_PUBLIC))
72 {
73 Eo *ck = props_check_add(box, wdg_public_get(it_data->wdg));
74 eo_do (ck, eo_event_callback_add(ELM_ENTRY_EVENT_CHANGED, _wdg_public_change_cb, it_data->wdg));
75 elm_object_tooltip_text_set(ck, "Check to make widget accissible from code");
76 }
77 else if (!strcmp(it_data->desc, DB_DEF_NAME))
78 {
79 Eo *entry = props_entry_add(box, wdg_name_get(it_data->wdg), GUI_TYPE_STRING);
80 eo_do (entry, eo_event_callback_add(ELM_ENTRY_EVENT_ACTIVATED, _wdg_name_change_cb, it_data->wdg));
81 elm_object_tooltip_text_set(entry, "Widget name");
82 }
83 else if (!strcmp(it_data->desc, DB_DEF_CLASS))
84 {
85 Eo *entry = props_entry_add(box, wdg_class_name_get(it_data->wdg), GUI_TYPE_STRING);
86 elm_object_disabled_set(entry, EINA_TRUE);
87 elm_object_tooltip_text_set(entry, "Widget class");
88 }
89 return box;
90}
91
92static void
93_desc_item_del(void *data, Evas_Object *obj EINA_UNUSED)
94{
95 It_Data *it_data = data;
96 _it_data_free(it_data);
97}
98
99static Evas_Object *
100_desc_item_content_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
101{
102 return _description_item_content_get(data);
103}
104
105void
106descview_init(void)
107{
108 Egui_Layout_Widgets *g = egui_layout_gui_get();
109
110 desc_list = g->main_win->description_list;
111
112 if (!_itc_desc)
113 {
114 _itc_desc = elm_genlist_item_class_new();
115 _itc_desc->item_style = "full";
116 _itc_desc->func.content_get = _desc_item_content_get;
117 _itc_desc->func.del = _desc_item_del;
118 }
119}
120
121void
122descview_shutdown(void)
123{
124 eo_do(desc_list, elm_obj_genlist_clear());
125 desc_list = NULL;
126}
diff --git a/src/bin/egui_gui/descview.h b/src/bin/egui_gui/descview.h
new file mode 100644
index 0000000..4c9d9ca
--- /dev/null
+++ b/src/bin/egui_gui/descview.h
@@ -0,0 +1,14 @@
1
2#ifndef _DESCVIEW_H
3#define _DESCVIEW_H
4
5void
6descview_init(void);
7
8void
9descview_build(const Gui_Widget *wdg);
10
11void
12descview_shutdown(void);
13
14#endif \ No newline at end of file
diff --git a/src/bin/egui_gui/dnd.c b/src/bin/egui_gui/dnd.c
new file mode 100644
index 0000000..12c8f74
--- /dev/null
+++ b/src/bin/egui_gui/dnd.c
@@ -0,0 +1,512 @@
1
2#include <Eo.h>
3#include <Evas.h>
4#include <Ecore.h>
5#include "egui_log.h"
6#include "egui_layout.h"
7#include "gui_widget.h"
8
9typedef struct
10{
11 const char *data; /*DnD data*/
12 Eo *image; /* image for DnD icon. */
13 Eo *obj; /*object, where drag starts */
14 const Gui_Widget *wdg; /* let's think about it as about DnD data. */
15
16 void (*_drag_start_cb)(const Gui_Widget *wdg, const Eo *obj);
17} Drag_Info;
18
19typedef struct
20{
21 Ecore_Timer *tm;
22 Drag_Info *drag_info;
23 int dnd_in_out; /* Main objects enter/leave counter*/
24} DnD_Info;
25
26typedef struct
27{
28 const Gui_Widget *wdg;
29 void (*drop_target_enter)(void *data, Evas_Object *obj);
30 void *enterdata;
31 void (*drop_target_leave)(void *data, Evas_Object *obj);
32 void *leavedata;
33 Elm_Drop_Cb drop_target_drop;
34 void *dropdata;
35 Elm_Drag_Pos drop_target_pos;
36 void *posdata;
37
38 Eo *obj; /* This obj is used only to properly call elm_drop_target_del() */
39 const Gui_Widget *drop_target;
40} Target_Info;
41
42#define TIME_TO_DRAG 0.1
43#define DND_IMAGE_SIZE 15
44#define DROP_TARGET "__drop_target__"
45
46static DnD_Info _dnd_info;
47int aa;
48
49/* Determine if dragged object is inside droppable. */
50Eina_Bool
51dnd_is_in_drop_target()
52{
53 return !!_dnd_info.dnd_in_out;
54}
55
56const char*
57dnd_drag_data_get()
58{
59 return _dnd_info.drag_info->data;
60}
61
62const Eo*
63dnd_drag_obj_get()
64{
65 return _dnd_info.drag_info->obj;
66}
67
68const Gui_Widget*
69dnd_drag_wdg_get()
70{
71 return _dnd_info.drag_info->wdg;
72}
73
74static void
75_dragpos(void *data EINA_UNUSED, Eo * obj EINA_UNUSED, Evas_Coord x EINA_UNUSED, Evas_Coord y EINA_UNUSED, Elm_Xdnd_Action action EINA_UNUSED)
76{
77 //ERR("%s: %d %d", (char *) data, x, y);
78}
79
80static void
81_dragaccept(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Eina_Bool doaccept EINA_UNUSED)
82{
83 //ERR("accept: %d", doaccept);
84}
85
86static void
87_dragstate(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED)
88{
89 //ERR("%s", (char *) data);
90}
91
92/* This callback is called only for a window object.
93 * So Target_Info -> wdg is always Main Widget.
94 * Obj is not NULL only for Canvas, which can be also be a drop target. */
95static void
96_dropenter(void *data, Evas_Object *obj)
97{
98 _dnd_info.dnd_in_out++;
99 Target_Info *ti = data;
100 ti->drop_target = ti->wdg;
101
102 if (ti->drop_target_enter)
103 ti->drop_target_enter(ti->enterdata, obj);
104}
105
106/* This callback is called only for a window object.
107 * So Target_Info -> wdg is always Main Widget.
108 * Obj is not NULL only for Canvas, which can be also be a drop target. */
109static void
110_dropleave(void *data, Evas_Object *obj)
111{
112 Target_Info *main_wdg_ti = data;
113 _dnd_info.dnd_in_out--;
114
115 /* if ti->drop_target is not current main widget, then it means,
116 * that prev drop target, box for example wasn't leaved properly.
117 * For example moving mouse fast from one window to another will cause "jump".
118 * So need to call leave properly.
119 * */
120 if (main_wdg_ti->drop_target != main_wdg_ti->wdg)
121 {
122 Target_Info *ti = wdg_data_get(main_wdg_ti->drop_target, DROP_TARGET);
123 if (ti->drop_target_leave)
124 ti->drop_target_leave(ti->leavedata, obj);
125 }
126 main_wdg_ti->drop_target = NULL;
127
128 if (main_wdg_ti->drop_target_leave)
129 main_wdg_ti->drop_target_leave(main_wdg_ti->leavedata, obj);
130}
131
132static Eina_Bool
133_dropcb(void *data EINA_UNUSED, Evas_Object *obj, Elm_Selection_Data *ev)
134{
135 Target_Info *main_wdg_ti = data;
136 Target_Info *ti;
137 /* if drop_target == NULL, then we drop on MAIN CANVAS*/
138 if (main_wdg_ti->drop_target)
139 {
140 ti = wdg_data_get(main_wdg_ti->drop_target, DROP_TARGET);
141 }
142 else
143 {
144 ti = main_wdg_ti;
145 }
146
147 if (ti->drop_target_drop)
148 ti->drop_target_drop(ti->dropdata, obj, ev);
149 return EINA_TRUE;
150}
151
152static void
153_drop_target_iterate(Gui_Widget **drop_candidate, const Gui_Session *session, Evas_Coord x, Evas_Coord y)
154{
155 Eina_Bool stop = EINA_TRUE;
156 Eid *wdg_id;
157 Eo *o;
158 Evas_Coord ox, oy, ow, oh;
159 double aprx = 0.05;
160
161 const Eina_List *lst, *l;
162 const Gui_Widget *dragged_wdg = dnd_drag_wdg_get();
163 lst = wdg_children_list_get(*drop_candidate);
164 EINA_LIST_FOREACH(lst, l, wdg_id)
165 {
166 Gui_Widget *w = wdg_get(wdg_id);
167 /* If widget is not active, or is not a drop target, continue. */
168 if (!w || !wdg_data_get(w, DROP_TARGET))
169 continue;
170 /* If iterated object is dragged one, continue.
171 * This can happen when start dragging some drop target. */
172 if (w == dragged_wdg)
173 continue;
174 o = session_eo_get(session, w);
175 eo_do(o, evas_obj_position_get(&ox, &oy));
176 eo_do(o, evas_obj_size_get(&ow, &oh));
177 if (((x >= ox) && (x <= ox + ow)) &&
178 ((y >= oy) && (y <= oy + oh)))
179 {
180 *drop_candidate = w;
181 /* Suppose we have win, a resize object box, and a table packed into the box.
182 * We drag, so want to enter the box first, and table after.
183 * So while pointer in in 5% of width of the box, force to return the box as a drop target. */
184 if (((x > ox + (Evas_Coord) (ow * aprx)) && (x <= ox + (Evas_Coord) (ow * (1- aprx)))) &&
185 ((y > oy + (Evas_Coord) (oh * aprx)) && (y <= oy + (Evas_Coord) (oh * (1- aprx)))))
186 stop = EINA_FALSE;
187 }
188 }
189
190 if (!stop)
191 _drop_target_iterate(drop_candidate, session, x, y);
192}
193
194/* This callback is called every time for a window object.
195 * So Target_Info -> wdg is always Main Widget*/
196static void
197_droppos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action)
198{
199 Target_Info *main_wdg_ti = data;
200 const Gui_Widget *wdg = main_wdg_ti->wdg;
201
202 /* For canvas only*/
203 if (!wdg)
204 {
205 if (main_wdg_ti->drop_target_pos)
206 {
207 main_wdg_ti->drop_target_pos(main_wdg_ti->posdata, obj, x, y, action);
208 }
209 return;
210 }
211
212 Eo *wdg_eo, *iwin;
213 Evas_Coord p_x = 0, p_y = 0;
214 Evas_Coord iwin_x = 0, iwin_y = 0;
215 Gui_Widget *drop_candidate = (Gui_Widget *) wdg;
216
217 Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(wdg_context_get(wdg));
218 wdg_eo = session_eo_get(session, wdg);
219 /* Usually main_wdg is win.
220 * But when it is not, need to get image of Editor win */
221 if (IS_WIN(wdg))
222 {
223 iwin = elm_win_inlined_image_object_get(wdg_eo);
224 }
225 else
226 {
227 Eo *main_obj_inlined_win_img = eo_do(wdg_eo, eo_key_data_get("__editor_win"));
228 iwin = elm_win_inlined_image_object_get(main_obj_inlined_win_img);
229 }
230 eo_do(iwin, evas_obj_position_get(&iwin_x, &iwin_y));
231
232 /* if p_x or p_y is < 0, but we inside this callback, drop to window*/
233 p_x = x - iwin_x;
234 p_y = y - iwin_y;
235 _drop_target_iterate(&drop_candidate, session, p_x, p_y);
236
237 if (main_wdg_ti->drop_target != drop_candidate)
238 {
239 /* Call leave callback for previous target widget.
240 * If prev wdg is MainWdg, don't call leave. */
241 if (main_wdg_ti->drop_target != wdg)
242 {
243 Target_Info *ti = wdg_data_get(main_wdg_ti->drop_target, DROP_TARGET);
244 if (ti->drop_target_leave)
245 {
246 ti->drop_target_leave(ti->leavedata, NULL);
247 }
248 }
249
250 /* Call enter callback for new target widget.
251 * If new wdg is MainWdg, don't call enter. */
252 if (drop_candidate != wdg)
253 {
254 Target_Info *ti = wdg_data_get(drop_candidate, DROP_TARGET);
255 if (ti->drop_target_enter)
256 {
257 ti->drop_target_enter(ti->enterdata, NULL);
258 }
259 }
260 main_wdg_ti->drop_target = drop_candidate;
261 }
262
263 /* Need to calculate coord inside object */
264 if (drop_candidate != wdg)
265 {
266 wdg_eo = session_eo_get(session, drop_candidate);
267 Evas_Coord obj_x, obj_y;
268 eo_do(wdg_eo, evas_obj_position_get(&obj_x, &obj_y));
269 p_x = p_x - obj_x;
270 p_y = p_y - obj_y;
271 }
272
273 /* Simulate poscb inside drop candidate.
274 * Get callbacks from drop candidate and call. */
275 Target_Info *ti = wdg_data_get(drop_candidate, DROP_TARGET);
276 if (ti->drop_target_pos)
277 {
278 ti->drop_target_pos(ti->posdata, NULL, p_x, p_y, action);
279 }
280}
281
282static Evas_Object *
283_image_create_icon(void *data, Evas_Object *parent, Evas_Coord *xoff, Evas_Coord *yoff)
284{
285 //if (!data) return NULL;
286 Evas_Object *ic = NULL;
287 Evas_Object *io = data;
288 const char *f, *g;
289 Evas_Coord x, y, w, h, xm, ym;
290
291 elm_image_file_get(io, &f, &g);
292 ic = elm_image_add(parent);
293 elm_image_file_set(ic, f, g);
294 evas_object_geometry_get(io, &x, &y, &w, &h);
295 evas_object_move(ic, x, y);
296 evas_object_resize(ic, 40, 40);
297 evas_object_show(ic);
298
299 evas_pointer_canvas_xy_get(evas_object_evas_get(io), &xm, &ym);
300 if (xoff) *xoff = xm - 30;
301 if (yoff) *yoff = ym - 30;
302
303 return ic;
304}
305
306static Eina_Bool
307_drag_start(void *data)
308{
309 Drag_Info *di = data;
310 Evas_Object *(*image_create_icon_f)(void *data, Evas_Object *parent, Evas_Coord *xoff, Evas_Coord *yoff) = NULL;
311 Evas_Object *drag_image = di->image;
312 if (drag_image)
313 image_create_icon_f = _image_create_icon;
314
315 _dnd_info.tm = NULL;
316 _dnd_info.drag_info = di;
317 _dnd_info.dnd_in_out = 0;
318 elm_drag_start(di->obj, ELM_SEL_FORMAT_TEXT,
319 di->data, ELM_XDND_ACTION_COPY,
320 image_create_icon_f, drag_image,
321 _dragpos, NULL,
322 _dragaccept, NULL,
323 _dragstate, NULL);
324 if (di->_drag_start_cb)
325 {
326 di->_drag_start_cb(di->wdg, di->obj);
327 }
328 return ECORE_CALLBACK_CANCEL;
329}
330
331static Eina_Bool
332_drag_mouse_up(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
333{
334 eo_do(obj, eo_event_callback_del(EVAS_OBJECT_EVENT_MOUSE_UP, _drag_mouse_up, NULL));
335 if (_dnd_info.tm)
336 {
337 ecore_timer_del(_dnd_info.tm);
338 _dnd_info.tm = NULL;
339 }
340 return EO_CALLBACK_CONTINUE;
341}
342
343static Eina_Bool
344_drag_mouse_down(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
345{
346 Drag_Info *di = data;
347 eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_UP, _drag_mouse_up, NULL));
348
349 ecore_timer_del(_dnd_info.tm);
350 _dnd_info.tm = ecore_timer_add(TIME_TO_DRAG, _drag_start, di);
351 return EO_CALLBACK_CONTINUE;
352}
353
354static Eina_Bool
355_drag_data_free(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
356{
357 Drag_Info *di = data;
358 free(di);
359 _dnd_info.drag_info = NULL;
360 return EO_CALLBACK_CONTINUE;
361}
362
363/* Function to make Eo object draggable, when mouse down/up are handled inside.
364 * Dragging from factory. */
365void
366drag_add(Eo *obj, Eo *image, const char *data)
367{
368 Drag_Info *di = calloc(1, sizeof(Drag_Info));
369 di->image = image;
370 di->data = data;
371 di->obj = obj;
372 eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_DOWN, _drag_mouse_down, di));
373 eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_DEL, _drag_data_free, di));
374}
375
376/* Function to start dragging, when mouse down/up are handled outside.
377 * Dragging widgets. */
378void
379drag_start(Eo *obj, Eo *image, const char *data, const Gui_Widget *wdg, void (*cb)(const Gui_Widget *, const Eo *))
380{
381 Drag_Info *di = calloc(1, sizeof(Drag_Info));
382 di->image = image;
383 di->data = data;
384 di->obj = obj;
385 di->wdg = wdg;
386 di->_drag_start_cb = cb;
387 _dnd_info.drag_info = di;
388
389 ecore_timer_del(_dnd_info.tm);
390 _dnd_info.tm = ecore_timer_add(TIME_TO_DRAG, _drag_start, di);
391}
392
393/* Function to stop dragging, when mouse down/up are handled outside.
394 * Dragging widgets. */
395void
396drag_stop()
397{
398 if (_dnd_info.tm)
399 {
400 ecore_timer_del(_dnd_info.tm);
401 _dnd_info.tm = NULL;
402 }
403 free(_dnd_info.drag_info);
404 _dnd_info.drag_info = NULL;
405 _dnd_info.dnd_in_out = 0;
406}
407
408static Target_Info*
409_target_info_new(Gui_Widget *wdg, Eo *obj)
410{
411 Target_Info *ti;
412
413 if (wdg)
414 {
415 ti = wdg_data_get(wdg, DROP_TARGET);
416 if (!ti)
417 {
418 ti = calloc(1, sizeof(Target_Info));
419 ti->wdg = wdg;
420 wdg_data_set(wdg, DROP_TARGET, ti);
421 }
422 }
423 else if (obj)
424 {
425 ti = eo_do(obj, eo_key_data_get(DROP_TARGET));
426 if (!ti)
427 {
428 ti = calloc(1, sizeof(Target_Info));
429 eo_do(obj, eo_key_data_set(DROP_TARGET, ti, NULL));
430 }
431 }
432 return ti;
433}
434
435void
436drop_target_wdg_set(Gui_Widget *wdg,
437 void (*drop_target_enter)(void *, Evas_Object *obj), void *enterdata,
438 void (*drop_target_leave)(void *, Evas_Object *obj), void *leavedata,
439 Elm_Drag_Pos drop_target_pos, void *posdata,
440 Elm_Drop_Cb drop_target_drop, void *dropdata)
441{
442 Target_Info *ti = _target_info_new(wdg, NULL);
443
444 ti->drop_target_enter = drop_target_enter;
445 ti->enterdata = enterdata;
446 ti->drop_target_leave = drop_target_leave;
447 ti->leavedata = leavedata;
448 ti->drop_target_pos = drop_target_pos;
449 ti->posdata = posdata;
450 ti->drop_target_drop = drop_target_drop;
451 ti->dropdata = dropdata;
452
453 /* if Elm DnD will work, call here elm_drop_target_add() for widget's Eo */
454}
455
456void
457drop_target_main_wdg_set(Gui_Widget *wdg, Eo *obj,
458 void (*drop_target_enter)(void *, Evas_Object *obj), void *enterdata,
459 void (*drop_target_leave)(void *, Evas_Object *obj), void *leavedata,
460 Elm_Drag_Pos drop_target_pos, void *posdata,
461 Elm_Drop_Cb drop_target_drop, void *dropdata)
462{
463 Target_Info *ti = _target_info_new(wdg, obj);
464 ti->obj = obj;
465
466 ti->drop_target_enter = drop_target_enter;
467 ti->enterdata = enterdata;
468 ti->drop_target_leave = drop_target_leave;
469 ti->leavedata = leavedata;
470 ti->drop_target_pos = drop_target_pos;
471 ti->posdata = posdata;
472 ti->drop_target_drop = drop_target_drop;
473 ti->dropdata = dropdata;
474
475 elm_drop_target_add(obj, ELM_SEL_FORMAT_TEXT,
476 _dropenter, ti,
477 _dropleave, ti,
478 _droppos, ti,
479 _dropcb, ti
480 );
481}
482
483void
484drop_target_wdg_del(Gui_Widget *wdg, Eo *obj)
485{
486 Target_Info *ti = NULL;
487
488 if (wdg)
489 {
490 ti = wdg_data_get(wdg, DROP_TARGET);
491 wdg_data_set(wdg, DROP_TARGET, NULL);
492 }
493 else if (obj)
494 {
495 ti = eo_do(obj, eo_key_data_get(DROP_TARGET));
496 eo_do(obj, eo_key_data_del(DROP_TARGET));
497 }
498
499 if (!ti) return;
500 /* call elm_drop_target_del() only for main objects, t.e. if obj exists. */
501 if (ti->obj)
502 {
503 elm_drop_target_del(ti->obj, ELM_SEL_FORMAT_TEXT,
504 _dropenter, ti,
505 _dropleave, ti,
506 _droppos, ti,
507 _dropcb, ti);
508 }
509 free(ti);
510}
511
512
diff --git a/src/bin/egui_gui/dnd.h b/src/bin/egui_gui/dnd.h
new file mode 100644
index 0000000..bb7d6c3
--- /dev/null
+++ b/src/bin/egui_gui/dnd.h
@@ -0,0 +1,43 @@
1
2#ifndef _DND_H
3#define _DND_H
4
5void
6drag_add(Eo *obj, Eo *image, const char *data);
7
8void
9drag_start(Eo *obj, Eo *image, const char *data, const Gui_Widget *wdg, void (*cb)(const Gui_Widget *, const Eo *));
10
11void
12drag_stop();
13
14void
15drop_target_wdg_set(Gui_Widget *wdg,
16 void (*drop_target_enter)(void *, Evas_Object *obj), void *enterdata,
17 void (*drop_target_leave)(void *, Evas_Object *obj), void *leavedata,
18 Elm_Drag_Pos drop_target_pos, void *posdata,
19 Elm_Drop_Cb drop_target_drop, void *dropdata);
20
21void
22drop_target_main_wdg_set(Gui_Widget *wdg, Eo *obj,
23 void (*drop_target_enter)(void *, Evas_Object *obj), void *enterdata,
24 void (*drop_target_leave)(void *, Evas_Object *obj), void *leavedata,
25 Elm_Drag_Pos drop_target_pos, void *posdata,
26 Elm_Drop_Cb drop_target_drop, void *dropdata);
27
28void
29drop_target_wdg_del(Gui_Widget *wdg, Eo *obj);
30
31const char*
32dnd_drag_data_get();
33
34const Eo*
35dnd_drag_obj_get();
36
37const Gui_Widget*
38dnd_drag_wdg_get();
39
40Eina_Bool
41dnd_is_in_drop_target();
42
43#endif
diff --git a/src/bin/egui_gui/editor.c b/src/bin/egui_gui/editor.c
index bb44cb6..98c2de5 100644
--- a/src/bin/egui_gui/editor.c
+++ b/src/bin/egui_gui/editor.c
@@ -1,3 +1,4 @@
1#include <libgen.h>
1 2
2#include "egui_log.h" 3#include "egui_log.h"
3#include "ffi_glue.h" 4#include "ffi_glue.h"
@@ -5,18 +6,66 @@
5#include "gui_widget.h" 6#include "gui_widget.h"
6#include "props_helper.h" 7#include "props_helper.h"
7#include "objtree.h" 8#include "objtree.h"
8#include "propview.h" 9
10#include "prop_layout.h"
11#include "contentview.h"
9#include "itemview.h" 12#include "itemview.h"
13#include "propview.h"
14#include "cbview.h"
15#include "key_bindings.h"
16
17#include "dnd.h"
18
10#include "gui_parser.h" 19#include "gui_parser.h"
11#include "egui_logic_private.h" 20#include "egui_logic_private.h"
12 21
22#define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT 1
13#include <Elementary.h> 23#include <Elementary.h>
24#include <Edje_Edit.h>
25
14#include "elm_widget.h" 26#include "elm_widget.h"
15 27
16#define WIN_INFO "win_info_key" 28#define MAIN_WDG_INFO "main_wdg_info_key"
29#define CURSOR_DROP_X "cursor_drop_x"
30#define CURSOR_DROP_Y "cursor_drop_y"
31
32#define EDITOR_DND_DATA "__EDITOR_DND_DATA__"
33#define EDITOR_DRAG_DATA "__EDITOR_DRAG_DATA__"
34#define DND_SESSION "__DND_SESSION__"
35
36typedef struct
37{
38 Eo *eo_cur;
39
40 Eina_Bool packed; /* Need this, because no API to check if object is packed into table
41 and unpack causes error message. */
42 int box_pack_idx;
43
44 int cell_part_x; /* Which fifth part of sell was selected*/
45 int cell_part_y; /* Used in order to check if need to repack or not. */
46
47 int table_w; /* Table width/height. Calculate it once in the beginning. */
48 int table_h;
49
50 int table_pack_x;
51 int table_pack_y;
52 Eina_List *table_borders;
53
54 int pointer_x;
55 int pointer_y;
56}
57DnD_Info;
58
59/* Function to call in the end of undo/redo in order to update view.
60 * Update is made according to head memento. */
61static void
62_editor_undo_redo_post(const Gui_Memento *memento);
63
64static void
65_wdg_parent_win_reload(const Gui_Widget *wdg);
17 66
18static Gui_Context *_active_ctx = NULL; 67static Gui_Context *_active_ctx = NULL;
19static const GUI *g; 68static const Egui_Layout_Widgets *g;
20 69
21void 70void
22_active_context_set(Gui_Context *ctx) 71_active_context_set(Gui_Context *ctx)
@@ -50,46 +99,66 @@ typedef enum {
50 99
51} Border_Type; 100} Border_Type;
52 101
53typedef struct _Win_Info 102typedef struct _Main_Wdg_Info
54{ 103{
55 Eo *frame; 104 Eo *frame;
56} Win_Info; 105} Main_Wdg_Info;
57 106
58static Win_Info* 107static Main_Wdg_Info*
59win_info_new() 108main_wdg_info_new()
60{ 109{
61 return calloc(1, sizeof(Win_Info)); 110 return calloc(1, sizeof(Main_Wdg_Info));
62} 111}
63 112
64static void 113static void
65win_info_frame_set(Win_Info *wi, Eo *fr) 114main_wdg_info_frame_set(Main_Wdg_Info *wi, Eo *fr)
66{ 115{
67 wi->frame = fr; 116 wi->frame = fr;
68} 117}
69 118
70static Eo* 119static Eo*
71win_info_frame_get(const Win_Info *wi) 120main_wdg_info_frame_get(const Main_Wdg_Info *wi)
72{ 121{
73 return wi->frame; 122 return wi->frame;
74} 123}
75 124
125Eina_Bool
126widget_name_change(Gui_Widget *wdg, const char *str)
127{
128 const Gui_Context *ctx = wdg_context_get(wdg);
129 if (!eid_rename(wdg_eid_get(wdg), str))
130 {
131 ERR("Name \"%s\" already exists!", str);
132 return EINA_FALSE;
133 }
134
135 const Gui_Widget *sel = gui_context_data_get(ctx, SELECTED_WDG);
136 objtree_item_selected_set(sel);
137
138 return EINA_TRUE;
139}
140
141/* x_fix/y_fix - correction of initial position of smart_parent. whis is not resized before elm_run. */
76static void 142static void
77_canvas_free_coords_get(const Gui_Context *ctx, Evas_Coord *x, Evas_Coord *y) 143_canvas_free_coords_get(const Gui_Context *ctx, Evas_Coord x_fix, Evas_Coord y_fix, Evas_Coord *x, Evas_Coord *y)
78{ 144{
79 Evas_Coord x0 = 340, y0 = 120, w0 = 1060, h0 = 900, retx, rety, ymax = 120; 145 Evas_Coord x0 = 340 + x_fix, y0 = 120 + y_fix, w0 = 1060, h0 = 900, retx, rety, ymax = 120;
80 Eina_List *win_list = gui_context_win_list_get(ctx); 146 Eina_List *main_widgets = gui_context_main_widgets_get(ctx);
81 Eina_List *itr; 147 Eina_List *itr;
82 Gui_Widget *wdg; 148 Eid *wdg_id;
83 retx = x0; 149 retx = x0;
84 rety = y0; 150 rety = y0;
85 EINA_LIST_FOREACH(win_list, itr, wdg) 151
152 EINA_LIST_FOREACH(main_widgets, itr, wdg_id)
86 { 153 {
87 Evas_Coord fx, fy, fw, fh; 154 Evas_Coord fx, fy, fw, fh;
88 Win_Info *wi = wdg_data_get(wdg, WIN_INFO); 155 Gui_Widget *wdg = wdg_get(wdg_id);
156 if (!wdg) continue;
157 Main_Wdg_Info *wi = wdg_data_get(wdg, MAIN_WDG_INFO);
89 if (wi) 158 if (wi)
90 { 159 {
91 eo_do(win_info_frame_get(wi), evas_obj_size_get(&fw, &fh)); 160 eo_do(main_wdg_info_frame_get(wi), evas_obj_size_get(&fw, &fh));
92 eo_do(win_info_frame_get(wi), evas_obj_position_get(&fx, &fy)); 161 eo_do(main_wdg_info_frame_get(wi), evas_obj_position_get(&fx, &fy));
93 if ((fx + fw) < (x0 + w0 - 100)) 162 if ((fx + fw) < (x0 + w0 - 100))
94 { 163 {
95 retx = fx + fw; 164 retx = fx + fw;
@@ -129,18 +198,37 @@ static Eina_Bool
129_marker_mouse_in(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); 198_marker_mouse_in(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
130static Eina_Bool 199static Eina_Bool
131_marker_mouse_out(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); 200_marker_mouse_out(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
201
202enum
203{
204 BORDER_SELECTION,
205 BORDER_DROP_TARGET
206};
207
132#define STR(par) #par 208#define STR(par) #par
133 209
134#define LINE(base_obj, id, x, y, l, w, visibility) \ 210#define LINE(id, color, x, y, l, w, visibility) \
135 ({\ 211 ({\
136 Eo *line = NULL;\ 212 Eo *line = NULL;\
137 eo_do(base_obj, line = eo_key_data_get(STR(id)));\ 213 eo_do(g->main_win->main_win, line = eo_key_data_get(STR(id"_"color)));\
138 if (!line)\ 214 if (!line)\
139 {\ 215 {\
140 line = eo_add(EVAS_RECTANGLE_CLASS, evas_object_evas_get(base_obj));\ 216 line = eo_add(EVAS_RECTANGLE_CLASS, g->main_win->main_win);\
141 eo_unref(line);\ 217 eo_do(g->main_win->main_win, eo_key_data_set(STR(id"_"color), line, NULL));\
142 eo_do(base_obj, eo_key_data_set(STR(id), line, NULL));\ 218 switch (color) \
143 eo_do(line, evas_obj_color_set(0, 255, 0, 255));\ 219 {\
220 case BORDER_SELECTION:\
221 {\
222 eo_do(line, evas_obj_color_set(0, 255, 0, 255));\
223 break;\
224 }\
225 case BORDER_DROP_TARGET:\
226 {\
227 eo_do(line, evas_obj_color_set(85, 200, 248, 255));\
228 break;\
229 }\
230 }\
231 eo_do(evas_object_smart_parent_get(g->main_win->main_box), evas_obj_smart_member_add(line)); \
144 }\ 232 }\
145 eo_do(line, evas_obj_visibility_set(visibility));\ 233 eo_do(line, evas_obj_visibility_set(visibility));\
146 eo_do(line, evas_obj_position_set(x, y));\ 234 eo_do(line, evas_obj_position_set(x, y));\
@@ -148,21 +236,20 @@ _marker_mouse_out(void *data, Eo *obj, const Eo_Event_Description *desc, void *e
148 eo_do(line, evas_obj_raise());\ 236 eo_do(line, evas_obj_raise());\
149 }) 237 })
150 238
151#define MARKER(base_obj, id, x, y, visibility) \ 239#define MARKER(id, x, y, visibility) \
152 ({ \ 240 ({ \
153 Eo *_m = NULL;\ 241 Eo *_m = NULL;\
154 eo_do(base_obj, _m = eo_key_data_get(STR(id)));\ 242 eo_do(g->main_win->main_win, _m = eo_key_data_get(STR(id)));\
155 if (!_m)\ 243 if (!_m)\
156 {\ 244 {\
157 _m = eo_add(EVAS_RECTANGLE_CLASS, evas_object_evas_get(base_obj));\ 245 _m = eo_add(EVAS_RECTANGLE_CLASS, g->main_win->main_win);\
158 eo_unref(_m);\ 246 eo_do(g->main_win->main_win, eo_key_data_set(STR(id), _m, NULL));\
159 eo_do(base_obj, eo_key_data_set(STR(id), _m, NULL));\
160 eo_do(_m, evas_obj_color_set(0, 255, 0, 255));\ 247 eo_do(_m, evas_obj_color_set(0, 255, 0, 255));\
161 eo_do(_m, evas_obj_size_set(7, 7));\ 248 eo_do(_m, evas_obj_size_set(7, 7));\
162 eo_do(_m, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_DOWN, _marker_mouse_down, (void *) (intptr_t) id)); \ 249 eo_do(_m, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_DOWN, _marker_mouse_down, (void *) (intptr_t) id)); \
163 eo_do(_m, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_UP, _marker_mouse_up, (void *) (intptr_t) id)); \
164 eo_do(_m, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_IN, _marker_mouse_in, (void *) (intptr_t) id)); \ 250 eo_do(_m, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_IN, _marker_mouse_in, (void *) (intptr_t) id)); \
165 eo_do(_m, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_OUT, _marker_mouse_out, (void *) (intptr_t) id)); \ 251 eo_do(_m, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_OUT, _marker_mouse_out, (void *) (intptr_t) id)); \
252 eo_do(evas_object_smart_parent_get(g->main_win->main_box), evas_obj_smart_member_add(_m)); \
166 }\ 253 }\
167 eo_do(_m, evas_obj_position_set(x, y)); \ 254 eo_do(_m, evas_obj_position_set(x, y)); \
168 eo_do(_m, evas_obj_raise());\ 255 eo_do(_m, evas_obj_raise());\
@@ -172,8 +259,28 @@ _marker_mouse_out(void *data, Eo *obj, const Eo_Event_Description *desc, void *e
172/* Draws border around obj, Evas is taken from base_obj; 259/* Draws border around obj, Evas is taken from base_obj;
173 * markers and lines are saved in base_obj*/ 260 * markers and lines are saved in base_obj*/
174static void 261static void
175_border_draw(const Eo *base_obj, Eo *obj, Eina_Bool visibility) 262_wdg_border_draw(const Gui_Widget *wdg, Eina_Bool visibility, int border_type_color)
176{ 263{
264 const Gui_Session *session = gui_context_editor_session_get(_active_context_get());
265 Eo *obj = NULL;
266 Eo *win_wdg_eo = NULL;
267 if (wdg)
268 {
269 if (IS_MAIN(wdg))
270 {
271 Main_Wdg_Info *wi = wdg_data_get(wdg, MAIN_WDG_INFO);
272 if (wi) obj = main_wdg_info_frame_get(wi);
273 }
274 else
275 {
276 const Gui_Widget *win_wdg = wdg_main_wdg_get(wdg);
277 Main_Wdg_Info *wi = wdg_data_get(win_wdg, MAIN_WDG_INFO);
278 if (wi) win_wdg_eo = main_wdg_info_frame_get(wi);
279 obj = session_eo_get(session, wdg);
280 win_wdg_eo = elm_object_content_get(win_wdg_eo);
281 }
282 }
283
177 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0, minw = 0, minh = 0; 284 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0, minw = 0, minh = 0;
178 Evas_Coord lw = 0 , lh = 0, hs = 5; 285 Evas_Coord lw = 0 , lh = 0, hs = 5;
179 286
@@ -184,12 +291,25 @@ _border_draw(const Eo *base_obj, Eo *obj, Eina_Bool visibility)
184 /* This is made, to have opportunity to pass NULL and hide border.*/ 291 /* This is made, to have opportunity to pass NULL and hide border.*/
185 if (obj) 292 if (obj)
186 { 293 {
294 Evas_Coord bx = 0, by = 0, bw = 0, bh = 0;
295 if (win_wdg_eo) eo_do(win_wdg_eo,
296 evas_obj_position_get(&bx, &by),
297 evas_obj_size_get(&bw, &bh));
298
187 eo_do(obj, evas_obj_position_get(&ox, &oy)); 299 eo_do(obj, evas_obj_position_get(&ox, &oy));
300
301 /* In case the objects has been shifted outside of the window
302 * e.g with naviframe item push */
303 if (ox < 0 || oy < 0) return;
304
188 eo_do(obj, evas_obj_size_hint_min_get(&minw, &minh)); 305 eo_do(obj, evas_obj_size_hint_min_get(&minw, &minh));
189 eo_do(obj, evas_obj_size_get(&ow, &oh)); 306 eo_do(obj, evas_obj_size_get(&ow, &oh));
190 if (ow < minw) ow = minw; 307 if (ow < minw) ow = minw;
191 if (oh < minh) oh = minh; 308 if (oh < minh) oh = minh;
192 309
310 ox += bx;
311 oy += by;
312
193 lw = ow + 2; 313 lw = ow + 2;
194 lh = oh + 2; 314 lh = oh + 2;
195 /* Redraw border only if coords or object were changed. */ 315 /* Redraw border only if coords or object were changed. */
@@ -209,78 +329,40 @@ _border_draw(const Eo *base_obj, Eo *obj, Eina_Bool visibility)
209 } 329 }
210 } 330 }
211 331
212 LINE(base_obj, BORDER_TOP, ox - 1, oy - 1, lw, 1, visibility); 332 switch (border_type_color)
213 LINE(base_obj, BORDER_BOTTOM, ox - 1, oy + oh + 1, lw, 1, visibility); 333 {
214 LINE(base_obj, BORDER_RIGHT, ox + ow + 1, oy - 1, 1, lh, visibility); 334 case BORDER_SELECTION:
215 LINE(base_obj, BORDER_LEFT, ox - 1, oy - 1, 1, lh, visibility); 335 {
216 336 LINE(BORDER_TOP, BORDER_SELECTION, ox - 1, oy - 1, lw, 1, visibility);
217 MARKER(base_obj, BORDER_MARKER_TOP_LEFT, ox - 1 - hs - 1, oy - 1 - hs - 1, visibility); 337 LINE(BORDER_BOTTOM, BORDER_SELECTION, ox - 1, oy + oh + 1, lw, 1, visibility);
218 MARKER(base_obj, BORDER_MARKER_TOP, ox + ow / 2 - hs / 2, oy - 1 - hs - 1, visibility); 338 LINE(BORDER_RIGHT, BORDER_SELECTION, ox + ow + 1, oy - 1, 1, lh, visibility);
219 MARKER(base_obj, BORDER_MARKER_TOP_RIGHT, ox + ow + 1, oy - 1 - hs - 1, visibility); 339 LINE(BORDER_LEFT, BORDER_SELECTION, ox - 1, oy - 1, 1, lh, visibility);
220 MARKER(base_obj, BORDER_MARKER_RIGHT, ox + ow + 1, oy + oh / 2 - hs / 2, visibility); 340
221 MARKER(base_obj, BORDER_MARKER_BOTTOM_RIGHT, ox + ow + 1, oy + oh + 1, visibility); 341 MARKER(BORDER_MARKER_TOP_LEFT, ox - 1 - hs - 1, oy - 1 - hs - 1, visibility);
222 MARKER(base_obj, BORDER_MARKER_BOTTOM, ox + ow / 2 - hs / 2, oy + oh + 1, visibility); 342 MARKER(BORDER_MARKER_TOP, ox + ow / 2 - hs / 2, oy - 1 - hs - 1, visibility);
223 MARKER(base_obj, BORDER_MARKER_BOTTOM_LEFT, ox - 1 - hs - 1, oy + oh + 1, visibility); 343 MARKER(BORDER_MARKER_TOP_RIGHT, ox + ow + 1, oy - 1 - hs - 1, visibility);
224 MARKER(base_obj, BORDER_MARKER_LEFT, ox - 1 - hs - 1 , oy + oh / 2 - hs / 2, visibility); 344 MARKER(BORDER_MARKER_RIGHT, ox + ow + 1, oy + oh / 2 - hs / 2, visibility);
225} 345 MARKER(BORDER_MARKER_BOTTOM_RIGHT, ox + ow + 1, oy + oh + 1, visibility);
226 346 MARKER(BORDER_MARKER_BOTTOM, ox + ow / 2 - hs / 2, oy + oh + 1, visibility);
227static void 347 MARKER(BORDER_MARKER_BOTTOM_LEFT, ox - 1 - hs - 1, oy + oh + 1, visibility);
228_wdg_border_draw(const Gui_Widget *wdg, Eina_Bool visibility) 348 MARKER(BORDER_MARKER_LEFT, ox - 1 - hs - 1 , oy + oh / 2 - hs / 2, visibility);
229{ 349 break;
230 const Gui_Session *session = gui_context_editor_session_get(_active_context_get()); 350 }
231 Eo *obj = session_eo_get(session, wdg); 351 case BORDER_DROP_TARGET:
232 if (!obj) return; 352 {
233 const Gui_Widget *win_wdg = wdg_parent_win_wdg_get(wdg); 353 LINE(BORDER_TOP, BORDER_DROP_TARGET, ox - 1, oy - 1, lw, 1, visibility);
234 if (!win_wdg) return; 354 LINE(BORDER_BOTTOM, BORDER_DROP_TARGET, ox - 1, oy + oh + 1, lw, 1, visibility);
235 Eo *win_wdg_eo; 355 LINE(BORDER_RIGHT, BORDER_DROP_TARGET, ox + ow + 1, oy - 1, 1, lh, visibility);
236 win_wdg_eo = session_eo_get(session, win_wdg); 356 LINE(BORDER_LEFT, BORDER_DROP_TARGET, ox - 1, oy - 1, 1, lh, visibility);
237 _border_draw(win_wdg_eo, obj, visibility); 357 break;
358 }
359 }
238} 360}
239#undef LINE 361#undef LINE
240#undef MARKER 362#undef MARKER
241#undef STR 363#undef STR
242 364
243static void 365static void
244_on_mouse_move_widget_drag(void *data, Evas *e EINA_UNUSED, Evas_Object *obj,
245void *event_info)
246{
247 Gui_Context *ctx = data;
248 static int cx, cy;
249 Evas_Coord ox, oy;
250 Evas_Event_Mouse_Move *ev = event_info;
251
252 /*FIXME: remove static stuff after tripple callback wil be fixed*/
253 if ((cx == ev->cur.canvas.x) && (cy == ev->cur.canvas.y))
254 return;
255
256 eo_do(obj, evas_obj_position_get(&ox, &oy));
257 ox = ox + (ev->cur.canvas.x - ev->prev.canvas.x);
258 oy = oy + (ev->cur.canvas.y - ev->prev.canvas.y);
259
260 eo_do(obj, evas_obj_position_set(ox, oy));
261 {
262 Gui_Widget *wdg = wdg_find_by_eo(gui_context_editor_session_get(ctx), ctx, obj);
263 Gui_Widget_Property *prop;
264 Gui_Value *val;
265
266 if (wdg)
267 {
268 prop = wdg_prop_get(wdg, DB_DEF_EVAS_OBJECT_CLASS, POSITION_SET);
269 if (prop)
270 {
271 val = prop_value_nth_get(prop, 0);
272 gui_value_int_set(val, ox);
273 val = prop_value_nth_get(prop, 1);
274 gui_value_int_set(val, oy);
275 propview_item_update(prop);
276 }
277 }
278 }
279 cx = ev->cur.canvas.x;
280 cy = ev->cur.canvas.y;
281}
282
283static void
284_frame_mouse_move(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *fr, void *event_info) 366_frame_mouse_move(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *fr, void *event_info)
285{ 367{
286 Evas_Coord ox, oy; 368 Evas_Coord ox, oy;
@@ -307,12 +389,9 @@ _frame_mouse_move(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *fr,
307 gui_value_int_set(val, oy); 389 gui_value_int_set(val, oy);
308 propview_item_update(prop); 390 propview_item_update(prop);
309 } 391 }
310
311 /* Redraw win border, when moving frame. */
312 _border_draw(canvas_get(), fr, EINA_TRUE);
313} 392}
314 393
315static const Gui_Widget* 394const Gui_Widget*
316_editor_wdg_selected_get() 395_editor_wdg_selected_get()
317{ 396{
318 Gui_Context *ctx = _active_context_get(); 397 Gui_Context *ctx = _active_context_get();
@@ -329,23 +408,14 @@ _editor_wdg_selected_set(const Gui_Widget *wdg)
329 /* Hide previous border*/ 408 /* Hide previous border*/
330 if (old_wdg) 409 if (old_wdg)
331 { 410 {
332 if (IS_WIN(old_wdg)) 411 _wdg_border_draw(old_wdg, EINA_FALSE, BORDER_SELECTION);
333 {
334 Win_Info *wi = wdg_data_get(old_wdg, WIN_INFO);
335 Eo *fr = win_info_frame_get(wi);
336 _border_draw(canvas_get(), fr, EINA_FALSE);
337 }
338 else
339 {
340 _wdg_border_draw(old_wdg, EINA_FALSE);
341 }
342 } 412 }
343 else 413 else
344 { 414 {
345 /* During context call _win_resize() will be called. 415 /* During context call _win_resize() will be called.
346 * It will draw border around win, but widget was not selected yet. 416 * It will draw border around win, but widget was not selected yet.
347 * So need to hide border. */ 417 * So need to hide border. */
348 _border_draw(canvas_get(), NULL, EINA_FALSE); 418 _wdg_border_draw(NULL, EINA_FALSE, BORDER_SELECTION);
349 } 419 }
350 420
351 /* Show new border*/ 421 /* Show new border*/
@@ -354,21 +424,15 @@ _editor_wdg_selected_set(const Gui_Widget *wdg)
354 Gui_Context *ctx = (Gui_Context *) wdg_context_get(wdg); 424 Gui_Context *ctx = (Gui_Context *) wdg_context_get(wdg);
355 gui_context_data_set(ctx, SELECTED_WDG, (Gui_Widget *) wdg); 425 gui_context_data_set(ctx, SELECTED_WDG, (Gui_Widget *) wdg);
356 426
427 /* Stack up parent frame */
428 const Gui_Widget *main_wdg = wdg_main_wdg_get(wdg);
429 Main_Wdg_Info *wi = wdg_data_get(main_wdg, MAIN_WDG_INFO);
430 Eo *fr = main_wdg_info_frame_get(wi);
431 eo_do(fr, evas_obj_raise());
432
357 Eo *obj = session_eo_get(gui_context_editor_session_get(ctx), wdg); 433 Eo *obj = session_eo_get(gui_context_editor_session_get(ctx), wdg);
358 /* Stack up */
359 // eo_do(obj, evas_obj_raise());
360 /* Set focus */ 434 /* Set focus */
361 eo_do(obj, evas_obj_focus_set(EINA_TRUE)); 435 eo_do(obj, evas_obj_focus_set(EINA_TRUE));
362 if (IS_WIN(wdg))
363 {
364 Win_Info *wi = wdg_data_get(wdg, WIN_INFO);
365 Eo *fr = win_info_frame_get(wi);
366 _border_draw(canvas_get(), fr, EINA_TRUE);
367 }
368 else
369 {
370 _wdg_border_draw(wdg, EINA_TRUE);
371 }
372 } 436 }
373 else 437 else
374 { 438 {
@@ -378,62 +442,53 @@ _editor_wdg_selected_set(const Gui_Widget *wdg)
378 442
379/* Second parameter is used to indicate if the wdg has to be deleted */ 443/* Second parameter is used to indicate if the wdg has to be deleted */
380static void 444static void
381_iter_widget_delete(Gui_Widget *wdg, Eina_Bool del_wdg) 445_iter_widget_delete(Gui_Widget *wdg)
382{ 446{
383 Eina_List *children = NULL, *l, *l2; 447 const Eina_List *children = NULL, *l, *l2;
384 Gui_Widget *w; 448 Eid *wid;
449 Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(_active_context_get());
385 450
386 children = wdg_children_list_get(wdg); 451 children = wdg_children_list_get(wdg);
387 EINA_LIST_FOREACH_SAFE(children, l, l2, w) 452 EINA_LIST_FOREACH_SAFE(children, l, l2, wid)
388 { 453 {
389 _iter_widget_delete(w, del_wdg); 454 Gui_Widget *w = wdg_get(wid);
455 if (w) _iter_widget_delete(w);
390 } 456 }
391 457
392 /* If widget is Win, look for its frame and unset content, but don't delete frame. */ 458 /* If widget is Win, look for its frame and unset content, but don't delete frame. */
393 Eo *win_inlined_image = NULL; 459 Eo *optional_win = NULL;
394 if (IS_WIN(wdg)) 460 /* Each time we iterate over widgets in order to delete them, we set window's frame invisible.
461 * DUring creation it will be visible again. Frame deleted only when project is closed. */
462 if (IS_MAIN(wdg))
395 { 463 {
396 Win_Info *wi = wdg_data_get(wdg, WIN_INFO); 464 Main_Wdg_Info *wi = wdg_data_get(wdg, MAIN_WDG_INFO);
397 Eo *fr = win_info_frame_get(wi); 465 if (wi)
398 if (fr)
399 {