#include #include "mmath.h" #include #include #include "slider.h" //------------------------------------------------------------- // Slider - The Slider Widget // // Slider is a slider widget which operates on an interval // of type double. Slider supports different layouts as // well as a scale. //------------------------------------------------------------ //------------------------------------------------------------ //.F Slider::Slider // // Constructor // //.u Syntax: //.f Slider::Slider(QWidget *parent, const char *name, Orientation orient = Horizontal, ScalePos scalePos = None, int bgStyle = BgTrough) // //.u Parameters //.p // QWidget *parent -- parent widget // const char *name -- The Widget's name. Default = 0. // Orientation Orient -- Orientation of the slider. Can be Slider::Horizontal // or Slider::Vertical. // Defaults to Horizontal. // ScalePos scalePos -- Position of the scale. Can be Slider::None, // Slider::Left, Slider::Right, Slider::Top, // or Slider::Bottom. Defaults to Slider::None. // QColor fillcolor -- the color used to fill in the full side // of the Slider //------------------------------------------------------------ Slider::Slider(QWidget *parent, const char *name, Qt::Orientation orient, ScalePos scalePos, QColor fillColor) : SliderBase(parent,name) { d_thumbLength = 16; d_thumbHalf = 8; d_thumbWidth = 16; d_scaleDist = 4; d_scaleStep = 0.0; d_scalePos = scalePos; d_xMargin = 0; d_yMargin = 0; d_mMargin = 1; d_fillColor = fillColor; d_sliderRect.setRect(0, 0, 8, 8); setOrientation(orient); } //------------------------------------------------------------ //.F Slider::~Slider // Destructor //.u Syntax //.f Slider::~Slider() //------------------------------------------------------------ Slider::~Slider() { } //---------------------------------------------------- // //.F Slider::setThumbLength // // Set the slider's thumb length // //.u Syntax // void Slider::setThumbLength(int l) // //.u Parameters //.p int l -- new length // //----------------------------------------------------- void Slider::setThumbLength(int l) { d_thumbLength = qwtMax(l,8); d_thumbHalf = d_thumbLength / 2; resize(size()); } //------------------------------------------------------------ // //.F Slider::setThumbWidth // Change the width of the thumb // //.u Syntax //.p void Slider::setThumbWidth(int w) // //.u Parameters //.p int w -- new width // //------------------------------------------------------------ void Slider::setThumbWidth(int w) { d_thumbWidth = qwtMax(w,4); resize(size()); } //------------------------------------------------------------ //.- //.F Slider::scaleChange // Notify changed scale // //.u Syntax //.f void Slider::scaleChange() // //.u Description // Called by QwtScaledWidget // //------------------------------------------------------------ void Slider::scaleChange() { if (!hasUserScale()) d_scale.setScale(minValue(), maxValue(), d_maxMajor, d_maxMinor); update(); } //------------------------------------------------------------ //.- //.F Slider::fontChange // Notify change in font // //.u Syntax //.f Slider::fontChange(const QFont &oldFont) // //------------------------------------------------------------ void Slider::fontChange(const QFont & /*oldFont*/) { repaint(); } //------------------------------------------------------------ // // roundedPath // Returns a rectangle with rounded corners // // roundCorner can be an bitwise-or combination of // UpperLeft, UpperRight, LowerRight, LowerLeft //------------------------------------------------------------ QPainterPath Slider::roundedPath(QRect r, int xrad, int yrad, RoundCorner roundCorner) { return roundedPath(r.x(), r.y(), r.width(), r.height(), xrad, yrad, roundCorner); } QPainterPath Slider::roundedPath(int x, int y, int w, int h, int xrad, int yrad, RoundCorner roundCorner) { QPainterPath rounded_rect; rounded_rect.addRect(x, y + yrad, w, h - 2 * yrad); if (roundCorner & UpperLeft) { rounded_rect.moveTo(x + xrad, y + yrad); rounded_rect.arcTo(x, y, xrad*2, yrad*2, 180, -90); } else { rounded_rect.moveTo(x, y + yrad); rounded_rect.lineTo(x,y); rounded_rect.lineTo(x + xrad, y); } rounded_rect.lineTo(x + w - xrad, y); if (roundCorner & UpperRight) rounded_rect.arcTo(x + w - xrad * 2, y, xrad*2, yrad*2, 90, -90); else { rounded_rect.lineTo(x + w, y); rounded_rect.lineTo(x + w, y + yrad); } if (roundCorner & LowerLeft) { rounded_rect.moveTo(x + xrad, y + h - yrad); rounded_rect.arcTo(x, y + h - yrad*2, xrad*2, yrad*2, 180, 90); } else { rounded_rect.moveTo(x, y + h - yrad); rounded_rect.lineTo(x, y + h); rounded_rect.lineTo(x + xrad, y + h); } rounded_rect.lineTo(x + w - xrad, y + h); if (roundCorner & LowerRight) rounded_rect.arcTo(x + w - xrad*2, y + h - yrad*2, xrad*2, yrad*2, 270, 90); else { rounded_rect.lineTo(x + w, y + h); rounded_rect.lineTo(x + w, y + h - yrad); } return rounded_rect; } //------------------------------------------------------------ // drawSlider // Draw the slider into the specified rectangle. //------------------------------------------------------------ void Slider::drawSlider(QPainter *p, const QRect &r) { p->setRenderHint(QPainter::Antialiasing); const QPalette& pal = palette(); QBrush brBack(pal.window()); QBrush brMid(pal.mid()); QBrush brDark(pal.dark()); QRect cr; int ipos,dist1; double rpos; int xrad = 4; int yrad = 4; // for the empty side QColor e_mask_edge = pal.mid().color(); QColor e_mask_center = pal.midlight().color(); int e_alpha = 215; e_mask_edge.setAlpha(e_alpha); e_mask_center.setAlpha(e_alpha); QLinearGradient e_mask; e_mask.setColorAt(0, e_mask_edge); e_mask.setColorAt(0.5, e_mask_center); e_mask.setColorAt(1, e_mask_edge); // for the full side rpos = (value() - minValue()) / (maxValue() - minValue()); int f_brightness = 155 * rpos + 100; int f_alpha; int f_edge; if (pal.currentColorGroup() == QPalette::Disabled) { f_alpha = 185; f_edge = 100; } else { f_alpha = 127; f_edge = 0; } QColor f_mask_center = QColor(f_brightness, f_brightness, f_brightness, f_alpha); QColor f_mask_edge = QColor(f_edge, f_edge, f_edge, f_alpha); QLinearGradient f_mask; f_mask.setColorAt(0, f_mask_edge); f_mask.setColorAt(0.5, f_mask_center); f_mask.setColorAt(1, f_mask_edge); // for the thumb QLinearGradient thumbGrad; QColor thumb_edge = pal.dark().color(); QColor thumb_center = pal.midlight().color(); thumbGrad.setColorAt(0, thumb_edge); thumbGrad.setColorAt(0.5, thumb_center); thumbGrad.setColorAt(1, thumb_edge); if (d_orient == Qt::Horizontal) { cr.setRect(r.x(), r.y() + d_mMargin, r.width(), r.height() - 2*d_mMargin); // // Draw background // QPainterPath bg_rect = roundedPath(cr, xrad, yrad, (RoundCorner) (UpperLeft | UpperRight | LowerLeft | LowerRight) ); p->fillPath(bg_rect, d_fillColor); dist1 = int(double(cr.width() - d_thumbLength) * rpos); ipos = cr.x() + dist1; markerPos = ipos + d_thumbHalf; // // Draw empty right side // e_mask.setStart(QPointF(0, cr.y())); e_mask.setFinalStop(QPointF(0, cr.y() + cr.height())); QPainterPath e_rect = roundedPath(ipos + d_thumbLength, cr.y(), cr.width() - d_thumbLength - dist1, cr.height(), xrad, yrad, (RoundCorner) (UpperRight | LowerRight) ); p->fillPath(e_rect, QBrush(e_mask)); // // Draw full left side // f_mask.setStart(QPointF(0, cr.y())); f_mask.setFinalStop(QPointF(0, cr.y() + cr.height())); QPainterPath f_rect = roundedPath(cr.x(), cr.y(), ipos + 1, cr.height(), xrad, yrad, (RoundCorner) (LowerLeft | UpperLeft) ); p->fillPath(f_rect, QBrush(f_mask)); // // Draw thumb // QPainterPath thumb_rect = roundedPath(ipos, r.y(), d_thumbLength, r.height(), 2, 2, (RoundCorner) (UpperLeft | UpperRight | LowerLeft | LowerRight) ); thumbGrad.setStart(QPointF(0, cr.y())); thumbGrad.setFinalStop(QPointF(0, cr.y() + cr.height())); p->fillPath(thumb_rect, QBrush(thumbGrad)); // center line p->fillRect(ipos + d_thumbHalf, cr.y(), 1, cr.height(), pal.dark().color()); } else // (d_orient == Qt::Vertical) { cr.setRect(r.x() + d_mMargin, r.y(), r.width() - 2*d_mMargin, r.height()); // // Draw background // QPainterPath bg_rect = roundedPath(cr, xrad, yrad, (RoundCorner) (UpperLeft | UpperRight | LowerLeft | LowerRight) ); p->fillPath(bg_rect, d_fillColor); dist1 = int(double(cr.height() - d_thumbLength) * (1.0 - rpos)); ipos = cr.y() + dist1; markerPos = ipos + d_thumbHalf; // // Draw empty upper filling // e_mask.setStart(QPointF(cr.x(), 0)); e_mask.setFinalStop(QPointF(cr.x() + cr.width(), 0)); QPainterPath e_rect = roundedPath(cr.x(), cr.y(), cr.width(), ipos + 1, xrad, yrad, (RoundCorner) (UpperLeft | UpperRight) ); p->fillPath(e_rect, QBrush(e_mask)); // // Draw lower filling mask // f_mask.setStart(QPointF(cr.x(), 0)); f_mask.setFinalStop(QPointF(cr.x() + cr.width(), 0)); QPainterPath f_rect = roundedPath(cr.x(), ipos + d_thumbLength, cr.width(), cr.height() - d_thumbLength - dist1, xrad, yrad, (RoundCorner) (LowerLeft | LowerRight) ); p->fillPath(f_rect, QBrush(f_mask)); // // Draw thumb // QPainterPath thumb_rect = roundedPath(r.x(), ipos, r.width(), d_thumbLength, 2, 2, (RoundCorner) (UpperLeft | UpperRight | LowerLeft | LowerRight) ); thumbGrad.setStart(QPointF(cr.x(), 0)); thumbGrad.setFinalStop(QPointF(cr.x() + cr.width(), 0)); p->fillPath(thumb_rect, QBrush(thumbGrad)); // center line p->fillRect(cr.x(), ipos + d_thumbHalf, cr.width(), 1, pal.dark().color()); } } //------------------------------------------------------------ //.- //.F Slider::getValue // Determine the value corresponding to a specified // mouse location. // //.u Syntax //.f double Slider::getValue(const QPoint &p) // //.u Parameters //.p const QPoint &p -- // //.u Description // Called by SliderBase //------------------------------------------------------------ double Slider::getValue( const QPoint &p) { double rv; int pos; QRect r = d_sliderRect; if (d_orient == Qt::Horizontal) { if (r.width() <= d_thumbLength) { rv = 0.5 * (minValue() + maxValue()); } else { pos = p.x() - r.x() - d_thumbHalf; rv = minValue() + rint( (maxValue() - minValue()) * double(pos) / double(r.width() - d_thumbLength) / step() ) * step(); } } else { if (r.height() <= d_thumbLength) { rv = 0.5 * (minValue() + maxValue()); } else { pos = p.y() - r.y() - d_thumbHalf; rv = minValue() + rint( (maxValue() - minValue()) * (1.0 - double(pos) / double(r.height() - d_thumbLength)) / step() ) * step(); } } return(rv); } //------------------------------------------------------------ //.- //.F Slider::getScrollMode // Determine scrolling mode and direction // //.u Syntax //.f void Slider::getScrollMode( const QPoint &p, int &scrollMode, int &direction ) // //.u Parameters //.p const QPoint &p -- point // //.u Description // Called by SliderBase // //------------------------------------------------------------ void Slider::getScrollMode( QPoint &p, const Qt::MouseButton &button, int &scrollMode, int &direction ) { if(cursorHoming() && button == Qt::LeftButton) { if(d_sliderRect.contains(p)) { scrollMode = ScrMouse; direction = 0; int mp = 0; QRect cr; QPoint cp; int ipos,dist1; double rpos; cr = d_sliderRect; rpos = (value() - minValue()) / (maxValue() - minValue()); if(d_orient == Qt::Horizontal) { dist1 = int(double(cr.width() - d_thumbLength) * rpos); ipos = cr.x() + dist1; mp = ipos + d_thumbHalf; p.setX(mp); cp = mapToGlobal( QPoint(mp, p.y()) ); } else { dist1 = int(double(cr.height() - d_thumbLength) * (1.0 - rpos)); ipos = cr.y() + dist1; mp = ipos + d_thumbHalf; p.setY(mp); cp = mapToGlobal( QPoint(p.x(), mp) ); } cursor().setPos(cp.x(), cp.y()); } } else { int currentPos; if (d_orient == Qt::Horizontal) currentPos = p.x(); else currentPos = p.y(); if (d_sliderRect.contains(p)) { if ((currentPos > markerPos - d_thumbHalf) && (currentPos < markerPos + d_thumbHalf)) { scrollMode = ScrMouse; direction = 0; } else { scrollMode = ScrPage; if (((currentPos > markerPos) && (d_orient == Qt::Horizontal)) || ((currentPos <= markerPos) && (d_orient != Qt::Horizontal))) direction = 1; else direction = -1; } } else { scrollMode = ScrNone; direction = 0; } } } //------------------------------------------------------------ //.F Slider::paintEvent // Qt paint event // //.u Syntax //.f void Slider::paintEvent(QPaintEvent *e) //------------------------------------------------------------ void Slider::paintEvent(QPaintEvent* /*e*/) { QPainter p; if (p.begin(this)) { if (d_scalePos != None) { p.fillRect(rect(), palette().window()); d_scale.draw(&p); } drawSlider(&p, d_sliderRect); } p.end(); } //------------------------------------------------------------ //.F Slider::resizeEvent // Qt resize event // //.u Parameters //.p QResizeEvent *e // //.u Syntax //.f void Slider::resizeEvent(QResizeEvent *e) //------------------------------------------------------------ void Slider::resizeEvent(QResizeEvent *e) { d_resized = TRUE; QSize s = e->size(); int sliderWidth = d_thumbWidth; // reposition slider if(d_orient == Qt::Horizontal) { switch(d_scalePos) { case Top: d_sliderRect.setRect(this->rect().x() + d_xMargin, this->rect().y() + s.height() - 1 - d_yMargin - sliderWidth, s.width() - 2 * d_xMargin, sliderWidth); d_scale.setGeometry(d_sliderRect.x() + d_thumbHalf, d_sliderRect.y() - d_scaleDist, d_sliderRect.width() - d_thumbLength, ScaleDraw::Top); break; case Bottom: d_sliderRect.setRect(this->rect().x() + d_xMargin, this->rect().y() + d_yMargin, s.width() - 2*d_xMargin, sliderWidth); d_scale.setGeometry(d_sliderRect.x() + d_thumbHalf, d_sliderRect.y() + d_sliderRect.height() + d_scaleDist, d_sliderRect.width() - d_thumbLength, ScaleDraw::Bottom); break; default: d_sliderRect.setRect(this->rect().x(), this->rect().x(), s.width(), s.height()); break; } } else // d_orient == Qt::Vertical { switch(d_scalePos) { case Left: d_sliderRect.setRect(this->rect().x() + s.width() - sliderWidth - 1 - d_xMargin, this->rect().y() + d_yMargin, sliderWidth, s.height() - 2 * d_yMargin); d_scale.setGeometry(d_sliderRect.x() - d_scaleDist, d_sliderRect.y() + d_thumbHalf, s.height() - d_thumbLength, ScaleDraw::Left); break; case Right: d_sliderRect.setRect(this->rect().x() + d_xMargin, this->rect().y() + d_yMargin, sliderWidth, s.height() - 2* d_yMargin); d_scale.setGeometry(this->rect().x() + d_sliderRect.width() + d_scaleDist, d_sliderRect.y() + d_thumbHalf, s.height() - d_thumbLength, ScaleDraw::Right); break; default: d_sliderRect.setRect(this->rect().x(), this->rect().x(), s.width(), s.height()); break; } } } //------------------------------------------------------------ //.- //.F Slider::valueChange // Notify change of value // //.u Syntax //.f void Slider::valueChange() // //------------------------------------------------------------ void Slider::valueChange() { update(); SliderBase::valueChange(); } //------------------------------------------------------------ //.- //.F Slider::rangeChange // Notify change of range // //.u Description // //.u Syntax //.f void Slider::rangeChange() // //------------------------------------------------------------ void Slider::rangeChange() { if (!hasUserScale()) d_scale.setScale(minValue(), maxValue(), d_maxMajor, d_maxMinor); SliderBase::rangeChange(); repaint(); } //------------------------------------------------------------ // //.F Slider::setMargins // Set distances between the widget's border and // internals. // //.u Syntax //.f void Slider::setMargins(int hor, int vert) // //.u Parameters //.p int hor, int vert -- Margins // //------------------------------------------------------------ void Slider::setMargins(int hor, int vert) { d_xMargin = qwtMax(0, hor); d_yMargin = qwtMin(0, vert); resize(this->size()); } //------------------------------------------------------------ // //.F Slider::sizeHint // Return a recommended size // //.u Syntax //.f QSize Slider::sizeHint() const // //.u Note // The return value of sizeHint() depends on the font and the // scale. //------------------------------------------------------------ QSize Slider::sizeHint() //const ddskrjo { QPainter p; int msWidth = 0, msHeight = 0; int w = 40; int h = 40; if (d_scalePos != None) { if (p.begin(this)) { msWidth = d_scale.maxWidth(&p, FALSE); msHeight = d_scale.maxHeight(&p); } p.end(); switch(d_orient) { case Qt::Vertical: w = 2*d_xMargin + d_thumbWidth + msWidth + d_scaleDist + 2; break; case Qt::Horizontal: h = 2*d_yMargin + d_thumbWidth + msHeight + d_scaleDist; break; } } else { // no scale switch(d_orient) { case Qt::Vertical: w = 16; break; case Qt::Horizontal: h = 16; break; } } return QSize(w, h); } //--------------------------------------------------------- // setOrientation //--------------------------------------------------------- void Slider::setOrientation(Qt::Orientation o) { d_orient = o; ScaleDraw::OrientationX so = ScaleDraw::Bottom; switch(d_orient) { case Qt::Vertical: if (d_scalePos == Right) so = ScaleDraw::Right; else so = ScaleDraw::Left; break; case Qt::Horizontal: if (d_scalePos == Bottom) so = ScaleDraw::Bottom; else so = ScaleDraw::Top; break; } d_scale.setGeometry(0, 0, 40, so); if (d_orient == Qt::Vertical) setMinimumSize(10,20); else setMinimumSize(20,10); QRect r = geometry(); setGeometry(r.x(), r.y(), r.height(), r.width()); update(); } Qt::Orientation Slider::orientation() const { return d_orient; } double Slider::lineStep() const { return 1.0; } double Slider::pageStep() const { return 1.0; } void Slider::setLineStep(double) { } void Slider::setPageStep(double) { }