X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1629fb3b72c5e0aaf9ea291400f9748ef1763c32..16d865f756b8bc251467139b3b75752219ab97bd:/src/univ/themes/win32.cpp diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index 997c95c089..4142f5940f 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,8 +277,48 @@ 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 GetFrameMinSize(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, wxBitmap *bmpDisabled); @@ -299,11 +363,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, @@ -408,6 +473,19 @@ private: m_penLightGrey, m_penHighlight; + wxFont m_titlebarFont; + + // the checked and unchecked bitmaps for DrawCheckItem() + wxBitmap m_bmpCheckBitmaps[IndicatorStatus_Max]; + + // the bitmaps returned by GetIndicator() + wxBitmap m_bmpIndicators[IndicatorType_Max] + [IndicatorState_Max] + [IndicatorStatus_Max]; + + // 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]; }; @@ -422,10 +500,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: @@ -438,8 +516,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); @@ -469,7 +547,7 @@ public: wxWin32CheckboxInputHandler(wxInputHandler *handler) : wxStdCheckboxInputHandler(handler) { } - virtual bool HandleKey(wxControl *control, + virtual bool HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed); }; @@ -480,11 +558,44 @@ 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; +}; + +class wxWin32FrameInputHandler : public wxStdFrameInputHandler +{ +public: + wxWin32FrameInputHandler(wxInputHandler *handler) + : wxStdFrameInputHandler(handler) { } + + virtual bool HandleMouse(wxInputConsumer *control, + const wxMouseEvent& event); +}; + // ---------------------------------------------------------------------------- // wxWin32ColourScheme: uses (default) Win32 colours // ---------------------------------------------------------------------------- @@ -508,7 +619,7 @@ public: wxWin32Theme(); virtual ~wxWin32Theme(); - virtual wxRenderer *GetRenderer() { return m_renderer; } + virtual wxRenderer *GetRenderer(); virtual wxInputHandler *GetInputHandler(const wxString& control); virtual wxColourScheme *GetColourScheme(); @@ -534,6 +645,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[] = { @@ -888,7 +1076,7 @@ static const char *pressed_unchecked_radio_xpm[] = { }; static const char ** - bmpIndicators[IndicatorType_Max][IndicatorState_Max][IndicatorStatus_Max] = + xpmIndicators[IndicatorType_Max][IndicatorState_Max][IndicatorStatus_Max] = { // checkboxes first { @@ -930,6 +1118,12 @@ static const char ** } }; +static const char **xpmChecked[IndicatorStatus_Max] = +{ + checked_item_xpm, + unchecked_item_xpm +}; + // ============================================================================ // implementation // ============================================================================ @@ -942,8 +1136,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; } @@ -962,6 +1156,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 ) @@ -1018,6 +1222,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 wxWin32FrameInputHandler(GetDefaultInputHandler()); else handler = GetDefaultInputHandler(); @@ -1034,6 +1244,10 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control) wxColourScheme *wxWin32Theme::GetColourScheme() { + if ( !m_scheme ) + { + m_scheme = new wxWin32ColourScheme; + } return m_scheme; } @@ -1072,7 +1286,7 @@ wxColour wxWin32ColourScheme::GetBackground(wxWindow *win) const // the colour set by the user should be used for the normal state // and for the states for which we don't have any specific colours - if ( !col.Ok() || (flags != 0) ) + if ( !col.Ok() || (flags & wxCONTROL_PRESSED) != 0 ) { if ( wxDynamicCast(win, wxScrollBar) ) col = Get(flags & wxCONTROL_PRESSED ? SCROLLBAR_PRESSED @@ -1089,6 +1303,44 @@ 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 wxColour(GetSysColor(COLOR_3DHADOW)); +#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_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: @@ -1105,14 +1357,24 @@ 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 GAUGE: return Get(HIGHLIGHT); + case MAX: default: wxFAIL_MSG(_T("invalid standard colour")); @@ -1145,6 +1407,9 @@ wxWin32Renderer::wxWin32Renderer(const wxColourScheme *scheme) m_colHighlight = wxSCHEME_COLOUR(scheme, SHADOW_HIGHLIGHT); m_penHighlight = wxPen(m_colHighlight, 0, wxSOLID); + m_titlebarFont = wxSystemSettings::GetFont(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; @@ -1314,6 +1579,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); } // ---------------------------------------------------------------------------- @@ -1913,8 +2185,16 @@ void wxWin32Renderer::DrawCheckItem(wxDC& dc, } else // use default bitmap { - bmp = wxBitmap(flags & wxCONTROL_CHECKED ? checked_item_xpm - : unchecked_item_xpm); + IndicatorStatus i = flags & wxCONTROL_CHECKED + ? IndicatorStatus_Checked + : IndicatorStatus_Unchecked; + + if ( !m_bmpCheckBitmaps[i].Ok() ) + { + m_bmpCheckBitmaps[i] = wxBitmap(xpmChecked[i]); + } + + bmp = m_bmpCheckBitmaps[i]; } dc.DrawBitmap(bmp, rect.x, rect.y + (rect.height - bmp.GetHeight()) / 2 - 1, @@ -1949,8 +2229,19 @@ wxBitmap wxWin32Renderer::GetIndicator(IndicatorType indType, int flags) ? IndicatorStatus_Checked : IndicatorStatus_Unchecked; - const char **xpm = bmpIndicators[indType][indState][indStatus]; - return xpm ? wxBitmap(xpm) : wxNullBitmap; + wxBitmap bmp = m_bmpIndicators[indType][indState][indStatus]; + if ( !bmp.Ok() ) + { + const char **xpm = xpmIndicators[indType][indState][indStatus]; + if ( xpm ) + { + // create and cache it + bmp = wxBitmap(xpm); + m_bmpIndicators[indType][indState][indStatus] = bmp; + } + } + + return bmp; } void wxWin32Renderer::DrawCheckOrRadioButton(wxDC& dc, @@ -2009,8 +2300,14 @@ void wxWin32Renderer::DrawRadioButton(wxDC& dc, wxAlignment align, int indexAccel) { + wxBitmap bmp; + if ( bitmap.Ok() ) + bmp = bitmap; + else + bmp = GetRadioBitmap(flags); + DrawCheckOrRadioButton(dc, label, - bitmap.Ok() ? bitmap : GetRadioBitmap(flags), + bmp, rect, flags, align, indexAccel, FOCUS_RECT_OFFSET_Y); // default focus rect offset } @@ -2023,8 +2320,14 @@ void wxWin32Renderer::DrawCheckButton(wxDC& dc, wxAlignment align, int indexAccel) { + wxBitmap bmp; + if ( bitmap.Ok() ) + bmp = bitmap; + else + bmp = GetCheckBitmap(flags); + DrawCheckOrRadioButton(dc, label, - bitmap.Ok() ? bitmap : GetCheckBitmap(flags), + bmp, rect, flags, align, indexAccel, 0); // no focus rect offset for checkboxes } @@ -2323,6 +2626,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", @@ -2332,6 +2636,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)); @@ -2413,8 +2735,6 @@ void wxWin32Renderer::DrawSliderTicks(wxDC& dc, // menu and menubar // ---------------------------------------------------------------------------- -#if wxUSE_MENUS - // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer class WXDLLEXPORT wxWin32MenuGeometryInfo : public wxMenuGeometryInfo { @@ -2439,12 +2759,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; @@ -2464,10 +2782,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, @@ -2593,7 +2907,7 @@ wxMenuGeometryInfo *wxWin32Renderer::GetMenuGeometry(wxWindow *win, { // prepare the dc: for now we draw all the items with the system font wxClientDC dc(win); - dc.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); // the height of a normal item wxCoord heightText = dc.GetCharHeight(); @@ -2679,54 +2993,88 @@ 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); + } + + // 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); + } -#endif // wxUSE_MENUS/!wxUSE_MENUS + rectIn.Deflate(STATBAR_BORDER_X, STATBAR_BORDER_Y); + + wxDCClipper clipper(dc, rectIn); + DrawLabel(dc, label, rectIn, flags, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL); +} // ---------------------------------------------------------------------------- // combobox // ---------------------------------------------------------------------------- void wxWin32Renderer::GetComboBitmaps(wxBitmap *bmpNormal, + wxBitmap *bmpFocus, wxBitmap *bmpPressed, wxBitmap *bmpDisabled) { @@ -2910,6 +3258,567 @@ 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; + r.width -= FRAME_TITLEBAR_HEIGHT + 2; + } + else + { + r.x += 1; + r.width -= 3; + } + + if ( flags & wxTOPLEVEL_BUTTON_CLOSE ) + r.width -= FRAME_BUTTON_WIDTH + 2; + if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE ) + r.width -= FRAME_BUTTON_WIDTH; + if ( flags & wxTOPLEVEL_BUTTON_RESTORE ) + r.width -= FRAME_BUTTON_WIDTH; + if ( flags & wxTOPLEVEL_BUTTON_ICONIZE ) + r.width -= FRAME_BUTTON_WIDTH; + if ( flags & wxTOPLEVEL_BUTTON_HELP ) + r.width -= FRAME_BUTTON_WIDTH; + + dc.SetFont(m_titlebarFont); + dc.SetTextForeground(col); + + wxCoord textW; + dc.GetTextExtent(title, &textW, NULL); + if ( textW > r.width ) + { + // text is too big, let's shorten it and add "..." after it: + size_t len = title.length(); + wxCoord WSoFar, letterW; + + dc.GetTextExtent(wxT("..."), &WSoFar, NULL); + if ( WSoFar > r.width ) + { + // not enough space to draw anything + return; + } + + wxString s; + s.Alloc(len); + for (size_t i = 0; i < len; i++) + { + dc.GetTextExtent(title[i], &letterW, NULL); + if ( letterW + WSoFar > r.width ) + break; + WSoFar += letterW; + s << title[i]; + } + s << wxT("..."); + dc.DrawLabel(s, wxNullBitmap, r, + wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL); + } + else + 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::GetFrameMinSize(int flags) const +{ + wxSize s(0, 0); + + 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; + + if ( flags & wxTOPLEVEL_ICON ) + s.x += FRAME_TITLEBAR_HEIGHT + 2; + if ( flags & wxTOPLEVEL_BUTTON_CLOSE ) + s.x += FRAME_BUTTON_WIDTH + 2; + if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE ) + s.x += FRAME_BUTTON_WIDTH; + if ( flags & wxTOPLEVEL_BUTTON_RESTORE ) + s.x += FRAME_BUTTON_WIDTH; + if ( flags & wxTOPLEVEL_BUTTON_ICONIZE ) + s.x += FRAME_BUTTON_WIDTH; + if ( flags & wxTOPLEVEL_BUTTON_HELP ) + s.x += FRAME_BUTTON_WIDTH; + } + + 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 // ---------------------------------------------------------------------------- @@ -2976,19 +3885,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; @@ -3014,16 +3921,29 @@ 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; } @@ -3069,7 +3989,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 @@ -3089,7 +4009,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 @@ -3104,7 +4024,7 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxControl *control, return FALSE; } - wxScrollBar *scrollbar = wxStaticCast(control, wxScrollBar); + wxScrollBar *scrollbar = wxStaticCast(control->GetInputWindow(), wxScrollBar); wxHitTest ht; if ( m_scrollPaused ) { @@ -3196,7 +4116,7 @@ bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxControl *control, // wxWin32CheckboxInputHandler // ---------------------------------------------------------------------------- -bool wxWin32CheckboxInputHandler::HandleKey(wxControl *control, +bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed) { @@ -3237,7 +4157,7 @@ bool wxWin32CheckboxInputHandler::HandleKey(wxControl *control, // wxWin32TextCtrlInputHandler // ---------------------------------------------------------------------------- -bool wxWin32TextCtrlInputHandler::HandleKey(wxControl *control, +bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer *control, const wxKeyEvent& event, bool pressed) { @@ -3271,3 +4191,122 @@ 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) ) + { + wxTopLevelWindow * + parentTLW = wxDynamicCast(statbar->GetParent(), wxTopLevelWindow); + + wxCHECK_MSG( parentTLW, FALSE, + _T("the status bar should be a child of a TLW") ); + + // a maximized window can't be resized anyhow + if ( !parentTLW->IsMaximized() ) + { + // VZ: I think that the standard Windows behaviour is to only + // show the resizing cursor when the mouse is on top of the + // grip itself but apparently different Windows versions behave + // differently (?) and it seems a better UI to allow resizing + // the status bar even when the mouse is above the grip + wxSize sizeSbar = statbar->GetSize(); + + int diff = sizeSbar.x - pt.x; + return diff >= 0 && diff < (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); +} + +// ---------------------------------------------------------------------------- +// wxWin32FrameInputHandler +// ---------------------------------------------------------------------------- + +bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer, + const wxMouseEvent& event) +{ + if ( event.LeftDClick() ) + { + wxTopLevelWindow *tlw = + wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow); + + long hit = tlw->HitTest(event.GetPosition()); + + if ( hit == wxHT_TOPLEVEL_TITLEBAR ) + { + tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK, + tlw->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE + : wxTOPLEVEL_BUTTON_MAXIMIZE); + return TRUE; + } + } + + return wxStdFrameInputHandler::HandleMouse(consumer, event); +} +