Enlightenment CVS committal

Author  : moom
Project : e17
Module  : proto

Dir     : e17/proto/etk/src/lib


Modified Files:
        etk_textblock.c etk_textblock.h etk_window.c 


Log Message:
* More work on the the textblock: make the cursor blink and fix some 
bugs



===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_textblock.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -3 -r1.19 -r1.20
--- etk_textblock.c     10 Jul 2006 03:26:53 -0000      1.19
+++ etk_textblock.c     21 Jul 2006 00:31:30 -0000      1.20
@@ -3,6 +3,7 @@
 #include "etk_textblock.h"
 #include <stdlib.h>
 #include <string.h>
+#include <Ecore.h>
 #include <Ecore_Job.h>
 #include "etk_string.h"
 #include "etk_utils.h"
@@ -14,6 +15,9 @@
 
 #define ETK_TB_OBJECT_HEIGHT 300
 
+#define ETK_TB_OBJECT_SHOW_CURSOR_DELAY 0.75
+#define ETK_TB_OBJECT_HIDE_CURSOR_DELAY 0.25
+
 #define ETK_TB_TAG_PARAM_IS(param, len) \
    (param_len == (len) && strncasecmp(param_start, (param), (len)) == 0)
    
@@ -34,12 +38,14 @@
    Etk_Textblock_Object_Line *lines;
    Etk_Textblock_Object_Line *last_line;
    
+   Etk_Bool cursor_visible;
    Etk_Textblock_Iter *cursor;
    Etk_Textblock_Iter *selection;
    
    Evas_Object *cursor_object;
    Evas_Object *clip;
    
+   Ecore_Timer *cursor_timer;
    Ecore_Job *update_job;
 };
 
@@ -82,6 +88,8 @@
 
 static Etk_Bool _etk_textblock_iter_is_valid(Etk_Textblock *tb, 
Etk_Textblock_Iter *iter);
 static Etk_Bool _etk_textblock_node_is_default_paragraph(Etk_Textblock_Node 
*node);
+static Etk_Bool _etk_textblock_node_is_empty_line(Etk_Textblock_Node *node, 
const char **face, int *size);
+static Etk_Bool _etk_textblock_node_is_empty(Etk_Textblock_Node *node);
 
 static int _etk_textblock_int_parse(const char *int_string, int length, int 
error_value);
 static float _etk_textblock_float_parse(const char *float_string, int length, 
float error_value);
@@ -106,7 +114,8 @@
 static void _etk_textblock_object_cursor_update_queue(Evas_Object *tbo);
 static void _etk_textblock_object_cursor_update(Evas_Object *tbo);
 static void _etk_textblock_object_update(Evas_Object *tbo);
-static void _etk_textblock_object_update_job(void *data);
+static void _etk_textblock_object_update_job_cb(void *data);
+static int _etk_textblock_object_cursor_timer_cb(void *data);
 
 static Etk_Textblock_Object_Line 
*_etk_textblock_object_line_get_from_node(Evas_Object *tbo, Etk_Textblock_Node 
*node);
 static Evas_Textblock_Cursor 
