X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1b4651028a315ed881858165675667fdaef58d6c..9298c435cf9b3f5112de555c46c52c51f1d284bb:/src/univ/themes/win32.cpp diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index 716bcc0ec9..3261e10239 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,17 @@ 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; + +static const size_t NUM_STATUSBAR_GRIP_BANDS = 3; +static const size_t WIDTH_STATUSBAR_GRIP_BAND = 4; +static const size_t STATUSBAR_GRIP_SIZE = + WIDTH_STATUSBAR_GRIP_BAND*NUM_STATUSBAR_GRIP_BANDS; + enum IndicatorType { IndicatorType_Check, @@ -114,6 +129,16 @@ public: Arrow_StateMax }; + enum wxFrameButtonType + { + FrameButton_Close, + FrameButton_Minimize, + FrameButton_Maximize, + FrameButton_Restore, + FrameButton_Help, + FrameButton_Max + }; + // ctor wxWin32Renderer(const wxColourScheme *scheme); @@ -235,7 +260,6 @@ public: int end, int step = 1, int flags = 0); -#if wxUSE_MENUS virtual void DrawMenuBarItem(wxDC& dc, const wxRect& rect, @@ -253,7 +277,45 @@ public: virtual void DrawMenuSeparator(wxDC& dc, wxCoord y, const wxMenuGeometryInfo& geomInfo); -#endif + + virtual void DrawStatusField(wxDC& dc, + const wxRect& rect, + const wxString& label, + int flags = 0); + + // titlebars + virtual void DrawFrameTitleBar(wxDC& dc, + const wxRect& rect, + const wxString& title, + const wxIcon& icon, + int flags, + int specialButton = 0, + int specialButtonFlags = 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 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, @@ -300,11 +362,12 @@ public: wxOrientation orient) const; virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); } -#if wxUSE_MENUS virtual wxSize GetMenuBarItemSize(const wxSize& sizeText) const; virtual wxMenuGeometryInfo *GetMenuGeometry(wxWindow *win, const wxMenu& menu) const; -#endif + + virtual wxSize GetStatusBarBorders(wxCoord *borderBetweenFields) const; + protected: // helper of DrawLabel() and DrawCheckOrRadioButton() void DoDrawLabel(wxDC& dc, @@ -409,6 +472,11 @@ private: 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 +491,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 +507,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 +538,7 @@ public: wxWin32CheckboxInputHandler(wxInputHandler *handler) : wxStdCheckboxInputHandler(handler) { } - virtual bool HandleKey(wxControl *control, + virtual bool HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed); }; @@ -481,11 +549,34 @@ public: wxWin32TextCtrlInputHandler(wxInputHandler *handler) : wxStdTextCtrlInputHandler(handler) { } - virtual bool HandleKey(wxControl *control, + virtual bool HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed); }; +class wxWin32StatusBarInputHandler : public wxStdInputHandler +{ +public: + wxWin32StatusBarInputHandler(wxInputHandler *handler); + + virtual bool HandleMouse(wxInputConsumer *consumer, + const wxMouseEvent& event); + + virtual bool HandleMouseMove(wxInputConsumer *consumer, + const wxMouseEvent& event); + +protected: + // is the given point over the statusbar grip? + bool IsOnGrip(wxWindow *statbar, const wxPoint& pt) const; + +private: + // the cursor we had replaced with the resize one + wxCursor m_cursorOld; + + // was the mouse over the grip last time we checked? + bool m_isOnGrip; +}; + // ---------------------------------------------------------------------------- // wxWin32ColourScheme: uses (default) Win32 colours // ---------------------------------------------------------------------------- @@ -509,7 +600,7 @@ public: wxWin32Theme(); virtual ~wxWin32Theme(); - virtual wxRenderer *GetRenderer() { return m_renderer; } + virtual wxRenderer *GetRenderer(); virtual wxInputHandler *GetInputHandler(const wxString& control); virtual wxColourScheme *GetColourScheme(); @@ -535,6 +626,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[] = { @@ -943,8 +1111,8 @@ WX_IMPLEMENT_THEME(wxWin32Theme, win32, wxTRANSLATE("Win32 theme")); wxWin32Theme::wxWin32Theme() { - m_scheme = new wxWin32ColourScheme; - m_renderer = new wxWin32Renderer(m_scheme); + m_scheme = NULL; + m_renderer = NULL; m_handlerDefault = NULL; } @@ -963,6 +1131,16 @@ wxWin32Theme::~wxWin32Theme() delete m_scheme; } +wxRenderer *wxWin32Theme::GetRenderer() +{ + if ( !m_renderer ) + { + m_renderer = new wxWin32Renderer(GetColourScheme()); + } + + return m_renderer; +} + wxInputHandler *wxWin32Theme::GetDefaultInputHandler() { if ( !m_handlerDefault ) @@ -1019,6 +1197,12 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control) else if ( control == wxINP_HANDLER_NOTEBOOK ) handler = new wxStdNotebookInputHandler(GetDefaultInputHandler()); #endif // wxUSE_NOTEBOOK +#if wxUSE_STATUSBAR + else if ( control == wxINP_HANDLER_STATUSBAR ) + handler = new wxWin32StatusBarInputHandler(GetDefaultInputHandler()); +#endif // wxUSE_STATUSBAR + else if ( control == wxINP_HANDLER_TOPLEVEL ) + handler = new wxStdFrameInputHandler(GetDefaultInputHandler()); else handler = GetDefaultInputHandler(); @@ -1035,6 +1219,10 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control) wxColourScheme *wxWin32Theme::GetColourScheme() { + if ( !m_scheme ) + { + m_scheme = new wxWin32ColourScheme; + } return m_scheme; } @@ -1090,8 +1278,6 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const { switch ( col ) { - case WINDOW: return *wxWHITE; - // use the system colours under Windows #if defined(__WXMSW__) case WINDOW: return wxColour(GetSysColor(COLOR_WINDOW)); @@ -1121,8 +1307,17 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const 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_INACTIVECAPTIONTEXT)); + case TITLEBAR_ACTIVE_TEXT: return wxColour(GetSysColor(COLOR_CAPTIONTEXT)); + + case DESKTOP: return wxColour(0x808000); #else // !__WXMSW__ // use the standard Windows colours elsewhere + case WINDOW: return *wxWHITE; + case CONTROL_PRESSED: case CONTROL_CURRENT: case CONTROL: return wxColour(0xc0c0c0); @@ -1137,13 +1332,20 @@ 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 wxColour(0xc0c0c0); + case TITLEBAR_ACTIVE_TEXT:return *wxWHITE; + + case DESKTOP: return wxColour(0x808000); #endif // __WXMSW__ case MAX: @@ -1178,6 +1380,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; static const size_t ARROW_LENGTH = 4; @@ -1347,6 +1552,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); } // ---------------------------------------------------------------------------- @@ -2356,6 +2568,7 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc, rectInt.SetBottom(y3); rectInt.Deflate(2); +#if !defined(__WXMGL__) static const char *stipple_xpm[] = { /* columns rows colors chars-per-pixel */ "2 2 2 1", @@ -2365,6 +2578,24 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc, "w ", " w", }; +#else + // VS: MGL can only do 8x8 stipple brushes + static const char *stipple_xpm[] = { + /* columns rows colors chars-per-pixel */ + "8 8 2 1", + " c None", + "w c white", + /* pixels */ + "w w w w ", + " w w w w", + "w w w w ", + " w w w w", + "w w w w ", + " w w w w", + "w w w w ", + " w w w w", + }; +#endif dc.SetBrush(wxBrush(stipple_xpm)); dc.SetTextForeground(wxSCHEME_COLOUR(m_scheme, SHADOW_HIGHLIGHT)); @@ -2446,8 +2677,6 @@ void wxWin32Renderer::DrawSliderTicks(wxDC& dc, // menu and menubar // ---------------------------------------------------------------------------- -#if wxUSE_MENUS - // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer class WXDLLEXPORT wxWin32MenuGeometryInfo : public wxMenuGeometryInfo { @@ -2472,12 +2701,10 @@ private: // the height of a normal (not separator) item wxCoord m_heightItem; - friend wxMenuGeometryInfo *wxWin32Renderer:: - GetMenuGeometry(wxWindow *, const wxMenu&) const; + friend wxMenuGeometryInfo * + wxWin32Renderer::GetMenuGeometry(wxWindow *, const wxMenu&) const; }; -#endif // wxUSE_MENUS - // FIXME: all constants are hardcoded but shouldn't be static const wxCoord MENU_LEFT_MARGIN = 9; static const wxCoord MENU_RIGHT_MARGIN = 18; @@ -2497,10 +2724,6 @@ static const wxCoord MENU_SEPARATOR_HEIGHT = 3; // the size of the standard checkmark bitmap static const wxCoord MENU_CHECK_SIZE = 9; -// we can't implement these methods without wxMenuGeometryInfo implementation -// which we don't have if !wxUSE_MENUS -#if wxUSE_MENUS - void wxWin32Renderer::DrawMenuBarItem(wxDC& dc, const wxRect& rectOrig, const wxString& label, @@ -2712,48 +2935,81 @@ wxMenuGeometryInfo *wxWin32Renderer::GetMenuGeometry(wxWindow *win, return gi; } -#else // !wxUSE_MENUS +// ---------------------------------------------------------------------------- +// status bar +// ---------------------------------------------------------------------------- -/* -void wxWin32Renderer::DrawMenuBarItem(wxDC& WXUNUSED(dc), - const wxRect& WXUNUSED(rectOrig), - const wxString& WXUNUSED(label), - int WXUNUSED(flags), - int WXUNUSED(indexAccel)) -{ -} +static const wxCoord STATBAR_BORDER_X = 2; +static const wxCoord STATBAR_BORDER_Y = 2; -void wxWin32Renderer::DrawMenuItem(wxDC& WXUNUSED(dc), - wxCoord WXUNUSED(y), - const wxMenuGeometryInfo& WXUNUSED(gi), - const wxString& WXUNUSED(label), - const wxString& WXUNUSED(accel), - const wxBitmap& WXUNUSED(bitmap), - int WXUNUSED(flags), - int WXUNUSED(indexAccel)) +wxSize wxWin32Renderer::GetStatusBarBorders(wxCoord *borderBetweenFields) const { -} + if ( borderBetweenFields ) + *borderBetweenFields = 2; -void wxWin32Renderer::DrawMenuSeparator(wxDC& WXUNUSED(dc), - wxCoord WXUNUSED(y), - const wxMenuGeometryInfo& WXUNUSED(gi)) -{ + return wxSize(STATBAR_BORDER_X, STATBAR_BORDER_Y); } -wxSize wxWin32Renderer::GetMenuBarItemSize(const wxSize& size) const +void wxWin32Renderer::DrawStatusField(wxDC& dc, + const wxRect& rect, + const wxString& label, + int flags) { - return size; -} + wxRect rectIn; -wxMenuGeometryInfo * -wxWin32Renderer::GetMenuGeometry(wxWindow *WXUNUSED(win), - const wxMenu& WXUNUSED(menu)) const -{ - return NULL; -} -*/ + if ( flags & wxCONTROL_ISDEFAULT ) + { + // draw the size grip: it is a normal rect except that in the lower + // right corner we have several bands which may be used for dragging + // the status bar corner + // + // each band consists of 4 stripes: m_penHighlight, double + // m_penDarkGrey and transparent one + wxCoord x2 = rect.GetRight(), + y2 = rect.GetBottom(); + + // draw the upper left part of the rect normally + dc.SetPen(m_penDarkGrey); + dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), y2); + dc.DrawLine(rect.GetLeft() + 1, rect.GetTop(), x2, rect.GetTop()); + + // draw the grey stripes of the grip + size_t n; + wxCoord ofs = WIDTH_STATUSBAR_GRIP_BAND - 1; + for ( n = 0; n < NUM_STATUSBAR_GRIP_BANDS; n++, ofs += WIDTH_STATUSBAR_GRIP_BAND ) + { + dc.DrawLine(x2 - ofs + 1, y2 - 1, x2, y2 - ofs); + dc.DrawLine(x2 - ofs, y2 - 1, x2, y2 - ofs - 1); + } -#endif // wxUSE_MENUS/!wxUSE_MENUS + // draw the white stripes + dc.SetPen(m_penHighlight); + ofs = WIDTH_STATUSBAR_GRIP_BAND + 1; + for ( n = 0; n < NUM_STATUSBAR_GRIP_BANDS; n++, ofs += WIDTH_STATUSBAR_GRIP_BAND ) + { + dc.DrawLine(x2 - ofs + 1, y2 - 1, x2, y2 - ofs); + } + + // draw the remaining rect boundaries + ofs -= WIDTH_STATUSBAR_GRIP_BAND; + dc.DrawLine(x2, rect.GetTop(), x2, y2 - ofs + 1); + dc.DrawLine(rect.GetLeft(), y2, x2 - ofs + 1, y2); + + rectIn = rect; + rectIn.Deflate(1); + + rectIn.width -= STATUSBAR_GRIP_SIZE; + } + else // normal pane + { + DrawBorder(dc, wxBORDER_STATIC, rect, flags, &rectIn); + } + + rectIn.Deflate(STATBAR_BORDER_X, STATBAR_BORDER_Y); + + wxDCClipper clipper(dc, rectIn); + DrawLabel(dc, label, rectIn, flags, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL); +} // ---------------------------------------------------------------------------- // combobox @@ -2944,6 +3200,484 @@ int wxWin32Renderer::PixelToScrollbar(const wxScrollBar *scrollbar, return StandardPixelToScrollbar(scrollbar, coord, m_sizeScrollbarArrow); } +// ---------------------------------------------------------------------------- +// top level windows +// ---------------------------------------------------------------------------- + +int wxWin32Renderer::HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const +{ + wxRect client = GetFrameClientArea(rect, flags); + + if ( client.Inside(pt) ) + return wxHT_TOPLEVEL_CLIENT_AREA; + + if ( flags & wxTOPLEVEL_TITLEBAR ) + { + wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); + + if ( flags & wxTOPLEVEL_ICON ) + { + if ( wxRect(client.GetPosition(), GetFrameIconSize()).Inside(pt) ) + return wxHT_TOPLEVEL_ICON; + } + + wxRect btnRect(client.GetRight() - 2 - FRAME_BUTTON_WIDTH, + client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2, + FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT); + + if ( flags & wxTOPLEVEL_BUTTON_CLOSE ) + { + if ( btnRect.Inside(pt) ) + return wxHT_TOPLEVEL_BUTTON_CLOSE; + btnRect.x -= FRAME_BUTTON_WIDTH + 2; + } + if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE ) + { + if ( btnRect.Inside(pt) ) + return wxHT_TOPLEVEL_BUTTON_MAXIMIZE; + btnRect.x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_BUTTON_RESTORE ) + { + if ( btnRect.Inside(pt) ) + return wxHT_TOPLEVEL_BUTTON_RESTORE; + btnRect.x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_BUTTON_ICONIZE ) + { + if ( btnRect.Inside(pt) ) + return wxHT_TOPLEVEL_BUTTON_ICONIZE; + btnRect.x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_BUTTON_HELP ) + { + if ( btnRect.Inside(pt) ) + return wxHT_TOPLEVEL_BUTTON_HELP; + btnRect.x -= FRAME_BUTTON_WIDTH; + } + + if ( pt.y >= client.y && pt.y < client.y + FRAME_TITLEBAR_HEIGHT ) + return wxHT_TOPLEVEL_TITLEBAR; + } + + if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) ) + { + // we are certainly at one of borders, lets decide which one: + + int border = 0; + // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined! + if ( pt.x < client.x ) + border |= wxHT_TOPLEVEL_BORDER_W; + else if ( pt.x >= client.width + client.x ) + border |= wxHT_TOPLEVEL_BORDER_E; + if ( pt.y < client.y ) + border |= wxHT_TOPLEVEL_BORDER_N; + else if ( pt.y >= client.height + client.y ) + border |= wxHT_TOPLEVEL_BORDER_S; + return border; + } + + return wxHT_NOWHERE; +} + +void wxWin32Renderer::DrawFrameTitleBar(wxDC& dc, + const wxRect& rect, + const wxString& title, + const wxIcon& icon, + int flags, + int specialButton, + int specialButtonFlags) +{ + 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_BUTTON_CLOSE ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_CLOSE, + (specialButton == wxTOPLEVEL_BUTTON_CLOSE) ? + specialButtonFlags : 0); + x -= FRAME_BUTTON_WIDTH + 2; + } + if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_MAXIMIZE, + (specialButton == wxTOPLEVEL_BUTTON_MAXIMIZE) ? + specialButtonFlags : 0); + x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_BUTTON_RESTORE ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_RESTORE, + (specialButton == wxTOPLEVEL_BUTTON_RESTORE) ? + specialButtonFlags : 0); + x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_BUTTON_ICONIZE ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_ICONIZE, + (specialButton == wxTOPLEVEL_BUTTON_ICONIZE) ? + specialButtonFlags : 0); + x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_BUTTON_HELP ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_HELP, + (specialButton == wxTOPLEVEL_BUTTON_HELP) ? + specialButtonFlags : 0); + 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) +{ + wxColour col = (flags & wxTOPLEVEL_ACTIVE) ? + wxSCHEME_COLOUR(m_scheme, TITLEBAR_ACTIVE_TEXT) : + wxSCHEME_COLOUR(m_scheme, TITLEBAR_TEXT); + + 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(col); + dc.DrawLabel(title, wxNullBitmap, r, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL); +} + +void wxWin32Renderer::DrawFrameIcon(wxDC& dc, + const wxRect& rect, + const wxIcon& icon, + int flags) +{ + if ( icon.Ok() ) + { + 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); + + size_t idx = 0; + switch (button) + { + case wxTOPLEVEL_BUTTON_CLOSE: idx = FrameButton_Close; break; + case wxTOPLEVEL_BUTTON_MAXIMIZE: idx = FrameButton_Maximize; break; + case wxTOPLEVEL_BUTTON_ICONIZE: idx = FrameButton_Minimize; break; + case wxTOPLEVEL_BUTTON_RESTORE: idx = FrameButton_Restore; break; + case wxTOPLEVEL_BUTTON_HELP: idx = FrameButton_Help; break; + default: + wxFAIL_MSG(wxT("incorrect button specification")); + } + + if ( flags & wxCONTROL_PRESSED ) + { + DrawShadedRect(dc, &r, m_penBlack, m_penHighlight); + DrawShadedRect(dc, &r, m_penDarkGrey, m_penLightGrey); + DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), r); + dc.DrawBitmap(m_bmpFrameButtons[idx], r.x+1, r.y+1, TRUE); + } + else + { + DrawShadedRect(dc, &r, m_penHighlight, m_penBlack); + DrawShadedRect(dc, &r, m_penLightGrey, m_penDarkGrey); + DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), r); + 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); +} + + +// ---------------------------------------------------------------------------- +// standard icons +// ---------------------------------------------------------------------------- + +static char *error_xpm[]={ +"32 32 5 1", +". c None", +"# c #800000", +"b c #808080", +"a c #ff0000", +"c c #ffffff", +"...........########.............", +"........###aaaaaaaa###..........", +".......#aaaaaaaaaaaaaa#.........", +".....##aaaaaaaaaaaaaaaa##.......", +"....#aaaaaaaaaaaaaaaaaaaa#......", +"...#aaaaaaaaaaaaaaaaaaaaaa#.....", +"...#aaaaaaaaaaaaaaaaaaaaaa#b....", +"..#aaaaaacaaaaaaaaaacaaaaaa#b...", +".#aaaaaacccaaaaaaaacccaaaaaa#...", +".#aaaaacccccaaaaaacccccaaaaa#b..", +".#aaaaaacccccaaaacccccaaaaaa#bb.", +"#aaaaaaaacccccaacccccaaaaaaaa#b.", +"#aaaaaaaaaccccccccccaaaaaaaaa#b.", +"#aaaaaaaaaaccccccccaaaaaaaaaa#bb", +"#aaaaaaaaaaaccccccaaaaaaaaaaa#bb", +"#aaaaaaaaaaaccccccaaaaaaaaaaa#bb", +"#aaaaaaaaaaccccccccaaaaaaaaaa#bb", +"#aaaaaaaaaccccccccccaaaaaaaaa#bb", +"#aaaaaaaacccccaacccccaaaaaaaa#bb", +".#aaaaaacccccaaaacccccaaaaaa#bbb", +".#aaaaacccccaaaaaacccccaaaaa#bbb", +".#aaaaaacccaaaaaaaacccaaaaaa#bb.", +"..#aaaaaacaaaaaaaaaacaaaaaa#bbb.", +"...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.", +"...#aaaaaaaaaaaaaaaaaaaaaa#bbb..", +"....#aaaaaaaaaaaaaaaaaaaa#bbb...", +".....##aaaaaaaaaaaaaaaa##bbbb...", +"......b#aaaaaaaaaaaaaa#bbbbb....", +".......b###aaaaaaaa###bbbbb.....", +".........bb########bbbbbb.......", +"..........bbbbbbbbbbbbbb........", +".............bbbbbbbb..........."}; + +static char *info_xpm[]={ +"32 32 6 1", +". c None", +"d c #000000", +"c c #0000ff", +"# c #808080", +"a c #c0c0c0", +"b c #ffffff", +"...........########.............", +"........###abbbbbba###..........", +"......##abbbbbbbbbbbba##........", +".....#abbbbbbbbbbbbbbbba#.......", +"....#bbbbbbbaccccabbbbbbbd......", +"...#bbbbbbbbccccccbbbbbbbbd.....", +"..#bbbbbbbbbccccccbbbbbbbbbd....", +".#abbbbbbbbbaccccabbbbbbbbbad...", +".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..", +"#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.", +"#bbbbbbbbbbcccccccbbbbbbbbbbbd#.", +"#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", +"#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", +"#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", +"#bbbbbbbbbbbbcccccbbbbbbbbbbbd##", +"#abbbbbbbbbbbcccccbbbbbbbbbbad##", +".#bbbbbbbbbbbcccccbbbbbbbbbbd###", +".#abbbbbbbbbbcccccbbbbbbbbbad###", +"..#bbbbbbbbcccccccccbbbbbbbd###.", +"...dbbbbbbbbbbbbbbbbbbbbbbd####.", +"....dbbbbbbbbbbbbbbbbbbbbd####..", +".....dabbbbbbbbbbbbbbbbad####...", +"......ddabbbbbbbbbbbbadd####....", +".......#dddabbbbbbaddd#####.....", +"........###dddabbbd#######......", +"..........####dbbbd#####........", +".............#dbbbd##...........", +"...............dbbd##...........", +"................dbd##...........", +".................dd##...........", +"..................###...........", +"...................##..........."}; + +static char *question_xpm[]={ +"32 32 6 1", +". c None", +"c c #000000", +"d c #0000ff", +"# c #808080", +"a c #c0c0c0", +"b c #ffffff", +"...........########.............", +"........###abbbbbba###..........", +"......##abbbbbbbbbbbba##........", +".....#abbbbbbbbbbbbbbbba#.......", +"....#bbbbbbbbbbbbbbbbbbbbc......", +"...#bbbbbbbaddddddabbbbbbbc.....", +"..#bbbbbbbadabbddddabbbbbbbc....", +".#abbbbbbbddbbbbddddbbbbbbbac...", +".#bbbbbbbbddddbbddddbbbbbbbbc#..", +"#abbbbbbbbddddbaddddbbbbbbbbac#.", +"#bbbbbbbbbaddabddddbbbbbbbbbbc#.", +"#bbbbbbbbbbbbbadddbbbbbbbbbbbc##", +"#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##", +"#bbbbbbbbbbbbbddabbbbbbbbbbbbc##", +"#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##", +"#abbbbbbbbbbbbbbbbbbbbbbbbbbac##", +".#bbbbbbbbbbbaddabbbbbbbbbbbc###", +".#abbbbbbbbbbddddbbbbbbbbbbac###", +"..#bbbbbbbbbbddddbbbbbbbbbbc###.", +"...cbbbbbbbbbaddabbbbbbbbbc####.", +"....cbbbbbbbbbbbbbbbbbbbbc####..", +".....cabbbbbbbbbbbbbbbbac####...", +"......ccabbbbbbbbbbbbacc####....", +".......#cccabbbbbbaccc#####.....", +"........###cccabbbc#######......", +"..........####cbbbc#####........", +".............#cbbbc##...........", +"...............cbbc##...........", +"................cbc##...........", +".................cc##...........", +"..................###...........", +"...................##..........."}; + +static char *warning_xpm[]={ +"32 32 6 1", +". c None", +"c c #000000", +"# c #808000", +"d c #808080", +"b c #c0c0c0", +"a c #ffff00", +".............###................", +"............#aabc...............", +"...........#aaaabcd.............", +"...........#aaaaacdd............", +"..........#aaaaaabcdd...........", +"..........#aaaaaaacdd...........", +".........#aaaaaaaabcdd..........", +".........#aaaaaaaaacdd..........", +"........#aaaaaaaaaabcdd.........", +"........#aaabcccbaaacdd.........", +".......#aaaacccccaaabcdd........", +".......#aaaacccccaaaacdd........", +"......#aaaaacccccaaaabcdd.......", +"......#aaaaacccccaaaaacdd.......", +".....#aaaaaacccccaaaaabcdd......", +".....#aaaaaa#ccc#aaaaaacdd......", +"....#aaaaaaabcccbaaaaaabcdd.....", +"....#aaaaaaaacccaaaaaaaacdd.....", +"...#aaaaaaaaa#c#aaaaaaaabcdd....", +"...#aaaaaaaaabcbaaaaaaaaacdd....", +"..#aaaaaaaaaaacaaaaaaaaaabcdd...", +"..#aaaaaaaaaaaaaaaaaaaaaaacdd...", +".#aaaaaaaaaaabccbaaaaaaaaabcdd..", +".#aaaaaaaaaaaccccaaaaaaaaaacdd..", +"#aaaaaaaaaaaaccccaaaaaaaaaabcdd.", +"#aaaaaaaaaaaabccbaaaaaaaaaaacdd.", +"#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd", +"#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd", +".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd", +"..#ccccccccccccccccccccccccddddd", +"....ddddddddddddddddddddddddddd.", +".....ddddddddddddddddddddddddd.."}; + +wxIcon wxWin32Renderer::GetStdIcon(int which) const +{ + 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); + } +} + + // ---------------------------------------------------------------------------- // text control geometry // ---------------------------------------------------------------------------- @@ -3046,16 +3780,28 @@ 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 *win = control->GetInputWindow(); + if ( wxWindow::FindFocus() != control->GetInputWindow() ) + { + win->SetFocus(); + + return TRUE; + } + } + return FALSE; } @@ -3101,7 +3847,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 @@ -3121,7 +3867,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 @@ -3136,7 +3882,7 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxControl *control, return FALSE; } - wxScrollBar *scrollbar = wxStaticCast(control, wxScrollBar); + wxScrollBar *scrollbar = wxStaticCast(control->GetInputWindow(), wxScrollBar); wxHitTest ht; if ( m_scrollPaused ) { @@ -3228,7 +3974,7 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxControl *control, // wxWin32CheckboxInputHandler // ---------------------------------------------------------------------------- -bool wxWin32CheckboxInputHandler::HandleKey(wxControl *control, +bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed) { @@ -3269,7 +4015,7 @@ bool wxWin32CheckboxInputHandler::HandleKey(wxControl *control, // wxWin32TextCtrlInputHandler // ---------------------------------------------------------------------------- -bool wxWin32TextCtrlInputHandler::HandleKey(wxControl *control, +bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed) { @@ -3303,3 +4049,81 @@ bool wxWin32TextCtrlInputHandler::HandleKey(wxControl *control, return wxStdTextCtrlInputHandler::HandleKey(control, event, pressed); } +// ---------------------------------------------------------------------------- +// wxWin32StatusBarInputHandler +// ---------------------------------------------------------------------------- + +wxWin32StatusBarInputHandler:: +wxWin32StatusBarInputHandler(wxInputHandler *handler) + : wxStdInputHandler(handler) +{ + m_isOnGrip = FALSE; +} + +bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow *statbar, + const wxPoint& pt) const +{ + if ( statbar->HasFlag(wxST_SIZEGRIP) && + statbar->GetParent()->HasFlag(wxRESIZE_BORDER) ) + { + wxSize sizeSbar = statbar->GetSize(); + + return (sizeSbar.x - pt.x) < (wxCoord)STATUSBAR_GRIP_SIZE && + (sizeSbar.y - pt.y) < (wxCoord)STATUSBAR_GRIP_SIZE; + } + + return FALSE; +} + +bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer *consumer, + const wxMouseEvent& event) +{ + if ( event.Button(1) ) + { + if ( event.ButtonDown(1) ) + { + wxWindow *statbar = consumer->GetInputWindow(); + + if ( IsOnGrip(statbar, event.GetPosition()) ) + { + wxTopLevelWindow *tlw = wxDynamicCast(statbar->GetParent(), + wxTopLevelWindow); + if ( tlw ) + { + tlw->PerformAction(wxACTION_TOPLEVEL_RESIZE, + wxHT_TOPLEVEL_BORDER_SE); + + statbar->SetCursor(m_cursorOld); + + return TRUE; + } + } + } + } + + return wxStdInputHandler::HandleMouse(consumer, event); +} + +bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer *consumer, + const wxMouseEvent& event) +{ + wxWindow *statbar = consumer->GetInputWindow(); + + bool isOnGrip = IsOnGrip(statbar, event.GetPosition()); + if ( isOnGrip != m_isOnGrip ) + { + m_isOnGrip = isOnGrip; + if ( isOnGrip ) + { + m_cursorOld = statbar->GetCursor(); + statbar->SetCursor(wxCURSOR_SIZENWSE); + } + else + { + statbar->SetCursor(m_cursorOld); + } + } + + return wxStdInputHandler::HandleMouseMove(consumer, event); +} +