]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/themes/win32.cpp
clean up of memory debugging macros and chanegs to compile with CW7 (patch 548408)
[wxWidgets.git] / src / univ / themes / win32.cpp
index 3e11c5ff999d09ea3efa622475ffc52db17b3eaa..ccf87bc3ff467184d2f05af90bad77e2a56b1dfd 100644 (file)
 #include "wx/spinbutt.h"
 #include "wx/settings.h"
 #include "wx/menu.h"
+#include "wx/artprov.h"
+#include "wx/toplevel.h"
 
 #include "wx/univ/scrtimer.h"
-#include "wx/toplevel.h"
 #include "wx/univ/renderer.h"
 #include "wx/univ/inphand.h"
 #include "wx/univ/colschem.h"
@@ -147,7 +148,8 @@ public:
     virtual void DrawBackground(wxDC& dc,
                                 const wxColour& col,
                                 const wxRect& rect,
-                                int flags = 0);
+                                int flags = 0,
+                                wxWindow *window = NULL);
     virtual void DrawLabel(wxDC& dc,
                            const wxString& label,
                            const wxRect& rect,
@@ -321,8 +323,6 @@ public:
     virtual wxSize GetFrameIconSize() const;
     virtual int HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const;
 
-    virtual wxIcon GetStdIcon(int which) const;
-
     virtual void GetComboBitmaps(wxBitmap *bmpNormal,
                                  wxBitmap *bmpFocus,
                                  wxBitmap *bmpPressed,
@@ -355,7 +355,7 @@ public:
     virtual wxSize GetToolBarButtonSize(wxCoord *separator) const
         { if ( separator ) *separator = 5; return wxSize(16, 15); }
     virtual wxSize GetToolBarMargin() const
-        { return wxSize(6, 6); }
+        { return wxSize(4, 4); }
 
     virtual wxRect GetTextTotalArea(const wxTextCtrl *text,
                                     const wxRect& rect) const;
@@ -405,7 +405,8 @@ protected:
     // DrawButtonBorder() helper
     void DoDrawBackground(wxDC& dc,
                           const wxColour& col,
-                          const wxRect& rect);
+                          const wxRect& rect,
+                          wxWindow *window = NULL );
 
     // DrawBorder() helpers: all of them shift and clip the DC after drawing
     // the border
@@ -602,8 +603,8 @@ class wxWin32SystemMenuEvtHandler;
 class wxWin32FrameInputHandler : public wxStdFrameInputHandler
 {
 public:
-    wxWin32FrameInputHandler(wxInputHandler *handler)
-        : wxStdFrameInputHandler(handler), m_menuHandler(NULL) { }
+    wxWin32FrameInputHandler(wxInputHandler *handler);
+    ~wxWin32FrameInputHandler();
 
     virtual bool HandleMouse(wxInputConsumer *control,
                              const wxMouseEvent& event);
@@ -628,6 +629,18 @@ public:
     virtual wxColour GetBackground(wxWindow *win) const;
 };
 
+// ----------------------------------------------------------------------------
+// wxWin32ArtProvider
+// ----------------------------------------------------------------------------
+
+class wxWin32ArtProvider : public wxArtProvider
+{
+protected:
+    virtual wxBitmap CreateBitmap(const wxArtID& id,
+                                  const wxArtClient& client,
+                                  const wxSize& size);
+};
+
 // ----------------------------------------------------------------------------
 // wxWin32Theme
 // ----------------------------------------------------------------------------
@@ -641,6 +654,7 @@ public:
     virtual ~wxWin32Theme();
 
     virtual wxRenderer *GetRenderer();
+    virtual wxArtProvider *GetArtProvider();
     virtual wxInputHandler *GetInputHandler(const wxString& control);
     virtual wxColourScheme *GetColourScheme();
 
@@ -649,6 +663,8 @@ private:
     wxInputHandler *GetDefaultInputHandler();
 
     wxWin32Renderer *m_renderer;
+    
+    wxWin32ArtProvider *m_artProvider;
 
     // the names of the already created handlers and the handlers themselves
     // (these arrays are synchronized)
@@ -1160,6 +1176,7 @@ wxWin32Theme::wxWin32Theme()
     m_scheme = NULL;
     m_renderer = NULL;
     m_handlerDefault = NULL;
+    m_artProvider = NULL;
 }
 
 wxWin32Theme::~wxWin32Theme()
@@ -1175,6 +1192,7 @@ wxWin32Theme::~wxWin32Theme()
 
     delete m_renderer;
     delete m_scheme;