*_etk_textblock_object_cursor_get_from_iter(Evas_Object *tbo, 
Etk_Textblock_Iter *iter);
@@ -864,6 +873,53 @@
 }
 
 /**
+ * @brief Sets whether the cursor of the textblock object is visible or not
+ * @param tbo a textblock object
+ * @param visible ETK_TRUE to show the cursor, ETK_FALSE to hide it
+ */
+void etk_textblock_object_cursor_visible_set(Evas_Object *tbo, Etk_Bool 
visible)
+{
+   Etk_Textblock_Object_SD *tbo_sd;
+   
+   if (!tbo || !(tbo_sd = evas_object_smart_data_get(tbo)) || 
tbo_sd->cursor_visible == visible)
+      return;
+   
+   if (visible)
+   {
+      evas_object_show(tbo_sd->cursor_object);
+      if (!tbo_sd->cursor_timer)
+      {
+         tbo_sd->cursor_timer = 
ecore_timer_add(ETK_TB_OBJECT_SHOW_CURSOR_DELAY,
+            _etk_textblock_object_cursor_timer_cb, tbo);
+      }
+      else
+         ecore_timer_interval_set(tbo_sd->cursor_timer, 
ETK_TB_OBJECT_SHOW_CURSOR_DELAY);
+   }
+   else
+   {
+      evas_object_hide(tbo_sd->cursor_object);
+      ecore_timer_del(tbo_sd->cursor_timer);
+      tbo_sd->cursor_timer = NULL;
+   }
+   
+   tbo_sd->cursor_visible = visible;
+}
+
+/**
+ * @brief Gets whether the cursor of the textblock object is visible or not
+ * @param tbo a textblock object
+ * @return Returns ETK_TRUE if the cursor is visible, ETK_FALSE otherwise
+ */
+Etk_Bool etk_textblock_object_cursor_visible_get(Evas_Object *tbo)
+{
+   Etk_Textblock_Object_SD *tbo_sd;
+   
+   if (!tbo || !(tbo_sd = evas_object_smart_data_get(tbo)))
+      return ETK_FALSE;
+   return tbo_sd->cursor_visible;
+}
+
+/**
  * @brief Gets the cursor's iterator of the textblock object
  * @param tbo a textblock object
  * @return Returns the cursor's iterator of the textblock object
@@ -932,6 +988,36 @@
        (c == 0x2028) || (c == 0x2029) || (c == 0x202f) || (c == 0x205f) || (c 
== 0x3000));
 }
 
+/**
+ * @brief Gets the average size of a character written with font @a font_name
+ * @param evas an evas
+ * @param font_face the face of the font to use
+ * @param font_size the size of the font to use
+ * @param w the location where to store the average width of a character
+ * @param h the location where to store the average height of a character
+ */
+/* TODO: cache the result! */
+/* TODO: better test text */
+void etk_textblock_char_size_get(Evas *evas, const char *font_face, int 
font_size, int *w, int *h)
+{
+   Evas_Object *text_object;
+   char *text = "This is a test";
+   int len = 14;
+   int tw = 0;
+   
+   if (!evas || !font_face)
+      return;
+   
+   text_object = evas_object_text_add(evas);
+   evas_object_text_font_set(text_object, font_face, font_size);
+   evas_object_text_text_set(text_object, text);
+   evas_object_geometry_get(text_object, NULL, NULL, &tw, h);
+   evas_object_del(text_object);
+   
+   if (w)
+      *w = tw / len;
+}
+
 /**************************
  *
  * Etk specific functions
@@ -1971,9 +2057,15 @@
          node_hierarchy = evas_list_remove_list(node_hierarchy, 
node_hierarchy);
       }
       
-      /* Finally, we split the original node, and we attach the right part to 
the new node hierarchy */
+      /* Finally, we split the original node, and we attach the right nodes to 
the new node hierarchy */
       right_node = _etk_textblock_node_split(iter->tb, node, iter->index, 
iter->pos);
-      _etk_textblock_node_attach(right_node, parent, left_node);
+      while (right_node)
+      {
+         node = right_node->next;
+         _etk_textblock_node_attach(right_node, parent, left_node);
+         left_node = right_node;
+         right_node = node;
+      }
       
       return ETK_TRUE;
    }
@@ -2043,9 +2135,59 @@
       return ETK_FALSE;
    
    return ETK_TRUE;
