# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1007532229 0 # Node ID 4a02842f8074a3841607c7885416c9e63e8b4fd9 # Parent 61869769c050466d884272ec0ef1dc6c9313208d Added shift-tab and up/down/left/right button support. And added missing checkbox fix for windows. diff -r 61869769c050 -r 4a02842f8074 dw.h --- a/dw.h Thu Nov 29 15:10:39 2001 +0000 +++ b/dw.h Wed Dec 05 06:03:49 2001 +0000 @@ -351,6 +351,7 @@ typedef struct _bubblebutton { #if defined(__WIN32__) || defined(WINNT) ColorInfo cinfo; + int checkbox; #endif unsigned long id; char bubbletext[BUBBLE_HELP_MAX]; diff -r 61869769c050 -r 4a02842f8074 os2/dw.c --- a/os2/dw.c Thu Nov 29 15:10:39 2001 +0000 +++ b/os2/dw.c Wed Dec 05 06:03:49 2001 +0000 @@ -439,6 +439,178 @@ return 0; } +int _focus_check_box_back(Box *box, HWND handle, int start, HWND defaultitem) +{ + int z; + static HWND lasthwnd, firsthwnd; + static int finish_searching; + + /* Start is 2 when we have cycled completely and + * need to set the focus to the last widget we found + * that was valid. + */ + if(start == 2) + { + if(lasthwnd) + WinSetFocus(HWND_DESKTOP, lasthwnd); + return 0; + } + + /* Start is 1 when we are entering the function + * for the first time, it is zero when entering + * the function recursively. + */ + if(start == 1) + { + lasthwnd = handle; + finish_searching = 0; + firsthwnd = 0; + } + + /* Vertical boxes are inverted on OS/2 */ + if(box->type == BOXVERT) + { + for(z=box->count-1;z>-1;z--) + { + if(box->items[z].type == TYPEBOX) + { + Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER); + + if(thisbox && _focus_check_box_back(thisbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + else + { + if(box->items[z].hwnd == handle) + { + if(lasthwnd == handle && firsthwnd) + WinSetFocus(HWND_DESKTOP, firsthwnd); + else if(lasthwnd == handle && !firsthwnd) + finish_searching = 1; + else + WinSetFocus(HWND_DESKTOP, lasthwnd); + + /* If we aren't looking for the last handle, + * return immediately. + */ + if(!finish_searching) + return 1; + } + if(_validate_focus(box->items[z].hwnd)) + { + /* Start is 3 when we are looking for the + * first valid item in the layout. + */ + if(start == 3) + { + if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd)) + { + WinSetFocus(HWND_DESKTOP, box->items[z].hwnd); + return 1; + } + } + + if(!firsthwnd) + firsthwnd = box->items[z].hwnd; + + lasthwnd = box->items[z].hwnd; + } + else + { + char tmpbuf[100] = ""; + + WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); + if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ + { + Box *notebox; + HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, + (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); + + if(page) + { + notebox = (Box *)WinQueryWindowPtr(page, QWP_USER); + + if(notebox && _focus_check_box_back(notebox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + } + } + } + } + } + else + { + for(z=0;zcount;z++) + { + if(box->items[z].type == TYPEBOX) + { + Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER); + + if(thisbox && _focus_check_box_back(thisbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + else + { + if(box->items[z].hwnd == handle) + { + if(lasthwnd == handle && firsthwnd) + WinSetFocus(HWND_DESKTOP, firsthwnd); + else if(lasthwnd == handle && !firsthwnd) + finish_searching = 1; + else + WinSetFocus(HWND_DESKTOP, lasthwnd); + + /* If we aren't looking for the last handle, + * return immediately. + */ + if(!finish_searching) + return 1; + } + if(_validate_focus(box->items[z].hwnd)) + { + /* Start is 3 when we are looking for the + * first valid item in the layout. + */ + if(start == 3) + { + if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd)) + { + WinSetFocus(HWND_DESKTOP, box->items[z].hwnd); + return 1; + } + } + + if(!firsthwnd) + firsthwnd = box->items[z].hwnd; + + lasthwnd = box->items[z].hwnd; + } + else + { + char tmpbuf[100] = ""; + + WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); + if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ + { + Box *notebox; + HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, + (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); + + if(page) + { + notebox = (Box *)WinQueryWindowPtr(page, QWP_USER); + + if(notebox && _focus_check_box_back(notebox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + } + } + } + } + } + return 0; +} + /* This function finds the first widget in the * layout and moves the current focus to it. */ @@ -485,6 +657,33 @@ } } +/* This function finds the current widget in the + * layout and moves the current focus to the next item. + */ +void _shift_focus_back(HWND handle) +{ + Box *thisbox; + HWND box, lastbox = WinQueryWindow(handle, QW_PARENT); + + /* Find the toplevel window */ + while((box = WinQueryWindow(lastbox, QW_PARENT)) > 0x80000001) + { + lastbox = box; + } + + box = WinWindowFromID(lastbox, FID_CLIENT); + if(box) + thisbox = WinQueryWindowPtr(box, QWP_USER); + else + thisbox = WinQueryWindowPtr(lastbox, QWP_USER); + + if(thisbox) + { + if(_focus_check_box_back(thisbox, handle, 1, 0) == 0) + _focus_check_box_back(thisbox, handle, 2, 0); + } +} + /* ResetWindow: * Resizes window to the exact same size to trigger * recalculation of frame. @@ -1330,7 +1529,10 @@ case WM_CHAR: if(SHORT1FROMMP(mp2) == '\t') { - _shift_focus(hWnd); + if(CHARMSG(&msg)->fs & KC_SHIFT) + _shift_focus_back(hWnd); + else + _shift_focus(hWnd); return FALSE; } else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault) @@ -1361,7 +1563,10 @@ case WM_CHAR: if(SHORT1FROMMP(mp2) == '\t') { - _shift_focus(hWnd); + if(CHARMSG(&msg)->fs & KC_SHIFT) + _shift_focus_back(hWnd); + else + _shift_focus(hWnd); return FALSE; } else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault) @@ -1986,7 +2191,10 @@ case WM_CHAR: if(SHORT1FROMMP(mp2) == '\t') { - _shift_focus(hWnd); + if(CHARMSG(&msg)->fs & KC_SHIFT) + _shift_focus_back(hWnd); + else + _shift_focus(hWnd); return FALSE; } break; @@ -2410,8 +2618,21 @@ #endif if(SHORT1FROMMP(mp2) == '\t') { + if(CHARMSG(&msg)->fs & KC_SHIFT) + _shift_focus_back(hwnd); + else + _shift_focus(hwnd); + WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0); + return FALSE; + } + else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_LEFT || CHARMSG(&msg)->vkey == VK_UP)) + { + _shift_focus_back(hwnd); + return FALSE; + } + else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_RIGHT || CHARMSG(&msg)->vkey == VK_DOWN)) + { _shift_focus(hwnd); - WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0); return FALSE; } } @@ -2429,7 +2650,6 @@ if(!*bubble->bubbletext) break; - if(hwndBubble) { WinDestroyWindow(hwndBubble); diff -r 61869769c050 -r 4a02842f8074 win/dw.c --- a/win/dw.c Thu Nov 29 15:10:39 2001 +0000 +++ b/win/dw.c Wed Dec 05 06:03:49 2001 +0000 @@ -459,6 +459,109 @@ return 0; } +int _focus_check_box_back(Box *box, HWND handle, int start, HWND defaultitem) +{ + int z; + static HWND lasthwnd, firsthwnd; + static int finish_searching; + + /* Start is 2 when we have cycled completely and + * need to set the focus to the last widget we found + * that was valid. + */ + if(start == 2) + { + if(lasthwnd) + SetFocus(lasthwnd); + return 0; + } + + /* Start is 1 when we are entering the function + * for the first time, it is zero when entering + * the function recursively. + */ + if(start == 1) + { + lasthwnd = handle; + finish_searching = 0; + firsthwnd = 0; + } + + for(z=0;zcount;z++) + { + if(box->items[z].type == TYPEBOX) + { + Box *thisbox = (Box *)GetWindowLong(box->items[z].hwnd, GWL_USERDATA); + + if(thisbox && _focus_check_box_back(thisbox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + else + { + if(box->items[z].hwnd == handle) + { + if(lasthwnd == handle && firsthwnd) + SetFocus(firsthwnd); + else if(lasthwnd == handle && !firsthwnd) + finish_searching = 1; + else + SetFocus(lasthwnd); + + /* If we aren't looking for the last handle, + * return immediately. + */ + if(!finish_searching) + return 1; + } + if(_validate_focus(box->items[z].hwnd)) + { + /* Start is 3 when we are looking for the + * first valid item in the layout. + */ + if(start == 3) + { + if(!defaultitem || (defaultitem && box->items[z].hwnd == defaultitem)) + { + SetFocus(_normalize_handle(box->items[z].hwnd)); + return 1; + } + } + + if(!firsthwnd) + firsthwnd = _normalize_handle(box->items[z].hwnd); + + lasthwnd = _normalize_handle(box->items[z].hwnd); + } + else + { + char tmpbuf[100] = ""; + + GetClassName(box->items[z].hwnd, tmpbuf, 99); + + if(strnicmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL))==0) /* Notebook */ + { + NotebookPage **array = (NotebookPage **)GetWindowLong(box->items[z].hwnd, GWL_USERDATA); + int pageid = TabCtrl_GetCurSel(box->items[z].hwnd); + + if(pageid > -1 && array && array[pageid]) + { + Box *notebox; + + if(array[pageid]->hwnd) + { + notebox = (Box *)GetWindowLong(array[pageid]->hwnd, GWL_USERDATA); + + if(notebox && _focus_check_box_back(notebox, handle, start == 3 ? 3 : 0, defaultitem)) + return 1; + } + } + } + } + } + } + return 0; +} + /* This function finds the first widget in the * layout and moves the current focus to it. */ @@ -508,6 +611,29 @@ } } +/* This function finds the current widget in the + * layout and moves the current focus to the next item. + */ +void _shift_focus_back(HWND handle) +{ + Box *thisbox; + + HWND box, lastbox = GetParent(handle); + + /* Find the toplevel window */ + while((box = GetParent(lastbox))) + { + lastbox = box; + } + + thisbox = (Box *)GetWindowLong(lastbox, GWL_USERDATA); + if(thisbox) + { + if(_focus_check_box_back(thisbox, handle, 1, 0) == 0) + _focus_check_box_back(thisbox, handle, 2, 0); + } +} + /* ResetWindow: * Resizes window to the exact same size to trigger * recalculation of frame. @@ -1332,7 +1458,10 @@ case WM_CHAR: if(LOWORD(mp1) == '\t') { - _shift_focus(hWnd); + if(GetAsyncKeyState(VK_SHIFT)) + _shift_focus_back(hWnd); + else + _shift_focus(hWnd); return TRUE; } break; @@ -1653,12 +1782,24 @@ case WM_CHAR: if(LOWORD(mp1) == '\t') { - if(cinfo->combo) - _shift_focus(cinfo->combo); - else if(cinfo->buddy) - _shift_focus(cinfo->buddy); + if(GetAsyncKeyState(VK_SHIFT)) + { + if(cinfo->combo) + _shift_focus_back(cinfo->combo); + else if(cinfo->buddy) + _shift_focus_back(cinfo->buddy); + else + _shift_focus_back(hWnd); + } else - _shift_focus(hWnd); + { + if(cinfo->combo) + _shift_focus(cinfo->combo); + else if(cinfo->buddy) + _shift_focus(cinfo->buddy); + else + _shift_focus(hWnd); + } return FALSE; } else if(LOWORD(mp1) == '\r') @@ -1787,7 +1928,10 @@ if(LOWORD(mp1) == '\t') { - _shift_focus(hWnd); + if(GetAsyncKeyState(VK_SHIFT)) + _shift_focus_back(hWnd); + else + _shift_focus(hWnd); return FALSE; } @@ -1878,7 +2022,10 @@ case WM_CHAR: if(LOWORD(mp1) == '\t') { - _shift_focus(hWnd); + if(GetAsyncKeyState(VK_SHIFT)) + _shift_focus_back(hWnd); + else + _shift_focus(hWnd); return FALSE; } break; @@ -2261,11 +2408,20 @@ #endif if(LOWORD(mp1) == '\t') { - _shift_focus(hwnd); + if(GetAsyncKeyState(VK_SHIFT)) + _shift_focus_back(hwnd); + else + _shift_focus(hwnd); return FALSE; } } break; + case WM_KEYDOWN: + if(mp1 == VK_LEFT || mp1 == VK_UP) + _shift_focus_back(hwnd); + if(mp1 == VK_RIGHT || mp1 == VK_DOWN) + _shift_focus(hwnd); + break; case WM_TIMER: if (hwndBubble) {