Enlightenment CVS committal

Author  : dj2
Project : e17
Module  : libs/ewl

Dir     : e17/libs/ewl/src/lib


Modified Files:
        ewl_enums.h ewl_misc.c ewl_text.c ewl_text.h ewl_widget.c 


Log Message:
- do some cleanup in the ewl_widget that was missing
- add in triggers for the ewl_text. This allows you to make things like html
  a href tags in ewl_text boxes
  - multiline triggers are not currently supported.
- several bug fixes for the ewl_text stuff

===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_enums.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -3 -r1.5 -r1.6
--- ewl_enums.h 30 Jun 2005 19:20:30 -0000      1.5
+++ ewl_enums.h 21 Jul 2005 00:47:58 -0000      1.6
@@ -311,6 +311,13 @@
 };
 typedef enum Ewl_Text_Style Ewl_Text_Style;
 
+enum Ewl_Text_Trigger_Type {
+       EWL_TEXT_TRIGGER_TYPE_NONE,
+       EWL_TEXT_TRIGGER_TYPE_SELECTION,
+       EWL_TEXT_TRIGGER_TYPE_TRIGGER
+};
+typedef enum Ewl_Text_Trigger_Type Ewl_Text_Trigger_Type;
+
 /**
  * @}
  */
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_misc.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -3 -r1.11 -r1.12
--- ewl_misc.c  6 Jul 2005 13:44:39 -0000       1.11
+++ ewl_misc.c  21 Jul 2005 00:47:58 -0000      1.12
@@ -30,6 +30,7 @@
 static unsigned int    print_theme_keys = 0;
 static unsigned int    debug_level = 0;
 
+static Ecore_Idle_Enterer *idle_enterer = NULL;
 static int _ewl_init_count = 0;
 
 /*
@@ -174,7 +175,7 @@
 
        ewl_embed_list = ecore_list_new();
        ewl_window_list = ecore_list_new();
-       ecore_idle_enterer_add(ewl_idle_render, NULL);
+       idle_enterer = ecore_idle_enterer_add(ewl_idle_render, NULL);
 
        ewl_text_context_init();
 
@@ -193,7 +194,6 @@
 
        if (--_ewl_init_count)
                DRETURN_INT(_ewl_init_count, DLEVEL_STABLE);
-
        /*
         * Destroy all existing widgets.
         */
@@ -207,6 +207,12 @@
                ewl_embed_list = NULL;
        }
 
+       ewl_text_context_shutdown();
+
+       ecore_idle_enterer_del(idle_enterer);
+       idle_enterer = NULL;
+
+
        /*
         * Shut down the various EWL subsystems cleanly.
         */
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_text.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -3 -r1.9 -r1.10
--- ewl_text.c  10 Jul 2005 22:13:48 -0000      1.9
+++ ewl_text.c  21 Jul 2005 00:47:58 -0000      1.10
@@ -13,8 +13,6 @@
  *   ewl_text_context_default_create
  *   - new theme keys for the align/wrap stuff
  * - need to fill in the condense function
- * - need to wrap the click->coord stuff. This has to be careful and add/sub
- *   the \n and \t from the text when going too/from textblock
  */
 
 /* Make a static hash to look up the context's. They can be shared between
@@ -22,6 +20,7 @@
  * they can be destroyed
  */
 static Ecore_Hash *context_hash = NULL;
+static void ewl_text_context_cb_free(void *data);
 static int ewl_text_context_compare(Ewl_Text_Context *a, Ewl_Text_Context *b);
 static void ewl_text_context_print(Ewl_Text_Context *tx, char *indent);
 static Ewl_Text_Context *ewl_text_context_dup(Ewl_Text_Context *old);
@@ -39,6 +38,12 @@
 static void ewl_text_op_set(Ewl_Text *t, unsigned int context_mask, 
                                                Ewl_Text_Context *tx_change);
 
