changeset 839:ccfa5173659f

Initial implementation of scrollboxes on Windows. Windows does not have a scrolledview/area widget like on other platforms, so I have created one. Implemented the layout system like I did on MacOS and discovered what likely is the issue on the Mac. There seems to be a bug in the layout system which is avoided by packing into a single expandable box. When used and padding are exactly the same, the layout engine drops out to prevent a divide by zero. Will look into fixing this in the layout engine, but for now using the container box workaround. The scrolled view widget is not finished, will need to implement the scrollbars but internally.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 29 Mar 2011 17:21:50 +0000
parents 8e0405435d0a
children 2967934fb587
files dw.h win/dw.c
diffstat 2 files changed, 117 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/dw.h	Tue Mar 29 03:31:38 2011 +0000
+++ b/dw.h	Tue Mar 29 17:21:50 2011 +0000
@@ -592,6 +592,7 @@
 #define SplitbarClassName "dwsplitbar"
 #define ObjectClassName "dwobjectclass"
 #define BrowserClassName "dwbrowserclass"
+#define ScrollClassName "dwscrollclass"
 #define DefaultFont NULL
 
 typedef struct _color {
--- a/win/dw.c	Tue Mar 29 03:31:38 2011 +0000
+++ b/win/dw.c	Tue Mar 29 17:21:50 2011 +0000
@@ -89,6 +89,7 @@
 int _lookup_icon(HWND handle, HICON hicon, int type);
 HFONT _acquire_font(HWND handle, char *fontname);
 void _click_default(HWND handle);
+void _do_resize(Box *thisbox, int x, int y);
 
 typedef struct _sighandler
 {
@@ -1366,6 +1367,42 @@
                            (width + vectorx) - 20, height + vectory, FALSE);
                }
             }