+}
+
+/* Checks if the node belongs to an empty line (i.e. a line containing no 
text, but which may contain empty format nodes)
+ * If the line is empty, the format of the line is stored in "face", "size" */
+/* TODO: return also the style?? (effect, italic, bold, ...) */
+static Etk_Bool _etk_textblock_node_is_empty_line(Etk_Textblock_Node *node, 
const char **face, int *size)
+{
+   Etk_Textblock_Node *line, *n;
+   Etk_Textblock_Format format;
+   
+   for (n = node; n; n = n->parent)
+   {
+      if (n->type == ETK_TEXTBLOCK_NODE_LINE)
+         break;
+   }
+   if (!(line = n))
+      return ETK_FALSE;
+   
+   if (_etk_textblock_node_is_empty(line))
+   {
+      for (n = line; n->children; n = n->children);
+      _etk_textblock_node_format_get(n, &format);
+      if (face)
+         *face = format.font_face;
+      if (size)
+         *size = format.font_size;
+      
+      return ETK_TRUE;
+   }
+   else
+      return ETK_FALSE;
+}
+
+/* Checks recursively whether the node and its children contain some text. If 
not, it returns ETK_TRUE */
+static Etk_Bool _etk_textblock_node_is_empty(Etk_Textblock_Node *node)
+{
+   Etk_Textblock_Node *n;
    
+   if (!node)
+      return ETK_FALSE;
+   
+   if (node->unicode_length > 0)
+      return ETK_FALSE;
+   
+   for (n = node->children; n; n = n->next)
+   {
+      if (!_etk_textblock_node_is_empty(n))
+         return ETK_FALSE;
+   }
+   return ETK_TRUE;
 }
 
+
 /* Parses an integer and return 'error_value' if it fails */
 static int _etk_textblock_int_parse(const char *int_string, int length, int 
error_value)
 {
@@ -2687,7 +2829,7 @@
    line->need_content_update |= content_update;
    
    if (!tbo_sd->update_job)
-      tbo_sd->update_job = ecore_job_add(_etk_textblock_object_update_job, 
tbo);
+      tbo_sd->update_job = ecore_job_add(_etk_textblock_object_update_job_cb, 
tbo);
 }
 
 /* Updates the line of the textblock object */
@@ -2696,6 +2838,8 @@
    Etk_Textblock_Object_SD *tbo_sd;
    Evas *evas;
    int ox, oy, ow, oh;
+   const char *font_face;
+   int font_size;
    
    if (!tbo || !line || !(tbo_sd = evas_object_smart_data_get(tbo)))
       return;
@@ -2709,37 +2853,53 @@
       return;
    
    evas_object_geometry_get(tbo, &ox, &oy, &ow, &oh);
+   line->geometry.w = ow;
    
-   if (!line->object)
+   if (!_etk_textblock_node_is_empty_line(line->node, &font_face, &font_size))
    {
-      line->object = evas_object_textblock_add(evas);
-      evas_object_textblock_style_set(line->object, tbo_sd->style);
-      evas_object_clip_set(line->object, tbo_sd->clip);
-      evas_object_smart_member_add(line->object, tbo);
+      if (!line->object)
+      {
+         line->object = evas_object_textblock_add(evas);
+         evas_object_textblock_style_set(line->object, tbo_sd->style);
+         evas_object_clip_set(line->object, tbo_sd->clip);
+         evas_object_smart_member_add(line->object, tbo);
+         
+         line->need_content_update = ETK_TRUE;
+         line->need_geometry_update = ETK_TRUE;
+      }
       
-      line->need_content_update = ETK_TRUE;
-      line->need_geometry_update = ETK_TRUE;
+      if (line->need_content_update)
+      {
+         Evas_Textblock_Cursor *cur;
+         
+         evas_object_textblock_clear(line->object);
+         cur = evas_object_textblock_cursor_new(line->object);
+         evas_textblock_cursor_node_first(cur);
+         _etk_textblock_object_line_fill(tbo, cur, line->node);
+         evas_textblock_cursor_free(cur);
+         
+         line->need_content_update = ETK_FALSE;
+      }
+      
+      if (line->need_geometry_update)
+      {
+         evas_object_resize(line->object, line->geometry.w, 
ETK_TB_OBJECT_HEIGHT);
+         evas_object_textblock_size_formatted_get(line->object, NULL, 
&line->geometry.h);
+         
+         line->need_geometry_update = ETK_FALSE;
+      }
    }
