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); }
void wxVScrolledWindow::UpdateScrollbar() { // see how many lines can we fit on screen const wxCoord hWindow = GetClientSize().y; wxCoord h = 0; size_t line; for ( line = m_lineFirst; line < m_lineMax; line++ ) { if ( h > hWindow ) break; h += OnGetLineHeight(line); } // if we still have remaining space below, maybe we can fit everything? if ( h < hWindow ) { wxCoord hAll = h; for ( size_t lineFirst = m_lineFirst; lineFirst > 0; lineFirst-- ) { hAll += OnGetLineHeight(m_lineFirst - 1); if ( hAll > hWindow ) break; } if ( hAll < hWindow ) { // we don't need scrollbar at all RemoveScrollbar(); return; } } m_nVisible = line - m_lineFirst; int pageSize = m_nVisible; if ( h > hWindow ) { // last line is only partially visible, we still need the scrollbar and // so we have to "fix" pageSize because if it is equal to m_lineMax the // scrollbar is not shown at all under MSW pageSize--; } // set the scrollbar parameters to reflect this SetScrollbar(wxVERTICAL, m_lineFirst, pageSize, m_lineMax); }
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 -= OnGetLineHeight(line); if ( y < 0 ) { // Only change selection if item is fully visible if ( (y + fromBottom) >= 0 ) { wxVListBox::SetSelection((int)line); return; } } } }
size_t wxVScrolledWindow::FindFirstFromBottom(size_t lineLast, bool full) { const wxCoord hWindow = GetClientSize().y; // go upwards until we arrive at a line such that lineLast is not visible // any more when it is shown size_t lineFirst = lineLast; wxCoord h = 0; for ( ;; ) { h += OnGetLineHeight(lineFirst); if ( h > hWindow ) { // for this line to be fully visible we need to go one line // down, but if it is enough for it to be only partly visible then // this line will do as well if ( full ) { lineFirst++; } break; } if ( !lineFirst ) break; lineFirst--; } return lineFirst; }
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; } }
// hit testing int wxSymbolListCtrl::HitTest(const wxPoint& pt) { wxCoord lineHeight = OnGetLineHeight(0); int atLine = GetVisibleBegin() + (pt.y/lineHeight); int symbol = (atLine*m_symbolsPerLine) + (pt.x/(m_cellSize.x+1)); if (symbol >= m_minSymbolValue && symbol <= m_maxSymbolValue) return symbol; return -1; }
// // Returns the height of the line // wxCoord KeyView::GetLineHeight(int line) { // Make sure line is valid if (line < 0 || line >= (int) mLines.GetCount()) { wxASSERT(false); return 0; } return OnGetLineHeight(line); }
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; }
void wxVScrolledWindow::RefreshLine(size_t line) { // is this line visible? if ( !IsVisible(line) ) { // no, it is useless to do anything return; } // calculate the rect occupied by this line on screen wxRect rect; rect.width = GetClientSize().x; rect.height = OnGetLineHeight(line); for ( size_t n = GetVisibleBegin(); n < line; n++ ) { rect.y += OnGetLineHeight(n); } // do refresh it RefreshRect(rect); }
wxCoord wxVScrolledWindow::GetLinesHeight(size_t lineMin, size_t lineMax) const { if ( lineMin == lineMax ) return 0; else if ( lineMin > lineMax ) return -GetLinesHeight(lineMax, lineMin); //else: lineMin < lineMax // let the user code know that we're going to need all these lines OnGetLinesHint(lineMin, lineMax); // do sum up their heights wxCoord height = 0; for ( size_t line = lineMin; line < lineMax; line++ ) { height += OnGetLineHeight(line); } return height; }
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 rectLine; rectLine.width = clientSize.x; dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT))); dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); dc.SetBackgroundMode(wxTRANSPARENT); // 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; 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; } }