+    wxArtProvider::RemoveProvider(m_artProvider);
 }
 
 wxRenderer *wxWin32Theme::GetRenderer()
@@ -1187,6 +1205,16 @@ wxRenderer *wxWin32Theme::GetRenderer()
     return m_renderer;
 }
 
+wxArtProvider *wxWin32Theme::GetArtProvider()
+{
+    if ( !m_artProvider )
+    {
+        m_artProvider = new wxWin32ArtProvider;
+    }
+
+    return m_artProvider;
+}
+
 wxInputHandler *wxWin32Theme::GetDefaultInputHandler()
 {
     if ( !m_handlerDefault )
@@ -1338,8 +1366,12 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const
 
         case CONTROL_TEXT:      return wxColour(GetSysColor(COLOR_BTNTEXT));
 
-        case SCROLLBAR:         return wxColour(GetSysColor(COLOR_SCROLLBAR));
-        case SCROLLBAR_PRESSED: return wxColour(GetSysColor(COLOR_HIGHLIGHT));
+#if defined(COLOR_3DLIGHT)
+        case SCROLLBAR:         return wxColour(GetSysColor(COLOR_3DLIGHT));
+#else
+        case SCROLLBAR:         return wxColour(0xe0e0e0);
+#endif
+        case SCROLLBAR_PRESSED: return wxColour(GetSysColor(COLOR_BTNTEXT));
 
         case HIGHLIGHT:         return wxColour(GetSysColor(COLOR_HIGHLIGHT));
         case HIGHLIGHT_TEXT:    return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT));
@@ -1836,8 +1868,12 @@ wxRect wxWin32Renderer::GetBorderDimensions(wxBorder border) const
             break;
 
         default:
+        { 
+            // char *crash = NULL;
+            // *crash = 0;
             wxFAIL_MSG(_T("unknown border type"));
             // fall through
+        }
 
         case wxBORDER_DEFAULT:
         case wxBORDER_NONE:
@@ -2381,7 +2417,11 @@ void wxWin32Renderer::DrawToolBarButton(wxDC& dc,
     }
     else // a separator
     {
-        // TODO
+        // leave a small gap aroudn the line, also account for the toolbar
+        // border itself
+        DrawVerticalLine(dc, rectOrig.x + rectOrig.width/2,
+                         rectOrig.y + 2*BORDER_THICKNESS,
+                         rectOrig.GetBottom() - BORDER_THICKNESS);
     }
 }
 
