]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/themes/win32.cpp
docs corrections and docs for Chris' wxImage::SaveFile(filename_only) patch
[wxWidgets.git] / src / univ / themes / win32.cpp
index 4142f5940fae2867e15f6ecc487d3f52d24701c3..ec3d13ca87ffd71c879020066b292c762e100f88 100644 (file)
@@ -38,6 +38,7 @@
     #include "wx/scrolbar.h"
     #include "wx/slider.h"
     #include "wx/textctrl.h"
+    #include "wx/toolbar.h"
 
     #ifdef __WXMSW__
         // for COLOR_* constants
@@ -228,6 +229,11 @@ public:
                                  int flags = 0,
                                  wxAlignment align = wxALIGN_LEFT,
                                  int indexAccel = -1);
+    virtual void DrawToolBarButton(wxDC& dc,
+                                   const wxString& label,
+                                   const wxBitmap& bitmap,
+                                   const wxRect& rect,
+                                   int flags);
     virtual void DrawTextLine(wxDC& dc,
                               const wxString& text,
                               const wxRect& rect,
@@ -346,11 +352,16 @@ public:
     virtual wxCoord GetCheckItemMargin() const
         { return 0; }
 
+    virtual wxSize GetToolBarButtonSize(wxCoord *separator) const
+        { if ( separator ) *separator = 5; return wxSize(16, 15); }
+    virtual wxSize GetToolBarMargin() const
+        { return wxSize(6, 6); }
+
     virtual wxRect GetTextTotalArea(const wxTextCtrl *text,
-                                    const wxRect& rect);
+                                    const wxRect& rect) const;
     virtual wxRect GetTextClientArea(const wxTextCtrl *text,
                                      const wxRect& rect,
-                                     wxCoord *extraSpaceBeyond);
+                                     wxCoord *extraSpaceBeyond) const;
 
     virtual wxSize GetTabIndent() const { return wxSize(2, 2); }
     virtual wxSize GetTabPadding() const { return wxSize(6, 5); }
@@ -586,14 +597,24 @@ private:
     bool m_isOnGrip;
 };
 
+class wxWin32SystemMenuEvtHandler;
+
 class wxWin32FrameInputHandler : public wxStdFrameInputHandler
 {
 public:
     wxWin32FrameInputHandler(wxInputHandler *handler)
-        : wxStdFrameInputHandler(handler) { }
+        : wxStdFrameInputHandler(handler), m_menuHandler(NULL) { }
 
     virtual bool HandleMouse(wxInputConsumer *control,
                              const wxMouseEvent& event);
+
+    virtual bool HandleActivation(wxInputConsumer *consumer, bool activated);
+                             
+    void PopupSystemMenu(wxTopLevelWindow *window, const wxPoint& pos) const;
+
+private:
+    // was the mouse over the grip last time we checked?
+    wxWin32SystemMenuEvtHandler *m_menuHandler;
 };
 
 // ----------------------------------------------------------------------------
@@ -1226,6 +1247,10 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
         else if ( control == wxINP_HANDLER_STATUSBAR )
             handler = new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
 #endif // wxUSE_STATUSBAR
+#if wxUSE_TOOLBAR
+        else if ( control == wxINP_HANDLER_TOOLBAR )
+            handler = new wxStdToolbarInputHandler(GetDefaultInputHandler());
+#endif // wxUSE_TOOLBAR
         else if ( control == wxINP_HANDLER_TOPLEVEL )
             handler = new wxWin32FrameInputHandler(GetDefaultInputHandler());
         else
@@ -1313,8 +1338,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));
@@ -2332,6 +2361,38 @@ void wxWin32Renderer::DrawCheckButton(wxDC& dc,
                            0); // no focus rect offset for checkboxes
 }
 
+void wxWin32Renderer::DrawToolBarButton(wxDC& dc,
+                                        const wxString& label,
+                                        const wxBitmap& bitmap,
+                                        const wxRect& rectOrig,
+                                        int flags)
+{
+    if ( !label.empty() || bitmap.Ok() )
+    {
+        wxRect rect = rectOrig;
+        rect.Deflate(BORDER_THICKNESS);
+
+        if ( flags & wxCONTROL_PRESSED )
+        {
+            DrawBorder(dc, wxBORDER_SUNKEN, rect, flags);
+        }
+        else if ( flags & wxCONTROL_CURRENT )
+        {
+            DrawBorder(dc, wxBORDER_RAISED, rect, flags);
+        }
+
+        dc.DrawLabel(label, bitmap, rect, wxALIGN_CENTRE);
+    }
+    else // a separator
+    {
+        // 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);
+    }
+}
+
 // ----------------------------------------------------------------------------
 // text control
 // ----------------------------------------------------------------------------
