diff --git a/qtest.pro b/qtest.pro index 97274fa..63ef85f 100644 --- a/qtest.pro +++ b/qtest.pro @@ -11,7 +11,7 @@ DESTPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\back\reimpl" VPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\back\reimpl" "$$PWD\src\cont" SOURCES += qtestmain.cpp qtclasses.cpp backlasses.cpp backsessionclasses.cpp contclasses.cpp contsessionclasses.cpp -HEADERS += qtclasses.h backlasses.h backsessionclasses.h contclasses.h contsessionclasses.h global.h debug.h backfuncs.h ipolicyconfig.h msinclude.h qtvisuals.h +HEADERS += qtclasses.h backlasses.h backsessionclasses.h contclasses.h contsessionclasses.h global.h debug.h backfuncs.h ipolicyconfig.h msinclude.h RESOURCES = assets.qrc RC_ICONS += assets/logo.ico diff --git a/src/qt/qtclasses.cpp b/src/qt/qtclasses.cpp index 2174d7d..6e90375 100644 --- a/src/qt/qtclasses.cpp +++ b/src/qt/qtclasses.cpp @@ -34,6 +34,7 @@ bool MeterSlider::event(QEvent* ev) { void MeterSlider::paintEvent(QPaintEvent *event) { QStyleOptionSlider sliderComplex = QStyleOptionSlider(); sliderComplex.initFrom(this); + /* * sliderComplex.initFrom(this); * sliderComplex.subControls = QStyle::SC_None; @@ -64,36 +65,46 @@ void MeterSlider::paintEvent(QPaintEvent *event) { * //sliderComplex.subControls = QStyle::SC_SliderGroove; * if (this->tickPosition() != NoTicks) sliderComplex.subControls |= QStyle::SC_SliderTickmarks; * QStylePainter p(this); - * p.drawComplexControl(QStyle::CC_Slider, sliderComplex); */ + //p.drawComplexControl(QStyle::CC_Slider, sliderComplex); + - /* - * QStyleOptionSlider sliderComplex2 = QStyleOptionSlider(); - * sliderComplex2.initFrom(this); - * sliderComplex2.orientation = this->orientation(); - * sliderComplex2.maximum = this->maximum(); - * sliderComplex2.minimum = this->minimum(); - * sliderComplex2.tickPosition = (QSlider::TickPosition)this->tickPosition(); - * sliderComplex2.tickInterval = this->tickInterval(); - * sliderComplex2.upsideDown = (this->orientation() == Qt::Horizontal) ? - * (this->invertedAppearance() != (sliderComplex2.direction == Qt::RightToLeft)) - * : (!this->invertedAppearance()); - * sliderComplex2.subControls = QStyle::SC_SliderHandle; - * sliderComplex2.direction = Qt::LeftToRight; // we use the upsideDown option instead - * sliderComplex2.sliderPosition = this->sliderPosition(); - * sliderComplex2.sliderValue = this->value(); - * sliderComplex2.singleStep = this->singleStep(); - * sliderComplex2.pageStep = this->pageStep(); - * if (this->orientation() == Qt::Horizontal) - * sliderComplex2.state |= QStyle::State_Horizontal; - * - * if (this->isSliderDown()) { - * sliderComplex2.activeSubControls = QStyle::SC_SliderHandle; - * sliderComplex2.state |= QStyle::State_Sunken; - * } else { - * sliderComplex2.activeSubControls = QStyle::SC_SliderHandle; - * } - */ + + QStyleOptionSlider sliderComplex2 = QStyleOptionSlider(); + sliderComplex2.initFrom(this); + sliderComplex2.orientation = this->orientation(); + sliderComplex2.maximum = this->maximum(); + sliderComplex2.minimum = this->minimum(); + sliderComplex2.tickPosition = (QSlider::TickPosition)this->tickPosition(); + sliderComplex2.tickInterval = this->tickInterval(); + sliderComplex2.upsideDown = (this->orientation() == Qt::Horizontal) ? + (this->invertedAppearance() != (sliderComplex2.direction == Qt::RightToLeft)) + : (!this->invertedAppearance()); + sliderComplex2.subControls = QStyle::SC_SliderHandle; + sliderComplex2.direction = Qt::LeftToRight; // we use the upsideDown option instead + sliderComplex2.sliderPosition = this->sliderPosition(); + sliderComplex2.sliderValue = this->value(); + sliderComplex2.singleStep = this->singleStep(); + sliderComplex2.pageStep = this->pageStep(); + if (this->orientation() == Qt::Horizontal) + sliderComplex2.state |= QStyle::State_Horizontal; + + if (this->isSliderDown()) { + sliderComplex2.activeSubControls = QStyle::SC_SliderHandle; + sliderComplex2.state |= QStyle::State_Sunken; + } else { + sliderComplex2.activeSubControls = QStyle::SC_SliderHandle; + } + + sliderComplex2.subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle; + if ((QSlider::TickPosition)this->tickPosition() != NoTicks) + sliderComplex2.subControls |= QStyle::SC_SliderTickmarks; + + QPainter painter(this); + QStyle* stle = QApplication::style(); + stle->drawComplexControl((QStyle::ComplexControl)CC_MeterSlider, &sliderComplex2, &painter, this); + + //Q_D(QSlider); /* @@ -108,39 +119,43 @@ void MeterSlider::paintEvent(QPaintEvent *event) { * //p.drawComplexControl(QStyle::CC_Slider, opt); */ //QSlider::paintEvent(event); - int left = 0, top = 0, right = 0, bottom = 0; - ((QWidget*)parent())->layout()->getContentsMargins(&left, &top, &right, &bottom); - QStyle *style = QApplication::style(); - //int lol = style->pixelMetric(QStyle::PM_SliderSpaceAvailable); - QPainter painter(this); - //painter.setPen(Qt::blue); - painter.setOpacity(1.0); - painter.setClipping(false); - painter.setCompositionMode(QPainter::CompositionMode::CompositionMode_Source); - float peakLength = (this->width() * (this->peakValue)); - double stepWidth = (double)this->width() * ((double)this->singleStep() / (this->maximum() - this->minimum())); - //Fusion seems to fuck around with bar's height and width - //const qreal dpr = painter->device()->devicePixelRatio(); - //QStyleOptionSlider sliderComplex = QStyleOptionSlider(); //slider.initFrom(this); - QRect sliderSize = style->subControlRect(QStyle::CC_Slider, (QStyleOptionComplex*)&sliderComplex, QStyle::SC_SliderHandle); - int handleCenterPos = QStyle::sliderPositionFromValue(this->minimum(), this->maximum(), this->value(), this->width()); - int unattenuatedPeakMeter = ((this->width() * this->peakValue) >= handleCenterPos - (sliderSize.width() / 2)) - ? this->width() - (sliderSize.width() / 2) - : this->width() * this->peakValue; - //QApplication::style()->subControlRect(QStyle::CC_Slider, (QStyleOptionComplex*)&slider, QStyle::SC_SliderHandle); - painter.fillRect(0, (this->height() / 2) - 3, this->width(), - 4, Qt::white); - painter.fillRect(0, (this->height() / 2) - 3, this->width() * this->peakValue, - 4, Qt::gray); - painter.fillRect(0, (this->height() / 2) - 3, (this->width() - ((this->maximum() - this->value()) * stepWidth)) * this->peakValue, - 4, Qt::green); - // - ((this->maximum() - this->value()) * stepWidth)) - //double ratio = ; - double handleShift = (double)((sliderSize.width() * ((double)(this->maximum() - this->value()) / 100))); - painter.fillRect((this->width() - ((this->maximum() - this->value()) * stepWidth)) - (sliderSize.width()) + handleShift, top / 2, sliderSize.width(), sliderSize.height() - bottom, Qt::magenta); - //sliderComplex.subControls = QStyle::SC_SliderHandle; - //p.drawComplexControl(QStyle::CC_Slider, sliderComplex); + //IL CODE WENO lbockomet + /* + * int left = 0, top = 0, right = 0, bottom = 0; + * ((QWidget*)parent())->layout()->getContentsMargins(&left, &top, &right, &bottom); + * + * QStyle *style = QApplication::style(); + * //int lol = style->pixelMetric(QStyle::PM_SliderSpaceAvailable); + * QPainter painter(this); + * //painter.setPen(Qt::blue); + * painter.setOpacity(1.0); + * painter.setClipping(false); + * painter.setCompositionMode(QPainter::CompositionMode::CompositionMode_Source); + * float peakLength = (this->width() * (this->peakValue)); + * double stepWidth = (double)this->width() * ((double)this->singleStep() / (this->maximum() - this->minimum())); + * //Fusion seems to fuck around with bar's height and width + * //const qreal dpr = painter->device()->devicePixelRatio(); + * //QStyleOptionSlider sliderComplex = QStyleOptionSlider(); //slider.initFrom(this); + * QRect sliderSize = style->subControlRect(QStyle::CC_Slider, (QStyleOptionComplex*)&sliderComplex, QStyle::SC_SliderHandle); + * int handleCenterPos = QStyle::sliderPositionFromValue(this->minimum(), this->maximum(), this->value(), this->width()); + * int unattenuatedPeakMeter = ((this->width() * this->peakValue) >= handleCenterPos - (sliderSize.width() / 2)) + * ? this->width() - (sliderSize.width() / 2) + * : this->width() * this->peakValue; + * //QApplication::style()->subControlRect(QStyle::CC_Slider, (QStyleOptionComplex*)&slider, QStyle::SC_SliderHandle); + * painter.fillRect(0, (this->height() / 2) - 3, this->width(), + * 4, Qt::white); + * painter.fillRect(0, (this->height() / 2) - 3, this->width() * this->peakValue, + * 4, Qt::gray); + * painter.fillRect(0, (this->height() / 2) - 3, (this->width() - ((this->maximum() - this->value()) * stepWidth)) * this->peakValue, + * 4, Qt::green); + * // - ((this->maximum() - this->value()) * stepWidth)) + * //double ratio = ; + * double handleShift = (double)((sliderSize.width() * ((double)(this->maximum() - this->value()) / 100))); + * painter.fillRect((this->width() - ((this->maximum() - this->value()) * stepWidth)) - (sliderSize.width()) + handleShift, top / 2, sliderSize.width(), sliderSize.height() - bottom, Qt::magenta); + * //sliderComplex.subControls = QStyle::SC_SliderHandle; + * //p.drawComplexControl(QStyle::CC_Slider, sliderComplex); + */ } void ExtendedCheckBox::customEvent(QEvent* ev) { @@ -317,8 +332,8 @@ SessionWidget::SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent) mainSlider->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); //mainSlider->setMinimumWidth(120 /*1/16 1080p*/); mainSlider->setFocusPolicy(Qt::StrongFocus); - mainSlider->setTickPosition(QSlider::TicksBothSides); - mainSlider->setTickInterval(5); + //mainSlider->setTickPosition(QSlider::TicksBothSides); + //mainSlider->setTickInterval(5); mainSlider->setSingleStep(1); mainSlider->setRange(0,100); @@ -428,7 +443,7 @@ ChannelWidget::ChannelWidget(uint32_t channelCount, EndpointHandler* eph, QWidge for(uint64_t channel = 0, col = 0, row = 0; channel < channelCount && channelCount > 1; channel++){ MeterSlider* tmp = new MeterSlider(Qt::Horizontal); QLabel* tmpLb = new QLabel(""); - tmp->setTickInterval(5); + //tmp->setTickInterval(5); tmp->setSingleStep(1); tmp->setRange(0,100); @@ -520,8 +535,8 @@ EndpointWidget::EndpointWidget(EndpointHandler* eph, QWidget *parent, uint64_t i //muteButton->setStyleSheet("background-color: #A3C1DA; color: red"); mainSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); mainSlider->setFocusPolicy(Qt::StrongFocus); - mainSlider->setTickPosition(QSlider::TicksBothSides); - mainSlider->setTickInterval(5); + //mainSlider->setTickPosition(QSlider::TicksBothSides); + //mainSlider->setTickInterval(5); mainSlider->setSingleStep(1); mainSlider->setRange(0,100); diff --git a/src/qt/qtclasses.h b/src/qt/qtclasses.h index fd9f936..47216be 100644 --- a/src/qt/qtclasses.h +++ b/src/qt/qtclasses.h @@ -29,7 +29,7 @@ #include #include #include - +#include //#include /* * #else @@ -44,7 +44,6 @@ #include "global.h" #include "contclasses.h" -#include "qtvisuals.h" enum SpawnPos { LEFT = (1 << 1), @@ -76,8 +75,8 @@ class MeterSlider : public QSlider { private: ~MeterSlider(); float peakValue; - MixerStyle* style; + friend class MixerStyle; protected: bool event(QEvent* ev) override; void paintEvent(QPaintEvent *event) override; @@ -89,6 +88,9 @@ public: using QSlider::QSlider; }; +//todo: TEST. TEST. +#include "qtvisuals.h" + class ExtendedCheckBox : public QCheckBox { Q_OBJECT protected: diff --git a/src/qt/qtvisuals.h b/src/qt/qtvisuals.h index 5aba5ca..bad98bb 100644 --- a/src/qt/qtvisuals.h +++ b/src/qt/qtvisuals.h @@ -1,84 +1,567 @@ #pragma once #include +#include +#include +#include +//#include "qstylehelper.cpp" + +//repeats. bruh. +//#include +//#include + +enum CustomComplexControl { + CC_MeterSlider = 0xf0000001 +}; + + +namespace qt64 { + static inline QLatin1String operator""_L1(const char* ch, uint64_t) { + return QLatin1String(ch); + } +} + +using namespace qt64; + class MixerStyle : public QProxyStyle { - Q_OBJECT - public: using QProxyStyle::QProxyStyle; - //void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, - //QPainter *p, const QWidget *widget) const override; - + //void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, + // QPainter *painter, const QWidget *widget) const override; + //Click on slider = move handle to click pos int styleHint(QStyle::StyleHint hint, const QStyleOption* option = 0, const QWidget* widget = 0, QStyleHintReturn* returnData = 0) const { if (hint == QStyle::SH_Slider_AbsoluteSetButtons) return (Qt::LeftButton | Qt::MiddleButton | Qt::RightButton); return QProxyStyle::styleHint(hint, option, widget, returnData); } + + /* + * #ifdef Q_OS_DARWIN + * static const qreal qstyleBaseDpi = 72; + * #else + * static const qreal qstyleBaseDpi = 96; + * #endif + */ + + //Q_GUI_EXPORT int qt_defaultDpiX() const; + + qreal dpi(const QStyleOption *option) const { + #ifndef Q_OS_DARWIN + // Prioritize the application override, except for on macOS where + // we have historically not supported the AA_Use96Dpi flag. + if (QCoreApplication::testAttribute(Qt::AA_Use96Dpi)) + return 96; + #endif + + // Expect that QStyleOption::QFontMetrics::QFont has the correct DPI set + if (option) + return option->fontMetrics.fontDpi(); + + // Fall back to historical Qt behavior: hardocded 72 DPI on mac, + // primary screen DPI on other platforms. + #ifdef Q_OS_DARWIN + return qstyleBaseDpi; + #else + return QGuiApplication::primaryScreen()->physicalDotsPerInch(); + #endif + } + + qreal dpiScaled(qreal value, qreal dpi) const { + static const qreal qstyleBaseDpi = 96; + return value * dpi / qstyleBaseDpi; + } + + qreal dpiScaled(qreal value, const QPaintDevice *device) const { + return dpiScaled(value, device->logicalDpiX()); + } + + qreal dpiScaled(qreal value, const QStyleOption *option) const { + return dpiScaled(value, dpi(option)); + } + + QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option, + SubControl subControl, const QWidget *widget) const { + QRect rect = QCommonStyle::subControlRect(CC_Slider, option, subControl, widget); + + switch (control) { + #if QT_CONFIG(slider) + case CC_MeterSlider: + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { + int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget); + switch (subControl) { + case SC_SliderHandle: { + const bool bothTicks = (slider->tickPosition & QSlider::TicksBothSides) == QSlider::TicksBothSides; + if (slider->orientation == Qt::Horizontal) { + rect.setHeight(baseStyle()->pixelMetric(PM_SliderThickness, option, widget)); + rect.setWidth(baseStyle()->pixelMetric(PM_SliderLength, option, widget)); + int centerY = slider->rect.center().y() - rect.height() / 2; + if (!bothTicks) { + if (slider->tickPosition & QSlider::TicksAbove) + centerY += tickSize; + if (slider->tickPosition & QSlider::TicksBelow) + centerY -= tickSize - 1; + } + rect.moveTop(centerY); + } else { + rect.setWidth(baseStyle()->pixelMetric(PM_SliderThickness, option, widget)); + rect.setHeight(baseStyle()->pixelMetric(PM_SliderLength, option, widget)); + int centerX = slider->rect.center().x() - rect.width() / 2; + if (!bothTicks) { + if (slider->tickPosition & QSlider::TicksAbove) + centerX += tickSize; + if (slider->tickPosition & QSlider::TicksBelow) + centerX -= tickSize - 1; + } + rect.moveLeft(centerX); + } + } + break; + case SC_SliderGroove: { + QPoint grooveCenter = slider->rect.center(); + //rect.setWidth(std::abs(grooveCenter.x()) * 2); + const int grooveThickness = this->dpiScaled(7, option); //QStyleHelper::dpiScaled(7, option); + const bool bothTicks = (slider->tickPosition & QSlider::TicksBothSides) == QSlider::TicksBothSides; + if (slider->orientation == Qt::Horizontal) { + rect.setHeight(grooveThickness); + if (!bothTicks) { + if (slider->tickPosition & QSlider::TicksAbove) + grooveCenter.ry() += tickSize; + if (slider->tickPosition & QSlider::TicksBelow) + grooveCenter.ry() -= tickSize - 1; + } + } else { + rect.setWidth(grooveThickness); + if (!bothTicks) { + if (slider->tickPosition & QSlider::TicksAbove) + grooveCenter.rx() += tickSize; + if (slider->tickPosition & QSlider::TicksBelow) + grooveCenter.rx() -= tickSize - 1; + } + } + rect.moveCenter(grooveCenter); + break; + } + default: + break; + } + } + return rect; + break; +#endif // QT_CONFIG(slider) + default: + return baseStyle()->subControlRect(control, option, subControl, widget); + break; + } + + } + + void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget) const { + switch (cc) { + #if QT_CONFIG(slider) + case CC_MeterSlider: + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { + const qreal dpr = painter->device()->devicePixelRatio(); + const QColor buttonColor = this->buttonColor(option->palette); + QRect groove = this->subControlRect(static_cast(CC_MeterSlider), option, SC_SliderGroove, widget); + QRect handle = this->subControlRect(static_cast(CC_MeterSlider), option, SC_SliderHandle, widget); + + bool horizontal = slider->orientation == Qt::Horizontal; + bool ticksAbove = slider->tickPosition & QSlider::TicksAbove; + bool ticksBelow = slider->tickPosition & QSlider::TicksBelow; + QColor activeHighlight = this->highlight(option->palette); + QPixmap cache; + QBrush oldBrush = painter->brush(); + QPen oldPen = painter->pen(); + QColor shadowAlpha(Qt::black); + shadowAlpha.setAlpha(10); + QColor outline; + if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) + outline = this->highlightedOutline(option->palette); + + if ((option->subControls & SC_SliderGroove) && groove.isValid()) { + QColor grooveColor; + grooveColor.setHsv(buttonColor.hue(), + qMin(255, (int)(buttonColor.saturation())), + qMin(255, (int)(buttonColor.value()*0.9))); + QString groovePixmapName = "slider_groove" + QString::number(groove.width());//QStyleHelper::uniqueName("slider_groove"_L1, option, groove.size(), dpr); + QRect pixmapRect(0, 0, groove.width(), groove.height()); + + // draw background groove + if (!QPixmapCache::find(groovePixmapName, &cache)) { + cache = this->styleCachePixmap(pixmapRect.size(), dpr); + QPainter groovePainter(&cache); + groovePainter.setRenderHint(QPainter::Antialiasing, true); + groovePainter.translate(0.5, 0.5); + QLinearGradient gradient; + if (horizontal) { + gradient.setStart(pixmapRect.center().x(), pixmapRect.top()); + gradient.setFinalStop(pixmapRect.center().x(), pixmapRect.bottom()); + } + else { + gradient.setStart(pixmapRect.left(), pixmapRect.center().y()); + gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y()); + } + groovePainter.setPen(QPen(outline)); + gradient.setColorAt(0, grooveColor.darker(110)); + gradient.setColorAt(1, grooveColor.lighter(110));//palette.button().color().darker(115)); + groovePainter.setBrush(gradient); + groovePainter.drawRoundedRect(pixmapRect.adjusted(1, 1, -2, -2), 1, 1); + groovePainter.end(); + QPixmapCache::insert(groovePixmapName, cache); + } + painter->drawPixmap(groove.topLeft(), cache); + + // draw groove lines (vol + unattenuated vol) + const MeterSlider* widgetCast = qobject_cast(widget); + if (widgetCast) { + QRect clipRect; + //if (!groovePixmapName.isEmpty()) groovePixmapName += QLatin1String("_unattenuated"); + //groovePixmapName += "_unattenuated"_L1; + //lf (!QPixmapCache::find(groovePixmapName, &cache)) { + cache = styleCachePixmap(pixmapRect.size(), dpr); + QPainter groovePainter(&cache); + QLinearGradient gradient; + if (horizontal) { + gradient.setStart(pixmapRect.center().x(), pixmapRect.top()); + gradient.setFinalStop(pixmapRect.center().x(), pixmapRect.bottom()); + } + else { + gradient.setStart(pixmapRect.left(), pixmapRect.center().y()); + gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y()); + } + QColor highlight = QColor(30,30,30,100); //this->highlight(option->palette); + QColor highlightedoutline = highlight.darker(140); + QColor grooveOutline = outline; + if (qGray(grooveOutline.rgb()) > qGray(highlightedoutline.rgb())) + grooveOutline = highlightedoutline; + + float peakValue = ((MeterSlider*)widget)->peakValue; + groovePainter.setRenderHint(QPainter::Antialiasing, true); + groovePainter.translate(0.5, 0.5); + groovePainter.setPen(QPen(grooveOutline)); + gradient.setColorAt(0, highlight); + gradient.setColorAt(1, highlight.lighter(130)); + groovePainter.setBrush(gradient); + groovePainter.drawRoundedRect(pixmapRect.adjusted( + 1, 1, + -pixmapRect.width() + (pixmapRect.width() * peakValue), + -2), 1, 1); + groovePainter.setPen(this->innerContrastLine()); + groovePainter.setBrush(Qt::green); + double stepWidth = (double)widgetCast->width() * ((double)widgetCast->singleStep() / (widgetCast->maximum() - widgetCast->minimum())); + groovePainter.drawRoundedRect(pixmapRect.adjusted( + 1, 1, + -pixmapRect.width() + ((widgetCast->width() - ((widgetCast->maximum() - widgetCast->value()) * stepWidth)) * peakValue), + -2), 1, 1); + + groovePainter.end(); + //QPixmapCache::insert(groovePixmapName, cache); + //} + //} + if (horizontal) { + if (slider->upsideDown) + clipRect = QRect(handle.right(), groove.top(), groove.right() - handle.right(), groove.height()); + else + clipRect = QRect(groove.left() + 2, groove.top() + 2, + groove.right() - 2, 2); + } else { + if (slider->upsideDown) + clipRect = QRect(groove.left(), handle.bottom(), groove.width(), groove.height() - (handle.bottom() - slider->rect.top())); + else + clipRect = QRect(groove.left(), groove.top(), groove.width(), handle.top() - groove.top()); + } + painter->save(); + painter->setClipRect(clipRect.adjusted(0, 0, 1, 1), Qt::IntersectClip); + painter->drawPixmap(groove.topLeft(), cache); + painter->restore(); + } + } + if (option->subControls & SC_SliderTickmarks) { + painter->save(); + painter->translate(slider->rect.x(), slider->rect.y()); + painter->setPen(outline); + int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget); + int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget); + int interval = slider->tickInterval; + if (interval <= 0) { + interval = slider->singleStep; + if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval, + available) + - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, + 0, available) < 3) + interval = slider->pageStep; + } + if (interval <= 0) + interval = 1; + + int v = slider->minimum; + int len = proxy()->pixelMetric(PM_SliderLength, slider, widget); + QVector lines; + while (v <= slider->maximum + 1) { + if (v == slider->maximum + 1 && interval == 1) + break; + const int v_ = qMin(v, slider->maximum); + int pos = sliderPositionFromValue(slider->minimum, slider->maximum, + v_, (horizontal + ? slider->rect.width() + : slider->rect.height()) - len, + slider->upsideDown) + len / 2; + int extra = 2 - ((v_ == slider->minimum || v_ == slider->maximum) ? 1 : 0); + + if (horizontal) { + if (ticksAbove) { + lines += QLine(pos, slider->rect.top() + extra, + pos, slider->rect.top() + tickSize); + } + if (ticksBelow) { + lines += QLine(pos, slider->rect.bottom() - extra, + pos, slider->rect.bottom() - tickSize); + } + } else { + if (ticksAbove) { + lines += QLine(slider->rect.left() + extra, pos, + slider->rect.left() + tickSize, pos); + } + if (ticksBelow) { + lines += QLine(slider->rect.right() - extra, pos, + slider->rect.right() - tickSize, pos); + } + } + // in the case where maximum is max int + int nextInterval = v + interval; + if (nextInterval < v) + break; + v = nextInterval; + } + painter->drawLines(lines); + painter->restore(); + } + // draw handle + if ((option->subControls & SC_SliderHandle) ) { + QString handlePixmapName = "slider_handle" + QString::number(handle.height());//QStyleHelper::uniqueName("slider_handle"_L1, option,//handle.size(), dpr); + if (!QPixmapCache::find(handlePixmapName, &cache)) { + cache = styleCachePixmap(handle.size(), dpr); + QRect pixmapRect(0, 0, handle.width(), handle.height()); + QPainter handlePainter(&cache); + QRect gradRect = pixmapRect.adjusted(2, 2, -2, -2); + + // gradient fill + QRect r = pixmapRect.adjusted(1, 1, -2, -2); + QLinearGradient gradient = qt_fusion_gradient(gradRect, this->buttonColor(option->palette),horizontal ? TopDown : FromLeft); + + handlePainter.setRenderHint(QPainter::Antialiasing, true); + handlePainter.translate(0.5, 0.5); + + handlePainter.setPen(Qt::NoPen); + handlePainter.setBrush(QColor(0, 0, 0, 40)); + handlePainter.drawRect(horizontal ? r.adjusted(-1, 2, 1, -2) : r.adjusted(2, -1, -2, 1)); + + handlePainter.setPen(QPen(this->outline(option->palette))); + if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) + handlePainter.setPen(QPen(this->highlightedOutline(option->palette))); + + handlePainter.setBrush(gradient); + handlePainter.drawRoundedRect(r, 2, 2); + handlePainter.setBrush(Qt::NoBrush); + handlePainter.setPen(this->innerContrastLine()); + handlePainter.drawRoundedRect(r.adjusted(1, 1, -1, -1), 2, 2); + + QColor cornerAlpha = outline.darker(120); + cornerAlpha.setAlpha(80); + + //handle shadow + handlePainter.setPen(shadowAlpha); + handlePainter.drawLine(QPoint(r.left() + 2, r.bottom() + 1), QPoint(r.right() - 2, r.bottom() + 1)); + handlePainter.drawLine(QPoint(r.right() + 1, r.bottom() - 3), QPoint(r.right() + 1, r.top() + 4)); + handlePainter.drawLine(QPoint(r.right() - 1, r.bottom()), QPoint(r.right() + 1, r.bottom() - 2)); + + handlePainter.end(); + QPixmapCache::insert(handlePixmapName, cache); + } + + painter->drawPixmap(handle.topLeft(), cache); + + } + painter->setBrush(oldBrush); + painter->setPen(oldPen); + } + break; + default: + baseStyle()->drawComplexControl(cc, option, painter, widget); +#endif // QT_CONFIG(slider) +} +} + +private: + enum Direction { + TopDown, + FromLeft, + BottomUp, + FromRight + }; + + QColor highlightedOutline(const QPalette &pal) const { + QColor highlightedOutline = highlight(pal).darker(125); + if (highlightedOutline.value() > 160) + highlightedOutline.setHsl(highlightedOutline.hue(), highlightedOutline.saturation(), 160); + return highlightedOutline; + } + + QColor outline(const QPalette &pal) const { + if (pal.window().style() == Qt::TexturePattern) + return QColor(0, 0, 0, 160); + return pal.window().color().darker(140); + } + + QColor buttonColor(const QPalette &pal) const { + QColor buttonColor = pal.button().color(); + int val = qGray(buttonColor.rgb()); + buttonColor = buttonColor.lighter(100 + qMax(1, (180 - val)/6)); + buttonColor.setHsv(buttonColor.hue(), buttonColor.saturation() * 0.75, buttonColor.value()); + return buttonColor; + } + + QColor highlight(const QPalette &pal) const { + if (isMacSystemPalette(pal)) + return QColor(60, 140, 230); + return pal.color(QPalette::Highlight); + } + + QColor innerContrastLine() const { + return QColor(255, 255, 255, 30); + } + + bool isMacSystemPalette(const QPalette &pal) const { + Q_UNUSED(pal); +#if defined(Q_OS_MACOS) + const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette(); + if (themePalette && themePalette->color(QPalette::Normal, QPalette::Highlight) == + pal.color(QPalette::Normal, QPalette::Highlight) && + themePalette->color(QPalette::Normal, QPalette::HighlightedText) == + pal.color(QPalette::Normal, QPalette::HighlightedText)) + return true; +#endif + return false; + } + + inline QPixmap styleCachePixmap(const QSize &size, qreal pixelRatio) const { + //not api + QPixmap cachePixmap = QPixmap(size * pixelRatio); + cachePixmap.setDevicePixelRatio(pixelRatio); + cachePixmap.fill(Qt::transparent); + return cachePixmap; + } + + static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseColor, Direction direction = TopDown) +{ + int x = rect.center().x(); + int y = rect.center().y(); + QLinearGradient gradient; + switch (direction) { + case FromLeft: + gradient = QLinearGradient(rect.left(), y, rect.right(), y); + break; + case FromRight: + gradient = QLinearGradient(rect.right(), y, rect.left(), y); + break; + case BottomUp: + gradient = QLinearGradient(x, rect.bottom(), x, rect.top()); + break; + case TopDown: + default: + gradient = QLinearGradient(x, rect.top(), x, rect.bottom()); + break; + } + if (baseColor.gradient()) + gradient.setStops(baseColor.gradient()->stops()); + else { + QColor gradientStartColor = baseColor.color().lighter(124); + QColor gradientStopColor = baseColor.color().lighter(102); + gradient.setColorAt(0, gradientStartColor); + gradient.setColorAt(1, gradientStopColor); + // Uncomment for adding shiny shading + // QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 55); + // QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 45); + // gradient.setColorAt(0.5, midColor1); + // gradient.setColorAt(0.501, midColor2); + } + return gradient; +} + }; + /* * void MixerStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, - * QPainter *p, const QWidget *widget) const { - * #if QT_CONFIG(slider) - * case CC_Slider: - * if (const QStyleOptionSlider *slider = qstyleoption_cast(opt)) { - * if (slider->subControls == SC_SliderTickmarks) { - * int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget); - * int ticks = slider->tickPosition; - * int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget); - * int len = proxy()->pixelMetric(PM_SliderLength, slider, widget); - * int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget); - * int interval = slider->tickInterval; - * if (interval <= 0) { - * interval = slider->singleStep; - * if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval, - * available) - * - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, - * 0, available) < 3) - * interval = slider->pageStep; - * } - * if (!interval) - * interval = 1; - * int fudge = len / 2; - * int pos; - * // Since there is no subrect for tickmarks do a translation here. - * QPainterStateSaver pss(p); - * p->translate(slider->rect.x(), slider->rect.y()); - * p->setPen(slider->palette.windowText().color()); - * int v = slider->minimum; - * while (v <= slider->maximum + 1) { - * if (v == slider->maximum + 1 && interval == 1) - * break; - * const int v_ = qMin(v, slider->maximum); - * pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, - * v_, available) + fudge; - ** - * if (slider->orientation == Qt::Horizontal) { - * if (ticks & QSlider::TicksAbove) - * p->drawLine(pos, 0, pos, tickOffset - 2); - * if (ticks & QSlider::TicksBelow) - * p->drawLine(pos, tickOffset + thickness + 1, pos, - * slider->rect.height()-1); - * } else { - * if (ticks & QSlider::TicksAbove) - * p->drawLine(0, pos, tickOffset - 2, pos); - * if (ticks & QSlider::TicksBelow) - * p->drawLine(tickOffset + thickness + 1, pos, - * slider->rect.width()-1, pos); - * } - * // in the case where maximum is max int - * int nextInterval = v + interval; - * if (nextInterval < v) - * break; - * v = nextInterval; - * } - * } - * } - * break; -*#endif // QT_CONFIG(slider) -*/ -//} + * QPainter *p, const QWidget *widget) const { + * switch (cc) { + * #if QT_CONFIG(slider) + * case CC_Slider: + * if (const QStyleOptionSlider *slider = qstyleoption_cast(opt)) { + * if (slider->subControls == SC_SliderTickmarks) { + * int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget); + * int ticks = slider->tickPosition; + * int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget); + * int len = proxy()->pixelMetric(PM_SliderLength, slider, widget); + * int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget); + * int interval = slider->tickInterval; + * if (interval <= 0) { + * interval = slider->singleStep; + * if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval, + * available) + * - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, + * 0, available) < 3) + * interval = slider->pageStep; + * } + * if (!interval) + * interval = 1; + * int fudge = len / 2; + * int pos; + * // Since there is no subrect for tickmarks do a translation here. + * p->save(); + * p->translate(slider->rect.x(), slider->rect.y()); + * p->setPen(slider->palette.windowText().color()); + * int v = slider->minimum; + * while (v <= slider->maximum + 1) { + * if (v == slider->maximum + 1 && interval == 1) + * break; + * const int v_ = qMin(v, slider->maximum); + * pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, + * v_, available) + fudge; + * if (slider->orientation == Qt::Horizontal) { + * if (ticks & QSlider::TicksAbove) + * p->drawLine(pos, 0, pos, tickOffset - 2); + * if (ticks & QSlider::TicksBelow) + * p->drawLine(pos, tickOffset + thickness + 1, pos, + * slider->rect.height()-1); + * } else { + * if (ticks & QSlider::TicksAbove) + * p->drawLine(0, pos, tickOffset - 2, pos); + * if (ticks & QSlider::TicksBelow) + * p->drawLine(tickOffset + thickness + 1, pos, + * slider->rect.width()-1, pos); + * } + * // in the case where maximum is max int + * int nextInterval = v + interval; + * if (nextInterval < v) + * break; + * v = nextInterval; + * } + * } + * } + * p->restore(); + * break; + * default: + * baseStyle()->drawComplexControl(cc, opt, p, widget); + * break; + * } + * #endif // QT_CONFIG(slider) + * } + */ + +//void MixerStyle:: diff --git a/src/qtestmain.cpp b/src/qtestmain.cpp index e4a6aec..f37e337 100644 --- a/src/qtestmain.cpp +++ b/src/qtestmain.cpp @@ -7,6 +7,7 @@ #include #include #include +#include //#include "contclasses.h" #define INIT_FILELOG #include "qtclasses.h" @@ -54,7 +55,11 @@ int main (int argc, char* argv[]) { * } */ - QApplication::setStyle(new MixerStyle(QStyleFactory::create("windowsvista"))); + QApplication::setStyle(new MixerStyle(QStyleFactory::create("Fusion"))); + QPalette palette = QGuiApplication::palette(); + //todo: ez full apply os accent colorw + palette.setColor(QPalette::Active, QPalette::Highlight, QColor(255, 192, 203, 200));//QColor(30,30,30,100)); + QGuiApplication::setPalette(palette); //Check if running //https://stackoverflow.com/questions/48060989/qt-show-application-if-currently-running initialize_file_log();