1. fixed (yet again) highlighting of buttons and checkboxes

2. wrote input handlers for the checkbox
3. fixed bug in wXMouseEvent generation in gtk/window.cpp
4. added focus rect drawing and check/radio geometry queries to wxRenderer


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8309 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-09-08 19:03:00 +00:00
parent f40a103306
commit 0399bce91f
19 changed files with 540 additions and 71 deletions

View File

@@ -111,6 +111,9 @@ protected:
virtual wxSize DoGetBestClientSize() const;
virtual void DoDraw(wxControlRenderer *renderer);
virtual wxString GetInputHandlerType() const;
virtual bool CanBeHighlighted() const { return TRUE; }
// common part of all ctors
void Init();

View File

@@ -24,6 +24,8 @@
#define wxACTION_CHECKBOX_CLEAR _T("clear") // SetValue(FALSE)
#define wxACTION_CHECKBOX_TOGGLE _T("toggle") // toggle the check state
// additionally it accepts wxACTION_BUTTON_PRESS and RELEASE
// ----------------------------------------------------------------------------
// wxCheckBox
// ----------------------------------------------------------------------------
@@ -79,14 +81,32 @@ public:
virtual void SetValue(bool value);
virtual bool GetValue() const;
// set/get the margin between the checkbox bitmap and the label
void SetMargin(wxCoord margin) { m_checkMargin = margin; }
wxCoord GetMargin() const { return m_checkMargin; }
// set/get the margins between the checkbox bitmap and the border and
// between the bitmap and the label and above it
void SetMargins(wxCoord marginLeft, wxCoord marginRight, wxCoord marginTop)
{
m_checkMarginLeft = marginLeft;
m_checkMarginRight = marginRight;
m_checkMarginTop = marginTop;
}
wxCoord GetLeftMargin() const { return m_checkMarginLeft; }
wxCoord GetRightMargin() const { return m_checkMarginRight; }
wxCoord GetTopMargin() const { return m_checkMarginTop; }
// set/get the bitmaps to use for the checkbox indicator
void SetBitmap(const wxBitmap& bmp, State state, Status status);
wxBitmap GetBitmap(State state, Status status) const;
// wxCheckBox actions
void Toggle();
virtual void Press();
virtual void Release();
virtual void Click();
virtual void ChangeValue(bool value);
// overridden base class virtuals
virtual bool IsPressed() const { return m_isPressed; }
protected:
virtual bool PerformAction(const wxControlAction& action,
long numArg = -1,
@@ -94,9 +114,15 @@ protected:
virtual void DoDraw(wxControlRenderer *renderer);
virtual wxSize DoGetBestClientSize() const;
virtual wxString GetInputHandlerType() const;
virtual bool CanBeHighlighted() const { return TRUE; }
// common part of all ctors
void Init();
// set the margins to the default values if they were not set yet
void SetMargins();
private:
// the current check status
Status m_status;
@@ -104,8 +130,13 @@ private:
// the bitmaps to use for the different states
wxBitmap m_bitmaps[State_Max][Status_Max];
// the distance between the checkbox and the label (-1 means default)
wxCoord m_checkMargin;
// the distance between the checkbox and the label/border (-1 means default)
wxCoord m_checkMarginLeft,
m_checkMarginRight,
m_checkMarginTop;
// is the checkbox currently pressed?
bool m_isPressed;
DECLARE_DYNAMIC_CLASS(wxCheckBox)
};

View File

@@ -90,9 +90,8 @@ public:
const wxString& strArg = wxEmptyString);
protected:
// create the event translator object for this control: the base class
// action creates the default one which doesn't do anything
virtual wxInputHandler *CreateInputHandler() const;
// get the type of event translator object for this control
virtual wxString GetInputHandlerType() const;
// event handlers
void OnMouse(wxMouseEvent& event);

View File

@@ -25,6 +25,18 @@ class WXDLLEXPORT wxListBox;
class WXDLLEXPORT wxRenderer;
class WXDLLEXPORT wxScrollBar;
// ----------------------------------------------------------------------------
// types of the standard input handlers which can be passed to
// wxTheme::GetInputHandler()
// ----------------------------------------------------------------------------
#define wxINP_HANDLER_DEFAULT _T("")
#define wxINP_HANDLER_BUTTON _T("button")
#define wxINP_HANDLER_CHECKBOX _T("checkbox")
#define wxINP_HANDLER_RADIOBTN _T("radiobtn")
#define wxINP_HANDLER_SCROLLBAR _T("scrollbar")
#define wxINP_HANDLER_LISTBOX _T("listbox")
// ----------------------------------------------------------------------------
// wxInputHandler: maps the events to the actions
// ----------------------------------------------------------------------------
@@ -232,4 +244,21 @@ protected:
bool m_toggleOnPressAlways;
};
// ----------------------------------------------------------------------------
// wxStdCheckboxInputHandler: handles the mouse events for the check and radio
// boxes (handling the keyboard input is simple, but its handling differs a
// lot between GTK and MSW, so a new class should be derived for this)
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxStdCheckboxInputHandler : public wxStdButtonInputHandler
{
public:
wxStdCheckboxInputHandler(wxInputHandler *inphand);
virtual bool HandleMouse(wxControl *control,
const wxMouseEvent& event);
virtual bool HandleMouseMove(wxControl *control,
const wxMouseEvent& event);
};
#endif // _WX_UNIV_INPHAND_H_

