Enlightenment CVS committal

Author  : moom
Project : e17
Module  : proto

Dir     : e17/proto/etk/src/lib


Modified Files:
        etk_text_view.c etk_textblock.c etk_textblock.h 


Log Message:
* More TB work: start the selection code


===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_text_view.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -3 -r1.9 -r1.10
--- etk_text_view.c     10 Jul 2006 03:26:53 -0000      1.9
+++ etk_text_view.c     22 Jul 2006 15:32:07 -0000      1.10
@@ -158,16 +158,26 @@
 {
    Etk_Text_View *text_view;
    Etk_Textblock_Iter *cursor;
+   Etk_Textblock_Iter *selection;
    
    if (!(text_view = ETK_TEXT_VIEW(object)) || !event || 
!text_view->textblock_object)
       return;
    
    cursor = etk_textblock_object_cursor_get(text_view->textblock_object);
+   selection = 
etk_textblock_object_selection_bound_get(text_view->textblock_object);
    
    if (strcmp(event->key, "Left") == 0)
+   {
       etk_textblock_iter_backward_char(cursor);
+      if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
+         etk_textblock_iter_copy(selection, cursor);
+   }
    else if (strcmp(event->key, "Right") == 0)
+   {
       etk_textblock_iter_forward_char(cursor);
+      if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
+         etk_textblock_iter_copy(selection, cursor);
+   }
    else if (strcmp(event->key, "Return") == 0 || strcmp(event->key, 
"KP_Enter") == 0)
       etk_textblock_text_insert(text_view->textblock, cursor, "\n", -1);
    else if (event->string && !(strlen(event->string) == 1 && event->string[0] 
< 0x20))
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_textblock.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -3 -r1.20 -r1.21
--- etk_textblock.c     21 Jul 2006 00:31:30 -0000      1.20
+++ etk_textblock.c     22 Jul 2006 15:32:07 -0000      1.21
@@ -13,7 +13,8 @@
  * @{
  */
 
-#define ETK_TB_OBJECT_HEIGHT 300
+#define ETK_TB_OBJECT_DEFAULT_HEIGHT 300
+#define ETK_TB_EMPTY_LINE_WIDTH 3
 
 #define ETK_TB_OBJECT_SHOW_CURSOR_DELAY 0.75
 #define ETK_TB_OBJECT_HIDE_CURSOR_DELAY 0.25
@@ -37,14 +38,20 @@
    
    Etk_Textblock_Object_Line *lines;
    Etk_Textblock_Object_Line *last_line;
+   Etk_Textblock_Object_Line *first_visible_line;
+   Etk_Textblock_Object_Line *last_visible_line;
    
    Etk_Bool cursor_visible;
    Etk_Textblock_Iter *cursor;
    Etk_Textblock_Iter *selection;
    
    Evas_Object *cursor_object;
+   Evas_List *selection_rects;
    Evas_Object *clip;
    
+   int xoffset;
+   int yoffset;
+   
    Ecore_Timer *cursor_timer;
    Ecore_Job *update_job;
 };
@@ -121,6 +128,8 @@
 static Evas_Textblock_Cursor 
*_etk_textblock_object_cursor_get_from_iter(Evas_Object *tbo, 
Etk_Textblock_Iter *iter);
 static int _etk_textblock_text_nodes_count(Etk_Textblock_Node *line, 
Etk_Textblock_Node *node);
 
+static Evas_List *_etk_textblock_object_range_geometry_get(Evas_Object *tbo, 
Etk_Textblock_Iter *start, Etk_Textblock_Iter *end);
+
 static void _etk_tb_object_smart_add(Evas_Object *obj);
 static void _etk_tb_object_smart_del(Evas_Object *obj);
 static void _etk_tb_object_smart_move(Evas_Object *obj, Evas_Coord x, 
Evas_Coord y);
@@ -358,7 +367,7 @@
          node_start = i;
       unicode_length++;
       
-      /* If we have parsed a full node, a escape sequence or a "end of line" 
sequence, we insert the text or
+      /* If we have parsed a full node, a escape sequence or a end-of-line 
sequence, we insert the text or
        * we create a new line */
       if ((node_start >= 0 && node_end >= 0) || (esc_start >= 0 && esc_end >= 
0)  || new_line)
       {
@@ -634,6 +643,7 @@
  * @return Returns ETK_FALSE if the movement was not possible (i.e. if the 
iterator already points
  * on the first character of the textblock)
  */
+/* TODO: improve placement */
 Etk_Bool etk_textblock_iter_backward_char(Etk_Textblock_Iter *iter)
 {
    if (!(iter || !_etk_textblock_iter_is_valid(NULL, iter)))
@@ -669,6 +679,7 @@
  * @return Returns ETK_FALSE if the movement was not possible (i.e. if the 
iterator already points
  * after the last character of the textblock)
  */
+/* TODO: improve placement */
 Etk_Bool etk_textblock_iter_forward_char(Etk_Textblock_Iter *iter)
 {
    if (!(iter || !_etk_textblock_iter_is_valid(NULL, iter)))
@@ -848,10 +859,10 @@
                   evas_textblock_cursor_format_append(cur, "+ wrap=none");
                evas_textblock_cursor_node_prev(cur);
                evas_textblock_cursor_node_delete(cur);
-               evas_textblock_cursor_free(cur);
                break;
             }
          }
+         evas_textblock_cursor_free(cur);
          
          _etk_textblock_object_line_update_queue(tbo, line, ETK_FALSE, 
ETK_TRUE);
       }
@@ -949,7 +960,6 @@
    return tbo_sd->selection;
 }
 
