diff options
Diffstat (limited to 'src/libraries')
-rwxr-xr-x | src/libraries/build.lua | 5 | ||||
-rw-r--r-- | src/libraries/winFang.c | 208 | ||||
-rw-r--r-- | src/libraries/winFang.h | 49 |
3 files changed, 261 insertions, 1 deletions
diff --git a/src/libraries/build.lua b/src/libraries/build.lua index 6566e66..4e277e1 100755 --- a/src/libraries/build.lua +++ b/src/libraries/build.lua | |||
@@ -15,7 +15,7 @@ end | |||
15 | 15 | ||
16 | LDFLAGS = '-L ' .. dir .. ' ' .. LDFLAGS | 16 | LDFLAGS = '-L ' .. dir .. ' ' .. LDFLAGS |
17 | 17 | ||
18 | removeFiles(dir, {'LumbrJack.o', lib_d .. '/libLumbrJack.so', 'Runnr.o', lib_d .. '/libRunnr.so', 'SledjHamr.o', lib_d .. '/libSledjHamr.so'}) | 18 | removeFiles(dir, {'LumbrJack.o', lib_d .. '/libLumbrJack.so', 'Runnr.o', lib_d .. '/libRunnr.so', 'SledjHamr.o', lib_d .. '/libSledjHamr.so', 'winFang.o', lib_d .. '/libwinFang.so'}) |
19 | 19 | ||
20 | runCommand('C libraries', dir, 'gcc ' .. CFLAGS .. ' -fPIC -c LumbrJack.c') | 20 | runCommand('C libraries', dir, 'gcc ' .. CFLAGS .. ' -fPIC -c LumbrJack.c') |
21 | runCommand(nil, dir, 'gcc ' .. CFLAGS .. ' -shared -Wl,-soname,libLumbrJack.so -o ' .. lib_d .. '/libLumbrJack.so LumbrJack.o') | 21 | runCommand(nil, dir, 'gcc ' .. CFLAGS .. ' -shared -Wl,-soname,libLumbrJack.so -o ' .. lib_d .. '/libLumbrJack.so LumbrJack.o') |
@@ -31,3 +31,6 @@ CFLAGS = CFLAGS .. ' -DPACKAGE_LOCALE_DIR=\\"' .. locale_d .. '\\"' | |||
31 | 31 | ||
32 | runCommand(nil, dir, 'gcc ' .. CFLAGS .. ' -fPIC -c SledjHamr.c') | 32 | runCommand(nil, dir, 'gcc ' .. CFLAGS .. ' -fPIC -c SledjHamr.c') |
33 | runCommand(nil, dir, 'gcc ' .. CFLAGS .. ' -shared -Wl,-soname,libSledjHamr.so -o ' .. lib_d .. '/libSledjHamr.so SledjHamr.o') | 33 | runCommand(nil, dir, 'gcc ' .. CFLAGS .. ' -shared -Wl,-soname,libSledjHamr.so -o ' .. lib_d .. '/libSledjHamr.so SledjHamr.o') |
34 | |||
35 | runCommand(nil, dir, 'gcc ' .. CFLAGS .. ' -fPIC -c winFang.c') | ||
36 | runCommand(nil, dir, 'gcc ' .. CFLAGS .. ' -shared -Wl,-soname,libwinFang.so -o ' .. lib_d .. '/libwinFang.so winFang.o') | ||
diff --git a/src/libraries/winFang.c b/src/libraries/winFang.c new file mode 100644 index 0000000..4d54627 --- /dev/null +++ b/src/libraries/winFang.c | |||
@@ -0,0 +1,208 @@ | |||
1 | #include "winFang.h" | ||
2 | |||
3 | |||
4 | // Elm inlined image windows needs this to change focus on mouse click. | ||
5 | // Evas style event callback. | ||
6 | static void _cb_mouse_down_elm(void *data, Evas *evas, Evas_Object *obj, void *event_info) | ||
7 | { | ||
8 | Evas_Event_Mouse_Down *ev = event_info; | ||
9 | |||
10 | if (1 == ev->button) | ||
11 | elm_object_focus_set(obj, EINA_TRUE); | ||
12 | } | ||
13 | |||
14 | static void cb_mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event_info) | ||
15 | { | ||
16 | Evas_Event_Mouse_Move *ev = event_info; | ||
17 | Evas_Object *orig = data; | ||
18 | Evas_Coord x, y; | ||
19 | Evas_Map *p; | ||
20 | int i, w, h; | ||
21 | |||
22 | if (!ev->buttons) return; | ||
23 | evas_object_geometry_get(obj, &x, &y, NULL, NULL); | ||
24 | evas_object_move(obj, | ||
25 | x + (ev->cur.canvas.x - ev->prev.output.x), | ||
26 | y + (ev->cur.canvas.y - ev->prev.output.y)); | ||
27 | evas_object_image_size_get(orig, &w, &h); | ||
28 | p = evas_map_new(4); | ||
29 | evas_object_map_enable_set(orig, EINA_TRUE); | ||
30 | // evas_object_raise(orig); | ||
31 | for (i = 0; i < 4; i++) | ||
32 | { | ||
33 | Evas_Object *hand; | ||
34 | char key[32]; | ||
35 | |||
36 | snprintf(key, sizeof(key), "h-%i\n", i); | ||
37 | hand = evas_object_data_get(orig, key); | ||
38 | evas_object_raise(hand); | ||
39 | evas_object_geometry_get(hand, &x, &y, NULL, NULL); | ||
40 | x += 15; | ||
41 | y += 15; | ||
42 | evas_map_point_coord_set(p, i, x, y, 0); | ||
43 | if (i == 0) evas_map_point_image_uv_set(p, i, 0, 0); | ||
44 | else if (i == 1) evas_map_point_image_uv_set(p, i, w, 0); | ||
45 | else if (i == 2) evas_map_point_image_uv_set(p, i, w, h); | ||
46 | else if (i == 3) evas_map_point_image_uv_set(p, i, 0, h); | ||
47 | } | ||
48 | evas_object_map_set(orig, p); | ||
49 | evas_map_free(p); | ||
50 | } | ||
51 | |||
52 | static void _on_done(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) | ||
53 | { | ||
54 | elm_exit(); | ||
55 | } | ||
56 | |||
57 | void winFangHide(winFang *win) | ||
58 | { | ||
59 | int i; | ||
60 | |||
61 | evas_object_hide(win->win); | ||
62 | for (i = 0; i < 4; i++) | ||
63 | evas_object_hide(win->hand[i]); | ||
64 | } | ||
65 | |||
66 | void winFangShow(winFang *win) | ||
67 | { | ||
68 | int i; | ||
69 | |||
70 | evas_object_show(win->win); | ||
71 | for (i = 0; i < 4; i++) | ||
72 | evas_object_show(win->hand[i]); | ||
73 | } | ||
74 | |||
75 | winFang *winFangAdd(Evas_Object *parent, int x, int y, int w, int h, char *title, char *name) | ||
76 | { | ||
77 | winFang *result; | ||
78 | Evas_Object *obj, *obj2, *bg; | ||
79 | char buf[PATH_MAX]; | ||
80 | int i; | ||
81 | |||
82 | result = calloc(1, sizeof(winFang)); | ||
83 | eina_clist_init(&result->widgets); | ||
84 | |||
85 | if (parent) result->internal = EINA_TRUE; | ||
86 | |||
87 | result->x = x; | ||
88 | result->y = y; | ||
89 | result->w = w; | ||
90 | result->h = h; | ||
91 | |||
92 | // In theory this should create an EWS window, in practice, I'm not seeing any difference. | ||
93 | // Guess I'll have to implement my own internal window manager. I don't think a basic one will be that hard. Famous last words. | ||
94 | // elm_config_engine_set("ews"); | ||
95 | if (result->internal) | ||
96 | { | ||
97 | result->win = elm_win_add(parent, name, ELM_WIN_INLINED_IMAGE); | ||
98 | obj = elm_win_inlined_image_object_get(result->win); | ||
99 | // On mouse down we try to shift focus to the backing image, this seems to be the correct thing to force focus onto it's widgets. | ||
100 | // According to the Elm inlined image window example, this is what's needed to. | ||
101 | evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN, _cb_mouse_down_elm, NULL); | ||
102 | elm_win_alpha_set(result->win, EINA_TRUE); | ||
103 | |||
104 | // image object for win is unlinked to its pos/size - so manual control | ||
105 | // this allows also for using map and other things with it. | ||
106 | evas_object_move(obj, result->x, result->y); | ||
107 | // Odd, it needs to be resized twice. WTF? | ||
108 | evas_object_resize(obj, result->w, result->h); | ||
109 | |||
110 | obj2 = evas_object_evas_get(obj); | ||
111 | // Create corner handles. | ||
112 | snprintf(buf, sizeof(buf), "%s/pt.png", elm_app_data_dir_get()); | ||
113 | for (i = 0; i < 4; i++) | ||
114 | { | ||
115 | char key[32]; | ||
116 | int cx = result->x, cy = result->y; | ||
117 | |||
118 | if (i == 1) cx += result->w; | ||
119 | else if (i == 2) {cx += result->w; cy += result->h;} | ||
120 | else if (i == 3) cy += result->h; | ||
121 | snprintf(key, sizeof(key), "h-%i\n", i); | ||
122 | #if 1 | ||
123 | result->hand[i] = evas_object_image_filled_add(obj2); | ||
124 | evas_object_image_file_set(result->hand[i], buf, NULL); | ||
125 | evas_object_resize(result->hand[i], 31, 31); | ||
126 | evas_object_move(result->hand[i], cx - 15, cy - 15); | ||
127 | evas_object_data_set(obj, key, result->hand[i]); | ||
128 | evas_object_show(result->hand[i]); | ||
129 | evas_object_event_callback_add(result->hand[i], EVAS_CALLBACK_MOUSE_MOVE, cb_mouse_move, obj); | ||
130 | #else | ||
131 | // TODO - No idea why, but using this version makes the window vanish when you click on a handle. | ||
132 | result->hand[i] = eo_add(EVAS_OBJ_IMAGE_CLASS, obj2, | ||
133 | evas_obj_image_filled_set(EINA_TRUE), | ||
134 | evas_obj_image_file_set(buf, NULL), | ||
135 | evas_obj_size_set(31, 31), | ||
136 | evas_obj_position_set(cx - 15, cy - 15), | ||
137 | eo_key_data_set(key, result->hand[i], NULL), | ||
138 | evas_obj_visibility_set(EINA_TRUE) | ||
139 | ); | ||
140 | evas_object_event_callback_add(result->hand[i], EVAS_CALLBACK_MOUSE_MOVE, cb_mouse_move, obj); | ||
141 | eo_unref(result->hand[i]); | ||
142 | #endif | ||
143 | } | ||
144 | } | ||
145 | else | ||
146 | { | ||
147 | result->win = elm_win_add(parent, name, ELM_WIN_BASIC); | ||
148 | evas_object_move(result->win, result->x, result->y); | ||
149 | evas_object_smart_callback_add(result->win, "delete,request", _on_done, NULL); | ||
150 | } | ||
151 | |||
152 | elm_win_title_set(result->win, title); | ||
153 | // Apparently transparent is not good enough for ELM backgrounds, so make it an Evas rectangle. | ||
154 | // Apparently coz ELM prefers stuff to have edjes. A bit over the top if all I want is a transparent rectangle. | ||
155 | bg = eo_add(EVAS_OBJ_RECTANGLE_CLASS, evas_object_evas_get(result->win), | ||
156 | evas_obj_size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND), | ||
157 | evas_obj_color_set(50, 0, 100, 100), | ||
158 | evas_obj_visibility_set(EINA_TRUE) | ||
159 | ); | ||
160 | elm_win_resize_object_add(result->win, bg); | ||
161 | eo_unref(bg); | ||
162 | |||
163 | evas_object_resize(result->win, result->w, result->h); | ||
164 | evas_object_show(result->win); | ||
165 | |||
166 | return result; | ||
167 | } | ||
168 | |||
169 | void winFangDel(winFang *win) | ||
170 | { | ||
171 | Widget *wid; | ||
172 | |||
173 | if (!win) return; | ||
174 | |||
175 | // Elm will delete our widgets, but if we are using eo, we need to unref them. | ||
176 | EINA_CLIST_FOR_EACH_ENTRY(wid, &win->widgets, Widget, node) | ||
177 | { | ||
178 | if (wid->on_del) wid->on_del(wid, wid->obj, NULL); | ||
179 | eo_unref(wid->obj); | ||
180 | } | ||
181 | if (win->on_del) win->on_del(win, win->win, NULL); | ||
182 | evas_object_del(win->win); | ||
183 | } | ||
184 | |||
185 | Widget *widgetAdd(winFang *win, const Eo_Class *klass, Evas_Object *parent, char *title) | ||
186 | { | ||
187 | Widget *result; | ||
188 | |||
189 | result = calloc(1, sizeof(Widget)); | ||
190 | strcpy(result->magic, "Widget"); | ||
191 | eina_clist_add_head(&win->widgets, &result->node); | ||
192 | |||
193 | if (parent) | ||
194 | { | ||
195 | result->obj = eo_add(klass, parent, | ||
196 | evas_obj_size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND), | ||
197 | evas_obj_size_hint_align_set(EVAS_HINT_FILL, EVAS_HINT_FILL), | ||
198 | evas_obj_visibility_set(EINA_TRUE) | ||
199 | ); | ||
200 | if (title) | ||
201 | { | ||
202 | result->label = strdup(title); | ||
203 | elm_object_text_set(result->obj, result->label); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | return result; | ||
208 | } | ||
diff --git a/src/libraries/winFang.h b/src/libraries/winFang.h new file mode 100644 index 0000000..219dcf0 --- /dev/null +++ b/src/libraries/winFang.h | |||
@@ -0,0 +1,49 @@ | |||
1 | #define EFL_API_OVERRIDE 1 | ||
2 | /* Enable access to unstable EFL API that are still in beta */ | ||
3 | #define EFL_BETA_API_SUPPORT 1 | ||
4 | /* Enable access to unstable EFL EO API. */ | ||
5 | #define EFL_EO_API_SUPPORT 1 | ||
6 | |||
7 | |||
8 | #include <Eo.h> | ||
9 | #include <Eina.h> | ||
10 | #include <Evas.h> | ||
11 | #include <Elementary.h> | ||
12 | |||
13 | |||
14 | typedef struct _winFang | ||
15 | { | ||
16 | Evas_Object *win; | ||
17 | Eina_Clist widgets; | ||
18 | int x, y, w, h; | ||
19 | Eina_Bool internal; | ||
20 | |||
21 | Evas_Object *hand[4]; | ||
22 | |||
23 | Eina_Clist node; | ||
24 | void *data; | ||
25 | Evas_Smart_Cb on_del; | ||
26 | } winFang; | ||
27 | |||
28 | typedef struct _Widget | ||
29 | { | ||
30 | char magic[8]; | ||
31 | Evas_Object *obj; | ||
32 | |||
33 | char *label, *look, *action, *help; | ||
34 | // foreground / background colour | ||
35 | // thing | ||
36 | // types {} | ||
37 | // skangCoord x, y, w, h | ||
38 | |||
39 | Eina_Clist node; | ||
40 | void *data; | ||
41 | Evas_Smart_Cb on_del; | ||
42 | } Widget; | ||
43 | |||
44 | winFang *winFangAdd(Evas_Object *parent, int x, int y, int w, int h, char *title, char *name); | ||
45 | void winFangHide(winFang *win); | ||
46 | void winFangShow(winFang *win); | ||
47 | void winFangDel(winFang *win); | ||
48 | |||
49 | Widget *widgetAdd(winFang *win, const Eo_Class *klass, Evas_Object *parent, char *title); | ||