-   
-   if (line->need_content_update)
+   else
    {
-      Evas_Textblock_Cursor *cur;
+      if (line->object)
+      {
+         evas_object_del(line->object);
+         line->object = NULL;
+      }
       
-      evas_object_textblock_clear(line->object);
-      cur = evas_object_textblock_cursor_new(line->object);
-      evas_textblock_cursor_node_first(cur);
-      _etk_textblock_object_line_fill(tbo, cur, line->node);
-      evas_textblock_cursor_free(cur);
+      etk_textblock_char_size_get(evas, "Vera", 10, NULL, &line->geometry.h);
       
       line->need_content_update = ETK_FALSE;
-   }
-   
-   if (line->need_geometry_update)
-   {
-      line->geometry.w = ow;
-      evas_object_resize(line->object, line->geometry.w, ETK_TB_OBJECT_HEIGHT);
-      evas_object_textblock_size_formatted_get(line->object, NULL, 
&line->geometry.h);
-      
       line->need_geometry_update = ETK_FALSE;
    }
 }
@@ -2753,7 +2913,7 @@
       return;
    
    if (!tbo_sd->update_job)
-      tbo_sd->update_job = ecore_job_add(_etk_textblock_object_update_job, 
tbo);
+      tbo_sd->update_job = ecore_job_add(_etk_textblock_object_update_job_cb, 
tbo);
 }
 
 /* Updates the cursor object and the selection of the textblock object */
@@ -2804,19 +2964,19 @@
    {
       _etk_textblock_object_line_update(tbo, line, y);
       
-      if ((y + line->geometry.h <= 0 || y >= oh))
+      if (line->object)
       {
-         if (line->object)
+         if ((y + line->geometry.h <= 0 || y >= oh))
          {
             evas_object_del(line->object);
             line->object = NULL;
          }
-      }
-      else
-      {
-         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);
+         else
+         {
+            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);
+         }
       }
       
       y += line->geometry.h;
@@ -2827,7 +2987,7 @@
 }
 
 /* The job used to update the textblock object */
-static void _etk_textblock_object_update_job(void *data)
+static void _etk_textblock_object_update_job_cb(void *data)
 {
    Evas_Object *tbo;
    Etk_Textblock_Object_SD *tbo_sd;
@@ -2839,6 +2999,29 @@
    tbo_sd->update_job = NULL;
 }
 
+/* The timer that shows/hides the cursor of a textblock object */
+static int _etk_textblock_object_cursor_timer_cb(void *data)
+{
+   Evas_Object *tbo;
+   Etk_Textblock_Object_SD *tbo_sd;
+   
+   if (!(tbo = data) || !(tbo_sd = evas_object_smart_data_get(tbo)) || 
!tbo_sd->cursor_visible)
+      return 1;
+   
+   if (evas_object_visible_get(tbo_sd->cursor_object))
+   {
+      evas_object_hide(tbo_sd->cursor_object);
+      ecore_timer_interval_set(tbo_sd->cursor_timer, 
ETK_TB_OBJECT_HIDE_CURSOR_DELAY);
+   }
+   else
+   {
+      evas_object_show(tbo_sd->cursor_object);
+      ecore_timer_interval_set(tbo_sd->cursor_timer, 
ETK_TB_OBJECT_SHOW_CURSOR_DELAY);
+   }
+   
+   return 1;
+}
+
 /* Gets the line of a textblock object that contains the given node */
 static Etk_Textblock_Object_Line 
*_etk_textblock_object_line_get_from_node(Evas_Object *tbo, Etk_Textblock_Node 
*node)
 {
@@ -2954,6 +3137,8 @@
    tbo_sd = malloc(sizeof(Etk_Textblock_Object_SD));
    tbo_sd->tb = NULL;
    tbo_sd->wrap = ETK_TEXTBLOCK_WRAP_WORD;
+   tbo_sd->cursor_visible = ETK_TRUE;
+   tbo_sd->cursor_timer = NULL;
    tbo_sd->update_job = NULL;
    
    tbo_sd->clip = evas_object_rectangle_add(evas);
@@ -2986,6 +3171,8 @@
    if (!obj || !(tbo_sd = evas_object_smart_data_get(obj)))
       return;
    
+   if (tbo_sd->cursor_timer)
+      ecore_timer_del(tbo_sd->cursor_timer);
    if (tbo_sd->update_job)
       ecore_job_del(tbo_sd->update_job);
    
@@ -3063,15 +3250,25 @@
    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)
    {
       if (line->object)
          evas_object_show(line->object);
    }
    
