aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/extantz/winFang.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/extantz/winFang.c')
-rw-r--r--src/extantz/winFang.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/extantz/winFang.c b/src/extantz/winFang.c
new file mode 100644
index 0000000..0f0328f
--- /dev/null
+++ b/src/extantz/winFang.c
@@ -0,0 +1,154 @@
1#include "extantz.h"
2
3
4// Elm inlined image windows needs this to change focus on mouse click.
5// Evas style event callback.
6static 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
14static 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
52static void create_handles(Evas_Object *obj)
53{
54 int i;
55 Evas_Coord x, y, w, h;
56
57 evas_object_geometry_get(obj, &x, &y, &w, &h);
58 for (i = 0; i < 4; i++)
59 {
60 Evas_Object *hand;
61 char buf[PATH_MAX];
62 char key[32];
63
64 hand = evas_object_image_filled_add(evas_object_evas_get(obj));
65 evas_object_resize(hand, 31, 31);
66 snprintf(buf, sizeof(buf), "%s/pt.png", elm_app_data_dir_get());
67 evas_object_image_file_set(hand, buf, NULL);
68 if (i == 0) evas_object_move(hand, x - 15, y - 15);
69 else if (i == 1) evas_object_move(hand, x + w - 15, y - 15);
70 else if (i == 2) evas_object_move(hand, x + w - 15, y + h - 15);
71 else if (i == 3) evas_object_move(hand, x - 15, y + h - 15);
72 evas_object_event_callback_add(hand, EVAS_CALLBACK_MOUSE_MOVE, cb_mouse_move, obj);
73 evas_object_show(hand);
74 snprintf(key, sizeof(key), "h-%i\n", i);
75 evas_object_data_set(obj, key, hand);
76 }
77}
78
79winFang *winFangAdd(globals *ourGlobals)
80{
81 winFang *result;
82 Evas_Object *bg;
83
84 result = calloc(1, sizeof(winFang));
85 eina_clist_init(&result->widgets);
86
87 // In theory this should create an EWS window, in practice, I'm not seeing any difference.
88 // 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.
89// elm_config_engine_set("ews");
90 result->win = elm_win_add(ourGlobals->win, "inlined", ELM_WIN_INLINED_IMAGE);
91 // 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.
92 // According to the Elm inlined image window example, this is what's needed to.
93 evas_object_event_callback_add(elm_win_inlined_image_object_get(result->win), EVAS_CALLBACK_MOUSE_DOWN, _cb_mouse_down_elm, NULL);
94 elm_win_alpha_set(result->win, EINA_TRUE);
95
96 // Apparently transparent is not good enough for ELM backgrounds, so make it a rectangle.
97 // Apparently coz ELM prefers stuff to have edjes. A bit over the top if all I want is a transparent rectangle.
98 bg = evas_object_rectangle_add(evas_object_evas_get(result->win));
99 evas_object_color_set(bg, 50, 0, 100, 100);
100 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
101 elm_win_resize_object_add(result->win, bg);
102 evas_object_show(bg);
103
104 return result;
105}
106
107void winFangComplete(globals *ourGlobals, winFang *win, int x, int y, int w, int h)
108{
109 // image object for win is unlinked to its pos/size - so manual control
110 // this allows also for using map and other things with it.
111 evas_object_move(elm_win_inlined_image_object_get(win->win), x, y);
112 // Odd, it needs to be resized twice. WTF?
113 evas_object_resize(win->win, w, h);
114 evas_object_resize(elm_win_inlined_image_object_get(win->win), w, h);
115 evas_object_show(win->win);
116 create_handles(elm_win_inlined_image_object_get(win->win));
117}
118
119void winFangDel(globals *ourGlobals, winFang *win)
120{
121 Widget *wid;
122
123 if (!win) return;
124
125 // Elm will delete our widgets, but if we are using eo, we need to unref them.
126 EINA_CLIST_FOR_EACH_ENTRY(wid, &win->widgets, Widget, node)
127 {
128 if (wid->on_del) wid->on_del(wid, wid->obj, NULL);
129 eo_unref(wid->obj);
130 }
131 if (win->on_del) win->on_del(win, win->win, NULL);
132 evas_object_del(win->win);
133}
134
135Widget *widgetAdd(winFang *win, const Eo_Class *klass, Evas_Object *parent, char *title)
136{
137 Widget *result;
138
139 result = calloc(1, sizeof(Widget));
140 strcpy(result->magic, "Widget");
141 eina_clist_add_head(&win->widgets, &result->node);
142
143 if (parent)
144 {
145 result->obj = eo_add(klass, parent,
146 evas_obj_size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND),
147 evas_obj_size_hint_align_set(EVAS_HINT_FILL, EVAS_HINT_FILL),
148 evas_obj_visibility_set(EINA_TRUE)
149 );
150 if (title) elm_object_text_set(result->obj, title);
151 }
152
153 return result;
154}