diff options
Diffstat (limited to 'src/extantz/winFang.c')
-rw-r--r-- | src/extantz/winFang.c | 154 |
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. | ||
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 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 | |||
79 | winFang *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 | |||
107 | void 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 | |||
119 | void 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 | |||
135 | Widget *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 | } | ||