summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordiscomfitor <michael.blumenkrantz@gmail.com>2013-09-01 15:41:30 +0100
committerdiscomfitor <michael.blumenkrantz@gmail.com>2013-09-01 15:41:50 +0100
commite91397adf3a42fbe12ed28e3d013ba00aadc39cb (patch)
treea0961abbd755e429149fe50718a93a9d73cc2440
parent1b3ecbf7ac87e0db422767a0b2144154e8ce81ec (diff)
fix a bunch of window delete stuff, add chat cycling
-rw-r--r--src/modules/chat_basic.c223
1 files changed, 159 insertions, 64 deletions
diff --git a/src/modules/chat_basic.c b/src/modules/chat_basic.c
index ec6a57e..7a76c2a 100644
--- a/src/modules/chat_basic.c
+++ b/src/modules/chat_basic.c
@@ -21,35 +21,8 @@
21static Eina_List *handlers = NULL; 21static Eina_List *handlers = NULL;
22static Eina_Hash *chats = NULL; 22static Eina_Hash *chats = NULL;
23 23
24static void 24typedef Elm_Object_Item *(Chat_Toolbar_Item_Cycle_Cb)(const Elm_Object_Item*);
25chat_win_key(S2_Auth *sa, Evas *e EINA_UNUSED, Evas_Object *obj, Evas_Event_Key_Down *ev) 25typedef Elm_Object_Item *(Chat_Toolbar_Item_End_Cb)(const Evas_Object *);
26{
27 if ((!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "KP_Enter")))
28 {
29 char *s;
30 const char *txt;
31 S2_Contact *sc;
32 Evas_Object *pane, *entry;
33
34 /* FIXME: add popup error or something? */
35 if (shotgun_connection_state_get(sa->auth) != SHOTGUN_CONNECTION_STATE_CONNECTED) return;
36 sc = ui_contact_find(sa, evas_object_data_get(obj, "focused"));
37
38 pane = evas_object_data_get(obj, sc->jid);
39 entry = elm_object_part_content_get(pane, "elm.swallow.right");
40
41 txt = elm_entry_entry_get(entry);
42 if ((!txt) || (!txt[0])) return;
43
44 s = elm_entry_markup_to_utf8(txt);
45
46 ui_shotgun_message_send(sa, sc, s, SHOTGUN_MESSAGE_STATUS_ACTIVE, sc->xhtml_im);
47 elm_entry_entry_set(entry, "");
48 elm_entry_cursor_end_set(entry);
49
50 free(s);
51 }
52}
53 26
54static void 27static void
55chat_insert(Evas_Object *win, Evas_Object *entry, const char *from, const char *msg) 28chat_insert(Evas_Object *win, Evas_Object *entry, const char *from, const char *msg)
@@ -157,10 +130,142 @@ chat_win_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info
157 eina_hash_del_by_key(chats, &sa->auth); 130 eina_hash_del_by_key(chats, &sa->auth);
158} 131}
159 132
133static void
134chat_focus(Evas_Object *pane)
135{
136 Evas_Object *ic, *cur, *ly, *win = evas_object_data_get(pane, "win");
137 Elm_Object_Item *it;
138 Eina_Stringshare *focused;
139 S2_Contact *sc;
140
141 sc = evas_object_data_get(pane, "sc");
142 focused = evas_object_data_get(win, "focused");
143 /* trying to refocus current focused */
144 if (focused == sc->jid) return;
145 ly = evas_object_data_get(win, "layout");
146
147 cur = elm_layout_content_unset(ly, "swallow.chat");
148 if (cur) evas_object_hide(cur);
149 elm_layout_content_set(ly, "swallow.chat", pane);
150 evas_object_data_set(win, "focused", sc->jid);
151 evas_object_data_del(pane, "updated");
152
153 elm_win_title_set(win, ui_contact_name_get(sc));
154 it = evas_object_data_get(pane, "toolbar_item");
155 if (it) //can be NULL if selected during creation */
156 elm_toolbar_item_selected_set(it, 1);
157 elm_object_focus_set(elm_object_part_content_get(pane, "elm.swallow.right"), 1);
158
159 ic = evas_object_data_get(win, "icon");
160 if (sc->info.photo.data && sc->info.photo.size)
161 evas_object_image_memfile_set(ic, sc->info.photo.data, sc->info.photo.size, NULL, NULL);
162 else
163 evas_object_image_file_set(ic, evas_object_data_get(win, "file"), "chat_basic/userunknown");
164 elm_win_icon_object_set(win, ic);
165}
166
167
168static void
169chat_cycle(Evas_Object *win, Chat_Toolbar_Item_Cycle_Cb it_cb, Chat_Toolbar_Item_End_Cb end_cb)
170{
171 Evas_Object *pane, *p;
172 Eina_Stringshare *focused;
173 Elm_Object_Item *start, *it, *itr;
174
175 focused = evas_object_data_get(win, "focused");
176 pane = evas_object_data_get(win, focused);
177 start = evas_object_data_get(pane, "toolbar_item");
178 if (!start) return; //probably window deleted
179 /* starting point */
180 it = itr = it_cb(start);
181 do {
182 p = elm_object_item_data_get(it);
183 if (evas_object_data_get(p, "updated"))
184 {
185 chat_focus(p);
186 return;
187 }
188 it = it_cb(it);
189 } while (it);
190 it = end_cb(elm_object_item_widget_get(start));
191 do {
192 if (it == start) break;
193 p = elm_object_item_data_get(it);
194 if (evas_object_data_get(p, "updated"))
195 {
196 chat_focus(p);
197 return;
198 }
199 it = it_cb(it);
200 } while (it);
201 chat_focus(elm_object_item_data_get(itr));
202}
203
204static void
205chat_cycle_prev(Evas_Object *win)
206{
207 chat_cycle(win, elm_toolbar_item_prev_get, elm_toolbar_last_item_get);
208}
209
210static void
211chat_cycle_next(Evas_Object *win)
212{
213 chat_cycle(win, elm_toolbar_item_next_get, elm_toolbar_first_item_get);
214}
215
216static void
217chat_win_key(S2_Auth *sa, Evas *e EINA_UNUSED, Evas_Object *obj, Evas_Event_Key_Down *ev)
218{
219 if ((!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "KP_Enter")))
220 {
221 char *s;
222 const char *txt;
223 S2_Contact *sc;
224 Evas_Object *pane, *entry;
225
226 /* FIXME: add popup error or something? */
227 if (shotgun_connection_state_get(sa->auth) != SHOTGUN_CONNECTION_STATE_CONNECTED) return;
228 sc = ui_contact_find(sa, evas_object_data_get(obj, "focused"));
229
230 pane = evas_object_data_get(obj, sc->jid);
231 entry = elm_object_part_content_get(pane, "elm.swallow.right");
232
233 txt = elm_entry_entry_get(entry);
234 if ((!txt) || (!txt[0])) return;
235
236 s = elm_entry_markup_to_utf8(txt);
237
238 ui_shotgun_message_send(sa, sc, s, SHOTGUN_MESSAGE_STATUS_ACTIVE, sc->xhtml_im);
239 elm_entry_entry_set(entry, "");
240 elm_entry_cursor_end_set(entry);
241
242 free(s);
243 }
244 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
245 chat_cycle_next(obj);
246 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
247 chat_cycle_prev(obj);
248 else if (!strcmp(ev->keyname, "Tab"))
249 {
250 if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
251 chat_cycle_prev(obj);
252 else
253 chat_cycle_next(obj);
254 }
255 else if ((!strcmp(ev->keyname, "w")) || (!strcmp(ev->keyname, "Escape")))
256 {
257 Eina_Stringshare *focused;
258
259 focused = evas_object_data_get(obj, "focused");
260 evas_object_del(evas_object_data_get(obj, focused));
261 }
262}
263
264
160static Evas_Object * 265static Evas_Object *
161chat_win_new(S2_Auth *sa) 266chat_win_new(S2_Auth *sa)
162{ 267{
163 Evas_Object *win, *box, *ly, *tb; 268 Evas_Object *win, *box, *ly, *tb, *ic;
164 const char *override; 269 const char *override;
165 char buf[PATH_MAX]; 270 char buf[PATH_MAX];
166 Evas *e; 271 Evas *e;
@@ -185,6 +290,10 @@ chat_win_new(S2_Auth *sa)
185 1 | evas_object_key_grab(win, "Tab", ctrl | shift, alt, 1); /* worst warn_unused ever. */ 290 1 | evas_object_key_grab(win, "Tab", ctrl | shift, alt, 1); /* worst warn_unused ever. */
186 1 | evas_object_key_grab(win, "Return", 0, ctrl | shift | alt, 1); /* worst warn_unused ever. */ 291 1 | evas_object_key_grab(win, "Return", 0, ctrl | shift | alt, 1); /* worst warn_unused ever. */
187 1 | evas_object_key_grab(win, "KP_Enter", 0, ctrl | shift | alt, 1); /* worst warn_unused ever. */ 292 1 | evas_object_key_grab(win, "KP_Enter", 0, ctrl | shift | alt, 1); /* worst warn_unused ever. */
293 1 | evas_object_key_grab(win, "Escape", 0, ctrl | shift | alt, 1); /* worst warn_unused ever. */
294
295 ic = evas_object_image_filled_add(e);
296 evas_object_data_set(win, "icon", ic);
188 297
189 box = elm_box_add(win); 298 box = elm_box_add(win);
190 EXPAND(box); 299 EXPAND(box);
@@ -221,31 +330,6 @@ chat_win_new(S2_Auth *sa)
221} 330}
222 331
223static void 332static void
224chat_focus(Evas_Object *pane)
225{
226 Evas_Object *cur, *ly, *win = elm_object_top_widget_get(pane);
227 Elm_Object_Item *it;
228 Eina_Stringshare *focused;
229 S2_Contact *sc;
230
231 sc = evas_object_data_get(pane, "sc");
232 focused = evas_object_data_get(win, "focused");
233 /* trying to refocus current focused */
234 if (focused == sc->jid) return;
235 ly = evas_object_data_get(win, "layout");
236
237 cur = elm_layout_content_unset(ly, "swallow.chat");
238 if (cur) evas_object_hide(cur);
239 elm_layout_content_set(ly, "swallow.chat", pane);
240 evas_object_data_set(win, "focused", sc->jid);
241
242 it = evas_object_data_get(pane, "toolbar_item");
243 if (it) //can be NULL if selected during creation */
244 elm_toolbar_item_selected_set(it, 1);
245 elm_object_focus_set(elm_object_part_content_get(pane, "elm.swallow.right"), 1);
246}
247
248static void
249chat_toolbar_select(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 333chat_toolbar_select(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
250{ 334{
251 chat_focus(data); 335 chat_focus(data);
@@ -255,28 +339,28 @@ static void
255chat_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *pane, void *event_info EINA_UNUSED) 339chat_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *pane, void *event_info EINA_UNUSED)
256{ 340{
257 Evas_Object *win; 341 Evas_Object *win;
258 Elm_Object_Item *it, *next; 342 Elm_Object_Item *it;
259 S2_Contact *sc = data; 343 S2_Contact *sc = data;
260 Eina_Stringshare *focused; 344 Eina_Stringshare *focused;
261 345
262 win = elm_object_top_widget_get(pane); 346 win = evas_object_data_get(pane, "win");
263 focused = evas_object_data_get(win, "focused"); 347 focused = evas_object_data_get(win, "focused");
348 evas_object_event_callback_del(pane, EVAS_CALLBACK_DEL, chat_del_cb);
264 it = evas_object_data_get(pane, "toolbar_item"); 349 it = evas_object_data_get(pane, "toolbar_item");
265 if (!it) return; //canvas deleted 350 if (!it) return; //canvas deleted
351 evas_object_data_del(win, sc->jid);
266 if (focused != sc->jid) 352 if (focused != sc->jid)
267 { 353 {
268 elm_object_item_del(it); 354 elm_object_item_del(it);
269 return; 355 return;
270 } 356 }
271 next = elm_toolbar_item_prev_get(it); 357 if (elm_toolbar_items_count(elm_layout_content_get(evas_object_data_get(win, "layout"), "swallow.bar")) == 1)
272 if (!next) elm_toolbar_item_next_get(it); 358 evas_object_del(win);
273 if (next) 359 else
274 { 360 {
275 elm_toolbar_item_selected_set(next, 1); 361 chat_cycle_next(win);
276 elm_object_item_del(it); 362 elm_object_item_del(it);
277 } 363 }
278 else
279 evas_object_del(win);
280} 364}
281 365
282static void 366static void
@@ -296,6 +380,12 @@ chat_new(Evas_Object *win, S2_Contact *sc)
296 380
297 pane = elm_panes_add(win); 381 pane = elm_panes_add(win);
298 evas_object_event_callback_add(pane, EVAS_CALLBACK_DEL, chat_del_cb, sc); 382 evas_object_event_callback_add(pane, EVAS_CALLBACK_DEL, chat_del_cb, sc);
383 /* elm is hilarious:
384 * if a widget is not directly parented to another elm widget,
385 * that widget is considered "not elm" and widget heirarchy functions will
386 * all return the same object.
387 */
388 evas_object_data_set(pane, "win", win);
299 evas_object_data_set(pane, "sc", sc); 389 evas_object_data_set(pane, "sc", sc);
300 evas_object_data_set(win, sc->jid, pane); 390 evas_object_data_set(win, sc->jid, pane);
301 elm_panes_horizontal_set(pane, 1); 391 elm_panes_horizontal_set(pane, 1);
@@ -366,7 +456,12 @@ chat_message(void *d EINA_UNUSED, int t EINA_UNUSED, Shotgun_Event_Message *ev)
366 win = eina_hash_find(chats, &ev->account); 456 win = eina_hash_find(chats, &ev->account);
367 jid = ui_jid_base_get(ev->jid); 457 jid = ui_jid_base_get(ev->jid);
368 pane = evas_object_data_get(win, jid); 458 pane = evas_object_data_get(win, jid);
369 if (!pane) 459 if (pane)
460 {
461 if (!evas_object_visible_get(pane))
462 evas_object_data_set(pane, "updated", (void*)1);
463 }
464 else
370 { 465 {
371 S2_Contact *sc; 466 S2_Contact *sc;
372 467