changeset 1422:131bedf41332

Initial support for automatic redrawing on Windows and ranged/bitmap auto-calculation support. Also some code optimization and cleanup on the Mac gleaned from the Windows changes.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sat, 03 Dec 2011 02:08:40 +0000
parents 63d253a2cdd9
children 1bb1865fed9d
files mac/dw.m win/dw.c
diffstat 2 files changed, 134 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/mac/dw.m	Sat Dec 03 00:09:34 2011 +0000
+++ b/mac/dw.m	Sat Dec 03 02:08:40 2011 +0000
@@ -152,10 +152,13 @@
 int _dw_main_iteration(NSDate *date);
 
 /* Internal function to queue a window redraw */
-void _dw_redraw(id window)
+void _dw_redraw(id window, int skip)
 {
     static id lastwindow = nil;
     
+    if(skip && window == nil)
+      return;
+
     if(lastwindow != window && lastwindow != nil)
     {
         dw_window_redraw(lastwindow);
@@ -455,7 +458,8 @@
 int _event_handler(id object, NSEvent *event, int message)
 {
     int ret = _event_handler1(object, event, message);
-    _dw_redraw(nil);
+    if(ret != -1)
+        _dw_redraw(nil, FALSE);
     return ret;
 }
 
@@ -3540,7 +3544,9 @@
  * Entryfield/Combobox/Spinbutton: 150x(maxfontheight)
  * Spinbutton: 50x(maxfontheight)
  * Text/Status: (textwidth)x(textheight)
- */
+ * Ranged: 100x14 or 14x100 for vertical.
+ * Buttons/Bitmaps: Size of text or image and border.
+*/
 void _control_size(id handle, int *width, int *height)
 {
     int thiswidth = 1, thisheight = 1, extrawidth = 0, extraheight = 0;
@@ -3779,7 +3785,7 @@
         [button setParent:view];
     }
     /* Queue a redraw on the top-level window */
-    _dw_redraw([object window]);
+    _dw_redraw([object window], TRUE);
 
     /* Free the old data */
     if(thisbox->count)
@@ -8173,9 +8179,11 @@
         
         /* Check to see if any of the sizes need to be recalculated */
         if(item && (item->origwidth == -1 || item->origheight == -1))
+        {
             _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL); 
-        /* Queue a redraw on the top-level window */
-        _dw_redraw([object window]);
+            /* Queue a redraw on the top-level window */
+            _dw_redraw([object window], TRUE);
+        }
         return DW_ERROR_NONE;
     }
     return DW_ERROR_UNKNOWN;
@@ -8354,9 +8362,11 @@
     
     /* Check to see if any of the sizes need to be recalculated */
     if(item && (item->origwidth == -1 || item->origheight == -1))
+    {
         _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL);        
-    /* Queue a redraw on the top-level window */
-    _dw_redraw([object window]);
+        /* Queue a redraw on the top-level window */
+        _dw_redraw([object window], TRUE);
+    }
 }
 
 /*
@@ -8450,8 +8460,16 @@
             [iv setImage:pixmap];
         }
         [pixmap release];
-        /* Queue a redraw on the top-level window */
-        _dw_redraw([iv window]);
+        /* If we changed the text... */
+        Item *item = _box_item(handle);
+       
+        /* Check to see if any of the sizes need to be recalculated */
+        if(item && (item->origwidth == -1 || item->origheight == -1))
+        {
+            _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL);        
+            /* Queue a redraw on the top-level window */
+            _dw_redraw([iv window], TRUE);
+        }
     }
 }
 
@@ -8486,7 +8504,7 @@
         {
             [iv setImage:bitmap];
             /* Queue a redraw on the top-level window */
-            _dw_redraw([iv window]);
+            _dw_redraw([iv window], TRUE);
         }
     }
 }
--- a/win/dw.c	Sat Dec 03 00:09:34 2011 +0000
+++ b/win/dw.c	Sat Dec 03 02:08:40 2011 +0000
@@ -182,6 +182,21 @@
 void _click_default(HWND handle);
 void _do_resize(Box *thisbox, int x, int y);
 
+/* Internal function to queue a window redraw */
+void _dw_redraw(HWND window, int skip)
+{
+    static HWND lastwindow = 0;
+    
+    if(skip && !window)
+      return;
+    
+    if(lastwindow != window && lastwindow)
+    {
+        dw_window_redraw(lastwindow);
+    }
+    lastwindow = window;
+}
+
 typedef struct _sighandler
 {
    struct _sighandler   *next;
@@ -1052,6 +1067,8 @@
    /* Find the toplevel window */
    while((box = GetParent(lastbox)))
    {
+      if(box == DW_HWND_OBJECT)
+         return 0;
       lastbox = box;
    }
    if(lastbox)
@@ -2388,11 +2405,13 @@
       break;
    }
    if(result != -1)
+   {
+      /* Make sure any queued redraws are handled */
+      _dw_redraw(0, FALSE);
+      /* Then finally return */
       return result;
-   else
-   {
-      return DefWindowProc(hWnd, msg, mp1, mp2);
-   }
+   }
+   return DefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 VOID CALLBACK _TimerProc(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime)
@@ -4339,25 +4358,44 @@
  * Entryfield/Combobox/Spinbutton: 150x(maxfontheight)
  * Spinbutton: 50x(maxfontheight)
  * Text/Status: (textwidth)x(textheight)
