void tpanelscrollbar::OnScrollHandler(wxScrollEvent &event) { wxEventType type = event.GetEventType(); bool upok = (type == wxEVT_SCROLL_TOP || type == wxEVT_SCROLL_LINEUP || type == wxEVT_SCROLL_PAGEUP || type == wxEVT_SCROLL_THUMBRELEASE || type == wxEVT_SCROLL_CHANGED); bool downok = (type == wxEVT_SCROLL_BOTTOM || type == wxEVT_SCROLL_LINEDOWN || type == wxEVT_SCROLL_PAGEDOWN || type == wxEVT_SCROLL_THUMBRELEASE || type == wxEVT_SCROLL_CHANGED); int y; if (type == wxEVT_SCROLL_LINEUP || type == wxEVT_SCROLL_LINEDOWN) { y = GetThumbPosition(); if (type == wxEVT_SCROLL_LINEUP) { y -= gc.linescrollspeed; } else { y += gc.linescrollspeed; } SetThumbPosition(std::max(0, y)); ScrollItems(); } else { if (type == wxEVT_SCROLLWIN_THUMBRELEASE || type == wxEVT_SCROLL_CHANGED) { y = event.GetPosition(); SetThumbPosition(y); } else { y = GetThumbPosition(); } ScrollItemsForPosition(y); event.Skip(); } OnScrollHandlerCommon(upok, downok, 0, y); }
// This determines the scrollbar size and position such that, where possible // the item at the top of the visible screen is unmoved void tpanelscrollbar::RepositionItems() { tpanelscrollpane *tsp = get_paired_ptr(); if (!tsp) return; #if TPANEL_SCROLLING_COPIOUS_LOGGING LogMsgFormat(LOGT::TPANELTRACE, "TSCL: tpanelscrollbar::RepositionItems %s, START %d %d", cstr(GetThisName()), GetThumbPosition(), parent->GetCurrentDisp().size()); #endif scroll_virtual_size = 0; int cumul_size = 0; bool have_scroll_offset = false; int scroll_offset = 0; for (auto &disp : parent->GetCurrentDisp()) { wxPoint p = disp.item->GetPosition(); wxSize s = disp.item->GetSize(); if (!disp.item->IsShown()) { s.y = 0; } scroll_virtual_size += s.y; if (p.x == 0 && p.y + s.y > 0 && p.y <= 0) { // This is an item which is visible at the top of the list // We should use the *last* matching item, this is as earlier items may grow in size to overlap the top of the screen // p.y is non-positive // The scroll offset should be increased as p.y increases in magnitude below 0 scroll_offset = cumul_size - p.y; have_scroll_offset = true; } cumul_size += s.y; } if (parent->pimpl()->displayoffset == 0 && GetThumbPosition() == 0 && have_scroll_offset && !scroll_always_freeze) { // We were at the very top, we would normally be scrolling down as something has been inserted above // Scroll back to the top instead // Don't do this if scroll_always_freeze is true scroll_offset = 0; } scroll_always_freeze = false; if (!have_scroll_offset) { scroll_offset = GetThumbPosition(); } scroll_client_size = tsp->GetClientSize().y; SetScrollbar(scroll_offset, scroll_client_size, scroll_virtual_size, 1); ScrollItems(); #if TPANEL_SCROLLING_COPIOUS_LOGGING LogMsgFormat(LOGT::TPANELTRACE, "TSCL: tpanelscrollbar::RepositionItems %s, END %d %d %d %d %d", cstr(GetThisName()), GetThumbPosition(), scroll_offset, have_scroll_offset, scroll_always_freeze, cumul_size); #endif }
bool wxScrollBar::OnArrow(wxScrollArrows::Arrow arrow) { int oldThumbPos = GetThumbPosition(); PerformAction(arrow == wxScrollArrows::Arrow_First ? wxACTION_SCROLL_LINE_UP : wxACTION_SCROLL_LINE_DOWN); // did we scroll till the end? return GetThumbPosition() != oldThumbPos; }
// Essentially an int to float conversion. void AttachableScrollBar::SetViewInfoFromScrollBar() { ViewInfo & mViewInfo = *mpViewInfo; int hlast = mViewInfo.sbarH; mViewInfo.sbarH = GetThumbPosition(); if (mViewInfo.sbarH != hlast) mViewInfo.SetBeforeScreenWidth(mViewInfo.sbarH); }
void wxScrollBar::SetThumbPosition( int viewStart ) { if (GetThumbPosition() != viewStart) { g_signal_handlers_block_by_func(m_widget, (gpointer)gtk_value_changed, this); gtk_range_set_value((GtkRange*)m_widget, viewStart); m_scrollPos[0] = gtk_range_get_value((GtkRange*)m_widget); g_signal_handlers_unblock_by_func(m_widget, (gpointer)gtk_value_changed, this); } }
void tpanelscrollbar::mousewheelhandler(wxMouseEvent &event) { int pxdelta = -event.GetWheelRotation() * gc.mousewheelscrollspeed / event.GetWheelDelta(); #if TPANEL_SCROLLING_COPIOUS_LOGGING LogMsgFormat(LOGT::TPANELTRACE, "TSCL: tpanelscrollbar::mousewheelhandler %s, %d %d %d", cstr(GetThisName()), GetScrollPos(wxVERTICAL), event.GetWheelRotation(), pxdelta); #endif int y = GetThumbPosition(); SetThumbPosition(std::max(0, y + pxdelta)); ScrollItems(); // Use gc.mousewheelscrollspeed as the threshold, this is to try and make mousewheel scrolling smooth across pages OnScrollHandlerCommon(pxdelta < 0, pxdelta > 0, std::abs(gc.mousewheelscrollspeed), GetScrollPos(wxVERTICAL)); }
wxCoord wxScrollBar::ScrollbarToPixel(int thumbPos) { int range = GetRange(); if ( !range ) { // the only valid position anyhow return 0; } if ( thumbPos == -1 ) { // by default use the current thumb position thumbPos = GetThumbPosition(); } const wxSize sizeArrow = m_renderer->GetScrollbarArrowSize(); return (thumbPos * GetScrollbarSize()) / range + (IsVertical() ? sizeArrow.y : sizeArrow.x); }
void wxScrollBar::SetThumbPosition( int viewStart ) { if (GetThumbPosition() != viewStart) { GtkAdjustment* adj = ((GtkRange*)m_widget)->adjustment; const int i = (GtkRange*)m_widget == m_scrollBar[1]; const int max = int(adj->upper - adj->page_size); if (viewStart > max) viewStart = max; if (viewStart < 0) viewStart = 0; m_scrollPos[i] = adj->value = viewStart; // If a "value_changed" signal emission is not already in progress if (!m_blockValueChanged[i]) { gtk_adjustment_value_changed(adj); } } }
// Essentially an int to float conversion. void AttachableScrollBar::SetViewInfoFromScrollBar() { ViewInfo & mViewInfo = *mpViewInfo; int hlast = mViewInfo.sbarH; int vlast = mViewInfo.vpos; int hoffset = 0; int voffset = 0; mViewInfo.sbarH = GetThumbPosition(); if (mViewInfo.sbarH != hlast) { mViewInfo.h = mViewInfo.sbarH / mViewInfo.zoom; if (mViewInfo.h > mViewInfo.total - mViewInfo.screen) mViewInfo.h = mViewInfo.total - mViewInfo.screen; if (mViewInfo.h < 0.0) mViewInfo.h = 0.0; hoffset = (mViewInfo.sbarH - hlast); } }
void wxScrollBar::SetThumbPosition( int viewStart ) { if (GetThumbPosition() != viewStart) { GtkAdjustment* adj = ((GtkRange*)m_widget)->adjustment; const int i = (GtkRange*)m_widget == m_scrollBar[1]; const int max = int(adj->upper - adj->page_size); if (viewStart > max) viewStart = max; if (viewStart < 0) viewStart = 0; m_scrollPos[i] = adj->value = viewStart; g_signal_handlers_disconnect_by_func( m_widget, (gpointer)gtk_value_changed, this); gtk_adjustment_value_changed(adj); g_signal_connect_after(m_widget, "value_changed", G_CALLBACK(gtk_value_changed), this); } }
void wxScrollBar::SetRange(int range) { SetScrollbar(GetThumbPosition(), GetThumbSize(), range, GetPageSize()); }
void wxScrollBar::SetPageSize( int pageLength ) { SetScrollbar(GetThumbPosition(), GetThumbSize(), GetRange(), pageLength); }
wxRect wxScrollBar::GetScrollbarRect(wxScrollBar::Element elem, int thumbPos) const { if ( thumbPos == -1 ) { thumbPos = GetThumbPosition(); } const wxSize sizeArrow = m_renderer->GetScrollbarArrowSize(); wxSize sizeTotal = GetClientSize(); wxCoord *start, *width; wxCoord length, arrow; wxRect rect; if ( IsVertical() ) { rect.x = 0; rect.width = sizeTotal.x; length = sizeTotal.y; start = &rect.y; width = &rect.height; arrow = sizeArrow.y; } else // horizontal { rect.y = 0; rect.height = sizeTotal.y; length = sizeTotal.x; start = &rect.x; width = &rect.width; arrow = sizeArrow.x; } switch ( elem ) { case wxScrollBar::Element_Arrow_Line_1: *start = 0; *width = arrow; break; case wxScrollBar::Element_Arrow_Line_2: *start = length - arrow; *width = arrow; break; case wxScrollBar::Element_Arrow_Page_1: case wxScrollBar::Element_Arrow_Page_2: // we don't have them at all break; case wxScrollBar::Element_Thumb: case wxScrollBar::Element_Bar_1: case wxScrollBar::Element_Bar_2: // we need to calculate the thumb position - do it { length -= 2*arrow; wxCoord thumbStart, thumbEnd; int range = GetRange(); if ( !range ) { thumbStart = thumbEnd = 0; } else { GetScrollBarThumbSize(length, thumbPos, GetThumbSize(), range, &thumbStart, &thumbEnd); } if ( elem == wxScrollBar::Element_Thumb ) { *start = thumbStart; *width = thumbEnd - thumbStart; } else if ( elem == wxScrollBar::Element_Bar_1 ) { *start = 0; *width = thumbStart; } else // elem == wxScrollBar::Element_Bar_2 { *start = thumbEnd; *width = length - thumbEnd; } // everything is relative to the start of the shaft so far *start += arrow; } break; case wxScrollBar::Element_Max: default: wxFAIL_MSG( wxT("unknown scrollbar element") ); } return rect; }
wxHitTest wxScrollBar::HitTestBar(const wxPoint& pt) const { // we only need to work with either x or y coord depending on the // orientation, choose one (but still check the other one to verify if the // mouse is in the window at all) const wxSize sizeArrowSB = m_renderer->GetScrollbarArrowSize(); wxCoord coord, sizeArrow, sizeTotal; wxSize size = GetSize(); if ( GetWindowStyle() & wxVERTICAL ) { if ( pt.x < 0 || pt.x > size.x ) return wxHT_NOWHERE; coord = pt.y; sizeArrow = sizeArrowSB.y; sizeTotal = size.y; } else // horizontal { if ( pt.y < 0 || pt.y > size.y ) return wxHT_NOWHERE; coord = pt.x; sizeArrow = sizeArrowSB.x; sizeTotal = size.x; } // test for the arrows first as it's faster if ( coord < 0 || coord > sizeTotal ) { return wxHT_NOWHERE; } else if ( coord < sizeArrow ) { return wxHT_SCROLLBAR_ARROW_LINE_1; } else if ( coord > sizeTotal - sizeArrow ) { return wxHT_SCROLLBAR_ARROW_LINE_2; } else { // calculate the thumb position in pixels sizeTotal -= 2*sizeArrow; wxCoord thumbStart, thumbEnd; int range = GetRange(); if ( !range ) { // clicking the scrollbar without range has no effect return wxHT_NOWHERE; } else { GetScrollBarThumbSize(sizeTotal, GetThumbPosition(), GetThumbSize(), range, &thumbStart, &thumbEnd); } // now compare with the thumb position coord -= sizeArrow; if ( coord < thumbStart ) return wxHT_SCROLLBAR_BAR_1; else if ( coord > thumbEnd ) return wxHT_SCROLLBAR_BAR_2; else return wxHT_SCROLLBAR_THUMB; } }
// Calls ScrollItemsForPosition for the current position void tpanelscrollbar::ScrollItems() { ScrollItemsForPosition(GetThumbPosition()); }
gg_tl_dat BigScrollBar::GetBigThumbPosition() { gg_tl_dat result = (((gg_tl_dat)GetThumbPosition())*m_BigRange)/SCROLLBAR_LENGTH; return result; }