@@ -3829,7 +3890,7 @@ static inline int GetTextBorderWidth()
 }
 
 wxRect wxWin32Renderer::GetTextTotalArea(const wxTextCtrl *text,
-                                         const wxRect& rect)
+                                         const wxRect& rect) const
 {
     wxRect rectTotal = rect;
 
@@ -3844,7 +3905,7 @@ wxRect wxWin32Renderer::GetTextTotalArea(const wxTextCtrl *text,
 
 wxRect wxWin32Renderer::GetTextClientArea(const wxTextCtrl *text,
                                           const wxRect& rect,
-                                          wxCoord *extraSpaceBeyond)
+                                          wxCoord *extraSpaceBeyond) const
 {
     wxRect rectText = rect;
 
@@ -3936,7 +3997,8 @@ bool wxWin32InputHandler::HandleMouse(wxInputConsumer *control,
     {
         wxWindow *win = control->GetInputWindow();
 
-        if ( wxWindow::FindFocus() != control->GetInputWindow() )
+        if (( wxWindow::FindFocus() != control->GetInputWindow() ) &&
+            ( win->AcceptsFocus() ) )
         {
             win->SetFocus();
 
@@ -4291,22 +4353,170 @@ bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer,
                                            const wxMouseEvent& event)
 {
-    if ( event.LeftDClick() )
+    if ( event.LeftDClick() || event.LeftDown() || event.RightDown() )
     {
         wxTopLevelWindow *tlw =
             wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
 
         long hit = tlw->HitTest(event.GetPosition());
 
-        if ( hit == wxHT_TOPLEVEL_TITLEBAR )
+        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();
+    
+private:
+    DECLARE_EVENT_TABLE()
+    void OnSystemMenu(wxCommandEvent &event);
+    void OnCloseFrame(wxCommandEvent &event);
+    void OnClose(wxCloseEvent &event);
+   
+    wxWin32FrameInputHandler *m_inputHnd;
+    wxTopLevelWindow         *m_wnd;
+    wxAcceleratorTable        m_oldAccelTable;
+};
+
+wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
+                                wxWin32FrameInputHandler *handler,
+                                wxInputConsumer *consumer)
+{
+    m_inputHnd = handler;
+    m_wnd = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
+    m_wnd->PushEventHandler(this);
+    
+    // VS: This code relies on using generic implementation of 
+    //     wxAcceleratorTable in wxUniv!
+    wxAcceleratorTable table = *m_wnd->GetAcceleratorTable();
+    m_oldAccelTable = table;
+    table.Add(wxAcceleratorEntry(wxACCEL_ALT, WXK_SPACE, wxID_SYSTEM_MENU));
+    table.Add(wxAcceleratorEntry(wxACCEL_ALT, WXK_F4, wxID_CLOSE_FRAME));
+    m_wnd->SetAcceleratorTable(table);
+}
+
+void wxWin32SystemMenuEvtHandler::RemoveSelf()
+{
+    if ( m_wnd )
+    {
+        m_wnd->SetAcceleratorTable(m_oldAccelTable);
+        m_wnd->RemoveEventHandler(this); 
+    }
+}
+
+BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler, wxEvtHandler)
+    EVT_MENU(wxID_SYSTEM_MENU, wxWin32SystemMenuEvtHandler::OnSystemMenu)
+    EVT_MENU(wxID_CLOSE_FRAME, wxWin32SystemMenuEvtHandler::OnCloseFrame)
+    EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose)
+END_EVENT_TABLE()
+
+void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent &WXUNUSED(event))
+{
+    int border = ((m_wnd->GetWindowStyle() & wxRESIZE_BORDER) &&
+                  !m_wnd->IsMaximized()) ?
+                      RESIZEABLE_FRAME_BORDER_THICKNESS :
+                      FRAME_BORDER_THICKNESS;
+    wxPoint pt = m_wnd->GetClientAreaOrigin();
+    pt.x = -pt.x + border;
+    pt.y = -pt.y + border + FRAME_TITLEBAR_HEIGHT;
+
+    wxAcceleratorTable table = *m_wnd->GetAcceleratorTable();
+    m_wnd->SetAcceleratorTable(wxNullAcceleratorTable);
+    m_inputHnd->PopupSystemMenu(m_wnd, pt);
+    m_wnd->SetAcceleratorTable(table);
+}
+
+void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent &WXUNUSED(event))
+{
+    m_wnd->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
+                         wxTOPLEVEL_BUTTON_CLOSE);
+}
+
+void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent &event)
+{
+    m_wnd = NULL;
+    event.Skip();
+}
+
+
+bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer *consumer, 
+                                                bool activated)
+{
+    if ( consumer->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU )
+    {
+        if ( !activated && m_menuHandler )
+        {
+            m_menuHandler->RemoveSelf();
+            wxDELETE(m_menuHandler);
+        }
+        else if ( activated )
+        {
+            if ( m_menuHandler )
+            {
+                m_menuHandler->RemoveSelf();
+                delete m_menuHandler;
+            }
+
+            m_menuHandler = new wxWin32SystemMenuEvtHandler(this, consumer);
+        }
+    }
+
+    return wxStdFrameInputHandler::HandleActivation(consumer, activated);
+}