]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/topluniv.cpp
Tries to fix wxListBox focus problems.
[wxWidgets.git] / src / univ / topluniv.cpp
index 625ec55828c89f8a9b6d3f3f6617ef9b28791c27..f9bfbeaa8683ede62ee26f40caa42f9b21b13e16 100644 (file)
 #endif
 
 #include "wx/defs.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/dcclient.h"
+    #include "wx/settings.h"
+#endif
+
 #include "wx/toplevel.h"
 #include "wx/univ/renderer.h"
-#include "wx/dcclient.h"
 #include "wx/bitmap.h"
 #include "wx/image.h"
 #include "wx/cshelp.h"
@@ -45,12 +50,12 @@ END_EVENT_TABLE()
 
 WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow)
 
-
 // ============================================================================
 // implementation
 // ============================================================================
 
 int wxTopLevelWindow::ms_drawDecorations = -1;
+int wxTopLevelWindow::ms_canIconize = -1;
 
 void wxTopLevelWindow::Init()
 {
@@ -63,7 +68,7 @@ bool wxTopLevelWindow::Create(wxWindow *parent,
                               wxWindowID id,
                               const wxString& title,
                               const wxPoint& pos,
-                              const wxSize& sizeOrig,
+                              const wxSize& size,
                               long style,
                               const wxString &name)
 {
@@ -72,9 +77,18 @@ bool wxTopLevelWindow::Create(wxWindow *parent,
          exstyleOrig = 0;
 
     if ( ms_drawDecorations == -1 )
-        ms_drawDecorations = TRUE;
-        // FIXME_MGL -- this is temporary; we assume for now that native TLW
-        //              can't do decorations, which is not true
+    {
+        ms_drawDecorations = 
+            !wxSystemSettings::GetCapability(wxSYS_CAN_DRAW_FRAME_DECORATIONS) 
+            || wxGetEnv(wxT("WXDECOR"), NULL);
+        // FIXME -- wxUniv should provide a way to force non-native decorations!
+        //          $WXDECOR is just a hack in absence of better wxUniv solution
+    }
+
+    if ( ms_canIconize == -1 )
+    {
+        ms_canIconize = wxSystemSettings::GetCapability(wxSYS_CAN_ICONIZE_FRAME);
+    }
 
     if ( ms_drawDecorations )
     {
@@ -82,16 +96,16 @@ bool wxTopLevelWindow::Create(wxWindow *parent,
 
         styleOrig = style;
         exstyleOrig = GetExtraStyle();
-        style &= ~(wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | 
-                   wxSYSTEM_MENU | wxRESIZE_BORDER | wxFRAME_TOOL_WINDOW | 
+        style &= ~(wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX |
+                   wxSYSTEM_MENU | wxRESIZE_BORDER | wxFRAME_TOOL_WINDOW |
                    wxTHICK_FRAME);
         style = wxSIMPLE_BORDER;
-        SetExtraStyle(exstyleOrig & 
+        SetExtraStyle(exstyleOrig &
                       ~(wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP));
     }
 
-    if ( !wxTopLevelWindowNative::Create(parent, id, title, pos, 
-                                         sizeOrig, style, name) )
+    if ( !wxTopLevelWindowNative::Create(parent, id, title, pos,
+                                         size, style, name) )
         return FALSE;
 
     if ( ms_drawDecorations )
@@ -99,14 +113,14 @@ bool wxTopLevelWindow::Create(wxWindow *parent,
         m_windowStyle = styleOrig;
         m_exStyle = exstyleOrig;
     }
-        
+
     return TRUE;
 }
 
 bool wxTopLevelWindow::ShowFullScreen(bool show, long style)
 {
     if ( show == IsFullScreen() ) return FALSE;
-    
+
     if ( ms_drawDecorations )
     {
         if ( show )
@@ -133,10 +147,15 @@ long wxTopLevelWindow::GetDecorationsStyle() const
     if ( m_windowStyle & wxCAPTION )
     {
         style |= wxTOPLEVEL_TITLEBAR | wxTOPLEVEL_BUTTON_CLOSE;
-        if ( m_windowStyle & wxMINIMIZE_BOX )
+        if ( (m_windowStyle & wxMINIMIZE_BOX) && ms_canIconize )
             style |= wxTOPLEVEL_BUTTON_ICONIZE;
         if ( m_windowStyle & wxMAXIMIZE_BOX )
-            style |= wxTOPLEVEL_BUTTON_MAXIMIZE;
+        {
+            if ( IsMaximized() )
+                style |= wxTOPLEVEL_BUTTON_RESTORE;
+            else
+                style |= wxTOPLEVEL_BUTTON_MAXIMIZE;
+        }
 #if wxUSE_HELP
         if ( m_exStyle & (wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP))
             style |= wxTOPLEVEL_BUTTON_HELP;
@@ -146,7 +165,7 @@ long wxTopLevelWindow::GetDecorationsStyle() const
         style |= wxTOPLEVEL_BORDER;
     if ( m_windowStyle & (wxRESIZE_BORDER | wxTHICK_FRAME) )
         style |= wxTOPLEVEL_RESIZEABLE;
-        
+
     if ( IsMaximized() )
         style |= wxTOPLEVEL_MAXIMIZED;
     if ( GetIcon().Ok() )
@@ -176,7 +195,7 @@ wxPoint wxTopLevelWindow::GetClientAreaOrigin() const
         wxTopLevelWindowNative::DoGetClientSize(&w, &h);
         wxRect rect = wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
                              wxSize(w, h));
-        rect = m_renderer->GetFrameClientArea(rect, 
+        rect = m_renderer->GetFrameClientArea(rect,
                                               GetDecorationsStyle());
         return rect.GetPosition();
     }
@@ -194,7 +213,7 @@ void wxTopLevelWindow::DoGetClientSize(int *width, int *height) const
         wxTopLevelWindowNative::DoGetClientSize(&w, &h);
         wxRect rect = wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
                              wxSize(w, h));
-        rect = m_renderer->GetFrameClientArea(rect, 
+        rect = m_renderer->GetFrameClientArea(rect,
                                               GetDecorationsStyle());
         if ( width )
             *width = rect.width;
@@ -209,7 +228,7 @@ void wxTopLevelWindow::DoSetClientSize(int width, int height)
 {
     if ( ms_drawDecorations )
     {
-        wxSize size = m_renderer->GetFrameTotalSize(wxSize(width, height), 
+        wxSize size = m_renderer->GetFrameTotalSize(wxSize(width, height),
                                                GetDecorationsStyle());
         wxTopLevelWindowNative::DoSetClientSize(size.x, size.y);
     }
@@ -232,7 +251,7 @@ void wxTopLevelWindow::OnNcPaint(wxPaintEvent& event)
         rect.height = size.y;
 
         wxWindowDC dc(this);
-        m_renderer->DrawFrameTitleBar(dc, rect, 
+        m_renderer->DrawFrameTitleBar(dc, rect,
                                       GetTitle(), m_titlebarIcon,
                                       GetDecorationsStyle(),
                                       m_pressedButton,
@@ -245,8 +264,8 @@ 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());
+
+    return m_renderer->HitTestFrame(rect, pt+GetClientAreaOrigin(), GetDecorationsStyle());
 }
 
 // ----------------------------------------------------------------------------
@@ -256,25 +275,27 @@ long wxTopLevelWindow::HitTest(const wxPoint& pt) const
 void wxTopLevelWindow::SetIcon(const wxIcon& icon)
 {
     wxTopLevelWindowNative::SetIcon(icon);
-    if ( !m_renderer ) return;
 
-    wxSize size = m_renderer->GetFrameIconSize();
-    
-    if ( !icon.Ok() || size.x == -1  )
-        m_titlebarIcon = icon;
-    else
+    if ( ms_drawDecorations && m_renderer )
     {
-        wxBitmap bmp1;
-        bmp1.CopyFromIcon(icon);
-        if ( !bmp1.Ok() )
-            m_titlebarIcon = wxNullIcon;
-        else if ( bmp1.GetWidth() == size.x && bmp1.GetHeight() == size.y )
+        wxSize size = m_renderer->GetFrameIconSize();
+
+        if ( !icon.Ok() || size.x == -1  )
             m_titlebarIcon = icon;
         else
         {
-            wxImage img = bmp1.ConvertToImage();
-            img.Rescale(size.x, size.y);
-            m_titlebarIcon.CopyFromBitmap(wxBitmap(img));
+            wxBitmap bmp1;
+            bmp1.CopyFromIcon(icon);
+            if ( !bmp1.Ok() )
+                m_titlebarIcon = wxNullIcon;
+            else if ( bmp1.GetWidth() == size.x && bmp1.GetHeight() == size.y )
+                m_titlebarIcon = icon;
+            else
+            {
+                wxImage img = bmp1.ConvertToImage();
+                img.Rescale(size.x, size.y);
+                m_titlebarIcon.CopyFromBitmap(wxBitmap(img));
+            }
         }
     }
 }
@@ -310,7 +331,7 @@ void wxTopLevelWindow::ClickTitleBarButton(long button)
             }
 #endif
             break;
-            
+
         default:
             wxFAIL_MSG(wxT("incorrect button specification"));
     }
@@ -320,33 +341,32 @@ bool wxTopLevelWindow::PerformAction(const wxControlAction& action,
                                      long numArg,
                                      const wxString& strArg)
 {
+    bool isActive = numArg != 0;
+
     if ( action == wxACTION_TOPLEVEL_ACTIVATE )
     {
-        if ( m_isActive != (bool)numArg )
+        if ( m_isActive != isActive )
         {
-            Refresh();
-            m_isActive = (bool)numArg;
-            wxNcPaintEvent event(GetId());
-            event.SetEventObject(this);
-            GetEventHandler()->ProcessEvent(event);
+            m_isActive = isActive;
+            RefreshTitleBar();
         }
         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;
@@ -354,7 +374,28 @@ bool wxTopLevelWindow::PerformAction(const wxControlAction& action,
         ClickTitleBarButton(numArg);
         return TRUE;
     }
-    
+
+    else if ( action == wxACTION_TOPLEVEL_MOVE )
+    {
+        InteractiveMove(wxINTERACTIVE_MOVE);
+        return TRUE;
+    }
+
+    else if ( action == wxACTION_TOPLEVEL_RESIZE )
+    {
+        int flags = wxINTERACTIVE_RESIZE;
+        if ( numArg & wxHT_TOPLEVEL_BORDER_N )
+            flags |= wxINTERACTIVE_RESIZE_N;
+        if ( numArg & wxHT_TOPLEVEL_BORDER_S )
+            flags |= wxINTERACTIVE_RESIZE_S;
+        if ( numArg & wxHT_TOPLEVEL_BORDER_W )
+            flags |= wxINTERACTIVE_RESIZE_W;
+        if ( numArg & wxHT_TOPLEVEL_BORDER_E )
+            flags |= wxINTERACTIVE_RESIZE_E;
+        InteractiveMove(flags);
+        return TRUE;
+    }
+
     else
         return FALSE;
 }
@@ -370,6 +411,7 @@ wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler *inphand)
     m_winCapture = NULL;
     m_winHitTest = 0;
     m_winPressed = 0;
+    m_borderCursorOn = FALSE;
 }
 
 bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer *consumer,
@@ -389,7 +431,7 @@ bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer *consumer,
         {
             wxTopLevelWindow *w = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
             long hit = w->HitTest(event.GetPosition());
-            
+
             if ( hit & wxHT_TOPLEVEL_ANY_BUTTON )
             {
                 m_winCapture = w;
@@ -399,6 +441,17 @@ bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer *consumer,
                 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
                 return TRUE;
             }
+            else if ( hit & wxHT_TOPLEVEL_TITLEBAR )
+            {
+                consumer->PerformAction(wxACTION_TOPLEVEL_MOVE);
+                return TRUE;
+            }
+            else if ( (consumer->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER)
+                      && (hit & wxHT_TOPLEVEL_ANY_BORDER) )
+            {
+                consumer->PerformAction(wxACTION_TOPLEVEL_RESIZE, hit);
+                return TRUE;
+            }
         }
 
         else // up
@@ -422,11 +475,9 @@ bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer *consumer,
     return wxStdInputHandler::HandleMouse(consumer, event);
 }
 
-bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer *consumer, 
+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());
@@ -437,18 +488,74 @@ bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer *consumer,
                 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE, m_winPressed);
             else
                 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
-            
+
             m_winHitTest = hit;
             return TRUE;
         }
     }
+    else if ( consumer->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER )
+    {
+        wxTopLevelWindow *win = wxStaticCast(consumer->GetInputWindow(),
+                                             wxTopLevelWindow);
+        long hit = win->HitTest(event.GetPosition());
+
+        if ( hit != m_winHitTest )
+        {
+            m_winHitTest = hit;
+
+            if ( m_borderCursorOn )
+            {
+                m_borderCursorOn = FALSE;
+                win->SetCursor(m_origCursor);
+            }
+
+            if ( hit & wxHT_TOPLEVEL_ANY_BORDER )
+            {
+                m_borderCursorOn = TRUE;
+                wxCursor cur;
+
+                switch (hit)
+                {
+                    case wxHT_TOPLEVEL_BORDER_N:
+                    case wxHT_TOPLEVEL_BORDER_S:
+                        cur = wxCursor(wxCURSOR_SIZENS);
+                        break;
+                    case wxHT_TOPLEVEL_BORDER_W:
+                    case wxHT_TOPLEVEL_BORDER_E:
+                        cur = wxCursor(wxCURSOR_SIZEWE);
+                        break;
+                    case wxHT_TOPLEVEL_BORDER_NE:
+                    case wxHT_TOPLEVEL_BORDER_SW:
+                        cur = wxCursor(wxCURSOR_SIZENESW);
+                        break;
+                    case wxHT_TOPLEVEL_BORDER_NW:
+                    case wxHT_TOPLEVEL_BORDER_SE:
+                        cur = wxCursor(wxCURSOR_SIZENWSE);
+                        break;
+                    default:
+                        m_borderCursorOn = FALSE;
+                        break;
+                }
+                if ( m_borderCursorOn )
+                {
+                    m_origCursor = win->GetCursor();
+                    win->SetCursor(cur);
+                }
+            }
+        }
+    }
 
     return wxStdInputHandler::HandleMouseMove(consumer, event);
 }
 
-bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer *consumer, 
+bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer *consumer,
                                               bool activated)
 {
+    if ( m_borderCursorOn )
+    {
+        consumer->GetInputWindow()->SetCursor(m_origCursor);
+        m_borderCursorOn = FALSE;
+    }
     consumer->PerformAction(wxACTION_TOPLEVEL_ACTIVATE, activated);
     return FALSE;
 }