View File

@@ -168,6 +168,8 @@ protected:
virtual void DoDraw(wxControlRenderer *renderer);
virtual wxBorder GetDefaultBorder() const;
virtual wxString GetInputHandlerType() const;
// common part of all ctors
void Init();

View File

@@ -104,6 +104,9 @@ public:
int flags = 0,
wxRect *rectIn = (wxRect *)NULL) = 0;
// draw a check/radio focus border
virtual void DrawCheckBoxFocusBorder(wxDC& dc, wxRect *rect) = 0;
// draw push button border and return the rectangle left for the label
virtual void DrawButtonBorder(wxDC& dc,
const wxRect& rect,
@@ -194,6 +197,16 @@ public:
// get the height of a listbox item from the base font height
virtual wxCoord GetListboxItemHeight(wxCoord fontHeight) = 0;
// get the standard size of the checkbox bitmap and the margins around it
virtual wxSize GetCheckBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const = 0;
// get the standard size of the radio btn bitmap and the margins around it
virtual wxSize GetRadioBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const = 0;
// virtual dtor for any base class
virtual ~wxRenderer();
@@ -279,6 +292,8 @@ public:
virtual void DrawVerticalLine(wxDC& dc,
wxCoord x, wxCoord y1, wxCoord y2)
{ m_renderer->DrawVerticalLine(dc, x, y1, y2); }
virtual void DrawCheckBoxFocusBorder(wxDC& dc, wxRect *rect)
{ m_renderer->DrawCheckBoxFocusBorder(dc, rect); }
virtual void DrawButtonBorder(wxDC& dc,
const wxRect& rect,
int flags = 0,
@@ -332,6 +347,18 @@ public:
{ return m_renderer->PixelToScrollbar(scrollbar, coord); }
virtual wxCoord GetListboxItemHeight(wxCoord fontHeight)
{ return m_renderer->GetListboxItemHeight(fontHeight); }
virtual wxSize GetCheckBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const
{ return m_renderer->GetCheckBitmapSize(marginLeft,
marginRight,
marginTop); }
virtual wxSize GetRadioBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const
{ return m_renderer->GetRadioBitmapSize(marginLeft,
marginRight,
marginTop); }
protected:
wxRenderer *m_renderer;
@@ -365,7 +392,10 @@ public:
wxStretch stretch = wxSTRETCH_NOT);
void DrawBackgroundBitmap();
void DrawScrollbar(const wxScrollBar *scrollbar, int thumbPosOld);
void DrawLabelBox(const wxBitmap& bitmap, wxCoord margin);
void DrawLabelBox(const wxBitmap& bitmap,
wxCoord marginLeft,
wxCoord marginRight,
wxCoord marginTop);
// accessors
wxWindow *GetWindow() const { return m_window; }

View File

@@ -110,7 +110,9 @@ protected:
virtual void DoDraw(wxControlRenderer *renderer);
virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; }
// event handler
virtual wxString GetInputHandlerType() const;
// event handlers
void OnIdle(wxIdleEvent& event);
// SetThumbPosition() helper

View File

@@ -23,8 +23,8 @@
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxRenderer;
class WXDLLEXPORT wxInputHandler;
class WXDLLEXPORT wxColourScheme;
class WXDLLEXPORT wxInputHandler;
struct WXDLLEXPORT wxThemeInfo;
class WXDLLEXPORT wxTheme
@@ -52,8 +52,8 @@ public:
// this theme
virtual wxRenderer *GetRenderer() = 0;
// get the input handler for the control with this name
virtual wxInputHandler *GetInputHandler(const wxString& control) = 0;
// get the input handler of the given type
virtual wxInputHandler *GetInputHandler(const wxString& handlerType) = 0;
// get the colour scheme for the control with this name
virtual wxColourScheme *GetColourScheme() = 0;

View File

