void wxVScrolledWindow::RefreshLines(size_t from, size_t to) { wxASSERT_MSG( from <= to, _T("RefreshLines(): empty range") ); // clump the range to just the visible lines -- it is useless to refresh // the other ones if ( from < GetVisibleBegin() ) from = GetVisibleBegin(); if ( to >= GetVisibleEnd() ) to = GetVisibleEnd(); else to++; // calculate the rect occupied by these lines on screen wxRect rect; rect.width = GetClientSize().x; for ( size_t nBefore = GetVisibleBegin(); nBefore < from; nBefore++ ) { rect.y += OnGetLineHeight(nBefore); } for ( size_t nBetween = from; nBetween < to; nBetween++ ) { rect.height += OnGetLineHeight(nBetween); } // do refresh it RefreshRect(rect); }
bool wxVScrolledWindow::ScrollToLine(size_t line) { if ( !m_lineMax ) { // we're empty, code below doesn't make sense in this case return false; } // determine the real first line to scroll to: we shouldn't scroll beyond // the end size_t lineFirstLast = FindFirstFromBottom(m_lineMax - 1, true); if ( line > lineFirstLast ) line = lineFirstLast; // anything to do? if ( line == m_lineFirst ) { // no return false; } // remember the currently shown lines for the refresh code below size_t lineFirstOld = GetVisibleBegin(), lineLastOld = GetVisibleEnd(); m_lineFirst = line; // the size of scrollbar thumb could have changed UpdateScrollbar(); // finally refresh the display -- but only redraw as few lines as possible // to avoid flicker if ( GetChildren().empty() && (GetVisibleBegin() >= lineLastOld || GetVisibleEnd() <= lineFirstOld ) ) { // the simplest case: we don't have any old lines left, just redraw // everything Refresh(); } else // overlap between the lines we showed before and should show now { // Avoid scrolling visible parts of the screen on Mac #ifdef __WXMAC__ if (!IsShownOnScreen()) Refresh(); else #endif ScrollWindow(0, GetLinesHeight(GetVisibleBegin(), lineFirstOld)); } return true; }
void wxVListBoxComboPopup::OnMouseMove(wxMouseEvent& event) { event.Skip(); // Move selection to cursor if it is inside the popup int y = event.GetPosition().y; int fromBottom = GetClientSize().y - y; // Since in any case we need to find out if the last item is only // partially visible, we might just as well replicate the HitTest // loop here. const size_t lineMax = GetVisibleEnd(); for ( size_t line = GetVisibleBegin(); line < lineMax; line++ ) { y -= OnGetRowHeight(line); if ( y < 0 ) { // Only change selection if item is fully visible if ( (y + fromBottom) >= 0 ) { wxVListBox::SetSelection((int)line); return; } } } }
bool wxVScrolledWindow::ScrollPages(int pages) { bool didSomething = false; while ( pages ) { int line; if ( pages > 0 ) { line = GetVisibleEnd(); if ( line ) line--; pages--; } else // pages < 0 { line = FindFirstFromBottom(GetVisibleBegin()); pages++; } didSomething = ScrollToLine(line); } return didSomething; }
void wxVListBox::RefreshSelected() { // only refresh those items which are currently visible and selected: for ( size_t n = GetVisibleBegin(), end = GetVisibleEnd(); n < end; n++ ) { if ( IsSelected(n) ) RefreshRow(n); } }
void wxVListBox::OnPaint(wxPaintEvent& WXUNUSED(event)) { wxSize clientSize = GetClientSize(); wxAutoBufferedPaintDC dc(this); // the update rectangle wxRect rectUpdate = GetUpdateClientRect(); // fill it with background colour dc.SetBackground(GetBackgroundColour()); dc.Clear(); // the bounding rectangle of the current line wxRect rectLine; rectLine.width = clientSize.x; // iterate over all visible lines const size_t lineMax = GetVisibleEnd(); for ( size_t line = GetFirstVisibleLine(); line < lineMax; line++ ) { const wxCoord hLine = OnGetLineHeight(line); rectLine.height = hLine; // and draw the ones which intersect the update rect if ( rectLine.Intersects(rectUpdate) ) { // don't allow drawing outside of the lines rectangle wxDCClipper clip(dc, rectLine); wxRect rect = rectLine; OnDrawBackground(dc, rect, line); OnDrawSeparator(dc, rect, line); rect.Deflate(m_ptMargins.x, m_ptMargins.y); OnDrawItem(dc, rect, line); } else // no intersection { if ( rectLine.GetTop() > rectUpdate.GetBottom() ) { // we are already below the update rect, no need to continue // further break; } //else: the next line may intersect the update rect } rectLine.y += hLine; } }
void wxVScrolledWindow::OnScroll(wxScrollWinEvent& event) { size_t lineFirstNew; const wxEventType evtType = event.GetEventType(); if ( evtType == wxEVT_SCROLLWIN_TOP ) { lineFirstNew = 0; } else if ( evtType == wxEVT_SCROLLWIN_BOTTOM ) { lineFirstNew = m_lineMax; } else if ( evtType == wxEVT_SCROLLWIN_LINEUP ) { lineFirstNew = m_lineFirst ? m_lineFirst - 1 : 0; } else if ( evtType == wxEVT_SCROLLWIN_LINEDOWN ) { lineFirstNew = m_lineFirst + 1; } else if ( evtType == wxEVT_SCROLLWIN_PAGEUP ) { lineFirstNew = FindFirstFromBottom(m_lineFirst); } else if ( evtType == wxEVT_SCROLLWIN_PAGEDOWN ) { lineFirstNew = GetVisibleEnd(); if ( lineFirstNew ) lineFirstNew--; } else if ( evtType == wxEVT_SCROLLWIN_THUMBRELEASE ) { lineFirstNew = event.GetPosition(); } else if ( evtType == wxEVT_SCROLLWIN_THUMBTRACK ) { lineFirstNew = event.GetPosition(); } else // unknown scroll event? { wxFAIL_MSG( _T("unknown scroll event type?") ); return; } ScrollToLine(lineFirstNew); #ifdef __WXMAC__ Update(); #endif // __WXMAC__ }
int wxVScrolledWindow::HitTest(wxCoord WXUNUSED(x), wxCoord y) const { const size_t lineMax = GetVisibleEnd(); for ( size_t line = GetVisibleBegin(); line < lineMax; line++ ) { y -= OnGetLineHeight(line); if ( y < 0 ) return line; } return wxNOT_FOUND; }
bool wxSymbolListCtrl::DoSetCurrent(int current) { wxASSERT_MSG( current == wxNOT_FOUND || (current >= m_minSymbolValue && current <= m_maxSymbolValue), wxT("wxSymbolListCtrl::DoSetCurrent(): invalid symbol value") ); if ( current == m_current ) { // nothing to do return false; } if ( m_current != wxNOT_FOUND ) RefreshRow(SymbolValueToLineNumber(m_current)); m_current = current; if ( m_current != wxNOT_FOUND ) { int lineNo = SymbolValueToLineNumber(m_current); // if the line is not visible at all, we scroll it into view but we // don't need to refresh it -- it will be redrawn anyhow if ( !IsVisible(lineNo) ) { ScrollToRow(lineNo); } else // line is at least partly visible { // it is, indeed, only partly visible, so scroll it into view to // make it entirely visible while ( (unsigned)lineNo + 1 == GetVisibleEnd() && ScrollToRow(GetVisibleBegin() + 1) ) ; // but in any case refresh it as even if it was only partly visible // before we need to redraw it entirely as its background changed RefreshRow(lineNo); } } return true; }
wxRect wxVListBox::GetItemRect(size_t n) const { wxRect itemrect; // check that this item is visible const size_t lineMax = GetVisibleEnd(); if ( n >= lineMax ) return itemrect; size_t line = GetVisibleBegin(); if ( n < line ) return itemrect; while ( line <= n ) { itemrect.y += itemrect.height; itemrect.height = OnGetRowHeight(line); line++; } itemrect.width = GetClientSize().x; return itemrect; }
void wxSymbolListCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) { // If size is larger, recalculate double buffer bitmap wxSize clientSize = GetClientSize(); if ( !m_doubleBuffer || clientSize.x > m_doubleBuffer->GetWidth() || clientSize.y > m_doubleBuffer->GetHeight() ) { delete m_doubleBuffer; m_doubleBuffer = new wxBitmap(clientSize.x+25,clientSize.y+25); } wxBufferedPaintDC dc(this,*m_doubleBuffer); // the update rectangle wxRect rectUpdate = GetUpdateClientRect(); // fill it with background colour dc.SetBackground(GetBackgroundColour()); dc.Clear(); // set the font to be displayed dc.SetFont(GetFont()); // the bounding rectangle of the current line wxRect rectRow; rectRow.width = clientSize.x; dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT))); dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); // iterate over all visible lines const size_t lineMax = GetVisibleEnd(); for ( size_t line = GetVisibleBegin(); line < lineMax; line++ ) { const wxCoord hRow = OnGetRowHeight(line); rectRow.height = hRow; // and draw the ones which intersect the update rect if ( rectRow.Intersects(rectUpdate) ) { // don't allow drawing outside of the lines rectangle wxDCClipper clip(dc, rectRow); wxRect rect = rectRow; rect.Deflate(m_ptMargins.x, m_ptMargins.y); OnDrawItem(dc, rect, line); } else // no intersection { if ( rectRow.GetTop() > rectUpdate.GetBottom() ) { // we are already below the update rect, no need to continue // further break; } //else: the next line may intersect the update rect } rectRow.y += hRow; } }