@@ -3167,7 +3207,8 @@ void wxWin32Renderer::GetComboBitmaps(wxBitmap *bmpNormal,
 
 void wxWin32Renderer::DoDrawBackground(wxDC& dc,
                                        const wxColour& col,
-                                       const wxRect& rect)
+                                       const wxRect& rect,
+                                       wxWindow *window )
 {
     wxBrush brush(col, wxSOLID);
     dc.SetBrush(brush);
@@ -3178,11 +3219,12 @@ void wxWin32Renderer::DoDrawBackground(wxDC& dc,
 void wxWin32Renderer::DrawBackground(wxDC& dc,
                                      const wxColour& col,
                                      const wxRect& rect,
-                                     int flags)
+                                     int flags,
+                                     wxWindow *window )
 {
     // just fill it with the given or default bg colour
     wxColour colBg = col.Ok() ? col : wxSCHEME_COLOUR(m_scheme, CONTROL);
-    DoDrawBackground(dc, colBg, rect);
+    DoDrawBackground(dc, colBg, rect, window );
 }
 
 // ----------------------------------------------------------------------------
@@ -3849,26 +3891,19 @@ static char *warning_xpm[]={
 "....ddddddddddddddddddddddddddd.",
 ".....ddddddddddddddddddddddddd.."};
 
-wxIcon wxWin32Renderer::GetStdIcon(int which) const
+wxBitmap wxWin32ArtProvider::CreateBitmap(const wxArtID& id,
+                                          const wxArtClient& WXUNUSED(client),
+                                          const wxSize& WXUNUSED(size))
 {
-    switch(which)
-    {
-        case wxICON_INFORMATION:
-            return wxIcon(info_xpm);
-
-        case wxICON_QUESTION:
-            return wxIcon(question_xpm);
-
-        case wxICON_EXCLAMATION:
-            return wxIcon(warning_xpm);
-
-        default:
-            wxFAIL_MSG(wxT("requested non existent standard icon"));
-            // still fall through
-
-        case wxICON_HAND:
-            return wxIcon(error_xpm);
-    }
+    if ( id == wxART_INFORMATION )
+        return wxBitmap(info_xpm);
+    if ( id == wxART_ERROR )
+        return wxBitmap(error_xpm);
+    if ( id == wxART_WARNING )
+        return wxBitmap(warning_xpm);
+    if ( id == wxART_QUESTION )
+        return wxBitmap(question_xpm);
+    return wxNullBitmap;
 }
 
 
@@ -4116,6 +4151,8 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer *control,
         // if we're scrolling the scrollbar because the arrow or the shaft was
         // pressed, check that the mouse stays on the same scrollbar element
 
+#if 0
+        // Always let thumb jump back if we leave the scrollbar
         if ( event.Moving() )
         {
             ht = m_renderer->HitTestScrollbar(scrollbar, event.GetPosition());
@@ -4124,6 +4161,21 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer *control,
         {
             ht = wxHT_NOWHERE;
         }
+#else
+        // Jump back only if we get far away from it
+        wxPoint pos = event.GetPosition();
+        if (scrollbar->HasFlag( wxVERTICAL ))
+        {
+            if (pos.x > -40 && pos.x < scrollbar->GetSize().x+40)
+               pos.x = 5;
+        }
+        else
+        {
+            if (pos.y > -40 && pos.y < scrollbar->GetSize().y+40)
+               pos.y = 5;
+        }
+        ht = m_renderer->HitTestScrollbar(scrollbar, pos );
+#endif
 
         // if we're dragging the thumb and the mouse stays in the scrollbar, it
         // is still ok - we only want to catch the case when the mouse leaves
@@ -4342,79 +4394,13 @@ bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
 // wxWin32FrameInputHandler
 // ----------------------------------------------------------------------------
 
-bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer,
-                                           const wxMouseEvent& event)
-{
-    if ( event.LeftDClick() || event.LeftDown() || event.RightDown() )
-    {
-        wxTopLevelWindow *tlw =
-            wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
-
-        long hit = tlw->HitTest(event.GetPosition());
-
-        if ( event.LeftDClick() && hit == wxHT_TOPLEVEL_TITLEBAR )
-        {
-            tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
-                               tlw->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
-                                                  : wxTOPLEVEL_BUTTON_MAXIMIZE);
-            return TRUE;
-        }
-        else if ( tlw->GetWindowStyle() & wxSYSTEM_MENU )
-        {
-            if ( (event.LeftDown() && hit == wxHT_TOPLEVEL_ICON) ||
-                 (event.RightDown() && 
-                      (hit == wxHT_TOPLEVEL_TITLEBAR || 
-                       hit == wxHT_TOPLEVEL_ICON)) )
-            {
-                PopupSystemMenu(tlw, event.GetPosition());
-                return TRUE;
-            }
-        }
-    }
-
-    return wxStdFrameInputHandler::HandleMouse(consumer, event);
-}
-
-void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow *window, 
-                                               const wxPoint& pos) const
-{
-    wxMenu *menu = new wxMenu;
-
-    if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
-        menu->Append(wxID_RESTORE_FRAME , _("&Restore"));
-    menu->Append(wxID_MOVE_FRAME , _("&Move"));
-    if ( window->GetWindowStyle() & wxRESIZE_BORDER )
-        menu->Append(wxID_RESIZE_FRAME , _("&Size"));
-    if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME) )
-        menu->Append(wxID_ICONIZE_FRAME , _("Mi&nimize"));
-    if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
-        menu->Append(wxID_MAXIMIZE_FRAME , _("Ma&ximize"));
-    menu->AppendSeparator();
-    menu->Append(wxID_CLOSE_FRAME, _("Close\tAlt-F4"));
-    
-    if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
-    {
-        if ( window->IsMaximized() )
-        {
-            menu->Enable(wxID_MAXIMIZE_FRAME, FALSE);
-            menu->Enable(wxID_MOVE_FRAME, FALSE);
-            if ( window->GetWindowStyle() & wxRESIZE_BORDER )
-                menu->Enable(wxID_RESIZE_FRAME, FALSE);
-        }
-        else
-            menu->Enable(wxID_RESTORE_FRAME, FALSE);
-    }
-
-    window->PopupMenu(menu, pos);
-    delete menu;
-}
-
 class wxWin32SystemMenuEvtHandler : public wxEvtHandler
 {
 public:
-    wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler *handler,
-                                wxInputConsumer *consumer);
-    void RemoveSelf();
+    wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler *handler);
+    
+    void Attach(wxInputConsumer *consumer);
+    void Detach();
     
 private:
     DECLARE_EVENT_TABLE()
@@ -4428,10 +4414,16 @@ private:
 };
 
 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
