dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
textbubbleslider.cpp
Go to the documentation of this file.
1 
12 /*
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, see <http://www.gnu.org/licenses/>
25 */
26 
27 #include <QDebug>
28 #include <QPainter>
29 #include <QDebug>
30 #include <qmath.h>
31 
32 #include "textbubbleslider.h"
33 
39  : QSlider(parent)
40  , indicatorValue(0)
41 {
42  construct();
43  hidden = false;
44 }
45 
52 TextBubbleSlider::TextBubbleSlider(QSlider *copySlider, QWidget *parent)
53  : QSlider(parent)
54 {
55  construct();
56 
57  hidden = false;
58 
59  // Copy settings
60  setSizePolicy(copySlider->sizePolicy());
61  setMinimumSize(copySlider->minimumSize());
62  setMaximumSize(copySlider->maximumSize());
63  setFocusPolicy(copySlider->focusPolicy());
64  setOrientation(copySlider->orientation());
65  setMaximum(copySlider->maximum());
66  setMinimum(copySlider->minimum());
67  setToolTip(copySlider->toolTip());
68 }
69 
75 {
76  font = QFont("Arial", 13);
77  slideHandleMargin = 2; // This is a dubious way to set the margin. In reality, it should be read
78  // from the style sheet.
79 }
80 
82 {
83 }
84 
90 unsigned int numIntegerDigits(int number)
91 {
92  unsigned int digits = 0;
93 
94  // If there is a negative sign, be sure to include it in digit count
95  if (number < 0)
96  digits = 1;
97 
98  while (number) {
99  number /= 10;
100  digits++;
101  }
102 
103  return digits;
104 }
105 
109 void TextBubbleSlider::setMaxPixelWidth()
110 {
111  // Calculate maximum number of digits possible in string
112  int maxNumDigits = numIntegerDigits(maximum()) > numIntegerDigits(minimum())
113  ? numIntegerDigits(maximum())
114  : numIntegerDigits(minimum());
115 
116  // Generate string with maximum pixel width. Suppose that "0" is
117  // the widest number in pixels.
118  QString maximumWidthString;
119  for (int i = 0; i < maxNumDigits; i++) {
120  maximumWidthString.append("0");
121  }
122 
123  // Calculate maximum possible pixel width for string.
124  QFontMetrics fontMetrics(font);
125  maximumFontWidth = fontMetrics.width(QString("%1").arg(maximumWidthString));
126  maximumFontHeight = fontMetrics.height();
127 
128  // Override stylesheet slider handle width
129  slideHandleWidth = maximumFontWidth + 6;
130  setStyleSheet(QString("QSlider::handle:horizontal { width: %1px; margin: -5px 0;}")
131  .arg(slideHandleWidth));
132 }
133 
140 {
141  // Pass value on to QSlider
142  QSlider::setMinimum(max);
143 
144  // Reset handler size
145  setMaxPixelWidth();
146 }
147 
154 {
155  // Pass value on to QSlider
156  QSlider::setMaximum(max);
157 
158  // Reset handler size
159  setMaxPixelWidth();
160 }
161 
167 {
168  hidden = h;
169 }
170 
175 void TextBubbleSlider::paintEvent(QPaintEvent *paintEvent)
176 {
177  if (hidden) {
178  return;
179  }
180 
181  int sliderHeight = height();
182  const double indicatorWidth = 5.0;
183 
184  // draw solid indicator behind everything
185  bool drawIndicator =
186  indicatorValue >= (minimum() * -0.1) && indicatorValue <= (1.1 * maximum());
187  qreal indicatorPos = 0;
188  QPen indicatorPen(QBrush(QColor(255, 0, 0, 180)), indicatorWidth, Qt::SolidLine, Qt::RoundCap,
189  Qt::RoundJoin);
190  if (drawIndicator) {
191  QPainter p(this);
192  p.setRenderHint(QPainter::Antialiasing);
193  p.setPen(indicatorPen);
194  indicatorPos = sliderPosFromValue(indicatorValue);
195  p.drawLine(QLineF(indicatorPos, indicatorWidth / 2.0, indicatorPos,
196  sliderHeight - indicatorWidth / 2.0));
197  }
198 
199  // Pass paint event on to QSlider
200  QSlider::paintEvent(paintEvent);
201 
202  // need a new painter after QSlider has done it's painting
203  QPainter painter(this);
204  painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
205 
206  // draw indicator translucent over handle + slider
207  if (drawIndicator) {
208  indicatorPen.setColor(QColor(255, 0, 0, 50));
209  painter.setPen(indicatorPen);
210  painter.drawLine(QLineF(indicatorPos, indicatorWidth / 2.0, indicatorPos,
211  sliderHeight - indicatorWidth / 2.0));
212  }
213 
214  /* Add numbers on top of handler */
215  qreal valuePos = sliderPosFromValue(value()) - maximumFontWidth / 2;
216 
217  // Draw neutral value text. Verically center it in the handle
218  painter.setFont(font);
219  painter.setPen(Qt::SolidLine);
220  QString neutralStringWidth = QString("%1").arg(value());
221  QFontMetrics fontMetrics(font);
222  int textWidth = fontMetrics.width(neutralStringWidth);
223  painter.drawText(QRectF(valuePos + maximumFontWidth - textWidth,
224  ceil((sliderHeight - maximumFontHeight) / 2.0), textWidth,
225  maximumFontHeight),
226  neutralStringWidth);
227 }
228 
230 {
231  bool changed = indicatorValue != us;
232  indicatorValue = us;
233  if (changed)
234  update();
235 }
236 
238 {
239  qreal offset = invertedAppearance() ? maximum() - val : val - minimum();
240  return slideHandleWidth / 2 + slideHandleMargin + // account for handle width
241  offset / (maximum() - minimum()) * (width() - (slideHandleWidth + slideHandleMargin) - 1);
242 }
TextBubbleSlider(QWidget *parent=nullptr)
TextBubbleSlider::TextBubbleSlider Constructs a regular text-bubble slider.
qreal sliderPosFromValue(const int val)
Creates a slider with a text bubble showing the slider value.
for i
Definition: OPPlots.m:140
void setMaximum(int)
TextBubbleSlider::setMaximum Reimplements setMaximum. Ensures that the slider handle is the correct s...
void setHidden(bool)
Hide the slider by not painting it.
void setMinimum(int)
TextBubbleSlider::setMinimum Reimplements setMinimum. Ensures that the slider handle is the correct s...
unsigned int numIntegerDigits(int number)
numIntegerDigits Counts the number of digits in an integer
void construct()
TextBubbleSlider::construct This function needs to be called from all constructors. It provides a single point where settings can be changed.
void setIndicatorValue(int us)
void paintEvent(QPaintEvent *event)
TextBubbleSlider::paintEvent Reimplements QSlider::paintEvent.