-
 /**************************
  * Misc funcs
  **************************/
@@ -1317,6 +1327,7 @@
 }
 
 /* Removes the empty nodes in the list of 'nodes' */
+/* TODO: do not clean empty lines and implement 
_etk_textblock_nodes_range_clean() */
 static void _etk_textblock_nodes_clean(Etk_Textblock *tb, Etk_Textblock_Node 
*nodes)
 {
    Etk_Textblock_Node *n;
@@ -1877,6 +1888,7 @@
 }
 
 /* Compares the two nodes. */
+/* TODO: OPTIMIZE this!!! Use a binary tree for the lines! */
 static int _etk_textblock_node_compare(Etk_Textblock_Node *node1, 
Etk_Textblock_Node *node2)
 {
    Etk_Textblock_Node *p1, *p2;
@@ -1893,6 +1905,7 @@
    c2 = node2;
    for (p1 = node1->parent; p1; p1 = p1->parent)
    {
+      c2 = node2;
       for (p2 = node2->parent; p2; p2 = p2->parent)
       {
          if (p1 == p2)
@@ -2883,7 +2896,7 @@
       
       if (line->need_geometry_update)
       {
-         evas_object_resize(line->object, line->geometry.w, 
ETK_TB_OBJECT_HEIGHT);
+         evas_object_resize(line->object, line->geometry.w, 
ETK_TB_OBJECT_DEFAULT_HEIGHT);
          evas_object_textblock_size_formatted_get(line->object, NULL, 
&line->geometry.h);
          
          line->need_geometry_update = ETK_FALSE;
@@ -2919,21 +2932,66 @@
 /* Updates the cursor object and the selection of the textblock object */
 static void _etk_textblock_object_cursor_update(Evas_Object *tbo)
 {
+   Evas *evas;
    Etk_Textblock_Object_SD *tbo_sd;
    Evas_Textblock_Cursor *cur;
    Etk_Textblock_Object_Line *line;
+   Evas_List *selection_geometry;
+   Etk_Geometry *rect_geometry;
+   Evas_Object *rect;
+   int visible;
    /* TODO: valg? */
    int cx = 0, cy = 0, cw = 0, ch = 0;
    int ox, oy;
+   int res;
    
-   if (!tbo || !(tbo_sd = evas_object_smart_data_get(tbo)))
+   if (!tbo || !(tbo_sd = evas_object_smart_data_get(tbo)) || !(evas = 
evas_object_evas_get(tbo)))
       return;
    
+   visible = evas_object_visible_get(tbo);
+   evas_object_geometry_get(tbo, &ox, &oy, NULL, NULL);
+   
+   /* Update the selection */
+   /* TODO: selection stacking ?! */
+   while (tbo_sd->selection_rects)
+   {
+      evas_object_del(tbo_sd->selection_rects->data);
+      tbo_sd->selection_rects = evas_list_remove_list(tbo_sd->selection_rects, 
tbo_sd->selection_rects);
+   }
+   res = etk_textblock_iter_compare(tbo_sd->cursor, tbo_sd->selection);
+   if (res != 0)
+   {
+      if (res < 0)
+         selection_geometry = _etk_textblock_object_range_geometry_get(tbo, 
tbo_sd->cursor, tbo_sd->selection);
+      else
+         selection_geometry = _etk_textblock_object_range_geometry_get(tbo, 
tbo_sd->selection, tbo_sd->cursor);
+      
+      while (selection_geometry)
+      {
+         rect_geometry = selection_geometry->data;
+         
+         rect = evas_object_rectangle_add(evas);
+         /* TODO: make the selection themeable */
+         evas_object_color_set(rect, 245, 205, 109, 102);
+         evas_object_move(rect, ox + rect_geometry->x, oy + rect_geometry->y);
+         evas_object_resize(rect, rect_geometry->w, rect_geometry->h);
+         evas_object_clip_set(rect, tbo_sd->clip);
+         evas_object_smart_member_add(rect, tbo);
+         if (visible)
+            evas_object_show(rect);
+         
+         free(rect_geometry);
+         tbo_sd->selection_rects = evas_list_append(tbo_sd->selection_rects, 
rect);
+         selection_geometry = evas_list_remove_list(selection_geometry, 
selection_geometry);
+      }
+   }
+   
+   
+   /* Update the cursor */
    line = _etk_textblock_object_line_get_from_node(tbo, tbo_sd->cursor->node);
    /* TODO: optimize?! */
    cur = _etk_textblock_object_cursor_get_from_iter(tbo, tbo_sd->cursor);
    evas_textblock_cursor_char_geometry_get(cur, &cx, &cy, &cw, &ch);
-   evas_object_geometry_get(tbo, &ox, &oy, NULL, NULL);
    
    /* TODO: make sure the cursor is visible?! */
    if (tbo_sd->cursor->pos < tbo_sd->cursor->node->unicode_length)
@@ -2956,6 +3014,9 @@
    if (!tbo || !(tbo_sd = evas_object_smart_data_get(tbo)))
       return;
    
+   tbo_sd->first_visible_line = NULL;
+   tbo_sd->last_visible_line = NULL;
+   
    /* We update the lines */
    /* TODO: optimize: Updates all the lines in several times and use a btree! 
*/
    y = 0;
@@ -2976,6 +3037,10 @@
             evas_object_move(line->object, ox + line->geometry.x, oy + 
line->geometry.y);
             evas_object_resize(line->object, line->geometry.w, 
line->geometry.h);
             evas_object_show(line->object);
+            
+            if (!tbo_sd->first_visible_line)
+               tbo_sd->first_visible_line = line;
+            tbo_sd->last_visible_line = line;
          }
       }
       
@@ -3119,6 +3184,125 @@
    return count;
 }
 
+
+/* Gets a list of Etk_Geometry's corresponding to the geometry of the text 
between @a start and @a end.
+ * The items of the returned list should be freed, and the list should be 
destroyed manually.
+ * Only the visible lines are stored in the list.  */
+static Evas_List *_etk_textblock_object_range_geometry_get(Evas_Object *tbo, 
Etk_Textblock_Iter *start, Etk_Textblock_Iter *end)
+{
+   Etk_Textblock_Object_SD *tbo_sd;
+   Etk_Textblock_Object_Line *line, *start_line, *end_line;
+   Evas_List *selection_geometry = NULL;
+   Etk_Geometry *rect_geometry;
+   Etk_Bool add_line;
+   Evas *evas;
+   
+   if (!tbo || !start || !end)
+      return NULL;
+   if (!(tbo_sd = evas_object_smart_data_get(tbo)) || !(evas = 
evas_object_evas_get(tbo)))
+      return NULL;
+   if (!tbo_sd->first_visible_line)
+      return NULL;
+   
+   if (_etk_textblock_node_compare(end->node, 
tbo_sd->first_visible_line->node) < 0)
+      return NULL;
+   
+   if (_etk_textblock_node_compare(start->node, 
tbo_sd->first_visible_line->node) <= 0)
+      add_line = ETK_TRUE;
+   else
+      add_line = ETK_FALSE;
+   
+   start_line = _etk_textblock_object_line_get_from_node(tbo, start->node);
+   end_line = _etk_textblock_object_line_get_from_node(tbo, end->node);
+   
+   for (line = tbo_sd->first_visible_line; line; line = line->next)
+   {
+      if (!add_line && line == start_line)
+         add_line = ETK_TRUE;
+      
+      /* We add the geometry of the line to the list */
+      if (add_line)
+      {
+         Evas_List *rects;
+         Evas_Textblock_Rectangle *rect;
+         const char *font_face;
+         int font_size;
+         
+         if (_etk_textblock_node_is_empty_line(line->node, &font_face, 
&font_size))
+         {
+            rect_geometry = malloc(sizeof(Etk_Geometry));
+            rect_geometry->x = line->geometry.x;
+            rect_geometry->y = line->geometry.y;
+            rect_geometry->w = ETK_TB_EMPTY_LINE_WIDTH;
+            /* TODO: correct font, and align */
+            etk_textblock_char_size_get(evas, "Vera", 10, NULL, 
&rect_geometry->h);
+            
+            selection_geometry = evas_list_append(selection_geometry, 
rect_geometry);
+         }
+         else if (line->object)
+         {
+            Evas_Textblock_Cursor *cur1, *cur2;
+            
+            cur1 = NULL;
+            /* TODO: optimize */
+            if (line == start_line)
+               cur1 = _etk_textblock_object_cursor_get_from_iter(tbo, start);
+            if (!cur1)
+            {
+               cur1 = evas_object_textblock_cursor_new(line->object);
+               evas_textblock_cursor_node_first(cur1);
+               while (!evas_textblock_cursor_node_text_get(cur1))
+               {
+                  if (!evas_textblock_cursor_node_next(cur1))
+                     break;
+               }
+               evas_textblock_cursor_char_first(cur1);
+            }
+            
+            cur2 = NULL;
+            /* TODO: optimize */
+            if (line == end_line)
+            {
+               cur2 = _etk_textblock_object_cursor_get_from_iter(tbo, end);
+               evas_textblock_cursor_char_prev(cur2);
+            }
+            if (!cur2)
+            {
+               cur2 = evas_object_textblock_cursor_new(line->object);
+               evas_textblock_cursor_node_last(cur2);
+               while (!evas_textblock_cursor_node_text_get(cur2))
+               {
+                  if (!evas_textblock_cursor_node_prev(cur2))
+                     break;
+               }
+               evas_textblock_cursor_char_last(cur2);
+            }
+            
+            rects = evas_textblock_cursor_range_geometry_get(cur1, cur2);
+            while (rects)
+            {
+               rect = rects->data;
+               
+               rect_geometry = malloc(sizeof(Etk_Geometry));
+               rect_geometry->x = rect->x + line->geometry.x;
+               rect_geometry->y = rect->y + line->geometry.y;
+               rect_geometry->w = rect->w;
+               rect_geometry->h = rect->h;
+               selection_geometry = evas_list_append(selection_geometry, 
rect_geometry);
+               
+               free(rect);
+               rects = evas_list_remove_list(rects, rects);
+            }
+         }
+      }
+      
+      if (line == end_line)
+         break;
+   }
+   
+   return selection_geometry;
+}
+
 /**************************
  *
  * Textblock object's smart object
@@ -3150,8 +3334,15 @@
    evas_object_clip_set(tbo_sd->cursor_object, tbo_sd->clip);
    evas_object_smart_member_add(tbo_sd->cursor_object, obj);
    
+   tbo_sd->selection_rects = NULL;
+   
    tbo_sd->lines = NULL;
    tbo_sd->last_line = NULL;
+   tbo_sd->first_visible_line = NULL;
+   tbo_sd->last_visible_line = NULL;
+   
+   tbo_sd->xoffset = 0;
+   tbo_sd->yoffset = 0;
    
    tbo_sd->cursor = NULL;
    tbo_sd->selection = NULL;
@@ -3176,6 +3367,11 @@
    if (tbo_sd->update_job)
       ecore_job_del(tbo_sd->update_job);
    
+   while (tbo_sd->selection_rects)
+   {
+      evas_object_del(tbo_sd->selection_rects->data);
+      tbo_sd->selection_rects = evas_list_remove_list(tbo_sd->selection_rects, 
tbo_sd->selection_rects);
+   }
    for (line = tbo_sd->lines; line; line = next)
    {
       if (line->object)
@@ -3202,9 +3398,10 @@
 {
    Etk_Textblock_Object_SD *tbo_sd;
    int prev_x, prev_y;
-   int cursor_x, cursor_y;
-   int line_x, line_y;
+   int current_x, current_y;
    Etk_Textblock_Object_Line *line;
+   Evas_Object *selection_rect;
+   Evas_List *l;
    
    if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)))
       return;
@@ -3212,17 +3409,27 @@
    evas_object_move(tbo_sd->clip, x, y);
    
    evas_object_geometry_get(obj, &prev_x, &prev_y, NULL, NULL);
-   for (line = tbo_sd->lines; line; line = line->next)
+   for (line = tbo_sd->first_visible_line; line; line = line->next)
    {
       if (line->object)
       {
-         evas_object_geometry_get(line->object, &line_x, &line_y, NULL, NULL);
-         evas_object_move(line->object, line_x + x - prev_x, line_y + y - 
prev_y);
+         evas_object_geometry_get(line->object, &current_x, &current_y, NULL, 
NULL);
+         evas_object_move(line->object, current_x + x - prev_x, current_y + y 
- prev_y);
       }
+      
+      if (line == tbo_sd->last_visible_line)
+         break;
    }
    
-   evas_object_geometry_get(tbo_sd->cursor_object, &cursor_x, &cursor_y, NULL, 
NULL);
-   evas_object_move(tbo_sd->cursor_object, cursor_x + x - prev_x, cursor_y + y 
- prev_y);
+   evas_object_geometry_get(tbo_sd->cursor_object, &current_x, &current_y, 
NULL, NULL);
+   evas_object_move(tbo_sd->cursor_object, current_x + x - prev_x, current_y + 
y - prev_y);
+   
+   for (l = tbo_sd->selection_rects; l; l = l->next)
+   {
+      selection_rect = l->data;
+      evas_object_geometry_get(selection_rect, &current_x, &current_y, NULL, 
NULL);
+      evas_object_move(selection_rect, current_x + x - prev_x, current_y + y - 
prev_y);
+   }
 }
 
 /* Resizes the textblock object */
@@ -3246,16 +3453,20 @@
 {
    Etk_Textblock_Object_SD *tbo_sd;
    Etk_Textblock_Object_Line *line;
+   Evas_List *l;
    
    if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)))
       return;
    
    evas_object_show(tbo_sd->clip);
    
