comctl32/button: Use get_draw_state() helper.

Use a helper so that the get draw state routine can be shared
by later code.

Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2018-09-05 22:57:18 +08:00 committed by Alexandre Julliard
parent 396ebaa588
commit fa4183ef84
1 changed files with 71 additions and 47 deletions

View File

@ -128,15 +128,16 @@ static const WORD maxCheckState[MAX_BTN_TYPE] =
BST_UNCHECKED /* BS_DEFCOMMANDLINK */ BST_UNCHECKED /* BS_DEFCOMMANDLINK */
}; };
/* These are indices into a states array to determine the theme state for a given theme part. */ /* Generic draw states, use get_draw_state() to get specific state for button type */
typedef enum enum draw_state
{ {
STATE_NORMAL, STATE_NORMAL,
STATE_DISABLED, STATE_DISABLED,
STATE_HOT, STATE_HOT,
STATE_PRESSED, STATE_PRESSED,
STATE_DEFAULTED STATE_DEFAULTED,
} ButtonState; DRAW_STATE_COUNT
};
typedef void (*pfPaint)( const BUTTON_INFO *infoPtr, HDC hdc, UINT action ); typedef void (*pfPaint)( const BUTTON_INFO *infoPtr, HDC hdc, UINT action );
@ -160,11 +161,11 @@ static const pfPaint btnPaintFunc[MAX_BTN_TYPE] =
PB_Paint /* BS_DEFCOMMANDLINK */ PB_Paint /* BS_DEFCOMMANDLINK */
}; };
typedef void (*pfThemedPaint)( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); typedef void (*pfThemedPaint)( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, int drawState, UINT dtflags, BOOL focused);
static void PB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); static void PB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, int drawState, UINT dtflags, BOOL focused);
static void CB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); static void CB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, int drawState, UINT dtflags, BOOL focused);
static void GB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); static void GB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, int drawState, UINT dtflags, BOOL focused);
static const pfThemedPaint btnThemedPaintFunc[MAX_BTN_TYPE] = static const pfThemedPaint btnThemedPaintFunc[MAX_BTN_TYPE] =
{ {
@ -286,6 +287,63 @@ static UINT BUTTON_BStoDT( DWORD style, DWORD ex_style )
return dtStyle; return dtStyle;
} }
static int get_draw_state(const BUTTON_INFO *infoPtr)
{
static const int pb_states[DRAW_STATE_COUNT] = { PBS_NORMAL, PBS_DISABLED, PBS_HOT, PBS_PRESSED, PBS_DEFAULTED };
static const int cb_states[3][DRAW_STATE_COUNT] =
{
{ CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDNORMAL },
{ CBS_CHECKEDNORMAL, CBS_CHECKEDDISABLED, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDNORMAL },
{ CBS_MIXEDNORMAL, CBS_MIXEDDISABLED, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDNORMAL }
};
static const int rb_states[2][DRAW_STATE_COUNT] =
{
{ RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDNORMAL },
{ RBS_CHECKEDNORMAL, RBS_CHECKEDDISABLED, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDNORMAL }
};
static const int gb_states[DRAW_STATE_COUNT] = { GBS_NORMAL, GBS_DISABLED, GBS_NORMAL, GBS_NORMAL, GBS_NORMAL };
LONG style = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
UINT type = get_button_type(style);
int check_state = infoPtr->state & 3;
enum draw_state state;
if (!IsWindowEnabled(infoPtr->hwnd))
state = STATE_DISABLED;
else if (infoPtr->state & BST_PUSHED)
state = STATE_PRESSED;
else if (infoPtr->state & BST_HOT)
state = STATE_HOT;
else if (infoPtr->state & BST_FOCUS)
state = STATE_DEFAULTED;
else
state = STATE_NORMAL;
switch (type)
{
case BS_PUSHBUTTON:
case BS_DEFPUSHBUTTON:
case BS_USERBUTTON:
case BS_SPLITBUTTON:
case BS_DEFSPLITBUTTON:
case BS_COMMANDLINK:
case BS_DEFCOMMANDLINK:
return pb_states[state];
case BS_CHECKBOX:
case BS_AUTOCHECKBOX:
return cb_states[check_state][state];
case BS_RADIOBUTTON:
case BS_3STATE:
case BS_AUTO3STATE:
case BS_AUTORADIOBUTTON:
return rb_states[check_state][state];
case BS_GROUPBOX:
return gb_states[state];
default:
WARN("Unsupported button type 0x%08x\n", type);
return PBS_NORMAL;
}
}
static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
BUTTON_INFO *infoPtr = (BUTTON_INFO *)GetWindowLongPtrW(hWnd, 0); BUTTON_INFO *infoPtr = (BUTTON_INFO *)GetWindowLongPtrW(hWnd, 0);
@ -402,20 +460,9 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
if (theme && btnThemedPaintFunc[btn_type]) if (theme && btnThemedPaintFunc[btn_type])
{ {
ButtonState drawState; int drawState = get_draw_state(infoPtr);
UINT dtflags; UINT dtflags = BUTTON_BStoDT(style, GetWindowLongW(hWnd, GWL_EXSTYLE));
if (IsWindowEnabled( hWnd ))
{
if (infoPtr->state & BST_PUSHED) drawState = STATE_PRESSED;
else if (infoPtr->state & BST_HOT) drawState = STATE_HOT;
else if (infoPtr->state & BST_FOCUS) drawState = STATE_DEFAULTED;
else drawState = STATE_NORMAL;
}
else
drawState = STATE_DISABLED;
dtflags = BUTTON_BStoDT(style, GetWindowLongW(hWnd, GWL_EXSTYLE));
btnThemedPaintFunc[btn_type](theme, infoPtr, hdc, drawState, dtflags, infoPtr->state & BST_FOCUS); btnThemedPaintFunc[btn_type](theme, infoPtr, hdc, drawState, dtflags, infoPtr->state & BST_FOCUS);
} }
else if (btnPaintFunc[btn_type]) else if (btnPaintFunc[btn_type])
@ -1352,14 +1399,11 @@ static void OB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
if (hrgn) DeleteObject( hrgn ); if (hrgn) DeleteObject( hrgn );
} }
static void PB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) static void PB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, int state, UINT dtFlags, BOOL focused)
{ {
static const int states[] = { PBS_NORMAL, PBS_DISABLED, PBS_HOT, PBS_PRESSED, PBS_DEFAULTED };
RECT bgRect, textRect; RECT bgRect, textRect;
HFONT font = infoPtr->font; HFONT font = infoPtr->font;
HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL; HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL;
int state = states[ drawState ];
WCHAR *text = get_button_text(infoPtr); WCHAR *text = get_button_text(infoPtr);
GetClientRect(infoPtr->hwnd, &bgRect); GetClientRect(infoPtr->hwnd, &bgRect);
@ -1392,31 +1436,14 @@ static void PB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, Bu
if (hPrevFont) SelectObject(hDC, hPrevFont); if (hPrevFont) SelectObject(hDC, hPrevFont);
} }
static void CB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) static void CB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, int state, UINT dtFlags, BOOL focused)
{ {
static const int cb_states[3][5] =
{
{ CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDNORMAL },
{ CBS_CHECKEDNORMAL, CBS_CHECKEDDISABLED, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDNORMAL },
{ CBS_MIXEDNORMAL, CBS_MIXEDDISABLED, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDNORMAL }
};
static const int rb_states[2][5] =
{
{ RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDNORMAL },
{ RBS_CHECKEDNORMAL, RBS_CHECKEDDISABLED, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDNORMAL }
};
SIZE sz; SIZE sz;
RECT bgRect, textRect; RECT bgRect, textRect;
HFONT font, hPrevFont = NULL; HFONT font, hPrevFont = NULL;
int checkState = infoPtr->state & 3;
DWORD dwStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE); DWORD dwStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
UINT btn_type = get_button_type( dwStyle ); UINT btn_type = get_button_type( dwStyle );
int part = (btn_type == BS_RADIOBUTTON) || (btn_type == BS_AUTORADIOBUTTON) ? BP_RADIOBUTTON : BP_CHECKBOX; int part = (btn_type == BS_RADIOBUTTON) || (btn_type == BS_AUTORADIOBUTTON) ? BP_RADIOBUTTON : BP_CHECKBOX;
int state = (part == BP_CHECKBOX)
? cb_states[ checkState ][ drawState ]
: rb_states[ checkState ][ drawState ];
WCHAR *text = get_button_text(infoPtr); WCHAR *text = get_button_text(infoPtr);
LOGFONTW lf; LOGFONTW lf;
BOOL created_font = FALSE; BOOL created_font = FALSE;
@ -1478,12 +1505,9 @@ static void CB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, Bu
if (hPrevFont) SelectObject(hDC, hPrevFont); if (hPrevFont) SelectObject(hDC, hPrevFont);
} }
static void GB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) static void GB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, int state, UINT dtFlags, BOOL focused)
{ {
static const int states[] = { GBS_NORMAL, GBS_DISABLED, GBS_NORMAL, GBS_NORMAL, GBS_NORMAL };
RECT bgRect, textRect, contentRect; RECT bgRect, textRect, contentRect;
int state = states[ drawState ];
WCHAR *text = get_button_text(infoPtr); WCHAR *text = get_button_text(infoPtr);
LOGFONTW lf; LOGFONTW lf;
HFONT font, hPrevFont = NULL; HFONT font, hPrevFont = NULL;