]> git.saurik.com Git - wxWidgets.git/commitdiff
input handling in wxTLW/Univ
authorVáclav Slavík <vslavik@fastmail.fm>
Fri, 28 Sep 2001 23:39:55 +0000 (23:39 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Fri, 28 Sep 2001 23:39:55 +0000 (23:39 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11731 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/univ/inpcons.h
include/wx/univ/inphand.h
include/wx/univ/renderer.h
include/wx/univ/toplevel.h
src/univ/themes/gtk.cpp
src/univ/themes/win32.cpp
src/univ/topluniv.cpp

index bd099c0cd0cd72109ce88379fa63347113f0be1d..4920a8f32c4e002492e62c519d5ab5371526c27d 100644 (file)
@@ -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_
index aa675e37ffcc24efa7f38ed3ead59763a6ad8052..d26a6e9ea452a7194e09f5209319f899ff392cc6 100644 (file)
@@ -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
index e71426e6eedd9b32b117fc3717dbc5e845b62a27..cfcdccf9c8b6b80627ac7e3eb8a2228d3186a62d 100644 (file)
@@ -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;
index b8b8ebfa7d2bc4edcee0a51851edeba474edb303..4c99fc95e2d82312106e56778e699e0ca8c1b5ff 100644 (file)
 // ----------------------------------------------------------------------------
 
 // 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__
index 9287b7390d30f79a1836096d618cd578656119b1..776d9cd4e70b184d53f9d9d98f5b002cb8a504ee 100644 (file)
@@ -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;
+}
+
 
 
 // ============================================================================
index a25e8d8f6cc8fad4ee4dfa9c98b3f02380984b5a..50d699434311d9a67a140972a061a41037bd4603 100644 (file)
@@ -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);
+    }
 }
 
 
index d79c39eba32ba3f0d92d534643230f4170308731..625ec55828c89f8a9b6d3f3f6617ef9b28791c27 100644 (file)
@@ -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);
 }