diff --git a/include/wx/univ/checkbox.h b/include/wx/univ/checkbox.h index 4a6ab343a8..d4d22753a8 100644 --- a/include/wx/univ/checkbox.h +++ b/include/wx/univ/checkbox.h @@ -114,6 +114,9 @@ protected: // send command event notifying about the checkbox state change virtual void SendEvent(); + // called when the checkbox becomes checked - radio button hook + virtual void OnCheck(); + // get the state corresponding to the flags (combination of wxCONTROL_XXX) wxCheckBox::State GetState(int flags) const; diff --git a/include/wx/univ/listbox.h b/include/wx/univ/listbox.h index 94cba3b362..c2ff33ff46 100644 --- a/include/wx/univ/listbox.h +++ b/include/wx/univ/listbox.h @@ -112,9 +112,6 @@ public: // override some more base class methods virtual bool SetFont(const wxFont& font); - virtual void Refresh( bool eraseBackground = TRUE, - const wxRect *rect = (const wxRect *) NULL ); - // the wxUniversal-specific methods // -------------------------------- diff --git a/include/wx/univ/radiobut.h b/include/wx/univ/radiobut.h index 0871048abe..155e8e4a47 100644 --- a/include/wx/univ/radiobut.h +++ b/include/wx/univ/radiobut.h @@ -66,8 +66,12 @@ protected: // another radiobutton void ClearValue(); + // called when the radio button becomes checked: we clear all the buttons + // in the same group with us here + virtual void OnCheck(); + // send event about radio button selection - void SendEvent(); + virtual void SendEvent(); private: DECLARE_DYNAMIC_CLASS(wxRadioButton) diff --git a/include/wx/univ/textctrl.h b/include/wx/univ/textctrl.h index 7582ba95a9..ccaf81902d 100644 --- a/include/wx/univ/textctrl.h +++ b/include/wx/univ/textctrl.h @@ -256,6 +256,9 @@ protected: // get the extent (width) of the text wxCoord GetTextWidth(const wxString& text) const; + // get the logical text width (accounting for scrolling) + wxCoord GetTotalWidth() const; + // refresh the text in the given (in logical coords) rect void RefreshTextRect(wxRect& rect); diff --git a/include/wx/univ/window.h b/include/wx/univ/window.h index 9cc66d02a3..e8e608e5cc 100644 --- a/include/wx/univ/window.h +++ b/include/wx/univ/window.h @@ -155,6 +155,10 @@ public: // this with both dx and dy non zero) wxRect ScrollNoRefresh(int dx, int dy, const wxRect *rect = NULL); + // after scrollbars are added or removed they must be refreshed by calling + // this function + void RefreshScrollbars(); + // overridden base class methods // ----------------------------- diff --git a/samples/listbox/lboxtest.cpp b/samples/listbox/lboxtest.cpp index a7d69c6d0a..5f5cd1370e 100644 --- a/samples/listbox/lboxtest.cpp +++ b/samples/listbox/lboxtest.cpp @@ -67,7 +67,6 @@ enum { LboxTest_Reset = 100, - LboxTest_Create, LboxTest_Add, LboxTest_AddText, LboxTest_AddSeveral, @@ -111,7 +110,6 @@ public: protected: // event handlers void OnButtonReset(wxCommandEvent& event); - void OnButtonCreate(wxCommandEvent& event); void OnButtonChange(wxCommandEvent& event); void OnButtonDelete(wxCommandEvent& event); void OnButtonDeleteSel(wxCommandEvent& event); @@ -128,10 +126,10 @@ protected: void OnCheckOrRadioBox(wxCommandEvent& event); void OnUpdateUIAddSeveral(wxUpdateUIEvent& event); - void OnUpdateUICreateButton(wxUpdateUIEvent& event); void OnUpdateUIClearButton(wxUpdateUIEvent& event); void OnUpdateUIDeleteButton(wxUpdateUIEvent& event); void OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event); + void OnUpdateUIResetButton(wxUpdateUIEvent& event); // reset the listbox parameters void Reset(); @@ -157,9 +155,6 @@ protected: bool m_horzScroll, m_vertScrollAlways; - // should the recreate button be enabled? - bool m_dirty; - // the controls // ------------ @@ -267,7 +262,6 @@ IMPLEMENT_APP(LboxTestApp) BEGIN_EVENT_TABLE(LboxTestFrame, wxFrame) EVT_BUTTON(LboxTest_Reset, LboxTestFrame::OnButtonReset) - EVT_BUTTON(LboxTest_Create, LboxTestFrame::OnButtonCreate) EVT_BUTTON(LboxTest_Change, LboxTestFrame::OnButtonChange) EVT_BUTTON(LboxTest_Delete, LboxTestFrame::OnButtonDelete) EVT_BUTTON(LboxTest_DeleteSel, LboxTestFrame::OnButtonDeleteSel) @@ -281,9 +275,7 @@ BEGIN_EVENT_TABLE(LboxTestFrame, wxFrame) EVT_TEXT_ENTER(LboxTest_AddText, LboxTestFrame::OnButtonAdd) EVT_TEXT_ENTER(LboxTest_DeleteText, LboxTestFrame::OnButtonDelete) - EVT_UPDATE_UI_RANGE(LboxTest_Reset, LboxTest_Create, - LboxTestFrame::OnUpdateUICreateButton) - + EVT_UPDATE_UI(LboxTest_Reset, LboxTestFrame::OnUpdateUIResetButton) EVT_UPDATE_UI(LboxTest_AddSeveral, LboxTestFrame::OnUpdateUIAddSeveral) EVT_UPDATE_UI(LboxTest_Clear, LboxTestFrame::OnUpdateUIClearButton) EVT_UPDATE_UI(LboxTest_DeleteText, LboxTestFrame::OnUpdateUIClearButton) @@ -325,7 +317,6 @@ LboxTestFrame::LboxTestFrame(const wxString& title) : wxFrame(NULL, -1, title, wxPoint(100, 100)) { // init everything - m_dirty = FALSE; m_radioSelMode = (wxRadioBox *)NULL; m_chkVScroll = @@ -377,12 +368,8 @@ LboxTestFrame::LboxTestFrame(const wxString& title) sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer sizerLeft->Add(m_radioSelMode, 0, wxGROW | wxALL, 5); - wxSizer *sizerBtn = new wxBoxSizer(wxHORIZONTAL); wxButton *btn = new wxButton(m_panel, LboxTest_Reset, _T("&Reset")); - sizerBtn->Add(btn, 0, wxLEFT | wxRIGHT, 5); - btn = new wxButton(m_panel, LboxTest_Create, _T("&Create")); - sizerBtn->Add(btn, 0, wxLEFT | wxRIGHT, 5); - sizerLeft->Add(sizerBtn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15); + sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15); // middle pane wxStaticBox *box2 = new wxStaticBox(m_panel, -1, _T("&Change listbox contents")); @@ -452,13 +439,12 @@ LboxTestFrame::LboxTestFrame(const wxString& title) sizerDown->Add(sizerBtns, 0, wxALL | wxALIGN_RIGHT, 5); // put everything together - sizerTop->Add(sizerUp, 1, wxGROW | (wxALL & ~wxBOTTOM), 10); + sizerTop->Add(sizerUp, 1, wxGROW | (wxALL & ~(wxTOP | wxBOTTOM)), 10); sizerTop->Add(0, 5, 0, wxGROW); // spacer in between sizerTop->Add(sizerDown, 0, wxGROW | (wxALL & ~wxTOP), 10); // final initialization Reset(); - m_dirty = FALSE; m_panel->SetAutoLayout(TRUE); m_panel->SetSizer(sizerTop); @@ -483,21 +469,10 @@ LboxTestFrame::~LboxTestFrame() void LboxTestFrame::Reset() { - if ( m_radioSelMode->GetSelection() == LboxSel_Single && - !m_chkSort->GetValue() && - m_chkHScroll->GetValue() && - !m_chkVScroll->GetValue() ) - { - // nothing to do - return; - } - m_radioSelMode->SetSelection(LboxSel_Single); m_chkSort->SetValue(FALSE); m_chkHScroll->SetValue(TRUE); m_chkVScroll->SetValue(FALSE); - - m_dirty = TRUE; } void LboxTestFrame::CreateLbox() @@ -540,8 +515,6 @@ void LboxTestFrame::CreateLbox() m_lbox->Set(items); m_sizerLbox->Add(m_lbox, 1, wxGROW | wxALL, 5); m_sizerLbox->Layout(); - - m_dirty = FALSE; } // ---------------------------------------------------------------------------- @@ -556,10 +529,7 @@ void LboxTestFrame::OnButtonQuit(wxCommandEvent& WXUNUSED(event)) void LboxTestFrame::OnButtonReset(wxCommandEvent& WXUNUSED(event)) { Reset(); -} -void LboxTestFrame::OnButtonCreate(wxCommandEvent& WXUNUSED(event)) -{ CreateLbox(); } @@ -638,9 +608,12 @@ void LboxTestFrame::OnButtonAddSeveral(wxCommandEvent& event) m_lbox->InsertItems(items, 0); } -void LboxTestFrame::OnUpdateUICreateButton(wxUpdateUIEvent& event) +void LboxTestFrame::OnUpdateUIResetButton(wxUpdateUIEvent& event) { - event.Enable(m_dirty); + event.Enable( (m_radioSelMode->GetSelection() != LboxSel_Single) || + m_chkSort->GetValue() || + !m_chkHScroll->GetValue() || + m_chkVScroll->GetValue() ); } void LboxTestFrame::OnUpdateUIDeleteButton(wxUpdateUIEvent& event) @@ -681,6 +654,6 @@ void LboxTestFrame::OnListboxDClick(wxCommandEvent& event) void LboxTestFrame::OnCheckOrRadioBox(wxCommandEvent& event) { - m_dirty = TRUE; + CreateLbox(); } diff --git a/samples/univ/univ.cpp b/samples/univ/univ.cpp index 9456dd9d2f..fcd86615f0 100644 --- a/samples/univ/univ.cpp +++ b/samples/univ/univ.cpp @@ -384,7 +384,7 @@ MyUnivFrame::MyUnivFrame(const wxString& title) new wxTextCtrl(this, -1, _T("Hello, Universe!"), wxPoint(550, 150), wxDefaultSize); #else // TEST_TEXT_ONLY -#if 0 +#if 1 wxTextCtrl *text = new wxTextCtrl(this, -1, _T("Hello, Universe!"), wxPoint(10, 40)); text->SetFont(wxFont(24, wxFONTFAMILY_DEFAULT, diff --git a/src/generic/scrolwin.cpp b/src/generic/scrolwin.cpp index 7cc1292503..013f51b037 100644 --- a/src/generic/scrolwin.cpp +++ b/src/generic/scrolwin.cpp @@ -304,7 +304,7 @@ void wxScrollHelper::HandleOnScroll(wxScrollWinEvent& event) if ( needsRefresh ) { - m_targetWindow->Refresh(GetRect()); + m_targetWindow->Refresh(TRUE, GetRect()); } else { diff --git a/src/univ/button.cpp b/src/univ/button.cpp index b926d7a9e5..4782b655c3 100644 --- a/src/univ/button.cpp +++ b/src/univ/button.cpp @@ -242,6 +242,7 @@ wxStdButtonInputHandler::wxStdButtonInputHandler(wxInputHandler *handler) : wxStdInputHandler(handler) { m_winCapture = NULL; + m_winHasMouse = FALSE; } bool wxStdButtonInputHandler::HandleKey(wxControl *control, diff --git a/src/univ/checkbox.cpp b/src/univ/checkbox.cpp index 26c8dd90ac..9952bdb588 100644 --- a/src/univ/checkbox.cpp +++ b/src/univ/checkbox.cpp @@ -92,10 +92,21 @@ void wxCheckBox::SetValue(bool value) { m_status = status; + if ( m_status == Status_Checked ) + { + // invoke the hook + OnCheck(); + } + Refresh(); } } +void wxCheckBox::OnCheck() +{ + // we do nothing here +} + // ---------------------------------------------------------------------------- // indicator bitmaps // ---------------------------------------------------------------------------- diff --git a/src/univ/listbox.cpp b/src/univ/listbox.cpp index 6ecf6f2559..7319af122c 100644 --- a/src/univ/listbox.cpp +++ b/src/univ/listbox.cpp @@ -245,6 +245,7 @@ void wxListBox::DoClear() } m_itemsClientData.Clear(); + m_selections.Clear(); } void wxListBox::Clear() @@ -371,6 +372,9 @@ void wxListBox::SetSelection(int n, bool select) } //else: not selected } + + wxASSERT_MSG( HasMultipleSelection() || (m_selections.GetCount() < 2), + _T("multiple selected items in single selection lbox?") ); } int wxListBox::GetSelection() const @@ -390,9 +394,15 @@ int wxListBox::GetSelections(wxArrayInt& selections) const { // always return sorted array to the user selections = m_selections; - selections.Sort(wxCompareInts); + size_t count = m_selections.GetCount(); - return m_selections.GetCount(); + // don't call sort on an empty array + if ( count ) + { + selections.Sort(wxCompareInts); + } + + return count; } // ---------------------------------------------------------------------------- @@ -401,18 +411,6 @@ int wxListBox::GetSelections(wxArrayInt& selections) const // added/deleted/changed subsequently // ---------------------------------------------------------------------------- -void wxListBox::Refresh(bool eraseBackground, const wxRect *rect) -{ - if ( rect ) - wxLogTrace(_T("listbox"), _T("Refreshing (%d, %d)-(%d, %d)"), - rect->x, rect->y, - rect->x + rect->width, rect->y + rect->height); - else - wxLogTrace(_T("listbox"), _T("Refreshing all")); - - wxControl::Refresh(eraseBackground, rect); -} - void wxListBox::RefreshFromItemToEnd(int from) { RefreshItems(from, GetCount() - from); @@ -515,9 +513,12 @@ void wxListBox::UpdateScrollbars() // what should be the scrollbar range now? int scrollRangeX = showScrollbarX - ? (maxWidth + 2*charWidth - 1) / charWidth + ? (maxWidth + charWidth - 1) / charWidth + 2 // FIXME + : 0; + int scrollRangeY = showScrollbarY + ? nLines + + (size.y % lineHeight + lineHeight - 1) / lineHeight : 0; - int scrollRangeY = showScrollbarY ? nLines : 0; // reset scrollbars if something changed: either the visibility status // or the range of a scrollbar which is shown @@ -558,7 +559,10 @@ void wxListBox::UpdateItems() rect.height = size.y; rect.y += m_updateFrom*GetLineHeight(); rect.height = m_updateCount*GetLineHeight(); - CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y); + + // we don't need to calculate x position as we always refresh the + // entire line(s) + CalcScrolledPosition(0, rect.y, NULL, &rect.y); wxLogTrace(_T("listbox"), _T("Refreshing items %d..%d (%d-%d)"), m_updateFrom, m_updateFrom + m_updateCount - 1, @@ -948,8 +952,15 @@ void wxListBox::Activate(int item) { if ( item != -1 ) SetCurrentItem(item); + else + item = m_current; - if ( m_current != -1 ) + if ( !(GetWindowStyle() & wxLB_MULTIPLE) ) + { + DeselectAll(item); + } + + if ( item != -1 ) { Select(); diff --git a/src/univ/radiobut.cpp b/src/univ/radiobut.cpp index b6f5bbfb01..de57e5f3fc 100644 --- a/src/univ/radiobut.cpp +++ b/src/univ/radiobut.cpp @@ -72,6 +72,48 @@ bool wxRadioButton::Create(wxWindow *parent, // radio button methods // ---------------------------------------------------------------------------- +void wxRadioButton::OnCheck() +{ + // clear all others radio buttons in our group: for this we need to + // find the radio button which is the first in the group, i.e. the one + // with wxRB_GROUP style + const wxWindowList& siblings = GetParent()->GetChildren(); + wxWindowList::Node *nodeStart = siblings.Find(this); + while ( nodeStart ) + { + // stop if we found a radio button with wxRB_GROUP style or it we + // are at the first control + if ( !nodeStart->GetPrevious() || + (nodeStart->GetData()->GetWindowStyle() & wxRB_GROUP) ) + break; + + nodeStart = nodeStart->GetPrevious(); + } + + // now clear all radio buttons from the starting one until the next + // one with wxRB_GROUP style + while ( nodeStart ) + { + wxWindow *win = nodeStart->GetData(); + if ( win != this ) + { + wxRadioButton *btn = wxDynamicCast(win, wxRadioButton); + if ( btn ) + { + btn->ClearValue(); + } + } + + nodeStart = nodeStart->GetNext(); + if ( !nodeStart || + (nodeStart->GetData()->GetWindowStyle() & wxRB_GROUP) ) + { + // we reached the next group + break; + } + } +} + void wxRadioButton::ChangeValue(bool value) { if ( value == IsChecked() ) @@ -79,52 +121,11 @@ void wxRadioButton::ChangeValue(bool value) if ( !IsChecked() ) { - // clear all others radio buttons in our group: for this we need to - // find the radio button which is the first in the group, i.e. the one - // with wxRB_GROUP style - const wxWindowList& siblings = GetParent()->GetChildren(); - wxWindowList::Node *nodeStart = siblings.Find(this); - while ( nodeStart ) - { - // stop if we found a radio button with wxRB_GROUP style or it we - // are at the first control - if ( !nodeStart->GetPrevious() || - (nodeStart->GetData()->GetWindowStyle() & wxRB_GROUP) ) - break; - - nodeStart = nodeStart->GetPrevious(); - } - - // now clear all radio buttons from the starting one until the next - // one with wxRB_GROUP style - while ( nodeStart ) - { - wxWindow *win = nodeStart->GetData(); - if ( win != this ) - { - wxRadioButton *btn = wxDynamicCast(win, wxRadioButton); - if ( btn ) - { - btn->ClearValue(); - } - } - - nodeStart = nodeStart->GetNext(); - if ( !nodeStart || - (nodeStart->GetData()->GetWindowStyle() & wxRB_GROUP) ) - { - // we reached the next group - break; - } - } - - SetValue(TRUE); - - SendEvent(); + wxCheckBox::ChangeValue(value); } else // attempt to clear a radio button - this can't be done { - // but still refresh as ou PRESSED flag changed + // but still refresh as our PRESSED flag changed Refresh(); } } diff --git a/src/univ/renderer.cpp b/src/univ/renderer.cpp index 5d1cc31348..d646c11fa0 100644 --- a/src/univ/renderer.cpp +++ b/src/univ/renderer.cpp @@ -497,6 +497,23 @@ void wxControlRenderer::DrawScrollbar(const wxScrollBar *scrollbar, rectUpdate.GetTop(), rectUpdate.GetRight(), rectUpdate.GetBottom()); + +#if 0 //def WXDEBUG_SCROLLBAR + static bool s_refreshDebug = FALSE; + if ( s_refreshDebug ) + { + wxClientDC dc(wxConstCast(scrollbar, wxScrollBar)); + dc.SetBrush(*wxRED_BRUSH); + dc.SetPen(*wxTRANSPARENT_PEN); + dc.DrawRectangle(rectUpdate); + + // under Unix we use "--sync" X option for this + #ifdef __WXMSW__ + ::GdiFlush(); + ::Sleep(200); + #endif // __WXMSW__ + } +#endif // WXDEBUG_SCROLLBAR } wxOrientation orient = scrollbar->IsVertical() ? wxVERTICAL @@ -620,18 +637,15 @@ void wxControlRenderer::DoDrawItems(const wxListBox *lbox, // scrollbar for the long strings m_dc.SetClippingRegion(rect.x, rect.y, rect.width + 1, rect.height + 1); - // the rect should go to the right visible border - int widthTotal; - lbox->GetVirtualSize(&widthTotal, NULL); - if ( widthTotal ) - rect.width = widthTotal; - //else: no horz scrolling at all - // adjust the rect position now lbox->CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y); rect.y += itemFirst*lineHeight; rect.height = lineHeight; + // the rect should go to the right visible border so adjust the width if x + // is shifted (rightmost point should stay the same) + rect.width -= rect.x; + // we'll keep the text colour unchanged m_dc.SetTextForeground(lbox->GetForegroundColour()); diff --git a/src/univ/scrolbar.cpp b/src/univ/scrolbar.cpp index 3c49c104a2..b4c41193f4 100644 --- a/src/univ/scrolbar.cpp +++ b/src/univ/scrolbar.cpp @@ -41,6 +41,12 @@ #include "wx/univ/inphand.h" #include "wx/univ/theme.h" +#define WXDEBUG_SCROLLBAR + +#ifndef __WXDEBUG__ + #undef WXDEBUG_SCROLLBAR +#endif // !__WXDEBUG__ + // ---------------------------------------------------------------------------- // wxScrollBarTimer: this class is used to repeatedly scroll the scrollbar // when the mouse is help pressed on the arrow or on the bar. It generates the @@ -196,13 +202,23 @@ void wxScrollBar::SetScrollbar(int position, int thumbSize, int range, int pageSize, bool refresh) { + // we only refresh everythign when the range changes, thumb position + // changes are handled in OnIdle + bool needsRefresh = (range != m_range) || + (thumbSize != m_thumbSize) || + (pageSize != m_pageSize); + // set all parameters m_range = range; m_thumbSize = thumbSize; SetThumbPosition(position); m_pageSize = pageSize; - if ( refresh ) + // ignore refresh parameter unless we really need to refresh everything - + // there ir a lot of existing code which just calls SetScrollbar() without + // specifying the last parameter even though it doesn't need at all to + // refresh the window immediately + if ( refresh && needsRefresh ) { // and update the window Refresh(); @@ -271,6 +287,23 @@ void wxScrollBar::OnIdle(wxIdleEvent& event) #endif // 0/1 } +#ifdef WXDEBUG_SCROLLBAR + static bool s_refreshDebug = FALSE; + if ( s_refreshDebug ) + { + wxClientDC dc(this); + dc.SetBrush(*wxCYAN_BRUSH); + dc.SetPen(*wxTRANSPARENT_PEN); + dc.DrawRectangle(rect); + + // under Unix we use "--sync" X option for this + #ifdef __WXMSW__ + ::GdiFlush(); + ::Sleep(200); + #endif // __WXMSW__ + } +#endif // WXDEBUG_SCROLLBAR + Refresh(TRUE, &rect); } diff --git a/src/univ/textctrl.cpp b/src/univ/textctrl.cpp index 7f8e63c21b..540ebb6733 100644 --- a/src/univ/textctrl.cpp +++ b/src/univ/textctrl.cpp @@ -64,6 +64,11 @@ // turn wxTextCtrl::Replace() debugging on (very inefficient!) #define WXDEBUG_TEXT_REPLACE +#ifndef __WXDEBUG__ + #undef WXDEBUG_TEXT + #undef WXDEBUG_TEXT_REPLACE +#endif + // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -1427,6 +1432,13 @@ void wxTextCtrl::OnSize(wxSizeEvent& event) event.Skip(); } +wxCoord wxTextCtrl::GetTotalWidth() const +{ + wxCoord w; + CalcUnscrolledPosition(m_rectText.width, 0, &w, NULL); + return w; +} + wxCoord wxTextCtrl::GetTextWidth(const wxString& text) const { wxCoord w; @@ -1984,7 +1996,7 @@ void wxTextCtrl::RefreshPixelRange(long line, wxCoord start, wxCoord width) if ( width == 0 ) { // till the end of line - rect.width = m_rectText.width - rect.x; + rect.width = GetTotalWidth() - rect.x; } else { diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index 72d99d2e97..c0a191be54 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -41,6 +41,13 @@ #include "wx/univ/renderer.h" #include "wx/univ/theme.h" +// turn Refresh() debugging on/off +#define WXDEBUG_REFRESH + +#ifndef __WXDEBUG__ + #undef WXDEBUG_REFRESH +#endif + // ============================================================================ // implementation // ============================================================================ @@ -278,28 +285,51 @@ void wxWindow::DoDraw(wxControlRenderer *renderer) void wxWindow::Refresh(bool eraseBackground, const wxRect *rectClient) { + wxRect rectWin; + wxPoint pt = GetClientAreaOrigin(); + + wxSize size = GetClientSize(); + if ( rectClient ) { - wxRect rectWin = *rectClient; - rectWin.Offset(GetClientAreaOrigin()); + rectWin = *rectClient; - wxWindowNative::Refresh(eraseBackground, &rectWin); + // don't refresh anything beyond the client area (scrollbars for + // example) + if ( rectWin.GetRight() > size.x ) + rectWin.SetRight(size.x); + if ( rectWin.GetBottom() > size.y ) + rectWin.SetBottom(size.y); - // debugging helper -#if 0 + rectWin.Offset(pt); + } + else // refresh the entire client area + { + rectWin.x = pt.x; + rectWin.y = pt.y; + rectWin.width = size.x; + rectWin.height = size.y; + } + + wxWindowNative::Refresh(eraseBackground, &rectWin); + + // debugging helper +#ifdef WXDEBUG_REFRESH + static bool s_refreshDebug = FALSE; + if ( s_refreshDebug ) + { wxWindowDC dc(this); - dc.SetBrush(*wxBLUE_BRUSH); + dc.SetBrush(*wxCYAN_BRUSH); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(rectWin); - ::GdiFlush(); - ::Sleep(1000); -#endif // 0 - } - else - { - wxWindowNative::Refresh(eraseBackground); + // under Unix we use "--sync" X option for this + #ifdef __WXMSW__ + ::GdiFlush(); + ::Sleep(200); + #endif // __WXMSW__ } +#endif // WXDEBUG_REFRESH } // ---------------------------------------------------------------------------- @@ -498,6 +528,15 @@ void wxWindow::DoSetClientSize(int width, int height) // window class // ---------------------------------------------------------------------------- +void wxWindow::RefreshScrollbars() +{ + if ( m_scrollbarHorz ) + m_scrollbarHorz->Refresh(); + + if ( m_scrollbarVert ) + m_scrollbarVert->Refresh(); +} + void wxWindow::PositionScrollbars() { // do not use GetClientSize/Rect as it relies on the scrollbars being @@ -543,6 +582,8 @@ void wxWindow::PositionScrollbars() m_scrollbarHorz->SetSize(rectBar, wxSIZE_NO_ADJUSTMENTS); } + + RefreshScrollbars(); } void wxWindow::SetScrollbar(int orient, @@ -582,9 +623,10 @@ void wxWindow::SetScrollbar(int orient, { if ( GetWindowStyle() & wxALWAYS_SHOW_SB ) { + // just disable the scrollbar scrollbar->Disable(); } - else + else // really remove the scrollbar { delete scrollbar; @@ -592,6 +634,12 @@ void wxWindow::SetScrollbar(int orient, m_scrollbarVert = NULL; else m_scrollbarHorz = NULL; + + // the size of the remaining scrollbar must be adjusted + if ( m_scrollbarHorz || m_scrollbarVert ) + { + PositionScrollbars(); + } } } } @@ -679,7 +727,7 @@ wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal) // just redraw everything as nothing of the displayed image will stay wxLogTrace(_T("scroll"), _T("refreshing everything")); - rect = rectTotal ? *rectTotal : GetClientRect(); + rect = rectTotal ? *rectTotal : wxRect(0, 0, sizeTotal.x, sizeTotal.y); } else // move the part which doesn't change to the new location {