mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-16 01:19:57 +00:00
898 lines
22 KiB
C++
898 lines
22 KiB
C++
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
|
|
* Qwt Widget Library
|
|
* Copyright (C) 1997 Josef Wilgen
|
|
* Copyright (C) 2002 Uwe Rathmann
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the Qwt License, Version 1.0
|
|
*****************************************************************************/
|
|
|
|
// vim: expandtab
|
|
|
|
#include <math.h>
|
|
#include <qevent.h>
|
|
#include <qdrawutil.h>
|
|
#include <qpainter.h>
|
|
#include "qwt_painter.h"
|
|
#include "qwt_paint_buffer.h"
|
|
#include "qwt_scale_draw.h"
|
|
#include "qwt_scale_map.h"
|
|
#include "qwt_slider.h"
|
|
|
|
class QwtSlider::PrivateData
|
|
{
|
|
public:
|
|
QRect sliderRect;
|
|
|
|
int thumbLength;
|
|
int thumbWidth;
|
|
int borderWidth;
|
|
int scaleDist;
|
|
int xMargin;
|
|
int yMargin;
|
|
|
|
QwtSlider::ScalePos scalePos;
|
|
QwtSlider::BGSTYLE bgStyle;
|
|
|
|
/*
|
|
Scale and values might have different maps. This is
|
|
confusing and I can't see strong arguments for such
|
|
a feature. TODO ...
|
|
*/
|
|
QwtScaleMap map; // linear map
|
|
mutable QSize sizeHintCache;
|
|
};
|
|
|
|
/*!
|
|
\brief Constructor
|
|
\param parent parent widget
|
|
\param orientation Orientation of the slider. Can be Qt::Horizontal
|
|
or Qt::Vertical. Defaults to Qt::Horizontal.
|
|
\param scalePos Position of the scale.
|
|
Defaults to QwtSlider::NoScale.
|
|
\param bgStyle Background style. QwtSlider::BgTrough draws the
|
|
slider button in a trough, QwtSlider::BgSlot draws
|
|
a slot underneath the button. An or-combination of both
|
|
may also be used. The default is QwtSlider::BgTrough.
|
|
|
|
QwtSlider enforces valid combinations of its orientation and scale position.
|
|
If the combination is invalid, the scale position will be set to NoScale.
|
|
Valid combinations are:
|
|
- Qt::Horizonal with NoScale, TopScale, or BottomScale;
|
|
- Qt::Vertical with NoScale, LeftScale, or RightScale.
|
|
*/
|
|
QwtSlider::QwtSlider(QWidget *parent,
|
|
Qt::Orientation orientation, ScalePos scalePos, BGSTYLE bgStyle):
|
|
QwtAbstractSlider(orientation, parent)
|
|
{
|
|
initSlider(orientation, scalePos, bgStyle);
|
|
}
|
|
|
|
#if QT_VERSION < 0x040000
|
|
/*!
|
|
\brief Constructor
|
|
|
|
Build a horizontal slider with no scale and BgTrough as
|
|
background style
|
|
|
|
\param parent parent widget
|
|
\param name Object name
|
|
*/
|
|
QwtSlider::QwtSlider(QWidget *parent, const char* name):
|
|
QwtAbstractSlider(Qt::Horizontal, parent)
|
|
{
|
|
setName(name);
|
|
initSlider(Qt::Horizontal, NoScale, BgTrough);
|
|
}
|
|
#endif
|
|
|
|
void QwtSlider::initSlider(Qt::Orientation orientation,
|
|
ScalePos scalePos, BGSTYLE bgStyle)
|
|
{
|
|
if (orientation == Qt::Vertical)
|
|
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
|
else
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
|
|
|
#if QT_VERSION >= 0x040000
|
|
setAttribute(Qt::WA_WState_OwnSizePolicy, false);
|
|
#else
|
|
clearWState( WState_OwnSizePolicy );
|
|
#endif
|
|
|
|
|
|
#if QT_VERSION < 0x040000
|
|
setWFlags(Qt::WNoAutoErase);
|
|
#endif
|
|
|
|
d_data = new QwtSlider::PrivateData;
|
|
|
|
d_data->borderWidth = 2;
|
|
d_data->scaleDist = 4;
|
|
d_data->scalePos = scalePos;
|
|
d_data->xMargin = 0;
|
|
d_data->yMargin = 0;
|
|
d_data->bgStyle = bgStyle;
|
|
|
|
if (bgStyle == BgSlot)
|
|
{
|
|
d_data->thumbLength = 16;
|
|
d_data->thumbWidth = 30;
|
|
}
|
|
else
|
|
{
|
|
d_data->thumbLength = 31;
|
|
d_data->thumbWidth = 16;
|
|
}
|
|
|
|
d_data->sliderRect.setRect(0,0,8,8);
|
|
|
|
QwtScaleDraw::Alignment align;
|
|
if ( orientation == Qt::Vertical )
|
|
{
|
|
// enforce a valid combination of scale position and orientation
|
|
if ((d_data->scalePos == BottomScale) || (d_data->scalePos == TopScale))
|
|
d_data->scalePos = NoScale;
|
|
// adopt the policy of layoutSlider (NoScale lays out like Left)
|
|
if (d_data->scalePos == RightScale)
|
|
align = QwtScaleDraw::RightScale;
|
|
else
|
|
align = QwtScaleDraw::LeftScale;
|
|
}
|
|
else
|
|
{
|
|
// enforce a valid combination of scale position and orientation
|
|
if ((d_data->scalePos == LeftScale) || (d_data->scalePos == RightScale))
|
|
d_data->scalePos = NoScale;
|
|
// adopt the policy of layoutSlider (NoScale lays out like Bottom)
|
|
if (d_data->scalePos == TopScale)
|
|
align = QwtScaleDraw::TopScale;
|
|
else
|
|
align = QwtScaleDraw::BottomScale;
|
|
}
|
|
|
|
scaleDraw()->setAlignment(align);
|
|
scaleDraw()->setLength(100);
|
|
|
|
setRange(0.0, 100.0, 1.0);
|
|
setValue(0.0);
|
|
}
|
|
|
|
QwtSlider::~QwtSlider()
|
|
{
|
|
delete d_data;
|
|
}
|
|
|
|
/*!
|
|
\brief Set the orientation.
|
|
\param o Orientation. Allowed values are Qt::Horizontal and Qt::Vertical.
|
|
|
|
If the new orientation and the old scale position are an invalid combination,
|
|
the scale position will be set to QwtSlider::NoScale.
|
|
\sa QwtAbstractSlider::orientation()
|
|
*/
|
|
void QwtSlider::setOrientation(Qt::Orientation o)
|
|
{
|
|
if ( o == orientation() )
|
|
return;
|
|
|
|
if (o == Qt::Horizontal)
|
|
{
|
|
if ((d_data->scalePos == LeftScale) || (d_data->scalePos == RightScale))
|
|
d_data->scalePos = NoScale;
|
|
}
|
|
else // if (o == Qt::Vertical)
|
|
{
|
|
if ((d_data->scalePos == BottomScale) || (d_data->scalePos == TopScale))
|
|
d_data->scalePos = NoScale;
|
|
}
|
|
|
|
#if QT_VERSION >= 0x040000
|
|
if ( !testAttribute(Qt::WA_WState_OwnSizePolicy) )
|
|
#else
|
|
if ( !testWState( WState_OwnSizePolicy ) )
|
|
#endif
|
|
{
|
|
QSizePolicy sp = sizePolicy();
|
|
sp.transpose();
|
|
setSizePolicy(sp);
|
|
|
|
#if QT_VERSION >= 0x040000
|
|
setAttribute(Qt::WA_WState_OwnSizePolicy, false);
|
|
#else
|
|
clearWState( WState_OwnSizePolicy );
|
|
#endif
|
|
}
|
|
|
|
QwtAbstractSlider::setOrientation(o);
|
|
layoutSlider();
|
|
}
|
|
|
|
/*!
|
|
\brief Change the scale position (and slider orientation).
|
|
|
|
\param s Position of the scale.
|
|
|
|
A valid combination of scale position and orientation is enforced:
|
|
- if the new scale position is Left or Right, the scale orientation will
|
|
become Qt::Vertical;
|
|
- if the new scale position is Bottom or Top the scale orientation will
|
|
become Qt::Horizontal;
|
|
- if the new scale position is QwtSlider::NoScale, the scale
|
|
orientation will not change.
|
|
*/
|
|
void QwtSlider::setScalePosition(ScalePos s)
|
|
{
|
|
if ( d_data->scalePos == s )
|
|
return;
|
|
|
|
d_data->scalePos = s;
|
|
|
|
switch(d_data->scalePos)
|
|
{
|
|
case BottomScale:
|
|
{
|
|
setOrientation(Qt::Horizontal);
|
|
scaleDraw()->setAlignment(QwtScaleDraw::BottomScale);
|
|
break;
|
|
}
|
|
case TopScale:
|
|
{
|
|
setOrientation(Qt::Horizontal);
|
|
scaleDraw()->setAlignment(QwtScaleDraw::TopScale);
|
|
break;
|
|
}
|
|
case LeftScale:
|
|
{
|
|
setOrientation(Qt::Vertical);
|
|
scaleDraw()->setAlignment(QwtScaleDraw::LeftScale);
|
|
break;
|
|
}
|
|
case RightScale:
|
|
{
|
|
setOrientation(Qt::Vertical);
|
|
scaleDraw()->setAlignment(QwtScaleDraw::RightScale);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
// nothing
|
|
}
|
|
}
|
|
|
|
layoutSlider();
|
|
}
|
|
|
|
//! Return the scale position.
|
|
QwtSlider::ScalePos QwtSlider::scalePosition() const
|
|
{
|
|
return d_data->scalePos;
|
|
}
|
|
|
|
/*!
|
|
\brief Change the slider's border width
|
|
\param bd border width
|
|
*/
|
|
void QwtSlider::setBorderWidth(int bd)
|
|
{
|
|
if ( bd < 0 )
|
|
bd = 0;
|
|
|
|
if ( bd != d_data->borderWidth )
|
|
{
|
|
d_data->borderWidth = bd;
|
|
layoutSlider();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief Set the slider's thumb length
|
|
\param thumbLength new length
|
|
*/
|
|
void QwtSlider::setThumbLength(int thumbLength)
|
|
{
|
|
if ( thumbLength < 8 )
|
|
thumbLength = 8;
|
|
|
|
if ( thumbLength != d_data->thumbLength )
|
|
{
|
|
d_data->thumbLength = thumbLength;
|
|
layoutSlider();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief Change the width of the thumb
|
|
\param w new width
|
|
*/
|
|
void QwtSlider::setThumbWidth(int w)
|
|
{
|
|
if ( w < 4 )
|
|
w = 4;
|
|
|
|
if ( d_data->thumbWidth != w )
|
|
{
|
|
d_data->thumbWidth = w;
|
|
layoutSlider();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief Set a scale draw
|
|
|
|
For changing the labels of the scales, it
|
|
is necessary to derive from QwtScaleDraw and
|
|
overload QwtScaleDraw::label().
|
|
|
|
\param scaleDraw ScaleDraw object, that has to be created with
|
|
new and will be deleted in ~QwtSlider or the next
|
|
call of setScaleDraw().
|
|
*/
|
|
void QwtSlider::setScaleDraw(QwtScaleDraw *scaleDraw)
|
|
{
|
|
const QwtScaleDraw *previousScaleDraw = this->scaleDraw();
|
|
if ( scaleDraw == NULL || scaleDraw == previousScaleDraw )
|
|
return;
|
|
|
|
if ( previousScaleDraw )
|
|
scaleDraw->setAlignment(previousScaleDraw->alignment());
|
|
|
|
setAbstractScaleDraw(scaleDraw);
|
|
layoutSlider();
|
|
}
|
|
|
|
/*!
|
|
\return the scale draw of the slider
|
|
\sa setScaleDraw()
|
|
*/
|
|
const QwtScaleDraw *QwtSlider::scaleDraw() const
|
|
{
|
|
return (QwtScaleDraw *)abstractScaleDraw();
|
|
}
|
|
|
|
/*!
|
|
\return the scale draw of the slider
|
|
\sa setScaleDraw()
|
|
*/
|
|
QwtScaleDraw *QwtSlider::scaleDraw()
|
|
{
|
|
return (QwtScaleDraw *)abstractScaleDraw();
|
|
}
|
|
|
|
//! Notify changed scale
|
|
void QwtSlider::scaleChange()
|
|
{
|
|
layoutSlider();
|
|
}
|
|
|
|
|
|
//! Notify change in font
|
|
void QwtSlider::fontChange(const QFont &f)
|
|
{
|
|
QwtAbstractSlider::fontChange( f );
|
|
layoutSlider();
|
|
}
|
|
|
|
/*!
|
|
Draw the slider into the specified rectangle.
|
|
|
|
\param painter Painter
|
|
\param r Rectangle
|
|
*/
|
|
void QwtSlider::drawSlider(QPainter *painter, const QRect &r)
|
|
{
|
|
QRect cr(r);
|
|
|
|
if (d_data->bgStyle & BgTrough)
|
|
{
|
|
qDrawShadePanel(painter, r.x(), r.y(),
|
|
r.width(), r.height(),
|
|
#if QT_VERSION < 0x040000
|
|
colorGroup(),
|
|
#else
|
|
palette(),
|
|
#endif
|
|
true, d_data->borderWidth,0);
|
|
|
|
cr.setRect(r.x() + d_data->borderWidth,
|
|
r.y() + d_data->borderWidth,
|
|
r.width() - 2 * d_data->borderWidth,
|
|
r.height() - 2 * d_data->borderWidth);
|
|
|
|
painter->fillRect(cr.x(), cr.y(), cr.width(), cr.height(),
|
|
#if QT_VERSION < 0x040000
|
|
colorGroup().brush(QColorGroup::Mid)
|
|
#else
|
|
palette().brush(QPalette::Mid)
|
|
#endif
|
|
);
|
|
}
|
|
|
|
if ( d_data->bgStyle & BgSlot)
|
|
{
|
|
int ws = 4;
|
|
int ds = d_data->thumbLength / 2 - 4;
|
|
if ( ds < 1 )
|
|
ds = 1;
|
|
|
|
QRect rSlot;
|
|
if (orientation() == Qt::Horizontal)
|
|
{
|
|
if ( cr.height() & 1 )
|
|
ws++;
|
|
rSlot = QRect(cr.x() + ds,
|
|
cr.y() + (cr.height() - ws) / 2,
|
|
cr.width() - 2 * ds, ws);
|
|
}
|
|
else
|
|
{
|
|
if ( cr.width() & 1 )
|
|
ws++;
|
|
rSlot = QRect(cr.x() + (cr.width() - ws) / 2,
|
|
cr.y() + ds,
|
|
ws, cr.height() - 2 * ds);
|
|
}
|
|
painter->fillRect(rSlot.x(), rSlot.y(), rSlot.width(), rSlot.height(),
|
|
#if QT_VERSION < 0x040000
|
|
colorGroup().brush(QColorGroup::Dark)
|
|
#else
|
|
palette().brush(QPalette::Dark)
|
|
#endif
|
|
);
|
|
qDrawShadePanel(painter, rSlot.x(), rSlot.y(),
|
|
rSlot.width(), rSlot.height(),
|
|
#if QT_VERSION < 0x040000
|
|
colorGroup(),
|
|
#else
|
|
palette(),
|
|
#endif
|
|
true, 1 ,0);
|
|
|
|
}
|
|
|
|
if ( isValid() )
|
|
drawThumb(painter, cr, xyPosition(value()));
|
|
}
|
|
|
|
/*!
|
|
Draw the thumb at a position
|
|
|
|
\param painter Painter
|
|
\param sliderRect Bounding rectangle of the slider
|
|
\param pos Position of the slider thumb
|
|
*/
|
|
void QwtSlider::drawThumb(QPainter *painter, const QRect &sliderRect, int pos)
|
|
{
|
|
pos++; // shade line points one pixel below
|
|
if (orientation() == Qt::Horizontal)
|
|
{
|
|
qDrawShadePanel(painter, pos - d_data->thumbLength / 2,
|
|
sliderRect.y(), d_data->thumbLength, sliderRect.height(),
|
|
#if QT_VERSION < 0x040000
|
|
colorGroup(),
|
|
#else
|
|
palette(),
|
|
#endif
|
|
false, d_data->borderWidth,
|
|
#if QT_VERSION < 0x040000
|
|
&colorGroup().brush(QColorGroup::Button)
|
|
#else
|
|
&palette().brush(QPalette::Button)
|
|
#endif
|
|
);
|
|
|
|
qDrawShadeLine(painter, pos, sliderRect.y(),
|
|
pos, sliderRect.y() + sliderRect.height() - 2,
|
|
#if QT_VERSION < 0x040000
|
|
colorGroup(),
|
|
#else
|
|
palette(),
|
|
#endif
|
|
true, 1);
|
|
}
|
|
else // Vertical
|
|
{
|
|
qDrawShadePanel(painter, sliderRect.x(), pos - d_data->thumbLength / 2,
|
|
sliderRect.width(), d_data->thumbLength,
|
|
#if QT_VERSION < 0x040000
|
|
colorGroup(),
|
|
#else
|
|
palette(),
|
|
#endif
|
|
false, d_data->borderWidth,
|
|
#if QT_VERSION < 0x040000
|
|
&colorGroup().brush(QColorGroup::Button)
|
|
#else
|
|
&palette().brush(QPalette::Button)
|
|
#endif
|
|
);
|
|
|
|
qDrawShadeLine(painter, sliderRect.x(), pos,
|
|
sliderRect.x() + sliderRect.width() - 2, pos,
|
|
#if QT_VERSION < 0x040000
|
|
colorGroup(),
|
|
#else
|
|
palette(),
|
|
#endif
|
|
true, 1);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Find the x/y position for a given value v
|
|
\param value Value
|
|
*/
|
|
int QwtSlider::xyPosition(double value) const
|
|
{
|
|
return d_data->map.transform(value);
|
|
}
|
|
|
|
/*!
|
|
Determine the value corresponding to a specified mouse location.
|
|
\param pos Mouse position
|
|
*/
|
|
double QwtSlider::getValue(const QPoint &pos)
|
|
{
|
|
return d_data->map.invTransform(
|
|
orientation() == Qt::Horizontal ? pos.x() : pos.y());
|
|
}
|
|
|
|
/*!
|
|
\brief Determine scrolling mode and direction
|
|
\param p point
|
|
\param scrollMode Scrolling mode
|
|
\param direction Direction
|
|
*/
|
|
void QwtSlider::getScrollMode(const QPoint &p,
|
|
int &scrollMode, int &direction )
|
|
{
|
|
if (!d_data->sliderRect.contains(p))
|
|
{
|
|
scrollMode = ScrNone;
|
|
direction = 0;
|
|
return;
|
|
}
|
|
|
|
const int pos = ( orientation() == Qt::Horizontal ) ? p.x() : p.y();
|
|
const int markerPos = xyPosition(value());
|
|
|
|
if ((pos > markerPos - d_data->thumbLength / 2)
|
|
&& (pos < markerPos + d_data->thumbLength / 2))
|
|
{
|
|
scrollMode = ScrMouse;
|
|
direction = 0;
|
|
return;
|
|
}
|
|
|
|
scrollMode = ScrPage;
|
|
direction = (pos > markerPos) ? 1 : -1;
|
|
|
|
if ( scaleDraw()->map().p1() > scaleDraw()->map().p2() )
|
|
direction = -direction;
|
|
}
|
|
|
|
/*!
|
|
Qt paint event
|
|
\param event Paint event
|
|
*/
|
|
void QwtSlider::paintEvent(QPaintEvent *event)
|
|
{
|
|
const QRect &ur = event->rect();
|
|
if ( ur.isValid() )
|
|
{
|
|
#if QT_VERSION < 0x040000
|
|
QwtPaintBuffer paintBuffer(this, ur);
|
|
draw(paintBuffer.painter(), ur);
|
|
#else
|
|
QPainter painter(this);
|
|
draw(&painter, ur);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//! Draw the QwtSlider
|
|
void QwtSlider::draw(QPainter *painter, const QRect&)
|
|
{
|
|
if (d_data->scalePos != NoScale)
|
|
{
|
|
#if QT_VERSION < 0x040000
|
|
scaleDraw()->draw(painter, colorGroup());
|
|
#else
|
|
scaleDraw()->draw(painter, palette());
|
|
#endif
|
|
}
|
|
|
|
drawSlider(painter, d_data->sliderRect);
|
|
|
|
if ( hasFocus() )
|
|
QwtPainter::drawFocusRect(painter, this, d_data->sliderRect);
|
|
}
|
|
|
|
//! Qt resize event
|
|
void QwtSlider::resizeEvent(QResizeEvent *)
|
|
{
|
|
layoutSlider( false );
|
|
}
|
|
|
|
/*!
|
|
Recalculate the slider's geometry and layout based on
|
|
the current rect and fonts.
|
|
\param update_geometry notify the layout system and call update
|
|
to redraw the scale
|
|
*/
|
|
void QwtSlider::layoutSlider( bool update_geometry )
|
|
{
|
|
int sliderWidth = d_data->thumbWidth;
|
|
int sld1 = d_data->thumbLength / 2 - 1;
|
|
int sld2 = d_data->thumbLength / 2 + d_data->thumbLength % 2;
|
|
if ( d_data->bgStyle & BgTrough )
|
|
{
|
|
sliderWidth += 2 * d_data->borderWidth;
|
|
sld1 += d_data->borderWidth;
|
|
sld2 += d_data->borderWidth;
|
|
}
|
|
|
|
int scd = 0;
|
|
if ( d_data->scalePos != NoScale )
|
|
{
|
|
int d1, d2;
|
|
scaleDraw()->getBorderDistHint(font(), d1, d2);
|
|
scd = qwtMax(d1, d2);
|
|
}
|
|
|
|
int slo = scd - sld1;
|
|
if ( slo < 0 )
|
|
slo = 0;
|
|
|
|
int x, y, length;
|
|
|
|
const QRect r = rect();
|
|
if (orientation() == Qt::Horizontal)
|
|
{
|
|
switch (d_data->scalePos)
|
|
{
|
|
case TopScale:
|
|
{
|
|
d_data->sliderRect.setRect(
|
|
r.x() + d_data->xMargin + slo,
|
|
r.y() + r.height() -
|
|
d_data->yMargin - sliderWidth,
|
|
r.width() - 2 * d_data->xMargin - 2 * slo,
|
|
sliderWidth);
|
|
|
|
x = d_data->sliderRect.x() + sld1;
|
|
y = d_data->sliderRect.y() - d_data->scaleDist;
|
|
|
|
break;
|
|
}
|
|
|
|
case BottomScale:
|
|
{
|
|
d_data->sliderRect.setRect(
|
|
r.x() + d_data->xMargin + slo,
|
|
r.y() + d_data->yMargin,
|
|
r.width() - 2 * d_data->xMargin - 2 * slo,
|
|
sliderWidth);
|
|
|
|
x = d_data->sliderRect.x() + sld1;
|
|
y = d_data->sliderRect.y() + d_data->sliderRect.height()
|
|
+ d_data->scaleDist;
|
|
|
|
break;
|
|
}
|
|
|
|
case NoScale: // like Bottom, but no scale. See QwtSlider().
|
|
default: // inconsistent orientation and scale position
|
|
{
|
|
d_data->sliderRect.setRect(
|
|
r.x() + d_data->xMargin + slo,
|
|
r.y() + d_data->yMargin,
|
|
r.width() - 2 * d_data->xMargin - 2 * slo,
|
|
sliderWidth);
|
|
|
|
x = d_data->sliderRect.x() + sld1;
|
|
y = 0;
|
|
|
|
break;
|
|
}
|
|
}
|
|
length = d_data->sliderRect.width() - (sld1 + sld2);
|
|
}
|
|
else // if (orientation() == Qt::Vertical
|
|
{
|
|
switch (d_data->scalePos)
|
|
{
|
|
case RightScale:
|
|
d_data->sliderRect.setRect(
|
|
r.x() + d_data->xMargin,
|
|
r.y() + d_data->yMargin + slo,
|
|
sliderWidth,
|
|
r.height() - 2 * d_data->yMargin - 2 * slo);
|
|
|
|
x = d_data->sliderRect.x() + d_data->sliderRect.width()
|
|
+ d_data->scaleDist;
|
|
y = d_data->sliderRect.y() + sld1;
|
|
|
|
break;
|
|
|
|
case LeftScale:
|
|
d_data->sliderRect.setRect(
|
|
r.x() + r.width() - sliderWidth - d_data->xMargin,
|
|
r.y() + d_data->yMargin + slo,
|
|
sliderWidth,
|
|
r.height() - 2 * d_data->yMargin - 2 * slo);
|
|
|
|
x = d_data->sliderRect.x() - d_data->scaleDist;
|
|
y = d_data->sliderRect.y() + sld1;
|
|
|
|
break;
|
|
|
|
case NoScale: // like Left, but no scale. See QwtSlider().
|
|
default: // inconsistent orientation and scale position
|
|
d_data->sliderRect.setRect(
|
|
r.x() + r.width() - sliderWidth - d_data->xMargin,
|
|
r.y() + d_data->yMargin + slo,
|
|
sliderWidth,
|
|
r.height() - 2 * d_data->yMargin - 2 * slo);
|
|
|
|
x = 0;
|
|
y = d_data->sliderRect.y() + sld1;
|
|
|
|
break;
|
|
}
|
|
length = d_data->sliderRect.height() - (sld1 + sld2);
|
|
}
|
|
|
|
scaleDraw()->move(x, y);
|
|
scaleDraw()->setLength(length);
|
|
|
|
d_data->map.setPaintXInterval(scaleDraw()->map().p1(),
|
|
scaleDraw()->map().p2());
|
|
|
|
if ( update_geometry )
|
|
{
|
|
d_data->sizeHintCache = QSize(); // invalidate
|
|
updateGeometry();
|
|
update();
|
|
}
|
|
}
|
|
|
|
//! Notify change of value
|
|
void QwtSlider::valueChange()
|
|
{
|
|
QwtAbstractSlider::valueChange();
|
|
update();
|
|
}
|
|
|
|
|
|
//! Notify change of range
|
|
void QwtSlider::rangeChange()
|
|
{
|
|
d_data->map.setScaleInterval(minValue(), maxValue());
|
|
|
|
if (autoScale())
|
|
rescale(minValue(), maxValue());
|
|
|
|
QwtAbstractSlider::rangeChange();
|
|
layoutSlider();
|
|
}
|
|
|
|
/*!
|
|
\brief Set distances between the widget's border and internals.
|
|
\param xMargin Horizontal margin
|
|
\param yMargin Vertical margin
|
|
*/
|
|
void QwtSlider::setMargins(int xMargin, int yMargin)
|
|
{
|
|
if ( xMargin < 0 )
|
|
xMargin = 0;
|
|
if ( yMargin < 0 )
|
|
yMargin = 0;
|
|
|
|
if ( xMargin != d_data->xMargin || yMargin != d_data->yMargin )
|
|
{
|
|
d_data->xMargin = xMargin;
|
|
d_data->yMargin = yMargin;
|
|
layoutSlider();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Set the background style.
|
|
*/
|
|
void QwtSlider::setBgStyle(BGSTYLE st)
|
|
{
|
|
d_data->bgStyle = st;
|
|
layoutSlider();
|
|
}
|
|
|
|
/*!
|
|
\return the background style.
|
|
*/
|
|
QwtSlider::BGSTYLE QwtSlider::bgStyle() const
|
|
{
|
|
return d_data->bgStyle;
|
|
}
|
|
|
|
/*!
|
|
\return the thumb length.
|
|
*/
|
|
int QwtSlider::thumbLength() const
|
|
{
|
|
return d_data->thumbLength;
|
|
}
|
|
|
|
/*!
|
|
\return the thumb width.
|
|
*/
|
|
int QwtSlider::thumbWidth() const
|
|
{
|
|
return d_data->thumbWidth;
|
|
}
|
|
|
|
/*!
|
|
\return the border width.
|
|
*/
|
|
int QwtSlider::borderWidth() const
|
|
{
|
|
return d_data->borderWidth;
|
|
}
|
|
|
|
/*!
|
|
\return QwtSlider::minimumSizeHint()
|
|
*/
|
|
QSize QwtSlider::sizeHint() const
|
|
{
|
|
return minimumSizeHint();
|
|
}
|
|
|
|
/*!
|
|
\brief Return a minimum size hint
|
|
\warning The return value of QwtSlider::minimumSizeHint() depends on
|
|
the font and the scale.
|
|
*/
|
|
QSize QwtSlider::minimumSizeHint() const
|
|
{
|
|
if (!d_data->sizeHintCache.isEmpty())
|
|
return d_data->sizeHintCache;
|
|
|
|
int sliderWidth = d_data->thumbWidth;
|
|
if (d_data->bgStyle & BgTrough)
|
|
sliderWidth += 2 * d_data->borderWidth;
|
|
|
|
int w = 0, h = 0;
|
|
if (d_data->scalePos != NoScale)
|
|
{
|
|
int d1, d2;
|
|
scaleDraw()->getBorderDistHint(font(), d1, d2);
|
|
int msMbd = qwtMax(d1, d2);
|
|
|
|
int mbd = d_data->thumbLength / 2;
|
|
if (d_data->bgStyle & BgTrough)
|
|
mbd += d_data->borderWidth;
|
|
|
|
if ( mbd < msMbd )
|
|
mbd = msMbd;
|
|
|
|
const int sdExtent = scaleDraw()->extent( QPen(), font() );
|
|
const int sdLength = scaleDraw()->minLength( QPen(), font() );
|
|
|
|
h = sliderWidth + sdExtent + d_data->scaleDist;
|
|
w = sdLength - 2 * msMbd + 2 * mbd;
|
|
}
|
|
else // no scale
|
|
{
|
|
w = 200;
|
|
h = sliderWidth;
|
|
}
|
|
|
|
if ( orientation() == Qt::Vertical )
|
|
qSwap(w, h);
|
|
|
|
w += 2 * d_data->xMargin;
|
|
h += 2 * d_data->yMargin;
|
|
|
|
d_data->sizeHintCache = QSize(w, h);
|
|
return d_data->sizeHintCache;
|
|
}
|