Try to make the slider more accurate when moodbar is activated.

Previously, the slide wasn't displayed at the exact position where the user clicked, and the moodbar's width was equal to the slider's width, while it should have been as long as long the groove.
This commit is contained in:
Arnaud Bienner 2014-04-23 00:03:30 +02:00
parent 2e61ef9b17
commit 3f79fa5c65
2 changed files with 45 additions and 15 deletions

View File

@ -204,7 +204,7 @@ void MoodbarProxyStyle::Render(ComplexControl control,
if (fade_target_.isNull()) {
if (state_ == FadingToOn) {
EnsureMoodbarRendered();
EnsureMoodbarRendered(option);
}
fade_target_ = moodbar_pixmap_;
QPainter p(&fade_target_);
@ -225,14 +225,14 @@ void MoodbarProxyStyle::Render(ComplexControl control,
break;
case MoodbarOn:
EnsureMoodbarRendered();
EnsureMoodbarRendered(option);
painter->drawPixmap(option->rect, moodbar_pixmap_);
DrawArrow(option, painter);
break;
}
}
void MoodbarProxyStyle::EnsureMoodbarRendered() {
void MoodbarProxyStyle::EnsureMoodbarRendered(const QStyleOptionSlider* opt) {
if (moodbar_colors_dirty_) {
moodbar_colors_ =
MoodbarRenderer::Colors(data_, moodbar_style_, slider_->palette());
@ -242,11 +242,19 @@ void MoodbarProxyStyle::EnsureMoodbarRendered() {
if (moodbar_pixmap_dirty_) {
moodbar_pixmap_ =
MoodbarPixmap(moodbar_colors_, slider_->size(), slider_->palette());
MoodbarPixmap(moodbar_colors_, slider_->size(), slider_->palette(), opt);
moodbar_pixmap_dirty_ = false;
}
}
int MoodbarProxyStyle::GetExtraSpace(const QStyleOptionComplex* opt) const
{
int space_available =
slider_->style()->pixelMetric(QStyle::PM_SliderSpaceAvailable, opt, slider_);
int w = slider_->width();
return w - space_available;
}
QRect MoodbarProxyStyle::subControlRect(ComplexControl cc,
const QStyleOptionComplex* opt,
SubControl sc,
@ -263,17 +271,23 @@ QRect MoodbarProxyStyle::subControlRect(ComplexControl cc,
case MoodbarOn:
case FadingToOn:
switch (sc) {
case SC_SliderGroove:
return opt->rect.adjusted(kMarginSize, kMarginSize, -kMarginSize,
case SC_SliderGroove: {
int margin_leftright = GetExtraSpace(opt) / 2;
return opt->rect.adjusted(margin_leftright, kMarginSize, -margin_leftright,
-kMarginSize);
}
case SC_SliderHandle: {
const QStyleOptionSlider* slider_opt =
qstyleoption_cast<const QStyleOptionSlider*>(opt);
const int x = (slider_opt->sliderValue - slider_opt->minimum) *
(opt->rect.width() - kArrowWidth) /
int space_available =
slider_->style()->pixelMetric(QStyle::PM_SliderSpaceAvailable, opt, slider_);
int w = slider_->width();
int margin = (w - space_available) / 2;
int x = (slider_opt->sliderValue - slider_opt->minimum) *
(space_available - kArrowWidth) /
(slider_opt->maximum - slider_opt->minimum);
x += margin;
return QRect(QPoint(opt->rect.left() + x, opt->rect.top()),
QSize(kArrowWidth, kArrowHeight));
@ -310,10 +324,16 @@ void MoodbarProxyStyle::DrawArrow(const QStyleOptionSlider* option,
QPixmap MoodbarProxyStyle::MoodbarPixmap(const ColorVector& colors,
const QSize& size,
const QPalette& palette) {
QRect rect(QPoint(0, 0), size);
const QPalette& palette,
const QStyleOptionSlider* opt) {
int margin_leftright = GetExtraSpace(opt);
const QRect rect(QPoint(0, 0), size);
QRect border_rect(rect);
border_rect.adjust(kMarginSize, kMarginSize, -kMarginSize, -kMarginSize);
// I would expect we need to adjust by margin_lr/2, so the extra space is
// distributed on both side, but if we do so, the margin is too small, and I'm
// not sure why...
border_rect.adjust(margin_leftright, kMarginSize, -margin_leftright, -kMarginSize);
QRect inner_rect(border_rect);
inner_rect.adjust(kBorderSize, kBorderSize, -kBorderSize, -kBorderSize);
@ -332,7 +352,13 @@ QPixmap MoodbarProxyStyle::MoodbarPixmap(const ColorVector& colors,
// Draw the outer bit
p.setPen(QPen(palette.brush(QPalette::Active, QPalette::Background),
kMarginSize, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
// First: a rectangle around the slier
p.drawRect(rect.adjusted(1, 1, -2, -2));
// Then, thicker border on left and right, because of the margins.
p.setPen(QPen(palette.brush(QPalette::Active, QPalette::Background),
margin_leftright*2-kBorderSize, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
p.drawLine(rect.topLeft(), rect.bottomLeft());
p.drawLine(rect.topRight(), rect.bottomRight());
p.end();

View File

@ -66,12 +66,12 @@ class MoodbarProxyStyle : public QProxyStyle {
void Render(ComplexControl control, const QStyleOptionSlider* option,
QPainter* painter, const QWidget* widget);
void EnsureMoodbarRendered();
void EnsureMoodbarRendered(const QStyleOptionSlider* opt);
void DrawArrow(const QStyleOptionSlider* option, QPainter* painter) const;
void ShowContextMenu(const QPoint& pos);
static QPixmap MoodbarPixmap(const ColorVector& colors, const QSize& size,
const QPalette& palette);
QPixmap MoodbarPixmap(const ColorVector& colors, const QSize& size,
const QPalette& palette, const QStyleOptionSlider* opt);
private slots:
void ReloadSettings();
@ -79,6 +79,10 @@ class MoodbarProxyStyle : public QProxyStyle {
void ChangeStyle(QAction* action);
private:
// The slider "groove" is smaller than the actual slider: this convenient
// function returns the difference between groove width and slider width.
int GetExtraSpace(const QStyleOptionComplex* opt) const;
Application* app_;
QSlider* slider_;