comparison win/dw.c @ 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 53b677d126dc
children 9be19dbd2ff4
comparison
equal deleted inserted replaced
838:8e0405435d0a 839:ccfa5173659f
87 void _resize_notebook_page(HWND handle, int pageid); 87 void _resize_notebook_page(HWND handle, int pageid);
88 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y); 88 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
89 int _lookup_icon(HWND handle, HICON hicon, int type); 89 int _lookup_icon(HWND handle, HICON hicon, int type);
90 HFONT _acquire_font(HWND handle, char *fontname); 90 HFONT _acquire_font(HWND handle, char *fontname);
91 void _click_default(HWND handle); 91 void _click_default(HWND handle);
92 void _do_resize(Box *thisbox, int x, int y);
92 93
93 typedef struct _sighandler 94 typedef struct _sighandler
94 { 95 {
95 struct _sighandler *next; 96 struct _sighandler *next;
96 ULONG message; 97 ULONG message;
1363 if(cinfo) 1364 if(cinfo)
1364 { 1365 {
1365 MoveWindow(cinfo->buddy, currentx + pad, currenty + pad, 1366 MoveWindow(cinfo->buddy, currentx + pad, currenty + pad,
1366 (width + vectorx) - 20, height + vectory, FALSE); 1367 (width + vectorx) - 20, height + vectory, FALSE);
1367 } 1368 }
1369 }
1370 else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
1371 {
1372 /* Then try the bottom or right box */
1373 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
1374 int cx = width + vectorx;
1375 int cy = height + vectory;
1376 int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
1377 Box *thisbox = (Box *)GetWindowLongPtr(cinfo->combo, GWLP_USERDATA);
1378 RECT rect;
1379
1380 /* Position the scrollbox */
1381 MoveWindow(handle, currentx + pad, currenty + pad, cx, cy, FALSE);
1382
1383 GetClientRect(handle, &rect);
1384 cx = rect.right;
1385 cy = rect.bottom;
1386
1387
1388 /* Get the required space for the box */
1389 _resize_box(thisbox, &depth, cx, cy, &usedx, &usedy, 1, &usedpadx, &usedpady);
1390
1391 if(cx < usedx)
1392 {
1393 cx = usedx;
1394 }
1395 if(cy < usedy)
1396 {
1397 cy = usedy;
1398 }
1399
1400 /* Position the scrolled box */
1401 MoveWindow(cinfo->combo, 0, 0, cx, cy, FALSE);
1402
1403 /* Layout the content of the scrollbox */
1404 _do_resize(thisbox, cx, cy);
1368 } 1405 }
1369 else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) 1406 else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
1370 { 1407 {
1371 /* Then try the bottom or right box */ 1408 /* Then try the bottom or right box */
1372 float *percent = (float *)dw_window_get_data(handle, "_dw_percent"); 1409 float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
2081 } 2118 }
2082 break; 2119 break;
2083 case WM_HSCROLL: 2120 case WM_HSCROLL:
2084 case WM_VSCROLL: 2121 case WM_VSCROLL:
2085 { 2122 {
2086 char tmpbuf[100]; 2123 char tmpbuf[100] = "";
2087 HWND handle = (HWND)mp2; 2124 HWND handle = (HWND)mp2;
2088 int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction; 2125 int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
2089 2126
2090 GetClassName(handle, tmpbuf, 99); 2127 if(!GetClassName(handle, tmpbuf, 99))
2091 #ifndef SCROLLBOX_DEBUG 2128 {
2092 dw_messagebox("Scrollbar", DW_MB_OK, "%s %d: %s",__FILE__,__LINE__,tmpbuf); 2129 GetClassName(hWnd, tmpbuf, 99);
2093 #endif 2130 }
2131
2094 if (strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0) 2132 if (strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0)
2095 { 2133 {
2096 2134
2097 if (handle == tmp->window) 2135 if (handle == tmp->window)
2098 { 2136 {
2107 tmp = NULL; 2145 tmp = NULL;
2108 } 2146 }
2109 } 2147 }
2110 else if(strnicmp(tmpbuf, SCROLLBARCLASSNAME, strlen(SCROLLBARCLASSNAME)+1)==0) 2148 else if(strnicmp(tmpbuf, SCROLLBARCLASSNAME, strlen(SCROLLBARCLASSNAME)+1)==0)
2111 { 2149 {
2112 #ifndef SCROLLBOX_DEBUG
2113 dw_messagebox("Scrollbar", DW_MB_OK, "%s %d",__FILE__,__LINE__);
2114 #endif
2115 if(handle == tmp->window) 2150 if(handle == tmp->window)
2116 { 2151 {
2117 int bar = (origmsg == WM_HSCROLL) ? SB_HORZ : SB_VERT; 2152 int bar = (origmsg == WM_HSCROLL) ? SB_HORZ : SB_VERT;
2118 int value = _HandleScroller(handle, bar, (int)HIWORD(mp1), (int)LOWORD(mp1)); 2153 int value = _HandleScroller(handle, bar, (int)HIWORD(mp1), (int)LOWORD(mp1));
2119 2154
3173 3208
3174 ShowWindow(handle1, SW_SHOW); 3209 ShowWindow(handle1, SW_SHOW);
3175 ShowWindow(handle2, SW_SHOW); 3210 ShowWindow(handle2, SW_SHOW);
3176 } 3211 }
3177 3212
3213 /* This handles any activity on the scrollbox */
3214 BOOL CALLBACK _scrollwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
3215 {
3216 switch (msg)
3217 {
3218 case WM_HSCROLL:
3219 case WM_VSCROLL:
3220 {
3221 HWND handle = (HWND)mp2;
3222 }
3223 break;
3224 }
3225 return DefWindowProc(hwnd, msg, mp1, mp2);
3226 }
3227
3178 /* This handles any activity on the splitbars (sizers) */ 3228 /* This handles any activity on the splitbars (sizers) */
3179 BOOL CALLBACK _splitwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2) 3229 BOOL CALLBACK _splitwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
3180 { 3230 {
3181 switch (msg) 3231 switch (msg)
3182 { 3232 {
3600 wc.cbClsExtra = 0; 3650 wc.cbClsExtra = 0;
3601 wc.cbWndExtra = 0; 3651 wc.cbWndExtra = 0;
3602 wc.hbrBackground = NULL; 3652 wc.hbrBackground = NULL;
3603 wc.lpszMenuName = NULL; 3653 wc.lpszMenuName = NULL;
3604 wc.lpszClassName = SplitbarClassName; 3654 wc.lpszClassName = SplitbarClassName;
3655
3656 RegisterClass(&wc);
3657
3658 /* Register the scroller control */
3659 memset(&wc, 0, sizeof(WNDCLASS));
3660 wc.style = CS_DBLCLKS;
3661 wc.lpfnWndProc = (WNDPROC)_scrollwndproc;
3662 wc.cbClsExtra = 0;
3663 wc.cbWndExtra = 32;
3664 wc.hbrBackground = NULL;
3665 wc.lpszMenuName = NULL;
3666 wc.lpszClassName = ScrollClassName;
3605 3667
3606 RegisterClass(&wc); 3668 RegisterClass(&wc);
3607 3669
3608 /* Register a frame control like on OS/2 */ 3670 /* Register a frame control like on OS/2 */
3609 memset(&wc, 0, sizeof(WNDCLASS)); 3671 memset(&wc, 0, sizeof(WNDCLASS));
4420 * type: Either DW_VERT (vertical) or DW_HORZ (horizontal). 4482 * type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
4421 * pad: Number of pixels to pad around the box. 4483 * pad: Number of pixels to pad around the box.
4422 */ 4484 */
4423 HWND API dw_scrollbox_new(int type, int pad) 4485 HWND API dw_scrollbox_new(int type, int pad)
4424 { 4486 {
4425 Box *newbox = calloc(sizeof(Box), 1); 4487 ColorInfo *cinfo = calloc(sizeof(ColorInfo), 1);
4426 HWND hwndframe; 4488 HWND hwndframe, box = dw_box_new(type, pad);
4427 4489 HWND tmpbox = dw_box_new(DW_VERT, 0);
4428 newbox->pad = pad; 4490 dw_box_pack_start(tmpbox, box, 1, 1, TRUE, TRUE, 0);
4429 newbox->type = type; 4491
4430 newbox->count = 0; 4492 cinfo->fore = cinfo->back = -1;
4431 newbox->grouphwnd = (HWND)NULL; 4493
4432 newbox->cinfo.fore = newbox->cinfo.back = -1; 4494 hwndframe = CreateWindow(ScrollClassName,
4433
4434 hwndframe = CreateWindow(FRAMECLASSNAME,
4435 "", 4495 "",
4436 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | WS_THICKFRAME, 4496 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
4437 0,0,2000,1000, 4497 0,0,2000,1000,
4438 DW_HWND_OBJECT, 4498 DW_HWND_OBJECT,
4439 NULL, 4499 NULL,
4440 DWInstance, 4500 DWInstance,
4441 NULL); 4501 NULL);
4442 4502
4443 newbox->cinfo.pOldProc = SubclassWindow(hwndframe, _colorwndproc); 4503 cinfo->buddy = box;
4444 newbox->cinfo.fore = newbox->cinfo.back = -1; 4504 cinfo->combo = tmpbox;
4445 4505 SetParent(tmpbox, hwndframe);
4446 SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox); 4506 SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)cinfo);
4447 _dw_log( "Handle for scrollbox %x\n", hwndframe); 4507 return hwndframe;
4448 return hwndframe;
4449 } 4508 }
4450 4509
4451 int API dw_scrollbox_get_pos( HWND handle, int orient ) 4510 int API dw_scrollbox_get_pos( HWND handle, int orient )
4452 { 4511 {
4453 return 0; 4512 return 0;
5865 * vsize: TRUE if the window (widget) should expand vertically to fill space given. 5924 * vsize: TRUE if the window (widget) should expand vertically to fill space given.
5866 * pad: Number of pixels of padding around the item. 5925 * pad: Number of pixels of padding around the item.
5867 */ 5926 */
5868 void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) 5927 void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
5869 { 5928 {
5870 Box *thisbox; 5929 Box *thisbox = NULL;
5930 char tmpbuf[100];
5871 5931
5872 /* 5932 /*
5873 * If you try and pack an item into itself VERY bad things can happen; like at least an 5933 * If you try and pack an item into itself VERY bad things can happen; like at least an
5874 * infinite loop on GTK! Lets be safe! 5934 * infinite loop on GTK! Lets be safe!
5875 */ 5935 */
5877 { 5937 {
5878 dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); 5938 dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!");
5879 return; 5939 return;
5880 } 5940 }
5881 5941
5882 thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA); 5942 GetClassName(box, tmpbuf, 99);
5943
5944 /* If we are in a scrolled box... extract the interal box */
5945 if(strnicmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
5946 {
5947 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(box, GWLP_USERDATA);
5948 if(cinfo)
5949 {
5950 box = cinfo->buddy;
5951 thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
5952 }
5953 }
5954 else //if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
5955 thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
5883 if(thisbox) 5956 if(thisbox)
5884 { 5957 {
5885 int z; 5958 int z;
5886 Item *tmpitem, *thisitem = thisbox->items; 5959 Item *tmpitem, *thisitem = thisbox->items;
5887 char tmpbuf[100];
5888 5960
5889 tmpitem = malloc(sizeof(Item)*(thisbox->count+1)); 5961 tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
5890 5962
5891 for(z=0;z<thisbox->count;z++) 5963 for(z=0;z<thisbox->count;z++)
5892 { 5964 {
9489 * vsize: TRUE if the window (widget) should expand vertically to fill space given. 9561 * vsize: TRUE if the window (widget) should expand vertically to fill space given.
9490 * pad: Number of pixels of padding around the item. 9562 * pad: Number of pixels of padding around the item.
9491 */ 9563 */
9492 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) 9564 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
9493 { 9565 {
9494 Box *thisbox; 9566 Box *thisbox = NULL;
9567 char tmpbuf[100];
9495 9568
9496 /* 9569 /*
9497 * If you try and pack an item into itself VERY bad things can happen; like at least an 9570 * If you try and pack an item into itself VERY bad things can happen; like at least an
9498 * infinite loop on GTK! Lets be safe! 9571 * infinite loop on GTK! Lets be safe!
9499 */ 9572 */
9501 { 9574 {
9502 dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); 9575 dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!");
9503 return; 9576 return;
9504 } 9577 }
9505 9578
9506 thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA); 9579 GetClassName(box, tmpbuf, 99);
9580
9581 /* If we are in a scrolled box... extract the interal box */
9582 if(strnicmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
9583 {
9584 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(box, GWLP_USERDATA);
9585 if(cinfo)
9586 {
9587 box = cinfo->buddy;
9588 thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
9589 }
9590 }
9591 else //if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
9592 thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
9507 if(thisbox) 9593 if(thisbox)
9508 { 9594 {
9509 int z; 9595 int z;
9510 Item *tmpitem, *thisitem = thisbox->items; 9596 Item *tmpitem, *thisitem = thisbox->items;
9511 char tmpbuf[100];
9512 9597
9513 tmpitem = malloc(sizeof(Item)*(thisbox->count+1)); 9598 tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
9514 9599
9515 for(z=0;z<thisbox->count;z++) 9600 for(z=0;z<thisbox->count;z++)
9516 { 9601 {