From 8f2ea39e1d950d33b36e84a02ea6c4de2b4b36c8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 19 Aug 2000 19:26:27 +0000 Subject: [PATCH] 1. wxInputHandler::Map() can return a sequence of actions, not only one 2. wxControl::PerformAction() takes a wxEvent parameter 3. wxGTK fix: send enter/leave events even when the mouse is captured 4. renamed "highlighted" state to "current" git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8140 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/univ/button.h | 3 +- include/wx/univ/control.h | 41 +++++++++++++++--- include/wx/univ/inphand.h | 12 +++--- include/wx/univ/renderer.h | 6 +-- samples/univ/univ.cpp | 27 +++++++++++- src/gtk/window.cpp | 76 +++++++++++++++++++++------------ src/gtk1/window.cpp | 76 +++++++++++++++++++++------------ src/univ/button.cpp | 5 ++- src/univ/control.cpp | 63 ++++++++++++++++++--------- src/univ/renderer.cpp | 4 +- src/univ/themes/gtk.cpp | 87 +++++++++++++++++++++++++++++++------- src/univ/themes/win32.cpp | 18 ++++---- 12 files changed, 300 insertions(+), 118 deletions(-) diff --git a/include/wx/univ/button.h b/include/wx/univ/button.h index 10605c5c8e..b51db4b7fd 100644 --- a/include/wx/univ/button.h +++ b/include/wx/univ/button.h @@ -73,7 +73,8 @@ public: protected: virtual wxInputHandler *CreateInputHandler() const; - virtual bool PerformAction(const wxControlAction& action); + virtual bool PerformAction(const wxControlAction& action, + const wxEvent& event); virtual wxSize DoGetBestSize() const; virtual void DoDraw(wxControlRenderer *renderer); diff --git a/include/wx/univ/control.h b/include/wx/univ/control.h index d9cbd101e2..31f1e2eeb0 100644 --- a/include/wx/univ/control.h +++ b/include/wx/univ/control.h @@ -21,10 +21,32 @@ class WXDLLEXPORT wxInputHandler; // ---------------------------------------------------------------------------- // wxControlAction: the action is currently just a string which identifies it, -// later it might become an atom (i.e. an opaque handler to string) +// later it might become an atom (i.e. an opaque handler to string). As one +// input event may result in several control actions (e.g. a macro expansion +// in the text control) we define an array of actions as well. // ---------------------------------------------------------------------------- typedef wxString wxControlAction; +class WXDLLEXPORT wxControlActions : public wxArrayString +{ +public: + wxControlActions() { } + wxControlActions(const wxControlAction& action) + { wxArrayString::Add(action); } + wxControlActions(const wxChar *action) + { wxArrayString::Add(action); } + + wxControlActions& Add(const wxControlActions& other) + { + size_t count = other.GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + wxArrayString::Add(other[n]); + } + + return *this; + } +}; // the list of actions which apply to all controls (other actions are defined // in the controls headers) @@ -68,12 +90,12 @@ public: // get the state information virtual bool IsFocused() const; - virtual bool IsHighlighted() const; + virtual bool IsCurrent() const; virtual bool IsPressed() const; virtual bool IsDefault() const; // operations - void Highlight(bool doit = TRUE); + void SetCurrent(bool doit = TRUE); // implementation only from now on @@ -94,19 +116,26 @@ protected: // draw the controls contents virtual void DoDraw(wxControlRenderer *renderer); - // perform the action, return TRUE if the control must be updated - virtual bool PerformAction(const wxControlAction& action); + // perform the action which resulted from the translation of the event + // (the exact event type depends on the action), return TRUE if the + // control must be updated + virtual bool PerformAction(const wxControlAction& action, + const wxEvent& event); // event handlers void OnMouse(wxMouseEvent& event); void OnKeyDown(wxKeyEvent& event); void OnKeyUp(wxKeyEvent& event); + void OnFocus(wxFocusEvent& event); void OnPaint(wxPaintEvent& event); private: // common part of all ctors void Init(); + // common part of OnMouse/OnKeyDown/Up + void PerformActions(const wxControlActions& actions, const wxEvent& event); + // input processor wxInputHandler *m_handler; @@ -115,7 +144,7 @@ private: int m_indexAccel; // state - bool m_isHighlighted; + bool m_isCurrent; DECLARE_DYNAMIC_CLASS(wxControl) DECLARE_EVENT_TABLE() diff --git a/include/wx/univ/inphand.h b/include/wx/univ/inphand.h index 64fbdca5c3..c3ef5e68f2 100644 --- a/include/wx/univ/inphand.h +++ b/include/wx/univ/inphand.h @@ -17,7 +17,7 @@ #pragma interface "inphand.h" #endif -#include "wx/control.h" // for wxControlAction +#include "wx/control.h" // for wxControlAction(s) // ---------------------------------------------------------------------------- // wxInputHandler: maps the events to the actions @@ -26,12 +26,12 @@ class WXDLLEXPORT wxInputHandler { public: - // map a keyboard event to an action (pressed == TRUE if the key was - // pressed, FALSE if released) - virtual wxControlAction Map(const wxKeyEvent& event, bool pressed) = 0; + // map a keyboard event to one or more actions (pressed == TRUE if the key + // was pressed, FALSE if released) + virtual wxControlActions Map(const wxKeyEvent& event, bool pressed) = 0; - // map a mouse event to an action - virtual wxControlAction Map(const wxMouseEvent& event) = 0; + // map a mouse event to one or more actions + virtual wxControlActions Map(const wxMouseEvent& event) = 0; // virtual dtor for any base class virtual ~wxInputHandler(); diff --git a/include/wx/univ/renderer.h b/include/wx/univ/renderer.h index 3f854377e1..7037afef63 100644 --- a/include/wx/univ/renderer.h +++ b/include/wx/univ/renderer.h @@ -37,10 +37,10 @@ class WXDLLEXPORT wxWindow; enum { wxRENDER_ENABLED = 0x00000001, - wxRENDER_FOCUSED = 0x00000002, + wxRENDER_FOCUSED = 0x00000002, // control currently has keyboard focus wxRENDER_PRESSED = 0x00000004, - wxRENDER_DEFAULT = 0x00000008, // button... - wxRENDER_HIGHLIGHT = 0x00000010, + wxRENDER_DEFAULT = 0x00000008, // only applies to the buttons + wxRENDER_CURRENT = 0x00000010, // mouse is currently over the control wxRENDER_FLAGS_MASK = 0x0000001f }; diff --git a/samples/univ/univ.cpp b/samples/univ/univ.cpp index d103d00759..3b3202c251 100644 --- a/samples/univ/univ.cpp +++ b/samples/univ/univ.cpp @@ -39,6 +39,21 @@ #include "wx/stattext.h" #endif +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + +// control ids +enum +{ + Univ_Button1, + Univ_Button2 +}; + +// ---------------------------------------------------------------------------- +// our classes +// ---------------------------------------------------------------------------- + // Define a new application type, each program should derive a class from wxApp class MyUnivApp : public wxApp { @@ -61,6 +76,7 @@ public: protected: // event handlers + void OnButton(wxCommandEvent& event); void OnLeftUp(wxMouseEvent& event); private: @@ -75,6 +91,8 @@ private: IMPLEMENT_APP(MyUnivApp) BEGIN_EVENT_TABLE(MyUnivFrame, wxFrame) + EVT_BUTTON(-1, MyUnivFrame::OnButton) + EVT_LEFT_UP(MyUnivFrame::OnLeftUp) END_EVENT_TABLE() @@ -152,7 +170,14 @@ MyUnivFrame::MyUnivFrame(const wxString& title) #undef CREATE_STATIC_ALIGN_DEMO - new wxButton(this, -1, _T("&Press me"), wxPoint(10, 300)); + new wxButton(this, Univ_Button1, _T("&Press me"), wxPoint(10, 300)); + new wxButton(this, Univ_Button2, _T("&And me"), wxPoint(100, 300)); +} + +void MyUnivFrame::OnButton(wxCommandEvent& event) +{ + wxLogDebug(_T("Button %d pressed."), + event.GetId() == Univ_Button1 ? 1 : 2); } void MyUnivFrame::OnLeftUp(wxMouseEvent& event) diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 72f6fe5b54..3f5e8f73b6 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -195,7 +195,11 @@ extern wxList wxPendingDelete; extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnScroll; extern wxCursor g_globalCursor; + +// mouse capture state: the window which has it and if the mouse is currently +// inside it static wxWindow *g_captureWindow = (wxWindow*) NULL; +static bool g_captureWindowHasMouse = FALSE; /* extern */ wxWindow *g_focusWindow = (wxWindow*) NULL; @@ -1366,11 +1370,31 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto return FALSE; } +// ============================================================================ +// the mouse events +// ============================================================================ + +// init wxMouseEvent with the info from gdk_event +#define InitMouseEvent(event, gdk_event) \ + event.SetTimestamp( gdk_event->time ); \ + event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK); \ + event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK); \ + event.m_altDown = (gdk_event->state & GDK_MOD1_MASK); \ + event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK); \ + event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK); \ + event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK); \ + event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK); \ +\ + event.m_x = (wxCoord)gdk_event->x; \ + event.m_y = (wxCoord)gdk_event->y \ + //----------------------------------------------------------------------------- // "motion_notify_event" //----------------------------------------------------------------------------- -static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win ) +static gint gtk_window_motion_notify_callback( GtkWidget *widget, + GdkEventMotion *gdk_event, + wxWindow *win ) { DEBUG_MAIN_THREAD @@ -1401,23 +1425,31 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion */ wxMouseEvent event( wxEVT_MOTION ); - event.SetTimestamp( gdk_event->time ); - event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK); - event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK); - event.m_altDown = (gdk_event->state & GDK_MOD1_MASK); - event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK); - event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK); - event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK); - event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK); + InitMouseEvent(event, gdk_event); - event.m_x = (wxCoord)gdk_event->x; - event.m_y = (wxCoord)gdk_event->y; - - // Some control don't have their own X window and thus cannot get - // any events. - - if (!g_captureWindow) + if ( g_captureWindow ) { + // synthetize a mouse enter or leave event if needed + GdkWindow *winUnderMouse = gdk_window_at_pointer(NULL, NULL); + bool hasMouse = winUnderMouse == gdk_event->window; + if ( hasMouse != g_captureWindowHasMouse ) + { + // the mouse changed window + g_captureWindowHasMouse = hasMouse; + + printf("Generating mouse %s event.\n", + g_captureWindowHasMouse ? "enter" : "leave"); + wxMouseEvent event(g_captureWindowHasMouse ? wxEVT_ENTER_WINDOW + : wxEVT_LEAVE_WINDOW); + InitMouseEvent(event, gdk_event); + win->GetEventHandler()->ProcessEvent(event); + } + } + else // no capture + { + // Some control don't have their own X window and thus cannot get + // any events. + wxCoord x = event.m_x; wxCoord y = event.m_y; if (win->m_wxwindow) @@ -1646,16 +1678,7 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_ gdk_window_get_pointer( widget->window, &x, &y, &state ); - event.m_shiftDown = (state & GDK_SHIFT_MASK); - event.m_controlDown = (state & GDK_CONTROL_MASK); - event.m_altDown = (state & GDK_MOD1_MASK); - event.m_metaDown = (state & GDK_MOD2_MASK); - event.m_leftDown = (state & GDK_BUTTON1_MASK); - event.m_middleDown = (state & GDK_BUTTON2_MASK); - event.m_rightDown = (state & GDK_BUTTON3_MASK); - - event.m_x = x; - event.m_y = y; + InitMouseEvent(event, gdk_event); if (win->GetEventHandler()->ProcessEvent( event )) { @@ -3528,6 +3551,7 @@ void wxWindow::CaptureMouse() cursor->GetCursor(), (guint32)GDK_CURRENT_TIME ); g_captureWindow = this; + g_captureWindowHasMouse = TRUE; } void wxWindow::ReleaseMouse() diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 72f6fe5b54..3f5e8f73b6 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -195,7 +195,11 @@ extern wxList wxPendingDelete; extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnScroll; extern wxCursor g_globalCursor; + +// mouse capture state: the window which has it and if the mouse is currently +// inside it static wxWindow *g_captureWindow = (wxWindow*) NULL; +static bool g_captureWindowHasMouse = FALSE; /* extern */ wxWindow *g_focusWindow = (wxWindow*) NULL; @@ -1366,11 +1370,31 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto return FALSE; } +// ============================================================================ +// the mouse events +// ============================================================================ + +// init wxMouseEvent with the info from gdk_event +#define InitMouseEvent(event, gdk_event) \ + event.SetTimestamp( gdk_event->time ); \ + event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK); \ + event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK); \ + event.m_altDown = (gdk_event->state & GDK_MOD1_MASK); \ + event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK); \ + event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK); \ + event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK); \ + event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK); \ +\ + event.m_x = (wxCoord)gdk_event->x; \ + event.m_y = (wxCoord)gdk_event->y \ + //----------------------------------------------------------------------------- // "motion_notify_event" //----------------------------------------------------------------------------- -static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win ) +static gint gtk_window_motion_notify_callback( GtkWidget *widget, + GdkEventMotion *gdk_event, + wxWindow *win ) { DEBUG_MAIN_THREAD @@ -1401,23 +1425,31 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion */ wxMouseEvent event( wxEVT_MOTION ); - event.SetTimestamp( gdk_event->time ); - event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK); - event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK); - event.m_altDown = (gdk_event->state & GDK_MOD1_MASK); - event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK); - event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK); - event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK); - event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK); + InitMouseEvent(event, gdk_event); - event.m_x = (wxCoord)gdk_event->x; - event.m_y = (wxCoord)gdk_event->y; - - // Some control don't have their own X window and thus cannot get - // any events. - - if (!g_captureWindow) + if ( g_captureWindow ) { + // synthetize a mouse enter or leave event if needed + GdkWindow *winUnderMouse = gdk_window_at_pointer(NULL, NULL); + bool hasMouse = winUnderMouse == gdk_event->window; + if ( hasMouse != g_captureWindowHasMouse ) + { + // the mouse changed window + g_captureWindowHasMouse = hasMouse; + + printf("Generating mouse %s event.\n", + g_captureWindowHasMouse ? "enter" : "leave"); + wxMouseEvent event(g_captureWindowHasMouse ? wxEVT_ENTER_WINDOW + : wxEVT_LEAVE_WINDOW); + InitMouseEvent(event, gdk_event); + win->GetEventHandler()->ProcessEvent(event); + } + } + else // no capture + { + // Some control don't have their own X window and thus cannot get + // any events. + wxCoord x = event.m_x; wxCoord y = event.m_y; if (win->m_wxwindow) @@ -1646,16 +1678,7 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_ gdk_window_get_pointer( widget->window, &x, &y, &state ); - event.m_shiftDown = (state & GDK_SHIFT_MASK); - event.m_controlDown = (state & GDK_CONTROL_MASK); - event.m_altDown = (state & GDK_MOD1_MASK); - event.m_metaDown = (state & GDK_MOD2_MASK); - event.m_leftDown = (state & GDK_BUTTON1_MASK); - event.m_middleDown = (state & GDK_BUTTON2_MASK); - event.m_rightDown = (state & GDK_BUTTON3_MASK); - - event.m_x = x; - event.m_y = y; + InitMouseEvent(event, gdk_event); if (win->GetEventHandler()->ProcessEvent( event )) { @@ -3528,6 +3551,7 @@ void wxWindow::CaptureMouse() cursor->GetCursor(), (guint32)GDK_CURRENT_TIME ); g_captureWindow = this; + g_captureWindowHasMouse = TRUE; } void wxWindow::ReleaseMouse() diff --git a/src/univ/button.cpp b/src/univ/button.cpp index ba1edc49ea..3015bcf2b5 100644 --- a/src/univ/button.cpp +++ b/src/univ/button.cpp @@ -151,7 +151,8 @@ void wxButton::Click() Command(event); } -bool wxButton::PerformAction(const wxControlAction& action) +bool wxButton::PerformAction(const wxControlAction& action, + const wxEvent& event) { bool wasPressed = IsPressed(); @@ -164,7 +165,7 @@ bool wxButton::PerformAction(const wxControlAction& action) else if ( action == wxACTION_BUTTON_RELEASE ) Release(); else - return wxControl::PerformAction(action); + return wxControl::PerformAction(action, event); return wasPressed != IsPressed(); } diff --git a/src/univ/control.cpp b/src/univ/control.cpp index 435a68a705..75ac3c96a8 100644 --- a/src/univ/control.cpp +++ b/src/univ/control.cpp @@ -57,6 +57,9 @@ BEGIN_EVENT_TABLE(wxControl, wxControlBase) EVT_LEAVE_WINDOW(wxControl::OnMouse) EVT_ENTER_WINDOW(wxControl::OnMouse) + EVT_SET_FOCUS(wxControl::OnFocus) + EVT_KILL_FOCUS(wxControl::OnFocus) + EVT_PAINT(wxControl::OnPaint) END_EVENT_TABLE() @@ -67,7 +70,7 @@ END_EVENT_TABLE() void wxControl::Init() { m_indexAccel = -1; - m_isHighlighted = FALSE; + m_isCurrent = FALSE; } bool wxControl::Create(wxWindow *parent, @@ -108,14 +111,14 @@ bool wxControl::IsDefault() const return FALSE; } -bool wxControl::IsHighlighted() const +bool wxControl::IsCurrent() const { - return m_isHighlighted; + return m_isCurrent; } -void wxControl::Highlight(bool doit) +void wxControl::SetCurrent(bool doit) { - m_isHighlighted = doit; + m_isCurrent = doit; } // ---------------------------------------------------------------------------- @@ -185,6 +188,15 @@ void wxControl::DoDraw(wxControlRenderer *renderer) renderer->DrawBorder(); } +// ---------------------------------------------------------------------------- +// focus handling +// ---------------------------------------------------------------------------- + +void wxControl::OnFocus(wxFocusEvent& event) +{ + Refresh(); +} + // ---------------------------------------------------------------------------- // input processing // ---------------------------------------------------------------------------- @@ -196,37 +208,48 @@ wxInputHandler *wxControl::CreateInputHandler() const void wxControl::OnKeyDown(wxKeyEvent& event) { - if ( PerformAction(m_handler->Map(event, TRUE)) ) - { - Refresh(); - } + PerformActions(m_handler->Map(event, TRUE), event); } void wxControl::OnKeyUp(wxKeyEvent& event) { - if ( PerformAction(m_handler->Map(event, FALSE)) ) - { - Refresh(); - } + PerformActions(m_handler->Map(event, FALSE), event); } void wxControl::OnMouse(wxMouseEvent& event) { - if ( PerformAction(m_handler->Map(event)) ) - { - Refresh(); - } + PerformActions(m_handler->Map(event), event); } -bool wxControl::PerformAction(const wxControlAction& action) +// ---------------------------------------------------------------------------- +// the actions +// ---------------------------------------------------------------------------- + +void wxControl::PerformActions(const wxControlActions& actions, + const wxEvent& event) +{ + bool needsRefresh = FALSE; + size_t count = actions.GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + if ( PerformAction(actions[n], event) ) + needsRefresh = TRUE; + } + + if ( needsRefresh ) + Refresh(); +} + +bool wxControl::PerformAction(const wxControlAction& action, + const wxEvent& event) { if ( (action == wxACTION_NONE) || !AcceptsFocus() ) return FALSE; if ( action == wxACTION_HIGHLIGHT ) - Highlight(TRUE); + SetCurrent(TRUE); else if ( action == wxACTION_UNHIGHLIGHT ) - Highlight(FALSE); + SetCurrent(FALSE); else return FALSE; diff --git a/src/univ/renderer.cpp b/src/univ/renderer.cpp index 27c03968fc..16bd3e2db8 100644 --- a/src/univ/renderer.cpp +++ b/src/univ/renderer.cpp @@ -73,8 +73,8 @@ int wxControlRenderer::GetStateFlags() const // it is not, even our default/focused controls shouldn't appear as such if ( wxTheApp->IsActive() ) { - if ( m_ctrl->IsHighlighted() ) - flags |= wxRENDER_HIGHLIGHT; + if ( m_ctrl->IsCurrent() ) + flags |= wxRENDER_CURRENT; if ( m_ctrl->IsFocused() ) flags |= wxRENDER_FOCUSED; if ( m_ctrl->IsPressed() ) diff --git a/src/univ/themes/gtk.cpp b/src/univ/themes/gtk.cpp index c506a74538..412de963e2 100644 --- a/src/univ/themes/gtk.cpp +++ b/src/univ/themes/gtk.cpp @@ -112,8 +112,8 @@ private: class wxGTKInputHandler : public wxInputHandler { public: - virtual wxControlAction Map(const wxKeyEvent& event, bool pressed); - virtual wxControlAction Map(const wxMouseEvent& event); + virtual wxControlActions Map(const wxKeyEvent& event, bool pressed); + virtual wxControlActions Map(const wxMouseEvent& event); }; class wxGTKButtonInputHandler : public wxGTKInputHandler @@ -121,11 +121,12 @@ class wxGTKButtonInputHandler : public wxGTKInputHandler public: wxGTKButtonInputHandler(); - virtual wxControlAction Map(const wxKeyEvent& event, bool pressed); - virtual wxControlAction Map(const wxMouseEvent& event); + virtual wxControlActions Map(const wxKeyEvent& event, bool pressed); + virtual wxControlActions Map(const wxMouseEvent& event); private: wxWindow *m_winCapture; + bool m_winHasMouse; }; // ---------------------------------------------------------------------------- @@ -441,6 +442,11 @@ void wxGTKRenderer::DrawButtonBorder(wxDC& dc, // button not pressed if ( flags & wxRENDER_DEFAULT ) + { + // TODO + } + + if ( flags & wxRENDER_FOCUSED ) { // button is currently default: add an extra border around it DrawRect(dc, &rect, m_penBlack); @@ -449,8 +455,8 @@ void wxGTKRenderer::DrawButtonBorder(wxDC& dc, // now draw a normal button DrawShadedRect(dc, &rect, m_penHighlight, m_penBlack); DrawAntiShadedRect(dc, &rect, - flags & wxRENDER_HIGHLIGHT ? m_penHighlight - : m_penLightGrey, + flags & wxRENDER_CURRENT ? m_penHighlight + : m_penLightGrey, m_penDarkGrey); } @@ -551,7 +557,7 @@ void wxGTKRenderer::DrawBackground(wxDC& dc, { colBg = wxColour(0x7f7f7f); } - else if ( flags & wxRENDER_HIGHLIGHT ) + else if ( flags & wxRENDER_CURRENT ) { colBg = wxColour(0xe0e0e0); } @@ -620,12 +626,12 @@ void wxGTKRenderer::AdjustSize(wxSize *size, const wxWindow *window) // wxGTKInputHandler // ---------------------------------------------------------------------------- -wxControlAction wxGTKInputHandler::Map(const wxKeyEvent& event, bool pressed) +wxControlActions wxGTKInputHandler::Map(const wxKeyEvent& event, bool pressed) { return wxACTION_NONE; } -wxControlAction wxGTKInputHandler::Map(const wxMouseEvent& event) +wxControlActions wxGTKInputHandler::Map(const wxMouseEvent& event) { if ( event.Entering() ) return wxACTION_HIGHLIGHT; @@ -644,8 +650,8 @@ wxGTKButtonInputHandler::wxGTKButtonInputHandler() m_winCapture = NULL; } -wxControlAction wxGTKButtonInputHandler::Map(const wxKeyEvent& event, - bool pressed) +wxControlActions wxGTKButtonInputHandler::Map(const wxKeyEvent& event, + bool pressed) { int keycode = event.GetKeyCode(); if ( keycode == WXK_SPACE || keycode == WXK_RETURN ) @@ -656,18 +662,67 @@ wxControlAction wxGTKButtonInputHandler::Map(const wxKeyEvent& event, return wxGTKInputHandler::Map(event, pressed); } -wxControlAction wxGTKButtonInputHandler::Map(const wxMouseEvent& event) +wxControlActions wxGTKButtonInputHandler::Map(const wxMouseEvent& event) { if ( event.IsButton() ) { + if ( event.ButtonDown() ) + { + m_winCapture = wxWindow::FindFocus(); + m_winCapture->CaptureMouse(); + m_winHasMouse = TRUE; + } + else // up + { + m_winCapture->ReleaseMouse(); + m_winCapture = NULL; + + if ( !m_winHasMouse ) + { + // the mouse was released outside the window, this doesn't + // count as a click + return wxGTKInputHandler::Map(event); + } + } + return wxACTION_BUTTON_TOGGLE; } -#if 0 // TODO - else if ( event.Leaving() ) + + // leaving the button should remove its pressed state + if ( event.Leaving() ) { - return wxACTION_BUTTON_RELEASE; + wxControlActions actions; + if ( m_winCapture ) + { + // we do have a pressed button + actions.Add(wxACTION_BUTTON_RELEASE); + + // remember that the mouse is now outside + m_winHasMouse = FALSE; + } + + actions.Add(wxGTKInputHandler::Map(event)); + + return actions; + } + + // entering it back should make it pressed again if it had been pressed + if ( event.Entering() ) + { + wxControlActions actions; + if ( m_winCapture ) + { + // we do have a pressed button + actions.Add(wxACTION_BUTTON_PRESS); + + // and the mouse is (back) inside it + m_winHasMouse = TRUE; + } + + actions.Add(wxGTKInputHandler::Map(event)); + + return actions; } -#endif // 0 return wxGTKInputHandler::Map(event); } diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index 58866fe6dd..cb14b6e670 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -107,8 +107,8 @@ private: class wxWin32InputHandler : public wxInputHandler { public: - virtual wxControlAction Map(const wxKeyEvent& event, bool pressed); - virtual wxControlAction Map(const wxMouseEvent& event); + virtual wxControlActions Map(const wxKeyEvent& event, bool pressed); + virtual wxControlActions Map(const wxMouseEvent& event); }; class wxWin32ButtonInputHandler : public wxWin32InputHandler @@ -116,8 +116,8 @@ class wxWin32ButtonInputHandler : public wxWin32InputHandler public: wxWin32ButtonInputHandler(); - virtual wxControlAction Map(const wxKeyEvent& event, bool pressed); - virtual wxControlAction Map(const wxMouseEvent& event); + virtual wxControlActions Map(const wxKeyEvent& event, bool pressed); + virtual wxControlActions Map(const wxMouseEvent& event); private: wxWindow *m_winCapture; @@ -617,12 +617,12 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window) // wxWin32InputHandler // ---------------------------------------------------------------------------- -wxControlAction wxWin32InputHandler::Map(const wxKeyEvent& event, bool pressed) +wxControlActions wxWin32InputHandler::Map(const wxKeyEvent& event, bool pressed) { return wxACTION_NONE; } -wxControlAction wxWin32InputHandler::Map(const wxMouseEvent& event) +wxControlActions wxWin32InputHandler::Map(const wxMouseEvent& event) { return wxACTION_NONE; } @@ -636,8 +636,8 @@ wxWin32ButtonInputHandler::wxWin32ButtonInputHandler() m_winCapture = NULL; } -wxControlAction wxWin32ButtonInputHandler::Map(const wxKeyEvent& event, - bool pressed) +wxControlActions wxWin32ButtonInputHandler::Map(const wxKeyEvent& event, + bool pressed) { int keycode = event.GetKeyCode(); if ( keycode == WXK_SPACE || keycode == WXK_RETURN ) @@ -648,7 +648,7 @@ wxControlAction wxWin32ButtonInputHandler::Map(const wxKeyEvent& event, return wxWin32InputHandler::Map(event, pressed); } -wxControlAction wxWin32ButtonInputHandler::Map(const wxMouseEvent& event) +wxControlActions wxWin32ButtonInputHandler::Map(const wxMouseEvent& event) { if ( event.IsButton() ) {