-   /* TODO: timer! */
-   evas_object_show(tbo_sd->cursor_object);
-   evas_object_show(tbo_sd->clip);
+   if (tbo_sd->cursor_visible)
+   {
+      evas_object_show(tbo_sd->cursor_object);
+      if (!tbo_sd->cursor_timer)
+      {
+         tbo_sd->cursor_timer = 
ecore_timer_add(ETK_TB_OBJECT_SHOW_CURSOR_DELAY,
+            _etk_textblock_object_cursor_timer_cb, obj);
+      }
+      else
+         ecore_timer_interval_set(tbo_sd->cursor_timer, 
ETK_TB_OBJECT_SHOW_CURSOR_DELAY);
+   }
 }
 
 /* Hides the textblock object */
@@ -3083,6 +3280,8 @@
    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)
    {
       if (line->object)
@@ -3090,7 +3289,11 @@
    }
    
    evas_object_hide(tbo_sd->cursor_object);
-   evas_object_hide(tbo_sd->clip);
+   if (tbo_sd->cursor_timer)
+   {
+      ecore_timer_del(tbo_sd->cursor_timer);
+      tbo_sd->cursor_timer = NULL;
+   }
 }
 
 /* Set the color of the textblock object */
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_textblock.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -3 -r1.11 -r1.12
--- etk_textblock.h     9 Jul 2006 00:15:57 -0000       1.11
+++ etk_textblock.h     21 Jul 2006 00:31:30 -0000      1.12
@@ -235,12 +235,15 @@
 void etk_textblock_object_wrap_set(Evas_Object *tbo, Etk_Textblock_Wrap wrap);
 Etk_Textblock_Wrap etk_textblock_object_wrap_get(Evas_Object *tbo);
 
+void etk_textblock_object_cursor_visible_set(Evas_Object *tbo, Etk_Bool 
visible);
+Etk_Bool etk_textblock_object_cursor_visible_get(Evas_Object *tbo);
 Etk_Textblock_Iter *etk_textblock_object_cursor_get(Evas_Object *tbo);
 Etk_Textblock_Iter *etk_textblock_object_selection_bound_get(Evas_Object *tbo);
 
 /* Misc funcs */
 int etk_textblock_unicode_length_get(const char *unicode_string);
 Etk_Bool etk_textblock_is_white_char(int c);
+void etk_textblock_char_size_get(Evas *evas, const char *font_face, int 
font_size, int *w, int *h);
 
 /** @} */
  
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_window.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -3 -r1.24 -r1.25
--- etk_window.c        4 Jul 2006 17:35:33 -0000       1.24
+++ etk_window.c        21 Jul 2006 00:31:30 -0000      1.25
@@ -313,10 +313,7 @@
  */
 void etk_window_modal_for_window(Etk_Window *window_to_modal, Etk_Window 
*window)
 {
-#if HAVE_ECORE_X   
-   int x, y, w, h;
-   int cw, ch;
-   
+#if HAVE_ECORE_X
    if (!window_to_modal)
       return;
    
@@ -333,13 +330,11 @@
       {
         Ecore_X_Window_State states[] = {ECORE_X_WINDOW_STATE_MODAL};
         
-        ecore_x_icccm_transient_for_set(window_to_modal->x_window,
-                                        window->x_window);
-        
+        ecore_x_icccm_transient_for_set(window_to_modal->x_window, 
window->x_window);
         ecore_x_netwm_window_state_set(window_to_modal->x_window, states, 1);
       }
    }
-#endif   
+#endif
 }
 
 /**



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