+static void ewl_text_triggers_remove(Ewl_Text *t);
+static void ewl_text_trigger_cb_free(void *value, void *data);
+static void ewl_text_triggers_cb_free(void *data);
+static void ewl_text_triggers_shift(Ewl_Text *t, unsigned int pos, 
+                                                       unsigned int len);
+
 /**
  * @param text: The text to set into the widget
  * @return Returns a new Ewl_Text widget on success, NULL on failure.
@@ -81,6 +86,9 @@
        }
        ewl_widget_inherit(EWL_WIDGET(t), "text");
 
+       t->triggers = ecore_list_new();
+       ecore_list_set_free_cb(t->triggers, ewl_text_triggers_cb_free);
+
        /* create the formatting tree before we do any formatting */
        t->formatting = ewl_text_btree_new();
        if (!t->formatting) 
@@ -101,6 +109,8 @@
                                        ewl_text_cb_show, NULL);
        ewl_callback_append(EWL_WIDGET(t), EWL_CALLBACK_HIDE,
                                        ewl_text_cb_hide, NULL);
+       ewl_callback_append(EWL_WIDGET(t), EWL_CALLBACK_DESTROY,
+                                       ewl_text_cb_destroy, NULL);
 
        DRETURN_INT(TRUE, DLEVEL_STABLE);
 }
@@ -280,7 +290,7 @@
 {
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("t", t);
-
+       
        ewl_text_text_insert(t, NULL, 0);
        ewl_text_text_insert(t, text, t->cursor_position);
 
@@ -342,6 +352,8 @@
                }
                t->text = NULL;
                t->length = 0;
+               t->cursor_position = 0;
+
        }
        else if (!t->text)
        {
@@ -380,9 +392,14 @@
                t->text[t->length] = '\0';
 
                ewl_text_btree_text_context_insert(t->formatting, 
t->current_context, idx, len);
-               t->cursor_position += len;
+               t->cursor_position = (idx + len - 1);
        }
 
+       if (text)
+               ewl_text_triggers_shift(t, idx, strlen(text));
+       else
+               ewl_text_triggers_remove(t);
+
        if (REALIZED(t))
                ewl_text_display(t);
 
