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
This commit is contained in:
@@ -73,7 +73,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual wxInputHandler *CreateInputHandler() const;
|
virtual wxInputHandler *CreateInputHandler() const;
|
||||||
virtual bool PerformAction(const wxControlAction& action);
|
virtual bool PerformAction(const wxControlAction& action,
|
||||||
|
const wxEvent& event);
|
||||||
virtual wxSize DoGetBestSize() const;
|
virtual wxSize DoGetBestSize() const;
|
||||||
virtual void DoDraw(wxControlRenderer *renderer);
|
virtual void DoDraw(wxControlRenderer *renderer);
|
||||||
|
|
||||||
|
@@ -21,10 +21,32 @@ class WXDLLEXPORT wxInputHandler;
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxControlAction: the action is currently just a string which identifies it,
|
// 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;
|
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
|
// the list of actions which apply to all controls (other actions are defined
|
||||||
// in the controls headers)
|
// in the controls headers)
|
||||||
@@ -68,12 +90,12 @@ public:
|
|||||||
|
|
||||||
// get the state information
|
// get the state information
|
||||||
virtual bool IsFocused() const;
|
virtual bool IsFocused() const;
|
||||||
virtual bool IsHighlighted() const;
|
virtual bool IsCurrent() const;
|
||||||
virtual bool IsPressed() const;
|
virtual bool IsPressed() const;
|
||||||
virtual bool IsDefault() const;
|
virtual bool IsDefault() const;
|
||||||
|
|
||||||
// operations
|
// operations
|
||||||
void Highlight(bool doit = TRUE);
|
void SetCurrent(bool doit = TRUE);
|
||||||
|
|
||||||
// implementation only from now on
|
// implementation only from now on
|
||||||
|
|
||||||
@@ -94,19 +116,26 @@ protected:
|
|||||||
// draw the controls contents
|
// draw the controls contents
|
||||||
virtual void DoDraw(wxControlRenderer *renderer);
|
virtual void DoDraw(wxControlRenderer *renderer);
|
||||||
|
|
||||||
// perform the action, return TRUE if the control must be updated
|
// perform the action which resulted from the translation of the event
|
||||||
virtual bool PerformAction(const wxControlAction& action);
|
// (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
|
// event handlers
|
||||||
void OnMouse(wxMouseEvent& event);
|
void OnMouse(wxMouseEvent& event);
|
||||||
void OnKeyDown(wxKeyEvent& event);
|
void OnKeyDown(wxKeyEvent& event);
|
||||||
void OnKeyUp(wxKeyEvent& event);
|
void OnKeyUp(wxKeyEvent& event);
|
||||||
|
void OnFocus(wxFocusEvent& event);
|
||||||
void OnPaint(wxPaintEvent& event);
|
void OnPaint(wxPaintEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
// common part of OnMouse/OnKeyDown/Up
|
||||||
|
void PerformActions(const wxControlActions& actions, const wxEvent& event);
|
||||||
|
|
||||||
// input processor
|
// input processor
|
||||||
wxInputHandler *m_handler;
|
wxInputHandler *m_handler;
|
||||||
|
|
||||||
@@ -115,7 +144,7 @@ private:
|
|||||||
int m_indexAccel;
|
int m_indexAccel;
|
||||||
|
|
||||||
// state
|
// state
|
||||||
bool m_isHighlighted;
|
bool m_isCurrent;
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxControl)
|
DECLARE_DYNAMIC_CLASS(wxControl)
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
#pragma interface "inphand.h"
|
#pragma interface "inphand.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/control.h" // for wxControlAction
|
#include "wx/control.h" // for wxControlAction(s)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxInputHandler: maps the events to the actions
|
// wxInputHandler: maps the events to the actions
|
||||||
@@ -26,12 +26,12 @@
|
|||||||
class WXDLLEXPORT wxInputHandler
|
class WXDLLEXPORT wxInputHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// map a keyboard event to an action (pressed == TRUE if the key was
|
// map a keyboard event to one or more actions (pressed == TRUE if the key
|
||||||
// pressed, FALSE if released)
|
// was pressed, FALSE if released)
|
||||||
virtual wxControlAction Map(const wxKeyEvent& event, bool pressed) = 0;
|
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed) = 0;
|
||||||
|
|
||||||
// map a mouse event to an action
|
// map a mouse event to one or more actions
|
||||||
virtual wxControlAction Map(const wxMouseEvent& event) = 0;
|
virtual wxControlActions Map(const wxMouseEvent& event) = 0;
|
||||||
|
|
||||||
// virtual dtor for any base class
|
// virtual dtor for any base class
|
||||||
virtual ~wxInputHandler();
|
virtual ~wxInputHandler();
|
||||||
|
@@ -37,10 +37,10 @@ class WXDLLEXPORT wxWindow;
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
wxRENDER_ENABLED = 0x00000001,
|
wxRENDER_ENABLED = 0x00000001,
|
||||||
wxRENDER_FOCUSED = 0x00000002,
|
wxRENDER_FOCUSED = 0x00000002, // control currently has keyboard focus
|
||||||
wxRENDER_PRESSED = 0x00000004,
|
wxRENDER_PRESSED = 0x00000004,
|
||||||
wxRENDER_DEFAULT = 0x00000008, // button...
|
wxRENDER_DEFAULT = 0x00000008, // only applies to the buttons
|
||||||
wxRENDER_HIGHLIGHT = 0x00000010,
|
wxRENDER_CURRENT = 0x00000010, // mouse is currently over the control
|
||||||
|
|
||||||
wxRENDER_FLAGS_MASK = 0x0000001f
|
wxRENDER_FLAGS_MASK = 0x0000001f
|
||||||
};
|
};
|
||||||
|
@@ -39,6 +39,21 @@
|
|||||||
#include "wx/stattext.h"
|
#include "wx/stattext.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// constants
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// control ids
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Univ_Button1,
|
||||||
|
Univ_Button2
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// our classes
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Define a new application type, each program should derive a class from wxApp
|
// Define a new application type, each program should derive a class from wxApp
|
||||||
class MyUnivApp : public wxApp
|
class MyUnivApp : public wxApp
|
||||||
{
|
{
|
||||||
@@ -61,6 +76,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// event handlers
|
// event handlers
|
||||||
|
void OnButton(wxCommandEvent& event);
|
||||||
void OnLeftUp(wxMouseEvent& event);
|
void OnLeftUp(wxMouseEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -75,6 +91,8 @@ private:
|
|||||||
IMPLEMENT_APP(MyUnivApp)
|
IMPLEMENT_APP(MyUnivApp)
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(MyUnivFrame, wxFrame)
|
BEGIN_EVENT_TABLE(MyUnivFrame, wxFrame)
|
||||||
|
EVT_BUTTON(-1, MyUnivFrame::OnButton)
|
||||||
|
|
||||||
EVT_LEFT_UP(MyUnivFrame::OnLeftUp)
|
EVT_LEFT_UP(MyUnivFrame::OnLeftUp)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
@@ -152,7 +170,14 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
|
|||||||
|
|
||||||
#undef CREATE_STATIC_ALIGN_DEMO
|
#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)
|
void MyUnivFrame::OnLeftUp(wxMouseEvent& event)
|
||||||
|
@@ -195,7 +195,11 @@ extern wxList wxPendingDelete;
|
|||||||
extern bool g_blockEventsOnDrag;
|
extern bool g_blockEventsOnDrag;
|
||||||
extern bool g_blockEventsOnScroll;
|
extern bool g_blockEventsOnScroll;
|
||||||
extern wxCursor g_globalCursor;
|
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 wxWindow *g_captureWindow = (wxWindow*) NULL;
|
||||||
|
static bool g_captureWindowHasMouse = FALSE;
|
||||||
|
|
||||||
/* extern */ wxWindow *g_focusWindow = (wxWindow*) NULL;
|
/* extern */ wxWindow *g_focusWindow = (wxWindow*) NULL;
|
||||||
|
|
||||||
@@ -1366,11 +1370,31 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
|
|||||||
return FALSE;
|
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"
|
// "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
|
DEBUG_MAIN_THREAD
|
||||||
|
|
||||||
@@ -1401,23 +1425,31 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
wxMouseEvent event( wxEVT_MOTION );
|
wxMouseEvent event( wxEVT_MOTION );
|
||||||
event.SetTimestamp( gdk_event->time );
|
InitMouseEvent(event, gdk_event);
|
||||||
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;
|
if ( g_captureWindow )
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
// 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 x = event.m_x;
|
||||||
wxCoord y = event.m_y;
|
wxCoord y = event.m_y;
|
||||||
if (win->m_wxwindow)
|
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 );
|
gdk_window_get_pointer( widget->window, &x, &y, &state );
|
||||||
|
|
||||||
event.m_shiftDown = (state & GDK_SHIFT_MASK);
|
InitMouseEvent(event, gdk_event);
|
||||||
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;
|
|
||||||
|
|
||||||
if (win->GetEventHandler()->ProcessEvent( event ))
|
if (win->GetEventHandler()->ProcessEvent( event ))
|
||||||
{
|
{
|
||||||
@@ -3528,6 +3551,7 @@ void wxWindow::CaptureMouse()
|
|||||||
cursor->GetCursor(),
|
cursor->GetCursor(),
|
||||||
(guint32)GDK_CURRENT_TIME );
|
(guint32)GDK_CURRENT_TIME );
|
||||||
g_captureWindow = this;
|
g_captureWindow = this;
|
||||||
|
g_captureWindowHasMouse = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxWindow::ReleaseMouse()
|
void wxWindow::ReleaseMouse()
|
||||||
|
@@ -195,7 +195,11 @@ extern wxList wxPendingDelete;
|
|||||||
extern bool g_blockEventsOnDrag;
|
extern bool g_blockEventsOnDrag;
|
||||||
extern bool g_blockEventsOnScroll;
|
extern bool g_blockEventsOnScroll;
|
||||||
extern wxCursor g_globalCursor;
|
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 wxWindow *g_captureWindow = (wxWindow*) NULL;
|
||||||
|
static bool g_captureWindowHasMouse = FALSE;
|
||||||
|
|
||||||
/* extern */ wxWindow *g_focusWindow = (wxWindow*) NULL;
|
/* extern */ wxWindow *g_focusWindow = (wxWindow*) NULL;
|
||||||
|
|
||||||
@@ -1366,11 +1370,31 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
|
|||||||
return FALSE;
|
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"
|
// "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
|
DEBUG_MAIN_THREAD
|
||||||
|
|
||||||
@@ -1401,23 +1425,31 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
wxMouseEvent event( wxEVT_MOTION );
|
wxMouseEvent event( wxEVT_MOTION );
|
||||||
event.SetTimestamp( gdk_event->time );
|
InitMouseEvent(event, gdk_event);
|
||||||
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;
|
if ( g_captureWindow )
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
// 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 x = event.m_x;
|
||||||
wxCoord y = event.m_y;
|
wxCoord y = event.m_y;
|
||||||
if (win->m_wxwindow)
|
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 );
|
gdk_window_get_pointer( widget->window, &x, &y, &state );
|
||||||
|
|
||||||
event.m_shiftDown = (state & GDK_SHIFT_MASK);
|
InitMouseEvent(event, gdk_event);
|
||||||
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;
|
|
||||||
|
|
||||||
if (win->GetEventHandler()->ProcessEvent( event ))
|
if (win->GetEventHandler()->ProcessEvent( event ))
|
||||||
{
|
{
|
||||||
@@ -3528,6 +3551,7 @@ void wxWindow::CaptureMouse()
|
|||||||
cursor->GetCursor(),
|
cursor->GetCursor(),
|
||||||
(guint32)GDK_CURRENT_TIME );
|
(guint32)GDK_CURRENT_TIME );
|
||||||
g_captureWindow = this;
|
g_captureWindow = this;
|
||||||
|
g_captureWindowHasMouse = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxWindow::ReleaseMouse()
|
void wxWindow::ReleaseMouse()
|
||||||
|
@@ -151,7 +151,8 @@ void wxButton::Click()
|
|||||||
Command(event);
|
Command(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxButton::PerformAction(const wxControlAction& action)
|
bool wxButton::PerformAction(const wxControlAction& action,
|
||||||
|
const wxEvent& event)
|
||||||
{
|
{
|
||||||
bool wasPressed = IsPressed();
|
bool wasPressed = IsPressed();
|
||||||
|
|
||||||
@@ -164,7 +165,7 @@ bool wxButton::PerformAction(const wxControlAction& action)
|
|||||||
else if ( action == wxACTION_BUTTON_RELEASE )
|
else if ( action == wxACTION_BUTTON_RELEASE )
|
||||||
Release();
|
Release();
|
||||||
else
|
else
|
||||||
return wxControl::PerformAction(action);
|
return wxControl::PerformAction(action, event);
|
||||||
|
|
||||||
return wasPressed != IsPressed();
|
return wasPressed != IsPressed();
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,9 @@ BEGIN_EVENT_TABLE(wxControl, wxControlBase)
|
|||||||
EVT_LEAVE_WINDOW(wxControl::OnMouse)
|
EVT_LEAVE_WINDOW(wxControl::OnMouse)
|
||||||
EVT_ENTER_WINDOW(wxControl::OnMouse)
|
EVT_ENTER_WINDOW(wxControl::OnMouse)
|
||||||
|
|
||||||
|
EVT_SET_FOCUS(wxControl::OnFocus)
|
||||||
|
EVT_KILL_FOCUS(wxControl::OnFocus)
|
||||||
|
|
||||||
EVT_PAINT(wxControl::OnPaint)
|
EVT_PAINT(wxControl::OnPaint)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
@@ -67,7 +70,7 @@ END_EVENT_TABLE()
|
|||||||
void wxControl::Init()
|
void wxControl::Init()
|
||||||
{
|
{
|
||||||
m_indexAccel = -1;
|
m_indexAccel = -1;
|
||||||
m_isHighlighted = FALSE;
|
m_isCurrent = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxControl::Create(wxWindow *parent,
|
bool wxControl::Create(wxWindow *parent,
|
||||||
@@ -108,14 +111,14 @@ bool wxControl::IsDefault() const
|
|||||||
return FALSE;
|
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();
|
renderer->DrawBorder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// focus handling
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxControl::OnFocus(wxFocusEvent& event)
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// input processing
|
// input processing
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -196,37 +208,48 @@ wxInputHandler *wxControl::CreateInputHandler() const
|
|||||||
|
|
||||||
void wxControl::OnKeyDown(wxKeyEvent& event)
|
void wxControl::OnKeyDown(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
if ( PerformAction(m_handler->Map(event, TRUE)) )
|
PerformActions(m_handler->Map(event, TRUE), event);
|
||||||
{
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxControl::OnKeyUp(wxKeyEvent& event)
|
void wxControl::OnKeyUp(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
if ( PerformAction(m_handler->Map(event, FALSE)) )
|
PerformActions(m_handler->Map(event, FALSE), event);
|
||||||
{
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxControl::OnMouse(wxMouseEvent& event)
|
void wxControl::OnMouse(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
if ( PerformAction(m_handler->Map(event)) )
|
PerformActions(m_handler->Map(event), event);
|
||||||
{
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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() )
|
if ( (action == wxACTION_NONE) || !AcceptsFocus() )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ( action == wxACTION_HIGHLIGHT )
|
if ( action == wxACTION_HIGHLIGHT )
|
||||||
Highlight(TRUE);
|
SetCurrent(TRUE);
|
||||||
else if ( action == wxACTION_UNHIGHLIGHT )
|
else if ( action == wxACTION_UNHIGHLIGHT )
|
||||||
Highlight(FALSE);
|
SetCurrent(FALSE);
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@@ -73,8 +73,8 @@ int wxControlRenderer::GetStateFlags() const
|
|||||||
// it is not, even our default/focused controls shouldn't appear as such
|
// it is not, even our default/focused controls shouldn't appear as such
|
||||||
if ( wxTheApp->IsActive() )
|
if ( wxTheApp->IsActive() )
|
||||||
{
|
{
|
||||||
if ( m_ctrl->IsHighlighted() )
|
if ( m_ctrl->IsCurrent() )
|
||||||
flags |= wxRENDER_HIGHLIGHT;
|
flags |= wxRENDER_CURRENT;
|
||||||
if ( m_ctrl->IsFocused() )
|
if ( m_ctrl->IsFocused() )
|
||||||
flags |= wxRENDER_FOCUSED;
|
flags |= wxRENDER_FOCUSED;
|
||||||
if ( m_ctrl->IsPressed() )
|
if ( m_ctrl->IsPressed() )
|
||||||
|
@@ -112,8 +112,8 @@ private:
|
|||||||
class wxGTKInputHandler : public wxInputHandler
|
class wxGTKInputHandler : public wxInputHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual wxControlAction Map(const wxKeyEvent& event, bool pressed);
|
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed);
|
||||||
virtual wxControlAction Map(const wxMouseEvent& event);
|
virtual wxControlActions Map(const wxMouseEvent& event);
|
||||||
};
|
};
|
||||||
|
|
||||||
class wxGTKButtonInputHandler : public wxGTKInputHandler
|
class wxGTKButtonInputHandler : public wxGTKInputHandler
|
||||||
@@ -121,11 +121,12 @@ class wxGTKButtonInputHandler : public wxGTKInputHandler
|
|||||||
public:
|
public:
|
||||||
wxGTKButtonInputHandler();
|
wxGTKButtonInputHandler();
|
||||||
|
|
||||||
virtual wxControlAction Map(const wxKeyEvent& event, bool pressed);
|
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed);
|
||||||
virtual wxControlAction Map(const wxMouseEvent& event);
|
virtual wxControlActions Map(const wxMouseEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxWindow *m_winCapture;
|
wxWindow *m_winCapture;
|
||||||
|
bool m_winHasMouse;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -441,6 +442,11 @@ void wxGTKRenderer::DrawButtonBorder(wxDC& dc,
|
|||||||
// button not pressed
|
// button not pressed
|
||||||
|
|
||||||
if ( flags & wxRENDER_DEFAULT )
|
if ( flags & wxRENDER_DEFAULT )
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( flags & wxRENDER_FOCUSED )
|
||||||
{
|
{
|
||||||
// button is currently default: add an extra border around it
|
// button is currently default: add an extra border around it
|
||||||
DrawRect(dc, &rect, m_penBlack);
|
DrawRect(dc, &rect, m_penBlack);
|
||||||
@@ -449,8 +455,8 @@ void wxGTKRenderer::DrawButtonBorder(wxDC& dc,
|
|||||||
// now draw a normal button
|
// now draw a normal button
|
||||||
DrawShadedRect(dc, &rect, m_penHighlight, m_penBlack);
|
DrawShadedRect(dc, &rect, m_penHighlight, m_penBlack);
|
||||||
DrawAntiShadedRect(dc, &rect,
|
DrawAntiShadedRect(dc, &rect,
|
||||||
flags & wxRENDER_HIGHLIGHT ? m_penHighlight
|
flags & wxRENDER_CURRENT ? m_penHighlight
|
||||||
: m_penLightGrey,
|
: m_penLightGrey,
|
||||||
m_penDarkGrey);
|
m_penDarkGrey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,7 +557,7 @@ void wxGTKRenderer::DrawBackground(wxDC& dc,
|
|||||||
{
|
{
|
||||||
colBg = wxColour(0x7f7f7f);
|
colBg = wxColour(0x7f7f7f);
|
||||||
}
|
}
|
||||||
else if ( flags & wxRENDER_HIGHLIGHT )
|
else if ( flags & wxRENDER_CURRENT )
|
||||||
{
|
{
|
||||||
colBg = wxColour(0xe0e0e0);
|
colBg = wxColour(0xe0e0e0);
|
||||||
}
|
}
|
||||||
@@ -620,12 +626,12 @@ void wxGTKRenderer::AdjustSize(wxSize *size, const wxWindow *window)
|
|||||||
// wxGTKInputHandler
|
// wxGTKInputHandler
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxControlAction wxGTKInputHandler::Map(const wxKeyEvent& event, bool pressed)
|
wxControlActions wxGTKInputHandler::Map(const wxKeyEvent& event, bool pressed)
|
||||||
{
|
{
|
||||||
return wxACTION_NONE;
|
return wxACTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlAction wxGTKInputHandler::Map(const wxMouseEvent& event)
|
wxControlActions wxGTKInputHandler::Map(const wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
if ( event.Entering() )
|
if ( event.Entering() )
|
||||||
return wxACTION_HIGHLIGHT;
|
return wxACTION_HIGHLIGHT;
|
||||||
@@ -644,8 +650,8 @@ wxGTKButtonInputHandler::wxGTKButtonInputHandler()
|
|||||||
m_winCapture = NULL;
|
m_winCapture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlAction wxGTKButtonInputHandler::Map(const wxKeyEvent& event,
|
wxControlActions wxGTKButtonInputHandler::Map(const wxKeyEvent& event,
|
||||||
bool pressed)
|
bool pressed)
|
||||||
{
|
{
|
||||||
int keycode = event.GetKeyCode();
|
int keycode = event.GetKeyCode();
|
||||||
if ( keycode == WXK_SPACE || keycode == WXK_RETURN )
|
if ( keycode == WXK_SPACE || keycode == WXK_RETURN )
|
||||||
@@ -656,18 +662,67 @@ wxControlAction wxGTKButtonInputHandler::Map(const wxKeyEvent& event,
|
|||||||
return wxGTKInputHandler::Map(event, pressed);
|
return wxGTKInputHandler::Map(event, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlAction wxGTKButtonInputHandler::Map(const wxMouseEvent& event)
|
wxControlActions wxGTKButtonInputHandler::Map(const wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
if ( event.IsButton() )
|
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;
|
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);
|
return wxGTKInputHandler::Map(event);
|
||||||
}
|
}
|
||||||
|
@@ -107,8 +107,8 @@ private:
|
|||||||
class wxWin32InputHandler : public wxInputHandler
|
class wxWin32InputHandler : public wxInputHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual wxControlAction Map(const wxKeyEvent& event, bool pressed);
|
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed);
|
||||||
virtual wxControlAction Map(const wxMouseEvent& event);
|
virtual wxControlActions Map(const wxMouseEvent& event);
|
||||||
};
|
};
|
||||||
|
|
||||||
class wxWin32ButtonInputHandler : public wxWin32InputHandler
|
class wxWin32ButtonInputHandler : public wxWin32InputHandler
|
||||||
@@ -116,8 +116,8 @@ class wxWin32ButtonInputHandler : public wxWin32InputHandler
|
|||||||
public:
|
public:
|
||||||
wxWin32ButtonInputHandler();
|
wxWin32ButtonInputHandler();
|
||||||
|
|
||||||
virtual wxControlAction Map(const wxKeyEvent& event, bool pressed);
|
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed);
|
||||||
virtual wxControlAction Map(const wxMouseEvent& event);
|
virtual wxControlActions Map(const wxMouseEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxWindow *m_winCapture;
|
wxWindow *m_winCapture;
|
||||||
@@ -617,12 +617,12 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window)
|
|||||||
// wxWin32InputHandler
|
// wxWin32InputHandler
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxControlAction wxWin32InputHandler::Map(const wxKeyEvent& event, bool pressed)
|
wxControlActions wxWin32InputHandler::Map(const wxKeyEvent& event, bool pressed)
|
||||||
{
|
{
|
||||||
return wxACTION_NONE;
|
return wxACTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlAction wxWin32InputHandler::Map(const wxMouseEvent& event)
|
wxControlActions wxWin32InputHandler::Map(const wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
return wxACTION_NONE;
|
return wxACTION_NONE;
|
||||||
}
|
}
|
||||||
@@ -636,8 +636,8 @@ wxWin32ButtonInputHandler::wxWin32ButtonInputHandler()
|
|||||||
m_winCapture = NULL;
|
m_winCapture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlAction wxWin32ButtonInputHandler::Map(const wxKeyEvent& event,
|
wxControlActions wxWin32ButtonInputHandler::Map(const wxKeyEvent& event,
|
||||||
bool pressed)
|
bool pressed)
|
||||||
{
|
{
|
||||||
int keycode = event.GetKeyCode();
|
int keycode = event.GetKeyCode();
|
||||||
if ( keycode == WXK_SPACE || keycode == WXK_RETURN )
|
if ( keycode == WXK_SPACE || keycode == WXK_RETURN )
|
||||||
@@ -648,7 +648,7 @@ wxControlAction wxWin32ButtonInputHandler::Map(const wxKeyEvent& event,
|
|||||||
return wxWin32InputHandler::Map(event, pressed);
|
return wxWin32InputHandler::Map(event, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlAction wxWin32ButtonInputHandler::Map(const wxMouseEvent& event)
|
wxControlActions wxWin32ButtonInputHandler::Map(const wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
if ( event.IsButton() )
|
if ( event.IsButton() )
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user