diff options
Diffstat (limited to 'app/wlib/mswlib/mswbutt.c')
-rw-r--r-- | app/wlib/mswlib/mswbutt.c | 155 |
1 files changed, 119 insertions, 36 deletions
diff --git a/app/wlib/mswlib/mswbutt.c b/app/wlib/mswlib/mswbutt.c index 16f31c1..ac5bc87 100644 --- a/app/wlib/mswlib/mswbutt.c +++ b/app/wlib/mswlib/mswbutt.c @@ -27,7 +27,15 @@ #include <commdlg.h> #include <math.h> #include "mswint.h" -int kludge12 = 0; + +/** Macros for button repeat timers */ +#define REPEAT_STAGE0_DELAY 500 +#define REPEAT_STAGE1_DELAY 150 +#define REPEAT_STAGE2_DELAY 75 +#define STOP_TIMER (-1) +#define INITIAL_WAIT (0) +#define SLOW_REPEATS (1) +#define FAST_REPEATS (2) /* ***************************************************************************** @@ -45,6 +53,9 @@ struct wButton_t { wBool_t busy; wBool_t selected; wIcon_p icon; + UINT_PTR timer_id; + int timer_count; + int timer_state; }; @@ -75,7 +86,7 @@ static void drawButton( HPEN oldPen, newPen; RECT rect; COLORREF color1, color2; - POS_T offw=5, offh=5; + wWinPix_t offw=5, offh=5; TRIVERTEX vert[2] ; GRADIENT_RECT gRect; @@ -191,7 +202,7 @@ static void buttDrawIcon( HDC butt_hDc ) { wIcon_p bm = b->icon; - POS_T offw=5, offh=5; + wWinPix_t offw=5, offh=5; if (b->selected || b->busy) { offw++; offh++; @@ -204,14 +215,22 @@ static void buttDrawIcon( } void wButtonSetBusy( - wButton_p b, - int value ) + wButton_p b, + int value) { - b->busy = value; - if (!value) - b->selected = FALSE; - /*SendMessage( b->hWnd, BM_SETSTATE, (WPARAM)value, 0L );*/ - InvalidateRgn( b->hWnd, NULL, FALSE ); + b->busy = value; + if (!value) { + b->selected = FALSE; + } + + // in case a timer is associated with the button, kill it + if (b->timer_id) { + KillTimer(b->hWnd, b->timer_id); + b->timer_id = 0; + b->timer_state = STOP_TIMER; + } + + InvalidateRgn(b->hWnd, NULL, FALSE); } @@ -227,6 +246,60 @@ void wButtonSetLabel( } InvalidateRgn( b->hWnd, NULL, FALSE ); } + +/** + * Button timer: handle timer events for buttons. These are used for + * auto-repeating presses. Three phases used are + * - initial delay before repetitions begin + * - slow repeats for a few cycles + * - fast repeats therafter + * - stop timer + * + * \param hWnd Handle of the window, unused + * \param message The message, unused + * \param timer The timer id is the wlib widget . + * \param timepast The timepast, unused + */ + +void CALLBACK buttTimer(HWND hWnd, UINT message, UINT_PTR timer, + DWORD timepast) +{ + wButton_p b = (wButton_p)timer; + if (b->timer_id == 0) { + b->timer_state = STOP_TIMER; + return ; + } + + /* Autorepeat state machine */ + switch (b->timer_state) { + case INITIAL_WAIT: + b->timer_state = SLOW_REPEATS; + b->timer_count = 0; + KillTimer(hWnd, (UINT_PTR)b); + SetTimer(hWnd, (UINT_PTR)b, REPEAT_STAGE1_DELAY, buttTimer); + break; + case SLOW_REPEATS: /* Enable slow auto-repeat */ + if (b->timer_count++ > 10) { + /* Start fast auto-repeat */ + b->timer_state = FAST_REPEATS; + KillTimer(hWnd, (UINT_PTR)b); + SetTimer(hWnd, (UINT_PTR)b, REPEAT_STAGE2_DELAY, buttTimer); + } + break; + case FAST_REPEATS: + break; + case STOP_TIMER: + default: + KillTimer(hWnd, (UINT_PTR)b); + b->timer_id = 0; + return; + break; + } + if (b->action) { + b->action(b->data); + } + return; +} static LRESULT buttPush( wControl_p b, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) @@ -240,7 +313,7 @@ static LRESULT buttPush( wControl_p b, HWND hWnd, UINT message, WPARAM wParam, L case WM_COMMAND: if (bb->action /*&& !bb->busy*/) { bb->action( bb->data ); - return 0L; + return (LRESULT)0; } break; @@ -249,10 +322,10 @@ static LRESULT buttPush( wControl_p b, HWND hWnd, UINT message, WPARAM wParam, L if (bb->type != B_BUTTON || (bb->option & BO_ICON) == 0) break; mi->CtlType = ODT_BUTTON; - mi->CtlID = wParam; + mi->CtlID = (UINT)wParam; mi->itemWidth = (UINT)ceil(bb->w*scaleIcon); mi->itemHeight = (UINT)ceil(bb->h*scaleIcon); - } return 0L; + } return (LRESULT)0; case WM_DRAWITEM: if (bb->type == B_BUTTON && (bb->option & BO_ICON) != 0) { @@ -261,10 +334,9 @@ static LRESULT buttPush( wControl_p b, HWND hWnd, UINT message, WPARAM wParam, L bb->selected = selected; InvalidateRgn( bb->hWnd, NULL, FALSE ); } - return TRUE; + return (LRESULT)TRUE; } break; - } return DefWindowProc( hWnd, message, wParam, lParam ); } @@ -279,15 +351,12 @@ static void buttDone( LRESULT CALLBACK pushButt( HWND hWnd, UINT message, - UINT wParam, - LONG lParam ) + WPARAM wParam, + LPARAM lParam ) { /* Catch <Return> and cause focus to leave control */ -#ifdef WIN32 - long inx = GetWindowLong( hWnd, GWL_ID ); -#else - short inx = GetWindowWord( hWnd, GWW_ID ); -#endif + + wIndex_t inx = (wIndex_t)GetWindowLongPtr( hWnd, GWL_ID ); wButton_p b = (wButton_p)mswMapIndex( inx ); PAINTSTRUCT ps; @@ -297,7 +366,7 @@ LRESULT CALLBACK pushButt( BeginPaint( hWnd, &ps ); buttDrawIcon( (wButton_p)b, ps.hdc ); EndPaint( hWnd, &ps ); - return 1L; + return (LRESULT)1; } break; case WM_CHAR: @@ -311,18 +380,29 @@ LRESULT CALLBACK pushButt( wParam, lParam ); /*SendMessage( ((wControl_p)(b->parent))->hWnd, WM_COMMAND, inx, MAKELONG( hWnd, EN_KILLFOCUS ) );*/ - return 0L; + return (LONG_PTR)0; } } break; case WM_KILLFOCUS: if ( b ) InvalidateRect( b->hWnd, NULL, TRUE ); - return 0L; + return (LRESULT)0; + break; + case WM_LBUTTONDOWN: + if (b->option&BO_REPEAT) { + SetTimer(hWnd, (UINT_PTR)b,REPEAT_STAGE0_DELAY,buttTimer); + b->timer_state = INITIAL_WAIT; + b->timer_id = (UINT_PTR)b; + } break; - case WM_LBUTTONUP: - /* don't know why but this solves a problem with color selection */ - Sleep( 0 ); + case WM_LBUTTONUP: + /* don't know why but this solves a problem with color selection */ + Sleep( 0 ); + if (b->timer_id) + KillTimer(hWnd, (UINT_PTR)b); + b->timer_id = 0; + b->timer_state = STOP_TIMER; break; } return CallWindowProc( oldButtProc, hWnd, message, wParam, lParam ); @@ -335,12 +415,12 @@ static callBacks_t buttonCallBacks = { wButton_p wButtonCreate( wWin_p parent, - POS_T x, - POS_T y, + wWinPix_t x, + wWinPix_t y, const char * helpStr, const char * labelStr, long option, - wPos_t width, + wWinPix_t width, wButtonCallBack_p action, void * data ) { @@ -366,11 +446,11 @@ wButton_p wButtonCreate( b->selected = 0; mswComputePos( (wControl_p)b, x, y ); if (b->option&BO_ICON) { - width = (wPos_t)ceil(bm->w*scaleIcon)+10; + width = (wWinPix_t)ceil(bm->w*scaleIcon)+10; h = (int)ceil(bm->h*scaleIcon)+10; b->icon = bm; } else { - width = (wPos_t)(width*mswScale); + width = (wWinPix_t)(width*mswScale); } style = ((b->option&BO_ICON)? BS_OWNERDRAW : BS_PUSHBUTTON) | WS_CHILD | WS_VISIBLE | @@ -379,7 +459,7 @@ wButton_p wButtonCreate( style |= BS_DEFPUSHBUTTON; b->hWnd = CreateWindow( "BUTTON", labelStr, style, b->x, b->y, /*CW_USEDEFAULT, CW_USEDEFAULT,*/ width, h, - ((wControl_p)parent)->hWnd, (HMENU)index, mswHInst, NULL ); + ((wControl_p)parent)->hWnd, (HMENU)(UINT_PTR)index, mswHInst, NULL ); if (b->hWnd == NULL) { mswFail("CreateWindow(BUTTON)"); return b; @@ -393,7 +473,10 @@ wButton_p wButtonCreate( mswCallBacks[B_BUTTON] = &buttonCallBacks; mswChainFocus( (wControl_p)b ); - oldButtProc = (WNDPROC) SetWindowLongPtr(b->hWnd, GWL_WNDPROC, (LONG_PTR)&pushButt); + oldButtProc = (WNDPROC)SetWindowLongPtr(b->hWnd, GWLP_WNDPROC, (LONG_PTR)&pushButt); +#ifdef _OLDCODE + oldButtProc = (WNDPROC)SetWindowLongPtr(b->hWnd, GWL_WNDPROC, (LONG_PTR)&pushButt); +#endif if (mswPalette) { hDc = GetDC( b->hWnd ); SelectPalette( hDc, mswPalette, 0 ); @@ -401,7 +484,7 @@ wButton_p wButtonCreate( ReleaseDC( b->hWnd, hDc ); } if ( !mswThickFont ) - SendMessage( b->hWnd, WM_SETFONT, (WPARAM)mswLabelFont, 0L ); + SendMessage( b->hWnd, WM_SETFONT, (WPARAM)mswLabelFont, (LPARAM)0 ); InvalidateRect(b->hWnd, &rect, TRUE); |