QStyleOptionProgressBar KisAbstractSliderSpinBox::progressBarOptions() const { const Q_D(KisAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); //Create opts for drawing the progress portion QStyleOptionProgressBar progressOpts; progressOpts.initFrom(this); progressOpts.maximum = d->maximum; progressOpts.minimum = d->minimum; qreal minDbl = d->minimum; qreal dValues = (d->maximum - minDbl); progressOpts.progress = dValues * pow((d->value - minDbl) / dValues, 1 / d->exponentRatio) + minDbl; progressOpts.text = valueString() + d->suffix; progressOpts.textAlignment = Qt::AlignCenter; progressOpts.textVisible = !(d->edit->isVisible()); //Change opts rect to be only the ComboBox's text area progressOpts.rect = progressRect(spinOpts); return progressOpts; }
void DAbstractSliderSpinBox::mouseReleaseEvent(QMouseEvent* e) { Q_D(DAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); d->isDragging = false; // Step up/down for buttons // Emulating mouse grab too if (upButtonRect(spinOpts).contains(e->pos()) && d->upButtonDown) { setInternalValue(d->value + d->singleStep); } else if (downButtonRect(spinOpts).contains(e->pos()) && d->downButtonDown) { setInternalValue(d->value - d->singleStep); } else if (progressRect(spinOpts).contains(e->pos()) && !(d->edit->isVisible()) && !(d->upButtonDown || d->downButtonDown)) { // Snap to percentage for progress area setInternalValue(valueForX(e->pos().x(),e->modifiers())); } else { // Confirm the last known value, since we might be ignoring move events setInternalValue(d->value); } d->upButtonDown = false; d->downButtonDown = false; update(); }
QSize KisAbstractSliderSpinBox::sizeHint() const { const Q_D(KisAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); QFontMetrics fm(font()); //We need at least 50 pixels or things start to look bad int w = qMax(fm.width(QString::number(d->maximum)), 50); QSize hint(w, d->edit->sizeHint().height() + 3); //Getting the size of the buttons is a pain as the calcs require a rect //that is "big enough". We run the calc twice to get the "smallest" buttons //This code was inspired by QAbstractSpinBox QSize extra(35, 6); spinOpts.rect.setSize(hint + extra); extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &spinOpts, QStyle::SC_SpinBoxEditField, this).size(); spinOpts.rect.setSize(hint + extra); extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &spinOpts, QStyle::SC_SpinBoxEditField, this).size(); hint += extra; spinOpts.rect = rect(); return style()->sizeFromContents(QStyle::CT_SpinBox, &spinOpts, hint, 0) .expandedTo(QApplication::globalStrut()); }
void DAbstractSliderSpinBox::mousePressEvent(QMouseEvent* e) { Q_D(DAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); // Depress buttons or highlight slider // Also used to emulate mouse grab... if (e->buttons() & Qt::LeftButton) { if (upButtonRect(spinOpts).contains(e->pos())) { d->upButtonDown = true; } else if (downButtonRect(spinOpts).contains(e->pos())) { d->downButtonDown = true; } } else if (e->buttons() & Qt::RightButton) { showEdit(); } update(); }
void DAbstractSliderSpinBox::paintBreeze(QPainter& painter) { Q_D(DAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); QStyleOptionProgressBar progressOpts = progressBarOptions(); QString valueText = progressOpts.text; progressOpts.text = QLatin1String(""); progressOpts.rect.adjust(0, 1, 0, -1); style()->drawComplexControl(QStyle::CC_SpinBox, &spinOpts, &painter, this); style()->drawControl(QStyle::CE_ProgressBarGroove, &progressOpts, &painter, this); painter.save(); QRect leftRect; int progressIndicatorPos = (progressOpts.progress - double(progressOpts.minimum)) / qMax(double(1.0), double(progressOpts.maximum) - progressOpts.minimum) * progressOpts.rect.width(); if (progressIndicatorPos >= 0 && progressIndicatorPos <= progressOpts.rect.width()) { leftRect = QRect(progressOpts.rect.left(), progressOpts.rect.top(), progressIndicatorPos, progressOpts.rect.height()); } else if (progressIndicatorPos > progressOpts.rect.width()) { painter.setPen(palette().highlightedText().color()); } else { painter.setPen(palette().buttonText().color()); } QRegion rightRect = progressOpts.rect; rightRect = rightRect.subtracted(leftRect); painter.setClipRegion(rightRect); QTextOption textOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter); textOption.setWrapMode(QTextOption::NoWrap); if (!(d->edit && d->edit->isVisible())) { painter.drawText(progressOpts.rect, valueText, textOption); } if (!leftRect.isNull()) { painter.setPen(palette().highlightedText().color()); painter.setClipRect(leftRect); style()->drawControl(QStyle::CE_ProgressBarContents, &progressOpts, &painter, this); if (!(d->edit && d->edit->isVisible())) { painter.drawText(progressOpts.rect, valueText, textOption); } } painter.restore(); }
int DAbstractSliderSpinBox::valueForX(int x, Qt::KeyboardModifiers modifiers) const { const Q_D(DAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); QRect correctedProgRect; if (d->style == DAbstractSliderSpinBoxPrivate::STYLE_FUSION) { correctedProgRect = progressRect(spinOpts).adjusted(2, 0, -2, 0); } else if (d->style == DAbstractSliderSpinBoxPrivate::STYLE_BREEZE) { correctedProgRect = progressRect(spinOpts); } else { // Adjust for magic number in style code (margins) correctedProgRect = progressRect(spinOpts).adjusted(2, 2, -2, -2); } // Compute the distance of the progress bar, in pixel double leftDbl = correctedProgRect.left(); double xDbl = x - leftDbl; // Compute the ration of the progress bar used, linearly (ignoring the exponent) double rightDbl = correctedProgRect.right(); double minDbl = d->minimum; double maxDbl = d->maximum; double dValues = (maxDbl - minDbl); double percent = (xDbl / (rightDbl - leftDbl)); // If SHIFT is pressed, movement should be slowed. if (modifiers & Qt::ShiftModifier) { percent = d->shiftPercent + (percent - d->shiftPercent) * d->slowFactor; } // Final value double realvalue = ((dValues * pow(percent, d->exponentRatio)) + minDbl); // If key CTRL is pressed, round to the closest step. if (modifiers & Qt::ControlModifier) { double fstep = d->fastSliderStep; if (modifiers & Qt::ShiftModifier) { fstep *= d->slowFactor; } realvalue = floor((realvalue+fstep / 2) / fstep) * fstep; } return int(realvalue); }
void KisAbstractSliderSpinBox::showEdit() { Q_D(KisAbstractSliderSpinBox); if (d->edit->isVisible()) return; d->edit->setGeometry(progressRect(spinBoxOptions())); d->edit->setText(valueString()); d->edit->selectAll(); d->edit->show(); d->edit->setFocus(Qt::OtherFocusReason); update(); }
void KisAbstractSliderSpinBox::mouseMoveEvent(QMouseEvent* e) { Q_D(KisAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); //Respect emulated mouse grab. if (e->buttons() & Qt::LeftButton && !(d->downButtonDown || d->upButtonDown)) { setInternalValue(valueForX(e->pos().x())); update(); } }
QSize DAbstractSliderSpinBox::sizeHint() const { const Q_D(DAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); QFont ft(font()); if (d->style == DAbstractSliderSpinBoxPrivate::STYLE_NOQUIRK) { // Some styles use bold font in progressbars // unfortunately there is no reliable way to check for that ft.setBold(true); } QFontMetrics fm(ft); QSize hint(fm.boundingRect(d->prefix + QString::number(d->maximum) + d->suffix).size()); hint += QSize(0, 2); switch (d->style) { case DAbstractSliderSpinBoxPrivate::STYLE_FUSION: hint += QSize(8, 8); break; case DAbstractSliderSpinBoxPrivate::STYLE_PLASTIQUE: hint += QSize(8, 0); break; case DAbstractSliderSpinBoxPrivate::STYLE_BREEZE: hint += QSize(2, 0); break; case DAbstractSliderSpinBoxPrivate::STYLE_NOQUIRK: // almost all "modern" styles have a margin around controls hint += QSize(6, 6); break; default: break; } // Getting the size of the buttons is a pain as the calcs require a rect // that is "big enough". We run the calc twice to get the "smallest" buttons // This code was inspired by QAbstractSpinBox QSize extra(1000, 0); spinOpts.rect.setSize(hint + extra); extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &spinOpts, QStyle::SC_SpinBoxEditField, this).size(); spinOpts.rect.setSize(hint + extra); extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &spinOpts, QStyle::SC_SpinBoxEditField, this).size(); hint += extra; spinOpts.rect.setSize(hint); return style()->sizeFromContents(QStyle::CT_SpinBox, &spinOpts, hint) .expandedTo(QApplication::globalStrut()); }
void DAbstractSliderSpinBox::showEdit() { Q_D(DAbstractSliderSpinBox); if (d->edit->isVisible()) return; if (d->style == DAbstractSliderSpinBoxPrivate::STYLE_PLASTIQUE) { d->edit->setGeometry(progressRect(spinBoxOptions()).adjusted(0, 0, -2, 0)); } else { d->edit->setGeometry(progressRect(spinBoxOptions())); } d->edit->setText(valueString()); d->edit->selectAll(); d->edit->show(); d->edit->setFocus(Qt::OtherFocusReason); update(); }
int KisAbstractSliderSpinBox::valueForX(int x) const { const Q_D(KisAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); //Adjust for magic number in style code (margins) QRect correctedProgRect = progressRect(spinOpts).adjusted(2, 2, -2, -2); qreal leftDbl = correctedProgRect.left(); qreal xDbl = x - leftDbl; qreal rightDbl = correctedProgRect.right(); qreal minDbl = d->minimum; qreal maxDbl = d->maximum; qreal dValues = (maxDbl - minDbl); qreal percent = (xDbl / (rightDbl - leftDbl)); return ((dValues * pow(percent, d->exponentRatio)) + minDbl); }
double SliderDoubleSpinBoxPrivate::valueForX(int x) const { QStyleOptionSpinBox spinOpts = spinBoxOptions(); // adjust for border used in the QStyles (FIXME: probably not exact) QRect correctedProgRect = progressRect(spinOpts).adjusted(2, 2, -2, -2); const double left = correctedProgRect.left(); const double right = correctedProgRect.right(); const double val = qMax(0.0 , x - left); const double range = q->maximum() - q->minimum(); double percent = val / (right - left); if (q->layoutDirection() == Qt::RightToLeft) { percent = 1 - percent; } return q->minimum() + percent * (range); }
void KisAbstractSliderSpinBox::mouseReleaseEvent(QMouseEvent* e) { Q_D(KisAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); //Step up/down for buttons //Emualting mouse grab too if (upButtonRect(spinOpts).contains(e->pos()) && d->upButtonDown) { setInternalValue(d->value + d->singleStep); } else if (downButtonRect(spinOpts).contains(e->pos()) && d->downButtonDown) { setInternalValue(d->value - d->singleStep); } else if (progressRect(spinOpts).contains(e->pos()) && !(d->edit->isVisible()) && !(d->upButtonDown || d->downButtonDown)) { //Snap to percentage for progress area setInternalValue(valueForX(e->pos().x())); } d->upButtonDown = false; d->downButtonDown = false; update(); }
void KisAbstractSliderSpinBox::paintEvent(QPaintEvent* e) { Q_D(KisAbstractSliderSpinBox); Q_UNUSED(e) QPainter painter(this); //Create options to draw spin box parts QStyleOptionSpinBox spinOpts = spinBoxOptions(); //Draw "SpinBox".Clip off the area of the lineEdit to avoid double //borders being drawn painter.save(); painter.setClipping(true); QRect eraseRect(QPoint(rect().x(), rect().y()), QPoint(progressRect(spinOpts).right(), rect().bottom())); painter.setClipRegion(QRegion(rect()).subtracted(eraseRect)); style()->drawComplexControl(QStyle::CC_SpinBox, &spinOpts, &painter, d->dummySpinBox); painter.setClipping(false); painter.restore(); //Create options to draw progress bar parts QStyleOptionProgressBar progressOpts = progressBarOptions(); //Draw "ProgressBar" in SpinBox style()->drawControl(QStyle::CE_ProgressBar, &progressOpts, &painter, 0); //Draw focus if necessary if (hasFocus() && d->edit->hasFocus()) { QStyleOptionFocusRect focusOpts; focusOpts.initFrom(this); focusOpts.rect = progressOpts.rect; focusOpts.backgroundColor = palette().color(QPalette::Window); style()->drawPrimitive(QStyle::PE_FrameFocusRect, &focusOpts, &painter, this); } }
QStyleOptionProgressBarV2 SliderDoubleSpinBoxPrivate::progressBarOptions() const { QStyleOptionSpinBox spinOpts = spinBoxOptions(); // scale up to model requrested precision with int const double factor = std::pow(10.0, q->decimals()); //Create opts for drawing the progress portion QStyleOptionProgressBarV2 progressOpts; progressOpts.initFrom(q); progressOpts.maximum = q->maximum() * factor; progressOpts.minimum = q->minimum() * factor; progressOpts.progress = q->value() * factor; progressOpts.text = QString::number(q->value(), 'f', q->decimals()) + q->suffix(); progressOpts.textAlignment = Qt::AlignCenter; progressOpts.textVisible = ! q->lineEdit()->isVisible(); //Change opts rect to be only the ComboBox's text area progressOpts.rect = progressRect(spinOpts); return progressOpts; }
void DAbstractSliderSpinBox::paintPlastique(QPainter& painter) { Q_D(DAbstractSliderSpinBox); QStyleOptionSpinBox spinOpts = spinBoxOptions(); QStyleOptionProgressBar progressOpts = progressBarOptions(); style()->drawComplexControl(QStyle::CC_SpinBox, &spinOpts, &painter, d->dummySpinBox); painter.save(); QRect rect = progressOpts.rect.adjusted(2, 0, -2, 0); QRect leftRect; int progressIndicatorPos = (progressOpts.progress - double(progressOpts.minimum)) / qMax(double(1.0), double(progressOpts.maximum) - progressOpts.minimum) * rect.width(); if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width()) { leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height()); } else if (progressIndicatorPos > rect.width()) { painter.setPen(palette().highlightedText().color()); } else { painter.setPen(palette().buttonText().color()); } QRegion rightRect = rect; rightRect = rightRect.subtracted(leftRect); QTextOption textOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter); textOption.setWrapMode(QTextOption::NoWrap); if (!(d->edit && d->edit->isVisible())) { painter.setClipRegion(rightRect); painter.setClipping(true); painter.drawText(rect.adjusted(-2, 0, 2, 0), progressOpts.text, textOption); painter.setClipping(false); } if (!leftRect.isNull()) { painter.setPen(palette().highlight().color()); painter.setBrush(palette().highlight()); painter.drawRect(leftRect.adjusted(0, 0, 0, -1)); if (!(d->edit && d->edit->isVisible())) { painter.setPen(palette().highlightedText().color()); painter.setClipRect(leftRect.adjusted(0, 0, 1, 0)); painter.setClipping(true); painter.drawText(rect.adjusted(-2, 0, 2, 0), progressOpts.text, textOption); painter.setClipping(false); } } painter.restore(); }