@@ -108,6 +108,7 @@ public:
protected:
// event handlers
void OnButton(wxCommandEvent& event);
void OnCheckBox(wxCommandEvent& event);
void OnListBox(wxCommandEvent& event);
void OnLeftUp(wxMouseEvent& event);
@@ -148,6 +149,7 @@ WX_USE_THEME(gtk);
BEGIN_EVENT_TABLE(MyUnivFrame, wxFrame)
EVT_BUTTON(-1, MyUnivFrame::OnButton)
EVT_CHECKBOX(-1, MyUnivFrame::OnCheckBox)
EVT_LISTBOX(-1, MyUnivFrame::OnListBox)
EVT_LEFT_UP(MyUnivFrame::OnLeftUp)
@@ -353,6 +355,12 @@ void MyUnivFrame::OnButton(wxCommandEvent& event)
}
}
void MyUnivFrame::OnCheckBox(wxCommandEvent& event)
{
wxLogDebug(_T("Checkbox became %schecked."),
event.IsChecked() ? _T("") : _T("un"));
}
void MyUnivFrame::OnListBox(wxCommandEvent& event)
{
wxLogDebug(_T("Listbox item %d selected."), event.GetInt());

View File

@@ -348,6 +348,8 @@ static wxWindowGTK *FindFocusedChild(wxWindowGTK *win)
static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
{
// wxUniversal widgets draw the borders and scrollbars themselves
#ifndef __WXUNIVERSAL__
if (!win->m_hasVMT)
return;
@@ -385,8 +387,6 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
}
}
// wxUniversal widgets draw the borders themselves
#ifndef __WXUNIVERSAL__
int dx = 0;
int dy = 0;
if (GTK_WIDGET_NO_WINDOW (widget))
@@ -1452,6 +1452,7 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget,
wxMouseEvent event(g_captureWindowHasMouse ? wxEVT_ENTER_WINDOW
: wxEVT_LEAVE_WINDOW);
InitMouseEvent(event, gdk_event);
event.SetEventObject(win);
win->GetEventHandler()->ProcessEvent(event);
}
}

View File

@@ -348,6 +348,8 @@ static wxWindowGTK *FindFocusedChild(wxWindowGTK *win)
static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
{
// wxUniversal widgets draw the borders and scrollbars themselves
#ifndef __WXUNIVERSAL__
if (!win->m_hasVMT)
return;
@@ -385,8 +387,6 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
}
}
// wxUniversal widgets draw the borders themselves
#ifndef __WXUNIVERSAL__
int dx = 0;
int dy = 0;
if (GTK_WIDGET_NO_WINDOW (widget))
@@ -1452,6 +1452,7 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget,
wxMouseEvent event(g_captureWindowHasMouse ? wxEVT_ENTER_WINDOW
: wxEVT_LEAVE_WINDOW);
InitMouseEvent(event, gdk_event);
event.SetEventObject(win);
win->GetEventHandler()->ProcessEvent(event);
}
}

View File

