diff --git a/include/wx/univ/renderer.h b/include/wx/univ/renderer.h index 20bfe6c343..aa9e332cfa 100644 --- a/include/wx/univ/renderer.h +++ b/include/wx/univ/renderer.h @@ -161,13 +161,9 @@ public: // the left/top side, width/heigh - of the right/bottom one virtual wxRect GetBorderDimensions(wxBorder border) const = 0; - // the scrollbar rectangle may need adjusting if the window has the border - // as the renderer might wish to combine the scrollbar border and the - // window one - virtual void AdjustScrollbar(wxOrientation orient, - wxBorder border, - bool hasOtherScrollbar, - wxRect* rect) const = 0; + // the scrollbars may be drawn either inside the window border or outside + // it - this function is used to decide how to draw them + virtual bool AreScrollbarsInsideBorder() const = 0; // adjust the size of the control of the given class: for most controls, // this just takes into account the border, but for some (buttons, for @@ -316,11 +312,8 @@ public: { m_renderer->AdjustSize(size, window); } virtual wxRect GetBorderDimensions(wxBorder border) const { return m_renderer->GetBorderDimensions(border); } - virtual void AdjustScrollbar(wxOrientation orient, - wxBorder border, - bool hasOtherScrollbar, - wxRect* rect) const - { m_renderer->AdjustScrollbar(orient, border, hasOtherScrollbar, rect); } + virtual bool AreScrollbarsInsideBorder() const + { return m_renderer->AreScrollbarsInsideBorder(); } virtual wxRect GetScrollbarRect(const wxScrollBar *scrollbar, wxScrollBar::Element elem, diff --git a/include/wx/univ/theme.h b/include/wx/univ/theme.h index faa0befc0f..db65d9b5bb 100644 --- a/include/wx/univ/theme.h +++ b/include/wx/univ/theme.h @@ -118,7 +118,7 @@ struct WXDLLEXPORT wxThemeInfo // and this one must be inserted in the source file #define WX_IMPLEMENT_THEME(classname, themename, themedesc) \ - extern bool wxThemeUse##themename = TRUE; \ + bool wxThemeUse##themename = TRUE; \ wxTheme *wxCtorFor##themename() { return new classname; } \ wxThemeInfo classname::ms_info##themename(wxCtorFor##themename, \ #themename, themedesc) diff --git a/samples/univ/univ.cpp b/samples/univ/univ.cpp index bac9da5e04..f63cb9917c 100644 --- a/samples/univ/univ.cpp +++ b/samples/univ/univ.cpp @@ -213,7 +213,7 @@ bool MyUnivApp::OnInit() // ---------------------------------------------------------------------------- MyUnivFrame::MyUnivFrame(const wxString& title) - : wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(700, 600)) + : wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(700, 700)) { SetBackgroundColour(wxGetApp().GetBgColour()); @@ -334,7 +334,10 @@ MyUnivFrame::MyUnivFrame(const wxString& title) i % 10 ? _T("") : _T("very very long "), i)); } - new wxCheckBox(this, -1, _T("Check me"), wxPoint(10, 520)); + new wxCheckBox(this, -1, _T("Check me"), wxPoint(10, 550)); + new wxCheckBox(this, -1, _T("Don't check me"), + wxPoint(150, 550), wxDefaultSize, + wxALIGN_RIGHT); } void MyUnivFrame::OnButton(wxCommandEvent& event) diff --git a/src/univ/checkbox.cpp b/src/univ/checkbox.cpp index 4f339eafb1..4ecd5eeca6 100644 --- a/src/univ/checkbox.cpp +++ b/src/univ/checkbox.cpp @@ -30,7 +30,7 @@ #if wxUSE_CHECKBOX #ifndef WX_PRECOMP - #include "wx/dc.h" + #include "wx/dcclient.h" #include "wx/checkbox.h" #include "wx/validate.h" #endif @@ -134,7 +134,7 @@ void wxCheckBox::DoDraw(wxControlRenderer *renderer) wxSize wxCheckBox::DoGetBestClientSize() const { - wxClientDC dc(wxConstCast(this, wxButton)); + wxClientDC dc(wxConstCast(this, wxCheckBox)); wxCoord width, height; dc.GetMultiLineTextExtent(GetLabel(), &width, &height); diff --git a/src/univ/files.lst b/src/univ/files.lst index ea66d510fc..1ed3480722 100644 --- a/src/univ/files.lst +++ b/src/univ/files.lst @@ -1,6 +1,7 @@ UNIVOBJS = \ bmpbuttn.o \ button.o \ + checkbox.o \ colschem.o \ control.o \ inphand.o \ @@ -13,11 +14,13 @@ UNIVOBJS = \ stattext.o \ theme.o \ gtk.o \ - winuniv.o + winuniv.o \ + win32.o UNIVDEPS = \ bmpbuttn.d \ button.d \ + checkbox.d \ colschem.d \ control.d \ inphand.d \ @@ -30,5 +33,5 @@ UNIVDEPS = \ stattext.d \ theme.d \ gtk.d \ - win32.d \ - winuniv.d + winuniv.d \ + win32.d diff --git a/src/univ/renderer.cpp b/src/univ/renderer.cpp index f26d4ff9eb..07f2838434 100644 --- a/src/univ/renderer.cpp +++ b/src/univ/renderer.cpp @@ -643,13 +643,13 @@ void wxControlRenderer::DrawLabelBox(const wxBitmap& bitmap, wxCoord margin) if ( m_window->GetWindowStyle() & wxALIGN_RIGHT ) { - rectBmp.SetRight(m_rect.GetRight()); - rectLabel.SetRight(rectBmp.GetLeft() - margin); + rectBmp.x = m_rect.GetRight() - rectBmp.width; rectLabel.SetLeft(m_rect.GetLeft()); + rectLabel.SetRight(rectBmp.GetLeft() - margin); } else // normal (checkbox to the left of the text) case { - rectBmp.SetLeft(m_rect.GetLeft()); + rectBmp.x = m_rect.GetLeft(); rectLabel.SetLeft(rectBmp.GetRight() + margin); rectLabel.SetRight(m_rect.GetRight()); } diff --git a/src/univ/themes/gtk.cpp b/src/univ/themes/gtk.cpp index c6c50b7d8c..f7254d57e0 100644 --- a/src/univ/themes/gtk.cpp +++ b/src/univ/themes/gtk.cpp @@ -27,7 +27,7 @@ #ifndef WX_PRECOMP #include "wx/intl.h" #include "wx/log.h" - #include "wx/dc.h" + #include "wx/dcmemory.h" #include "wx/window.h" #include "wx/button.h" @@ -111,10 +111,7 @@ public: virtual void AdjustSize(wxSize *size, const wxWindow *window); virtual wxRect GetBorderDimensions(wxBorder border) const; - virtual void AdjustScrollbar(wxOrientation orient, - wxBorder border, - bool hasOtherScrollbar, - wxRect* rect) const; + virtual bool AreScrollbarsInsideBorder() const; // hit testing for the input handlers virtual wxRect GetScrollbarRect(const wxScrollBar *scrollbar, @@ -129,6 +126,10 @@ public: virtual wxCoord GetListboxItemHeight(wxCoord fontHeight) { return fontHeight + 2; } + // helpers for "wxBitmap wxColourScheme::Get()" + void DrawCheckBitmap(wxDC& dc, const wxRect& rect); + void DrawUncheckBitmap(wxDC& dc, const wxRect& rect); + protected: // DrawBackground() helpers @@ -287,6 +288,11 @@ public: #if wxUSE_CHECKBOX virtual wxBitmap Get(wxCheckBox::State state, wxCheckBox::Status status); #endif // wxUSE_CHECKBOX + +private: + // the checkbox bitmaps + wxBitmap m_bmpCheck, + m_bmpUncheck; }; // ---------------------------------------------------------------------------- @@ -449,7 +455,26 @@ wxColour wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col) const wxBitmap wxGTKColourScheme::Get(wxCheckBox::State state, wxCheckBox::Status status) { - return wxNullBitmap; + if ( !m_bmpCheck.Ok() ) + { + // init the bitmaps once only + wxRect rect; + rect.width = + rect.height = 10; + m_bmpCheck.Create(rect.width, rect.height); + m_bmpUncheck.Create(rect.width, rect.height); + + wxGTKRenderer *renderer = (wxGTKRenderer *)wxTheme::Get()->GetRenderer(); + + wxMemoryDC dc; + dc.SelectObject(m_bmpCheck); + renderer->DrawCheckBitmap(dc, rect); + + dc.SelectObject(m_bmpUncheck); + renderer->DrawUncheckBitmap(dc, rect); + } + + return status == wxCheckBox::Status_Checked ? m_bmpCheck : m_bmpUncheck; } #endif // wxUSE_CHECKBOX @@ -668,32 +693,10 @@ wxRect wxGTKRenderer::GetBorderDimensions(wxBorder border) const return rect; } -void wxGTKRenderer::AdjustScrollbar(wxOrientation orient, - wxBorder border, - bool hasOtherScrollbar, - wxRect* rect) const +bool wxGTKRenderer::AreScrollbarsInsideBorder() const { - wxRect rectBorder = GetBorderDimensions(border); - - if ( orient == wxVERTICAL ) - { - // blend the top and right scrollbar borders into the window border - rect->y -= rectBorder.y; - rect->x += rectBorder.width; - - // if there is no horz scrollbar, also do it with the bottom one - if ( !hasOtherScrollbar ) - rect->height += rectBorder.height; - } - else // wxHORIZONTAL - { - // the logic is the same as above - rect->x -= rectBorder.x; - rect->y += rectBorder.height; - - if ( !hasOtherScrollbar ) - rect->width += rectBorder.width; - } + // no, the scrollbars are outside the border in GTK+ + return FALSE; } // ---------------------------------------------------------------------------- @@ -1320,6 +1323,36 @@ void wxGTKRenderer::AdjustSize(wxSize *size, const wxWindow *window) } } +// ---------------------------------------------------------------------------- +// checkbox buttons +// ---------------------------------------------------------------------------- + +void wxGTKRenderer::DrawUncheckBitmap(wxDC& dc, const wxRect& rectTotal) +{ + wxRect rect = rectTotal; + DrawShadedRect(dc, &rect, m_penHighlight, m_penBlack); + DrawAntiShadedRect(dc, &rect, m_penLightGrey, m_penDarkGrey); + + wxColour col = wxSCHEME_COLOUR(m_scheme, SHADOW_IN); + dc.SetPen(wxPen(col, 0, wxSOLID)); + dc.DrawPoint(rect.GetRight(), rect.GetBottom()); + + dc.SetPen(*wxTRANSPARENT_PEN); + dc.SetBrush(wxBrush(col, wxSOLID)); + dc.DrawRectangle(rect); +} + +void wxGTKRenderer::DrawCheckBitmap(wxDC& dc, const wxRect& rectTotal) +{ + wxRect rect = rectTotal; + DrawAntiShadedRect(dc, &rect, m_penDarkGrey, m_penHighlight); + DrawShadedRect(dc, &rect, m_penBlack, m_penLightGrey); + + dc.SetPen(*wxTRANSPARENT_PEN); + dc.SetBrush(wxBrush(wxSCHEME_COLOUR(m_scheme, CONTROL_PRESSED), wxSOLID)); + dc.DrawRectangle(rect); +} + // ============================================================================ // wxInputHandler // ============================================================================ diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index 4cf5f31fab..66d33b2d58 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -24,20 +24,6 @@ #pragma hdrstop #endif -extern int foo = 0; - -static struct Foo -{ - Foo(); -} s_foo; - -Foo::Foo() -{ - int x; - x = 1; - x++; -} - #ifndef WX_PRECOMP #include "wx/timer.h" #include "wx/intl.h" @@ -143,10 +129,7 @@ public: virtual void AdjustSize(wxSize *size, const wxWindow *window); virtual wxRect GetBorderDimensions(wxBorder border) const; - virtual void AdjustScrollbar(wxOrientation orient, - wxBorder border, - bool hasOtherScrollbar, - wxRect* rect) const; + virtual bool AreScrollbarsInsideBorder() const; virtual wxRect GetScrollbarRect(const wxScrollBar *scrollbar, wxScrollBar::Element elem, @@ -854,12 +837,9 @@ wxRect wxWin32Renderer::GetBorderDimensions(wxBorder border) const return rect; } -void wxWin32Renderer::AdjustScrollbar(wxOrientation orient, - wxBorder border, - bool hasOtherScrollbar, - wxRect* rect) const +bool wxWin32Renderer::AreScrollbarsInsideBorder() const { - // don't do anything - we don't blend scrollbars into borders + return TRUE; } // ---------------------------------------------------------------------------- diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index 21485b1e27..64b5861251 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -291,18 +291,6 @@ wxSize wxWindow::AdjustSize(const wxSize& size) const return sz; } -void wxWindow::DoSetClientSize(int width, int height) -{ - // take into account the scrollbars - if ( m_scrollbarVert ) - width += m_scrollbarVert->GetSize().x; - - if ( m_scrollbarHorz ) - height += m_scrollbarHorz->GetSize().y; - - wxWindowNative::DoSetClientSize(width, height); -} - wxPoint wxWindow::GetClientAreaOrigin() const { wxPoint pt = wxWindowBase::GetClientAreaOrigin(); @@ -317,32 +305,60 @@ void wxWindow::DoGetClientSize(int *width, int *height) const { wxWindowNative::DoGetClientSize(width, height); + // we assume that the scrollbars are positioned correctly (by a previous + // call to PositionScrollbars()) here + wxRect rectBorder; if ( m_renderer ) rectBorder = m_renderer->GetBorderDimensions(GetBorder()); - // TODO we should be smarter about combining the scrollbar borders with - // the window ones - so far we just blend the right and bottom - // borders of the vertical scrollbar (and left/bottom of the - // horizontal one) into the window border, but this risks to look - // ugly with other renderers/border styles + wxSize size = GetSize(); + if ( width ) { if ( m_scrollbarVert ) - *width -= m_scrollbarVert->GetSize().x; + *width -= size.x - m_scrollbarVert->GetPosition().x; + else + *width -= rectBorder.width; - *width -= rectBorder.x + rectBorder.width; + *width -= rectBorder.x; } if ( height ) { if ( m_scrollbarHorz ) - *height -= m_scrollbarHorz->GetSize().y; + *height -= size.y - m_scrollbarHorz->GetPosition().y; + else + *height -= rectBorder.height; - *height -= rectBorder.y + rectBorder.height; + *height -= rectBorder.y; } } +void wxWindow::DoSetClientSize(int width, int height) +{ + // take into account the borders + wxRect rectBorder = m_renderer->GetBorderDimensions(GetBorder()); + width += rectBorder.x; + height += rectBorder.y; + + // and the scrollbars (as they may be offset into the border, use the + // scrollbar position, not size - this supposes that PositionScrollbars() + // had been called before) + wxSize size = GetSize(); + if ( m_scrollbarVert ) + width += size.x - m_scrollbarVert->GetPosition().x; + else + width += rectBorder.width; + + if ( m_scrollbarHorz ) + height += size.y - m_scrollbarHorz->GetPosition().y; + else + height += rectBorder.height; + + wxWindowNative::DoSetClientSize(width, height); +} + // ---------------------------------------------------------------------------- // scrolling: we implement it entirely ourselves except for ScrollWindow() // function which is supposed to be (efficiently) implemented by the native @@ -351,29 +367,46 @@ void wxWindow::DoGetClientSize(int *width, int *height) const void wxWindow::PositionScrollbars() { - wxRect rectClient = GetClientRect(), - rectBar; + // do not use GetClientSize/Rect as it relies on the scrollbars being + // correctly positioned + wxSize size = GetSize(); + wxBorder border = GetBorder(); + wxRect rectBorder = m_renderer->GetBorderDimensions(border); + bool inside = m_renderer->AreScrollbarsInsideBorder(); + + int height = m_scrollbarHorz ? m_scrollbarHorz->GetSize().y : 0; + int width = m_scrollbarVert ? m_scrollbarVert->GetSize().x : 0; + + wxRect rectBar; if ( m_scrollbarVert ) { - rectBar.x = rectClient.GetRight() + 1; - rectBar.y = rectClient.GetTop(); - rectBar.width = m_scrollbarVert->GetSize().x; - rectBar.height = rectClient.GetHeight(); - m_renderer->AdjustScrollbar(wxVERTICAL, GetBorder(), - m_scrollbarHorz != NULL, &rectBar); + rectBar.x = size.x - width; + if ( inside ) + rectBar.x -= rectBorder.width; + rectBar.width = width; + rectBar.y = 0; + if ( inside ) + rectBar.y += rectBorder.y; + rectBar.height = size.y - height; + if ( inside ) + rectBar.height -= rectBorder.y + rectBorder.height; m_scrollbarVert->SetSize(rectBar, wxSIZE_NO_ADJUSTMENTS); } if ( m_scrollbarHorz ) { - rectBar.x = rectClient.GetLeft(); - rectBar.y = rectClient.GetBottom() + 1; - rectBar.width = rectClient.GetWidth(); - rectBar.height = m_scrollbarHorz->GetSize().y; - m_renderer->AdjustScrollbar(wxHORIZONTAL, GetBorder(), - m_scrollbarVert != NULL, &rectBar); + rectBar.y = size.y - height; + if ( inside ) + rectBar.y -= rectBorder.height; + rectBar.height = height; + rectBar.x = 0; + if ( inside ) + rectBar.x += rectBorder.x; + rectBar.width = size.x - width; + if ( inside ) + rectBar.width -= rectBorder.x + rectBorder.width; m_scrollbarHorz->SetSize(rectBar, wxSIZE_NO_ADJUSTMENTS); }