From 813edf09b3457f4b3298c8353cb623cb7e49bc89 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Fri, 28 Sep 2001 23:39:55 +0000 Subject: [PATCH] input handling in wxTLW/Univ git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11731 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/univ/inpcons.h | 6 +- include/wx/univ/inphand.h | 1 + include/wx/univ/renderer.h | 17 +++- include/wx/univ/toplevel.h | 88 ++++++++++++-------- src/univ/themes/gtk.cpp | 15 +++- src/univ/themes/win32.cpp | 150 ++++++++++++++++++++++++++++------ src/univ/topluniv.cpp | 160 ++++++++++++++++++++++++++++++++++--- 7 files changed, 362 insertions(+), 75 deletions(-) diff --git a/include/wx/univ/inpcons.h b/include/wx/univ/inpcons.h index bd099c0cd0..4920a8f32c 100644 --- a/include/wx/univ/inpcons.h +++ b/include/wx/univ/inpcons.h @@ -90,7 +90,9 @@ private: \ void OnKeyDown(wxKeyEvent& event); \ void OnKeyUp(wxKeyEvent& event); \ void OnFocus(wxFocusEvent& event); \ - void OnActivate(wxActivateEvent& event); +public: /* because of docview :-( */ \ + void OnActivate(wxActivateEvent& event); \ +private: // implement the event table entries for wxControlContainer #define WX_EVENT_TABLE_INPUT_CONSUMER(classname) \ @@ -134,7 +136,7 @@ private: \ void classname::OnActivate(wxActivateEvent& event) \ { \ wxInputConsumer::OnActivate(event); \ - } + } \ #endif // _WX_UNIV_INPCONS_H_ diff --git a/include/wx/univ/inphand.h b/include/wx/univ/inphand.h index aa675e37ff..d26a6e9ea4 100644 --- a/include/wx/univ/inphand.h +++ b/include/wx/univ/inphand.h @@ -36,6 +36,7 @@ #define wxINP_HANDLER_SLIDER _T("slider") #define wxINP_HANDLER_SPINBTN _T("spinbtn") #define wxINP_HANDLER_TEXTCTRL _T("textctrl") +#define wxINP_HANDLER_TOPLEVEL _T("toplevel") // ---------------------------------------------------------------------------- // wxInputHandler: maps the events to the actions diff --git a/include/wx/univ/renderer.h b/include/wx/univ/renderer.h index e71426e6ee..cfcdccf9c8 100644 --- a/include/wx/univ/renderer.h +++ b/include/wx/univ/renderer.h @@ -251,7 +251,8 @@ public: const wxString& title, const wxIcon& icon, int flags, - int pressedButtons = 0) = 0; + int specialButton = 0, + int specialButtonFlags = 0) = 0; // draw frame borders virtual void DrawFrameBorder(wxDC& dc, @@ -392,6 +393,10 @@ public: virtual wxSize GetFrameTotalSize(const wxSize& clientSize, int flags) const = 0; // get titlebar icon size virtual wxSize GetFrameIconSize() const = 0; + // returns one of wxHT_TOPLEVEL_XXX constants + virtual int HitTestFrame(const wxRect& rect, + const wxPoint& pt, + int flags) const = 0; // virtual dtor for any base class virtual ~wxRenderer(); @@ -622,8 +627,10 @@ public: const wxString& title, const wxIcon& icon, int flags, - int pressedButtons = 0) - { m_renderer->DrawFrameTitleBar(dc, rect, title, icon, flags, pressedButtons); } + int specialButton = 0, + int specialButtonFlag = 0) + { m_renderer->DrawFrameTitleBar(dc, rect, title, icon, flags, + specialButton, specialButtonFlag); } virtual void DrawFrameBorder(wxDC& dc, const wxRect& rect, int flags) @@ -723,6 +730,10 @@ public: { return m_renderer->GetFrameTotalSize(clientSize, flags); } virtual wxSize GetFrameIconSize() const { return m_renderer->GetFrameIconSize(); } + virtual int HitTestFrame(const wxRect& rect, + const wxPoint& pt, + int flags) const + { return m_renderer->HitTestFrame(rect, pt, flags); } protected: wxRenderer *m_renderer; diff --git a/include/wx/univ/toplevel.h b/include/wx/univ/toplevel.h index b8b8ebfa7d..4c99fc95e2 100644 --- a/include/wx/univ/toplevel.h +++ b/include/wx/univ/toplevel.h @@ -23,54 +23,57 @@ // ---------------------------------------------------------------------------- // frame decorations type flags used in wxRenderer and wxColourScheme -// (also used for hit tests) enum { wxTOPLEVEL_ACTIVE = 0x00000001, wxTOPLEVEL_MAXIMIZED = 0x00000002, wxTOPLEVEL_TITLEBAR = 0x00000004, - wxTOPLEVEL_RESIZEABLE = 0x00000008, - wxTOPLEVEL_ICON = 0x00000010, - wxTOPLEVEL_BUTTON_CLOSE = 0x00000020, - wxTOPLEVEL_BUTTON_MAXIMIZE = 0x00000040, - wxTOPLEVEL_BUTTON_MINIMIZE = 0x00000080, - wxTOPLEVEL_BUTTON_RESTORE = 0x00000100, - wxTOPLEVEL_BUTTON_HELP = 0x00000200, - wxTOPLEVEL_BORDER = 0x00000400, + wxTOPLEVEL_ICON = 0x00000009, + wxTOPLEVEL_RESIZEABLE = 0x00000010, + wxTOPLEVEL_BORDER = 0x00000020, + wxTOPLEVEL_BUTTON_CLOSE = 0x01000000, + wxTOPLEVEL_BUTTON_MAXIMIZE = 0x02000000, + wxTOPLEVEL_BUTTON_ICONIZE = 0x04000000, + wxTOPLEVEL_BUTTON_RESTORE = 0x08000000, + wxTOPLEVEL_BUTTON_HELP = 0x10000000, }; // frame hit test return values: enum { - wxHT_TOPLEVEL_NOWHERE = 0, - wxHT_TOPLEVEL_CLIENT_AREA, - wxHT_TOPLEVEL_ICON, - wxHT_TOPLEVEL_TITLEBAR, - wxHT_TOPLEVEL_BUTTON_CLOSE = wxTOPLEVEL_BUTTON_CLOSE, - wxHT_TOPLEVEL_BUTTON_MAXIMIZE = wxTOPLEVEL_BUTTON_MAXIMIZE, - wxHT_TOPLEVEL_BUTTON_MINIMIZE = wxTOPLEVEL_BUTTON_MINIMIZE, - wxHT_TOPLEVEL_BUTTON_RESTORE = wxTOPLEVEL_BUTTON_RESTORE, - wxHT_TOPLEVEL_BUTTON_HELP = wxTOPLEVEL_BUTTON_HELP, - wxHT_TOPLEVEL_BORDER_N, - wxHT_TOPLEVEL_BORDER_S, - wxHT_TOPLEVEL_BORDER_E, - wxHT_TOPLEVEL_BORDER_W, - wxHT_TOPLEVEL_BORDER_NE = wxHT_TOPLEVEL_BORDER_N | wxHT_TOPLEVEL_BORDER_E, - wxHT_TOPLEVEL_BORDER_SE = wxHT_TOPLEVEL_BORDER_S | wxHT_TOPLEVEL_BORDER_E, - wxHT_TOPLEVEL_BORDER_NW = wxHT_TOPLEVEL_BORDER_N | wxHT_TOPLEVEL_BORDER_W, - wxHT_TOPLEVEL_BORDER_SW = wxHT_TOPLEVEL_BORDER_S | wxHT_TOPLEVEL_BORDER_W, + wxHT_TOPLEVEL_NOWHERE = 0x00000000, + wxHT_TOPLEVEL_CLIENT_AREA = 0x00000001, + wxHT_TOPLEVEL_ICON = 0x00000002, + wxHT_TOPLEVEL_TITLEBAR = 0x00000004, + + wxHT_TOPLEVEL_BORDER_N = 0x00000010, + wxHT_TOPLEVEL_BORDER_S = 0x00000020, + wxHT_TOPLEVEL_BORDER_E = 0x00000040, + wxHT_TOPLEVEL_BORDER_W = 0x00000080, + wxHT_TOPLEVEL_ANY_BORDER = 0x000000F0, + wxHT_TOPLEVEL_BORDER_NE = wxHT_TOPLEVEL_BORDER_N | wxHT_TOPLEVEL_BORDER_E, + wxHT_TOPLEVEL_BORDER_SE = wxHT_TOPLEVEL_BORDER_S | wxHT_TOPLEVEL_BORDER_E, + wxHT_TOPLEVEL_BORDER_NW = wxHT_TOPLEVEL_BORDER_N | wxHT_TOPLEVEL_BORDER_W, + wxHT_TOPLEVEL_BORDER_SW = wxHT_TOPLEVEL_BORDER_S | wxHT_TOPLEVEL_BORDER_W, + + wxHT_TOPLEVEL_BUTTON_CLOSE = /*0x01000000*/ wxTOPLEVEL_BUTTON_CLOSE, + wxHT_TOPLEVEL_BUTTON_MAXIMIZE = /*0x02000000*/ wxTOPLEVEL_BUTTON_MAXIMIZE, + wxHT_TOPLEVEL_BUTTON_ICONIZE = /*0x04000000*/ wxTOPLEVEL_BUTTON_ICONIZE, + wxHT_TOPLEVEL_BUTTON_RESTORE = /*0x08000000*/ wxTOPLEVEL_BUTTON_RESTORE, + wxHT_TOPLEVEL_BUTTON_HELP = /*0x10000000*/ wxTOPLEVEL_BUTTON_HELP, + wxHT_TOPLEVEL_ANY_BUTTON = 0x1F000000 }; // ---------------------------------------------------------------------------- // the actions supported by this control // ---------------------------------------------------------------------------- -#define wxACTION_TOPLEVEL_ACTIVATE _T("activate") // (de)activate the frame -#define wxACTION_TOPLEVEL_CLOSE _T("close") // close the frame -#define wxACTION_TOPLEVEL_MAXIMIZE _T("maximize") // maximize the frame -#define wxACTION_TOPLEVEL_MINIMIZE _T("minimize") // minimize the frame -#define wxACTION_TOPLEVEL_RESTORE _T("restore") // undo maximization -#define wxACTION_TOPLEVEL_CONTEXT_HELP _T("contexthelp")// context help mode +#define wxACTION_TOPLEVEL_ACTIVATE _T("activate") // (de)activate the frame +#define wxACTION_TOPLEVEL_BUTTON_PRESS _T("pressbtn") // press titlebar btn +#define wxACTION_TOPLEVEL_BUTTON_RELEASE _T("releasebtn") // press titlebar btn +#define wxACTION_TOPLEVEL_BUTTON_CLICK _T("clickbtn") // press titlebar btn +#define wxACTION_TOPLEVEL_MOVE _T("move") // move the frame +#define wxACTION_TOPLEVEL_RESIZE _T("resize") // resize the frame //----------------------------------------------------------------------------- // wxTopLevelWindow @@ -112,19 +115,26 @@ public: // implementation from now on // -------------------------- + + // tests for frame's part at given point + long HitTest(const wxPoint& pt) const; protected: virtual bool PerformAction(const wxControlAction& action, long numArg = -1, const wxString& strArg = wxEmptyString); - virtual wxWindow *GetInputWindow() const { return (wxWindow*)this; } + // handle titlebar button click event + virtual void ClickTitleBarButton(long button); - // common part of all ctors - void Init(); + virtual wxWindow *GetInputWindow() const { return (wxWindow*)this; } // return wxTOPLEVEL_xxx combination based on current state of the frame long GetDecorationsStyle() const; + + // common part of all ctors + void Init(); + void RefreshTitleBar(); void OnNcPaint(wxPaintEvent& event); // TRUE if wxTLW should render decorations (aka titlebar) itself @@ -135,6 +145,8 @@ protected: wxIcon m_titlebarIcon; // saved window style in fullscreen mdoe long m_fsSavedStyle; + // currently pressed titlebar button + long m_pressedButton; DECLARE_DYNAMIC_CLASS(wxTopLevelWindow) DECLARE_EVENT_TABLE() @@ -154,6 +166,12 @@ public: const wxMouseEvent& event); virtual bool HandleMouseMove(wxInputConsumer *consumer, const wxMouseEvent& event); virtual bool HandleActivation(wxInputConsumer *consumer, bool activated); + +private: + // the window (button) which has capture or NULL and the last hittest result + wxTopLevelWindow *m_winCapture; + long m_winHitTest; + long m_winPressed; }; #endif // __WX_UNIV_TOPLEVEL_H__ diff --git a/src/univ/themes/gtk.cpp b/src/univ/themes/gtk.cpp index 9287b7390d..776d9cd4e7 100644 --- a/src/univ/themes/gtk.cpp +++ b/src/univ/themes/gtk.cpp @@ -48,6 +48,7 @@ #include "wx/univ/inphand.h" #include "wx/univ/colschem.h" #include "wx/univ/theme.h" +#include "wx/toplevel.h" // ---------------------------------------------------------------------------- // constants (to be removed, for testing only) @@ -211,7 +212,8 @@ public: const wxString& title, const wxIcon& icon, int flags, - int pressedButtons = 0); + int specialButton = 0, + int specialButtonFlag = 0); virtual void DrawFrameBorder(wxDC& dc, const wxRect& rect, int flags); @@ -235,6 +237,7 @@ public: virtual wxRect GetFrameClientArea(const wxRect& rect, int flags) const; virtual wxSize GetFrameTotalSize(const wxSize& clientSize, int flags) const; virtual wxSize GetFrameIconSize() const; + virtual int HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const; virtual void GetComboBitmaps(wxBitmap *bmpNormal, wxBitmap *bmpFocus, @@ -649,6 +652,8 @@ wxInputHandler *wxGTKTheme::GetInputHandler(const wxString& control) else if ( control == wxINP_HANDLER_NOTEBOOK ) handler = new wxStdNotebookInputHandler(GetDefaultInputHandler()); #endif // wxUSE_NOTEBOOK + else if ( control == wxINP_HANDLER_TOPLEVEL ) + handler = new wxStdFrameInputHandler(GetDefaultInputHandler()); else handler = GetDefaultInputHandler(); @@ -2379,7 +2384,8 @@ void wxGTKRenderer::DrawFrameTitleBar(wxDC& dc, const wxString& title, const wxIcon& icon, int flags, - int pressedButtons) + int specialButton, + int specialButtonFlag) { } @@ -2431,6 +2437,11 @@ wxSize wxGTKRenderer::GetFrameIconSize() const return wxSize(-1, -1); } +int wxGTKRenderer::HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const +{ + return wxHT_TOPLEVEL_CLIENT_AREA; +} + // ============================================================================ diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index a25e8d8f6c..50d6994343 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -280,7 +280,8 @@ public: const wxString& title, const wxIcon& icon, int flags, - int pressedButtons = 0); + int specialButton = 0, + int specialButtonFlags = 0); virtual void DrawFrameBorder(wxDC& dc, const wxRect& rect, int flags); @@ -302,6 +303,7 @@ public: virtual wxRect GetFrameClientArea(const wxRect& rect, int flags) const; virtual wxSize GetFrameTotalSize(const wxSize& clientSize, int flags) const; virtual wxSize GetFrameIconSize() const; + virtual int HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const; virtual void GetComboBitmaps(wxBitmap *bmpNormal, wxBitmap *bmpFocus, @@ -1150,6 +1152,8 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control) else if ( control == wxINP_HANDLER_NOTEBOOK ) handler = new wxStdNotebookInputHandler(GetDefaultInputHandler()); #endif // wxUSE_NOTEBOOK + else if ( control == wxINP_HANDLER_TOPLEVEL ) + handler = new wxStdFrameInputHandler(GetDefaultInputHandler()); else handler = GetDefaultInputHandler(); @@ -3097,12 +3101,91 @@ int wxWin32Renderer::PixelToScrollbar(const wxScrollBar *scrollbar, // top level windows // ---------------------------------------------------------------------------- +int wxWin32Renderer::HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const +{ + wxRect client = GetFrameClientArea(rect, flags); + + if ( client.Inside(pt) ) + return wxHT_TOPLEVEL_CLIENT_AREA; + + if ( flags & wxTOPLEVEL_TITLEBAR ) + { + wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); + + if ( flags & wxTOPLEVEL_ICON ) + { + if ( wxRect(client.GetPosition(), GetFrameIconSize()).Inside(pt) ) + return wxHT_TOPLEVEL_ICON; + } + + wxRect btnRect(client.GetRight() - 2 - FRAME_BUTTON_WIDTH, + client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2, + FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT); + + if ( flags & wxTOPLEVEL_BUTTON_CLOSE ) + { + if ( btnRect.Inside(pt) ) + return wxHT_TOPLEVEL_BUTTON_CLOSE; + btnRect.x -= FRAME_BUTTON_WIDTH + 2; + } + if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE ) + { + if ( btnRect.Inside(pt) ) + return wxHT_TOPLEVEL_BUTTON_MAXIMIZE; + btnRect.x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_BUTTON_RESTORE ) + { + if ( btnRect.Inside(pt) ) + return wxHT_TOPLEVEL_BUTTON_RESTORE; + btnRect.x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_BUTTON_ICONIZE ) + { + if ( btnRect.Inside(pt) ) + return wxHT_TOPLEVEL_BUTTON_ICONIZE; + btnRect.x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_BUTTON_HELP ) + { + if ( btnRect.Inside(pt) ) + return wxHT_TOPLEVEL_BUTTON_HELP; + btnRect.x -= FRAME_BUTTON_WIDTH; + } + + if ( pt.y < client.y + FRAME_TITLEBAR_HEIGHT ) + return wxHT_TOPLEVEL_TITLEBAR; + } + + if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) ) + { + // we are certainly at one of borders, lets decide which one: + + wxCoord midX = client.x + client.width/2, + midY = client.y + client.height/2; + int border = 0; + // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined! + if ( pt.x < midX ) + border |= wxHT_TOPLEVEL_BORDER_W; + else + border |= wxHT_TOPLEVEL_BORDER_E; + if ( pt.y < midY ) + border |= wxHT_TOPLEVEL_BORDER_N; + else + border |= wxHT_TOPLEVEL_BORDER_S; + return border; + } + + return wxHT_NOWHERE; +} + void wxWin32Renderer::DrawFrameTitleBar(wxDC& dc, const wxRect& rect, const wxString& title, const wxIcon& icon, int flags, - int pressedButtons) + int specialButton, + int specialButtonFlags) { if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) ) { @@ -3117,32 +3200,42 @@ void wxWin32Renderer::DrawFrameTitleBar(wxDC& dc, wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); wxCoord x,y; - x = client.GetRight() -2 - FRAME_BUTTON_WIDTH; + x = client.GetRight() - 2 - FRAME_BUTTON_WIDTH; y = client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2; - if ( flags & wxTOPLEVEL_CLOSE_BUTTON ) + if ( flags & wxTOPLEVEL_BUTTON_CLOSE ) { - DrawFrameButton(dc, x, y, wxTOPLEVEL_CLOSE_BUTTON); + DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_CLOSE, + (specialButton == wxTOPLEVEL_BUTTON_CLOSE) ? + specialButtonFlags : 0); x -= FRAME_BUTTON_WIDTH + 2; } - if ( flags & wxTOPLEVEL_MAXIMIZE_BUTTON ) + if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE ) { - DrawFrameButton(dc, x, y, wxTOPLEVEL_MAXIMIZE_BUTTON); + DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_MAXIMIZE, + (specialButton == wxTOPLEVEL_BUTTON_MAXIMIZE) ? + specialButtonFlags : 0); x -= FRAME_BUTTON_WIDTH; } - if ( flags & wxTOPLEVEL_RESTORE_BUTTON ) + if ( flags & wxTOPLEVEL_BUTTON_RESTORE ) { - DrawFrameButton(dc, x, y, wxTOPLEVEL_RESTORE_BUTTON); + DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_RESTORE, + (specialButton == wxTOPLEVEL_BUTTON_RESTORE) ? + specialButtonFlags : 0); x -= FRAME_BUTTON_WIDTH; } - if ( flags & wxTOPLEVEL_MINIMIZE_BUTTON ) + if ( flags & wxTOPLEVEL_BUTTON_ICONIZE ) { - DrawFrameButton(dc, x, y, wxTOPLEVEL_MINIMIZE_BUTTON); + DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_ICONIZE, + (specialButton == wxTOPLEVEL_BUTTON_ICONIZE) ? + specialButtonFlags : 0); x -= FRAME_BUTTON_WIDTH; } - if ( flags & wxTOPLEVEL_HELP_BUTTON ) + if ( flags & wxTOPLEVEL_BUTTON_HELP ) { - DrawFrameButton(dc, x, y, wxTOPLEVEL_HELP_BUTTON); + DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_HELP, + (specialButton == wxTOPLEVEL_BUTTON_HELP) ? + specialButtonFlags : 0); x -= FRAME_BUTTON_WIDTH; } } @@ -3211,24 +3304,33 @@ void wxWin32Renderer::DrawFrameButton(wxDC& dc, int flags) { wxRect r(x, y, FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT); - - DrawShadedRect(dc, &r, m_penHighlight, m_penBlack); - DrawShadedRect(dc, &r, m_penLightGrey, m_penDarkGrey); - DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), r); - + size_t idx = 0; switch (button) { - case wxTOPLEVEL_CLOSE_BUTTON: idx = FrameButton_Close; break; - case wxTOPLEVEL_MAXIMIZE_BUTTON: idx = FrameButton_Maximize; break; - case wxTOPLEVEL_MINIMIZE_BUTTON: idx = FrameButton_Minimize; break; - case wxTOPLEVEL_RESTORE_BUTTON: idx = FrameButton_Restore; break; - case wxTOPLEVEL_HELP_BUTTON: idx = FrameButton_Help; break; + case wxTOPLEVEL_BUTTON_CLOSE: idx = FrameButton_Close; break; + case wxTOPLEVEL_BUTTON_MAXIMIZE: idx = FrameButton_Maximize; break; + case wxTOPLEVEL_BUTTON_ICONIZE: idx = FrameButton_Minimize; break; + case wxTOPLEVEL_BUTTON_RESTORE: idx = FrameButton_Restore; break; + case wxTOPLEVEL_BUTTON_HELP: idx = FrameButton_Help; break; default: wxFAIL_MSG(wxT("incorrect button specification")); } - dc.DrawBitmap(m_bmpFrameButtons[idx], r.x, r.y, TRUE); + if ( flags & wxCONTROL_PRESSED ) + { + DrawShadedRect(dc, &r, m_penBlack, m_penHighlight); + DrawShadedRect(dc, &r, m_penDarkGrey, m_penLightGrey); + DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), r); + dc.DrawBitmap(m_bmpFrameButtons[idx], r.x+1, r.y+1, TRUE); + } + else + { + DrawShadedRect(dc, &r, m_penHighlight, m_penBlack); + DrawShadedRect(dc, &r, m_penLightGrey, m_penDarkGrey); + DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), r); + dc.DrawBitmap(m_bmpFrameButtons[idx], r.x, r.y, TRUE); + } } diff --git a/src/univ/topluniv.cpp b/src/univ/topluniv.cpp index d79c39eba3..625ec55828 100644 --- a/src/univ/topluniv.cpp +++ b/src/univ/topluniv.cpp @@ -31,6 +31,7 @@ #include "wx/dcclient.h" #include "wx/bitmap.h" #include "wx/image.h" +#include "wx/cshelp.h" // ---------------------------------------------------------------------------- @@ -55,6 +56,7 @@ void wxTopLevelWindow::Init() { m_isActive = FALSE; m_windowStyle = 0; + m_pressedButton = 0; } bool wxTopLevelWindow::Create(wxWindow *parent, @@ -80,12 +82,12 @@ bool wxTopLevelWindow::Create(wxWindow *parent, styleOrig = style; exstyleOrig = GetExtraStyle(); -// style &= ~(wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | -// wxSYSTEM_MENU | wxRESIZE_BORDER | wxFRAME_TOOL_WINDOW | -// wxTHICK_FRAME); -// style = wxSIMPLE_BORDER; -// SetExtraStyle(exstyleOrig & -// ~(wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP)); + style &= ~(wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | + wxSYSTEM_MENU | wxRESIZE_BORDER | wxFRAME_TOOL_WINDOW | + wxTHICK_FRAME); + style = wxSIMPLE_BORDER; + SetExtraStyle(exstyleOrig & + ~(wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP)); } if ( !wxTopLevelWindowNative::Create(parent, id, title, pos, @@ -132,11 +134,13 @@ long wxTopLevelWindow::GetDecorationsStyle() const { style |= wxTOPLEVEL_TITLEBAR | wxTOPLEVEL_BUTTON_CLOSE; if ( m_windowStyle & wxMINIMIZE_BOX ) - style |= wxTOPLEVEL_BUTTON_MINIMIZE; + style |= wxTOPLEVEL_BUTTON_ICONIZE; if ( m_windowStyle & wxMAXIMIZE_BOX ) style |= wxTOPLEVEL_BUTTON_MAXIMIZE; +#if wxUSE_HELP if ( m_exStyle & (wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP)) style |= wxTOPLEVEL_BUTTON_HELP; +#endif } if ( (m_windowStyle & (wxSIMPLE_BORDER | wxNO_BORDER)) == 0 ) style |= wxTOPLEVEL_BORDER; @@ -153,6 +157,13 @@ long wxTopLevelWindow::GetDecorationsStyle() const return style; } +void wxTopLevelWindow::RefreshTitleBar() +{ + wxNcPaintEvent event(GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); +} + // ---------------------------------------------------------------------------- // client area handling // ---------------------------------------------------------------------------- @@ -223,10 +234,21 @@ void wxTopLevelWindow::OnNcPaint(wxPaintEvent& event) wxWindowDC dc(this); m_renderer->DrawFrameTitleBar(dc, rect, GetTitle(), m_titlebarIcon, - GetDecorationsStyle()); + GetDecorationsStyle(), + m_pressedButton, + wxCONTROL_PRESSED); } } +long wxTopLevelWindow::HitTest(const wxPoint& pt) const +{ + int w, h; + wxTopLevelWindowNative::DoGetClientSize(&w, &h); + wxRect rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w, h)); + + return m_renderer->HitTestFrame(rect, pt, GetDecorationsStyle()); +} + // ---------------------------------------------------------------------------- // icons // ---------------------------------------------------------------------------- @@ -261,6 +283,39 @@ void wxTopLevelWindow::SetIcon(const wxIcon& icon) // actions // ---------------------------------------------------------------------------- +void wxTopLevelWindow::ClickTitleBarButton(long button) +{ + switch ( button ) + { + case wxTOPLEVEL_BUTTON_CLOSE: + Close(); + break; + + case wxTOPLEVEL_BUTTON_ICONIZE: + Iconize(); + break; + + case wxTOPLEVEL_BUTTON_MAXIMIZE: + Maximize(); + break; + + case wxTOPLEVEL_BUTTON_RESTORE: + Restore(); + break; + + case wxTOPLEVEL_BUTTON_HELP: +#if wxUSE_HELP + { + wxContextHelp contextHelp(this); + } +#endif + break; + + default: + wxFAIL_MSG(wxT("incorrect button specification")); + } +} + bool wxTopLevelWindow::PerformAction(const wxControlAction& action, long numArg, const wxString& strArg) @@ -274,10 +329,32 @@ bool wxTopLevelWindow::PerformAction(const wxControlAction& action, wxNcPaintEvent event(GetId()); event.SetEventObject(this); GetEventHandler()->ProcessEvent(event); - printf("activation: %i\n", m_isActive); } return TRUE; } + + else if ( action == wxACTION_TOPLEVEL_BUTTON_PRESS ) + { + m_pressedButton = numArg; + RefreshTitleBar(); + return TRUE; + } + + else if ( action == wxACTION_TOPLEVEL_BUTTON_RELEASE ) + { + m_pressedButton = 0; + RefreshTitleBar(); + return TRUE; + } + + else if ( action == wxACTION_TOPLEVEL_BUTTON_CLICK ) + { + m_pressedButton = 0; + RefreshTitleBar(); + ClickTitleBarButton(numArg); + return TRUE; + } + else return FALSE; } @@ -290,17 +367,82 @@ bool wxTopLevelWindow::PerformAction(const wxControlAction& action, wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler *inphand) : wxStdInputHandler(inphand) { + m_winCapture = NULL; + m_winHitTest = 0; + m_winPressed = 0; } bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer *consumer, const wxMouseEvent& event) { + // the button has 2 states: pressed and normal with the following + // transitions between them: + // + // normal -> left down -> capture mouse and go to pressed state + // pressed -> left up inside -> generate click -> go to normal + // outside ------------------> + // + // the other mouse buttons are ignored + if ( event.Button(1) ) + { + if ( event.ButtonDown(1) ) + { + wxTopLevelWindow *w = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow); + long hit = w->HitTest(event.GetPosition()); + + if ( hit & wxHT_TOPLEVEL_ANY_BUTTON ) + { + m_winCapture = w; + m_winCapture->CaptureMouse(); + m_winHitTest = hit; + m_winPressed = hit; + consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed); + return TRUE; + } + } + + else // up + { + if ( m_winCapture ) + { + m_winCapture->ReleaseMouse(); + m_winCapture = NULL; + + if ( m_winHitTest == m_winPressed ) + { + consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK, m_winPressed); + return TRUE; + } + } + //else: the mouse was released outside the window, this doesn't + // count as a click + } + } + return wxStdInputHandler::HandleMouse(consumer, event); } bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer *consumer, const wxMouseEvent& event) { + // we only have to do something when the mouse leaves/enters the pressed + // button and don't care about the other ones + if ( event.GetEventObject() == m_winCapture ) + { + long hit = m_winCapture->HitTest(event.GetPosition()); + + if ( hit != m_winHitTest ) + { + if ( hit != m_winPressed ) + consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE, m_winPressed); + else + consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed); + + m_winHitTest = hit; + return TRUE; + } + } + return wxStdInputHandler::HandleMouseMove(consumer, event); } -- 2.45.2