@@ -130,6 +130,11 @@ void wxButton::DoDraw(wxControlRenderer *renderer)
// input processing
// ----------------------------------------------------------------------------
wxString wxButton::GetInputHandlerType() const
{
return wxINP_HANDLER_BUTTON;
}
void wxButton::Press()
{
if ( !m_isPressed )
@@ -296,6 +301,7 @@ bool wxStdButtonInputHandler::HandleMouseMove(wxControl *control,
m_winHasMouse = FALSE;
// we do have a pressed button, so release it
control->SetCurrent(FALSE);
control->PerformAction(wxACTION_BUTTON_RELEASE);
return TRUE;
@@ -309,6 +315,7 @@ bool wxStdButtonInputHandler::HandleMouseMove(wxControl *control,
// we did have a pressed button which we released when leaving the
// window, press it again
control->SetCurrent(TRUE);
control->PerformAction(wxACTION_BUTTON_PRESS);
return TRUE;

View File

@@ -33,10 +33,13 @@
#include "wx/dcclient.h"
#include "wx/checkbox.h"
#include "wx/validate.h"
#include "wx/button.h" // for wxACTION_BUTTON_XXX
#endif
#include "wx/univ/theme.h"
#include "wx/univ/renderer.h"
#include "wx/univ/inphand.h"
#include "wx/univ/colschem.h"
// ============================================================================
@@ -51,7 +54,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl)
void wxCheckBox::Init()
{
m_checkMargin = -1;
m_checkMarginLeft =
m_checkMarginRight =
m_checkMarginTop = -1;
m_isPressed = FALSE;
m_status = Status_Unchecked;
}
@@ -125,16 +131,36 @@ void wxCheckBox::DoDraw(wxControlRenderer *renderer)
else
state = State_Normal;
renderer->DrawLabelBox(GetBitmap(state, m_status), m_checkMargin);
SetMargins();
renderer->DrawLabelBox(GetBitmap(state, m_status),
m_checkMarginLeft,
m_checkMarginRight,
m_checkMarginTop);
}
// ----------------------------------------------------------------------------
// geometry calculations
// ----------------------------------------------------------------------------
void wxCheckBox::SetMargins()
{
wxCoord *left = m_checkMarginLeft == -1 ? &m_checkMarginLeft : NULL,
*right = m_checkMarginRight == -1 ? &m_checkMarginRight : NULL,
*top = m_checkMarginTop == -1 ? &m_checkMarginTop : NULL;
if ( left || right || top )
{
GetRenderer()->GetCheckBitmapSize(left, right, top);
}
}
wxSize wxCheckBox::DoGetBestClientSize() const
{
wxClientDC dc(wxConstCast(this, wxCheckBox));
wxCheckBox *self = wxConstCast(this, wxCheckBox);
self->SetMargins();
wxClientDC dc(self);
wxCoord width, height;
dc.GetMultiLineTextExtent(GetLabel(), &width, &height);
@@ -143,25 +169,82 @@ wxSize wxCheckBox::DoGetBestClientSize() const
height = bmp.GetHeight();
height += GetCharHeight();
width += bmp.GetWidth() + 2*GetCharWidth();
width += bmp.GetWidth()
+ m_checkMarginLeft + m_checkMarginRight
+ GetCharWidth();
return wxSize(width, height);
}
// ----------------------------------------------------------------------------
// checkbox actions
// ----------------------------------------------------------------------------
void wxCheckBox::Press()
{
if ( !m_isPressed )
{
m_isPressed = TRUE;
Refresh();
}
}
void wxCheckBox::Release()
{
if ( m_isPressed )
{
m_isPressed = FALSE;
Refresh();
}
}
void wxCheckBox::Toggle()
{
ChangeValue(!GetValue());
m_isPressed = FALSE;
}
void wxCheckBox::ChangeValue(bool value)
{
SetValue(value);
Click();
}
void wxCheckBox::Click()
{
wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, GetId());
InitCommandEvent(event);
event.SetInt(IsChecked());
Command(event);
}
// ----------------------------------------------------------------------------
// input handling
// ----------------------------------------------------------------------------
wxString wxCheckBox::GetInputHandlerType() const
{
return wxINP_HANDLER_CHECKBOX;
}
bool wxCheckBox::PerformAction(const wxControlAction& action,
long numArg,
const wxString& strArg)
{
if ( action == wxACTION_BUTTON_PRESS )
Press();
else if ( action == wxACTION_BUTTON_RELEASE )
Release();
if ( action == wxACTION_CHECKBOX_CHECK )
SetValue(TRUE);
ChangeValue(TRUE);
else if ( action == wxACTION_CHECKBOX_CLEAR )
SetValue(FALSE);
ChangeValue(FALSE);
else if ( action == wxACTION_CHECKBOX_TOGGLE )
SetValue(!GetValue());
Toggle();
else
return wxControl::PerformAction(action, numArg, strArg);
@@ -170,3 +253,27 @@ bool wxCheckBox::PerformAction(const wxControlAction& action,
#endif // wxUSE_CHECKBOX
#if wxUSE_CHECKBOX || wxUSE_RADIOBTN
// ----------------------------------------------------------------------------
// wxStdCheckboxInputHandler
// ----------------------------------------------------------------------------
wxStdCheckboxInputHandler::wxStdCheckboxInputHandler(wxInputHandler *inphand)
: wxStdButtonInputHandler(inphand)
{
}
bool wxStdCheckboxInputHandler::HandleMouse(wxControl *control,
const wxMouseEvent& event)
{
return wxStdButtonInputHandler::HandleMouse(control, event);
}
bool wxStdCheckboxInputHandler::HandleMouseMove(wxControl *control,
const wxMouseEvent& event)
{
return wxStdButtonInputHandler::HandleMouseMove(control, event);
}
#endif // wxUSE_RADIOBTN || wxUSE_CHECKBOX

View File

@@ -77,7 +77,7 @@ bool wxControl::Create(wxWindow *parent,
if ( !wxControlBase::Create(parent, id, pos, size, style, validator, name) )
return FALSE;
m_handler = CreateInputHandler();
m_handler = wxTheme::Get()->GetInputHandler(GetInputHandlerType());
return TRUE;
}
@@ -143,9 +143,9 @@ void wxControl::OnFocus(wxFocusEvent& event)
// input processing
// ----------------------------------------------------------------------------
wxInputHandler *wxControl::CreateInputHandler() const
wxString wxControl::GetInputHandlerType() const
{
return wxTheme::Get()->GetInputHandler(GetClassInfo()->GetClassName());
return wxINP_HANDLER_DEFAULT;
}
void wxControl::OnKeyDown(wxKeyEvent& event)

View File

@@ -870,6 +870,15 @@ void wxListBox::Activate(int item)
}
}
// ----------------------------------------------------------------------------
// input handling
// ----------------------------------------------------------------------------
wxString wxListBox::GetInputHandlerType() const
{
return wxINP_HANDLER_LISTBOX;
}
bool wxListBox::PerformAction(const wxControlAction& action,
long numArg,
const wxString& strArg)

View File