+ * Ranged: 100x14 or 14x100 for vertical.
+ * Buttons/Bitmaps: Size of text or image and border.
  */
 void _control_size(HWND handle, int *width, int *height)
 {
    int thiswidth = 1, thisheight = 1, extrawidth = 0, extraheight = 0;
    char tmpbuf[100], *buf = dw_window_get_text(handle);
    static char testtext[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+   HBITMAP hbm = 0;
 
    GetClassName(handle, tmpbuf, 99);
 
-    /* If we have a string... 
-     * calculate the size with the current font.
-     */
-    if(buf)
-    {
-       if(*buf)
-          dw_font_text_extents_get(handle, NULL, buf, &thiswidth, &thisheight);
-       dw_free(buf);
-    }
-            
+   /* If we have a string... 
+    * calculate the size with the current font.
+    */
+   if(buf)
+   {
+      if(*buf)
+         dw_font_text_extents_get(handle, NULL, buf, &thiswidth, &thisheight);
+      dw_free(buf);
+   }
+   
+   /* Attempt to get bitmap from classes that can have them */
+   if(strnicmp(tmpbuf, STATICCLASSNAME, strlen(STATICCLASSNAME)+1) == 0)
+      hbm = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
+   if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1) == 0)
+      hbm = (HBITMAP)SendMessage(handle, BM_GETIMAGE, IMAGE_BITMAP, 0);
+      
+   /* If we got an image... set the sizes appropriately */
+   if(hbm)
+   {
+      BITMAP bmi;
+      
+      GetObject(hbm, sizeof(BITMAP), &bmi);
+      thiswidth = bmi.bmWidth;
+      thisheight = bmi.bmHeight;
+   }
+   
    /* Combobox */
    if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1) == 0)
    {
@@ -4367,11 +4405,32 @@
       if(thisheight < 18)
         thisheight = 18;
    }
+   /* Ranged: Percent, Slider, Scrollbar */
+   else if(strnicmp(tmpbuf, PROGRESS_CLASS, strlen(PROGRESS_CLASS)+1) == 0 || 
+           strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1) == 0 ||
+           strnicmp(tmpbuf, SCROLLBARCLASSNAME, strlen(SCROLLBARCLASSNAME)+1) == 0)
+   {
+      if(strnicmp(tmpbuf, SCROLLBARCLASSNAME, strlen(SCROLLBARCLASSNAME)+1) == 0 &&
+        GetWindowLong(handle, GWL_STYLE) & SBS_VERT)
+      {
+         /* Vertical */
+         thiswidth = 14;
+         thisheight = 100;
+      }
+      else
+      {
+         /* Horizontal */
+         thiswidth = 100;
+         thisheight = 14;
+      }
+   }
+   /* Spinbuttons */
    else if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1) == 0)
    {
       dw_font_text_extents_get(handle, NULL, testtext, NULL, &thisheight);
       thiswidth = 50;
    }
+   /* Entryfields */
    else if(strnicmp(tmpbuf, EDITCLASSNAME, strlen(EDITCLASSNAME)+1) == 0 &&
            !(GetWindowLong(handle, GWL_STYLE) & ES_MULTILINE))
    {
@@ -4383,11 +4442,19 @@
    {
       ULONG style = GetWindowLong(handle, GWL_STYLE);
       
-      if(style & BS_AUTOCHECKBOX || style & BS_AUTORADIOBUTTON)
+      /* Bitmap buttons */
+      if(hbm)
+      {
+         extrawidth = 2;
+         extraheight = 2;
+      }
+      /* Checkbox or radio button */
+      else if(style & BS_AUTOCHECKBOX || style & BS_AUTORADIOBUTTON)
       {
          extrawidth = 24;
          extraheight = 4;
       }
+      /* Text buttons */
       else
       {
          extrawidth = 8;
@@ -4399,7 +4466,6 @@
       extrawidth = 4;
       extraheight = 2;
    }
-   
 
    /* Set the requested sizes */    
    if(width)
@@ -4468,7 +4534,11 @@
         
        /* Check to see if any of the sizes need to be recalculated */
        if(item && (item->origwidth == -1 || item->origheight == -1))
+       {
           _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL); 
+          /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(handle), TRUE);
+       }
        return DW_ERROR_NONE;
     }
    return DW_ERROR_UNKNOWN;
@@ -6214,6 +6284,19 @@
       DeleteObject(oldbitmap);
    else if(icon && oldicon)
       DeleteObject(oldicon);
+
+   /* If we changed the bitmap... */
+   {
+      Item *item = _box_item(handle);
+       
+      /* Check to see if any of the sizes need to be recalculated */
+      if(item && (item->origwidth == -1 || item->origheight == -1))
+      {
+         _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL); 
+         /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(handle), TRUE);
+      }
+   }
 }
 
 /*
@@ -6336,7 +6419,11 @@
        
       /* Check to see if any of the sizes need to be recalculated */
       if(item && (item->origwidth == -1 || item->origheight == -1))
+      {
          _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL); 
+         /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(handle), TRUE);
+      }
    }
 }
 
@@ -6566,6 +6653,8 @@
             SendMessage(item, UDM_SETBUDDY, (WPARAM)cinfo->buddy, 0);
          }
       }
+      /* Queue a redraw on the top-level window */
+      _dw_redraw(_toplevel_window(item), TRUE);
    }
 }