+            else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
+            {
+                /* Then try the bottom or right box */
+                ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+                int cx = width + vectorx;
+                int cy = height + vectory;
+                int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
+                Box *thisbox = (Box *)GetWindowLongPtr(cinfo->combo, GWLP_USERDATA);
+                RECT rect;
+                
+                /* Position the scrollbox */
+                MoveWindow(handle, currentx + pad, currenty + pad, cx, cy, FALSE);
+
+                GetClientRect(handle, &rect);
+                cx = rect.right;
+                cy = rect.bottom;
+
+
+                /* Get the required space for the box */
+                _resize_box(thisbox, &depth, cx, cy, &usedx, &usedy, 1, &usedpadx, &usedpady);
+                
+                if(cx < usedx)
+                {
+                    cx = usedx;
+                }
+                if(cy < usedy)
+                {
+                    cy = usedy;
+                }
+
+                /* Position the scrolled box */
+                MoveWindow(cinfo->combo, 0, 0, cx, cy, FALSE);
+
+                /* Layout the content of the scrollbox */
+                _do_resize(thisbox, cx, cy);
+            }
             else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
             {
                /* Then try the bottom or right box */
@@ -2083,14 +2120,15 @@
                case WM_HSCROLL:
                case WM_VSCROLL:
                   {
-                     char tmpbuf[100];
+                     char tmpbuf[100] = "";
                      HWND handle = (HWND)mp2;
                      int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
 
-                     GetClassName(handle, tmpbuf, 99);
-#ifndef SCROLLBOX_DEBUG
-dw_messagebox("Scrollbar", DW_MB_OK, "%s %d: %s",__FILE__,__LINE__,tmpbuf);
-#endif
+                     if(!GetClassName(handle, tmpbuf, 99))
+                     {
+                         GetClassName(hWnd, tmpbuf, 99);
+                     }
+
                      if (strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0)
                      {
 
@@ -2109,9 +2147,6 @@
                      }
                      else if(strnicmp(tmpbuf, SCROLLBARCLASSNAME, strlen(SCROLLBARCLASSNAME)+1)==0)
                      {
-#ifndef SCROLLBOX_DEBUG
-dw_messagebox("Scrollbar", DW_MB_OK, "%s %d",__FILE__,__LINE__);
-#endif
                         if(handle == tmp->window)
                         {
                            int bar = (origmsg == WM_HSCROLL) ? SB_HORZ : SB_VERT;
@@ -3175,6 +3210,21 @@
    ShowWindow(handle2, SW_SHOW);
 }
 
+/* This handles any activity on the scrollbox */
+BOOL CALLBACK _scrollwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   switch (msg)
+   {
+   case WM_HSCROLL:
+   case WM_VSCROLL:
+      {
+         HWND handle = (HWND)mp2;
+      }
+      break;
+   }
+   return DefWindowProc(hwnd, msg, mp1, mp2);
+}
+
 /* This handles any activity on the splitbars (sizers) */
 BOOL CALLBACK _splitwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
@@ -3605,6 +3655,18 @@
 
    RegisterClass(&wc);
 
+   /* Register the scroller control */
+   memset(&wc, 0, sizeof(WNDCLASS));
+   wc.style = CS_DBLCLKS;
+   wc.lpfnWndProc = (WNDPROC)_scrollwndproc;
+   wc.cbClsExtra = 0;
+   wc.cbWndExtra = 32;
+   wc.hbrBackground = NULL;
+   wc.lpszMenuName = NULL;
+   wc.lpszClassName = ScrollClassName;
+
+   RegisterClass(&wc);
+
    /* Register a frame control like on OS/2 */
    memset(&wc, 0, sizeof(WNDCLASS));
    wc.style = CS_DBLCLKS;
@@ -4422,30 +4484,27 @@
  */
 HWND API dw_scrollbox_new(int type, int pad)
 {
-   Box *newbox = calloc(sizeof(Box), 1);
-   HWND hwndframe;
-
-   newbox->pad = pad;
-   newbox->type = type;
-   newbox->count = 0;
-   newbox->grouphwnd = (HWND)NULL;
-   newbox->cinfo.fore = newbox->cinfo.back = -1;
-
-   hwndframe = CreateWindow(FRAMECLASSNAME,
+    ColorInfo *cinfo = calloc(sizeof(ColorInfo), 1);
+    HWND hwndframe, box = dw_box_new(type, pad);
+    HWND tmpbox = dw_box_new(DW_VERT, 0);
+    dw_box_pack_start(tmpbox, box, 1, 1, TRUE, TRUE, 0);
+
+    cinfo->fore = cinfo->back = -1;
+
+    hwndframe = CreateWindow(ScrollClassName,
                       "",
-                      WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | WS_THICKFRAME,
+                      WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
                       0,0,2000,1000,
                       DW_HWND_OBJECT,
                       NULL,
                       DWInstance,
                       NULL);
 
-   newbox->cinfo.pOldProc = SubclassWindow(hwndframe, _colorwndproc);
-   newbox->cinfo.fore = newbox->cinfo.back = -1;
-
-   SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox);
-_dw_log( "Handle for scrollbox %x\n", hwndframe);
-   return hwndframe;
+    cinfo->buddy = box;
+    cinfo->combo = tmpbox;
+    SetParent(tmpbox, hwndframe);
+    SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)cinfo);
+    return hwndframe;
 }
 
 int API dw_scrollbox_get_pos( HWND handle, int orient )
@@ -5867,7 +5926,8 @@
  */
 void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
 {
-   Box *thisbox;
+   Box *thisbox = NULL;
+   char tmpbuf[100];
 
       /*
        * If you try and pack an item into itself VERY bad things can happen; like at least an
@@ -5879,12 +5939,24 @@
       return;
    }
 
-   thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
+   GetClassName(box, tmpbuf, 99);
+
+   /* If we are in a scrolled box... extract the interal box */
+   if(strnicmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
+   {
+        ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(box, GWLP_USERDATA);
+        if(cinfo)
+        {
+            box = cinfo->buddy;
+            thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
+        }
+   }
+   else //if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
+       thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
    if(thisbox)
    {
       int z;
       Item *tmpitem, *thisitem = thisbox->items;
-      char tmpbuf[100];
 
       tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
 
@@ -9491,7 +9563,8 @@
  */
 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
 {
-   Box *thisbox;
+   Box *thisbox = NULL;
+   char tmpbuf[100];
 
       /*
        * If you try and pack an item into itself VERY bad things can happen; like at least an
@@ -9503,12 +9576,24 @@
       return;
    }
 
-   thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
+   GetClassName(box, tmpbuf, 99);
+
+   /* If we are in a scrolled box... extract the interal box */
+   if(strnicmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
+   {
+        ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(box, GWLP_USERDATA);
+        if(cinfo)
+        {
+            box = cinfo->buddy;
+            thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
+        }
+   }
+   else //if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
+       thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
    if(thisbox)
    {
       int z;
       Item *tmpitem, *thisitem = thisbox->items;
-      char tmpbuf[100];
 
       tmpitem = malloc(sizeof(Item)*(thisbox->count+1));