@@ -458,7 +458,7 @@ void wxControlRenderer::DrawBitmap(const wxBitmap& bitmap,
}
else if ( alignment & wxALIGN_CENTRE )
{
x = (rect.GetLeft() + rect.GetRight() - width) / 2;
x = (rect.GetLeft() + rect.GetRight() - width + 1) / 2;
}
else // alignment & wxALIGN_LEFT
{
@@ -471,7 +471,7 @@ void wxControlRenderer::DrawBitmap(const wxBitmap& bitmap,
}
else if ( alignment & wxALIGN_CENTRE_VERTICAL )
{
y = (rect.GetTop() + rect.GetBottom() - height) / 2;
y = (rect.GetTop() + rect.GetBottom() - height + 1) / 2;
}
else // alignment & wxALIGN_TOP
{
@@ -635,19 +635,26 @@ void wxControlRenderer::DrawItems(const wxListBox *lbox,
}
}
void wxControlRenderer::DrawLabelBox(const wxBitmap& bitmap, wxCoord margin)
void wxControlRenderer::DrawLabelBox(const wxBitmap& bitmap,
wxCoord marginLeft,
wxCoord marginRight,
wxCoord marginTop)
{
m_dc.SetFont(m_window->GetFont());
m_dc.SetTextForeground(m_window->GetForegroundColour());
if ( margin == -1 )
margin = 4;
// draw the focus border around everything
int flags = m_window->GetStateFlags();
if ( flags & wxCONTROL_FOCUSED )
{
m_renderer->DrawCheckBoxFocusBorder(m_dc, &m_rect);
}
// calculate the position of the bitmap and of the label
wxRect rectBmp;
rectBmp.width = bitmap.GetWidth();
rectBmp.height = bitmap.GetHeight();
rectBmp.y = m_rect.y + (m_rect.height - rectBmp.height + 1) / 2;
wxCoord xBmp,
yBmp = m_rect.y
+ (m_rect.height - bitmap.GetHeight() + 1) / 2
+ marginTop;
wxRect rectLabel;
wxString label = m_window->GetLabel();
@@ -656,25 +663,25 @@ void wxControlRenderer::DrawLabelBox(const wxBitmap& bitmap, wxCoord margin)
if ( m_window->GetWindowStyle() & wxALIGN_RIGHT )
{
rectBmp.x = m_rect.GetRight() - rectBmp.width;
xBmp = m_rect.GetRight() - bitmap.GetWidth() - marginLeft;
rectLabel.SetLeft(m_rect.GetLeft());
rectLabel.SetRight(rectBmp.GetLeft() - margin);
rectLabel.SetRight(xBmp - marginRight);
}
else // normal (checkbox to the left of the text) case
{
rectBmp.x = m_rect.GetLeft();
rectLabel.SetLeft(rectBmp.GetRight() + margin);
xBmp = m_rect.GetLeft() + marginLeft;
rectLabel.SetLeft(xBmp + bitmap.GetWidth() + marginRight);
rectLabel.SetRight(m_rect.GetRight());
}
DrawBitmap(bitmap, rectBmp);
m_dc.DrawBitmap(bitmap, xBmp, yBmp, TRUE /* use mask */);
wxControl *ctrl = wxStaticCast(m_window, wxControl);
m_renderer->DrawLabel(m_dc,
label,
rectLabel,
m_window->GetStateFlags(),
flags,
wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL,
ctrl->GetAccelIndex());
}

View File

@@ -309,6 +309,11 @@ void wxScrollBar::SetState(Element which, int flags)
// input processing
// ----------------------------------------------------------------------------
wxString wxScrollBar::GetInputHandlerType() const
{
return wxINP_HANDLER_SCROLLBAR;
}
bool wxScrollBar::PerformAction(const wxControlAction& action,
long numArg,
const wxString& strArg)

View File

@@ -31,6 +31,7 @@
#include "wx/window.h"
#include "wx/button.h"
#include "wx/checkbox.h"
#include "wx/scrolbar.h"
#endif // WX_PRECOMP
@@ -86,6 +87,7 @@ public:
int flags = 0,
int alignment = wxALIGN_LEFT,
int indexAccel = -1);
virtual void DrawCheckBoxFocusBorder(wxDC& dc, wxRect *rect);
virtual void DrawButtonBorder(wxDC& dc,
const wxRect& rect,
int flags = 0,
@@ -126,9 +128,16 @@ public:
virtual wxCoord GetListboxItemHeight(wxCoord fontHeight)
{ return fontHeight + 2; }
virtual wxSize GetCheckBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const;
virtual wxSize GetRadioBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const;
// helpers for "wxBitmap wxColourScheme::Get()"
void DrawCheckBitmap(wxDC& dc, const wxRect& rect);
void DrawUncheckBitmap(wxDC& dc, const wxRect& rect);
void DrawUncheckBitmap(wxDC& dc, const wxRect& rect, bool isPressed);
protected:
// DrawBackground() helpers
@@ -276,6 +285,17 @@ protected:
}
};
class wxGTKCheckboxInputHandler : public wxStdCheckboxInputHandler
{
public:
wxGTKCheckboxInputHandler(wxInputHandler *handler)
: wxStdCheckboxInputHandler(handler) { }
virtual bool HandleKey(wxControl *control,
const wxKeyEvent& event,
bool pressed);
};
// ----------------------------------------------------------------------------
// wxGTKColourScheme: uses the standard GTK colours
// ----------------------------------------------------------------------------
@@ -290,9 +310,10 @@ public:
#endif // wxUSE_CHECKBOX
private:
// the checkbox bitmaps
wxBitmap m_bmpCheck,
m_bmpUncheck;
// the checkbox bitmaps: first row is for the normal, second for the
// pressed state and the columns are for checked and unchecked status
// respectively
wxBitmap m_bitmapsCheckbox[2][2];
};
// ----------------------------------------------------------------------------
@@ -312,6 +333,9 @@ public:
virtual wxColourScheme *GetColourScheme() { return m_scheme; }
private:
// get the default input handler
wxInputHandler *GetDefaultInputHandler();
wxGTKRenderer *m_renderer;
// the names of the already created handlers and the handlers themselves
@@ -319,6 +343,8 @@ private:
wxSortedArrayString m_handlerNames;
wxArrayHandlers m_handlers;
wxGTKInputHandler *m_handlerDefault;
wxGTKColourScheme *m_scheme;
WX_DECLARE_THEME(gtk)
@@ -338,6 +364,7 @@ wxGTKTheme::wxGTKTheme()
{
m_scheme = new wxGTKColourScheme;
m_renderer = new wxGTKRenderer(m_scheme);
m_handlerDefault = NULL;
}
wxGTKTheme::~wxGTKTheme()
@@ -345,6 +372,16 @@ wxGTKTheme::~wxGTKTheme()
WX_CLEAR_ARRAY(m_handlers);
}
wxInputHandler *wxGTKTheme::GetDefaultInputHandler()
{
if ( !m_handlerDefault )
{
m_handlerDefault = new wxGTKInputHandler(m_renderer);
}
return m_handlerDefault;
}
wxInputHandler *wxGTKTheme::GetInputHandler(const wxString& control)
{
wxInputHandler *handler;
@@ -352,15 +389,17 @@ wxInputHandler *wxGTKTheme::GetInputHandler(const wxString& control)
if ( n == wxNOT_FOUND )
{
// create a new handler
if ( control.Matches(_T("wx*Button")) )
handler = new wxStdButtonInputHandler(GetInputHandler(_T("wxControl")));
else if ( control == _T("wxScrollBar") )
if ( control == wxINP_HANDLER_BUTTON )
handler = new wxStdButtonInputHandler(GetDefaultInputHandler());
else if ( control == wxINP_HANDLER_SCROLLBAR )
handler = new wxGTKScrollBarInputHandler(m_renderer,
GetInputHandler(_T("wxControl")));
else if ( control == _T("wxListBox") )
handler = new wxStdListboxInputHandler(GetInputHandler(_T("wxControl")), FALSE);
GetDefaultInputHandler());
else if ( control == wxINP_HANDLER_CHECKBOX )
handler = new wxGTKCheckboxInputHandler(GetDefaultInputHandler());
else if ( control == wxINP_HANDLER_LISTBOX )
handler = new wxStdListboxInputHandler(GetDefaultInputHandler());
else
handler = new wxGTKInputHandler(m_renderer);
handler = GetDefaultInputHandler();
n = m_handlerNames.Add(control);
m_handlers.Insert(handler, n);
@@ -455,26 +494,42 @@ wxColour wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col) const
wxBitmap wxGTKColourScheme::Get(wxCheckBox::State state,
wxCheckBox::Status status)
{
if ( !m_bmpCheck.Ok() )
if ( !m_bitmapsCheckbox[0][0].Ok() )
{
// init the bitmaps once only
wxRect rect;
rect.width =
rect.height = 10;
m_bmpCheck.Create(rect.width, rect.height);
m_bmpUncheck.Create(rect.width, rect.height);
for ( int i = 0; i < 2; i++ )
{
for ( int j = 0; j < 2; j++ )
m_bitmapsCheckbox[i][j].Create(rect.width, rect.height);
}
wxGTKRenderer *renderer = (wxGTKRenderer *)wxTheme::Get()->GetRenderer();
wxMemoryDC dc;
dc.SelectObject(m_bmpCheck);
// normal checked
dc.SelectObject(m_bitmapsCheckbox[0][0]);
renderer->DrawCheckBitmap(dc, rect);
dc.SelectObject(m_bmpUncheck);
renderer->DrawUncheckBitmap(dc, rect);
// normal unchecked
dc.SelectObject(m_bitmapsCheckbox[0][1]);
renderer->DrawUncheckBitmap(dc, rect, FALSE);
// pressed checked
m_bitmapsCheckbox[1][0] = m_bitmapsCheckbox[0][0];
// pressed unchecked
dc.SelectObject(m_bitmapsCheckbox[1][1]);
renderer->DrawUncheckBitmap(dc, rect, TRUE);
}
return status == wxCheckBox::Status_Checked ? m_bmpCheck : m_bmpUncheck;
int row = state == wxCheckBox::State_Pressed ? 1 : 0;
int col = status == wxCheckBox::Status_Checked ? 0 : 1;
return m_bitmapsCheckbox[row][col];
}
#endif // wxUSE_CHECKBOX
@@ -700,9 +755,14 @@ bool wxGTKRenderer::AreScrollbarsInsideBorder() const
}
// ----------------------------------------------------------------------------
// button border
// borders
// ----------------------------------------------------------------------------
void wxGTKRenderer::DrawCheckBoxFocusBorder(wxDC& dc, wxRect *rect)
{
DrawRect(dc, rect, m_penBlack);
}
void wxGTKRenderer::DrawButtonBorder(wxDC& dc,
const wxRect& rectTotal,
int flags,
@@ -1288,6 +1348,38 @@ int wxGTKRenderer::PixelToScrollbar(const wxScrollBar *scrollbar,
GetScrollbarArrowSize(scrollbar));
}
// ----------------------------------------------------------------------------
// check/radio bitmaps geometry
// ----------------------------------------------------------------------------
wxSize wxGTKRenderer::GetCheckBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const
{
if ( marginLeft )
*marginLeft = 2;
if ( marginRight )
*marginRight = 5;
if ( marginTop )
*marginTop = 1;
return wxSize(10, 10);
}
wxSize wxGTKRenderer::GetRadioBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const
{
if ( marginLeft )
*marginLeft = 1;
if ( marginRight )
*marginRight = 4;
if ( marginTop )
*marginTop = 1;
return wxSize(11, 11);
}
// ----------------------------------------------------------------------------
// size adjustments
// ----------------------------------------------------------------------------
@@ -1327,7 +1419,9 @@ void wxGTKRenderer::AdjustSize(wxSize *size, const wxWindow *window)
// checkbox buttons
// ----------------------------------------------------------------------------
void wxGTKRenderer::DrawUncheckBitmap(wxDC& dc, const wxRect& rectTotal)
void wxGTKRenderer::DrawUncheckBitmap(wxDC& dc,
const wxRect& rectTotal,
bool isPressed)
{
wxRect rect = rectTotal;
DrawShadedRect(dc, &rect, m_penHighlight, m_penBlack);
@@ -1335,7 +1429,11 @@ void wxGTKRenderer::DrawUncheckBitmap(wxDC& dc, const wxRect& rectTotal)
wxColour col = wxSCHEME_COLOUR(m_scheme, SHADOW_IN);
dc.SetPen(wxPen(col, 0, wxSOLID));
dc.DrawPoint(rect.GetRight(), rect.GetBottom());
dc.DrawPoint(rect.GetRight() - 1, rect.GetBottom() - 1);
if ( isPressed )
col = wxSCHEME_COLOUR(m_scheme, CONTROL_PRESSED);
//else: it is SHADOW_IN, leave as is
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxBrush(col, wxSOLID));
@@ -1412,3 +1510,24 @@ bool wxGTKInputHandler::HandleMouseMove(wxControl *control,
return TRUE;
}
// ----------------------------------------------------------------------------
// wxGTKCheckboxInputHandler
// ----------------------------------------------------------------------------
bool wxGTKCheckboxInputHandler::HandleKey(wxControl *control,
const wxKeyEvent& event,
bool pressed)
{
if ( pressed )
{
int keycode = event.GetKeyCode();
if ( keycode == WXK_SPACE || keycode == WXK_RETURN )
{
control->PerformAction(wxACTION_CHECKBOX_TOGGLE);
return TRUE;
}
}
return FALSE;
}

