X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/54800df8d8f5e425c4f11538cd05341c51243543..6c5ac6e1f1a5a3400b51f3bf61d061cf3ed3857a:/src/univ/themes/win32.cpp?ds=sidebyside diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index 596bc217a3..a25e8d8f6c 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -1,4 +1,3 @@ -/////////////////////////////////////////////////////////////////////////////// // Name: univ/themes/win32.cpp // Purpose: wxUniversal theme implementing Win32-like LNF // Author: Vadim Zeitlin @@ -39,6 +38,11 @@ #include "wx/scrolbar.h" #include "wx/slider.h" #include "wx/textctrl.h" + + #ifdef __WXMSW__ + // for COLOR_* constants + #include "wx/msw/private.h" + #endif #endif // WX_PRECOMP #include "wx/notebook.h" @@ -47,7 +51,7 @@ #include "wx/menu.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" @@ -63,6 +67,12 @@ static const int BORDER_THICKNESS = 2; static const int FOCUS_RECT_OFFSET_X = 1; static const int FOCUS_RECT_OFFSET_Y = 1; +static const int FRAME_BORDER_THICKNESS = 3; +static const int RESIZEABLE_FRAME_BORDER_THICKNESS = 4; +static const int FRAME_TITLEBAR_HEIGHT = 18; +static const int FRAME_BUTTON_WIDTH = 16; +static const int FRAME_BUTTON_HEIGHT = 14; + enum IndicatorType { IndicatorType_Check, @@ -88,7 +98,6 @@ enum IndicatorStatus IndicatorStatus_Max }; -// ---------------------------------------------------------------------------- // wxWin32Renderer: draw the GUI elements in Win32 style // ---------------------------------------------------------------------------- @@ -115,6 +124,16 @@ public: Arrow_StateMax }; + enum wxFrameButtonType + { + FrameButton_Close, + FrameButton_Minimize, + FrameButton_Maximize, + FrameButton_Restore, + FrameButton_Help, + FrameButton_Max + }; + // ctor wxWin32Renderer(const wxColourScheme *scheme); @@ -255,7 +274,37 @@ public: wxCoord y, const wxMenuGeometryInfo& geomInfo); #endif + // titlebars + virtual void DrawFrameTitleBar(wxDC& dc, + const wxRect& rect, + const wxString& title, + const wxIcon& icon, + int flags, + int pressedButtons = 0); + virtual void DrawFrameBorder(wxDC& dc, + const wxRect& rect, + int flags); + virtual void DrawFrameBackground(wxDC& dc, + const wxRect& rect, + int flags); + virtual void DrawFrameTitle(wxDC& dc, + const wxRect& rect, + const wxString& title, + int flags); + virtual void DrawFrameIcon(wxDC& dc, + const wxRect& rect, + const wxIcon& icon, + int flags); + virtual void DrawFrameButton(wxDC& dc, + wxCoord x, wxCoord y, + int button, + int flags = 0); + virtual wxRect GetFrameClientArea(const wxRect& rect, int flags) const; + virtual wxSize GetFrameTotalSize(const wxSize& clientSize, int flags) const; + virtual wxSize GetFrameIconSize() const; + virtual void GetComboBitmaps(wxBitmap *bmpNormal, + wxBitmap *bmpFocus, wxBitmap *bmpPressed, wxBitmap *bmpDisabled); @@ -408,6 +457,11 @@ private: m_penDarkGrey, m_penLightGrey, m_penHighlight; + + wxFont m_titlebarFont; + + // titlebar icons: + wxBitmap m_bmpFrameButtons[FrameButton_Max]; // first row is for the normal state, second - for the disabled wxBitmap m_bmpArrows[Arrow_StateMax][Arrow_Max]; @@ -423,10 +477,10 @@ class wxWin32InputHandler : public wxInputHandler public: wxWin32InputHandler(wxWin32Renderer *renderer); - virtual bool HandleKey(wxControl *control, + virtual bool HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed); - virtual bool HandleMouse(wxControl *control, + virtual bool HandleMouse(wxInputConsumer *control, const wxMouseEvent& event); protected: @@ -439,8 +493,8 @@ public: wxWin32ScrollBarInputHandler(wxWin32Renderer *renderer, wxInputHandler *handler); - virtual bool HandleMouse(wxControl *control, const wxMouseEvent& event); - virtual bool HandleMouseMove(wxControl *control, const wxMouseEvent& event); + virtual bool HandleMouse(wxInputConsumer *control, const wxMouseEvent& event); + virtual bool HandleMouseMove(wxInputConsumer *control, const wxMouseEvent& event); virtual bool OnScrollTimer(wxScrollBar *scrollbar, const wxControlAction& action); @@ -470,7 +524,7 @@ public: wxWin32CheckboxInputHandler(wxInputHandler *handler) : wxStdCheckboxInputHandler(handler) { } - virtual bool HandleKey(wxControl *control, + virtual bool HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed); }; @@ -481,7 +535,7 @@ public: wxWin32TextCtrlInputHandler(wxInputHandler *handler) : wxStdTextCtrlInputHandler(handler) { } - virtual bool HandleKey(wxControl *control, + virtual bool HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed); }; @@ -535,6 +589,83 @@ private: // standard bitmaps // ---------------------------------------------------------------------------- +// frame buttons bitmaps + +static const char *frame_button_close_xpm[] = { +"12 10 2 1", +" c None", +". c black", +" ", +" .. .. ", +" .. .. ", +" .... ", +" .. ", +" .... ", +" .. .. ", +" .. .. ", +" ", +" "}; + +static const char *frame_button_help_xpm[] = { +"12 10 2 1", +" c None", +". c #000000", +" .... ", +" .. .. ", +" .. .. ", +" .. ", +" .. ", +" .. ", +" ", +" .. ", +" .. ", +" "}; + +static const char *frame_button_maximize_xpm[] = { +"12 10 2 1", +" c None", +". c #000000", +" ......... ", +" ......... ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" ......... ", +" "}; + +static const char *frame_button_minimize_xpm[] = { +"12 10 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ...... ", +" ...... ", +" "}; + +static const char *frame_button_restore_xpm[] = { +"12 10 2 1", +" c None", +". c #000000", +" ...... ", +" ...... ", +" . . ", +" ...... . ", +" ...... . ", +" . ... ", +" . . ", +" . . ", +" ...... ", +" "}; + // menu bitmaps static const char *checked_menu_xpm[] = { @@ -1090,6 +1221,41 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const { switch ( col ) { + // use the system colours under Windows +#if defined(__WXMSW__) + case WINDOW: return wxColour(GetSysColor(COLOR_WINDOW)); + + case CONTROL_PRESSED: + case CONTROL_CURRENT: + case CONTROL: return wxColour(GetSysColor(COLOR_BTNFACE)); + + case CONTROL_TEXT: return wxColour(GetSysColor(COLOR_BTNTEXT)); + + case SCROLLBAR: return wxColour(GetSysColor(COLOR_SCROLLBAR)); + case SCROLLBAR_PRESSED: return wxColour(GetSysColor(COLOR_HIGHLIGHT)); + + case HIGHLIGHT: return wxColour(GetSysColor(COLOR_HIGHLIGHT)); + case HIGHLIGHT_TEXT: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT)); + +#if defined(COLOR_3DDKSHADOW) + case SHADOW_DARK: return wxColour(GetSysColor(COLOR_3DDKSHADOW)); +#else + case SHADOW_DARK: return *wxBLACK; +#endif + + case CONTROL_TEXT_DISABLED: + case SHADOW_HIGHLIGHT: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT)); + + case SHADOW_IN: return wxColour(GetSysColor(COLOR_BTNFACE)); + + case CONTROL_TEXT_DISABLED_SHADOW: + case SHADOW_OUT: return wxColour(GetSysColor(COLOR_BTNSHADOW)); + + case TITLEBAR: return wxColour(GetSysColor(COLOR_INACTIVECAPTION)); + case TITLEBAR_ACTIVE: return wxColour(GetSysColor(COLOR_ACTIVECAPTION)); + case TITLEBAR_TEXT: return wxColour(GetSysColor(COLOR_CAPTIONTEXT)); +#else // !__WXMSW__ + // use the standard Windows colours elsewhere case WINDOW: return *wxWHITE; case CONTROL_PRESSED: @@ -1106,14 +1272,19 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const case SHADOW_DARK: return *wxBLACK; - case CONTROL_TEXT_DISABLED: - case SHADOW_HIGHLIGHT: return wxColour(0xe0e0e0); + case CONTROL_TEXT_DISABLED:return wxColour(0xe0e0e0); + case SHADOW_HIGHLIGHT: return wxColour(0xffffff); case SHADOW_IN: return wxColour(0xc0c0c0); case CONTROL_TEXT_DISABLED_SHADOW: case SHADOW_OUT: return wxColour(0x7f7f7f); + case TITLEBAR: return wxColour(0xaeaaae); + case TITLEBAR_ACTIVE: return wxColour(0x820300); + case TITLEBAR_TEXT: return *wxWHITE; +#endif // __WXMSW__ + case MAX: default: wxFAIL_MSG(_T("invalid standard colour")); @@ -1145,6 +1316,9 @@ wxWin32Renderer::wxWin32Renderer(const wxColourScheme *scheme) m_colHighlight = wxSCHEME_COLOUR(scheme, SHADOW_HIGHLIGHT); m_penHighlight = wxPen(m_colHighlight, 0, wxSOLID); + + m_titlebarFont = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT); + m_titlebarFont.SetWeight(wxFONTWEIGHT_BOLD); // init the arrow bitmaps static const size_t ARROW_WIDTH = 7; @@ -1315,6 +1489,13 @@ wxWin32Renderer::wxWin32Renderer(const wxColourScheme *scheme) m_bmpArrows[Arrow_Pressed][n] = m_bmpArrows[Arrow_Normal][n]; } + + // init the frame buttons bitmaps + m_bmpFrameButtons[FrameButton_Close] = wxBitmap(frame_button_close_xpm); + m_bmpFrameButtons[FrameButton_Minimize] = wxBitmap(frame_button_minimize_xpm); + m_bmpFrameButtons[FrameButton_Maximize] = wxBitmap(frame_button_maximize_xpm); + m_bmpFrameButtons[FrameButton_Restore] = wxBitmap(frame_button_restore_xpm); + m_bmpFrameButtons[FrameButton_Help] = wxBitmap(frame_button_help_xpm); } // ---------------------------------------------------------------------------- @@ -2682,6 +2863,7 @@ wxMenuGeometryInfo *wxWin32Renderer::GetMenuGeometry(wxWindow *win, #else // !wxUSE_MENUS +/* void wxWin32Renderer::DrawMenuBarItem(wxDC& WXUNUSED(dc), const wxRect& WXUNUSED(rectOrig), const wxString& WXUNUSED(label), @@ -2718,6 +2900,7 @@ wxWin32Renderer::GetMenuGeometry(wxWindow *WXUNUSED(win), { return NULL; } +*/ #endif // wxUSE_MENUS/!wxUSE_MENUS @@ -2726,6 +2909,7 @@ wxWin32Renderer::GetMenuGeometry(wxWindow *WXUNUSED(win), // ---------------------------------------------------------------------------- void wxWin32Renderer::GetComboBitmaps(wxBitmap *bmpNormal, + wxBitmap *bmpFocus, wxBitmap *bmpPressed, wxBitmap *bmpDisabled) { @@ -2909,6 +3093,192 @@ int wxWin32Renderer::PixelToScrollbar(const wxScrollBar *scrollbar, return StandardPixelToScrollbar(scrollbar, coord, m_sizeScrollbarArrow); } +// ---------------------------------------------------------------------------- +// top level windows +// ---------------------------------------------------------------------------- + +void wxWin32Renderer::DrawFrameTitleBar(wxDC& dc, + const wxRect& rect, + const wxString& title, + const wxIcon& icon, + int flags, + int pressedButtons) +{ + if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) ) + { + DrawFrameBorder(dc, rect, flags); + } + if ( flags & wxTOPLEVEL_TITLEBAR ) + { + DrawFrameBackground(dc, rect, flags); + if ( flags & wxTOPLEVEL_ICON ) + DrawFrameIcon(dc, rect, icon, flags); + DrawFrameTitle(dc, rect, title, flags); + + wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); + wxCoord x,y; + x = client.GetRight() -2 - FRAME_BUTTON_WIDTH; + y = client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2; + + if ( flags & wxTOPLEVEL_CLOSE_BUTTON ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_CLOSE_BUTTON); + x -= FRAME_BUTTON_WIDTH + 2; + } + if ( flags & wxTOPLEVEL_MAXIMIZE_BUTTON ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_MAXIMIZE_BUTTON); + x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_RESTORE_BUTTON ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_RESTORE_BUTTON); + x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_MINIMIZE_BUTTON ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_MINIMIZE_BUTTON); + x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_HELP_BUTTON ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_HELP_BUTTON); + x -= FRAME_BUTTON_WIDTH; + } + } +} + +void wxWin32Renderer::DrawFrameBorder(wxDC& dc, + const wxRect& rect, + int flags) +{ + if ( !(flags & wxTOPLEVEL_BORDER) ) return; + + wxRect r(rect); + + DrawShadedRect(dc, &r, m_penLightGrey, m_penBlack); + DrawShadedRect(dc, &r, m_penHighlight, m_penDarkGrey); + DrawShadedRect(dc, &r, m_penLightGrey, m_penLightGrey); + if ( flags & wxTOPLEVEL_RESIZEABLE ) + DrawShadedRect(dc, &r, m_penLightGrey, m_penLightGrey); +} + +void wxWin32Renderer::DrawFrameBackground(wxDC& dc, + const wxRect& rect, + int flags) +{ + if ( !(flags & wxTOPLEVEL_TITLEBAR) ) return; + + wxColour col = (flags & wxTOPLEVEL_ACTIVE) ? + wxSCHEME_COLOUR(m_scheme, TITLEBAR_ACTIVE) : + wxSCHEME_COLOUR(m_scheme, TITLEBAR); + + wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); + r.height = FRAME_TITLEBAR_HEIGHT; + + DrawBackground(dc, col, r); +} + +void wxWin32Renderer::DrawFrameTitle(wxDC& dc, + const wxRect& rect, + const wxString& title, + int flags) +{ + wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); + r.height = FRAME_TITLEBAR_HEIGHT; + if ( flags & wxTOPLEVEL_ICON ) + r.x += FRAME_TITLEBAR_HEIGHT; + else + r.x += 1; + + dc.SetFont(m_titlebarFont); + dc.SetTextForeground(wxSCHEME_COLOUR(m_scheme, TITLEBAR_TEXT)); + dc.DrawLabel(title, wxNullBitmap, r, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL); +} + +void wxWin32Renderer::DrawFrameIcon(wxDC& dc, + const wxRect& rect, + const wxIcon& icon, + int flags) +{ + wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); + dc.DrawIcon(icon, r.x, r.y); +} + +void wxWin32Renderer::DrawFrameButton(wxDC& dc, + wxCoord x, wxCoord y, + int button, + 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; + default: + wxFAIL_MSG(wxT("incorrect button specification")); + } + + dc.DrawBitmap(m_bmpFrameButtons[idx], r.x, r.y, TRUE); +} + + +wxRect wxWin32Renderer::GetFrameClientArea(const wxRect& rect, + int flags) const +{ + wxRect r(rect); + + if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) ) + { + int border = (flags & wxTOPLEVEL_RESIZEABLE) ? + RESIZEABLE_FRAME_BORDER_THICKNESS : + FRAME_BORDER_THICKNESS; + r.Inflate(-border); + } + if ( flags & wxTOPLEVEL_TITLEBAR ) + { + r.y += FRAME_TITLEBAR_HEIGHT; + r.height -= FRAME_TITLEBAR_HEIGHT; + } + + return r; +} + +wxSize wxWin32Renderer::GetFrameTotalSize(const wxSize& clientSize, + int flags) const +{ + wxSize s(clientSize); + + if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) ) + { + int border = (flags & wxTOPLEVEL_RESIZEABLE) ? + RESIZEABLE_FRAME_BORDER_THICKNESS : + FRAME_BORDER_THICKNESS; + s.x += 2*border; + s.y += 2*border; + } + if ( flags & wxTOPLEVEL_TITLEBAR ) + s.y += FRAME_TITLEBAR_HEIGHT; + + return s; +} + +wxSize wxWin32Renderer::GetFrameIconSize() const +{ + return wxSize(16, 16); +} + + + // ---------------------------------------------------------------------------- // text control geometry // ---------------------------------------------------------------------------- @@ -2975,19 +3345,17 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window) #if wxUSE_BUTTON if ( wxDynamicCast(window, wxButton) ) { - // TODO - size->x += 3*window->GetCharWidth(); -#if 0 // do allow creating small buttons if wanted - wxSize sizeDef = wxButton::GetDefaultSize(); - if ( size->x < sizeDef.x ) - size->x = sizeDef.x; -#endif // 0 - - wxCoord heightBtn = (11*(window->GetCharHeight() + 8))/10; - if ( size->y < heightBtn - 8 ) - size->y = heightBtn; - else - size->y += 9; + if ( !(window->GetWindowStyle() & wxBU_EXACTFIT) ) + { + // TODO: don't harcode all this + size->x += 3*window->GetCharWidth(); + + wxCoord heightBtn = (11*(window->GetCharHeight() + 8))/10; + if ( size->y < heightBtn - 8 ) + size->y = heightBtn; + else + size->y += 9; + } // no border width adjustments for buttons return; @@ -3013,16 +3381,24 @@ wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer *renderer) m_renderer = renderer; } -bool wxWin32InputHandler::HandleKey(wxControl *control, +bool wxWin32InputHandler::HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed) { return FALSE; } -bool wxWin32InputHandler::HandleMouse(wxControl *control, +bool wxWin32InputHandler::HandleMouse(wxInputConsumer *control, const wxMouseEvent& event) { + // clicking on the control gives it focus + if ( event.ButtonDown() && wxWindow::FindFocus() != control->GetInputWindow() ) + { + control->GetInputWindow()->SetFocus(); + + return TRUE; + } + return FALSE; } @@ -3068,7 +3444,7 @@ bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar *scrollbar, return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar, action); } -bool wxWin32ScrollBarInputHandler::HandleMouse(wxControl *control, +bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer *control, const wxMouseEvent& event) { // remember the current state @@ -3088,7 +3464,7 @@ bool wxWin32ScrollBarInputHandler::HandleMouse(wxControl *control, return rc; } -bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxControl *control, +bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer *control, const wxMouseEvent& event) { // we don't highlight scrollbar elements, so there is no need to process @@ -3103,7 +3479,7 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxControl *control, return FALSE; } - wxScrollBar *scrollbar = wxStaticCast(control, wxScrollBar); + wxScrollBar *scrollbar = wxStaticCast(control->GetInputWindow(), wxScrollBar); wxHitTest ht; if ( m_scrollPaused ) { @@ -3195,7 +3571,7 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxControl *control, // wxWin32CheckboxInputHandler // ---------------------------------------------------------------------------- -bool wxWin32CheckboxInputHandler::HandleKey(wxControl *control, +bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed) { @@ -3236,7 +3612,7 @@ bool wxWin32CheckboxInputHandler::HandleKey(wxControl *control, // wxWin32TextCtrlInputHandler // ---------------------------------------------------------------------------- -bool wxWin32TextCtrlInputHandler::HandleKey(wxControl *control, +bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed) {