diff options
Diffstat (limited to 'src/libs/utils')
-rw-r--r-- | src/libs/utils/detailsbutton.cpp | 54 | ||||
-rw-r--r-- | src/libs/utils/detailswidget.cpp | 32 | ||||
-rw-r--r-- | src/libs/utils/outputformatter.cpp | 21 | ||||
-rw-r--r-- | src/libs/utils/outputformatter.h | 2 | ||||
-rw-r--r-- | src/libs/utils/theme/theme.cpp | 356 | ||||
-rw-r--r-- | src/libs/utils/theme/theme.h | 217 | ||||
-rw-r--r-- | src/libs/utils/theme/theme_p.cpp | 47 | ||||
-rw-r--r-- | src/libs/utils/theme/theme_p.h | 59 | ||||
-rw-r--r-- | src/libs/utils/theme/welcometheme.cpp | 87 | ||||
-rw-r--r-- | src/libs/utils/theme/welcometheme.h | 87 | ||||
-rw-r--r-- | src/libs/utils/utils-lib.pri | 10 | ||||
-rw-r--r-- | src/libs/utils/utils.qbs | 13 |
12 files changed, 932 insertions, 53 deletions
diff --git a/src/libs/utils/detailsbutton.cpp b/src/libs/utils/detailsbutton.cpp index cfbfc1044f..3e36c12cb4 100644 --- a/src/libs/utils/detailsbutton.cpp +++ b/src/libs/utils/detailsbutton.cpp @@ -29,8 +29,8 @@ ****************************************************************************/ #include "detailsbutton.h" - -#include <utils/hostosinfo.h> +#include "hostosinfo.h" +#include "theme/theme.h" #include <QGraphicsOpacityEffect> #include <QGuiApplication> @@ -122,8 +122,15 @@ void DetailsButton::paintEvent(QPaintEvent *e) QPainter p(this); // draw hover animation - if (!HostOsInfo::isMacHost() && !isDown() && m_fader > 0) - p.fillRect(rect().adjusted(1, 1, -2, -2), QColor(255, 255, 255, int(m_fader*180))); + if (!HostOsInfo::isMacHost() && !isDown() && m_fader > 0) { + QColor c = creatorTheme()->color(Theme::DetailsButtonBackgroundColorHover); + c.setAlpha (int(m_fader * c.alpha())); + + QRect r = rect(); + if (creatorTheme()->widgetStyle() == Theme::StyleDefault) + r.adjust(1, 1, -2, -2); + p.fillRect(r, c); + } if (isChecked()) { if (m_checkedPixmap.isNull() || m_checkedPixmap.size() / m_checkedPixmap.devicePixelRatio() != contentsRect().size()) @@ -148,10 +155,6 @@ void DetailsButton::paintEvent(QPaintEvent *e) QPixmap DetailsButton::cacheRendering(const QSize &size, bool checked) { - QLinearGradient lg; - lg.setCoordinateMode(QGradient::ObjectBoundingMode); - lg.setFinalStop(0, 1); - const qreal pixelRatio = devicePixelRatio(); QPixmap pixmap(size * pixelRatio); pixmap.setDevicePixelRatio(pixelRatio); @@ -159,23 +162,30 @@ QPixmap DetailsButton::cacheRendering(const QSize &size, bool checked) QPainter p(&pixmap); p.setRenderHint(QPainter::Antialiasing, true); p.translate(0.5, 0.5); - p.setPen(Qt::NoPen); - if (!checked) { - lg.setColorAt(0, QColor(0, 0, 0, 10)); - lg.setColorAt(1, QColor(0, 0, 0, 16)); + + if (creatorTheme()->widgetStyle() == Theme::StyleDefault) { + QLinearGradient lg; + lg.setCoordinateMode(QGradient::ObjectBoundingMode); + lg.setFinalStop(0, 1); + if (!checked) { + lg.setColorAt(0, QColor(0, 0, 0, 10)); + lg.setColorAt(1, QColor(0, 0, 0, 16)); + } else { + lg.setColorAt(0, QColor(255, 255, 255, 0)); + lg.setColorAt(1, QColor(255, 255, 255, 50)); + } + p.setBrush(lg); + p.setPen(QColor(255,255,255,140)); + p.drawRoundedRect(1, 1, size.width()-3, size.height()-3, 1, 1); + p.setPen(QPen(QColor(0, 0, 0, 40))); + p.drawLine(0, 1, 0, size.height() - 2); + if (checked) + p.drawLine(1, size.height() - 1, size.width() - 1, size.height() - 1); } else { - lg.setColorAt(0, QColor(255, 255, 255, 0)); - lg.setColorAt(1, QColor(255, 255, 255, 50)); + p.setPen(Qt::NoPen); + p.drawRoundedRect(0, 0, size.width(), size.height(), 1, 1); } - p.setBrush(lg); - p.setPen(QColor(255,255,255,140)); - p.drawRoundedRect(1, 1, size.width()-3, size.height()-3, 1, 1); - p.setPen(QPen(QColor(0, 0, 0, 40))); - p.drawLine(0, 1, 0, size.height() - 2); - if (checked) - p.drawLine(1, size.height() - 1, size.width() - 1, size.height() - 1); - p.setPen(palette().color(QPalette::Text)); QRect textRect = p.fontMetrics().boundingRect(text()); diff --git a/src/libs/utils/detailswidget.cpp b/src/libs/utils/detailswidget.cpp index 68320d76c5..5218916cf7 100644 --- a/src/libs/utils/detailswidget.cpp +++ b/src/libs/utils/detailswidget.cpp @@ -31,6 +31,7 @@ #include "detailswidget.h" #include "detailsbutton.h" #include "hostosinfo.h" +#include "theme/theme.h" #include <QGridLayout> #include <QLabel> @@ -148,21 +149,22 @@ QPixmap DetailsWidget::createBackground(const QSize &size, int topHeight, QWidge if (HostOsInfo::isMacHost()) p.fillRect(fullRect, qApp->palette().window().color()); else - p.fillRect(fullRect, QColor(255, 255, 255, 40)); - - QLinearGradient lg(topRect.topLeft(), topRect.bottomLeft()); - lg.setColorAt(0, QColor(255, 255, 255, 130)); - lg.setColorAt(1, QColor(255, 255, 255, 0)); - p.fillRect(topRect, lg); - p.setRenderHint(QPainter::Antialiasing, true); - p.translate(0.5, 0.5); - p.setPen(QColor(0, 0, 0, 40)); - p.setBrush(Qt::NoBrush); - p.drawRoundedRect(fullRect.adjusted(0, 0, -1, -1), 2, 2); - p.setBrush(Qt::NoBrush); - p.setPen(QColor(255,255,255,140)); - p.drawRoundedRect(fullRect.adjusted(1, 1, -2, -2), 2, 2); - p.setPen(QPen(widget->palette().color(QPalette::Mid))); + p.fillRect(fullRect, creatorTheme()->color(Theme::DetailsWidgetBackgroundColor)); + + if (creatorTheme()->widgetStyle () == Theme::StyleDefault) { + QLinearGradient lg(topRect.topLeft(), topRect.bottomLeft()); + lg.setStops(creatorTheme()->gradient(Theme::DetailsWidgetHeaderGradient)); + p.fillRect(topRect, lg); + p.setRenderHint(QPainter::Antialiasing, true); + p.translate(0.5, 0.5); + p.setPen(QColor(0, 0, 0, 40)); + p.setBrush(Qt::NoBrush); + p.drawRoundedRect(fullRect.adjusted(0, 0, -1, -1), 2, 2); + p.setBrush(Qt::NoBrush); + p.setPen(QColor(255,255,255,140)); + p.drawRoundedRect(fullRect.adjusted(1, 1, -2, -2), 2, 2); + p.setPen(QPen(widget->palette().color(QPalette::Mid))); + } return pixmap; } diff --git a/src/libs/utils/outputformatter.cpp b/src/libs/utils/outputformatter.cpp index 5d952d2ed9..ca745e3f8a 100644 --- a/src/libs/utils/outputformatter.cpp +++ b/src/libs/utils/outputformatter.cpp @@ -28,10 +28,11 @@ ** ****************************************************************************/ +#include "ansiescapecodehandler.h" #include "outputformatter.h" +#include "theme/theme.h" #include <QPlainTextEdit> -#include <utils/ansiescapecodehandler.h> using namespace Utils; @@ -110,12 +111,6 @@ void OutputFormatter::clearLastLine() cursor.removeSelectedText(); } -QColor OutputFormatter::mixColors(const QColor &a, const QColor &b) -{ - return QColor((a.red() + 2 * b.red()) / 3, (a.green() + 2 * b.green()) / 3, - (a.blue() + 2* b.blue()) / 3, (a.alpha() + 2 * b.alpha()) / 3); -} - void OutputFormatter::initFormats() { if (!plainTextEdit()) @@ -127,26 +122,28 @@ void OutputFormatter::initFormats() m_formats = new QTextCharFormat[NumberOfFormats]; + Theme *theme = creatorTheme(); + // NormalMessageFormat m_formats[NormalMessageFormat].setFont(boldFont); - m_formats[NormalMessageFormat].setForeground(mixColors(p.color(QPalette::Text), QColor(Qt::blue))); + m_formats[NormalMessageFormat].setForeground(theme->color(Theme::OutputFormatter_NormalMessageTextColor)); // ErrorMessageFormat m_formats[ErrorMessageFormat].setFont(boldFont); - m_formats[ErrorMessageFormat].setForeground(mixColors(p.color(QPalette::Text), QColor(Qt::red))); + m_formats[ErrorMessageFormat].setForeground(theme->color(Theme::OutputFormatter_ErrorMessageTextColor)); // StdOutFormat m_formats[StdOutFormat].setFont(m_font); - m_formats[StdOutFormat].setForeground(p.color(QPalette::Text)); + m_formats[StdOutFormat].setForeground(theme->color(Theme::OutputFormatter_StdOutTextColor)); m_formats[StdOutFormatSameLine] = m_formats[StdOutFormat]; // StdErrFormat m_formats[StdErrFormat].setFont(m_font); - m_formats[StdErrFormat].setForeground(mixColors(p.color(QPalette::Text), QColor(Qt::red))); + m_formats[StdErrFormat].setForeground(theme->color(Theme::OutputFormatter_StdErrTextColor)); m_formats[StdErrFormatSameLine] = m_formats[StdErrFormat]; m_formats[DebugFormat].setFont(m_font); - m_formats[DebugFormat].setForeground(mixColors(p.color(QPalette::Text), QColor(Qt::magenta))); + m_formats[DebugFormat].setForeground(theme->color(Theme::OutputFormatter_DebugTextColor)); } void OutputFormatter::handleLink(const QString &href) diff --git a/src/libs/utils/outputformatter.h b/src/libs/utils/outputformatter.h index 2f29a195bf..6dba8e5f10 100644 --- a/src/libs/utils/outputformatter.h +++ b/src/libs/utils/outputformatter.h @@ -73,8 +73,6 @@ protected: QTextCharFormat charFormat(OutputFormat format) const; void append(QTextCursor &cursor, const QString &text, const QTextCharFormat &format); - static QColor mixColors(const QColor &a, const QColor &b); - private: QPlainTextEdit *m_plainTextEdit; QTextCharFormat *m_formats; diff --git a/src/libs/utils/theme/theme.cpp b/src/libs/utils/theme/theme.cpp new file mode 100644 index 0000000000..97d1627115 --- /dev/null +++ b/src/libs/utils/theme/theme.cpp @@ -0,0 +1,356 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>. +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "theme.h" +#include "theme_p.h" +#include "qtcassert.h" + +#include <QApplication> +#include <QFileInfo> +#include <QMetaEnum> +#include <QSettings> + +namespace Utils { + +static Theme *m_creatorTheme = 0; + +Theme *creatorTheme() +{ + return m_creatorTheme; +} + +void setCreatorTheme(Theme *theme) +{ + // TODO: memory management of theme object + m_creatorTheme = theme; +} + +Theme::Theme(QObject *parent) + : QObject(parent) + , d(new ThemePrivate) +{ +} + +Theme::~Theme() +{ + delete d; +} + +void Theme::drawIndicatorBranch(QPainter *painter, const QRect &rect, QStyle::State state) const +{ + Q_UNUSED(painter); + Q_UNUSED(rect); + Q_UNUSED(state); +} + +Theme::WidgetStyle Theme::widgetStyle() const +{ + return d->widgetStyle; +} + +bool Theme::flag(Theme::Flag f) const +{ + return d->flags[f]; +} + +QColor Theme::color(Theme::ColorRole role) const +{ + return d->colors[role].first; +} + +QGradientStops Theme::gradient(Theme::GradientRole role) const +{ + return d->gradientStops[role]; +} + +QString Theme::iconOverlay(Theme::MimeType mimetype) const +{ + return d->iconOverlays[mimetype]; +} + +QString Theme::dpiSpecificImageFile(const QString &fileName) const +{ + return dpiSpecificImageFile(fileName, QLatin1String("")); +} + +QString Theme::dpiSpecificImageFile(const QString &fileName, const QString &themePrefix) const +{ + // See QIcon::addFile() + const QFileInfo fi(fileName); + + bool at2x = (qApp->devicePixelRatio() > 1.0); + + const QString at2xFileName = fi.path() + QStringLiteral("/") + + fi.completeBaseName() + QStringLiteral("@2x.") + fi.suffix(); + const QString themedAt2xFileName = fi.path() + QStringLiteral("/") + themePrefix + + fi.completeBaseName() + QStringLiteral("@2x.") + fi.suffix(); + const QString themedFileName = fi.path() + QStringLiteral("/") + themePrefix + + fi.completeBaseName() + QStringLiteral(".") + fi.suffix(); + + if (at2x) { + if (QFile::exists(themedAt2xFileName)) + return themedAt2xFileName; + else if (QFile::exists(themedFileName)) + return themedFileName; + else if (QFile::exists(at2xFileName)) + return at2xFileName; + return fileName; + } else { + if (QFile::exists(themedFileName)) + return themedFileName; + return fileName; + } +} + +QPair<QColor, QString> Theme::readNamedColor(const QString &color) const +{ + if (d->palette.contains(color)) + return qMakePair(d->palette[color], color); + + bool ok = true; + const QRgb rgba = color.toLongLong(&ok, 16); + if (!ok) { + qWarning("Color '%s' is neither a named color nor a valid color", qPrintable(color)); + return qMakePair(Qt::black, QString()); + } + return qMakePair(QColor::fromRgba(rgba), QString()); +} + +QString Theme::imageFile(const QString &fileName) const +{ + return fileName; +} + +QString Theme::fileName() const +{ + return d->fileName; +} + +void Theme::setName(const QString &name) +{ + d->name = name; +} + +static QColor readColor(const QString &color) +{ + bool ok = true; + const QRgb rgba = color.toLongLong(&ok, 16); + return QColor::fromRgba(rgba); +} + +static QString writeColor(const QColor &color) +{ + return QString::number(color.rgba(), 16); +} + +// reading, writing of .creatortheme ini file //////////////////////////////// +void Theme::writeSettings(const QString &filename) const +{ + QSettings settings(filename, QSettings::IniFormat); + + const QMetaObject &m = *metaObject(); + { + settings.setValue(QLatin1String("ThemeName"), d->name); + } + { + settings.beginGroup(QLatin1String("Palette")); + for (int i = 0, total = d->colors.size(); i < total; ++i) { + const QPair<QColor, QString> var = d->colors[i]; + if (var.second.isEmpty()) + continue; + settings.setValue(var.second, writeColor(var.first)); + } + settings.endGroup(); + } + { + settings.beginGroup(QLatin1String("Colors")); + const QMetaEnum e = m.enumerator(m.indexOfEnumerator("ColorRole")); + for (int i = 0, total = e.keyCount(); i < total; ++i) { + const QString key = QLatin1String(e.key(i)); + const QPair<QColor, QString> var = d->colors[i]; + if (!var.second.isEmpty()) + settings.setValue(key, var.second); // named color + else + settings.setValue(key, writeColor(var.first)); + } + settings.endGroup(); + } + { + settings.beginGroup(QLatin1String("Gradients")); + const QMetaEnum e = m.enumerator(m.indexOfEnumerator("GradientRole")); + for (int i = 0, total = e.keyCount(); i < total; ++i) { + const QString key = QLatin1String(e.key(i)); + QGradientStops stops = gradient(static_cast<Theme::GradientRole>(i)); + settings.beginWriteArray(key); + int k = 0; + foreach (const QGradientStop stop, stops) { + settings.setArrayIndex(k); + settings.setValue(QLatin1String("pos"), stop.first); + settings.setValue(QLatin1String("color"), writeColor(stop.second)); + ++k; + } + settings.endArray(); + } + settings.endGroup(); + } + { + settings.beginGroup(QLatin1String("IconOverlay")); + const QMetaEnum e = m.enumerator(m.indexOfEnumerator("MimeType")); + for (int i = 0, total = e.keyCount(); i < total; ++i) { + const QString key = QLatin1String(e.key(i)); + settings.setValue(key, iconOverlay(static_cast<Theme::MimeType>(i))); + } + settings.endGroup(); + } + { + settings.beginGroup(QLatin1String("Flags")); + const QMetaEnum e = m.enumerator(m.indexOfEnumerator("Flag")); + for (int i = 0, total = e.keyCount(); i < total; ++i) { + const QString key = QLatin1String(e.key(i)); + settings.setValue(key, flag(static_cast<Theme::Flag>(i))); + } + settings.endGroup(); + } + + { + settings.beginGroup(QLatin1String("Style")); + const QMetaEnum e = m.enumerator(m.indexOfEnumerator("WidgetStyle")); + settings.setValue(QLatin1String("WidgetStyle"), QLatin1String(e.valueToKey(widgetStyle ()))); + settings.endGroup(); + } +} + +void Theme::readSettings(QSettings &settings) +{ + d->fileName = settings.fileName(); + const QMetaObject &m = *metaObject(); + + { + d->name = settings.value(QLatin1String("ThemeName"), QLatin1String("unnamed")).toString(); + } + { + settings.beginGroup(QLatin1String("Palette")); + foreach (const QString &key, settings.allKeys()) { + QColor c = readColor(settings.value(key).toString()); + d->palette[key] = c; + } + settings.endGroup(); + } + { + settings.beginGroup(QLatin1String("Style")); + QMetaEnum e = m.enumerator(m.indexOfEnumerator("WidgetStyle")); + QString val = settings.value(QLatin1String("WidgetStyle")).toString(); + d->widgetStyle = static_cast<Theme::WidgetStyle>(e.keysToValue (val.toLatin1().data())); + settings.endGroup(); + } + { + settings.beginGroup(QLatin1String("Colors")); + QMetaEnum e = m.enumerator(m.indexOfEnumerator("ColorRole")); + for (int i = 0, total = e.keyCount(); i < total; ++i) { + const QString key = QLatin1String(e.key(i)); + QTC_ASSERT(settings.contains(key), return);; + d->colors[i] = readNamedColor(settings.value(key).toString()); + } + settings.endGroup(); + } + { + settings.beginGroup(QLatin1String("Gradients")); + QMetaEnum e = m.enumerator(m.indexOfEnumerator("GradientRole")); + for (int i = 0, total = e.keyCount(); i < total; ++i) { + const QString key = QLatin1String(e.key(i)); + QGradientStops stops; + int size = settings.beginReadArray(key); + for (int j = 0; j < size; ++j) { + settings.setArrayIndex(j); + QTC_ASSERT(settings.contains(QLatin1String("pos")), return);; + double pos = settings.value(QLatin1String("pos")).toDouble(); + QTC_ASSERT(settings.contains(QLatin1String("color")), return);; + QColor c = readColor(settings.value(QLatin1String("color")).toString()); + stops.append(qMakePair(pos, c)); + } + settings.endArray(); + d->gradientStops[i] = stops; + } + settings.endGroup(); + } + { + settings.beginGroup(QLatin1String("IconOverlay")); + QMetaEnum e = m.enumerator(m.indexOfEnumerator("MimeType")); + for (int i = 0, total = e.keyCount(); i < total; ++i) { + const QString key = QLatin1String(e.key(i)); + QTC_ASSERT(settings.contains(key), return);; + d->iconOverlays[i] = settings.value(key).toString(); + } + settings.endGroup(); + } + { + settings.beginGroup(QLatin1String("Flags")); + QMetaEnum e = m.enumerator(m.indexOfEnumerator("Flag")); + for (int i = 0, total = e.keyCount(); i < total; ++i) { + const QString key = QLatin1String(e.key(i)); + QTC_ASSERT(settings.contains(key), return);; + d->flags[i] = settings.value(key).toBool(); + } + settings.endGroup(); + } +} + +QIcon Theme::standardIcon(QStyle::StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const +{ + Q_UNUSED(standardPixmap); + Q_UNUSED(opt); + Q_UNUSED(widget); + return QIcon(); +} + +QPalette Theme::palette(const QPalette &base) const +{ + if (!flag(DerivePaletteFromTheme)) + return base; + + // FIXME: introduce some more color roles for this + + QPalette pal = base; + pal.setColor(QPalette::All, QPalette::Window, color(Theme::BackgroundColorNormal)); + pal.setBrush(QPalette::All, QPalette::WindowText, color(Theme::TextColorNormal)); + pal.setColor(QPalette::All, QPalette::Base, color(Theme::BackgroundColorNormal)); + pal.setColor(QPalette::All, QPalette::AlternateBase, color(Theme::BackgroundColorAlternate)); + pal.setColor(QPalette::All, QPalette::Button, color(Theme::BackgroundColorDark)); + pal.setColor(QPalette::All, QPalette::BrightText, Qt::red); + pal.setBrush(QPalette::All, QPalette::Text, color(Theme::TextColorNormal)); + pal.setBrush(QPalette::All, QPalette::ButtonText, color(Theme::TextColorNormal)); + pal.setBrush(QPalette::All, QPalette::ToolTipBase, color(Theme::BackgroundColorSelected)); + pal.setColor(QPalette::Highlight, color(Theme::BackgroundColorSelected)); + pal.setColor(QPalette::HighlightedText, Qt::white); + pal.setColor(QPalette::ToolTipText, color(Theme::TextColorNormal)); + return pal; +} + +} // namespace Utils diff --git a/src/libs/utils/theme/theme.h b/src/libs/utils/theme/theme.h new file mode 100644 index 0000000000..4a55bdc409 --- /dev/null +++ b/src/libs/utils/theme/theme.h @@ -0,0 +1,217 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>. +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef THEME_H +#define THEME_H + +#include "../utils_global.h" + +#include <QStyle> +#include <QFlags> + +QT_FORWARD_DECLARE_CLASS(QSettings) + +namespace Utils { + +class ThemePrivate; + +class QTCREATOR_UTILS_EXPORT Theme : public QObject +{ + Q_OBJECT + + Q_ENUMS(ColorRole) + Q_ENUMS(GradientRole) + Q_ENUMS(MimeType) + Q_ENUMS(Flag) + Q_ENUMS(WidgetStyle) + +public: + Theme(QObject *parent = 0); + ~Theme(); + + enum ColorRole { + BackgroundColorAlternate, + BackgroundColorDark, + BackgroundColorHover, + BackgroundColorNormal, + BackgroundColorSelected, + BadgeLabelBackgroundColorChecked, + BadgeLabelBackgroundColorUnchecked, + BadgeLabelTextColorChecked, + BadgeLabelTextColorUnchecked, + CanceledSearchTextColor, + ComboBoxArrowColor, + ComboBoxArrowColorDisabled, + ComboBoxTextColor, + DetailsWidgetBackgroundColor, + DetailsButtonBackgroundColorHover, + DockWidgetResizeHandleColor, + DoubleTabWidget1stEmptyAreaBackgroundColor, + DoubleTabWidget1stSeparatorColor, + DoubleTabWidget2ndSeparatorColor, + DoubleTabWidget1stTabBackgroundColor, + DoubleTabWidget2ndTabBackgroundColor, + DoubleTabWidget1stTabActiveTextColor, + DoubleTabWidget1stTabInactiveTextColor, + DoubleTabWidget2ndTabActiveTextColor, + DoubleTabWidget2ndTabInactiveTextColor, + EditorPlaceholderColor, + FancyTabBarBackgroundColor, + FancyTabWidgetEnabledSelectedTextColor, + FancyTabWidgetEnabledUnselectedTextColor, + FancyTabWidgetDisabledSelectedTextColor, + FancyTabWidgetDisabledUnselectedTextColor, + FancyToolButtonHoverColor, + FancyToolButtonSelectedColor, + FutureProgressBackgroundColor, + MenuBarEmptyAreaBackgroundColor, + MenuBarItemBackgroundColor, + MenuBarItemTextColorDisabled, + MenuBarItemTextColorNormal, + MiniProjectTargetSelectorBackgroundColor, + MiniProjectTargetSelectorBorderColor, + MiniProjectTargetSelectorSummaryBackgroundColor, + MiniProjectTargetSelectorTextColor, + OutputPaneButtonFlashColor, + OutputPaneToggleButtonTextColorChecked, + OutputPaneToggleButtonTextColorUnchecked, + PanelButtonToolBackgroundColorHover, + PanelTextColor, + PanelsWidgetSeparatorLineColor, + PanelStatusBarBackgroundColor, + ProgressBarTitleColor, + ProgressBarColorError, + ProgressBarColorFinished, + ProgressBarColorNormal, + SearchResultWidgetBackgroundColor, + SearchResultWidgetTextColor, + TextColorDisabled, + TextColorHighlight, + TextColorNormal, + TodoItemTextColor, + ToggleButtonBackgroundColor, + ToolBarBackgroundColor, + TreeViewArrowColorNormal, + TreeViewArrowColorSelected, + + OutputFormatter_NormalMessageTextColor, + OutputFormatter_ErrorMessageTextColor, + OutputFormatter_StdOutTextColor, + OutputFormatter_StdErrTextColor, + OutputFormatter_DebugTextColor, + + QtOutputFormatter_LinkTextColor, + + /* Welcome Plugin */ + + Welcome_TextColorNormal, + Welcome_TextColorHeading, // #535353 // Sessions, Recent Projects + Welcome_BackgroundColorNormal, // #ffffff + Welcome_DividerColor, // #737373 + Welcome_Button_BorderColor, + Welcome_Button_TextColorNormal, + Welcome_Button_TextColorPressed, + Welcome_Link_TextColorNormal, + Welcome_Link_TextColorActive, + Welcome_Link_BackgroundColor, + Welcome_Caption_TextColorNormal, + Welcome_SideBar_BackgroundColor, + + Welcome_ProjectItem_TextColorFilepath, + Welcome_ProjectItem_BackgroundColorHover, + + Welcome_SessionItem_BackgroundColorNormal, + Welcome_SessionItem_BackgroundColorHover, + Welcome_SessionItemExpanded_BackgroundColor + }; + + enum GradientRole { + DetailsWidgetHeaderGradient, + Welcome_Button_GradientNormal, + Welcome_Button_GradientPressed + }; + + enum MimeType { + CppSourceMimetype, + CSourceMimetype, + CppHeaderMimetype, + ProMimetype, + PriMimetype, + PrfMimetype + }; + + enum Flag { + DrawTargetSelectorBottom, + DrawSearchResultWidgetFrame, + DrawProgressBarSunken, + DrawIndicatorBranch, + ComboBoxDrawTextShadow, + DerivePaletteFromTheme + }; + + enum WidgetStyle { + StyleDefault, + StyleFlat + }; + + WidgetStyle widgetStyle() const; + bool flag(Flag f) const; + QColor color(ColorRole role) const; + QGradientStops gradient(GradientRole role) const; + QString iconOverlay(MimeType mimetype) const; + QPalette palette(const QPalette &base) const; + QString dpiSpecificImageFile(const QString &fileName) const; + void drawIndicatorBranch(QPainter *painter, const QRect &rect, QStyle::State state) const; + QIcon standardIcon(QStyle::StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const; + QString imageFile(const QString &fileName) const; + + QString fileName() const; + void setName(const QString &name); + + void writeSettings(const QString &filename) const; + void readSettings(QSettings &settings); + ThemePrivate *d; + +signals: + void changed(); + +protected: + QString dpiSpecificImageFile(const QString &fileName, const QString &themePrefix) const; + +private: + QPair<QColor, QString> readNamedColor(const QString &color) const; +}; + +QTCREATOR_UTILS_EXPORT Theme *creatorTheme(); +QTCREATOR_UTILS_EXPORT void setCreatorTheme(Theme *theme); + +} // namespace Utils + +#endif // THEME_H diff --git a/src/libs/utils/theme/theme_p.cpp b/src/libs/utils/theme/theme_p.cpp new file mode 100644 index 0000000000..05c7916722 --- /dev/null +++ b/src/libs/utils/theme/theme_p.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>. +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "theme_p.h" + +#include <QMetaEnum> + +namespace Utils { + +ThemePrivate::ThemePrivate() + : widgetStyle(Theme::StyleDefault) +{ + const QMetaObject &m = Theme::staticMetaObject; + colors.resize (m.enumerator(m.indexOfEnumerator("ColorRole")).keyCount()); + gradientStops.resize (m.enumerator(m.indexOfEnumerator("GradientRole")).keyCount()); + iconOverlays.resize (m.enumerator(m.indexOfEnumerator("MimeType")).keyCount()); + flags.resize (m.enumerator(m.indexOfEnumerator("Flag")).keyCount()); +} + +} // namespace Utils diff --git a/src/libs/utils/theme/theme_p.h b/src/libs/utils/theme/theme_p.h new file mode 100644 index 0000000000..d507becafc --- /dev/null +++ b/src/libs/utils/theme/theme_p.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>. +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef THEME_P_H +#define THEME_P_H + +#include "theme.h" +#include "../utils_global.h" + +#include <QColor> +#include <QMap> + +namespace Utils { + +class QTCREATOR_UTILS_EXPORT ThemePrivate +{ +public: + ThemePrivate(); + + QString fileName; + QString name; + QVector<QPair<QColor, QString> > colors; + QVector<QString> iconOverlays; + QVector<QGradientStops> gradientStops; + QVector<bool> flags; + Theme::WidgetStyle widgetStyle; + QMap<QString, QColor> palette; +}; + +} // namespace Utils + +#endif // THEME_P_H diff --git a/src/libs/utils/theme/welcometheme.cpp b/src/libs/utils/theme/welcometheme.cpp new file mode 100644 index 0000000000..e8581a7d7d --- /dev/null +++ b/src/libs/utils/theme/welcometheme.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>. +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "welcometheme.h" + +#include "theme.h" + +using namespace Utils; + +#define IMPL_COLOR_PROPERTY(propName, enumName) \ + QColor WelcomeTheme::propName () const { \ + return creatorTheme()->color(Theme::enumName); \ + } + +#define GRADIENT(x) \ + QGradient grad; \ + grad.setStops(creatorTheme()->gradient(Theme::x)); \ + return grad; + +WelcomeTheme::WelcomeTheme(QObject *parent) + : QObject(parent) +{ +} + +QString WelcomeTheme::widgetStyle() const +{ + switch (creatorTheme()->widgetStyle()) { + case Theme::StyleDefault: + return QLatin1String("default"); + case Theme::StyleFlat: + return QLatin1String("flat"); + } + return QString::null; +} + +void WelcomeTheme::notifyThemeChanged() +{ + emit themeChanged(); +} + +IMPL_COLOR_PROPERTY(textColorNormal , Welcome_TextColorNormal ) +IMPL_COLOR_PROPERTY(textColorHeading , Welcome_TextColorHeading ) +IMPL_COLOR_PROPERTY(backgroundColorNormal , Welcome_BackgroundColorNormal ) +IMPL_COLOR_PROPERTY(dividerColor , Welcome_DividerColor ) +IMPL_COLOR_PROPERTY(button_BorderColor , Welcome_Button_BorderColor ) +IMPL_COLOR_PROPERTY(button_TextColorNormal , Welcome_Button_TextColorNormal ) +IMPL_COLOR_PROPERTY(button_TextColorPressed, Welcome_Button_TextColorPressed) +IMPL_COLOR_PROPERTY(link_TextColorNormal , Welcome_Link_TextColorNormal ) +IMPL_COLOR_PROPERTY(link_TextColorActive , Welcome_Link_TextColorActive ) +IMPL_COLOR_PROPERTY(link_BackgroundColor , Welcome_Link_BackgroundColor ) +IMPL_COLOR_PROPERTY(caption_TextColorNormal, Welcome_Caption_TextColorNormal) +IMPL_COLOR_PROPERTY(sideBar_BackgroundColor, Welcome_SideBar_BackgroundColor) +IMPL_COLOR_PROPERTY(projectItem_TextColorFilepath, Welcome_ProjectItem_TextColorFilepath) +IMPL_COLOR_PROPERTY(projectItem_BackgroundColorHover, Welcome_ProjectItem_BackgroundColorHover) +IMPL_COLOR_PROPERTY(sessionItem_BackgroundColorNormal, Welcome_SessionItem_BackgroundColorNormal) +IMPL_COLOR_PROPERTY(sessionItemExpanded_BackgroundColor, Welcome_SessionItemExpanded_BackgroundColor) +IMPL_COLOR_PROPERTY(sessionItem_BackgroundColorHover, Welcome_SessionItem_BackgroundColorHover) + +QGradient WelcomeTheme::button_GradientNormal () const { GRADIENT(Welcome_Button_GradientNormal); } +QGradient WelcomeTheme::button_GradientPressed () const { GRADIENT(Welcome_Button_GradientPressed); } diff --git a/src/libs/utils/theme/welcometheme.h b/src/libs/utils/theme/welcometheme.h new file mode 100644 index 0000000000..ec9f36c844 --- /dev/null +++ b/src/libs/utils/theme/welcometheme.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>. +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef WELCOMETHEME_H +#define WELCOMETHEME_H + +#include "../utils_global.h" + +#include <QStyle> + +#define DECLARE_COLOR_PROPERTY(propName) \ + Q_PROPERTY(QColor propName READ propName NOTIFY themeChanged) \ + QColor propName () const; + +/*! + * Expose theme properties to QML (for welcomeplugin) + */ +class QTCREATOR_UTILS_EXPORT WelcomeTheme : public QObject +{ + Q_OBJECT + +public: + WelcomeTheme(QObject *parent); + + DECLARE_COLOR_PROPERTY(textColorNormal) + DECLARE_COLOR_PROPERTY(textColorHeading) + DECLARE_COLOR_PROPERTY(backgroundColorNormal) + DECLARE_COLOR_PROPERTY(dividerColor) + DECLARE_COLOR_PROPERTY(button_BorderColor) + DECLARE_COLOR_PROPERTY(button_TextColorNormal) + DECLARE_COLOR_PROPERTY(button_TextColorPressed) + DECLARE_COLOR_PROPERTY(link_TextColorNormal) + DECLARE_COLOR_PROPERTY(link_TextColorActive) + DECLARE_COLOR_PROPERTY(link_BackgroundColor) + DECLARE_COLOR_PROPERTY(sideBar_BackgroundColor) + DECLARE_COLOR_PROPERTY(caption_TextColorNormal) + DECLARE_COLOR_PROPERTY(projectItem_TextColorFilepath) + DECLARE_COLOR_PROPERTY(projectItem_BackgroundColorHover) + DECLARE_COLOR_PROPERTY(sessionItem_BackgroundColorNormal) + DECLARE_COLOR_PROPERTY(sessionItemExpanded_BackgroundColor) + DECLARE_COLOR_PROPERTY(sessionItem_BackgroundColorHover) + + Q_PROPERTY(QGradient button_GradientNormal READ button_GradientNormal NOTIFY themeChanged) + Q_PROPERTY(QGradient button_GradientPressed READ button_GradientPressed NOTIFY themeChanged) + + Q_PROPERTY(QString widgetStyle READ widgetStyle CONSTANT) + + QString widgetStyle() const; + + QGradient button_GradientNormal () const; + QGradient button_GradientPressed () const; + +public slots: + void notifyThemeChanged(); + +signals: + void themeChanged(); +}; + +#endif // WELCOMETHEME_H diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri index 8b0257ba6e..087bcba89e 100644 --- a/src/libs/utils/utils-lib.pri +++ b/src/libs/utils/utils-lib.pri @@ -92,7 +92,10 @@ SOURCES += $$PWD/environment.cpp \ $$PWD/treemodel.cpp \ $$PWD/treeviewcombobox.cpp \ $$PWD/proxycredentialsdialog.cpp \ - $$PWD/macroexpander.cpp + $$PWD/macroexpander.cpp \ + $$PWD/theme/theme.cpp \ + $$PWD/theme/theme_p.cpp \ + $$PWD/theme/welcometheme.cpp win32:SOURCES += $$PWD/consoleprocess_win.cpp else:SOURCES += $$PWD/consoleprocess_unix.cpp @@ -189,7 +192,10 @@ HEADERS += \ $$PWD/algorithm.h \ $$PWD/QtConcurrentTools \ $$PWD/proxycredentialsdialog.h \ - $$PWD/macroexpander.h + $$PWD/macroexpander.h \ + $$PWD/theme/theme.h \ + $$PWD/theme/theme_p.h \ + $$PWD/theme/welcometheme.h FORMS += $$PWD/filewizardpage.ui \ $$PWD/projectintropage.ui \ diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index a665cfc3ba..a5a92af87a 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -205,6 +205,19 @@ QtcLibrary { ] Group { + name: "Theme" + prefix: "theme/" + files: [ + "theme.cpp", + "theme.h", + "theme_p.cpp", + "theme_p.h", + "welcometheme.cpp", + "welcometheme.h", + ] + } + + Group { name: "Tooltip" prefix: "tooltip/" files: [ |