View File

@@ -104,6 +104,7 @@ public:
int flags = 0,
int alignment = wxALIGN_LEFT,
int indexAccel = -1);
virtual void DrawCheckBoxFocusBorder(wxDC& dc, wxRect *rect);
virtual void DrawButtonBorder(wxDC& dc,
const wxRect& rect,
int flags = 0,
@@ -143,6 +144,13 @@ public:
virtual wxCoord GetListboxItemHeight(wxCoord fontHeight)
{ return fontHeight; }
virtual wxSize GetCheckBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const;
virtual wxSize GetRadioBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const;
protected:
// common part of DrawLabel() and DrawItem()
void DrawFocusRect(wxDC& dc, const wxRect& rect);
@@ -258,6 +266,17 @@ protected:
int m_interval;
};
class wxWin32CheckboxInputHandler : public wxStdCheckboxInputHandler
{
public:
wxWin32CheckboxInputHandler(wxInputHandler *handler)
: wxStdCheckboxInputHandler(handler) { }
virtual bool HandleKey(wxControl *control,
const wxKeyEvent& event,
bool pressed);
};
// ----------------------------------------------------------------------------
// wxWin32ColourScheme: uses (default) Win32 colours
// ----------------------------------------------------------------------------
@@ -289,6 +308,9 @@ public:
virtual wxColourScheme *GetColourScheme();
private:
// get the default input handler
wxInputHandler *GetDefaultInputHandler();
wxWin32Renderer *m_renderer;
// the names of the already created handlers and the handlers themselves
@@ -296,6 +318,8 @@ private:
wxSortedArrayString m_handlerNames;
wxArrayHandlers m_handlers;
wxWin32InputHandler *m_handlerDefault;
wxWin32ColourScheme *m_scheme;
WX_DECLARE_THEME(win32)
@@ -315,6 +339,7 @@ wxWin32Theme::wxWin32Theme()
{
m_scheme = new wxWin32ColourScheme;
m_renderer = new wxWin32Renderer(m_scheme);
m_handlerDefault = NULL;
}
wxWin32Theme::~wxWin32Theme()
@@ -325,6 +350,16 @@ wxWin32Theme::~wxWin32Theme()
delete m_scheme;
}
wxInputHandler *wxWin32Theme::GetDefaultInputHandler()
{
if ( !m_handlerDefault )
{
m_handlerDefault = new wxWin32InputHandler(m_renderer);
}
return m_handlerDefault;
}
wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
{
wxInputHandler *handler;
@@ -332,15 +367,17 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
if ( n == wxNOT_FOUND )
{
// create a new handler
if ( control.Matches(_T("wx*Button")) )
handler = new wxStdButtonInputHandler(GetInputHandler(_T("wxControl")));
else if ( control == _T("wxScrollBar") )
if ( control == wxINP_HANDLER_BUTTON )
handler = new wxStdButtonInputHandler(GetDefaultInputHandler());
else if ( control == wxINP_HANDLER_SCROLLBAR )
handler = new wxWin32ScrollBarInputHandler(m_renderer,
GetInputHandler(_T("wxControl")));
else if ( control == _T("wxListBox") )
handler = new wxStdListboxInputHandler(GetInputHandler(_T("wxControl")));
GetDefaultInputHandler());
else if ( control == wxINP_HANDLER_CHECKBOX )
handler = new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
else if ( control == wxINP_HANDLER_LISTBOX )
handler = new wxStdListboxInputHandler(GetDefaultInputHandler());
else
handler = new wxWin32InputHandler(m_renderer);
handler = GetDefaultInputHandler();
n = m_handlerNames.Add(control);
m_handlers.Insert(handler, n);
@@ -843,9 +880,14 @@ bool wxWin32Renderer::AreScrollbarsInsideBorder() const
}
// ----------------------------------------------------------------------------
// button border
// borders
// ----------------------------------------------------------------------------
void wxWin32Renderer::DrawCheckBoxFocusBorder(wxDC& dc, wxRect *rect)
{
// we don't have it
}
void wxWin32Renderer::DrawButtonBorder(wxDC& dc,
const wxRect& rectTotal,
int flags,
@@ -1268,6 +1310,34 @@ int wxWin32Renderer::PixelToScrollbar(const wxScrollBar *scrollbar,
return StandardPixelToScrollbar(scrollbar, coord, m_sizeScrollbarArrow);
}
// ----------------------------------------------------------------------------
// check/radio bitmaps geometry
// ----------------------------------------------------------------------------
wxSize wxWin32Renderer::GetCheckBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const
{
if ( marginLeft )
*marginLeft = 2;
if ( marginRight )
*marginRight = 5;
return wxSize(10, 10);
}
wxSize wxWin32Renderer::GetRadioBitmapSize(wxCoord *marginLeft,
wxCoord *marginRight,
wxCoord *marginTop) const
{
if ( marginLeft )
*marginLeft = 1;
if ( marginRight )
*marginRight = 4;
return wxSize(11, 11);
}
// ----------------------------------------------------------------------------
// size adjustments
// ----------------------------------------------------------------------------
@@ -1492,3 +1562,42 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxControl *control,
return wxStdScrollBarInputHandler::HandleMouseMove(control, event);
}
// ----------------------------------------------------------------------------
// wxWin32CheckboxInputHandler
// ----------------------------------------------------------------------------
bool wxWin32CheckboxInputHandler::HandleKey(wxControl *control,
const wxKeyEvent& event,
bool pressed)
{
if ( pressed )
{
wxControlAction action;
int keycode = event.GetKeyCode();
switch ( keycode )
{
case WXK_SPACE:
action = wxACTION_CHECKBOX_TOGGLE;
break;
case '-':
action = wxACTION_CHECKBOX_CHECK;
break;
case '+':
case '=':
action = wxACTION_CHECKBOX_CLEAR;
break;
}
if ( !!action )
{
control->PerformAction(wxACTION_CHECKBOX_TOGGLE);
return TRUE;
}
}
return FALSE;
}