Advance Wayland and KDE package bring-up
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 1997 Martin Jones <mjones@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "kselector.h"
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* 1D value selector with contents drawn by derived class.
|
||||
* See KColorDialog for example.
|
||||
*/
|
||||
|
||||
#define ARROWSIZE 5
|
||||
|
||||
class KSelectorPrivate
|
||||
{
|
||||
public:
|
||||
bool m_indent = true;
|
||||
QStyle::PrimitiveElement arrowPE = QStyle::PE_IndicatorArrowLeft;
|
||||
};
|
||||
|
||||
class KGradientSelectorPrivate
|
||||
{
|
||||
public:
|
||||
KGradientSelectorPrivate(KGradientSelector *qq)
|
||||
: q(qq)
|
||||
{
|
||||
}
|
||||
|
||||
KGradientSelector *q;
|
||||
QLinearGradient gradient;
|
||||
QString text1;
|
||||
QString text2;
|
||||
};
|
||||
|
||||
KSelector::KSelector(QWidget *parent)
|
||||
: QAbstractSlider(parent)
|
||||
, d(new KSelectorPrivate)
|
||||
{
|
||||
setOrientation(Qt::Horizontal);
|
||||
}
|
||||
|
||||
KSelector::KSelector(Qt::Orientation o, QWidget *parent)
|
||||
: QAbstractSlider(parent)
|
||||
, d(new KSelectorPrivate)
|
||||
{
|
||||
setOrientation(o);
|
||||
if (o == Qt::Horizontal) {
|
||||
setArrowDirection(Qt::UpArrow);
|
||||
}
|
||||
}
|
||||
|
||||
KSelector::~KSelector() = default;
|
||||
|
||||
void KSelector::setIndent(bool i)
|
||||
{
|
||||
d->m_indent = i;
|
||||
}
|
||||
|
||||
bool KSelector::indent() const
|
||||
{
|
||||
return d->m_indent;
|
||||
}
|
||||
|
||||
QRect KSelector::contentsRect() const
|
||||
{
|
||||
int w = indent() ? style()->pixelMetric(QStyle::PM_DefaultFrameWidth) : 0;
|
||||
// TODO: is the height:width ratio of an indicator arrow always 2:1? hm.
|
||||
int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
|
||||
|
||||
if (orientation() == Qt::Vertical) {
|
||||
if (arrowDirection() == Qt::RightArrow) {
|
||||
return QRect(w + ARROWSIZE, //
|
||||
iw,
|
||||
width() - w * 2 - ARROWSIZE,
|
||||
height() - iw * 2);
|
||||
} else {
|
||||
return QRect(w, //
|
||||
iw,
|
||||
width() - w * 2 - ARROWSIZE,
|
||||
height() - iw * 2);
|
||||
}
|
||||
} else { // Qt::Horizontal
|
||||
if (arrowDirection() == Qt::UpArrow) {
|
||||
return QRect(iw, //
|
||||
w,
|
||||
width() - 2 * iw,
|
||||
height() - w * 2 - ARROWSIZE);
|
||||
} else {
|
||||
return QRect(iw, //
|
||||
w + ARROWSIZE,
|
||||
width() - 2 * iw,
|
||||
height() - w * 2 - ARROWSIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KSelector::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter;
|
||||
int w = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||
int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
|
||||
|
||||
painter.begin(this);
|
||||
|
||||
if (indent()) {
|
||||
QStyleOptionFrame opt;
|
||||
opt.initFrom(this);
|
||||
opt.state = QStyle::State_Sunken;
|
||||
if (orientation() == Qt::Vertical) {
|
||||
opt.rect.adjust(0, iw - w, -5, w - iw);
|
||||
} else {
|
||||
opt.rect.adjust(iw - w, 0, w - iw, -5);
|
||||
}
|
||||
QBrush oldBrush = painter.brush();
|
||||
painter.setBrush(Qt::NoBrush);
|
||||
style()->drawPrimitive(QStyle::PE_Frame, &opt, &painter, this);
|
||||
painter.setBrush(oldBrush);
|
||||
}
|
||||
|
||||
drawContents(&painter);
|
||||
|
||||
QPoint pos = calcArrowPos(value());
|
||||
drawArrow(&painter, pos);
|
||||
|
||||
painter.end();
|
||||
}
|
||||
|
||||
void KSelector::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
setSliderDown(true);
|
||||
moveArrow(e->pos());
|
||||
}
|
||||
|
||||
void KSelector::mouseMoveEvent(QMouseEvent *e)
|
||||
{
|
||||
moveArrow(e->pos());
|
||||
}
|
||||
|
||||
void KSelector::mouseReleaseEvent(QMouseEvent *e)
|
||||
{
|
||||
moveArrow(e->pos());
|
||||
setSliderDown(false);
|
||||
}
|
||||
|
||||
void KSelector::wheelEvent(QWheelEvent *e)
|
||||
{
|
||||
int val = value() + e->angleDelta().y() / 120;
|
||||
setSliderDown(true);
|
||||
setValue(val);
|
||||
setSliderDown(false);
|
||||
}
|
||||
|
||||
void KSelector::moveArrow(const QPoint &pos)
|
||||
{
|
||||
int val;
|
||||
int w = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||
int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
|
||||
|
||||
if (orientation() == Qt::Vertical) {
|
||||
val = (maximum() - minimum()) * (height() - pos.y() - iw) / (height() - iw * 2) + minimum();
|
||||
} else {
|
||||
val = (maximum() - minimum()) * (pos.x() - iw) / (width() - iw * 2) + minimum();
|
||||
}
|
||||
|
||||
setValue(val);
|
||||
update();
|
||||
}
|
||||
|
||||
QPoint KSelector::calcArrowPos(int val)
|
||||
{
|
||||
QPoint p;
|
||||
int w = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||
int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
|
||||
|
||||
if (orientation() == Qt::Vertical) {
|
||||
p.setY(height() - iw - 1 - (height() - 2 * iw - 1) * val / (maximum() - minimum()));
|
||||
|
||||
if (d->arrowPE == QStyle::PE_IndicatorArrowRight) {
|
||||
p.setX(0);
|
||||
} else {
|
||||
p.setX(width() - 5);
|
||||
}
|
||||
} else {
|
||||
p.setX(iw + (width() - 2 * iw - 1) * val / (maximum() - minimum()));
|
||||
|
||||
if (d->arrowPE == QStyle::PE_IndicatorArrowDown) {
|
||||
p.setY(0);
|
||||
} else {
|
||||
p.setY(height() - 5);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void KSelector::setArrowDirection(Qt::ArrowType direction)
|
||||
{
|
||||
switch (direction) {
|
||||
case Qt::UpArrow:
|
||||
if (orientation() == Qt::Horizontal) {
|
||||
d->arrowPE = QStyle::PE_IndicatorArrowUp;
|
||||
} else {
|
||||
d->arrowPE = QStyle::PE_IndicatorArrowLeft;
|
||||
}
|
||||
break;
|
||||
case Qt::DownArrow:
|
||||
if (orientation() == Qt::Horizontal) {
|
||||
d->arrowPE = QStyle::PE_IndicatorArrowDown;
|
||||
} else {
|
||||
d->arrowPE = QStyle::PE_IndicatorArrowRight;
|
||||
}
|
||||
break;
|
||||
case Qt::LeftArrow:
|
||||
if (orientation() == Qt::Vertical) {
|
||||
d->arrowPE = QStyle::PE_IndicatorArrowLeft;
|
||||
} else {
|
||||
d->arrowPE = QStyle::PE_IndicatorArrowDown;
|
||||
}
|
||||
break;
|
||||
case Qt::RightArrow:
|
||||
if (orientation() == Qt::Vertical) {
|
||||
d->arrowPE = QStyle::PE_IndicatorArrowRight;
|
||||
} else {
|
||||
d->arrowPE = QStyle::PE_IndicatorArrowUp;
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::NoArrow:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ArrowType KSelector::arrowDirection() const
|
||||
{
|
||||
switch (d->arrowPE) {
|
||||
case QStyle::PE_IndicatorArrowUp:
|
||||
return Qt::UpArrow;
|
||||
case QStyle::PE_IndicatorArrowDown:
|
||||
return Qt::DownArrow;
|
||||
case QStyle::PE_IndicatorArrowRight:
|
||||
return Qt::RightArrow;
|
||||
case QStyle::PE_IndicatorArrowLeft:
|
||||
default:
|
||||
return Qt::LeftArrow;
|
||||
}
|
||||
}
|
||||
|
||||
void KSelector::drawContents(QPainter *)
|
||||
{
|
||||
}
|
||||
|
||||
void KSelector::drawArrow(QPainter *painter, const QPoint &pos)
|
||||
{
|
||||
painter->setPen(QPen());
|
||||
painter->setBrush(QBrush(palette().color(QPalette::ButtonText)));
|
||||
|
||||
QStyleOption o;
|
||||
|
||||
if (orientation() == Qt::Vertical) {
|
||||
o.rect = QRect(pos.x(), pos.y() - ARROWSIZE / 2, ARROWSIZE, ARROWSIZE);
|
||||
} else {
|
||||
o.rect = QRect(pos.x() - ARROWSIZE / 2, pos.y(), ARROWSIZE, ARROWSIZE);
|
||||
}
|
||||
style()->drawPrimitive(d->arrowPE, &o, painter, this);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
KGradientSelector::KGradientSelector(QWidget *parent)
|
||||
: KSelector(parent)
|
||||
, d(new KGradientSelectorPrivate(this))
|
||||
{
|
||||
}
|
||||
|
||||
KGradientSelector::KGradientSelector(Qt::Orientation o, QWidget *parent)
|
||||
: KSelector(o, parent)
|
||||
, d(new KGradientSelectorPrivate(this))
|
||||
{
|
||||
}
|
||||
|
||||
KGradientSelector::~KGradientSelector() = default;
|
||||
|
||||
void KGradientSelector::drawContents(QPainter *painter)
|
||||
{
|
||||
d->gradient.setStart(contentsRect().topLeft());
|
||||
if (orientation() == Qt::Vertical) {
|
||||
d->gradient.setFinalStop(contentsRect().bottomLeft());
|
||||
} else {
|
||||
d->gradient.setFinalStop(contentsRect().topRight());
|
||||
}
|
||||
QBrush gradientBrush(d->gradient);
|
||||
|
||||
if (!gradientBrush.isOpaque()) {
|
||||
QPixmap chessboardPattern(16, 16);
|
||||
QPainter patternPainter(&chessboardPattern);
|
||||
patternPainter.fillRect(0, 0, 8, 8, Qt::black);
|
||||
patternPainter.fillRect(8, 8, 8, 8, Qt::black);
|
||||
patternPainter.fillRect(0, 8, 8, 8, Qt::white);
|
||||
patternPainter.fillRect(8, 0, 8, 8, Qt::white);
|
||||
patternPainter.end();
|
||||
painter->fillRect(contentsRect(), QBrush(chessboardPattern));
|
||||
}
|
||||
painter->fillRect(contentsRect(), gradientBrush);
|
||||
|
||||
if (orientation() == Qt::Vertical) {
|
||||
int yPos = contentsRect().top() + painter->fontMetrics().ascent() + 2;
|
||||
int xPos = contentsRect().left() + (contentsRect().width() - painter->fontMetrics().horizontalAdvance(d->text2)) / 2;
|
||||
QPen pen(qGray(firstColor().rgb()) > 180 ? Qt::black : Qt::white);
|
||||
painter->setPen(pen);
|
||||
painter->drawText(xPos, yPos, d->text2);
|
||||
|
||||
yPos = contentsRect().bottom() - painter->fontMetrics().descent() - 2;
|
||||
xPos = contentsRect().left() + (contentsRect().width() - painter->fontMetrics().horizontalAdvance(d->text1)) / 2;
|
||||
pen.setColor(qGray(secondColor().rgb()) > 180 ? Qt::black : Qt::white);
|
||||
painter->setPen(pen);
|
||||
painter->drawText(xPos, yPos, d->text1);
|
||||
} else {
|
||||
int yPos = contentsRect().bottom() - painter->fontMetrics().descent() - 2;
|
||||
|
||||
QPen pen(qGray(firstColor().rgb()) > 180 ? Qt::black : Qt::white);
|
||||
painter->setPen(pen);
|
||||
painter->drawText(contentsRect().left() + 2, yPos, d->text1);
|
||||
|
||||
pen.setColor(qGray(secondColor().rgb()) > 180 ? Qt::black : Qt::white);
|
||||
painter->setPen(pen);
|
||||
painter->drawText(contentsRect().right() - painter->fontMetrics().horizontalAdvance(d->text2) - 2, yPos, d->text2);
|
||||
}
|
||||
}
|
||||
|
||||
QSize KGradientSelector::minimumSize() const
|
||||
{
|
||||
return sizeHint();
|
||||
}
|
||||
|
||||
void KGradientSelector::setStops(const QGradientStops &stops)
|
||||
{
|
||||
d->gradient.setStops(stops);
|
||||
update();
|
||||
}
|
||||
|
||||
QGradientStops KGradientSelector::stops() const
|
||||
{
|
||||
return d->gradient.stops();
|
||||
}
|
||||
|
||||
void KGradientSelector::setColors(const QColor &col1, const QColor &col2)
|
||||
{
|
||||
d->gradient.setColorAt(0.0, col1);
|
||||
d->gradient.setColorAt(1.0, col2);
|
||||
update();
|
||||
}
|
||||
|
||||
void KGradientSelector::setText(const QString &t1, const QString &t2)
|
||||
{
|
||||
d->text1 = t1;
|
||||
d->text2 = t2;
|
||||
update();
|
||||
}
|
||||
|
||||
void KGradientSelector::setFirstColor(const QColor &col)
|
||||
{
|
||||
d->gradient.setColorAt(0.0, col);
|
||||
update();
|
||||
}
|
||||
|
||||
void KGradientSelector::setSecondColor(const QColor &col)
|
||||
{
|
||||
d->gradient.setColorAt(1.0, col);
|
||||
update();
|
||||
}
|
||||
|
||||
void KGradientSelector::setFirstText(const QString &t)
|
||||
{
|
||||
d->text1 = t;
|
||||
update();
|
||||
}
|
||||
|
||||
void KGradientSelector::setSecondText(const QString &t)
|
||||
{
|
||||
d->text2 = t;
|
||||
update();
|
||||
}
|
||||
|
||||
QColor KGradientSelector::firstColor() const
|
||||
{
|
||||
return d->gradient.stops().first().second;
|
||||
}
|
||||
|
||||
QColor KGradientSelector::secondColor() const
|
||||
{
|
||||
return d->gradient.stops().last().second;
|
||||
}
|
||||
|
||||
QString KGradientSelector::firstText() const
|
||||
{
|
||||
return d->text1;
|
||||
}
|
||||
|
||||
QString KGradientSelector::secondText() const
|
||||
{
|
||||
return d->text2;
|
||||
}
|
||||
|
||||
#include "moc_kselector.cpp"
|
||||
Reference in New Issue
Block a user