summaryrefslogtreecommitdiff
path: root/src/libs/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/utils')
-rw-r--r--src/libs/utils/detailsbutton.cpp54
-rw-r--r--src/libs/utils/detailswidget.cpp32
-rw-r--r--src/libs/utils/outputformatter.cpp21
-rw-r--r--src/libs/utils/outputformatter.h2
-rw-r--r--src/libs/utils/theme/theme.cpp356
-rw-r--r--src/libs/utils/theme/theme.h217
-rw-r--r--src/libs/utils/theme/theme_p.cpp47
-rw-r--r--src/libs/utils/theme/theme_p.h59
-rw-r--r--src/libs/utils/theme/welcometheme.cpp87
-rw-r--r--src/libs/utils/theme/welcometheme.h87
-rw-r--r--src/libs/utils/utils-lib.pri10
-rw-r--r--src/libs/utils/utils.qbs13
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: [