-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscrollbar.cpp
More file actions
133 lines (106 loc) · 3.26 KB
/
Copy pathscrollbar.cpp
File metadata and controls
133 lines (106 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
////////////////////////////////////////////////////////////////////////////////
// Name: scrollbar.cpp
// Purpose: Implementation of class ScrollBar
// Author: Anton van Wezenbeek
// Copyright: (c) 2017-2026 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////
#include <QStyle>
#include <QStyleOption>
#include "scrollbar.h"
ScrollBar::ScrollBar( ScrollBarPosition pos, Qt::Orientation o, QWidget *parent )
: QScrollBar( o, parent )
, m_inverted( orientation() == Qt::Vertical)
, m_position( pos )
{
moveSlider( m_minBase, m_maxBase );
connect( this, SIGNAL( sliderMoved( int ) ), SLOT( catchSliderMoved( int ) ) );
connect( this, SIGNAL( valueChanged( int ) ), SLOT( catchValueChanged( int ) ) );
setFocusPolicy( Qt::WheelFocus );
}
void ScrollBar::catchValueChanged( int value )
{
double min, max;
sliderRange( value, min, max );
emit valueChanged( orientation(), min, max );
}
void ScrollBar::catchSliderMoved( int value )
{
double min, max;
sliderRange( value, min, max );
emit sliderMoved( orientation(), min, max );
}
int ScrollBar::extent() const
{
QStyleOptionSlider opt;
opt.subControls = QStyle::SC_None;
opt.activeSubControls = QStyle::SC_None;
opt.orientation = orientation();
opt.minimum = minimum();
opt.maximum = maximum();
opt.sliderPosition = sliderPosition();
opt.sliderValue = value();
opt.singleStep = singleStep();
opt.pageStep = pageStep();
opt.upsideDown = invertedAppearance();
if ( orientation() == Qt::Horizontal )
opt.state |= QStyle::State_Horizontal;
return style()->pixelMetric( QStyle::PM_ScrollBarExtent, &opt, this );
}
double ScrollBar::mapFromTick( int tick ) const
{
return m_minBase + ( m_maxBase - m_minBase ) * tick / m_baseTicks;
}
int ScrollBar::mapToTick( double v ) const
{
const double pos = ( v - m_minBase ) / ( m_maxBase - m_minBase ) * m_baseTicks;
return static_cast<int>( pos );
}
double ScrollBar::maxSliderValue() const
{
double max, dummy;
sliderRange( value(), dummy, max );
return max;
}
double ScrollBar::minSliderValue() const
{
double min, dummy;
sliderRange( value(), min, dummy );
return min;
}
void ScrollBar::moveSlider( double min, double max )
{
const int sliderTicks = qRound( ( max - min ) /
( m_maxBase - m_minBase ) * m_baseTicks );
// setRange initiates a valueChanged of the scrollbars
// in some situations. So we block
// and unblock the signals.
blockSignals( true );
setRange( sliderTicks / 2, m_baseTicks - sliderTicks / 2 );
int steps = sliderTicks / 200;
if ( steps <= 0 )
steps = 1;
setSingleStep( steps );
setPageStep( sliderTicks );
int tick = mapToTick( min + ( max - min ) / 2 );
if ( m_inverted )
tick = m_baseTicks - tick;
setSliderPosition( tick );
blockSignals( false );
}
void ScrollBar::setBase( double min, double max )
{
if ( min != m_minBase || max != m_maxBase )
{
m_minBase = min;
m_maxBase = max;
moveSlider( minSliderValue(), maxSliderValue() );
}
}
void ScrollBar::sliderRange( int value, double &min, double &max ) const
{
if ( m_inverted )
value = m_baseTicks - value;
const int visibleTicks = pageStep();
min = mapFromTick( value - visibleTicks / 2 );
max = mapFromTick( value + visibleTicks / 2 );
}