Enlightenment CVS committal

Author  : moom
Project : e17
Module  : proto

Dir     : e17/proto/etk/src/lib


Modified Files:
        etk_textblock.c 


Log Message:
* [Textblock] Mouse selection


===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_textblock.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -3 -r1.23 -r1.24
--- etk_textblock.c     26 Jul 2006 15:17:07 -0000      1.23
+++ etk_textblock.c     26 Jul 2006 20:48:09 -0000      1.24
@@ -42,12 +42,14 @@
    Etk_Textblock_Object_Line *last_visible_line;
    
    Etk_Bool cursor_visible;
+   Etk_Bool selecting;
    Etk_Textblock_Iter *cursor;
    Etk_Textblock_Iter *selection;
    
    Evas_Object *cursor_object;
    Evas_List *selection_rects;
    Evas_Object *clip;
+   Evas_Object *bg;
    
    int xoffset;
    int yoffset;
@@ -132,6 +134,11 @@
 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_textblock_object_iter_move_to(Evas_Object *tbo, 
Etk_Textblock_Iter *iter, int x, int y);
+
+static void _etk_tb_object_mouse_down_cb(void *data, Evas *e, Evas_Object 
*obj, void *event_info);
+static void _etk_tb_object_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, 
void *event_info);
+static void _etk_tb_object_mouse_move_cb(void *data, Evas *e, Evas_Object 
*obj, void *event_info);
 
 static void _etk_tb_object_smart_add(Evas_Object *obj);
 static void _etk_tb_object_smart_del(Evas_Object *obj);
@@ -3696,6 +3703,119 @@
    return selection_geometry;
 }
 
+/* Moves the iter to the position (x, y) */
+static void _etk_textblock_object_iter_move_to(Evas_Object *tbo, 
Etk_Textblock_Iter *iter, int x, int y)
+{
+   Etk_Textblock_Object_SD *tbo_sd;
+   Etk_Textblock_Object_Line *line, *l;
+   
+   if (!tbo || !iter || !(tbo_sd = evas_object_smart_data_get(tbo)))
+      return;
+   
+   /* TODO: optimize: use an AVL to store the object's lines */
+   /* TODO: take account of scrolling */
+   line = tbo_sd->last_line;
+   for (l = tbo_sd->lines; l; l = l->next)
+   {
+      if (l->geometry.y + l->geometry.h >= y)
+      {
+         line = l;
+         break;
+      }
+   }
+   
+   if (!line)
+      return;
+   
+   for (iter->node = line->node; iter->node->children; iter->node = 
iter->node->children);
+   iter->pos = 0;
+   iter->index = 0;
+   
+   if (line->object && !_etk_textblock_node_is_empty(line->node))
+   {
+      Etk_Textblock_Node *node;
+      Evas_Textblock_Cursor *cur;
+      const char *text;
+      int line_num;
+      int pos, i;
+      int lx, lw;
+      
+      cur = evas_object_textblock_cursor_new(line->object);
+      if (!evas_textblock_cursor_char_coord_set(cur, x - line->geometry.x, y - 
line->geometry.y))
+      {
+        line_num = evas_textblock_cursor_line_coord_set(cur, y - 
line->geometry.y);
+        if (line_num >= 0)
+        {
+            evas_textblock_cursor_line_geometry_get(cur, &lx, NULL, &lw, NULL);
+            
+            if (x - (line->geometry.x + lx) <= (lw / 2))
+               evas_textblock_cursor_line_first(cur);
+            else
+               evas_textblock_cursor_line_last(cur);
+         }
+      }
+      pos = evas_textblock_cursor_pos_get(cur);
+      
+      while (evas_textblock_cursor_node_prev(cur))
+      {
+         if ((text = evas_textblock_cursor_node_text_get(cur)) && *text)
+         {
+            if ((node = _etk_textblock_next_text_node_get(iter->node, 
ETK_TRUE, NULL)))
+               iter->node = node;
+         }
+      }
+      
+      iter->pos = pos;
+      iter->index = 0;
+      for (i = 0; i < pos; i++)
+         iter->index = 
evas_string_char_next_get(etk_string_get(iter->node->text), iter->index, NULL);
+      
+      evas_textblock_cursor_free(cur);
+   }
+   
+   _etk_textblock_iter_update(iter);
+}
+
+/* Called when the textblock object is pressed by the mouse */
+static void _etk_tb_object_mouse_down_cb(void *data, Evas *e, Evas_Object 
*obj, void *event_info)
+{
+   Etk_Textblock_Object_SD *tbo_sd;
+   Evas_Event_Mouse_Down *event;
+   int ox, oy;
+   
+   if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)) || !(event = 
event_info))
+      return;
+   
+   evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
+   _etk_textblock_object_iter_move_to(obj, tbo_sd->cursor, event->canvas.x - 
ox, event->canvas.y - oy);
+   etk_textblock_iter_copy(tbo_sd->selection, tbo_sd->cursor);
+   tbo_sd->selecting = ETK_TRUE;
+}
+
+/* Called when the textblock object is released by the mouse */
+static void _etk_tb_object_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, 
void *event_info)
+{
+   Etk_Textblock_Object_SD *tbo_sd;
+   
+   if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)))
+      return;
+   tbo_sd->selecting = ETK_FALSE;
+}
+
+/* Called when the mouse moves over the textblock object */
+static void _etk_tb_object_mouse_move_cb(void *data, Evas *e, Evas_Object 
*obj, void *event_info)
+{
+   Etk_Textblock_Object_SD *tbo_sd;
+   Evas_Event_Mouse_Move *event;
+   int ox, oy;
+   
+   if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)) || !(event = 
event_info) || !tbo_sd->selecting)
+      return;
+   
+   evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
+   _etk_textblock_object_iter_move_to(obj, tbo_sd->cursor, event->cur.canvas.x 
- ox, event->cur.canvas.y - oy);
+}
+
 /**************************
  *
  * Textblock object's smart object
@@ -3715,12 +3835,18 @@
    tbo_sd->tb = NULL;
    tbo_sd->wrap = ETK_TEXTBLOCK_WRAP_WORD;
    tbo_sd->cursor_visible = ETK_TRUE;
+   tbo_sd->selecting = ETK_FALSE;
    tbo_sd->cursor_timer = NULL;
    tbo_sd->update_job = NULL;
    
    tbo_sd->clip = evas_object_rectangle_add(evas);
    evas_object_smart_member_add(tbo_sd->clip, obj);
    
+   tbo_sd->bg = evas_object_rectangle_add(evas);
+   evas_object_color_set(tbo_sd->bg, 255, 255, 255, 0);
+   evas_object_clip_set(tbo_sd->bg, tbo_sd->clip);
+   evas_object_smart_member_add(tbo_sd->bg, obj);
+   
    tbo_sd->cursor_object = evas_object_rectangle_add(evas);
    /* TODO: make the cursor color themeable */
    evas_object_color_set(tbo_sd->cursor_object, 0, 0, 0, 255);