-   for (line = tbo_sd->lines; line; line = line->next)
+   for (line = tbo_sd->first_visible_line; line; line = line->next)
    {
       if (line->object)
          evas_object_show(line->object);
+      
+      if (line == tbo_sd->last_visible_line)
+         break;
    }
    
    if (tbo_sd->cursor_visible)
@@ -3269,6 +3480,9 @@
       else
          ecore_timer_interval_set(tbo_sd->cursor_timer, 
ETK_TB_OBJECT_SHOW_CURSOR_DELAY);
    }
+   
+   for (l = tbo_sd->selection_rects; l; l = l->next)
+      evas_object_show(l->data);
 }
 
 /* Hides the textblock object */
@@ -3276,16 +3490,20 @@
 {
    Etk_Textblock_Object_SD *tbo_sd;
    Etk_Textblock_Object_Line *line;
+   Evas_List *l;
    
    if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)))
       return;
    
    evas_object_hide(tbo_sd->clip);
    
-   for (line = tbo_sd->lines; line; line = line->next)
+   for (line = tbo_sd->first_visible_line; line; line = line->next)
    {
       if (line->object)
          evas_object_hide(line->object);
+      
+      if (line == tbo_sd->last_visible_line)
+         break;
    }
    
    evas_object_hide(tbo_sd->cursor_object);
