Implement setting foreground colour for wxRadioButton in wxMSW.
Native radio buttons don't support changing their foreground colour, so use owner drawn buttons if SetForegroundColour() was called, similarly to what was already done for wxCheckBox. Closes #10137. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76456 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -62,6 +62,7 @@ wxMSW:
|
||||
- Fix loading of bitmap with non-pre-multiplied alpha (Artur Wieczorek).
|
||||
- Support multiline strings in wxDC::DrawRotatedText() (Artur Wieczorek).
|
||||
- Fix stretchable spacers in vertical toolbars (Artur Wieczorek).
|
||||
- Implement setting foreground colour for wxRadioButton (Artur Wieczorek).
|
||||
- Add font colour support to wxFontPickerCtrl (Pana Alexandru).
|
||||
- Add wxEnhMetaFile::Detach() (Luca Bacci).
|
||||
- Add support for saving 256*256 32bpp ICOs in PNG format (Artur Wieczorek).
|
||||
|
@@ -47,18 +47,37 @@ public:
|
||||
// implementation only from now on
|
||||
virtual bool MSWCommand(WXUINT param, WXWORD id);
|
||||
virtual void Command(wxCommandEvent& event);
|
||||
virtual bool SetForegroundColour(const wxColour& colour);
|
||||
virtual bool MSWOnDraw(WXDRAWITEMSTRUCT *item);
|
||||
|
||||
virtual bool HasTransparentBackground() { return true; }
|
||||
|
||||
// make the radiobutton owner drawn or reset it to normal style
|
||||
void MSWMakeOwnerDrawn(bool ownerDrawn);
|
||||
|
||||
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
|
||||
|
||||
protected:
|
||||
virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; }
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
virtual void MSWDrawButtonBitmap(wxWindow *win, wxDC& dc,
|
||||
const wxRect& rect, int flags);
|
||||
|
||||
// return true if this checkbox is owner drawn
|
||||
bool IsOwnerDrawn() const;
|
||||
|
||||
private:
|
||||
// common part of all ctors
|
||||
void Init();
|
||||
|
||||
// event handlers used by owner-drawn radiobutton
|
||||
void OnMouseEnterOrLeave(wxMouseEvent& event);
|
||||
void OnMouseLeft(wxMouseEvent& event);
|
||||
void OnFocus(wxFocusEvent& event);
|
||||
|
||||
// true if the radio button is currently pressed
|
||||
bool m_isPressed;
|
||||
|
||||
// we need to store the state internally as the result of GetValue()
|
||||
// sometimes gets out of sync in WM_COMMAND handler
|
||||
bool m_isChecked;
|
||||
|
@@ -34,6 +34,8 @@
|
||||
#endif
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/renderer.h"
|
||||
#include "wx/msw/uxtheme.h"
|
||||
|
||||
// ============================================================================
|
||||
// wxRadioButton implementation
|
||||
@@ -46,6 +48,7 @@
|
||||
void wxRadioButton::Init()
|
||||
{
|
||||
m_isChecked = false;
|
||||
m_isPressed = false;
|
||||
}
|
||||
|
||||
bool wxRadioButton::Create(wxWindow *parent,
|
||||
@@ -82,11 +85,14 @@ bool wxRadioButton::Create(wxWindow *parent,
|
||||
|
||||
void wxRadioButton::SetValue(bool value)
|
||||
{
|
||||
::SendMessage(GetHwnd(), BM_SETCHECK,
|
||||
value ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
m_isChecked = value;
|
||||
|
||||
if ( !IsOwnerDrawn() )
|
||||
::SendMessage(GetHwnd(), BM_SETCHECK,
|
||||
value ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
else // owner drawn buttons don't react to this message
|
||||
Refresh();
|
||||
|
||||
if ( !value )
|
||||
return;
|
||||
|
||||
@@ -296,4 +302,126 @@ WXDWORD wxRadioButton::MSWGetStyle(long style, WXDWORD *exstyle) const
|
||||
return msStyle;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// owner drawn radio button stuff
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxRadioButton::SetForegroundColour(const wxColour& colour)
|
||||
{
|
||||
if ( !wxControl::SetForegroundColour(colour) )
|
||||
return false;
|
||||
|
||||
// the only way to change the radiobox foreground colour if themes are enablad
|
||||
// is to owner draw it
|
||||
if ( wxUxThemeEngine::GetIfActive() )
|
||||
MSWMakeOwnerDrawn(colour.IsOk());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxRadioButton::IsOwnerDrawn() const
|
||||
{
|
||||
return
|
||||
(::GetWindowLong(GetHwnd(), GWL_STYLE) & BS_OWNERDRAW) == BS_OWNERDRAW;
|
||||
}
|
||||
|
||||
void wxRadioButton::MSWMakeOwnerDrawn(bool ownerDrawn)
|
||||
{
|
||||
long style = ::GetWindowLong(GetHwnd(), GWL_STYLE);
|
||||
|
||||
// note that BS_RADIOBUTTON & BS_OWNERDRAW != 0 so we can't operate on
|
||||
// them as on independent style bits
|
||||
|
||||
if ( ownerDrawn )
|
||||
{
|
||||
style &= ~BS_RADIOBUTTON;
|
||||
style |= BS_OWNERDRAW;
|
||||
|
||||
Connect(wxEVT_ENTER_WINDOW,
|
||||
wxMouseEventHandler(wxRadioButton::OnMouseEnterOrLeave));
|
||||
Connect(wxEVT_LEAVE_WINDOW,
|
||||
wxMouseEventHandler(wxRadioButton::OnMouseEnterOrLeave));
|
||||
Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(wxRadioButton::OnMouseLeft));
|
||||
Connect(wxEVT_LEFT_UP, wxMouseEventHandler(wxRadioButton::OnMouseLeft));
|
||||
Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(wxRadioButton::OnFocus));
|
||||
Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(wxRadioButton::OnFocus));
|
||||
}
|
||||
else // reset to default colour
|
||||
{
|
||||
style &= ~BS_OWNERDRAW;
|
||||
style |= BS_RADIOBUTTON;
|
||||
|
||||
Disconnect(wxEVT_ENTER_WINDOW,
|
||||
wxMouseEventHandler(wxRadioButton::OnMouseEnterOrLeave));
|
||||
Disconnect(wxEVT_LEAVE_WINDOW,
|
||||
wxMouseEventHandler(wxRadioButton::OnMouseEnterOrLeave));
|
||||
Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(wxRadioButton::OnMouseLeft));
|
||||
Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(wxRadioButton::OnMouseLeft));
|
||||
Disconnect(wxEVT_SET_FOCUS, wxFocusEventHandler(wxRadioButton::OnFocus));
|
||||
Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(wxRadioButton::OnFocus));
|
||||
}
|
||||
|
||||
::SetWindowLong(GetHwnd(), GWL_STYLE, style);
|
||||
}
|
||||
|
||||
void wxRadioButton::OnMouseEnterOrLeave(wxMouseEvent& event)
|
||||
{
|
||||
const bool isHot = event.GetEventType() == wxEVT_ENTER_WINDOW;
|
||||
if ( !isHot )
|
||||
m_isPressed = false;
|
||||
|
||||
Refresh();
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void wxRadioButton::OnMouseLeft(wxMouseEvent& event)
|
||||
{
|
||||
// TODO: we should capture the mouse here to be notified about left up
|
||||
// event but this interferes with BN_CLICKED generation so if we
|
||||
// want to do this we'd need to generate them ourselves
|
||||
m_isPressed = event.GetEventType() == wxEVT_LEFT_DOWN;
|
||||
Refresh();
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void wxRadioButton::OnFocus(wxFocusEvent& event)
|
||||
{
|
||||
Refresh();
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
bool wxRadioButton::MSWOnDraw(WXDRAWITEMSTRUCT *item)
|
||||
{
|
||||
DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item;
|
||||
|
||||
if ( !IsOwnerDrawn() || dis->CtlType != ODT_BUTTON )
|
||||
return wxControl::MSWOnDraw(item);
|
||||
|
||||
// shall we draw a focus rect?
|
||||
const bool isFocused = m_isPressed || FindFocus() == this;
|
||||
|
||||
int flags = 0;
|
||||
if ( !IsEnabled() )
|
||||
flags |= wxCONTROL_DISABLED;
|
||||
|
||||
if ( m_isChecked )
|
||||
flags |= wxCONTROL_CHECKED;
|
||||
|
||||
if ( m_isPressed )
|
||||
flags |= wxCONTROL_PRESSED;
|
||||
|
||||
if ( wxFindWindowAtPoint(wxGetMousePosition()) == this )
|
||||
flags |= wxCONTROL_CURRENT;
|
||||
|
||||
return MSWOwnerDrawnButton(dis, flags, isFocused);
|
||||
}
|
||||
|
||||
void wxRadioButton::MSWDrawButtonBitmap(wxWindow *win, wxDC& dc, const wxRect& rect, int flags)
|
||||
{
|
||||
wxRendererNative::Get().DrawRadioBitmap(win, dc, rect, flags);
|
||||
}
|
||||
|
||||
#endif // wxUSE_RADIOBTN
|
||||
|
Reference in New Issue
Block a user