@@ -3743,6 +3869,10 @@
    tbo_sd->style = evas_textblock_style_new();
    evas_textblock_style_set(tbo_sd->style, "DEFAULT='font=Vera font_size=10 
align=left color=#000000'");
    
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN, 
_etk_tb_object_mouse_down_cb, NULL);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP, 
_etk_tb_object_mouse_up_cb, NULL);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE, 
_etk_tb_object_mouse_move_cb, NULL);
+   
    evas_object_smart_data_set(obj, tbo_sd);
 }
 
@@ -3773,6 +3903,8 @@
       free(line);
    }
    evas_object_del(tbo_sd->cursor_object);
+   evas_object_del(tbo_sd->clip);
+   evas_object_del(tbo_sd->bg);
    evas_textblock_style_free(tbo_sd->style);
    
    tbo_sd->tb->evas_objects = evas_list_remove(tbo_sd->tb->evas_objects, obj);
@@ -3799,6 +3931,7 @@
    if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)))
       return;
    
+   evas_object_move(tbo_sd->bg, x, y);
    evas_object_move(tbo_sd->clip, x, y);
    
    evas_object_geometry_get(obj, &prev_x, &prev_y, NULL, NULL);
@@ -3834,6 +3967,7 @@
    if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)))
       return;
    
+   evas_object_resize(tbo_sd->bg, w, h);
    evas_object_resize(tbo_sd->clip, w, h);
    
    /* TODO: optimization for non-wrapped lines? */
@@ -3851,6 +3985,7 @@
    if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)))
       return;
    
+   evas_object_show(tbo_sd->bg);
    evas_object_show(tbo_sd->clip);
    
    for (line = tbo_sd->first_visible_line; line; line = line->next)
@@ -3888,6 +4023,7 @@
    if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)))
       return;
    
+   evas_object_hide(tbo_sd->bg);
    evas_object_hide(tbo_sd->clip);
    
    for (line = tbo_sd->first_visible_line; line; line = line->next)



-------------------------------------------------------------------------
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