]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/topluniv.cpp
toplevel fixes
[wxWidgets.git] / src / univ / topluniv.cpp
index 6d2d646db2d9f9c32ed8738b679fbc9f13ae7d38..625ec55828c89f8a9b6d3f3f6617ef9b28791c27 100644 (file)
@@ -31,6 +31,7 @@
 #include "wx/dcclient.h"
 #include "wx/bitmap.h"
 #include "wx/image.h"
 #include "wx/dcclient.h"
 #include "wx/bitmap.h"
 #include "wx/image.h"
+#include "wx/cshelp.h"
 
 
 // ----------------------------------------------------------------------------
 
 
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 
 BEGIN_EVENT_TABLE(wxTopLevelWindow, wxTopLevelWindowNative)
 // ----------------------------------------------------------------------------
 
 BEGIN_EVENT_TABLE(wxTopLevelWindow, wxTopLevelWindowNative)
+    WX_EVENT_TABLE_INPUT_CONSUMER(wxTopLevelWindow)
     EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint)
 END_EVENT_TABLE()
 
     EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint)
 END_EVENT_TABLE()
 
+WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow)
+
 
 // ============================================================================
 // implementation
 
 // ============================================================================
 // implementation
@@ -51,6 +55,8 @@ int wxTopLevelWindow::ms_drawDecorations = -1;
 void wxTopLevelWindow::Init()
 {
     m_isActive = FALSE;
 void wxTopLevelWindow::Init()
 {
     m_isActive = FALSE;
+    m_windowStyle = 0;
+    m_pressedButton = 0;
 }
 
 bool wxTopLevelWindow::Create(wxWindow *parent,
 }
 
 bool wxTopLevelWindow::Create(wxWindow *parent,
@@ -72,6 +78,8 @@ bool wxTopLevelWindow::Create(wxWindow *parent,
 
     if ( ms_drawDecorations )
     {
 
     if ( ms_drawDecorations )
     {
+        CreateInputHandler(wxINP_HANDLER_TOPLEVEL);
+
         styleOrig = style;
         exstyleOrig = GetExtraStyle();
         style &= ~(wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | 
         styleOrig = style;
         exstyleOrig = GetExtraStyle();
         style &= ~(wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | 
@@ -97,17 +105,25 @@ bool wxTopLevelWindow::Create(wxWindow *parent,
 
 bool wxTopLevelWindow::ShowFullScreen(bool show, long style)
 {
 
 bool wxTopLevelWindow::ShowFullScreen(bool show, long style)
 {
-    // VZ: doesn't compile
-#if 0
     if ( show == IsFullScreen() ) return FALSE;
     
     if ( show == IsFullScreen() ) return FALSE;
     
-    return wxTopLevelWindowNative::ShowFullScreen(show, style);
-    
-    // FIXME_MGL -- must handle caption hiding here if not in
-    //              native decorations mode
-#endif // 0
+    if ( ms_drawDecorations )
+    {
+        if ( show )
+        {
+            m_fsSavedStyle = m_windowStyle;
+            if ( style & wxFULLSCREEN_NOBORDER )
+                m_windowStyle |= wxSIMPLE_BORDER;
+            if ( style & wxFULLSCREEN_NOCAPTION )
+                m_windowStyle &= ~wxCAPTION;
+        }
+        else
+        {
+            m_windowStyle = m_fsSavedStyle;
+        }
+    }
 
 
-    return FALSE;
+    return wxTopLevelWindowNative::ShowFullScreen(show, style);
 }
 
 long wxTopLevelWindow::GetDecorationsStyle() const
 }
 
 long wxTopLevelWindow::GetDecorationsStyle() const
@@ -116,13 +132,15 @@ long wxTopLevelWindow::GetDecorationsStyle() const
 
     if ( m_windowStyle & wxCAPTION )
     {
 
     if ( m_windowStyle & wxCAPTION )
     {
-        style |= wxTOPLEVEL_TITLEBAR | wxTOPLEVEL_CLOSE_BUTTON;
+        style |= wxTOPLEVEL_TITLEBAR | wxTOPLEVEL_BUTTON_CLOSE;
         if ( m_windowStyle & wxMINIMIZE_BOX )
         if ( m_windowStyle & wxMINIMIZE_BOX )
-            style |= wxTOPLEVEL_MINIMIZE_BUTTON;
+            style |= wxTOPLEVEL_BUTTON_ICONIZE;
         if ( m_windowStyle & wxMAXIMIZE_BOX )
         if ( m_windowStyle & wxMAXIMIZE_BOX )
-            style |= wxTOPLEVEL_MAXIMIZE_BUTTON;
+            style |= wxTOPLEVEL_BUTTON_MAXIMIZE;
+#if wxUSE_HELP
         if ( m_exStyle & (wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP))
         if ( m_exStyle & (wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP))
-            style |= wxTOPLEVEL_HELP_BUTTON;
+            style |= wxTOPLEVEL_BUTTON_HELP;
+#endif
     }
     if ( (m_windowStyle & (wxSIMPLE_BORDER | wxNO_BORDER)) == 0 )
         style |= wxTOPLEVEL_BORDER;
     }
     if ( (m_windowStyle & (wxSIMPLE_BORDER | wxNO_BORDER)) == 0 )
         style |= wxTOPLEVEL_BORDER;
@@ -133,12 +151,19 @@ long wxTopLevelWindow::GetDecorationsStyle() const
         style |= wxTOPLEVEL_MAXIMIZED;
     if ( GetIcon().Ok() )
         style |= wxTOPLEVEL_ICON;
         style |= wxTOPLEVEL_MAXIMIZED;
     if ( GetIcon().Ok() )
         style |= wxTOPLEVEL_ICON;
-    if ( /*m_isActive*/ 1 /* FIXME_MGL*/ )
+    if ( m_isActive )
         style |= wxTOPLEVEL_ACTIVE;
 
     return style;
 }
 
         style |= wxTOPLEVEL_ACTIVE;
 
     return style;
 }
 
+void wxTopLevelWindow::RefreshTitleBar()
+{
+    wxNcPaintEvent event(GetId());
+    event.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(event);
+}
+
 // ----------------------------------------------------------------------------
 // client area handling
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // client area handling
 // ----------------------------------------------------------------------------
@@ -209,10 +234,21 @@ void wxTopLevelWindow::OnNcPaint(wxPaintEvent& event)
         wxWindowDC dc(this);
         m_renderer->DrawFrameTitleBar(dc, rect, 
                                       GetTitle(), m_titlebarIcon,
         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
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // icons
 // ----------------------------------------------------------------------------
@@ -238,7 +274,181 @@ void wxTopLevelWindow::SetIcon(const wxIcon& icon)
         {
             wxImage img = bmp1.ConvertToImage();
             img.Rescale(size.x, size.y);
         {
             wxImage img = bmp1.ConvertToImage();
             img.Rescale(size.x, size.y);
-             m_titlebarIcon.CopyFromBitmap(wxBitmap(img));
+            m_titlebarIcon.CopyFromBitmap(wxBitmap(img));
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+// 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)
+{
+    if ( action == wxACTION_TOPLEVEL_ACTIVATE )
+    {
+        if ( m_isActive != (bool)numArg )
+        {
+            Refresh();
+            m_isActive = (bool)numArg;
+            wxNcPaintEvent event(GetId());
+            event.SetEventObject(this);
+            GetEventHandler()->ProcessEvent(event);
         }
         }
+        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;
+}
+
+
+// ============================================================================
+// wxStdFrameInputHandler: handles focus, resizing and titlebar buttons clicks
+// ============================================================================
+
+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);
+}
+
+bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer *consumer, 
+                                              bool activated)
+{
+    consumer->PerformAction(wxACTION_TOPLEVEL_ACTIVATE, activated);
+    return FALSE;
 }
 }