changeset 1561:46e34bd92336

Implemented guessing size of MLE on GTK... not as accurate as the other platforms... but until the bugs are fixed in GTK this is the best we can do. Also make dw_window_get_preferred_size() return our guesses. Added a piece of safety code on Windows... just in case.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 17 Jan 2012 18:18:00 +0000
parents ee47bda26916
children 9a8aa230a538
files gtk/dw.c gtk3/dw.c win/dw.c
diffstat 3 files changed, 222 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/gtk/dw.c	Tue Jan 17 16:33:21 2012 +0000
+++ b/gtk/dw.c	Tue Jan 17 18:18:00 2012 +0000
@@ -10019,6 +10019,85 @@
    }
 }
 
+/* Internal function to get the recommended size of scrolled items */
+void _get_scrolled_size(GtkWidget *item, gint *thiswidth, gint *thisheight)
+{
+   GtkWidget *widget = gtk_object_get_user_data(GTK_OBJECT(item));
+
+   /* Try to figure out the contents for MLE and Container */
+   if(widget && (GTK_IS_TEXT_VIEW(widget) || GTK_IS_CLIST(widget)))
+   {
+      if(GTK_IS_CLIST(widget))
+      {
+         GtkRequisition req;
+         
+         gtk_widget_size_request(widget, &req);
+         
+         *thiswidth = req.width + 20;
+         *thisheight = req.height + 20;
+      }
+      else
+      {
+         unsigned long bytes;
+         int height, width;
+         char *buf, *ptr;
+         int basicwidth;
+         int wrap = (gtk_text_view_get_wrap_mode(GTK_TEXT_VIEW(widget)) == GTK_WRAP_WORD);
+         static char testtext[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+         
+         *thisheight = 20;
+         basicwidth = *thiswidth = 20;
+         
+         dw_mle_get_size(item, &bytes, NULL);
+         
+         ptr = buf = alloca(bytes + 2);
+         dw_mle_export(item, buf, 0, (int)bytes);
+         buf[bytes] = 0;
+         strcat(buf, "\n");
+         
+         /* MLE */
+         while((ptr = strstr(buf, "\n")))
+         {
+            ptr[0] = 0;
+            width = 0;
+            if(strlen(buf))
+               dw_font_text_extents_get(item, NULL, buf, &width, &height);
+            else
+               dw_font_text_extents_get(item, NULL, testtext, NULL, &height);
+            
+            width += basicwidth;
+            
+            if(wrap && width > _DW_SCROLLED_MAX_WIDTH)
+            {
+               *thiswidth = _DW_SCROLLED_MAX_WIDTH;
+               *thisheight += height * (width / _DW_SCROLLED_MAX_WIDTH);
+            }
+            else
+            {
+               if(width > *thiswidth)
+                  *thiswidth = width > _DW_SCROLLED_MAX_WIDTH ? _DW_SCROLLED_MAX_WIDTH : width;
+            }
+            *thisheight += height;
+            buf = &ptr[1];
+         }
+      }
+   }
+   else
+   {
+      /* Set to max for others */
+      *thiswidth = _DW_SCROLLED_MAX_WIDTH;
+      *thisheight = _DW_SCROLLED_MAX_HEIGHT;
+   }
+   if(*thiswidth < _DW_SCROLLED_MIN_WIDTH)
+      *thiswidth = _DW_SCROLLED_MIN_WIDTH;
+   if(*thiswidth > _DW_SCROLLED_MAX_WIDTH)
+      *thiswidth = _DW_SCROLLED_MAX_WIDTH;
+   if(*thisheight < _DW_SCROLLED_MIN_HEIGHT)
+      *thisheight = _DW_SCROLLED_MIN_HEIGHT;
+   if(*thisheight > _DW_SCROLLED_MAX_HEIGHT)
+      *thisheight = _DW_SCROLLED_MAX_HEIGHT;
+}
+
 /* Internal box packing function called by the other 3 functions */
 void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname)
 {
@@ -10121,42 +10200,16 @@
          /* If it is a scrolled item and not expandable...
           * Clamp to minumum or maximum.
           */         
-         if(GTK_IS_SCROLLED_WINDOW(item))
+         if(GTK_IS_SCROLLED_WINDOW(item) && ((width < 1 && !hsize) || (height < 1 && !vsize)))
          {
-            GtkWidget *widget = gtk_object_get_user_data(GTK_OBJECT(item));
-            
-            /* Try to figure out the contents for MLE and Container */
-            if(widget && (GTK_IS_TEXT_VIEW(widget) || GTK_IS_CLIST(widget)))
-            {
-               GtkRequisition req;
-               
-               gtk_widget_size_request(widget, &req);
-               
-               if(thiswidth < 1 && !hsize)
-               {
-                  thiswidth = req.width + 20;
-                  if(thiswidth < _DW_SCROLLED_MIN_WIDTH)
-                     thiswidth = _DW_SCROLLED_MIN_WIDTH;
-                  if(thiswidth > _DW_SCROLLED_MAX_WIDTH)
-                     thiswidth = _DW_SCROLLED_MAX_WIDTH;
-               }
-               if(thisheight < 1 && !vsize)
-               {
-                  thisheight = req.height + 20;
-                  if(thisheight < _DW_SCROLLED_MIN_HEIGHT)
-                     thisheight = _DW_SCROLLED_MIN_HEIGHT;
-                  if(thisheight > _DW_SCROLLED_MAX_HEIGHT)
-                     thisheight = _DW_SCROLLED_MAX_HEIGHT;
-               }
-            }
-            else
-            {
-               /* Set to max for others */
-               if(thiswidth < 1 && !hsize)
-                  thiswidth = _DW_SCROLLED_MAX_WIDTH;
-               if(thisheight < 1 && !vsize)
-                  thisheight = _DW_SCROLLED_MAX_HEIGHT;
-            }
+            gint scrolledwidth = 0, scrolledheight = 0;
+         
+            _get_scrolled_size(item, &scrolledwidth, &scrolledheight);
+         
+            if(width < 1 && !hsize)
+               thiswidth = scrolledwidth;
+            if(height < 1 && !vsize)
+               thisheight = scrolledheight;
          }
          gtk_widget_set_usize(item, thiswidth, thisheight);
       }
