KWidgetsAddons

kxyselector.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 1997 Martin Jones <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "kxyselector.h"
9 
10 #include "loggingcategory.h"
11 
12 #include <QMouseEvent>
13 #include <QPainter>
14 #include <QStyle>
15 #include <QStyleOptionFrame>
16 
17 //-----------------------------------------------------------------------------
18 /*
19  * 2D value selector.
20  * The contents of the selector are drawn by derived class.
21  */
22 
23 class KXYSelectorPrivate
24 {
25 public:
26  KXYSelectorPrivate(KXYSelector *qq)
27  : q(qq)
28  , xPos(0)
29  , yPos(0)
30  , minX(0)
31  , maxX(100)
32  , minY(0)
33  , maxY(100)
34  , m_markerColor(Qt::white)
35  {
36  }
37 
38  void setValues(int _xPos, int _yPos);
39 
40  KXYSelector *const q;
41  int px;
42  int py;
43  int xPos;
44  int yPos;
45  int minX;
46  int maxX;
47  int minY;
48  int maxY;
49  QColor m_markerColor;
50 };
51 
53  : QWidget(parent)
54  , d(new KXYSelectorPrivate(this))
55 {
56 }
57 
58 KXYSelector::~KXYSelector() = default;
59 
60 int KXYSelector::xValue() const
61 {
62  return d->xPos;
63 }
64 
65 int KXYSelector::yValue() const
66 {
67  return d->yPos;
68 }
69 
70 void KXYSelector::setRange(int _minX, int _minY, int _maxX, int _maxY)
71 {
72  if (_maxX == _minX) {
73  qCWarning(KWidgetsAddonsLog) << "KXYSelector::setRange invalid range: " << _maxX << " == " << _minX << " (for X) ";
74  return;
75  }
76  if (_maxY == _minY) {
77  qCWarning(KWidgetsAddonsLog) << "KXYSelector::setRange invalid range: " << _maxY << " == " << _minY << " (for Y) ";
78  return;
79  }
80 
82  d->px = w;
83  d->py = w;
84  d->minX = _minX;
85  d->minY = _minY;
86  d->maxX = _maxX;
87  d->maxY = _maxY;
88 }
89 
90 void KXYSelector::setXValue(int _xPos)
91 {
92  setValues(_xPos, d->yPos);
93 }
94 
95 void KXYSelector::setYValue(int _yPos)
96 {
97  setValues(d->xPos, _yPos);
98 }
99 
100 void KXYSelector::setValues(int _xPos, int _yPos)
101 {
102  d->setValues(_xPos, _yPos);
103 }
104 
105 void KXYSelectorPrivate::setValues(int _xPos, int _yPos)
106 {
107  int w = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
108 
109  xPos = _xPos;
110  yPos = _yPos;
111 
112  if (xPos > maxX) {
113  xPos = maxX;
114  } else if (xPos < minX) {
115  xPos = minX;
116  }
117 
118  if (yPos > maxY) {
119  yPos = maxY;
120  } else if (yPos < minY) {
121  yPos = minY;
122  }
123 
124  Q_ASSERT(maxX != minX);
125  int xp = w + (q->width() - 2 * w) * xPos / (maxX - minX);
126 
127  Q_ASSERT(maxY != minY);
128  int yp = q->height() - w - (q->height() - 2 * w) * yPos / (maxY - minY);
129 
130  q->setPosition(xp, yp);
131 }
132 
134 {
135  d->m_markerColor = col;
136 }
137 
139 {
141  return rect().adjusted(w, w, -w, -w);
142 }
143 
145 {
147  return QSize(2 * w, 2 * w);
148 }
149 
150 void KXYSelector::paintEvent(QPaintEvent * /* ev */)
151 {
152  QStyleOptionFrame opt;
153  opt.initFrom(this);
154 
155  QPainter painter;
156  painter.begin(this);
157 
158  drawContents(&painter);
159  drawMarker(&painter, d->px, d->py);
160 
161  style()->drawPrimitive(QStyle::PE_Frame, &opt, &painter, this);
162 
163  painter.end();
164 }
165 
166 void KXYSelector::mousePressEvent(QMouseEvent *e)
167 {
168  mouseMoveEvent(e);
169 }
170 
171 void KXYSelector::mouseMoveEvent(QMouseEvent *e)
172 {
173  int xVal;
174  int yVal;
176  valuesFromPosition(e->pos().x() - w, e->pos().y() - w, xVal, yVal);
177  setValues(xVal, yVal);
178 
179  Q_EMIT valueChanged(d->xPos, d->yPos);
180 }
181 
182 void KXYSelector::wheelEvent(QWheelEvent *e)
183 {
184  setValues(xValue() + e->angleDelta().x() / 120, yValue() + e->angleDelta().y() / 120);
185  Q_EMIT valueChanged(d->xPos, d->yPos);
186 }
187 
188 void KXYSelector::valuesFromPosition(int x, int y, int &xVal, int &yVal) const
189 {
191 
192  xVal = ((d->maxX - d->minX) * (x - w)) / (width() - 2 * w);
193  yVal = d->maxY - (((d->maxY - d->minY) * (y - w)) / (height() - 2 * w));
194 
195  if (xVal > d->maxX) {
196  xVal = d->maxX;
197  } else if (xVal < d->minX) {
198  xVal = d->minX;
199  }
200 
201  if (yVal > d->maxY) {
202  yVal = d->maxY;
203  } else if (yVal < d->minY) {
204  yVal = d->minY;
205  }
206 }
207 
208 void KXYSelector::setPosition(int xp, int yp)
209 {
211 
212  if (xp < w) {
213  xp = w;
214  } else if (xp > width() - w) {
215  xp = width() - w;
216  }
217 
218  if (yp < w) {
219  yp = w;
220  } else if (yp > height() - w) {
221  yp = height() - w;
222  }
223 
224  d->px = xp;
225  d->py = yp;
226 
227  update();
228 }
229 
231 {
232 }
233 
234 void KXYSelector::drawMarker(QPainter *p, int xp, int yp)
235 {
236  QPen pen(d->m_markerColor);
237  p->setPen(pen);
238 
239  /*
240  p->drawLine( xp - 6, yp - 6, xp - 2, yp - 2 );
241  p->drawLine( xp - 6, yp + 6, xp - 2, yp + 2 );
242  p->drawLine( xp + 6, yp - 6, xp + 2, yp - 2 );
243  p->drawLine( xp + 6, yp + 6, xp + 2, yp + 2 );
244  */
245  p->drawEllipse(xp - 4, yp - 4, 8, 8);
246 }
247 
248 #include "moc_kxyselector.cpp"
QPoint pos() const const
void setPen(const QColor &color)
void setRange(int minX, int minY, int maxX, int maxY)
Sets the range of possible values.
Definition: kxyselector.cpp:70
void setXValue(int xPos)
Sets the current horizontal value.
Definition: kxyselector.cpp:90
KXYSelector(QWidget *parent=nullptr)
Constructs a two-dimensional selector widget which has a value range of [0..100] in both directions.
Definition: kxyselector.cpp:52
void setYValue(int yPos)
Sets the current vertical value.
Definition: kxyselector.cpp:95
void setValues(int xPos, int yPos)
Sets the current values in horizontal and vertical direction.
void drawEllipse(const QRectF &rectangle)
Q_EMITQ_EMIT
void update()
QPoint angleDelta() const const
virtual void drawContents(QPainter *)
Override this function to draw the contents of the widget.
void initFrom(const QWidget *widget)
QRect contentsRect() const
int x() const const
int y() const const
virtual int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const const=0
bool begin(QPaintDevice *device)
bool end()
QStyle * style() const const
void valuesFromPosition(int x, int y, int &xVal, int &yVal) const
Converts a pixel position to its corresponding values.
void valueChanged(int x, int y)
This signal is emitted whenever the user chooses a value, e.g.
PM_DefaultFrameWidth
void setMarkerColor(const QColor &col)
Sets the color used to draw the marker.
virtual void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
virtual void drawMarker(QPainter *p, int xp, int yp)
Override this function to draw the marker which indicates the currently selected value pair.
~KXYSelector() override
Destructs the widget.
QSize minimumSizeHint() const override
Reimplemented to give the widget a minimum size.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sat Sep 30 2023 04:01:00 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.