diff --git a/include/wx/app.h b/include/wx/app.h index 7eb05d1339..9e93dc03c5 100644 --- a/include/wx/app.h +++ b/include/wx/app.h @@ -59,6 +59,8 @@ static const int wxPRINT_POSTSCRIPT = 2; class WXDLLEXPORT wxAppBase : public wxEvtHandler { public: + wxAppBase(); + // the virtual functions which may/must be overridden in the derived class // ----------------------------------------------------------------------- @@ -163,8 +165,8 @@ public: // top level window functions // -------------------------- - // return TRUE if the active window belongs to our app - virtual bool IsActive() const = 0; + // return TRUE if our app has focus + virtual bool IsActive() const { return m_isActive; } // set the "main" top level window void SetTopWindow(wxWindow *win) { m_topWindow = win; } @@ -228,6 +230,11 @@ public: // printing. virtual void SetPrintMode(int WXUNUSED(mode)) { } int GetPrintMode() const { return wxPRINT_POSTSCRIPT; } + + // called by toolkit-specific code to set the app status: active (we have + // focus) or not and also the last window which had focus before we were + // deactivated + virtual void SetActive(bool isActive, wxWindow *lastFocus); #endif // wxUSE_GUI // implementation only from now on @@ -246,7 +253,6 @@ public: int argc; wxChar **argv; -//private: protected: // function used for dynamic wxApp creation static wxAppInitializerFunction m_appInitFn; @@ -256,19 +262,22 @@ protected: m_appName, // app name m_className; // class name - // if TRUE, exit the main loop when the last top level window is deleted - bool m_exitOnFrameDelete; - // TRUE if the application wants to get debug output bool m_wantDebugOutput; +#if wxUSE_GUI + // the main top level window - may be NULL + wxWindow *m_topWindow; + + // if TRUE, exit the main loop when the last top level window is deleted + bool m_exitOnFrameDelete; + // TRUE if the apps whats to use the best visual on systems where // more than one are available (Sun, SGI, XFree86 4.0 ?) bool m_useBestVisual; -#if wxUSE_GUI - // the main top level window - may be NULL - wxWindow *m_topWindow; + // does any of our windows has focus? + bool m_isActive; #endif // wxUSE_GUI }; diff --git a/include/wx/gtk/app.h b/include/wx/gtk/app.h index 0aa17f76e4..d719580464 100644 --- a/include/wx/gtk/app.h +++ b/include/wx/gtk/app.h @@ -47,8 +47,6 @@ public: virtual bool Pending(); virtual void Dispatch(); - virtual bool IsActive() const; - virtual wxIcon GetStdIcon(int which) const; // implementation only from now on @@ -67,8 +65,6 @@ public: void SuppressIdleEvents(bool arg = TRUE) { m_suppressIdleEvents = arg; } bool GetSuppressIdleEvents() const { return m_suppressIdleEvents; } - void SetActive(bool isActive) { m_isActive = isActive; } - bool m_initialized; gint m_idleTag; @@ -81,9 +77,6 @@ private: // Set to TRUE while we are in wxYield(). bool m_suppressIdleEvents; - // does any of our windows has focus? - bool m_isActive; - private: DECLARE_DYNAMIC_CLASS(wxApp) DECLARE_EVENT_TABLE() diff --git a/include/wx/gtk1/app.h b/include/wx/gtk1/app.h index 0aa17f76e4..d719580464 100644 --- a/include/wx/gtk1/app.h +++ b/include/wx/gtk1/app.h @@ -47,8 +47,6 @@ public: virtual bool Pending(); virtual void Dispatch(); - virtual bool IsActive() const; - virtual wxIcon GetStdIcon(int which) const; // implementation only from now on @@ -67,8 +65,6 @@ public: void SuppressIdleEvents(bool arg = TRUE) { m_suppressIdleEvents = arg; } bool GetSuppressIdleEvents() const { return m_suppressIdleEvents; } - void SetActive(bool isActive) { m_isActive = isActive; } - bool m_initialized; gint m_idleTag; @@ -81,9 +77,6 @@ private: // Set to TRUE while we are in wxYield(). bool m_suppressIdleEvents; - // does any of our windows has focus? - bool m_isActive; - private: DECLARE_DYNAMIC_CLASS(wxApp) DECLARE_EVENT_TABLE() diff --git a/include/wx/msw/app.h b/include/wx/msw/app.h index 657d274945..aa875c4dba 100644 --- a/include/wx/msw/app.h +++ b/include/wx/msw/app.h @@ -42,8 +42,6 @@ public: virtual bool Pending(); virtual void Dispatch(); - virtual bool IsActive() const { return m_isActive; } - virtual wxIcon GetStdIcon(int which) const; virtual void SetPrintMode(int mode) { m_printMode = mode; } @@ -65,14 +63,10 @@ public: void SetAuto3D(bool flag) { m_auto3D = flag; } bool GetAuto3D() const { return m_auto3D; } - // for private use only - void SetActive(bool isActive) { m_isActive = isActive; } - protected: bool m_showOnInit; int m_printMode; // wxPRINT_WINDOWS, wxPRINT_POSTSCRIPT bool m_auto3D ; // Always use 3D controls, except where overriden - bool m_isActive; /* Windows-specific wxApp definitions */ diff --git a/include/wx/univ/button.h b/include/wx/univ/button.h index d2a008199d..6712add26d 100644 --- a/include/wx/univ/button.h +++ b/include/wx/univ/button.h @@ -16,8 +16,16 @@ #pragma interface "univbutton.h" #endif +class WXDLLEXPORT wxInputHandler; + // ---------------------------------------------------------------------------- -// Pushbutton +// the actions supported by this control +// ---------------------------------------------------------------------------- + +#define wxACTION_BUTTON_TOGGLE _T("toggle") // press/release the button + +// ---------------------------------------------------------------------------- +// wxButton: a push button // ---------------------------------------------------------------------------- class WXDLLEXPORT wxButton : public wxButtonBase @@ -55,6 +63,8 @@ public: virtual bool IsDefault() const { return m_isDefault; } protected: + virtual wxInputHandler *CreateInputHandler() const; + virtual bool PerformAction(const wxControlAction& action); virtual wxSize DoGetBestSize() const; virtual void DoDraw(wxControlRenderer *renderer); diff --git a/include/wx/univ/control.h b/include/wx/univ/control.h index dff129d1f3..a106ebb716 100644 --- a/include/wx/univ/control.h +++ b/include/wx/univ/control.h @@ -17,21 +17,44 @@ #endif class WXDLLEXPORT wxControlRenderer; +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) +// ---------------------------------------------------------------------------- + +typedef wxString wxControlAction; + +// no action to perform (other actions are defined in the controls headers) +#define wxACTION_NONE _T("") + +// ---------------------------------------------------------------------------- +// wxControl: the base class for all GUI controls +// ---------------------------------------------------------------------------- class WXDLLEXPORT wxControl : public wxControlBase { public: wxControl(); - wxControl(wxWindow *parent, wxWindowID id, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, long style = 0, - const wxValidator& validator = wxDefaultValidator, - const wxString& name = wxControlNameStr) + wxControl(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxControlNameStr) { Create(parent, id, pos, size, style, validator, name); } + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxControlNameStr); + // this function will filter out '&' characters and will put the // accelerator char (the one immediately after '&') into m_chAccel virtual void SetLabel(const wxString &label); @@ -54,13 +77,27 @@ public: } 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; + // 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); + // event handlers + void OnMouse(wxMouseEvent& event); + void OnKeyDown(wxKeyEvent& event); + void OnKeyUp(wxKeyEvent& event); void OnPaint(wxPaintEvent& event); private: + // input processor + wxInputHandler *m_handler; + + // label with accel into wxString m_label; int m_indexAccel; diff --git a/include/wx/univ/inphand.h b/include/wx/univ/inphand.h new file mode 100644 index 0000000000..64fbdca5c3 --- /dev/null +++ b/include/wx/univ/inphand.h @@ -0,0 +1,47 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/univ/inphand.h +// Purpose: wxInputHandler class maps the keyboard and mouse events to the +// actions which then are performed by the control +// Author: Vadim Zeitlin +// Modified by: +// Created: 18.08.00 +// RCS-ID: $Id$ +// Copyright: (c) 2000 Vadim Zeitlin +// Licence: wxWindows license +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_UNIV_INPHAND_H_ +#define _WX_UNIV_INPHAND_H_ + +#ifdef __GNUG__ + #pragma interface "inphand.h" +#endif + +#include "wx/control.h" // for wxControlAction + +// ---------------------------------------------------------------------------- +// wxInputHandler: maps the events to the actions +// ---------------------------------------------------------------------------- + +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 mouse event to an action + virtual wxControlAction Map(const wxMouseEvent& event) = 0; + + // virtual dtor for any base class + virtual ~wxInputHandler(); +}; + +// ---------------------------------------------------------------------------- +// the control names which can be passed to wxTheme::GetInputHandler() +// ---------------------------------------------------------------------------- + +#define wxCONTROL_DEFAULT _T("control") +#define wxCONTROL_BUTTON _T("button") + +#endif // _WX_UNIV_INPHAND_H_ diff --git a/include/wx/univ/renderer.h b/include/wx/univ/renderer.h index 155b8d8e9e..cf5af17d6c 100644 --- a/include/wx/univ/renderer.h +++ b/include/wx/univ/renderer.h @@ -19,8 +19,8 @@ #pragma interface "renderer.h" #endif -#ifndef _WX_UNIX_RENDERER_H_ -#define _WX_UNIX_RENDERER_H_ +#ifndef _WX_UNIV_RENDERER_H_ +#define _WX_UNIV_RENDERER_H_ class WXDLLEXPORT wxControl; class WXDLLEXPORT wxDC; @@ -90,6 +90,9 @@ public: // example) it is more complicated - the result being, in any case, that // the control looks "nice" if it uses the adjusted rectangle virtual void AdjustSize(wxSize *size, const wxWindow *window) = 0; + + // virtual dtor for any base class + virtual ~wxRenderer(); }; // ---------------------------------------------------------------------------- @@ -176,5 +179,5 @@ private: wxRect m_rect; }; -#endif // _WX_UNIX_RENDERER_H_ +#endif // _WX_UNIV_RENDERER_H_ diff --git a/include/wx/univ/theme.h b/include/wx/univ/theme.h index 9adcc47d24..f58b3b22ef 100644 --- a/include/wx/univ/theme.h +++ b/include/wx/univ/theme.h @@ -11,8 +11,8 @@ // Licence: wxWindows license /////////////////////////////////////////////////////////////////////////////// -#ifndef _WX_UNIX_THEME_H_ -#define _WX_UNIX_THEME_H_ +#ifndef _WX_UNIV_THEME_H_ +#define _WX_UNIV_THEME_H_ #ifdef __GNUG__ #pragma interface "theme.h" @@ -23,7 +23,7 @@ // ---------------------------------------------------------------------------- class WXDLLEXPORT wxRenderer; -class WXDLLEXPORT wxInputHandler { }; +class WXDLLEXPORT wxInputHandler; class WXDLLEXPORT wxColourScheme { }; class WXDLLEXPORT wxTheme @@ -46,8 +46,14 @@ public: // the theme methods // ----------------- + + // get the renderer implementing all the control-drawing operations in + // this theme virtual wxRenderer *GetRenderer() = 0; - virtual wxInputHandler *GetInputHandler() = 0; + + // get the input handler for the control with this name + virtual wxInputHandler *GetInputHandler(const wxString& control) = 0; + virtual wxColourScheme *GetColourScheme() = 0; // implementation only from now on @@ -96,5 +102,5 @@ private: wxTheme::wxThemeInfo classname::ms_info(wxCtorFor##themename, \ #themename, themedesc) -#endif // _WX_UNIX_THEME_H_ +#endif // _WX_UNIV_THEME_H_ diff --git a/src/common/appcmn.cpp b/src/common/appcmn.cpp index 9e2b73d716..538eff7825 100644 --- a/src/common/appcmn.cpp +++ b/src/common/appcmn.cpp @@ -44,6 +44,21 @@ // implementation // =========================================================================== +wxAppBase::wxAppBase() +{ + wxTheApp = (wxApp *)this; + + // VZ: what's this? is it obsolete? + m_wantDebugOutput = FALSE; + +#if wxUSE_GUI + m_topWindow = (wxWindow *)NULL; + m_useBestVisual = FALSE; + m_exitOnFrameDelete = TRUE; + m_isActive = TRUE; +#endif // wxUSE_GUI +} + // ---------------------------------------------------------------------------- // initialization and termination // ---------------------------------------------------------------------------- @@ -107,3 +122,26 @@ void wxAppBase::ProcessPendingEvents() wxLEAVE_CRIT_SECT( *wxPendingEventsLocker ); } +// ---------------------------------------------------------------------------- +// misc +// ---------------------------------------------------------------------------- + +#if wxUSE_GUI + +void wxAppBase::SetActive(bool active, wxWindow *lastFocus) +{ + static wxWindow *s_lastFocus = (wxWindow *)NULL; + + m_isActive = active; + + // if we're being deactivated remember the last focused window + if ( !active ) + { + s_lastFocus = lastFocus; + } + + if ( s_lastFocus ) + s_lastFocus->Refresh(); +} + +#endif // wxUSE_GUI diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index 2fe2770315..684057d25d 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -245,12 +245,6 @@ END_EVENT_TABLE() wxApp::wxApp() { - wxTheApp = this; - - m_topWindow = (wxWindow *) NULL; - m_exitOnFrameDelete = TRUE; - m_isActive = TRUE; - m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL ); #if wxUSE_THREADS @@ -259,8 +253,6 @@ wxApp::wxApp() #endif m_colorCube = (unsigned char*) NULL; - - m_useBestVisual = FALSE; } wxApp::~wxApp() @@ -470,11 +462,6 @@ void wxApp::Dispatch() gtk_main_iteration(); } -bool wxApp::IsActive() const -{ - return m_isActive; -} - void wxApp::DeletePendingObjects() { wxNode *node = wxPendingDelete.First(); diff --git a/src/gtk/win_gtk.c b/src/gtk/win_gtk.c index e52487912a..6bee46df1c 100644 --- a/src/gtk/win_gtk.c +++ b/src/gtk/win_gtk.c @@ -522,18 +522,20 @@ gtk_pizza_realize (GtkWidget *widget) attributes.width = widget->allocation.width; attributes.height = widget->allocation.height; +#ifndef __WXUNIVERSAL__ if (pizza->shadow_type == GTK_MYSHADOW_NONE) { /* no border, no changes to sizes */ - } else - if (pizza->shadow_type == GTK_MYSHADOW_THIN) + } + else if (pizza->shadow_type == GTK_MYSHADOW_THIN) { /* GTK_MYSHADOW_THIN == wxSIMPLE_BORDER */ attributes.x += 1; attributes.y += 1; attributes.width -= 2; attributes.height -= 2; - } else + } + else { /* GTK_MYSHADOW_IN == wxSUNKEN_BORDER */ /* GTK_MYSHADOW_OUT == wxRAISED_BORDER */ @@ -542,6 +544,7 @@ gtk_pizza_realize (GtkWidget *widget) attributes.width -= 4; attributes.height -= 4; } +#endif /* __WXUNIVERSAL__ */ /* minimal size */ if (attributes.width < 2) attributes.width = 2; diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 6e3e21bc0b..72f6fe5b54 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -199,6 +199,11 @@ static wxWindow *g_captureWindow = (wxWindow*) NULL; /* extern */ wxWindow *g_focusWindow = (wxWindow*) NULL; +// the last window which had the focus - this is normally never NULL (except +// if we never had focus at all) as even when g_focusWindow is NULL it still +// keeps its previous value +static wxWindow *g_focusWindowLast = (wxWindow *)NULL; + // if we detect that the app has got/lost the focus, we set this variable to // either TRUE or FALSE and an activate event will be sent during the next // OnIdle() call and it is reset to -1: this value means that we shouldn't @@ -376,6 +381,8 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) } } + // wxUniversal widgets draw the borders themselves +#ifndef __WXUNIVERSAL__ int dx = 0; int dy = 0; if (GTK_WIDGET_NO_WINDOW (widget)) @@ -417,6 +424,7 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) gdk_gc_unref( gc ); return; } +#endif // __WXUNIVERSAL__ } //----------------------------------------------------------------------------- @@ -1508,6 +1516,7 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED( break; } + g_focusWindowLast = g_focusWindow = win; /* @@ -2176,6 +2185,7 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); +#ifndef __WXUNIVERSAL__ #if (GTK_MINOR_VERSION > 0) GtkPizza *pizza = GTK_PIZZA(m_wxwindow); @@ -2211,6 +2221,7 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE ); } #endif // GTK_MINOR_VERSION +#endif // __WXUNIVERSAL__ GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); m_acceptsFocus = TRUE; @@ -2569,7 +2580,7 @@ void wxWindow::OnInternalIdle() // do it only once g_sendActivateEvent = -1; - wxTheApp->SetActive(activate); + wxTheApp->SetActive(activate, g_focusWindowLast); wxActivateEvent event(wxEVT_ACTIVATE, activate, GetId()); event.SetEventObject(this); @@ -2635,6 +2646,7 @@ void wxWindow::DoSetClientSize( int width, int height ) int dw = 0; int dh = 0; +#ifndef __WXUNIVERSAL__ if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) { /* when using GTK 1.2 we set the shadow border size to 2 */ @@ -2647,6 +2659,7 @@ void wxWindow::DoSetClientSize( int width, int height ) dw += 1 * 2; dh += 1 * 2; } +#endif // __WXUNIVERSAL__ if (m_hasScrolling) { @@ -2697,6 +2710,7 @@ void wxWindow::DoGetClientSize( int *width, int *height ) const int dw = 0; int dh = 0; +#ifndef __WXUNIVERSAL__ if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) { /* when using GTK 1.2 we set the shadow border size to 2 */ @@ -2709,6 +2723,7 @@ void wxWindow::DoGetClientSize( int *width, int *height ) const dw += 1 * 2; dh += 1 * 2; } +#endif // __WXUNIVERSAL__ if (m_hasScrolling) { diff --git a/src/gtk1/app.cpp b/src/gtk1/app.cpp index 2fe2770315..684057d25d 100644 --- a/src/gtk1/app.cpp +++ b/src/gtk1/app.cpp @@ -245,12 +245,6 @@ END_EVENT_TABLE() wxApp::wxApp() { - wxTheApp = this; - - m_topWindow = (wxWindow *) NULL; - m_exitOnFrameDelete = TRUE; - m_isActive = TRUE; - m_idleTag = gtk_idle_add_priority( 1000, wxapp_idle_callback, (gpointer) NULL ); #if wxUSE_THREADS @@ -259,8 +253,6 @@ wxApp::wxApp() #endif m_colorCube = (unsigned char*) NULL; - - m_useBestVisual = FALSE; } wxApp::~wxApp() @@ -470,11 +462,6 @@ void wxApp::Dispatch() gtk_main_iteration(); } -bool wxApp::IsActive() const -{ - return m_isActive; -} - void wxApp::DeletePendingObjects() { wxNode *node = wxPendingDelete.First(); diff --git a/src/gtk1/win_gtk.c b/src/gtk1/win_gtk.c index e52487912a..6bee46df1c 100644 --- a/src/gtk1/win_gtk.c +++ b/src/gtk1/win_gtk.c @@ -522,18 +522,20 @@ gtk_pizza_realize (GtkWidget *widget) attributes.width = widget->allocation.width; attributes.height = widget->allocation.height; +#ifndef __WXUNIVERSAL__ if (pizza->shadow_type == GTK_MYSHADOW_NONE) { /* no border, no changes to sizes */ - } else - if (pizza->shadow_type == GTK_MYSHADOW_THIN) + } + else if (pizza->shadow_type == GTK_MYSHADOW_THIN) { /* GTK_MYSHADOW_THIN == wxSIMPLE_BORDER */ attributes.x += 1; attributes.y += 1; attributes.width -= 2; attributes.height -= 2; - } else + } + else { /* GTK_MYSHADOW_IN == wxSUNKEN_BORDER */ /* GTK_MYSHADOW_OUT == wxRAISED_BORDER */ @@ -542,6 +544,7 @@ gtk_pizza_realize (GtkWidget *widget) attributes.width -= 4; attributes.height -= 4; } +#endif /* __WXUNIVERSAL__ */ /* minimal size */ if (attributes.width < 2) attributes.width = 2; diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 6e3e21bc0b..72f6fe5b54 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -199,6 +199,11 @@ static wxWindow *g_captureWindow = (wxWindow*) NULL; /* extern */ wxWindow *g_focusWindow = (wxWindow*) NULL; +// the last window which had the focus - this is normally never NULL (except +// if we never had focus at all) as even when g_focusWindow is NULL it still +// keeps its previous value +static wxWindow *g_focusWindowLast = (wxWindow *)NULL; + // if we detect that the app has got/lost the focus, we set this variable to // either TRUE or FALSE and an activate event will be sent during the next // OnIdle() call and it is reset to -1: this value means that we shouldn't @@ -376,6 +381,8 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) } } + // wxUniversal widgets draw the borders themselves +#ifndef __WXUNIVERSAL__ int dx = 0; int dy = 0; if (GTK_WIDGET_NO_WINDOW (widget)) @@ -417,6 +424,7 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) gdk_gc_unref( gc ); return; } +#endif // __WXUNIVERSAL__ } //----------------------------------------------------------------------------- @@ -1508,6 +1516,7 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED( break; } + g_focusWindowLast = g_focusWindow = win; /* @@ -2176,6 +2185,7 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); +#ifndef __WXUNIVERSAL__ #if (GTK_MINOR_VERSION > 0) GtkPizza *pizza = GTK_PIZZA(m_wxwindow); @@ -2211,6 +2221,7 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE ); } #endif // GTK_MINOR_VERSION +#endif // __WXUNIVERSAL__ GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); m_acceptsFocus = TRUE; @@ -2569,7 +2580,7 @@ void wxWindow::OnInternalIdle() // do it only once g_sendActivateEvent = -1; - wxTheApp->SetActive(activate); + wxTheApp->SetActive(activate, g_focusWindowLast); wxActivateEvent event(wxEVT_ACTIVATE, activate, GetId()); event.SetEventObject(this); @@ -2635,6 +2646,7 @@ void wxWindow::DoSetClientSize( int width, int height ) int dw = 0; int dh = 0; +#ifndef __WXUNIVERSAL__ if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) { /* when using GTK 1.2 we set the shadow border size to 2 */ @@ -2647,6 +2659,7 @@ void wxWindow::DoSetClientSize( int width, int height ) dw += 1 * 2; dh += 1 * 2; } +#endif // __WXUNIVERSAL__ if (m_hasScrolling) { @@ -2697,6 +2710,7 @@ void wxWindow::DoGetClientSize( int *width, int *height ) const int dw = 0; int dh = 0; +#ifndef __WXUNIVERSAL__ if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) { /* when using GTK 1.2 we set the shadow border size to 2 */ @@ -2709,6 +2723,7 @@ void wxWindow::DoGetClientSize( int *width, int *height ) const dw += 1 * 2; dh += 1 * 2; } +#endif // __WXUNIVERSAL__ if (m_hasScrolling) { diff --git a/src/msw/app.cpp b/src/msw/app.cpp index cd32781e0b..70311095b4 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -828,16 +828,10 @@ wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NUL wxApp::wxApp() { - m_topWindow = NULL; - wxTheApp = this; - m_wantDebugOutput = TRUE; - argc = 0; argv = NULL; m_printMode = wxPRINT_WINDOWS; - m_exitOnFrameDelete = TRUE; m_auto3D = TRUE; - m_isActive = FALSE; } wxApp::~wxApp() diff --git a/src/msw/window.cpp b/src/msw/window.cpp index a646f0990d..8e5512f4a1 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -1884,19 +1884,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) #ifdef __WXUNIVERSAL__ case WM_ACTIVATEAPP: - { - // refresh the focused window - static wxWindow *s_lastFocus = NULL; - wxTheApp->SetActive(wParam != 0); - if ( !wParam ) - { - // we're being de activated - s_lastFocus = FindFocus(); - } - - if ( s_lastFocus ) - s_lastFocus->Refresh(); - } + wxTheApp->SetActive(wParam != 0, FindFocus()); break; #endif // __WXUNIVERSAL__ diff --git a/src/univ/button.cpp b/src/univ/button.cpp index ed196e30a4..695ef2fd3d 100644 --- a/src/univ/button.cpp +++ b/src/univ/button.cpp @@ -36,6 +36,7 @@ #endif #include "wx/univ/renderer.h" +#include "wx/univ/inphand.h" #include "wx/univ/theme.h" // ============================================================================ @@ -113,6 +114,29 @@ void wxButton::DoDraw(wxControlRenderer *renderer) renderer->DrawLabel(); } +// ---------------------------------------------------------------------------- +// input processing +// ---------------------------------------------------------------------------- + +wxInputHandler *wxButton::CreateInputHandler() const +{ + return wxTheme::Get()->GetInputHandler(wxCONTROL_BUTTON); +} + +bool wxButton::PerformAction(const wxControlAction& action) +{ + if ( action == wxACTION_BUTTON_TOGGLE ) + { + m_isPressed = !m_isPressed; + } + else + { + return wxControl::PerformAction(action); + } + + return TRUE; +} + // ---------------------------------------------------------------------------- // // ---------------------------------------------------------------------------- diff --git a/src/univ/control.cpp b/src/univ/control.cpp index 9a67468242..5e1e99881c 100644 --- a/src/univ/control.cpp +++ b/src/univ/control.cpp @@ -35,6 +35,7 @@ #endif #include "wx/univ/renderer.h" +#include "wx/univ/inphand.h" #include "wx/univ/theme.h" // ============================================================================ @@ -44,6 +45,18 @@ IMPLEMENT_DYNAMIC_CLASS(wxControl, wxWindow) BEGIN_EVENT_TABLE(wxControl, wxControlBase) + EVT_KEY_DOWN(wxControl::OnKeyDown) + EVT_KEY_UP(wxControl::OnKeyUp) + + EVT_LEFT_DOWN(wxControl::OnMouse) + EVT_LEFT_UP(wxControl::OnMouse) + EVT_RIGHT_DOWN(wxControl::OnMouse) + EVT_RIGHT_UP(wxControl::OnMouse) + EVT_MIDDLE_DOWN(wxControl::OnMouse) + EVT_MIDDLE_UP(wxControl::OnMouse) + EVT_LEAVE_WINDOW(wxControl::OnMouse) + EVT_ENTER_WINDOW(wxControl::OnMouse) + EVT_PAINT(wxControl::OnPaint) END_EVENT_TABLE() @@ -56,6 +69,24 @@ wxControl::wxControl() m_indexAccel = -1; } +bool wxControl::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxValidator& validator, + const wxString& name) +{ + if ( !wxControlBase::Create(parent, id, pos, size, style, validator, name) ) + return FALSE; + + SetBackgroundColour(parent->GetBackgroundColour()); + + m_handler = CreateInputHandler(); + + return TRUE; +} + // ---------------------------------------------------------------------------- // state flags // ---------------------------------------------------------------------------- @@ -143,4 +174,43 @@ void wxControl::DoDraw(wxControlRenderer *renderer) renderer->DrawBorder(); } +// ---------------------------------------------------------------------------- +// input processing +// ---------------------------------------------------------------------------- + +wxInputHandler *wxControl::CreateInputHandler() const +{ + return wxTheme::Get()->GetInputHandler(wxCONTROL_DEFAULT); +} + +void wxControl::OnKeyDown(wxKeyEvent& event) +{ + if ( PerformAction(m_handler->Map(event, TRUE)) ) + { + Refresh(); + } +} + +void wxControl::OnKeyUp(wxKeyEvent& event) +{ + if ( PerformAction(m_handler->Map(event, FALSE)) ) + { + Refresh(); + } +} + +void wxControl::OnMouse(wxMouseEvent& event) +{ + if ( PerformAction(m_handler->Map(event)) ) + { + Refresh(); + } +} + +bool wxControl::PerformAction(const wxControlAction& action) +{ + // nothing to do + return FALSE; +} + #endif // wxUSE_CONTROLS diff --git a/src/univ/files.lst b/src/univ/files.lst index 1e6c3e7cf7..903b09d45a 100644 --- a/src/univ/files.lst +++ b/src/univ/files.lst @@ -1,6 +1,7 @@ UNIVOBJS = \ button.o \ control.o \ + inphand.o \ renderer.o \ statbox.o \ stattext.o \ diff --git a/src/univ/inphand.cpp b/src/univ/inphand.cpp new file mode 100644 index 0000000000..6efe55b87e --- /dev/null +++ b/src/univ/inphand.cpp @@ -0,0 +1,42 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: univ/inphand.cpp +// Purpose: (trivial) wxInputHandler implementation +// Author: Vadim Zeitlin +// Modified by: +// Created: 18.08.00 +// RCS-ID: $Id$ +// Copyright: (c) 2000 Vadim Zeitlin +// Licence: wxWindows license +/////////////////////////////////////////////////////////////////////////////// + +// =========================================================================== +// declarations +// =========================================================================== + +// --------------------------------------------------------------------------- +// headers +// --------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "inphand.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#endif // WX_PRECOMP + +#include "wx/univ/inphand.h" + +// ============================================================================ +// implementation +// ============================================================================ + +wxInputHandler::~wxInputHandler() +{ +} diff --git a/src/univ/renderer.cpp b/src/univ/renderer.cpp index 014742fe37..4adab5f4ff 100644 --- a/src/univ/renderer.cpp +++ b/src/univ/renderer.cpp @@ -40,6 +40,10 @@ // implementation // ============================================================================ +wxRenderer::~wxRenderer() +{ +} + // ---------------------------------------------------------------------------- // wxControlRenderer // ---------------------------------------------------------------------------- diff --git a/src/univ/theme.cpp b/src/univ/theme.cpp index 6f165fccdc..ef1869f48b 100644 --- a/src/univ/theme.cpp +++ b/src/univ/theme.cpp @@ -34,6 +34,7 @@ #endif // WX_PRECOMP #include "wx/univ/renderer.h" +#include "wx/univ/inphand.h" #include "wx/univ/theme.h" // ============================================================================ @@ -111,9 +112,10 @@ wxTheme::wxThemeInfo::wxThemeInfo(wxTheme::Constructor c, } // ---------------------------------------------------------------------------- -// wxTheme dtor +// assorted trivial dtors // ---------------------------------------------------------------------------- wxTheme::~wxTheme() { } + diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index 5aaa259b70..a76f85620a 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -32,10 +32,11 @@ #endif // WX_PRECOMP #include "wx/univ/renderer.h" +#include "wx/univ/inphand.h" #include "wx/univ/theme.h" // ---------------------------------------------------------------------------- -// private classes +// wxWin32Renderer: draw the GUI elements in Win32 style // ---------------------------------------------------------------------------- class wxWin32Renderer : public wxRenderer @@ -94,26 +95,62 @@ private: m_penHighlight; }; +// ---------------------------------------------------------------------------- +// wxWin32InputHandler and derived classes: process the keyboard and mouse +// messages according to Windows standards +// ---------------------------------------------------------------------------- + class wxWin32InputHandler : public wxInputHandler { +public: + virtual wxControlAction Map(const wxKeyEvent& event, bool pressed); + virtual wxControlAction Map(const wxMouseEvent& event); }; +class wxWin32ButtonInputHandler : public wxWin32InputHandler +{ +public: + wxWin32ButtonInputHandler(); + + virtual wxControlAction Map(const wxKeyEvent& event, bool pressed); + virtual wxControlAction Map(const wxMouseEvent& event); + +private: + wxWindow *m_winCapture; +}; + +// ---------------------------------------------------------------------------- +// wxWin32ColourScheme +// ---------------------------------------------------------------------------- + class wxWin32ColourScheme : public wxColourScheme { }; +// ---------------------------------------------------------------------------- +// wxWin32Theme +// ---------------------------------------------------------------------------- + +WX_DEFINE_ARRAY(wxInputHandler *, wxArrayHandlers); + class wxWin32Theme : public wxTheme { public: wxWin32Theme(); + virtual ~wxWin32Theme(); virtual wxRenderer *GetRenderer() { return m_renderer; } - virtual wxInputHandler *GetInputHandler() { return m_handler; } + virtual wxInputHandler *GetInputHandler(const wxString& control); virtual wxColourScheme *GetColourScheme() { return m_scheme; } private: wxWin32Renderer *m_renderer; - wxWin32InputHandler *m_handler; + + // the names of the already created handlers and the handlers themselves + // (these arrays are synchronized) + wxSortedArrayString m_handlerNames; + wxArrayHandlers m_handlers; + wxWin32ColourScheme *m_scheme; WX_DECLARE_THEME(); @@ -132,13 +169,46 @@ WX_IMPLEMENT_THEME(wxWin32Theme, win32, wxTRANSLATE("Win32 theme")); wxWin32Theme::wxWin32Theme() { m_renderer = new wxWin32Renderer; - m_handler = NULL; m_scheme = NULL; } -// ---------------------------------------------------------------------------- +wxWin32Theme::~wxWin32Theme() +{ + WX_CLEAR_ARRAY(m_handlers); +} + +wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control) +{ + wxInputHandler *handler; + int n = m_handlerNames.Index(control); + if ( n == wxNOT_FOUND ) + { + // create a new handler + n = m_handlerNames.Add(control); + + if ( control == wxCONTROL_BUTTON ) + handler = new wxWin32ButtonInputHandler; + else + { + wxASSERT_MSG( control == wxCONTROL_DEFAULT, + _T("no input handler defined for this control") ); + + handler = new wxWin32InputHandler; + } + + m_handlers.Insert(handler, n); + } + else // we already have it + { + handler = m_handlers[n]; + } + + return handler; +} + +// ============================================================================ // wxWin32Renderer -// ---------------------------------------------------------------------------- +// ============================================================================ // ---------------------------------------------------------------------------- // construction @@ -493,19 +563,19 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window) { case wxBORDER_SUNKEN: case wxBORDER_RAISED: - size->x += 2; - size->y += 2; + size->x += 4; + size->y += 4; break; case wxBORDER_SIMPLE: case wxBORDER_STATIC: - size->x++; - size->y++; + size->x += 2; + size->y += 2; break; case wxBORDER_DOUBLE: - size->x += 3; - size->y += 3; + size->x += 6; + size->y += 6; break; default: @@ -518,3 +588,62 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window) } } } + +// ============================================================================ +// wxInputHandler +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxWin32InputHandler +// ---------------------------------------------------------------------------- + +wxControlAction wxWin32InputHandler::Map(const wxKeyEvent& event, bool pressed) +{ + return wxACTION_NONE; +} + +wxControlAction wxWin32InputHandler::Map(const wxMouseEvent& event) +{ + return wxACTION_NONE; +} + +// ---------------------------------------------------------------------------- +// wxWin32ButtonInputHandler +// ---------------------------------------------------------------------------- + +wxWin32ButtonInputHandler::wxWin32ButtonInputHandler() +{ + m_winCapture = NULL; +} + +wxControlAction wxWin32ButtonInputHandler::Map(const wxKeyEvent& event, + bool pressed) +{ + int keycode = event.GetKeyCode(); + if ( keycode == WXK_SPACE || keycode == WXK_RETURN ) + { + return wxACTION_BUTTON_TOGGLE; + } + + return wxWin32InputHandler::Map(event, pressed); +} + +wxControlAction wxWin32ButtonInputHandler::Map(const wxMouseEvent& event) +{ + if ( event.IsButton() ) + { + if ( event.ButtonDown() ) + { + m_winCapture = wxWindow::FindFocus(); + m_winCapture->CaptureMouse(); + } + else // up + { + m_winCapture->ReleaseMouse(); + } + + return wxACTION_BUTTON_TOGGLE; + } + + return wxWin32InputHandler::Map(event); +}