@@ -10408,11 +10461,25 @@
    int _locked_by_me = FALSE;
 
    DW_MUTEX_LOCK;
-   gtk_widget_size_request(handle, &req);
-   if(width)
-      *width = req.width;
-   if(height)
-      *height = req.height;
+   if(GTK_IS_SCROLLED_WINDOW(handle))
+   {
+      gint scrolledwidth, scrolledheight;
+      
+      _get_scrolled_size(handle, &scrolledwidth, &scrolledheight);
+      
+      if(width)
+         *width = scrolledwidth;
+      if(height)
+         *height = scrolledheight;
+   }
+   else
+   {
+      gtk_widget_size_request(handle, &req);
+      if(width)
+         *width = req.width;
+      if(height)
+         *height = req.height;
+   }
    DW_MUTEX_UNLOCK;
 }
 
--- a/gtk3/dw.c	Tue Jan 17 16:33:21 2012 +0000
+++ b/gtk3/dw.c	Tue Jan 17 18:18:00 2012 +0000
@@ -8337,6 +8337,94 @@
    exit(exitcode);
 }
 
+/* Internal function to get the recommended size of scrolled items */
+void _get_scrolled_size(GtkWidget *item, gint *thiswidth, gint *thisheight)
+{
+   GtkWidget *widget = g_object_get_data(G_OBJECT(item), "_dw_user");
+   
+   *thisheight = *thiswidth = 0;
+   
+   if(widget)
+   {
+      if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE))
+      {
+         *thiswidth = _DW_SCROLLED_MAX_WIDTH;
+         *thisheight = _DW_SCROLLED_MAX_HEIGHT;
+      }
+      else if(GTK_IS_TEXT_VIEW(widget))
+      {
+         unsigned long bytes;
+         int height, width;
+         char *buf, *ptr;
+         int wrap = (gtk_text_view_get_wrap_mode(GTK_TEXT_VIEW(widget)) == GTK_WRAP_WORD);
+         static char testtext[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+         int hscrolled = FALSE;
+         
+         *thiswidth = *thisheight = 0;
+         
+         dw_mle_get_size(item, &bytes, NULL);
+         
+         ptr = buf = alloca(bytes + 2);
+         dw_mle_export(item, buf, 0, (int)bytes);
+         buf[bytes] = 0;
+         strcat(buf, "\n");
+         
+         /* MLE */
+         while((ptr = strstr(buf, "\r")))
+         {
+            ptr[0] = 0;
+            width = 0;
+            if(strlen(buf))
+               dw_font_text_extents_get(item, NULL, buf, &width, &height);
+            else
+               dw_font_text_extents_get(item, NULL, testtext, NULL, &height);
+            
+            if(wrap && width > _DW_SCROLLED_MAX_WIDTH)
+            {
+               *thiswidth = _DW_SCROLLED_MAX_WIDTH;
+               *thisheight += height * (width / _DW_SCROLLED_MAX_WIDTH);
+            }
+            else
+            {
+               if(width > *thiswidth)
+               {
+                  if(width > _DW_SCROLLED_MAX_WIDTH)
+                  {
+                     *thiswidth = _DW_SCROLLED_MAX_WIDTH;
+                     hscrolled = TRUE;
+                  }
+                  else
+                     *thiswidth = width;
+               }
+            }
+            *thisheight += height;
+            if(ptr[1] == '\n')
+               buf = &ptr[2];
+            else
+               buf = &ptr[1];
+         }
+         if(hscrolled)
+            *thisheight += 20;
+      }
+      else
+      {
+         gtk_widget_get_preferred_height(GTK_WIDGET(widget), NULL, thisheight);
+         gtk_widget_get_preferred_width(GTK_WIDGET(widget), NULL, thiswidth);
+         
+         *thisheight += 20;
+         *thiswidth += 20;
+      }
+   }
+   if(*thiswidth < _DW_SCROLLED_MIN_WIDTH)
+      *thiswidth = _DW_SCROLLED_MIN_WIDTH;
+   if(*thiswidth > _DW_SCROLLED_MAX_WIDTH)
+      *thiswidth = _DW_SCROLLED_MAX_WIDTH;
+   if(*thisheight < _DW_SCROLLED_MIN_HEIGHT)
+      *thisheight = _DW_SCROLLED_MIN_HEIGHT;
+   if(*thisheight > _DW_SCROLLED_MAX_HEIGHT)
+      *thisheight = _DW_SCROLLED_MAX_HEIGHT;
+}
+
 /* Internal box packing function called by the other 3 functions */
 void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname)
 {
@@ -8467,48 +8555,20 @@
       /* Special case for scrolled windows */
       if(GTK_IS_SCROLLED_WINDOW(item))
       {
+         gint scrolledwidth = 0, scrolledheight = 0;
+         
+         /* Pre-run the calculation code for MLE/Container/Tree if needed */
+         if((width < 1 && !hsize) || (height < 1 && !vsize))
+            _get_scrolled_size(item, &scrolledwidth, &scrolledheight);
+         
          if(width > 0)
             gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(item), width);
          else if(!hsize)
-         {
-            /* If we aren't expandable set the minimum width */
-            gint thiswidth = 0;
-            GtkWidget *widget = g_object_get_data(G_OBJECT(item), "_dw_user");
-            
-            if(widget)
-            {
-               if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE))
-                  thiswidth = _DW_SCROLLED_MAX_WIDTH;
-               else
-                  gtk_widget_get_preferred_width(GTK_WIDGET(widget), NULL, &thiswidth);
-            }
-            if(thiswidth < _DW_SCROLLED_MIN_WIDTH)
-               thiswidth = _DW_SCROLLED_MIN_WIDTH;
-            if(thiswidth > _DW_SCROLLED_MAX_WIDTH)
-               thiswidth = _DW_SCROLLED_MAX_WIDTH;
-            gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(item), thiswidth);
-         }
+            gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(item), scrolledwidth);
          if(height > 0)
             gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(item), height);
          else if(!vsize)