@@ -3294,6 +3512,9 @@
       ecore_timer_del(tbo_sd->cursor_timer);
       tbo_sd->cursor_timer = NULL;
    }
+   
+   for (l = tbo_sd->selection_rects; l; l = l->next)
+      evas_object_hide(l->data);
 }
 
 /* Set the color of the textblock object */
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_textblock.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -3 -r1.12 -r1.13
--- etk_textblock.h     21 Jul 2006 00:31:30 -0000      1.12
+++ etk_textblock.h     22 Jul 2006 15:32:07 -0000      1.13
@@ -54,7 +54,7 @@
 typedef enum Etk_Textblock_Style_Type
 {
    ETK_TEXTBLOCK_STYLE_NONE,                    /**< No style is applied */
-   ETK_TEXTBLOCK_STYLE_OUTLINE,                 /**< The text is oulined */
+   ETK_TEXTBLOCK_STYLE_OUTLINE,                 /**< The text is outlined */
    ETK_TEXTBLOCK_STYLE_SHADOW,                  /**< The text has a sharp 
shadow */
    ETK_TEXTBLOCK_STYLE_SOFT_OUTLINE,            /**< The text has a soft 
outline */
    ETK_TEXTBLOCK_STYLE_GLOW,                    /**< The text has a glow */



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to