@@ -1699,9 +1716,469 @@
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
+/**
+ * @param t: The Ewl_Text into which to add the trigger
+ * @param trigger: The Ewl_Text_Trigger to add to the text
+ * @return Returns TRUE on successfull addition or FALSE on failure
+ *
+ * This will add the given trigger. The trigger must have size greater then
+ * 0, the trigger must not run over the end of the text and two triggers can
+ * not overlap.
+ */
+unsigned int
+ewl_text_trigger_add(Ewl_Text *t, Ewl_Text_Trigger *trigger)
+{
+       Ewl_Text_Trigger *cur;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("t", t, FALSE);
+       DCHECK_PARAM_PTR_RET("trigger", trigger, FALSE);
+
+       /* if we have no length, we start past the end of the text, or we
+        * extend past the end of the text then return an error */
+       if ((trigger->len == 0) || (trigger->pos > t->length)
+                       || ((trigger->pos + trigger->len) > t->length))
+       {
+               DRETURN_INT(FALSE, DLEVEL_STABLE);
+       }
+
+       trigger->parent = t;
+
+       ecore_list_goto_first(t->triggers);
+       while ((cur = ecore_list_next(t->triggers)))
+       {
+               if (trigger->pos < cur->pos)
+               {
+                       if ((trigger->pos + trigger->len) < cur->pos)
+                               break;
+                       /* overlapping triggers */
+                       DWARNING("Overlapping triggers are not allowed.\n");
+                       DRETURN_INT(FALSE, DLEVEL_STABLE);
+               }
+
+               if ((trigger->pos > (cur->pos + cur->len)))
+                       continue;
+
+               /* do not allow overlapping triggers */
+               if ((trigger->pos >= cur->pos) && (trigger->pos <= (cur->pos + 
cur->len)))
+               {
+                       DWARNING("Overlapping triggers are not allowed.\n");
+                       DRETURN_INT(FALSE, DLEVEL_STABLE);
+               }
+       }
+
+       if (cur)
+       {
+               /* we need to set our position to the one before the one we 
+                * are on because the _next callin the while will have
+                * advanced usto the next node, but we want to insert
+                * at the one before that */
+               ecore_list_goto_index(t->triggers, 
ecore_list_index(t->triggers) - 1);
+                ecore_list_insert(t->triggers, trigger);
+       }
+       else 
+               ecore_list_append(t->triggers, trigger);
+
+       /* we have to append this to the text so it will get cleaned up when
+        * the text widget is destroyed */
+       ewl_container_child_append(EWL_CONTAINER(t), EWL_WIDGET(trigger));
+
+       DRETURN_INT(TRUE, DLEVEL_STABLE);
+}
+
+/**
+ * @param t: The Ewl_Text to remove the trigger from
+ * @param trigger: The Ewl_Text_Trigger to remove
+ *
+ * This will remove the trigger from the text, but will NOT free the
+ * trigger.
+ */
+void
+ewl_text_trigger_del(Ewl_Text *t, Ewl_Text_Trigger *trigger)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+       DCHECK_PARAM_PTR("trigger", trigger);
+
+       ecore_list_goto(t->triggers, trigger);
+       ecore_list_remove(t->triggers);
+
+       trigger->parent = NULL;
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+static void
+ewl_text_triggers_remove(Ewl_Text *t)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+
+       if (!t->triggers) 
+               return;
+
+       ecore_list_for_each(t->triggers, ewl_text_trigger_cb_free, NULL);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+
+/* if we move the text (insertion, deleteion, etc) we need to shift the
+ * position of the current cursors so they appear in the correct positions */
+static void
+ewl_text_triggers_shift(Ewl_Text *t, unsigned int pos, unsigned int len)
+{
+       Ewl_Text_Trigger *cur;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+
+       ecore_list_goto_first(t->triggers);
+       while ((cur = ecore_list_next(t->triggers)))
+       {
+               /* its before us */
+               if ((pos + len) < cur->pos)
+               {
+                       cur->pos += len;
+                       continue;
+               }
+               
+               /* inserted into trigger */
+               if ((cur->pos <= pos) && ((cur->pos + cur->len) > pos))
+               {
+                       cur->len += len;
+                       continue;
+               }
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/*
+ * Trigger stuff 
+ */
+Ewl_Text_Trigger *
+ewl_text_trigger_new(Ewl_Text_Trigger_Type type)
+{
+       Ewl_Text_Trigger *trigger;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       
+       trigger = NEW(Ewl_Text_Trigger, 1);
+       if (!trigger)
+       {
+               DRETURN_PTR(NULL, DLEVEL_STABLE);
+       }
+
+       if (!ewl_text_trigger_init(trigger, type))
+       {
+               FREE(trigger);
+               DRETURN_PTR(NULL, DLEVEL_STABLE);
+       }
+
+       DRETURN_PTR(trigger, DLEVEL_STABLE);
+}
+
+int
+ewl_text_trigger_init(Ewl_Text_Trigger *trigger, Ewl_Text_Trigger_Type type)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("trigger", trigger, FALSE);
+
+       if (!ewl_widget_init(EWL_WIDGET(trigger), "trigger"))
+       {
+               DRETURN_INT(FALSE, DLEVEL_STABLE);
+       }
+       ewl_widget_inherit(EWL_WIDGET(trigger), "trigger");
+
+       trigger->areas = ecore_list_new();
+
+       DRETURN_INT(TRUE, DLEVEL_STABLE);
+}
+
+void
+ewl_text_trigger_free(Ewl_Text_Trigger *t)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+
+       if (t->areas)
+               ecore_list_destroy(t->areas);
+
+       t->parent = NULL;
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+static void
+ewl_text_trigger_cb_free(void *value, void *data)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("data", data);
+
+       ewl_text_trigger_free(data);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+static void
+ewl_text_triggers_cb_free(void *data)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("data", data);
+       
+       ewl_text_trigger_free(data);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+Ewl_Text_Trigger_Type 
+ewl_text_trigger_type_get(Ewl_Text_Trigger *t)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("t", t, EWL_TEXT_TRIGGER_TYPE_NONE);
+
+       DRETURN_INT(t->type, DLEVEL_STABLE);
+}
+
+void 
+ewl_text_trigger_start_pos_set(Ewl_Text_Trigger *t, unsigned int pos)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+
+       t->pos = pos;
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+unsigned int
+ewl_text_trigger_start_pos_get(Ewl_Text_Trigger *t)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("t", t, 0);
+
+       DRETURN_INT(t->pos, DLEVEL_STABLE);
+}
+
+void
+ewl_text_trigger_length_set(Ewl_Text_Trigger *t, unsigned int len)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+
+       t->len = len;
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+unsigned int
+ewl_text_trigger_length_get(Ewl_Text_Trigger *t)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("t", t, 0);
+
+       DRETURN_INT(t->len, DLEVEL_STABLE);
+}
+
 /*
  * Internal stuff 
  */