-         {
-            /* If we aren't expandable set the minimum height */
-            gint thisheight = 0;
-            GtkWidget *widget = g_object_get_data(G_OBJECT(item), "_dw_user");
-            
-            if(widget)
-            {
-               if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE))
-                  thisheight = _DW_SCROLLED_MAX_HEIGHT;
-               else
-                 gtk_widget_get_preferred_height(GTK_WIDGET(widget), NULL, &thisheight);
-            }
-            if(thisheight < _DW_SCROLLED_MIN_HEIGHT)
-               thisheight = _DW_SCROLLED_MIN_HEIGHT;
-            if(thisheight > _DW_SCROLLED_MAX_HEIGHT)
-               thisheight = _DW_SCROLLED_MAX_HEIGHT;
-            gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(item), thisheight);
-         }
+            gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(item), scrolledheight);
       }
       else
       {
@@ -8765,10 +8825,24 @@
    int _locked_by_me = FALSE;
 
    DW_MUTEX_LOCK;
-   if(width)
-      gtk_widget_get_preferred_width(handle, NULL, width);
-   if(height)
-      gtk_widget_get_preferred_height(handle, NULL, height);
+   if(GTK_IS_SCROLLED_WINDOW(handle))
+   {
+      gint scrolledwidth, scrolledheight;
+      
+      _get_scrolled_size(handle, &scrolledwidth, &scrolledheight);
+      
+      if(width)
+         *width = scrolledwidth;
+      if(height)
+         *height = scrolledheight;
+   }
+   else
+   {
+      if(width)
+         gtk_widget_get_preferred_width(handle, NULL, width);
+      if(height)
+         gtk_widget_get_preferred_height(handle, NULL, height);
+   }
    DW_MUTEX_UNLOCK;
 }
 
--- a/win/dw.c	Tue Jan 17 16:33:21 2012 +0000
+++ b/win/dw.c	Tue Jan 17 18:18:00 2012 +0000
@@ -4528,6 +4528,7 @@
          
          ptr = buf = _alloca(bytes + 2);
          dw_mle_export(handle, buf, 0, (int)bytes);
+         buf[bytes] = 0;
          strcat(buf, "\n");
          
          /* MLE */