-                                wxWin32FrameInputHandler *handler,
-                                wxInputConsumer *consumer)
+                                wxWin32FrameInputHandler *handler)
 {
     m_inputHnd = handler;
+    m_wnd = NULL;
+}
+
+void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer *consumer)
+{
+    wxASSERT_MSG( m_wnd == NULL, _T("can't attach the handler twice!") );
+
     m_wnd = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
     m_wnd->PushEventHandler(this);
     
@@ -4444,12 +4436,13 @@ wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
     m_wnd->SetAcceleratorTable(table);
 }
 
-void wxWin32SystemMenuEvtHandler::RemoveSelf()
+void wxWin32SystemMenuEvtHandler::Detach()
 {
     if ( m_wnd )
     {
         m_wnd->SetAcceleratorTable(m_oldAccelTable);
         m_wnd->RemoveEventHandler(this); 
+        m_wnd = NULL;
     }
 }
 
@@ -4488,25 +4481,99 @@ void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent &event)
 }
 
 
-bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer *consumer, 
-                                                bool activated)
+wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler *handler)
+        : wxStdFrameInputHandler(handler)
 {
-    if ( consumer->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU )
+    m_menuHandler = new wxWin32SystemMenuEvtHandler(this);
+}
+
+wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
+{
+    if ( m_menuHandler )
     {
-        if ( !activated && m_menuHandler )
+        m_menuHandler->Detach();
+        delete m_menuHandler;
+    }
+}
+
+bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer,
+                                           const wxMouseEvent& event)
+{
+    if ( event.LeftDClick() || event.LeftDown() || event.RightDown() )
+    {
+        wxTopLevelWindow *tlw =
+            wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
+
+        long hit = tlw->HitTest(event.GetPosition());
+
+        if ( event.LeftDClick() && hit == wxHT_TOPLEVEL_TITLEBAR )
         {
-            m_menuHandler->RemoveSelf();
-            wxDELETE(m_menuHandler);
+            tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
+                               tlw->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
+                                                  : wxTOPLEVEL_BUTTON_MAXIMIZE);
+            return TRUE;
         }
-        else if ( activated )
+        else if ( tlw->GetWindowStyle() & wxSYSTEM_MENU )
         {
-            if ( m_menuHandler )
+            if ( (event.LeftDown() && hit == wxHT_TOPLEVEL_ICON) ||
+                 (event.RightDown() && 
+                      (hit == wxHT_TOPLEVEL_TITLEBAR || 
+                       hit == wxHT_TOPLEVEL_ICON)) )
             {
-                m_menuHandler->RemoveSelf();
-                delete m_menuHandler;
+                PopupSystemMenu(tlw, event.GetPosition());
+                return TRUE;
             }
+        }
+    }
+
+    return wxStdFrameInputHandler::HandleMouse(consumer, event);
+}
 
-            m_menuHandler = new wxWin32SystemMenuEvtHandler(this, consumer);
+void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow *window, 
+                                               const wxPoint& pos) const
+{
+    wxMenu *menu = new wxMenu;
+
+    if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
+        menu->Append(wxID_RESTORE_FRAME , _("&Restore"));
+    menu->Append(wxID_MOVE_FRAME , _("&Move"));
+    if ( window->GetWindowStyle() & wxRESIZE_BORDER )
+        menu->Append(wxID_RESIZE_FRAME , _("&Size"));
+    if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME) )
+        menu->Append(wxID_ICONIZE_FRAME , _("Mi&nimize"));
+    if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
+        menu->Append(wxID_MAXIMIZE_FRAME , _("Ma&ximize"));
+    menu->AppendSeparator();
+    menu->Append(wxID_CLOSE_FRAME, _("Close\tAlt-F4"));
+    
+    if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
+    {
+        if ( window->IsMaximized() )
+        {
+            menu->Enable(wxID_MAXIMIZE_FRAME, FALSE);
+            menu->Enable(wxID_MOVE_FRAME, FALSE);
+            if ( window->GetWindowStyle() & wxRESIZE_BORDER )
+                menu->Enable(wxID_RESIZE_FRAME, FALSE);
+        }
+        else
+            menu->Enable(wxID_RESTORE_FRAME, FALSE);
+    }
+
+    window->PopupMenu(menu, pos);
+    delete menu;
+}
+
+bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer *consumer, 
+                                                bool activated)
+{
+    if ( consumer->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU )
+    {
+        // always detach if active frame changed:
+        m_menuHandler->Detach();
+
+        if ( activated )
+        {
+            m_menuHandler->Attach(consumer);
         }
     }