1 #include <qstyle.h>
2 #if QT_VERSION >= 0x040000
3 #include <qstyleoption.h>
4 #endif
5 #include "scrollbar.h"
6
ScrollBar(QWidget * parent)7 ScrollBar::ScrollBar(QWidget * parent):
8 QScrollBar(parent)
9 {
10 init();
11 }
12
ScrollBar(Qt::Orientation o,QWidget * parent)13 ScrollBar::ScrollBar(Qt::Orientation o,
14 QWidget *parent):
15 QScrollBar(o, parent)
16 {
17 init();
18 }
19
ScrollBar(double minBase,double maxBase,Qt::Orientation o,QWidget * parent)20 ScrollBar::ScrollBar(double minBase, double maxBase,
21 Qt::Orientation o, QWidget *parent):
22 QScrollBar(o, parent)
23 {
24 init();
25 setBase(minBase, maxBase);
26 moveSlider(minBase, maxBase);
27 }
28
init()29 void ScrollBar::init()
30 {
31 d_inverted = orientation() == Qt::Vertical;
32 d_baseTicks = 1000000;
33 d_minBase = 0.0;
34 d_maxBase = 1.0;
35 moveSlider(d_minBase, d_maxBase);
36
37 connect(this, SIGNAL(sliderMoved(int)), SLOT(catchSliderMoved(int)));
38 connect(this, SIGNAL(valueChanged(int)), SLOT(catchValueChanged(int)));
39 }
40
setInverted(bool inverted)41 void ScrollBar::setInverted(bool inverted)
42 {
43 if ( d_inverted != inverted )
44 {
45 d_inverted = inverted;
46 moveSlider(minSliderValue(), maxSliderValue());
47 }
48 }
49
isInverted() const50 bool ScrollBar::isInverted() const
51 {
52 return d_inverted;
53 }
54
setBase(double min,double max)55 void ScrollBar::setBase(double min, double max)
56 {
57 if ( min != d_minBase || max != d_maxBase )
58 {
59 d_minBase = min;
60 d_maxBase = max;
61
62 moveSlider(minSliderValue(), maxSliderValue());
63 }
64 }
65
moveSlider(double min,double max)66 void ScrollBar::moveSlider(double min, double max)
67 {
68 const int sliderTicks = qRound((max - min) /
69 (d_maxBase - d_minBase) * d_baseTicks);
70
71 // setRange initiates a valueChanged of the scrollbars
72 // in some situations. So we block
73 // and unblock the signals.
74
75 blockSignals(true);
76
77 setRange(sliderTicks / 2, d_baseTicks - sliderTicks / 2);
78 int steps = sliderTicks / 200;
79 if ( steps <= 0 )
80 steps = 1;
81
82 #if QT_VERSION < 0x040000
83 setSteps(steps, sliderTicks);
84 #else
85 setSingleStep(steps);
86 setPageStep(sliderTicks);
87 #endif
88
89 int tick = mapToTick(min + (max - min) / 2);
90 if ( isInverted() )
91 tick = d_baseTicks - tick;
92
93 #if QT_VERSION < 0x040000
94 directSetValue(tick);
95 rangeChange();
96 #else
97 setSliderPosition(tick);
98 #endif
99 blockSignals(false);
100 }
101
minBaseValue() const102 double ScrollBar::minBaseValue() const
103 {
104 return d_minBase;
105 }
106
maxBaseValue() const107 double ScrollBar::maxBaseValue() const
108 {
109 return d_maxBase;
110 }
111
sliderRange(int value,double & min,double & max) const112 void ScrollBar::sliderRange(int value, double &min, double &max) const
113 {
114 if ( isInverted() )
115 value = d_baseTicks - value;
116
117 const int visibleTicks = pageStep();
118
119 min = mapFromTick(value - visibleTicks / 2);
120 max = mapFromTick(value + visibleTicks / 2);
121 }
122
minSliderValue() const123 double ScrollBar::minSliderValue() const
124 {
125 double min, dummy;
126 sliderRange(value(), min, dummy);
127
128 return min;
129 }
130
maxSliderValue() const131 double ScrollBar::maxSliderValue() const
132 {
133 double max, dummy;
134 sliderRange(value(), dummy, max);
135
136 return max;
137 }
138
mapToTick(double v) const139 int ScrollBar::mapToTick(double v) const
140 {
141 return (int) ( ( v - d_minBase) / (d_maxBase - d_minBase ) * d_baseTicks );
142 }
143
mapFromTick(int tick) const144 double ScrollBar::mapFromTick(int tick) const
145 {
146 return d_minBase + ( d_maxBase - d_minBase ) * tick / d_baseTicks;
147 }
148
catchValueChanged(int value)149 void ScrollBar::catchValueChanged(int value)
150 {
151 double min, max;
152 sliderRange(value, min, max);
153 emit valueChanged(orientation(), min, max);
154 }
155
catchSliderMoved(int value)156 void ScrollBar::catchSliderMoved(int value)
157 {
158 double min, max;
159 sliderRange(value, min, max);
160 emit sliderMoved(orientation(), min, max);
161 }
162
extent() const163 int ScrollBar::extent() const
164 {
165 #if QT_VERSION < 0x040000
166 return style().pixelMetric(QStyle::PM_ScrollBarExtent, this);
167 #else
168 QStyleOptionSlider opt;
169 opt.init(this);
170 opt.subControls = QStyle::SC_None;
171 opt.activeSubControls = QStyle::SC_None;
172 opt.orientation = orientation();
173 opt.minimum = minimum();
174 opt.maximum = maximum();
175 opt.sliderPosition = sliderPosition();
176 opt.sliderValue = value();
177 opt.singleStep = singleStep();
178 opt.pageStep = pageStep();
179 opt.upsideDown = invertedAppearance();
180 if (orientation() == Qt::Horizontal)
181 opt.state |= QStyle::State_Horizontal;
182 return style()->pixelMetric(QStyle::PM_ScrollBarExtent, &opt, this);
183 #endif
184 }
185