+void ewl_text_triggers_configure(Ewl_Text *t)
+{
+       Ewl_Text_Trigger *cur;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+
+       if (!t->triggers)
+               return;
+
+       ecore_list_goto_first(t->triggers);
+       while ((cur = ecore_list_next(t->triggers)))
+       {
+               Ewl_Text_Trigger_Area *area;
+
+               if (!cur->areas) 
+                       continue;
+
+               ecore_list_goto_first(cur->areas);
+               while ((area = ecore_list_next(cur->areas)))
+                       ewl_widget_configure(EWL_WIDGET(area));
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void ewl_text_triggers_realize(Ewl_Text *t)
+{
+       Ewl_Text_Trigger *cur;
+       Ewl_Embed *emb;
+       int fiddled, tb_length;
+       Evas_Coord sx, sy, sh, ex, ey, ew, eh;
+       char *ptr;
+       unsigned int cur_idx = 0, cur_tb_idx = 0;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+
+       if (!t->triggers)
+               return;
+
+       emb = ewl_embed_widget_find(EWL_WIDGET(t));
+       if (!emb)
+       {
+               DRETURN(DLEVEL_STABLE);
+       }
+
+       /* we need to get the length of the textblock to make sure we aren't
+        * trying to access one past its end. if we are, we need to do the
+        * previous one then add the previous's width to get the correct x
+        * position */
+       tb_length = evas_object_textblock_length_get(t->textblock);
+
+       ecore_list_goto_first(t->triggers);
+       while ((cur = ecore_list_next(t->triggers)))
+       {
+               fiddled = 0;
+
+               /* get the index of the start of the trigger */
+               for (ptr = (t->text + cur_idx); cur_idx < cur->pos; cur_idx++)
+               {
+                       /* if this isn't a \r\n or \t increment the
+                        * textblock position */
+                       if ((*ptr != '\r') && (*ptr != '\n') && (*ptr != '\t')) 
+                               cur_tb_idx ++;
+                       ptr ++;
+               }
+
+               /* get the position of the start character */
+               evas_object_textblock_char_pos_get(t->textblock, cur_tb_idx,
+                                                               &sx, &sy, NULL, 
&sh);
+
+               /* get the index of the end of the trigger */
+               for (ptr = (t->text + cur_idx);
+                               cur_idx < (cur->pos + cur->len); cur_idx++)
+               {
+                       /* if this isn't a \r\n or \t increment the
+                        * textblock position */
+                       if ((*ptr != '\r') && (*ptr != '\n') && (*ptr != '\t')) 
+                               cur_tb_idx ++;
+                       ptr ++;
+               }
+
+               if (cur_tb_idx >= tb_length)
+               {
+                       cur_tb_idx = tb_length - 1;
+                       fiddled = 1;
+               }
+               evas_object_textblock_char_pos_get(t->textblock, cur_tb_idx,
+                                                               &ex, &ey, &ew, 
&eh);
+
+               if (fiddled)
+                       ex += ew;
+
+               /* whole trigger is on one line */
+               if (sy == ey)
+               {
+                       Ewl_Widget *area;
+
+                       area = ewl_text_trigger_area_new(cur->type);
+                       ewl_container_child_append(EWL_CONTAINER(t), area);
+                       ewl_widget_internal_set(area, TRUE);
+                       ewl_object_geometry_request(EWL_OBJECT(area), sx, sy, 
+                                                       (ex - sx), (ey - sy) + 
eh);
+
+                       ewl_callback_append(area, EWL_CALLBACK_FOCUS_IN, 
+                                               ewl_text_trigger_cb_focus_in, 
cur);
+                       ewl_callback_append(area, EWL_CALLBACK_FOCUS_OUT,
+                                               ewl_text_trigger_cb_focus_out, 
cur);
+                       ewl_callback_append(area, EWL_CALLBACK_MOUSE_DOWN,
+                                               ewl_text_trigger_cb_mouse_down, 
cur);
+                       ewl_callback_append(area, EWL_CALLBACK_MOUSE_UP,
+                                               ewl_text_trigger_cb_mouse_up, 
cur);
+                       ewl_widget_show(area);
+
+                       ecore_list_append(cur->areas, area);
+               } 
+               else /* multline trigger .... ?? */
+               {
+                       printf("FIXME: multline triggers aren't done yet 
...\n");
+               }
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void ewl_text_triggers_unrealize(Ewl_Text *t)
+{
+       Ewl_Text_Trigger *cur;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+
+       if (!t->triggers)
+               return;
+
+       ecore_list_goto_first(t->triggers);
+       while ((cur = ecore_list_next(t->triggers)))
+               ecore_list_clear(cur->areas);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void ewl_text_triggers_show(Ewl_Text *t)
+{
+       Ewl_Text_Trigger *cur;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+
+       if (!t->triggers)
+               return;
+
+       ecore_list_goto_first(t->triggers);
+       while ((cur = ecore_list_next(t->triggers)))
+       {
+               Ewl_Widget *area;
+
+               if (!cur->areas)
+                       continue;
+
+               ecore_list_goto_first(cur->areas);
+               while ((area = ecore_list_next(cur->areas)))
+                       ewl_widget_show(area);
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void ewl_text_triggers_hide(Ewl_Text *t)
+{
+       Ewl_Text_Trigger *cur;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("t", t);
+
+       if (!t->triggers)
+               return;
+
+       ecore_list_goto_first(t->triggers);
+       while ((cur = ecore_list_next(t->triggers)))
+       {
+               Ewl_Widget *area;
+
+               if (!cur->areas)
+                       continue;
+
+               ecore_list_goto_first(cur->areas);
+               while ((area = ecore_list_next(cur->areas)))
+                       ewl_widget_hide(area);
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
 void
 ewl_text_cb_configure(Ewl_Widget *w, void *ev, void *data)
 {
@@ -1729,6 +2206,8 @@
                 * itself behind the scenes */
                evas_damage_rectangle_add(evas_object_evas_get(t->textblock),
                                                        xx, yy, ww, hh);
+
+               ewl_text_triggers_configure(t);
        }
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
@@ -1760,6 +2239,7 @@
        evas_object_pass_events_set(t->textblock, 1);
 
        ewl_text_display(t);
+       ewl_text_triggers_realize(t);
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
@@ -1777,6 +2257,8 @@
        evas_object_del(t->textblock);
        t->textblock = NULL;
 
+       ewl_text_triggers_unrealize(t);
+
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
@@ -1790,6 +2272,8 @@
        t = EWL_TEXT(w);
        evas_object_show(t->textblock);
 
+       ewl_text_triggers_show(t);
+
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
@@ -1803,9 +2287,100 @@
        t = EWL_TEXT(w);
        evas_object_hide(t->textblock);
 
+       ewl_text_triggers_hide(t);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_text_cb_destroy(Ewl_Widget *w, void *ev, void *data)
+{
+       Ewl_Text *t;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       t = EWL_TEXT(w);
+
+       if (t->triggers)
+       {
+               ecore_list_destroy(t->triggers);
+               t->triggers = NULL;
+       }
+
+       ewl_text_btree_free(t->formatting);
+       t->formatting = NULL;
+
+       if (t->current_context)
+       {
+               t->current_context->ref_count --;
+               if (t->current_context->ref_count == 0)
+                       ewl_text_context_free(t->current_context);
+
+               t->current_context = NULL;
+       }
+
+       IF_FREE(t->text);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_text_trigger_cb_focus_in(Ewl_Widget *w, void *ev, void *data)
+{
+       Ewl_Text_Trigger *trigger;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       trigger = data;
+       ewl_callback_call_with_event_data(EWL_WIDGET(trigger), 
+                                       EWL_CALLBACK_FOCUS_IN, ev);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_text_trigger_cb_focus_out(Ewl_Widget *w, void *ev, void *data)
+{
+       Ewl_Text_Trigger *trigger;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       trigger = data;
+       ewl_callback_call_with_event_data(EWL_WIDGET(trigger), 
+                                       EWL_CALLBACK_FOCUS_OUT, ev);
+
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
+void
+ewl_text_trigger_cb_mouse_up(Ewl_Widget *w, void *ev, void *data)
+{
+       Ewl_Text_Trigger *trigger;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       trigger = data;
+       ewl_callback_call_with_event_data(EWL_WIDGET(trigger),
+                                       EWL_CALLBACK_MOUSE_UP, ev);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_text_trigger_cb_mouse_down(Ewl_Widget *w, void *ev, void *data)
+{
+       Ewl_Text_Trigger *trigger;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       trigger = data;
+       ewl_callback_call_with_event_data(EWL_WIDGET(trigger), 
+                                       EWL_CALLBACK_MOUSE_DOWN, ev);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+
 static Ewl_Text_Context *
 ewl_text_context_default_create(Ewl_Text *t)
 {
@@ -1844,9 +2419,17 @@
        {
                context_hash = ecore_hash_new(ecore_str_hash, 
ecore_str_compare);
                ecore_hash_set_free_key(context_hash, free);
+               ecore_hash_set_free_value(context_hash, 
ewl_text_context_cb_free);
        }
 }
 
+void
+ewl_text_context_shutdown(void)
+{
+       if (context_hash)
+               ecore_hash_destroy(context_hash);
+}
+
 static char *
 ewl_text_context_name_get(Ewl_Text_Context *tx, unsigned int context_mask,
                                                Ewl_Text_Context *tx_change)
@@ -2136,6 +2719,20 @@
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
+static void
+ewl_text_context_cb_free(void *data)
+{
+       Ewl_Text_Context *tx;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("data", data);
+
+       tx = data;
+       ewl_text_context_free(tx);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
 void
 ewl_text_context_font_set(Ewl_Text_Context *tx, const char *font)
 {
@@ -2519,13 +3116,13 @@
 
        if (tree->tx)
        {
-               tree->tx--;
-               if (tree->tx->ref_count <= 0)
+               tree->tx->ref_count --;
+               if (tree->tx->ref_count == 0)
                        ewl_text_context_free(tree->tx);
 
                tree->tx = NULL;
        }
-       IF_FREE(tree);
+       FREE(tree);
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
@@ -2596,7 +3193,6 @@
                DRETURN(DLEVEL_STABLE);
        }
 
-
        /* no children but we have a tx, we need to split this node */
        if (!tree->children)
        {
@@ -2718,7 +3314,6 @@
                        ctx->ref_count --;
                        if (ctx->ref_count == 0)
                                ewl_text_context_free(ctx);
-
                        tree->tx = new_tx;
                }
                else
@@ -2780,7 +3375,8 @@
        ecore_list_goto_first(tree->children);
        while ((child = ecore_list_next(tree->children)))
        {
-               if ((sum <= idx) && ((sum + child->length) >= idx))
+
+               if ((sum <= idx) && ((sum + child->length) > idx))
                {
                        int new_len;
 
@@ -2830,7 +3426,7 @@
        {
                int deleted = 0;
 
-               if ((sum <= idx) && ((sum + child->length) >= idx))
+               if ((sum <= idx) && ((sum + child->length) > idx))
                {
                        int del_length;
                        int new_len;
@@ -2952,7 +3548,13 @@
        while ((child = ecore_list_next(tree->children)))
        {
                char *t;
-               t = NEW(char, strlen(indent + 3));
+               t = NEW(char, strlen(indent) + 3);
+               if (!t)
+               {
+                       printf("OUT OF MEMORY...\n");
+                       DRETURN(DLEVEL_STABLE);
+               }
+
                sprintf(t, "%s  ", indent);
                ewl_text_btree_dump(child, t);
                FREE(t);
@@ -3056,11 +3658,13 @@
                char fmt[2048];
                char tmp;
                char *ptr;
-               char style[256];
+               char style[512];
                char align[128];
                Ewl_Text_Context *ctx;
 
                ctx = tree->tx;
+               style[0] = '\0';
+               align[0] = '\0';
 
                /* create the style string */
                ptr = style;
@@ -3219,4 +3823,48 @@
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
+/*
+ * Ewl_Text_Trigger_Area stuff
+ */
+Ewl_Widget *
+ewl_text_trigger_area_new(Ewl_Text_Trigger_Type type)
+{
+       Ewl_Text_Trigger_Area *area;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       area = NEW(Ewl_Text_Trigger_Area, 1);
+       if (!area)
+       {
+               DRETURN_PTR(NULL, DLEVEL_STABLE);
+       }
+
+       if (!ewl_text_trigger_area_init(area, type))
+       {
+               ewl_widget_destroy(EWL_WIDGET(area));
+               DRETURN_PTR(NULL, DLEVEL_STABLE);
+       }
+
+       DRETURN_PTR(area, DLEVEL_STABEL);
+}
+
+int
+ewl_text_trigger_area_init(Ewl_Text_Trigger_Area *area, 
+                               Ewl_Text_Trigger_Type type)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("area", area, FALSE);
+
+       if (!ewl_widget_init(EWL_WIDGET(area), 
+               ((type == EWL_TEXT_TRIGGER_TYPE_SELECTION) 
+                       ? "selection" : "trigger")))
+       {
+               DRETURN_INT(FALSE, DLEVEL_STABLE);
+       }
+       ewl_widget_color_set(EWL_WIDGET(area), 0, 0, 0, 0);
+
+       DRETURN_INT(TRUE, DLEVEL_STABLE);
+}
+
+
 
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_text.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -3 -r1.6 -r1.7
--- ewl_text.h  2 Jul 2005 17:11:13 -0000       1.6
+++ ewl_text.h  21 Jul 2005 00:47:58 -0000      1.7
@@ -28,6 +28,7 @@
 
 typedef struct Ewl_Text_BTree Ewl_Text_BTree;
 typedef struct Ewl_Text_Context Ewl_Text_Context;
+typedef struct Ewl_Text_Trigger Ewl_Text_Trigger;
 
 /**
  * Provides for layout of text as well as formatting portions of the text in
@@ -53,6 +54,9 @@
        Ewl_Text_BTree          *formatting;      /**< The formatting tree */
 
        unsigned int             delete_count;    /**< Number of deletes */
+
+       Ecore_List              *triggers;        /**< The list of triggers */
+       Ewl_Text_Trigger        *selection;       /**< The current selection */
 };
 
 Ewl_Widget     *ewl_text_new(const char *text);
@@ -172,14 +176,60 @@
                                                        unsigned int *b, 
unsigned int *a,
                                                        unsigned int idx);
 
+unsigned int    ewl_text_trigger_add(Ewl_Text *t, Ewl_Text_Trigger *trigger);
+void            ewl_text_trigger_del(Ewl_Text *t, Ewl_Text_Trigger *trigger);
+
+/*
+ * Trigger stuf
+ */
+struct Ewl_Text_Trigger
+{
+       Ewl_Widget               widget;        /**< Inherit from widget */
+       Ewl_Text_Trigger_Type    type;          /**< Trigger type */
+       unsigned int             pos;           /**< Trigger start position */
+       unsigned int             len;           /**< Trigger length */
+
+       Ewl_Text                *parent;        /**< The parent text area */
+       Ecore_List              *areas;         /**< The list of objects making 
up the trigger */
+};
+
+#define EWL_TEXT_TRIGGER(trigger) ((Ewl_Text_Trigger *) trigger)
+
+Ewl_Text_Trigger *ewl_text_trigger_new(Ewl_Text_Trigger_Type type);
+int             ewl_text_trigger_init(Ewl_Text_Trigger *trigger, 
+                                       Ewl_Text_Trigger_Type type);
+void            ewl_text_trigger_free(Ewl_Text_Trigger *t);
+
+Ewl_Text_Trigger_Type ewl_text_trigger_type_get(Ewl_Text_Trigger *t);
+
+void            ewl_text_trigger_start_pos_set(Ewl_Text_Trigger *t, 
+                                                       unsigned int pos);
+unsigned int    ewl_text_trigger_start_pos_get(Ewl_Text_Trigger *t);
+
+void            ewl_text_trigger_length_set(Ewl_Text_Trigger *t, 
+                                                       unsigned int len);
+unsigned int    ewl_text_trigger_length_get(Ewl_Text_Trigger *t);
+
 /*
  * Internal stuff
  */
+void ewl_text_triggers_configure(Ewl_Text *t);
+void ewl_text_triggers_realize(Ewl_Text *t);
+void ewl_text_triggers_unrealize(Ewl_Text *t);
+void ewl_text_triggers_show(Ewl_Text *t);
+void ewl_text_triggers_hide(Ewl_Text *t);
+
 void ewl_text_cb_configure(Ewl_Widget *w, void *ev, void *data);
 void ewl_text_cb_realize(Ewl_Widget *w, void *ev, void *data);
 void ewl_text_cb_unrealize(Ewl_Widget *w, void *ev, void *data);
 void ewl_text_cb_show(Ewl_Widget *w, void *ev, void *data);
 void ewl_text_cb_hide(Ewl_Widget *w, void *ev, void *data);
+void ewl_text_cb_destroy(Ewl_Widget *w, void *ev, void *data);
+
+void ewl_text_trigger_cb_focus_in(Ewl_Widget *w, void *ev, void *data);
+void ewl_text_trigger_cb_focus_out(Ewl_Widget *w, void *ev, void *data);
+void ewl_text_trigger_cb_mouse_up(Ewl_Widget *w, void *ev, void *data);
+void ewl_text_trigger_cb_mouse_down(Ewl_Widget *w, void *ev, void *data);
 
 /*
  * Ewl_Text_Context stuff
@@ -298,6 +348,7 @@
 };
 
 void ewl_text_context_init(void);
+void ewl_text_context_shutdown(void);
 
 Ewl_Text_BTree *ewl_text_btree_new(void);
 void ewl_text_btree_free(Ewl_Text_BTree *tree);
@@ -311,6 +362,22 @@
 void ewl_text_btree_condense(Ewl_Text_BTree *tree);
 void ewl_text_btree_dump(Ewl_Text_BTree *tree, char *indent);
 
+/*
+ * Ewl_Text_Trigger_Area stuff
+ */
+typedef struct Ewl_Text_Trigger_Area Ewl_Text_Trigger_Area;
+
+#define EWL_TEXT_TRIGGER_AREA(area) ((Ewl_Text_Trigger_Area *) area)
+
+struct Ewl_Text_Trigger_Area
+{
+       Ewl_Widget      widget;
+};
+
+Ewl_Widget *ewl_text_trigger_area_new(Ewl_Text_Trigger_Type type);
+int ewl_text_trigger_area_init(Ewl_Text_Trigger_Area *area,
+                               Ewl_Text_Trigger_Type type);
+
 /**
  * @}
  */
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_widget.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -3 -r1.10 -r1.11
--- ewl_widget.c        17 Jul 2005 21:37:12 -0000      1.10
+++ ewl_widget.c        21 Jul 2005 00:47:58 -0000      1.11
@@ -1065,6 +1065,12 @@
        IF_FREE(w->name);
        IF_FREE(w->appearance);
 
+       if (w->inheritance)
+               ecore_string_release(w->inheritance);
+
+       if (w->bit_state)
+               ecore_string_release(w->bit_state);
+       
        /*
         * Clear out the callbacks, this is a bit tricky because we don't want
         * to continue using this widget after the callbacks have been




-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to