From a1960f6e783b572538914b7f9cd6e29609998c66 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 14 Nov 2017 00:53:40 +0100 Subject: [PATCH] Utils: Make crumblepath graphics themable and high-DPI-able This change replaces the outdated CrumblePathButton graphics with new, themable and high-DPI-able variants. The new graphics need to be drawn in a different way, which reduces the required code in CrumblePath a bit. Change-Id: Ie006199c7f307ae7528b5c951c95cfa2a1c4308d Reviewed-by: Thomas Hartmann --- src/libs/utils/crumblepath.cpp | 376 ++++++------------ src/libs/utils/crumblepath.h | 11 +- .../utils/images/crumblepath-segment-end.png | Bin 250 -> 0 bytes .../crumblepath-segment-first-hover.png | Bin 0 -> 155 bytes .../crumblepath-segment-first-hover@2x.png | Bin 0 -> 278 bytes .../images/crumblepath-segment-first.png | Bin 0 -> 157 bytes .../images/crumblepath-segment-first@2x.png | Bin 0 -> 281 bytes .../images/crumblepath-segment-hover-end.png | Bin 256 -> 0 bytes .../images/crumblepath-segment-hover.png | Bin 676 -> 0 bytes .../images/crumblepath-segment-last-hover.png | Bin 0 -> 159 bytes .../crumblepath-segment-last-hover@2x.png | Bin 0 -> 289 bytes .../utils/images/crumblepath-segment-last.png | Bin 0 -> 159 bytes .../images/crumblepath-segment-last@2x.png | Bin 0 -> 290 bytes .../crumblepath-segment-middle-hover.png | Bin 0 -> 220 bytes .../crumblepath-segment-middle-hover@2x.png | Bin 0 -> 438 bytes .../images/crumblepath-segment-middle.png | Bin 0 -> 224 bytes .../images/crumblepath-segment-middle@2x.png | Bin 0 -> 445 bytes .../crumblepath-segment-selected-end.png | Bin 238 -> 0 bytes .../images/crumblepath-segment-selected.png | Bin 611 -> 0 bytes .../crumblepath-segment-single-hover.png | Bin 0 -> 106 bytes .../crumblepath-segment-single-hover@2x.png | Bin 0 -> 112 bytes .../images/crumblepath-segment-single.png | Bin 0 -> 106 bytes .../images/crumblepath-segment-single@2x.png | Bin 0 -> 112 bytes src/libs/utils/images/crumblepath-segment.png | Bin 666 -> 0 bytes src/libs/utils/images/triangle_vert.png | Bin 84 -> 0 bytes src/libs/utils/utils.qrc | 23 +- src/tools/icons/qtcreatoricons.svg | 184 +++++++++ 27 files changed, 321 insertions(+), 273 deletions(-) delete mode 100644 src/libs/utils/images/crumblepath-segment-end.png create mode 100644 src/libs/utils/images/crumblepath-segment-first-hover.png create mode 100644 src/libs/utils/images/crumblepath-segment-first-hover@2x.png create mode 100644 src/libs/utils/images/crumblepath-segment-first.png create mode 100644 src/libs/utils/images/crumblepath-segment-first@2x.png delete mode 100644 src/libs/utils/images/crumblepath-segment-hover-end.png delete mode 100644 src/libs/utils/images/crumblepath-segment-hover.png create mode 100644 src/libs/utils/images/crumblepath-segment-last-hover.png create mode 100644 src/libs/utils/images/crumblepath-segment-last-hover@2x.png create mode 100644 src/libs/utils/images/crumblepath-segment-last.png create mode 100644 src/libs/utils/images/crumblepath-segment-last@2x.png create mode 100644 src/libs/utils/images/crumblepath-segment-middle-hover.png create mode 100644 src/libs/utils/images/crumblepath-segment-middle-hover@2x.png create mode 100644 src/libs/utils/images/crumblepath-segment-middle.png create mode 100644 src/libs/utils/images/crumblepath-segment-middle@2x.png delete mode 100644 src/libs/utils/images/crumblepath-segment-selected-end.png delete mode 100644 src/libs/utils/images/crumblepath-segment-selected.png create mode 100644 src/libs/utils/images/crumblepath-segment-single-hover.png create mode 100644 src/libs/utils/images/crumblepath-segment-single-hover@2x.png create mode 100644 src/libs/utils/images/crumblepath-segment-single.png create mode 100644 src/libs/utils/images/crumblepath-segment-single@2x.png delete mode 100644 src/libs/utils/images/crumblepath-segment.png delete mode 100644 src/libs/utils/images/triangle_vert.png diff --git a/src/libs/utils/crumblepath.cpp b/src/libs/utils/crumblepath.cpp index e32e344b96..e30332a907 100644 --- a/src/libs/utils/crumblepath.cpp +++ b/src/libs/utils/crumblepath.cpp @@ -27,188 +27,132 @@ #include "qtcassert.h" #include "stylehelper.h" -#include +#include +#include + +#include #include -#include #include +#include +#include +#include +#include +#include #include namespace Utils { -static const int ArrowBorderSize = 12; - -class CrumblePathButton : public QPushButton +class CrumblePathButton final : public QPushButton { Q_OBJECT public: enum SegmentType { - LastSegment = 1, - MiddleSegment = 2, - FirstSegment = 4 + FirstSegment, + MiddleSegment, + LastSegment, + SingleSegment }; - explicit CrumblePathButton(const QString &title, QWidget *parent = 0); - void setSegmentType(int type); + explicit CrumblePathButton(const QString &title, QWidget *parent = nullptr); + void setSegmentType(SegmentType type); void select(bool s); void setData(const QVariant &data); QVariant data() const; protected: - void paintEvent(QPaintEvent *); - void mouseMoveEvent(QMouseEvent *e); - void leaveEvent(QEvent *); - void mousePressEvent(QMouseEvent *e); - void mouseReleaseEvent(QMouseEvent *e); - void changeEvent(QEvent * e); - -private: - void tintImages(); + void paintEvent(QPaintEvent*) override; private: - bool m_isHovering; - bool m_isPressed; - bool m_isSelected; - bool m_isEnd; - QColor m_baseColor; - QImage m_segment; - QImage m_segmentEnd; - QImage m_segmentSelected; - QImage m_segmentSelectedEnd; - QImage m_segmentHover; - QImage m_segmentHoverEnd; - QImage m_triangleIcon; - QPoint m_textPos; - + SegmentType m_segmentType = SingleSegment; QVariant m_data; }; CrumblePathButton::CrumblePathButton(const QString &title, QWidget *parent) - : QPushButton(title, parent), m_isHovering(false), m_isPressed(false), m_isSelected(false), m_isEnd(true) + : QPushButton(title, parent) { - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); setToolTip(title); - setMinimumHeight(25); - setMaximumHeight(25); + setMinimumHeight(24); + setMaximumHeight(24); setMouseTracking(true); - m_textPos.setX(18); - m_textPos.setY(height()); - m_baseColor = StyleHelper::baseColor(); - - m_segment = QImage(QLatin1String(":/utils/images/crumblepath-segment.png")); - m_segmentSelected = QImage(QLatin1String(":/utils/images/crumblepath-segment-selected.png")); - m_segmentHover = QImage(QLatin1String(":/utils/images/crumblepath-segment-hover.png")); - m_segmentEnd = QImage(QLatin1String(":/utils/images/crumblepath-segment-end.png")); - m_segmentSelectedEnd = QImage(QLatin1String(":/utils/images/crumblepath-segment-selected-end.png")); - m_segmentHoverEnd = QImage(QLatin1String(":/utils/images/crumblepath-segment-hover-end.png")); - m_triangleIcon = QImage(QLatin1String(":/utils/images/triangle_vert.png")); - - tintImages(); } -void CrumblePathButton::paintEvent(QPaintEvent *) +static QPixmap segmentPixmap(CrumblePathButton::SegmentType type, QStyle::State state) { - QPainter p(this); - QRect geom(0, 0, geometry().width(), geometry().height()); - - if (StyleHelper::baseColor() != m_baseColor) { - m_baseColor = StyleHelper::baseColor(); - tintImages(); + const QString segmentName = QLatin1String( + type == CrumblePathButton::FirstSegment ? + "first" : type == CrumblePathButton::MiddleSegment ? + "middle" : type == CrumblePathButton::LastSegment ? + "last" : "single"); + + const QIcon::Mode iconMode = state & QStyle::State_Enabled ? QIcon::Normal : QIcon::Disabled; + const bool hover = state & QStyle::State_MouseOver || state & QStyle::State_HasFocus; + + const QString pixmapKey = QStringLiteral("crumblePath-segment-%1-iconMode-%2-hover-%3") + .arg(segmentName).arg(iconMode).arg(hover); + QPixmap pixmap; + if (!QPixmapCache::find(pixmapKey, pixmap)) { + const QString maskFileName = QStringLiteral(":/utils/images/crumblepath-segment-%1%2.png") + .arg(segmentName).arg(QLatin1String(hover ? "-hover" : "")); + pixmap = Utils::Icon({{maskFileName, Theme::IconsBaseColor}}).pixmap(iconMode); + QPixmapCache::insert(pixmapKey, pixmap); } - if (m_isEnd) { - if (m_isPressed || m_isSelected) - StyleHelper::drawCornerImage(m_segmentSelectedEnd, &p, geom, 2, 0, 2, 0); - else if (m_isHovering) - StyleHelper::drawCornerImage(m_segmentHoverEnd, &p, geom, 2, 0, 2, 0); - else - StyleHelper::drawCornerImage(m_segmentEnd, &p, geom, 2, 0, 2, 0); - } else { - if (m_isPressed || m_isSelected) - StyleHelper::drawCornerImage(m_segmentSelected, &p, geom, 2, 0, 12, 0); - else if (m_isHovering) - StyleHelper::drawCornerImage(m_segmentHover, &p, geom, 2, 0, 12, 0); - else - StyleHelper::drawCornerImage(m_segment, &p, geom, 2, 0, 12, 0); - } - if (isEnabled()) - p.setPen(StyleHelper::panelTextColor()); - else - p.setPen(StyleHelper::panelTextColor().darker()); - QFontMetrics fm(p.font()); - QString textToDraw = fm.elidedText(text(), Qt::ElideRight, geom.width() - m_textPos.x()); - - p.drawText(QRectF(m_textPos.x(), 4, geom.width(), geom.height()), textToDraw); - - if (menu()) { - p.drawImage(geom.width() - m_triangleIcon.width() - 6, - geom.center().y() - m_triangleIcon.height() / 2, - m_triangleIcon); - } -} - -void CrumblePathButton::tintImages() -{ - StyleHelper::tintImage(m_segmentEnd, m_baseColor); - StyleHelper::tintImage(m_segmentSelectedEnd, m_baseColor); - StyleHelper::tintImage(m_segmentHoverEnd, m_baseColor); - StyleHelper::tintImage(m_segmentSelected, m_baseColor); - StyleHelper::tintImage(m_segmentHover, m_baseColor); - StyleHelper::tintImage(m_segment, m_baseColor); -} - -void CrumblePathButton::leaveEvent(QEvent *e) -{ - m_isHovering = false; - update(); - QPushButton::leaveEvent(e); + return pixmap; } -void CrumblePathButton::mouseMoveEvent(QMouseEvent *e) +void CrumblePathButton::paintEvent(QPaintEvent*) { - if (!isEnabled()) - return; - m_isHovering = true; - update(); - QPushButton::mouseMoveEvent(e); -} + QStyleOptionButton option; + initStyleOption(&option); + + const QPixmap pixmap = segmentPixmap(m_segmentType, option.state); + const int borderSize = 8; + const int overlapSize = 2; + const bool overlapLeft = + m_segmentType == MiddleSegment || m_segmentType == LastSegment; + const bool overlapRight = + m_segmentType == FirstSegment || m_segmentType == MiddleSegment; + QRect segmentRect = rect(); + segmentRect.setHeight(int(pixmap.height() / pixmap.devicePixelRatio())); + segmentRect.moveCenter(rect().center()); + segmentRect.adjust(overlapLeft ? -overlapSize : 0, 0, + overlapRight ? overlapSize : 0, 0); -void CrumblePathButton::mousePressEvent(QMouseEvent *e) -{ - if (!isEnabled()) - return; - m_isPressed = true; - update(); - QPushButton::mousePressEvent(e); -} - -void CrumblePathButton::mouseReleaseEvent(QMouseEvent *e) -{ - m_isPressed = false; - update(); - QPushButton::mouseReleaseEvent(e); -} - -void CrumblePathButton::changeEvent(QEvent *e) -{ - if (e && e->type() == QEvent::EnabledChange) - update(); + QPainter p(this); + StyleHelper::drawCornerImage(pixmap.toImage(), &p, segmentRect, borderSize, 0, borderSize, 0); + + const QPixmap middleSegmentPixmap = segmentPixmap(MiddleSegment, option.state); + const int middleSegmentPixmapWidth = + int(middleSegmentPixmap.width() / middleSegmentPixmap.devicePixelRatio()); + if (overlapLeft) + p.drawPixmap(-middleSegmentPixmapWidth + overlapSize, segmentRect.top(), middleSegmentPixmap); + if (overlapRight) + p.drawPixmap(width() - overlapSize, segmentRect.top(), middleSegmentPixmap); + + if (option.state & QStyle::State_Enabled) + option.palette.setColor(QPalette::ButtonText, creatorTheme()->color(Theme::PanelTextColorLight)); + else + option.palette.setColor(QPalette::Disabled, QPalette::ButtonText, creatorTheme()->color(Theme::IconsDisabledColor)); + + QStylePainter sp(this); + if (option.state & QStyle::State_Sunken) + sp.setOpacity(0.7); + sp.drawControl(QStyle::CE_PushButtonLabel, option); + if (option.features & QStyleOptionButton::HasMenu) { + option.rect = segmentRect.adjusted(segmentRect.width() - 18, 3, -10, 0); + StyleHelper::drawArrow(QStyle::PE_IndicatorArrowDown, &sp, &option); + } } -void CrumblePathButton::select(bool s) +void CrumblePathButton::setSegmentType(SegmentType type) { - m_isSelected = s; + m_segmentType = type; update(); } -void CrumblePathButton::setSegmentType(int type) -{ - bool useLeftPadding = !(type & FirstSegment); - m_isEnd = (type & LastSegment); - m_textPos.setX(useLeftPadding ? 18 : 4); -} - void CrumblePathButton::setData(const QVariant &data) { m_data = data; @@ -219,16 +163,21 @@ QVariant CrumblePathButton::data() const return m_data; } -/////////////////////////////////////////////////////////////////////////////// - -// -// CrumblePath -// CrumblePath::CrumblePath(QWidget *parent) : QWidget(parent) { - setMinimumHeight(25); - setMaximumHeight(25); - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + setMinimumHeight(24); + setMaximumHeight(24); + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + + auto layout = new QHBoxLayout(this); + m_buttonsLayout = new QHBoxLayout; + layout->addLayout(m_buttonsLayout); + layout->addStretch(1); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + setLayout(layout); + + setStyleSheet("QPushButton { margin: 12; }"); } CrumblePath::~CrumblePath() @@ -237,12 +186,6 @@ CrumblePath::~CrumblePath() m_buttons.clear(); } -void CrumblePath::selectIndex(int index) -{ - if (index > -1 && index < m_buttons.length()) - m_buttons[index]->select(true); -} - QVariant CrumblePath::dataForIndex(int index) const { if (index > -1 && index < m_buttons.length()) @@ -262,63 +205,35 @@ int CrumblePath::length() const return m_buttons.length(); } -bool lessThan(const QAction *a1, const QAction *a2) -{ - return a1->text() < a2->text(); -} - -bool greaterThan(const QAction *a1, const QAction *a2) -{ - return a1->text() > a2->text(); -} - -void CrumblePath::sortChildren(Qt::SortOrder order) -{ - QPushButton *lastButton = m_buttons.last(); - - QMenu *childList = lastButton->menu(); - QTC_ASSERT(childList, return); - QList actions = childList->actions(); - - std::stable_sort(actions.begin(), actions.end(), - order == Qt::AscendingOrder ? lessThan : greaterThan); - - childList->clear(); - childList->addActions(actions); -} - void CrumblePath::pushElement(const QString &title, const QVariant &data) { - CrumblePathButton *newButton = new CrumblePathButton(title, this); - newButton->hide(); + auto *newButton = new CrumblePathButton(title, this); + newButton->setData(data); + m_buttonsLayout->addWidget(newButton); connect(newButton, &QAbstractButton::clicked, this, &CrumblePath::emitElementClicked); - int segType = CrumblePathButton::MiddleSegment; - if (!m_buttons.isEmpty()) { - if (m_buttons.length() == 1) - segType = segType | CrumblePathButton::FirstSegment; - m_buttons.last()->setSegmentType(segType); + if (m_buttons.empty()) { + newButton->setSegmentType(CrumblePathButton::SingleSegment); } else { - segType = CrumblePathButton::FirstSegment | CrumblePathButton::LastSegment; - newButton->setSegmentType(segType); + m_buttons.last()->setSegmentType(m_buttons.count() > 1 + ? CrumblePathButton::MiddleSegment + : CrumblePathButton::FirstSegment); + newButton->setSegmentType(CrumblePathButton::LastSegment); } - newButton->setData(data); m_buttons.append(newButton); - - resizeButtons(); } void CrumblePath::addChild(const QString &title, const QVariant &data) { QTC_ASSERT(!m_buttons.isEmpty(), return); - QPushButton *lastButton = m_buttons.last(); + auto *lastButton = m_buttons.last(); QMenu *childList = lastButton->menu(); - if (childList == 0) + if (!childList) childList = new QMenu(lastButton); - QAction *childAction = new QAction(title, lastButton); + auto *childAction = new QAction(title, lastButton); childAction->setData(data); connect(childAction, &QAction::triggered, this, &CrumblePath::emitElementClicked); childList->addAction(childAction); @@ -327,18 +242,18 @@ void CrumblePath::addChild(const QString &title, const QVariant &data) void CrumblePath::popElement() { + if (m_buttons.isEmpty()) + return; + QWidget *last = m_buttons.last(); m_buttons.removeLast(); - last->setParent(0); + last->setParent(nullptr); last->deleteLater(); - int segType = CrumblePathButton::MiddleSegment | CrumblePathButton::LastSegment; - if (!m_buttons.isEmpty()) { - if (m_buttons.length() == 1) - segType = CrumblePathButton::FirstSegment | CrumblePathButton::LastSegment; - m_buttons.last()->setSegmentType(segType); - } - resizeButtons(); + if (!m_buttons.isEmpty()) + m_buttons.last()->setSegmentType(m_buttons.count() == 1 + ? CrumblePathButton::SingleSegment + : CrumblePathButton::LastSegment); } void CrumblePath::clear() @@ -347,67 +262,12 @@ void CrumblePath::clear() popElement(); } -void CrumblePath::resizeEvent(QResizeEvent *) -{ - resizeButtons(); -} - -void CrumblePath::resizeButtons() -{ - int totalWidthLeft = width(); - - if (!m_buttons.isEmpty()) { - QPoint nextElementPosition(0, 0); - - m_buttons.first()->raise(); - // rearrange all items so that the first item is on top (added last). - - // compute relative sizes - QList sizes; - int totalSize = 0; - sizes.reserve(m_buttons.length()); - for (int i = 0; i < m_buttons.length() ; ++i) { - CrumblePathButton *button = m_buttons.at(i); - - QFontMetrics fm(button->font()); - int originalSize = ArrowBorderSize + fm.width(button->text()) + ArrowBorderSize + 12; - sizes << originalSize; - totalSize += originalSize - ArrowBorderSize; - } - - for (int i = 0; i < m_buttons.length() ; ++i) { - CrumblePathButton *button = m_buttons.at(i); - - int candidateSize = (sizes.at(i) * totalWidthLeft) / totalSize; - if (candidateSize < ArrowBorderSize) - candidateSize = ArrowBorderSize; - if (candidateSize > sizes.at(i) * 1.3) - candidateSize = sizes.at(i) * 1.3; - - button->setMinimumWidth(candidateSize); - button->setMaximumWidth(candidateSize); - button->move(nextElementPosition); - - nextElementPosition.rx() += button->width() - ArrowBorderSize; - - button->show(); - if (i > 0) { - // work-around for a compiler / optimization bug in i686-apple-darwin9-g - // without volatile, the optimizer (-O2) seems to do the wrong thing (tm - // the m_buttons array with an invalid argument. - volatile int prevIndex = i - 1; - button->stackUnder(m_buttons[prevIndex]); - } - } - } -} - void CrumblePath::emitElementClicked() { QObject *element = sender(); - if (QAction *action = qobject_cast(element)) + if (auto *action = qobject_cast(element)) emit elementClicked(action->data()); - else if (CrumblePathButton *button = qobject_cast(element)) + else if (auto *button = qobject_cast(element)) emit elementClicked(button->data()); } diff --git a/src/libs/utils/crumblepath.h b/src/libs/utils/crumblepath.h index 32c10f15aa..7d1473fe04 100644 --- a/src/libs/utils/crumblepath.h +++ b/src/libs/utils/crumblepath.h @@ -27,8 +27,8 @@ #include "utils_global.h" -#include #include +#include namespace Utils { @@ -39,14 +39,12 @@ class QTCREATOR_UTILS_EXPORT CrumblePath : public QWidget Q_OBJECT public: - explicit CrumblePath(QWidget *parent = 0); + explicit CrumblePath(QWidget *parent = nullptr); ~CrumblePath(); - void selectIndex(int index); QVariant dataForIndex(int index) const; QVariant dataForLastIndex() const; int length() const; - void sortChildren(Qt::SortOrder order = Qt::AscendingOrder); public slots: void pushElement(const QString &title, const QVariant &data = QVariant()); @@ -57,16 +55,13 @@ public slots: signals: void elementClicked(const QVariant &data); -protected: - void resizeEvent(QResizeEvent *); - private: void emitElementClicked(); - void resizeButtons(); void setBackgroundStyle(); private: QList m_buttons; + QLayout *m_buttonsLayout = nullptr; }; } // namespace Utils diff --git a/src/libs/utils/images/crumblepath-segment-end.png b/src/libs/utils/images/crumblepath-segment-end.png deleted file mode 100644 index b472d595fbe51c3649496d775fcffd19ba568324..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^tUxTm!3HFa)Xf(FDb50q$YKTtZeb8+WSBKa0w}n~ z)5S4F<9z9a*IX?MA}#K#<(+KZzGT=I@e6V!)$iJ6-5$E-7NhN)^OoWvk1g1y6n!m? zm1tu;Cb8yqSLUn*Q-fBl;`(gk{l_cQs{iqX;(6*bxKo7WS==_fuP)+Nxv|YRsfopM zO{L}Ygte}hP2NOif8$hKGWk^T(w94f6Ylgjcs*TzF6QWh{kGjxhV wJKH+h$@ksauYRx1xGffY{a|%}YUCaEsx5-MmtAg31-hHT)78&qol`;+01gLW82|tP diff --git a/src/libs/utils/images/crumblepath-segment-first-hover.png b/src/libs/utils/images/crumblepath-segment-first-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..e3fa56580de3aee11351a04c9f968a65b88d718b GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^f973EseL1kFYy6OJGv`_U9ODyk7rAkfa4>QE#{unEt|{sEbIG{xpUWMlg> zSN?3zc0c!h>4MQyM2`|WBhmbpn7h=JCi3fcY=M}p>O_X}9f6pbzKFCG{RgrPXa&TS zR3I{SxpqKIN^K$o1y4XsSYskheGplAwE<%CDiir}T7N)HLR})C3fu3KxO(u=$Y~vb zEB4DRp=;_qg6gIugIud}?%!QGLIE_8B#xJZ4-$Rb^hT!v~4j cFIF?<3dpn_y4BJdLjV8(07*qoM6N<$f*jj(mH+?% literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment-first.png b/src/libs/utils/images/crumblepath-segment-first.png new file mode 100644 index 0000000000000000000000000000000000000000..063f9824fd63bc3ed0dede59f7629fe9b9dbb0e2 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^fx0+vYQQNuj_n`{ms*Dp0+ubVE*9Ew;Gu$^*J(6)f>Nv<=Pgg&ebxsLQ E0QYw|T>t<8 literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment-first@2x.png b/src/libs/utils/images/crumblepath-segment-first@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3b28155190be92a60eb3fdeb1417815be8c9c5ac GIT binary patch literal 281 zcmV+!0p|XRP)93Ay8;;Gqcjptv1<0vVrI$uhp+?ZQi9aRAD8OCaoZu*|-G3*g1)&nDLbj zGk?aDf8oq~-uKY~qpOH6CA>wV{wXnMc~_Fi#P6B{F?l&e1`4i$m?t%fG-U6A%q{%@ zF(qY){CYhLASSH}k)Es#5c8;SB43ITnFTclVv2etGIINtKukhaB5ghF?k928__-?} zZz|B}0yw%)J@YqqfOL5oQu^S<{0HJFOGgsY5J+7%U1LGKXhZh`&40`@_gBdC?*p??X&>vl$|<=ba8Xx3fiT^Un9u zk1ZCxug7r1&NWjxM(|S>RwRZ7wVeZT~=bSk+kWQy@oocoE znSEa&BJ85m=?K8h%?GFIp@XocVl?)9DoN z?(V)NlgT47L8H+SfK)1lgTVlwo}L6AA0Kfz9Ac$X`5uqQ<=X-#7l1?}!BZHI#~X}B zBkc8hST2`;M59s7x`2rVfc?a7x63Ds!3u?iLg8mP95$>3rBX=%*bi(roA~hXAPNau ztrli7ndhskD;o*2*{lGtLA<}e$6Bqn6Lu>6%j)&w_xnApxUd4)02YfyWVXHJ^Lajx zQug_LZzGWi5a9KC4-#xkE-o(K2Lb^Ax7$rcq8tw*m&@__l)A^``3NqTi<`GwdLJaA z<7ZJII2;Z>@V^39z~2I!&BpVimOca$P{hGt5YNxgKY_(!;ki*u{|ge(?yUOgbUHui zbUFZ|(Z~f9(mv?cQl!*)EbVt1jRpwN>-9XWLl%cZA++1=1C>ezE8yhhgoj2|6@x;j z2(PcN@$BrZPOU7L%LPEI)$$$07Sry37B8(X$ENJ-8 z^Z)VX@5+o5PFSAYo1ygIH~ONhSoDJKKO)f`YM=I7iNroxc_7SW;(tcg7fQdUaCZL? zUo`tne_m0jMjN;I!cLt{F5g=@cln?9T-fd=Q`M2k8Ct@?u*L1cACDad9|S3j3^ HP69-!`#`#0u3o=1d>wOuwVnsho}JpHeRYP9{>vtvXg)bb~Xb;;S*q&Y=lH{ z!<%B2|Jm@)zwO!X=e{l(j>3>YJI74+lSX2X%D(?Kzho6XcmiTo`9wZ+{0hX*)g;oF z_XgxUsSXf(P@c%wVPpWr%DN&lQ+y1>GP)(w(IOGafd*xs2Y(#iOK$? zpc{DT({V>Y>bj)W#c*|9o$)u`0h#hK_`2r9d;xN=3kt~zhU8fur7@=#kU7V`g5|M1 n!U}3*k!?~~hapP!KiYc>&Zq&rf02q%00000NkvXXu0mjf0Y`l> literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment-last.png b/src/libs/utils/images/crumblepath-segment-last.png new file mode 100644 index 0000000000000000000000000000000000000000..b69cc0a93f0df4b8fbbfcd917b6f97b67b002f98 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^fX$ENJ-8 z^Iv$?d_~3yCoE?k&rte*R(wIXPMM4NPt7_G-zW9HT)R#LADj)8XufsP^;@QZ80VV< z20z7Sd6a6kaq}IDNs=QBCIZCxT_Ae%j1{an^L HB{Ts5%E&pf literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment-last@2x.png b/src/libs/utils/images/crumblepath-segment-last@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..60bb6a51a801db8942986223e088e39127fa5059 GIT binary patch literal 290 zcmV+-0p0$IP)e9cr`H&~CNpVylF;!s^FNXWCi$19W6DbR@BsE-Wk(j5S## zb-P&gm2l=K`I7tHdt?|LL%RAmX0qK45_{9b>QMG%ec>1Yv5c}rzU7+%v3pgCd?>sG zvJI*Y#9ovjvU0n=fLKyRB7FtsKrEs8>Sso;8Vuhaq3QkbssPBkDSKKp0opgexO oSV6CfL6QAlV;vq*s^@6$Klt%@#_C9*R{#J207*qoM6N<$f~Vhn^Z)<= literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment-middle-hover.png b/src/libs/utils/images/crumblepath-segment-middle-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..01e45c2e94bcc129d5333feab6552224db844c1f GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^f;;GJS02JhXha!a_w>eqKqBj3Wn~&#Yz+U$Kap;mTqD Us(&%(r9jU1boFyt=akR{0Q4$U+5i9m literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment-middle-hover@2x.png b/src/libs/utils/images/crumblepath-segment-middle-hover@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..58f07fcfd910210507e3a5d43094095663529468 GIT binary patch literal 438 zcmV;n0ZIOeP)XD3CIngIc4u zqN&GHLxI)$zvmoKp)>#ZzI(qHe%n5DLJX*$t3{+WqcjF5%EQ|bUjhLp?*o=yk(~5d z?)Y=#2uoo?NHV#_;HgMp1KgrhE!A|}4L({o5mVO*#(DZ?X?6nsoR9VmlWSe1dA`6O>aNvULQz gJBJ+{)&IEOe~@852`Qr5!wIDw`f58JYZA8!s3q;;6q4HX;lhOG7PlH+AI}Q)bpfvI Y414?4KPV>nJ^(r0)78&qol`;+0C6}}sQ>@~ literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment-middle@2x.png b/src/libs/utils/images/crumblepath-segment-middle@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..909ca22e62c60d83de5d39c6b322795b85e2d37f GIT binary patch literal 445 zcmV;u0Yd(XP)g}Xi%oX4Fhv*CNYRbED)rLVg<1ZR>3S#MW}9K5(~l2BF>pqEdHAq zm`L(Z(V!b@{oXxq15WhmQw8nHznGeds*HkMBKa-Ch!^P2Dj2M*qy)z|-}D4>B4!*#CIxr|NyE$JYXC0P>q-M0-sN~#eedWOnASq&e$S^5mw4st+I9uHjKT_hLS!C&;N2BFd=X2kP ztYKM%tRTv*>(^;rpQd$rOo@;!%xJH1N9P*%iJa&R!+~}f7O*Zt=CP?A%qvw?&87yC zl+Jj^vB-~P7>BB;58;%^9$X@18*YA$(?|<4i2{*o`)41)st8#^f|kd-O|GCjt7Zjd nFegGb5a@0lcCb|2RtMxCtwo>Gjwb4w00000NkvXXu0mjfAj!Ti literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment-selected-end.png b/src/libs/utils/images/crumblepath-segment-selected-end.png deleted file mode 100644 index 8e79c969e377666f0e47cfdb79cf8d35fbb3afeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^tUxTm!3HFa)Xf(FDb50q$YKTtZeb8+WSBKa0w}n^ z)5S4F<9u$QBi|7P4wp4@e^$i5U)Xsudhy!ZiU(h8Q&BK7cDQmx!g}qrpZoHQ&INKb z?)lzgEuGvkQ*)`ywJ3vLgY~ba^n6+*Cn!z2cI!}@Z`NAoCp#A$<$Y-5ueJ0<)_FE* z=C^yh54Y89GmMS2Sju5JX?jex-kF=z9QB{+#8>HE7PR|*Wop}>`J4}`ciC<7n!m^R k-X{ybpC@bYYd*hI7i7qu86I>p2Iy7>Pgg&ebxsLQ0B}TG*#H0l diff --git a/src/libs/utils/images/crumblepath-segment-selected.png b/src/libs/utils/images/crumblepath-segment-selected.png deleted file mode 100644 index d6115fc968f2e39878faf91556415d89d289d016..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 611 zcmV-p0-XJcP))B;In$Y-UI$# z0D!9a=C=fX2Y~zuVFMA{lV{FxB%5^6&8yHWV2Z&0xpd=8yX=c!OAd_4)E!IQ}ZVzJnsa=9E#r&DOPTF>}=bre7Y@yrkk zg$_i!8IQ-%Y&Kug>9kH1fPX;0-v__nFRExX3d7+L>h=0-B9X8i0PrKU+ih^W-A5G+ z2BF*S0{Zoaz`!1WR-pQuOs11^I2_PuG?+KxaQJ2iAUY4=UkG~iivj4Ilm(;F$R)eo zPJRF#JrD@o2_BD!g@+eF^7(u$D^w}L>2#7g{{`@Ry?`lw2iR;j_F^y?xMZ1bNkko250%IE!I7FvZ2UiGFBEclSEY^QzMbc8yfiiY)g|$rK|%fl}aYc xI_CTpck+#^sY)agph}>_Oqj0U2vG61^}kaFNHe7FPqP33002ovPDHLkV1k&C5$FH_ diff --git a/src/libs/utils/images/crumblepath-segment-single-hover.png b/src/libs/utils/images/crumblepath-segment-single-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..886ea79b391aed55d90f2128641906964b337879 GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^fL zBjf4f7{Vc&9Kp)M%frjV<8VhxO3F!JC`tK78AGkIPJ5AVd@E2LgQu&X%Q~loCIHxq B8SnrA literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment-single-hover@2x.png b/src/libs/utils/images/crumblepath-segment-single-hover@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3eb0d983ee57440c2d42e6bd3379bf76e2ee1f72 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^Nh%1oZzkmP#|Nr+NUtbO6 zD0#X#hDd}bN3gPTO9-rCE&#Kqd&5Gd9g8F5I?TZWNgSKgeR;kogWK-CPMu6{1- HoD!MKTINXtvl5)})N>aX2#!#!Q(_W+--wIU6;OXk;vd$@?2>_-^ B82tbM literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment-single@2x.png b/src/libs/utils/images/crumblepath-segment-single@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d5403611464dddd1157af2adacfdd043080012c0 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^Nh%1nO_UzgJ|Nq4uq^|)v zN}eu`Arj%q5v;7-5&~;jc?22`aj`Zx1d8=WMjVp!mSJSrl{aT+cy7ETP&I?6tDnm{ Hr-UW|V9Fc~ literal 0 HcmV?d00001 diff --git a/src/libs/utils/images/crumblepath-segment.png b/src/libs/utils/images/crumblepath-segment.png deleted file mode 100644 index 7fa41efe2921d24e939bc9bf692e2810d7d439dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 666 zcmV;L0%iS)P)KP()D?39h>6zR+J#=>I8&(nX^EsC;Rt=20j83%&_HX4n;sZ`3k7N9i=paoHKwOZXvv)L5h zR4SF{L?Yp00g6ii1$lHxh8={*%ifS*FW1-CL5jf|pa9ltHH=21N8yd?^*VCPkx1lY zI-LdvLZQ$}0=pvNaQJg976Z7tx)QyT>Pf`oaj_wb1%tt_;Pd&|AXYpXHlD}N|H0$& z2$TL-fXx*GE|&}WII|b0z+Ui%+{)$UZ~H&>WUCh_9p zqQ^&BsZ>gU!C(+0c_Vq{bUIt>%cM{!BtWOrA>DcO`~6$6X`D=Mug=fUbDP&$CX-2k zR;zs_uui6X-RnF`o6HkIc6VzpX7?0eF-1XL=OFo+Kn!;aHA zf3{dGrbCbFmVjI?N1g;ZETAfWkbvRXv%V?t4-iBCo29K3(EtDd07*qoM6N<$f(V)~ ASpWb4 diff --git a/src/libs/utils/images/triangle_vert.png b/src/libs/utils/images/triangle_vert.png deleted file mode 100644 index b85dafda5906d8a872a9791fdb5b27d84236ecf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>0wld=oSO}#q&;06LpZJ{Cn#{O`Q6WF$YL0h hlyTf(a-#|ZLq(qEGt+y2F9DS?c)I$ztaD0e0s!zm77zdc diff --git a/src/libs/utils/utils.qrc b/src/libs/utils/utils.qrc index 061d42b285..60894bf88d 100644 --- a/src/libs/utils/utils.qrc +++ b/src/libs/utils/utils.qrc @@ -1,19 +1,28 @@ images/arrow.png - images/crumblepath-segment.png - images/crumblepath-segment-end.png - images/crumblepath-segment-hover-end.png - images/crumblepath-segment-hover.png - images/crumblepath-segment-selected-end.png - images/crumblepath-segment-selected.png + images/crumblepath-segment-first.png + images/crumblepath-segment-first-hover.png + images/crumblepath-segment-first@2x.png + images/crumblepath-segment-first-hover@2x.png + images/crumblepath-segment-middle.png + images/crumblepath-segment-middle-hover.png + images/crumblepath-segment-middle@2x.png + images/crumblepath-segment-middle-hover@2x.png + images/crumblepath-segment-last.png + images/crumblepath-segment-last-hover.png + images/crumblepath-segment-last@2x.png + images/crumblepath-segment-last-hover@2x.png + images/crumblepath-segment-single.png + images/crumblepath-segment-single-hover.png + images/crumblepath-segment-single@2x.png + images/crumblepath-segment-single-hover@2x.png images/progressindicator_big.png images/progressindicator_big@2x.png images/progressindicator_medium.png images/progressindicator_medium@2x.png images/progressindicator_small.png images/progressindicator_small@2x.png - images/triangle_vert.png images/next.png images/next@2x.png images/prev.png diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg index 5718af9f73..2fd16a1b7a 100644 --- a/src/tools/icons/qtcreatoricons.svg +++ b/src/tools/icons/qtcreatoricons.svg @@ -476,6 +476,26 @@ y1="73.5" x2="510.75" y2="75.5" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +