Implement theming for QtCreator

Adds a 'Theme' tab to the environment settings and a '-theme' command
line option.
A theme is a combination of colors, gradients, flags and style
information.

There are two themes:
- 'default': preserves the current default look
- 'dark': uses a more flat for many widgets, dark color theme
  for everything

This does not use a stylesheet (too limited), but rather sets
the palette via C++ and modifies drawing behavior.
Overall, the look is more flat (removed some gradients and bevels).

Tested on Ubuntu 14.04 using Qt 5.4 and running on a KDE
Desktop (Oxygen base style).

For a screenshot, see
https://gist.github.com/thorbenk/5ab06bea726de0aa7473

Changes:
- Introduce class Theme, defining the interface how to access theme
  specific settings. The class reads a .creatortheme file (INI file, via
  QSettings)

  - Define named colors in the [Palette] section
    (see dark.creatortheme for example usage)

  - Use either named colors of AARRGGBB (hex) in the [Colors]
    section

  - A file ending with .creatortheme may be supplied
    to the '-theme' command line option

- A global Theme instance can be accessed via creatorTheme()

- Query colors, gradients, icons and flags from the theme
  were possible (TODO: use this in more places...)

- There are very many color roles. It seems better to me
  to describe the role clearly, and then to consolidate later
  in the actual theme by assigning the same color.
  For example, one can set the text color of the output pane button
  individualy.

- Many elements are also drawn differently.
  For the dark theme, I wanted to have a flatter look.
  - Introduce Theme::WidgetStyle enum, for now {Original, Flat}.
  - The theme specifies which kind of widget style it wants.
  - The drawing code queries the theme's style flag and
    switches between the original, gradient based look and
    the new, flat look.

- Create some custom icons which look better on dark background
  (wip, currently folder/file icons)

- Let ManhattanStyle draw some elements for non-panelwidgets, too
  (open/close arrows in QTreeView, custom folder/file icons)

- For the welcomescreen, pass the WelcomeTheme class.
  WelcomeTheme exposes theme colors as Q_PROPERTY accessible from
  .qml

- Themes can be modified via the 'Themes' tab in the environment
  settings.

TODO:
* Unify image handling
* Avoid style name references
* Fix gradients

Change-Id: I92c2050ab0fb327649ea1eff4adec973d2073944
Reviewed-by: Thomas Hartmann <Thomas.Hartmann@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
Thorben Kroeger
2014-10-14 19:09:48 +02:00
committed by hjk
parent fd8fcd29a1
commit 84f5585b5d
94 changed files with 4135 additions and 359 deletions

View File

@@ -28,6 +28,7 @@ DATA_DIRS = \
examplebrowser \ examplebrowser \
snippets \ snippets \
templates \ templates \
themes \
designer \ designer \
schemes \ schemes \
styles \ styles \

View File

@@ -0,0 +1,129 @@
[General]
ThemeName=dark
[Palette]
shadowBackground=ff232323
text=ffe7e7e7
textDisabled=ffa0a0a4
hoverBackground=ff515151
selectedBackground=ff151515
normalBackground=ff333333
alternateBackground=ff515151
error=ffff0000
[Colors]
BackgroundColorAlternate=alternateBackground
BackgroundColorDark=shadowBackground
BackgroundColorHover=hoverBackground
BackgroundColorNormal=normalBackground
BackgroundColorSelected=selectedBackground
BadgeLabelBackgroundColorChecked=normalBackground
BadgeLabelBackgroundColorUnchecked=selectedBackground
BadgeLabelTextColorChecked=text
BadgeLabelTextColorUnchecked=text
CanceledSearchTextColor=ff0000
ComboBoxArrowColor=text
ComboBoxArrowColorDisabled=text
ComboBoxTextColor=text
DetailsButtonBackgroundColorHover=hoverBackground
DetailsWidgetBackgroundColor=ff4a4a4a
DockWidgetResizeHandleColor=shadowBackground
DoubleTabWidget1stEmptyAreaBackgroundColor=normalBackground
DoubleTabWidget1stSeparatorColor=hoverBackground
DoubleTabWidget1stTabActiveTextColor=text
DoubleTabWidget1stTabBackgroundColor=ff4a4a4a
DoubleTabWidget1stTabInactiveTextColor=textDisabled
DoubleTabWidget2ndSeparatorColor=hoverBackground
DoubleTabWidget2ndTabActiveTextColor=text
DoubleTabWidget2ndTabBackgroundColor=ff434343
DoubleTabWidget2ndTabInactiveTextColor=textDisabled
EditorPlaceholderColor=normalBackground
FancyTabBarBackgroundColor=shadowBackground
FancyTabWidgetDisabledSelectedTextColor=textDisabled
FancyTabWidgetDisabledUnselectedTextColor=textDisabled
FancyTabWidgetEnabledSelectedTextColor=text
FancyTabWidgetEnabledUnselectedTextColor=text
FancyToolButtonHoverColor=hoverBackground
FancyToolButtonSelectedColor=selectedBackground
FutureProgressBackgroundColor=shadowBackground
MenuBarEmptyAreaBackgroundColor=shadowBackground
MenuBarItemBackgroundColor=shadowBackground
MenuBarItemTextColorDisabled=textDisabled
MenuBarItemTextColorNormal=text
MiniProjectTargetSelectorBackgroundColor=shadowBackground
MiniProjectTargetSelectorBorderColor=shadowBackground
MiniProjectTargetSelectorSummaryBackgroundColor=shadowBackground
MiniProjectTargetSelectorTextColor=text
OutputFormatter_DebugTextColor=text
OutputFormatter_ErrorMessageTextColor=error
OutputFormatter_NormalMessageTextColor=text
OutputFormatter_StdErrTextColor=error
OutputFormatter_StdOutTextColor=text
OutputPaneButtonFlashColor=error
OutputPaneToggleButtonTextColorChecked=text
OutputPaneToggleButtonTextColorUnchecked=text
PanelButtonToolBackgroundColorHover=hoverBackground
PanelStatusBarBackgroundColor=shadowBackground
PanelTextColor=text
PanelsWidgetSeparatorLineColor=0
ProgressBarColorError=error
ProgressBarColorFinished=ff5aaa3c
ProgressBarColorNormal=hoverBackground
ProgressBarTitleColor=text
QtOutputFormatter_LinkTextColor=ff0000ff
SearchResultWidgetBackgroundColor=shadowBackground
SearchResultWidgetTextColor=text
TextColorDisabled=textDisabled
TextColorHighlight=ffff0000
TextColorNormal=text
TodoItemTextColor=ff000000
ToggleButtonBackgroundColor=shadowBackground
ToolBarBackgroundColor=shadowBackground
TreeViewArrowColorNormal=hoverBackground
TreeViewArrowColorSelected=text
Welcome_BackgroundColorNormal=normalBackground
Welcome_Button_BorderColor=0
Welcome_Button_TextColorNormal=ffe7e7e7
Welcome_Button_TextColorPressed=ffffffff
Welcome_Caption_TextColorNormal=ff4acb47
Welcome_DividerColor=ff232323
Welcome_Link_BackgroundColor=ff333333
Welcome_Link_TextColorActive=fff0f0f0
Welcome_Link_TextColorNormal=text
Welcome_ProjectItem_BackgroundColorHover=0
Welcome_ProjectItem_TextColorFilepath=textDisabled
Welcome_SessionItemExpanded_BackgroundColor=selectedBackground
Welcome_SessionItem_BackgroundColorHover=hoverBackground
Welcome_SessionItem_BackgroundColorNormal=0
Welcome_SideBar_BackgroundColor=ff434343
Welcome_TextColorHeading=text
Welcome_TextColorNormal=text
[Flags]
ComboBoxDrawTextShadow=false
DerivePaletteFromTheme=true
DrawIndicatorBranch=true
DrawProgressBarSunken=false
DrawSearchResultWidgetFrame=false
DrawTargetSelectorBottom=false
[Gradients]
DetailsWidgetHeaderGradient\1\color=0
DetailsWidgetHeaderGradient\1\pos=1
DetailsWidgetHeaderGradient\size=1
[IconOverlay]
CSourceMimetype=:/cppeditor/images/dark_qt_c.png
CppHeaderMimetype=:/cppeditor/images/dark_qt_h.png
CppSourceMimetype=:/cppeditor/images/dark_qt_cpp.png
PrfMimetype=:/qtsupport/images/dark_qt_project.png
PriMimetype=:/qtsupport/images/dark_qt_project.png
ProMimetype=:/qtsupport/images/dark_qt_project.png
#TODO: needs to be ported to new ini format!
[StandardIcons]
SP_FileIcon=:/core/images/dark_fileicon.png
SP_DirIcon=:/core/images/dark_foldericon.png
[Style]
WidgetStyle=StyleFlat

View File

@@ -0,0 +1,118 @@
[General]
ThemeName=default
[Palette]
brightText = ffffffff
darkText = ff000000
[Colors]
BackgroundColorAlternate=ff3d3d3d
BackgroundColorDark=ff232323
BackgroundColorHover=ff515151
BackgroundColorNormal=ffffffff
BackgroundColorSelected=ff151515
BadgeLabelBackgroundColorChecked=ffe0e0e0
BadgeLabelBackgroundColorUnchecked=ff808080
BadgeLabelTextColorChecked=ff606060
BadgeLabelTextColorUnchecked=ffffffff
CanceledSearchTextColor=ffff0000
ComboBoxArrowColor=ffb8b5b2
ComboBoxArrowColorDisabled=ffdcdcdc
ComboBoxTextColor=ffffffff
DetailsButtonBackgroundColorHover=b4ffffff
DetailsWidgetBackgroundColor=28ffffff
DockWidgetResizeHandleColor=ff000000
DoubleTabWidget1stEmptyAreaBackgroundColor=ffff0000
DoubleTabWidget1stSeparatorColor=ffff0000
DoubleTabWidget1stTabActiveTextColor=ff000000
DoubleTabWidget1stTabBackgroundColor=ffff0000
DoubleTabWidget1stTabInactiveTextColor=ff000000
DoubleTabWidget2ndSeparatorColor=ffff0000
DoubleTabWidget2ndTabActiveTextColor=ffffffff
DoubleTabWidget2ndTabBackgroundColor=ffff0000
DoubleTabWidget2ndTabInactiveTextColor=ff000000
EditorPlaceholderColor=ffe0dcd8
FancyTabBarBackgroundColor=ffff0000
FancyTabWidgetDisabledSelectedTextColor=ffffffff
FancyTabWidgetDisabledUnselectedTextColor=78ffffff
FancyTabWidgetEnabledSelectedTextColor=ff3c3c3c
FancyTabWidgetEnabledUnselectedTextColor=ffffffff
FancyToolButtonHoverColor=28ffffff
FancyToolButtonSelectedColor=32000000
FutureProgressBackgroundColor=ffff0000
MenuBarEmptyAreaBackgroundColor=ffff0000
MenuBarItemBackgroundColor=ffff0000
MenuBarItemTextColorDisabled=ffa0a0a4
MenuBarItemTextColorNormal=ff000000
MiniProjectTargetSelectorBackgroundColor=ffa0a0a0
MiniProjectTargetSelectorBorderColor=ff000000
MiniProjectTargetSelectorSummaryBackgroundColor=ff464646
MiniProjectTargetSelectorTextColor=a0ffffff
OutputFormatter_DebugTextColor=ffaa00aa
OutputFormatter_ErrorMessageTextColor=ffaa0000
OutputFormatter_NormalMessageTextColor=ff0000aa
OutputFormatter_StdErrTextColor=ffaa0000
OutputFormatter_StdOutTextColor=ff000000
OutputPaneButtonFlashColor=ffff0000
OutputPaneToggleButtonTextColorChecked=ffffffff
OutputPaneToggleButtonTextColorUnchecked=ff000000
PanelTextColor=brightText
PanelButtonToolBackgroundColorHover=25ffffff
PanelStatusBarBackgroundColor=ffff0000
PanelsWidgetSeparatorLineColor=ffbfbcb8
ProgressBarColorError=d2ff3c00
ProgressBarColorFinished=ff5aaa3c
ProgressBarColorNormal=b4ffffff
ProgressBarTitleColor=ffffffff
QtOutputFormatter_LinkTextColor=ff0000aa
SearchResultWidgetBackgroundColor=ffffffff
SearchResultWidgetTextColor=ff000000
TextColorDisabled=ff000000
TextColorHighlight=ffa0a0a4
TextColorNormal=ff000000
TodoItemTextColor=ff000000
ToggleButtonBackgroundColor=ffff0000
ToolBarBackgroundColor=ffff0000
TreeViewArrowColorNormal=ffff0000
TreeViewArrowColorSelected=ffff0000
Welcome_BackgroundColorNormal=ffffffff
Welcome_Button_BorderColor=ff737373
Welcome_Button_TextColorNormal=ff000000
Welcome_Button_TextColorPressed=ffc0c0c0
Welcome_Caption_TextColorNormal=ff328930
Welcome_DividerColor=ff737373
Welcome_Link_BackgroundColor=ff909090
Welcome_Link_TextColorActive=fff0f0f0
Welcome_Link_TextColorNormal=ff328930
Welcome_ProjectItem_BackgroundColorHover=fff9f9f9
Welcome_ProjectItem_TextColorFilepath=ff6b6b6b
Welcome_SessionItemExpanded_BackgroundColor=fff1f1f1
Welcome_SessionItem_BackgroundColorHover=fff9f9f9
Welcome_SessionItem_BackgroundColorNormal=19f9f9f9
Welcome_SideBar_BackgroundColor=ffebebeb
Welcome_TextColorHeading=ff535353
Welcome_TextColorNormal=ff000000
[Flags]
ComboBoxDrawTextShadow=true
DerivePaletteFromTheme=false
DrawIndicatorBranch=false
DrawProgressBarSunken=true
DrawSearchResultWidgetFrame=true
DrawTargetSelectorBottom=true
[Gradients]
DetailsWidgetHeaderGradient\1\color=ffffff
DetailsWidgetHeaderGradient\1\pos=1
DetailsWidgetHeaderGradient\size=1
[IconOverlay]
CSourceMimetype=:/cppeditor/images/qt_c.png
CppHeaderMimetype=:/cppeditor/images/qt_h.png
CppSourceMimetype=:/cppeditor/images/qt_cpp.png
PrfMimetype=:/qtsupport/images/qt_project.png
PriMimetype=:/qtsupport/images/qt_project.png
ProMimetype=:/qtsupport/images/qt_project.png
[Style]
WidgetStyle=StyleDefault

View File

@@ -66,7 +66,7 @@ Controls.ScrollView {
x: 32 x: 32
y: screenDependHeightDistance + 77 y: screenDependHeightDistance + 77
color: "#535353" color: creatorTheme.textColorHeading
text: qsTr("Sessions") text: qsTr("Sessions")
font.pixelSize: 16 font.pixelSize: 16
font.family: "Helvetica" font.family: "Helvetica"
@@ -78,7 +78,7 @@ Controls.ScrollView {
x: 406 x: 406
y: screenDependHeightDistance + 77 y: screenDependHeightDistance + 77
color: "#535353" color: creatorTheme.textColorHeading
text: qsTr("Recent Projects") text: qsTr("Recent Projects")
anchors.left: sessionsTitle.right anchors.left: sessionsTitle.right
anchors.leftMargin: 280 anchors.leftMargin: 280

View File

@@ -35,7 +35,6 @@ Item {
id: root id: root
property var fonts: CustomFonts {} property var fonts: CustomFonts {}
property var colors: CustomColors { }
property int screenDependHeightDistance: Math.min(50, Math.max(16, height / 30)) property int screenDependHeightDistance: Math.min(50, Math.max(16, height / 30))
@@ -48,7 +47,7 @@ Item {
Rectangle { Rectangle {
id: splitter id: splitter
color: "#737373" color: creatorTheme.dividerColor; // divider between left and right pane
width: 1 width: 1
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom

View File

@@ -61,61 +61,60 @@ Button {
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
antialiasing: true antialiasing: true
radius: 3 radius: (creatorTheme.widgetStyle === 'flat') ? 0 : 3
visible: !(button.pressed || button.checked) visible: !(button.pressed || button.checked)
gradient: Gradient { gradient: Gradient {
GradientStop { GradientStop {
position: 0 position: 0
color: "#f9f9f9" color: (theme==='dark') ? "#232323" : "#f9f9f9"
} }
GradientStop { GradientStop {
position: 0.49 position: 0.49
color: "#f9f9f9" color: (theme === 'dark') ? "#232323" : "#f9f9f9"
} }
GradientStop { GradientStop {
position: 0.5 position: 0.5
color: "#eeeeee" color: (theme === 'dark') ? "#232323" : "#eeeeee"
} }
GradientStop { GradientStop {
position: 1 position: 1
color: "#eeeeee" color: (theme === 'dark') ? "#232323" : "#eeeeee"
} }
} }
border.color: "#737373" border.color: creatorTheme.button_BorderColor
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
antialiasing: true antialiasing: true
radius: 3 radius: (creatorTheme.widgetStyle === 'flat') ? 0 : 3
visible: button.pressed || button.checked visible: button.pressed || button.checked
gradient: Gradient { gradient: Gradient {
GradientStop { GradientStop {
position: 0.00; position: 0.00;
color: "#4c4c4c"; color: (theme === "dark") ? "#151515" : "#4c4c4c"
} }
GradientStop { GradientStop {
position: 0.49; position: 0.49;
color: "#4c4c4c"; color: (theme === "dark") ? "#151515" : "#4c4c4c"
} }
GradientStop { GradientStop {
position: 0.50; position: 0.50;
color: "#424242"; color: (theme === "dark") ? "#151515" : "#424242"
} }
GradientStop { GradientStop {
position: 1.00; position: 1.00;
color: "#424242"; color: (theme === "dark") ? "#151515" : "#424242"
} }
} }
border.color: "#333333" border.color: creatorTheme.button_BorderColor
} }
} }
@@ -124,7 +123,9 @@ Button {
renderType: Text.NativeRendering renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
text: button.text text: button.text
color: button.pressed || button.checked ? "lightGray" : "black" color: button.pressed || button.checked
? creatorTheme.button_TextColorPressed
: creatorTheme.button_TextColorNormal
font.pixelSize: 15 font.pixelSize: 15
font.bold: false font.bold: false
smooth: true smooth: true

View File

@@ -34,6 +34,7 @@ Rectangle {
id: delegate id: delegate
height: 240 height: 240
width: 216 width: 216
color: creatorTheme.backgroundColorNormal
property alias caption: captionItem.text property alias caption: captionItem.text
property alias imageSource: imageItem.source property alias imageSource: imageItem.source
@@ -106,7 +107,7 @@ Rectangle {
y: 161 y: 161
width: 200 width: 200
height: 69 height: 69
color: "#ffffff" color: creatorTheme.backgroundColorNormal
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
anchors.left: parent.left anchors.left: parent.left
@@ -116,7 +117,7 @@ Rectangle {
id: captionItem id: captionItem
x: 16 x: 16
y: 170 y: 170
color: colors.strongForegroundColor color: creatorTheme.caption_TextColorNormal
text: qsTr("2D PAINTING EXAMPLE long description") text: qsTr("2D PAINTING EXAMPLE long description")
elide: Text.ElideRight elide: Text.ElideRight
anchors.right: parent.right anchors.right: parent.right
@@ -163,6 +164,7 @@ Rectangle {
x: 16 x: 16
y: 198 y: 198
text: qsTr("Tags:") text: qsTr("Tags:")
color: creatorTheme.textColorNormal
smooth: true smooth: true
font.italic: false font.italic: false
font.pixelSize: 11 font.pixelSize: 11

View File

@@ -44,7 +44,7 @@ Row {
LinkedText { LinkedText {
text: title text: title
font.pixelSize: 11 font.pixelSize: 11
color: "black" color: creatorTheme.textColorNormal // 'Qt Account' .. 'User Guide' on lower left
onClicked: { onClicked: {
if (openUrl) if (openUrl)
gettingStarted.openUrl(openUrl); gettingStarted.openUrl(openUrl);

View File

@@ -33,7 +33,8 @@ import QtQuick 2.1
NativeText { NativeText {
id: root id: root
height: 16 height: 16
color: active ? "#f0f0f0" : colors.linkColor color: active ? creatorTheme.link_TextColorActive
: creatorTheme.link_TextColorNormal
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
font: fonts.linkFont font: fonts.linkFont
@@ -53,7 +54,7 @@ NativeText {
property bool enlargeMouseArea: true property bool enlargeMouseArea: true
Rectangle { Rectangle {
color: "#909090" color: "#909090" // FIXME: theming: Where is this ever visible?
radius: 6 radius: 6
opacity: root.active opacity: root.active
z: -1 z: -1
@@ -65,7 +66,7 @@ NativeText {
} }
Rectangle { Rectangle {
color: "#909090" color: "#909090" // FIXME: theming: Where is this ever visible?
opacity: root.active opacity: root.active
z: -1 z: -1
anchors.rightMargin: -6 anchors.rightMargin: -6

View File

@@ -35,9 +35,9 @@ Item {
width: row.width + 8 width: row.width + 8
height: text.height height: text.height
Rectangle { Rectangle { // background shown on hover over project item
anchors.fill: parent anchors.fill: parent
color: "#f9f9f9" color: creatorTheme.projectItem_BackgroundColorHover
visible: mouseArea.containsMouse visible: mouseArea.containsMouse
} }
@@ -67,7 +67,7 @@ Item {
NativeText { NativeText {
id: pathText id: pathText
height: 20 height: 20
color: "#6b6b6b" color: creatorTheme.projectItem_TextColorFilepath
font: fonts.smallPath font: fonts.smallPath
} }
} }

View File

@@ -34,6 +34,7 @@ import QtQuick.Controls 1.0
Rectangle { Rectangle {
id: projectList id: projectList
height: column.height + 200 height: column.height + 200
color: creatorTheme.backgroundColorNormal
property alias model: repeater.model property alias model: repeater.model
// Behavior on verticalScrollBar.opacity { // Behavior on verticalScrollBar.opacity {

View File

@@ -37,9 +37,9 @@ Rectangle {
width: 930 width: 930
height: 27 height: 27
color: "#ffffff" color: creatorTheme.backgroundColorNormal
radius: 6 radius: 6
border.color: "#cccccc" border.color: "#cccccc" // FIXME: make themable
property alias placeholderText: lineEdit.placeholderText property alias placeholderText: lineEdit.placeholderText
property alias text: lineEdit.text property alias text: lineEdit.text
@@ -56,6 +56,8 @@ Rectangle {
font.pixelSize: 14 font.pixelSize: 14
placeholderText: qsTr("Search...") placeholderText: qsTr("Search...")
style: TextFieldStyle { style: TextFieldStyle {
placeholderTextColor: creatorTheme.textColorNormal
textColor: creatorTheme.textColorNormal
background: Item { background: Item {
} }
} }

View File

@@ -67,7 +67,10 @@ Item {
Rectangle { Rectangle {
z: -4 z: -4
color: "#f9f9f9" // background of session item
color: (iArea.hovered || text.hovered || area2.hovered)
? creatorTheme.sessionItem_BackgroundColorHover
: creatorTheme.sessionItem_BackgroundColorNormal
anchors.fill: parent anchors.fill: parent
visible: iArea.containsMouse || text.hovered visible: iArea.containsMouse || text.hovered
anchors.topMargin: 1 anchors.topMargin: 1
@@ -115,6 +118,7 @@ Item {
NativeText { NativeText {
text: projectsName[index] text: projectsName[index]
font: fonts.boldDescription font: fonts.boldDescription
color: creatorTheme.textColorNormal
} }
NativeText { NativeText {
x: 4 x: 4
@@ -139,7 +143,7 @@ Item {
maximumLineCount: 2 maximumLineCount: 2
elide: Text.ElideRight elide: Text.ElideRight
height: lineCount == 2 ? font.pixelSize * 2 + 4 : font.pixelSize + 2 height: lineCount == 2 ? font.pixelSize * 2 + 4 : font.pixelSize + 2
color: "#6b6b6b" color: creatorTheme.projectItem_TextColorFilepath
width: delegate.ListView.view.width - 48 width: delegate.ListView.view.width - 48
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
@@ -222,7 +226,8 @@ Item {
id: collapseButton id: collapseButton
visible: text.hovered || iArea.containsMouse || delegate.expanded visible: text.hovered || iArea.containsMouse || delegate.expanded
property color color: iArea.containsMouse ? "#E9E9E9" : "#f1f1f1" property color color: iArea.containsMouse ? creatorTheme.sessionItem_BackgroundColorHover
: creatorTheme.sessionItemExpanded_BackgroundColor
anchors.fill: parent anchors.fill: parent
Image { Image {
@@ -238,7 +243,7 @@ Item {
Rectangle { Rectangle {
color: collapseButton.color color: collapseButton.color
z: -1 z: -1
radius: 6 radius: creatorTheme.widgetStyle === 'flat' ? 0 : 6
anchors.fill: parent anchors.fill: parent
anchors.topMargin: 1 anchors.topMargin: 1
anchors.bottomMargin: 1 anchors.bottomMargin: 1

View File

@@ -48,10 +48,24 @@ ColumnLayout {
Layout.preferredWidth: tabs.width + 16 * 2 Layout.preferredWidth: tabs.width + 16 * 2
Layout.preferredHeight: tabs.height + screenDependHeightDistance * 2 Layout.preferredHeight: tabs.height + screenDependHeightDistance * 2
Image { Component {
fillMode: Image.Tile id: imageBackground
source: "images/background.png" Image {
fillMode: Image.Tile
source: "images/background.png"
anchors.fill: parent
}
}
Component {
id: flatBackground
Rectangle {
color: creatorTheme.sideBar_BackgroundColor
}
}
Loader {
id: topLeftLoader
anchors.fill: parent anchors.fill: parent
sourceComponent: creatorTheme.widgetStyle === 'flat' ? flatBackground : imageBackground;
} }
Tabs { Tabs {
@@ -64,7 +78,7 @@ ColumnLayout {
} }
Rectangle { Rectangle {
color: "#737373" color: creatorTheme.widgetStyle === 'flat' ? creatorTheme.sideBar_BackgroundColor : creatorTheme.dividerColor
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@@ -73,7 +87,7 @@ ColumnLayout {
} }
Rectangle { Rectangle {
color: "#737373" color: creatorTheme.widgetStyle === 'flat' ? creatorTheme.sideBar_BackgroundColor : creatorTheme.dividerColor
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@@ -83,7 +97,7 @@ ColumnLayout {
} }
Rectangle { Rectangle {
color: "#737373" color: creatorTheme.widgetStyle === 'flat' ? creatorTheme.sideBar_BackgroundColor : creatorTheme.dividerColor
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@@ -94,7 +108,7 @@ ColumnLayout {
} }
Rectangle { Rectangle {
color: "#ebebeb" color: creatorTheme.sideBar_BackgroundColor
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredWidth: innerColumn.width + 20 Layout.preferredWidth: innerColumn.width + 20
@@ -115,6 +129,7 @@ ColumnLayout {
NativeText { NativeText {
text: qsTr("New to Qt?") text: qsTr("New to Qt?")
color: creatorTheme.textColorNormal
font.pixelSize: 18 font.pixelSize: 18
} }
@@ -124,6 +139,7 @@ ColumnLayout {
Layout.preferredWidth: innerColumn.width Layout.preferredWidth: innerColumn.width
text: qsTr("Learn how to develop your own applications and explore Qt Creator.") text: qsTr("Learn how to develop your own applications and explore Qt Creator.")
color: creatorTheme.textColorNormal
font.pixelSize: 12 font.pixelSize: 12
wrapMode: Text.WrapAtWordBoundaryOrAnywhere wrapMode: Text.WrapAtWordBoundaryOrAnywhere
} }

View File

@@ -21,6 +21,7 @@ Product {
"snippets", "snippets",
"styles", "styles",
"templates", "templates",
"themes",
"welcomescreen" "welcomescreen"
] ]
} }

View File

@@ -29,8 +29,8 @@
****************************************************************************/ ****************************************************************************/
#include "detailsbutton.h" #include "detailsbutton.h"
#include "hostosinfo.h"
#include <utils/hostosinfo.h> #include "theme/theme.h"
#include <QGraphicsOpacityEffect> #include <QGraphicsOpacityEffect>
#include <QGuiApplication> #include <QGuiApplication>
@@ -122,8 +122,15 @@ void DetailsButton::paintEvent(QPaintEvent *e)
QPainter p(this); QPainter p(this);
// draw hover animation // draw hover animation
if (!HostOsInfo::isMacHost() && !isDown() && m_fader > 0) if (!HostOsInfo::isMacHost() && !isDown() && m_fader > 0) {
p.fillRect(rect().adjusted(1, 1, -2, -2), QColor(255, 255, 255, int(m_fader*180))); 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 (isChecked()) {
if (m_checkedPixmap.isNull() || m_checkedPixmap.size() / m_checkedPixmap.devicePixelRatio() != contentsRect().size()) 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) QPixmap DetailsButton::cacheRendering(const QSize &size, bool checked)
{ {
QLinearGradient lg;
lg.setCoordinateMode(QGradient::ObjectBoundingMode);
lg.setFinalStop(0, 1);
const qreal pixelRatio = devicePixelRatio(); const qreal pixelRatio = devicePixelRatio();
QPixmap pixmap(size * pixelRatio); QPixmap pixmap(size * pixelRatio);
pixmap.setDevicePixelRatio(pixelRatio); pixmap.setDevicePixelRatio(pixelRatio);
@@ -159,22 +162,29 @@ QPixmap DetailsButton::cacheRendering(const QSize &size, bool checked)
QPainter p(&pixmap); QPainter p(&pixmap);
p.setRenderHint(QPainter::Antialiasing, true); p.setRenderHint(QPainter::Antialiasing, true);
p.translate(0.5, 0.5); 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));
} else {
lg.setColorAt(0, QColor(255, 255, 255, 0));
lg.setColorAt(1, QColor(255, 255, 255, 50));
}
p.setBrush(lg); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
p.setPen(QColor(255,255,255,140)); QLinearGradient lg;
p.drawRoundedRect(1, 1, size.width()-3, size.height()-3, 1, 1); lg.setCoordinateMode(QGradient::ObjectBoundingMode);
p.setPen(QPen(QColor(0, 0, 0, 40))); lg.setFinalStop(0, 1);
p.drawLine(0, 1, 0, size.height() - 2); if (!checked) {
if (checked) lg.setColorAt(0, QColor(0, 0, 0, 10));
p.drawLine(1, size.height() - 1, size.width() - 1, size.height() - 1); 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 {
p.setPen(Qt::NoPen);
p.drawRoundedRect(0, 0, size.width(), size.height(), 1, 1);
}
p.setPen(palette().color(QPalette::Text)); p.setPen(palette().color(QPalette::Text));

View File

@@ -31,6 +31,7 @@
#include "detailswidget.h" #include "detailswidget.h"
#include "detailsbutton.h" #include "detailsbutton.h"
#include "hostosinfo.h" #include "hostosinfo.h"
#include "theme/theme.h"
#include <QGridLayout> #include <QGridLayout>
#include <QLabel> #include <QLabel>
@@ -148,21 +149,22 @@ QPixmap DetailsWidget::createBackground(const QSize &size, int topHeight, QWidge
if (HostOsInfo::isMacHost()) if (HostOsInfo::isMacHost())
p.fillRect(fullRect, qApp->palette().window().color()); p.fillRect(fullRect, qApp->palette().window().color());
else else
p.fillRect(fullRect, QColor(255, 255, 255, 40)); p.fillRect(fullRect, creatorTheme()->color(Theme::DetailsWidgetBackgroundColor));
QLinearGradient lg(topRect.topLeft(), topRect.bottomLeft()); if (creatorTheme()->widgetStyle () == Theme::StyleDefault) {
lg.setColorAt(0, QColor(255, 255, 255, 130)); QLinearGradient lg(topRect.topLeft(), topRect.bottomLeft());
lg.setColorAt(1, QColor(255, 255, 255, 0)); lg.setStops(creatorTheme()->gradient(Theme::DetailsWidgetHeaderGradient));
p.fillRect(topRect, lg); p.fillRect(topRect, lg);
p.setRenderHint(QPainter::Antialiasing, true); p.setRenderHint(QPainter::Antialiasing, true);
p.translate(0.5, 0.5); p.translate(0.5, 0.5);
p.setPen(QColor(0, 0, 0, 40)); p.setPen(QColor(0, 0, 0, 40));
p.setBrush(Qt::NoBrush); p.setBrush(Qt::NoBrush);
p.drawRoundedRect(fullRect.adjusted(0, 0, -1, -1), 2, 2); p.drawRoundedRect(fullRect.adjusted(0, 0, -1, -1), 2, 2);
p.setBrush(Qt::NoBrush); p.setBrush(Qt::NoBrush);
p.setPen(QColor(255,255,255,140)); p.setPen(QColor(255,255,255,140));
p.drawRoundedRect(fullRect.adjusted(1, 1, -2, -2), 2, 2); p.drawRoundedRect(fullRect.adjusted(1, 1, -2, -2), 2, 2);
p.setPen(QPen(widget->palette().color(QPalette::Mid))); p.setPen(QPen(widget->palette().color(QPalette::Mid)));
}
return pixmap; return pixmap;
} }

View File

@@ -28,10 +28,11 @@
** **
****************************************************************************/ ****************************************************************************/
#include "ansiescapecodehandler.h"
#include "outputformatter.h" #include "outputformatter.h"
#include "theme/theme.h"
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <utils/ansiescapecodehandler.h>
using namespace Utils; using namespace Utils;
@@ -110,12 +111,6 @@ void OutputFormatter::clearLastLine()
cursor.removeSelectedText(); 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() void OutputFormatter::initFormats()
{ {
if (!plainTextEdit()) if (!plainTextEdit())
@@ -127,26 +122,28 @@ void OutputFormatter::initFormats()
m_formats = new QTextCharFormat[NumberOfFormats]; m_formats = new QTextCharFormat[NumberOfFormats];
Theme *theme = creatorTheme();
// NormalMessageFormat // NormalMessageFormat
m_formats[NormalMessageFormat].setFont(boldFont); 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 // ErrorMessageFormat
m_formats[ErrorMessageFormat].setFont(boldFont); 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 // StdOutFormat
m_formats[StdOutFormat].setFont(m_font); 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]; m_formats[StdOutFormatSameLine] = m_formats[StdOutFormat];
// StdErrFormat // StdErrFormat
m_formats[StdErrFormat].setFont(m_font); 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[StdErrFormatSameLine] = m_formats[StdErrFormat];
m_formats[DebugFormat].setFont(m_font); 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) void OutputFormatter::handleLink(const QString &href)

View File

@@ -73,8 +73,6 @@ protected:
QTextCharFormat charFormat(OutputFormat format) const; QTextCharFormat charFormat(OutputFormat format) const;
void append(QTextCursor &cursor, const QString &text, const QTextCharFormat &format); void append(QTextCursor &cursor, const QString &text, const QTextCharFormat &format);
static QColor mixColors(const QColor &a, const QColor &b);
private: private:
QPlainTextEdit *m_plainTextEdit; QPlainTextEdit *m_plainTextEdit;
QTextCharFormat *m_formats; QTextCharFormat *m_formats;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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); }

View File

@@ -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

View File

@@ -92,7 +92,10 @@ SOURCES += $$PWD/environment.cpp \
$$PWD/treemodel.cpp \ $$PWD/treemodel.cpp \
$$PWD/treeviewcombobox.cpp \ $$PWD/treeviewcombobox.cpp \
$$PWD/proxycredentialsdialog.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 win32:SOURCES += $$PWD/consoleprocess_win.cpp
else:SOURCES += $$PWD/consoleprocess_unix.cpp else:SOURCES += $$PWD/consoleprocess_unix.cpp
@@ -189,7 +192,10 @@ HEADERS += \
$$PWD/algorithm.h \ $$PWD/algorithm.h \
$$PWD/QtConcurrentTools \ $$PWD/QtConcurrentTools \
$$PWD/proxycredentialsdialog.h \ $$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 \ FORMS += $$PWD/filewizardpage.ui \
$$PWD/projectintropage.ui \ $$PWD/projectintropage.ui \

View File

@@ -204,6 +204,19 @@ QtcLibrary {
"images/triangle_vert.png", "images/triangle_vert.png",
] ]
Group {
name: "Theme"
prefix: "theme/"
files: [
"theme.cpp",
"theme.h",
"theme_p.cpp",
"theme_p.h",
"welcometheme.cpp",
"welcometheme.h",
]
}
Group { Group {
name: "Tooltip" name: "Tooltip"
prefix: "tooltip/" prefix: "tooltip/"

View File

@@ -22,6 +22,11 @@
\"Parameter\" : \"color\", \"Parameter\" : \"color\",
\"Description\" : \"Override selected UI color\" \"Description\" : \"Override selected UI color\"
}, },
{
\"Name\" : \"-theme\",
\"Parameter\" : \"default|dark\",
\"Description\" : \"Choose a built-in theme or pass a .creatortheme file\"
},
{ {
\"Name\" : \"-presentationMode\", \"Name\" : \"-presentationMode\",
\"Description\" : \"Enable presentation mode with pop-ups for key combos\" \"Description\" : \"Enable presentation mode with pop-ups for key combos\"

View File

@@ -26,6 +26,8 @@
<file>images/locked@2x.png</file> <file>images/locked@2x.png</file>
<file>images/magnifier.png</file> <file>images/magnifier.png</file>
<file>images/magnifier@2x.png</file> <file>images/magnifier@2x.png</file>
<file>images/dark_magnifier.png</file>
<file>images/dark_magnifier@2x.png</file>
<file>images/minus.png</file> <file>images/minus.png</file>
<file>images/next.png</file> <file>images/next.png</file>
<file>images/panel_button.png</file> <file>images/panel_button.png</file>
@@ -103,5 +105,7 @@
<file>images/warning@2x.png</file> <file>images/warning@2x.png</file>
<file>images/info.png</file> <file>images/info.png</file>
<file>images/info@2x.png</file> <file>images/info@2x.png</file>
<file>images/dark_fileicon.png</file>
<file>images/dark_foldericon.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -101,6 +101,7 @@ const char OPTIONS[] = "QtCreator.Options";
const char TOGGLE_SIDEBAR[] = "QtCreator.ToggleSidebar"; const char TOGGLE_SIDEBAR[] = "QtCreator.ToggleSidebar";
const char TOGGLE_MODE_SELECTOR[] = "QtCreator.ToggleModeSelector"; const char TOGGLE_MODE_SELECTOR[] = "QtCreator.ToggleModeSelector";
const char TOGGLE_FULLSCREEN[] = "QtCreator.ToggleFullScreen"; const char TOGGLE_FULLSCREEN[] = "QtCreator.ToggleFullScreen";
const char THEMEOPTIONS[] = "QtCreator.ThemeOptions";
const char TR_SHOW_SIDEBAR[] = QT_TRANSLATE_NOOP("Core", "Show Sidebar"); const char TR_SHOW_SIDEBAR[] = QT_TRANSLATE_NOOP("Core", "Show Sidebar");
const char TR_HIDE_SIDEBAR[] = QT_TRANSLATE_NOOP("Core", "Hide Sidebar"); const char TR_HIDE_SIDEBAR[] = QT_TRANSLATE_NOOP("Core", "Hide Sidebar");
@@ -241,6 +242,8 @@ const char SETTINGS_ID_MIMETYPES[] = "D.MimeTypes";
const char SETTINGS_DEFAULTTEXTENCODING[] = "General/DefaultFileEncoding"; const char SETTINGS_DEFAULTTEXTENCODING[] = "General/DefaultFileEncoding";
const char SETTINGS_THEME[] = "Core/CreatorTheme";
const char ALL_FILES_FILTER[] = QT_TRANSLATE_NOOP("Core", "All Files (*)"); const char ALL_FILES_FILTER[] = QT_TRANSLATE_NOOP("Core", "All Files (*)");
const char TR_CLEAR_MENU[] = QT_TRANSLATE_NOOP("Core", "Clear Menu"); const char TR_CLEAR_MENU[] = QT_TRANSLATE_NOOP("Core", "Clear Menu");

View File

@@ -42,23 +42,30 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/find/findplugin.h> #include <coreplugin/find/findplugin.h>
#include <coreplugin/locator/locator.h> #include <coreplugin/locator/locator.h>
#include <coreplugin/coreconstants.h>
#include <utils/macroexpander.h> #include <utils/macroexpander.h>
#include <utils/savefile.h> #include <utils/savefile.h>
#include <utils/stringutils.h>
#include <utils/theme/theme.h>
#include <QtPlugin> #include <QtPlugin>
#include <QDebug> #include <QDebug>
#include <QDateTime> #include <QDateTime>
#include <QDir>
using namespace Core; using namespace Core;
using namespace Core::Internal; using namespace Core::Internal;
using namespace Utils;
CorePlugin::CorePlugin() : m_editMode(0), m_designMode(0) CorePlugin::CorePlugin()
: m_mainWindow(0)
, m_editMode(0)
, m_designMode(0)
, m_findPlugin(0)
, m_locator(0)
{ {
qRegisterMetaType<Core::Id>(); qRegisterMetaType<Core::Id>();
m_mainWindow = new MainWindow;
m_findPlugin = new FindPlugin;
m_locator = new Locator;
} }
CorePlugin::~CorePlugin() CorePlugin::~CorePlugin()
@@ -84,15 +91,55 @@ CorePlugin::~CorePlugin()
void CorePlugin::parseArguments(const QStringList &arguments) void CorePlugin::parseArguments(const QStringList &arguments)
{ {
QString themeName = QLatin1String("default");
QColor overrideColor;
bool overrideTheme = false;
for (int i = 0; i < arguments.size(); ++i) { for (int i = 0; i < arguments.size(); ++i) {
if (arguments.at(i) == QLatin1String("-color")) { if (arguments.at(i) == QLatin1String("-color")) {
const QString colorcode(arguments.at(i + 1)); const QString colorcode(arguments.at(i + 1));
m_mainWindow->setOverrideColor(QColor(colorcode)); overrideColor = QColor(colorcode);
i++; // skip the argument i++; // skip the argument
} }
if (arguments.at(i) == QLatin1String("-presentationMode")) if (arguments.at(i) == QLatin1String("-presentationMode"))
ActionManager::setPresentationModeEnabled(true); ActionManager::setPresentationModeEnabled(true);
if (arguments.at(i) == QLatin1String("-theme")) {
overrideTheme = true;
themeName = arguments.at(i + 1);
i++;
}
} }
QSettings *settings = Core::ICore::settings();
QString themeURI = settings->value(QLatin1String(Core::Constants::SETTINGS_THEME)).toString();
if (!QFileInfo::exists(themeURI) || overrideTheme) {
const QString builtInTheme = QStringLiteral("%1/themes/%2.creatortheme")
.arg(ICore::resourcePath()).arg(themeName);
if (QFile::exists(builtInTheme)) {
themeURI = builtInTheme;
} else if (themeName.endsWith(QLatin1String(".creatortheme"))) {
themeURI = themeName;
} else { // TODO: Fallback to default theme
qCritical("%s", qPrintable(QCoreApplication::translate("Application", "No valid theme '%1'")
.arg(themeName)));
}
}
QSettings themeSettings(themeURI, QSettings::IniFormat);
Theme *theme = new Theme(qApp);
theme->readSettings(themeSettings);
setCreatorTheme(theme);
qApp->setPalette(creatorTheme()->palette(qApp->palette()));
// defer creation of these widgets until here,
// because they need a valid theme set
m_mainWindow = new MainWindow;
m_findPlugin = new FindPlugin;
m_locator = new Locator;
if (overrideColor.isValid())
m_mainWindow->setOverrideColor(overrideColor);
} }
bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage) bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage)

View File

@@ -16,6 +16,7 @@ SOURCES += corejsextensions.cpp \
fancyactionbar.cpp \ fancyactionbar.cpp \
fancytabwidget.cpp \ fancytabwidget.cpp \
generalsettings.cpp \ generalsettings.cpp \
themesettings.cpp \
id.cpp \ id.cpp \
icontext.cpp \ icontext.cpp \
jsexpander.cpp \ jsexpander.cpp \
@@ -101,7 +102,15 @@ SOURCES += corejsextensions.cpp \
ioutputpane.cpp \ ioutputpane.cpp \
patchtool.cpp \ patchtool.cpp \
windowsupport.cpp \ windowsupport.cpp \
opendocumentstreeview.cpp opendocumentstreeview.cpp \
themeeditor/themecolors.cpp \
themeeditor/themecolorstableview.cpp \
themeeditor/colorvariable.cpp \
themeeditor/themeeditorwidget.cpp \
themeeditor/colorrole.cpp \
themeeditor/themesettingstablemodel.cpp \
themeeditor/sectionedtablemodel.cpp \
themeeditor/themesettingsitemdelegate.cpp
HEADERS += corejsextensions.h \ HEADERS += corejsextensions.h \
mainwindow.h \ mainwindow.h \
@@ -111,6 +120,7 @@ HEADERS += corejsextensions.h \
fancyactionbar.h \ fancyactionbar.h \
fancytabwidget.h \ fancytabwidget.h \
generalsettings.h \ generalsettings.h \
themesettings.h \
id.h \ id.h \
jsexpander.h \ jsexpander.h \
messagemanager.h \ messagemanager.h \
@@ -206,18 +216,28 @@ HEADERS += corejsextensions.h \
dialogs/addtovcsdialog.h \ dialogs/addtovcsdialog.h \
patchtool.h \ patchtool.h \
windowsupport.h \ windowsupport.h \
opendocumentstreeview.h opendocumentstreeview.h \
themeeditor/themecolors.h \
themeeditor/themecolorstableview.h \
themeeditor/colorvariable.h \
themeeditor/themeeditorwidget.h \
themeeditor/colorrole.h \
themeeditor/themesettingstablemodel.h \
themeeditor/sectionedtablemodel.h \
themeeditor/themesettingsitemdelegate.h \
FORMS += dialogs/newdialog.ui \ FORMS += dialogs/newdialog.ui \
dialogs/saveitemsdialog.ui \ dialogs/saveitemsdialog.ui \
dialogs/readonlyfilesdialog.ui \ dialogs/readonlyfilesdialog.ui \
dialogs/openwithdialog.ui \ dialogs/openwithdialog.ui \
generalsettings.ui \ generalsettings.ui \
themesettings.ui \
dialogs/externaltoolconfig.ui \ dialogs/externaltoolconfig.ui \
mimetypesettingspage.ui \ mimetypesettingspage.ui \
mimetypemagicdialog.ui \ mimetypemagicdialog.ui \
removefiledialog.ui \ removefiledialog.ui \
dialogs/addtovcsdialog.ui dialogs/addtovcsdialog.ui \
themeeditor/themeeditorwidget.ui
RESOURCES += core.qrc \ RESOURCES += core.qrc \
fancyactionbar.qrc fancyactionbar.qrc

View File

@@ -285,6 +285,30 @@ QtcPlugin {
] ]
} }
Group {
name: "ThemeEditor"
prefix: "themeeditor/"
files: [
"colorrole.cpp",
"colorrole.h",
"colorvariable.cpp",
"colorvariable.h",
"sectionedtablemodel.cpp",
"sectionedtablemodel.h",
"themecolors.cpp",
"themecolors.h",
"themecolorstableview.cpp",
"themecolorstableview.h",
"themeeditorwidget.cpp",
"themeeditorwidget.h",
"themeeditorwidget.ui",
"themesettingsitemdelegate.cpp",
"themesettingsitemdelegate.h",
"themesettingstablemodel.cpp",
"themesettingstablemodel.h",
]
}
Export { Export {
Depends { name: "Aggregation" } Depends { name: "Aggregation" }
Depends { name: "Utils" } Depends { name: "Utils" }

View File

@@ -42,6 +42,7 @@
#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/findplaceholder.h> #include <coreplugin/findplaceholder.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/theme/theme.h>
#include <QDebug> #include <QDebug>
@@ -56,7 +57,7 @@
using namespace Core; using namespace Core;
using namespace Core::Internal; using namespace Core::Internal;
using namespace Utils;
// ================EditorView==================== // ================EditorView====================
@@ -244,11 +245,17 @@ void EditorView::paintEvent(QPaintEvent *)
// Discreet indication where an editor would be if there is none // Discreet indication where an editor would be if there is none
QPainter painter(this); QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(Qt::NoPen); QRect rect = m_container->geometry();
painter.setBrush(palette().color(QPalette::Background).darker(107)); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
const int r = 3; painter.setRenderHint(QPainter::Antialiasing, true);
painter.drawRoundedRect(m_container->geometry().adjusted(r , r, -r, -r), r * 2, r * 2); painter.setPen(Qt::NoPen);
painter.setBrush(creatorTheme()->color(Theme::EditorPlaceholderColor));
const int r = 3;
painter.drawRoundedRect(rect.adjusted(r , r, -r, -r), r * 2, r * 2);
} else {
painter.fillRect(rect, creatorTheme()->color(Theme::EditorPlaceholderColor));
}
} }
void EditorView::mousePressEvent(QMouseEvent *e) void EditorView::mousePressEvent(QMouseEvent *e)

View File

@@ -36,6 +36,7 @@
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <utils/tooltip/tooltip.h> #include <utils/tooltip/tooltip.h>
#include <utils/tooltip/tipcontents.h> #include <utils/tooltip/tipcontents.h>
#include <utils/theme/theme.h>
#include <QPainter> #include <QPainter>
#include <QVBoxLayout> #include <QVBoxLayout>
@@ -145,30 +146,41 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
if (!Utils::HostOsInfo::isMacHost() // Mac UIs usually don't hover if (!Utils::HostOsInfo::isMacHost() // Mac UIs usually don't hover
&& m_fader > 0 && isEnabled() && !isDown() && !isChecked()) { && m_fader > 0 && isEnabled() && !isDown() && !isChecked()) {
painter.save(); painter.save();
int fader = int(40 * m_fader); const QColor hoverColor = creatorTheme()->color(Theme::FancyToolButtonHoverColor);
QLinearGradient grad(rect().topLeft(), rect().topRight()); QColor fadedHoverColor = hoverColor;
grad.setColorAt(0, Qt::transparent); fadedHoverColor.setAlpha(int(m_fader * hoverColor.alpha()));
grad.setColorAt(0.5, QColor(255, 255, 255, fader)); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
grad.setColorAt(1, Qt::transparent); QLinearGradient grad(rect().topLeft(), rect().topRight());
painter.fillRect(rect(), grad); grad.setColorAt(0, Qt::transparent);
painter.setPen(QPen(grad, 1.0)); grad.setColorAt(0.5, fadedHoverColor);
painter.drawLine(rect().topLeft(), rect().topRight()); grad.setColorAt(1, Qt::transparent);
painter.drawLine(rect().bottomLeft(), rect().bottomRight()); painter.fillRect(rect(), grad);
painter.setPen(QPen(grad, 1.0));
painter.drawLine(rect().topLeft(), rect().topRight());
painter.drawLine(rect().bottomLeft(), rect().bottomRight());
} else {
painter.fillRect(rect(), fadedHoverColor);
}
painter.restore(); painter.restore();
} else if (isDown() || isChecked()) { } else if (isDown() || isChecked()) {
painter.save(); painter.save();
QLinearGradient grad(rect().topLeft(), rect().topRight()); const QColor selectedColor = creatorTheme()->color(Theme::FancyToolButtonSelectedColor);
grad.setColorAt(0, Qt::transparent); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
grad.setColorAt(0.5, QColor(0, 0, 0, 50)); QLinearGradient grad(rect().topLeft(), rect().topRight());
grad.setColorAt(1, Qt::transparent); grad.setColorAt(0, Qt::transparent);
painter.fillRect(rect(), grad); grad.setColorAt(0.5, selectedColor);
painter.setPen(QPen(grad, 1.0)); grad.setColorAt(1, Qt::transparent);
painter.drawLine(rect().topLeft(), rect().topRight()); painter.fillRect(rect(), grad);
painter.drawLine(rect().topLeft(), rect().topRight()); painter.setPen(QPen(grad, 1.0));
painter.drawLine(rect().topLeft() + QPoint(0,1), rect().topRight() + QPoint(0,1)); painter.drawLine(rect().topLeft(), rect().topRight());
painter.drawLine(rect().bottomLeft(), rect().bottomRight()); painter.drawLine(rect().topLeft(), rect().topRight());
painter.drawLine(rect().bottomLeft(), rect().bottomRight()); painter.drawLine(rect().topLeft() + QPoint(0,1), rect().topRight() + QPoint(0,1));
painter.drawLine(rect().topLeft() - QPoint(0,1), rect().topRight() - QPoint(0,1)); painter.drawLine(rect().bottomLeft(), rect().bottomRight());
painter.drawLine(rect().bottomLeft(), rect().bottomRight());
painter.drawLine(rect().topLeft() - QPoint(0,1), rect().topRight() - QPoint(0,1));
} else {
painter.fillRect(rect(), selectedColor);
}
painter.restore(); painter.restore();
} }
@@ -261,7 +273,13 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
void FancyActionBar::paintEvent(QPaintEvent *event) void FancyActionBar::paintEvent(QPaintEvent *event)
{ {
QPainter painter(this); QPainter painter(this);
Q_UNUSED(event)
if (creatorTheme()->widgetStyle () == Theme::StyleFlat) {
// this paints the background of the bottom portion of the
// left tab bar
painter.fillRect(event->rect(), creatorTheme()->color(Theme::FancyTabBarBackgroundColor));
}
QColor light = Utils::StyleHelper::sidebarHighlight(); QColor light = Utils::StyleHelper::sidebarHighlight();
QColor dark = Utils::StyleHelper::sidebarShadow(); QColor dark = Utils::StyleHelper::sidebarShadow();
painter.setPen(dark); painter.setPen(dark);

View File

@@ -32,6 +32,7 @@
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/styledbar.h> #include <utils/styledbar.h>
#include <utils/theme/theme.h>
#include <QDebug> #include <QDebug>
@@ -47,6 +48,7 @@
using namespace Core; using namespace Core;
using namespace Internal; using namespace Internal;
using namespace Utils;
const int FancyTabBar::m_rounding = 22; const int FancyTabBar::m_rounding = 22;
const int FancyTabBar::m_textPadding = 4; const int FancyTabBar::m_textPadding = 4;
@@ -115,8 +117,12 @@ QSize FancyTabBar::tabSizeHint(bool minimum) const
void FancyTabBar::paintEvent(QPaintEvent *event) void FancyTabBar::paintEvent(QPaintEvent *event)
{ {
Q_UNUSED(event)
QPainter p(this); QPainter p(this);
if (creatorTheme()->widgetStyle() == Theme::StyleFlat) {
// draw background of upper part of left tab widget
// (Welcome, ... Help)
p.fillRect (event->rect(), creatorTheme()->color(Theme::FancyTabBarBackgroundColor));
}
for (int i = 0; i < count(); ++i) for (int i = 0; i < count(); ++i)
if (i != currentIndex()) if (i != currentIndex())
@@ -245,29 +251,35 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const
bool enabled = isTabEnabled(tabIndex); bool enabled = isTabEnabled(tabIndex);
if (selected) { if (selected) {
//background if (creatorTheme()->widgetStyle() == Theme::StyleFlat) {
painter->save(); // background color of a fancy tab that is active
QLinearGradient grad(rect.topLeft(), rect.topRight()); painter->fillRect(rect.adjusted(0, 0, 0, -1),
grad.setColorAt(0, QColor(255, 255, 255, 140)); creatorTheme()->color(Theme::BackgroundColorSelected));
grad.setColorAt(1, QColor(255, 255, 255, 210)); } else {
painter->fillRect(rect.adjusted(0, 0, 0, -1), grad); //background
painter->restore(); painter->save();
QLinearGradient grad(rect.topLeft(), rect.topRight());
grad.setColorAt(0, QColor(255, 255, 255, 140));
grad.setColorAt(1, QColor(255, 255, 255, 210));
painter->fillRect(rect.adjusted(0, 0, 0, -1), grad);
painter->restore();
//shadows //shadows
painter->setPen(QColor(0, 0, 0, 110)); painter->setPen(QColor(0, 0, 0, 110));
painter->drawLine(rect.topLeft() + QPoint(1,-1), rect.topRight() - QPoint(0,1)); painter->drawLine(rect.topLeft() + QPoint(1,-1), rect.topRight() - QPoint(0,1));
painter->drawLine(rect.bottomLeft(), rect.bottomRight()); painter->drawLine(rect.bottomLeft(), rect.bottomRight());
painter->setPen(QColor(0, 0, 0, 40)); painter->setPen(QColor(0, 0, 0, 40));
painter->drawLine(rect.topLeft(), rect.bottomLeft()); painter->drawLine(rect.topLeft(), rect.bottomLeft());
//highlights //highlights
painter->setPen(QColor(255, 255, 255, 50)); painter->setPen(QColor(255, 255, 255, 50));
painter->drawLine(rect.topLeft() + QPoint(0, -2), rect.topRight() - QPoint(0,2)); painter->drawLine(rect.topLeft() + QPoint(0, -2), rect.topRight() - QPoint(0,2));
painter->drawLine(rect.bottomLeft() + QPoint(0, 1), rect.bottomRight() + QPoint(0,1)); painter->drawLine(rect.bottomLeft() + QPoint(0, 1), rect.bottomRight() + QPoint(0,1));
painter->setPen(QColor(255, 255, 255, 40)); painter->setPen(QColor(255, 255, 255, 40));
painter->drawLine(rect.topLeft() + QPoint(0, 0), rect.topRight()); painter->drawLine(rect.topLeft() + QPoint(0, 0), rect.topRight());
painter->drawLine(rect.topRight() + QPoint(0, 1), rect.bottomRight() - QPoint(0, 1)); painter->drawLine(rect.topRight() + QPoint(0, 1), rect.bottomRight() - QPoint(0, 1));
painter->drawLine(rect.bottomLeft() + QPoint(0,-1), rect.bottomRight()-QPoint(0,1)); painter->drawLine(rect.bottomLeft() + QPoint(0,-1), rect.bottomRight()-QPoint(0,1));
}
} }
QString tabText(this->tabText(tabIndex)); QString tabText(this->tabText(tabIndex));
@@ -281,23 +293,24 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const
painter->setFont(boldFont); painter->setFont(boldFont);
painter->setPen(selected ? QColor(255, 255, 255, 160) : QColor(0, 0, 0, 110)); painter->setPen(selected ? QColor(255, 255, 255, 160) : QColor(0, 0, 0, 110));
const int textFlags = Qt::AlignCenter | (drawIcon ? Qt::AlignBottom : Qt::AlignVCenter) | Qt::TextWordWrap; const int textFlags = Qt::AlignCenter | (drawIcon ? Qt::AlignBottom : Qt::AlignVCenter) | Qt::TextWordWrap;
if (enabled) {
painter->drawText(tabTextRect, textFlags, tabText);
painter->setPen(selected ? QColor(60, 60, 60) : Utils::StyleHelper::panelTextColor());
} else {
painter->setPen(selected ? Utils::StyleHelper::panelTextColor() : QColor(255, 255, 255, 120));
}
if (!Utils::HostOsInfo::isMacHost() && !selected && enabled) { if (!Utils::HostOsInfo::isMacHost() && !selected && enabled) {
painter->save(); painter->save();
int fader = int(m_tabs[tabIndex]->fader()); int fader = int(m_tabs[tabIndex]->fader());
QLinearGradient grad(rect.topLeft(), rect.topRight()); if (creatorTheme()->widgetStyle() == Theme::StyleFlat) {
grad.setColorAt(0, Qt::transparent); QColor c = creatorTheme()->color(Theme::BackgroundColorHover);
grad.setColorAt(0.5, QColor(255, 255, 255, fader)); c.setAlpha(int(255 * fader/40.0)); // FIXME: hardcoded end value 40
grad.setColorAt(1, Qt::transparent); painter->fillRect(rect, c);
painter->fillRect(rect, grad); } else {
painter->setPen(QPen(grad, 1.0)); QLinearGradient grad(rect.topLeft(), rect.topRight());
painter->drawLine(rect.topLeft(), rect.topRight()); grad.setColorAt(0, Qt::transparent);
painter->drawLine(rect.bottomLeft(), rect.bottomRight()); grad.setColorAt(0.5, QColor(255, 255, 255, fader));
grad.setColorAt(1, Qt::transparent);
painter->fillRect(rect, grad);
painter->setPen(QPen(grad, 1.0));
painter->drawLine(rect.topLeft(), rect.topRight());
painter->drawLine(rect.bottomLeft(), rect.bottomRight());
}
painter->restore(); painter->restore();
} }
@@ -310,8 +323,19 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const
Utils::StyleHelper::drawIconWithShadow(tabIcon(tabIndex), tabIconRect, painter, enabled ? QIcon::Normal : QIcon::Disabled); Utils::StyleHelper::drawIconWithShadow(tabIcon(tabIndex), tabIconRect, painter, enabled ? QIcon::Normal : QIcon::Disabled);
} }
painter->setOpacity(1.0); //FIXME: was 0.7 before?
if (enabled) {
painter->setPen(selected
? creatorTheme()->color(Theme::FancyTabWidgetEnabledSelectedTextColor)
: creatorTheme()->color(Theme::FancyTabWidgetEnabledUnselectedTextColor));
} else {
painter->setPen(selected
? creatorTheme()->color(Theme::FancyTabWidgetDisabledSelectedTextColor)
: creatorTheme()->color(Theme::FancyTabWidgetDisabledUnselectedTextColor));
}
painter->translate(0, -1); painter->translate(0, -1);
painter->drawText(tabTextRect, textFlags, tabText); painter->drawText(tabTextRect, textFlags, tabText);
painter->restore(); painter->restore();
} }

View File

@@ -39,6 +39,7 @@
#include <aggregation/aggregate.h> #include <aggregation/aggregate.h>
#include <coreplugin/coreplugin.h> #include <coreplugin/coreplugin.h>
#include <utils/theme/theme.h>
#include <QDir> #include <QDir>
#include <QFrame> #include <QFrame>
@@ -52,6 +53,8 @@
static const int SEARCHRESULT_WARNING_LIMIT = 200000; static const int SEARCHRESULT_WARNING_LIMIT = 200000;
static const char SIZE_WARNING_ID[] = "sizeWarningLabel"; static const char SIZE_WARNING_ID[] = "sizeWarningLabel";
using namespace Utils;
namespace Core { namespace Core {
namespace Internal { namespace Internal {
@@ -93,11 +96,13 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
QFrame *topWidget = new QFrame; QFrame *topWidget = new QFrame;
QPalette pal; QPalette pal;
pal.setColor(QPalette::Window, QColor(255, 255, 225)); pal.setColor(QPalette::Window, creatorTheme()->color(Theme::SearchResultWidgetBackgroundColor));
pal.setColor(QPalette::WindowText, Qt::black); pal.setColor(QPalette::WindowText, creatorTheme()->color(Theme::SearchResultWidgetTextColor));
topWidget->setPalette(pal); topWidget->setPalette(pal);
topWidget->setFrameStyle(QFrame::Panel | QFrame::Raised); if (creatorTheme()->flag(Theme::DrawSearchResultWidgetFrame)) {
topWidget->setLineWidth(1); topWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
topWidget->setLineWidth(1);
}
topWidget->setAutoFillBackground(true); topWidget->setAutoFillBackground(true);
QHBoxLayout *topLayout = new QHBoxLayout(topWidget); QHBoxLayout *topLayout = new QHBoxLayout(topWidget);
topLayout->setMargin(2); topLayout->setMargin(2);
@@ -105,10 +110,12 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
layout->addWidget(topWidget); layout->addWidget(topWidget);
m_messageWidget = new QFrame; m_messageWidget = new QFrame;
pal.setColor(QPalette::WindowText, Qt::red); pal.setColor(QPalette::WindowText, creatorTheme()->color(Theme::CanceledSearchTextColor));
m_messageWidget->setPalette(pal); m_messageWidget->setPalette(pal);
m_messageWidget->setFrameStyle(QFrame::Panel | QFrame::Raised); if (creatorTheme()->flag(Theme::DrawSearchResultWidgetFrame)) {
m_messageWidget->setLineWidth(1); m_messageWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
m_messageWidget->setLineWidth(1);
}
m_messageWidget->setAutoFillBackground(true); m_messageWidget->setAutoFillBackground(true);
QHBoxLayout *messageLayout = new QHBoxLayout(m_messageWidget); QHBoxLayout *messageLayout = new QHBoxLayout(m_messageWidget);
messageLayout->setMargin(2); messageLayout->setMargin(2);

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

View File

@@ -37,6 +37,7 @@
#include "fancytabwidget.h" #include "fancytabwidget.h"
#include "documentmanager.h" #include "documentmanager.h"
#include "generalsettings.h" #include "generalsettings.h"
#include "themesettings.h"
#include "helpmanager.h" #include "helpmanager.h"
#include "idocumentfactory.h" #include "idocumentfactory.h"
#include "messagemanager.h" #include "messagemanager.h"
@@ -78,6 +79,7 @@
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/theme/theme.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
@@ -130,6 +132,7 @@ MainWindow::MainWindow() :
m_rightPaneWidget(0), m_rightPaneWidget(0),
m_versionDialog(0), m_versionDialog(0),
m_generalSettings(new GeneralSettings), m_generalSettings(new GeneralSettings),
m_themeSettings(new ThemeSettings),
m_shortcutSettings(new ShortcutSettings), m_shortcutSettings(new ShortcutSettings),
m_toolSettings(new ToolSettings), m_toolSettings(new ToolSettings),
m_mimeTypeSettings(new MimeTypeSettings), m_mimeTypeSettings(new MimeTypeSettings),
@@ -252,6 +255,7 @@ MainWindow::~MainWindow()
ExtensionSystem::PluginManager::removeObject(m_shortcutSettings); ExtensionSystem::PluginManager::removeObject(m_shortcutSettings);
ExtensionSystem::PluginManager::removeObject(m_generalSettings); ExtensionSystem::PluginManager::removeObject(m_generalSettings);
ExtensionSystem::PluginManager::removeObject(m_themeSettings);
ExtensionSystem::PluginManager::removeObject(m_toolSettings); ExtensionSystem::PluginManager::removeObject(m_toolSettings);
ExtensionSystem::PluginManager::removeObject(m_mimeTypeSettings); ExtensionSystem::PluginManager::removeObject(m_mimeTypeSettings);
ExtensionSystem::PluginManager::removeObject(m_systemEditor); ExtensionSystem::PluginManager::removeObject(m_systemEditor);
@@ -263,6 +267,8 @@ MainWindow::~MainWindow()
m_shortcutSettings = 0; m_shortcutSettings = 0;
delete m_generalSettings; delete m_generalSettings;
m_generalSettings = 0; m_generalSettings = 0;
delete m_themeSettings;
m_themeSettings = 0;
delete m_toolSettings; delete m_toolSettings;
m_toolSettings = 0; m_toolSettings = 0;
delete m_mimeTypeSettings; delete m_mimeTypeSettings;
@@ -320,6 +326,7 @@ bool MainWindow::init(QString *errorMessage)
m_progressManager->init(); // needs the status bar manager m_progressManager->init(); // needs the status bar manager
ExtensionSystem::PluginManager::addObject(m_generalSettings); ExtensionSystem::PluginManager::addObject(m_generalSettings);
ExtensionSystem::PluginManager::addObject(m_themeSettings);
ExtensionSystem::PluginManager::addObject(m_shortcutSettings); ExtensionSystem::PluginManager::addObject(m_shortcutSettings);
ExtensionSystem::PluginManager::addObject(m_toolSettings); ExtensionSystem::PluginManager::addObject(m_toolSettings);
ExtensionSystem::PluginManager::addObject(m_mimeTypeSettings); ExtensionSystem::PluginManager::addObject(m_mimeTypeSettings);
@@ -628,6 +635,7 @@ void MainWindow::registerDefaultActions()
// Options Action // Options Action
mtools->appendGroup(Constants::G_TOOLS_OPTIONS); mtools->appendGroup(Constants::G_TOOLS_OPTIONS);
mtools->addSeparator(globalContext, Constants::G_TOOLS_OPTIONS); mtools->addSeparator(globalContext, Constants::G_TOOLS_OPTIONS);
m_optionsAction = new QAction(tr("&Options..."), this); m_optionsAction = new QAction(tr("&Options..."), this);
cmd = ActionManager::registerAction(m_optionsAction, Constants::OPTIONS, globalContext); cmd = ActionManager::registerAction(m_optionsAction, Constants::OPTIONS, globalContext);
if (UseMacShortcuts) { if (UseMacShortcuts) {

View File

@@ -72,6 +72,7 @@ namespace Internal {
class ActionManagerPrivate; class ActionManagerPrivate;
class FancyTabWidget; class FancyTabWidget;
class GeneralSettings; class GeneralSettings;
class ThemeSettings;
class ProgressManagerPrivate; class ProgressManagerPrivate;
class ShortcutSettings; class ShortcutSettings;
class ToolSettings; class ToolSettings;
@@ -191,6 +192,7 @@ private:
QMap<QWidget *, IContext *> m_contextWidgets; QMap<QWidget *, IContext *> m_contextWidgets;
GeneralSettings *m_generalSettings; GeneralSettings *m_generalSettings;
ThemeSettings *m_themeSettings;
ShortcutSettings *m_shortcutSettings; ShortcutSettings *m_shortcutSettings;
ToolSettings *m_toolSettings; ToolSettings *m_toolSettings;
MimeTypeSettings *m_mimeTypeSettings; MimeTypeSettings *m_mimeTypeSettings;
@@ -206,6 +208,7 @@ private:
QAction *m_optionsAction; QAction *m_optionsAction;
QAction *m_toggleSideBarAction; QAction *m_toggleSideBarAction;
QAction *m_toggleModeSelectorAction; QAction *m_toggleModeSelectorAction;
QAction *m_themeAction;
QToolButton *m_toggleSideBarButton; QToolButton *m_toggleSideBarButton;
QColor m_overrideColor; QColor m_overrideColor;

View File

@@ -38,6 +38,7 @@
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/fancymainwindow.h> #include <utils/fancymainwindow.h>
#include <utils/theme/theme.h>
#include <QApplication> #include <QApplication>
#include <QComboBox> #include <QComboBox>
@@ -53,6 +54,8 @@
#include <QToolBar> #include <QToolBar>
#include <QToolButton> #include <QToolButton>
using namespace Utils;
// We define a currently unused state for indicating animations // We define a currently unused state for indicating animations
const QStyle::State State_Animating = QStyle::State(0x00000040); const QStyle::State State_Animating = QStyle::State(0x00000040);
@@ -242,7 +245,8 @@ void ManhattanStyle::unpolish(QApplication *app)
QPalette panelPalette(const QPalette &oldPalette, bool lightColored = false) QPalette panelPalette(const QPalette &oldPalette, bool lightColored = false)
{ {
QColor color = Utils::StyleHelper::panelTextColor(lightColored); Q_UNUSED(lightColored);
QColor color = creatorTheme()->color(Theme::PanelTextColor);
QPalette pal = oldPalette; QPalette pal = oldPalette;
pal.setBrush(QPalette::All, QPalette::WindowText, color); pal.setBrush(QPalette::All, QPalette::WindowText, color);
pal.setBrush(QPalette::All, QPalette::ButtonText, color); pal.setBrush(QPalette::All, QPalette::ButtonText, color);
@@ -310,17 +314,12 @@ void ManhattanStyle::polish(QPalette &pal)
QProxyStyle::polish(pal); QProxyStyle::polish(pal);
} }
QIcon ManhattanStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const QIcon ManhattanStyle::standardIcon(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const
{ {
QIcon icon; QIcon ico = creatorTheme()->standardIcon(standardPixmap, opt, widget);
switch (standardIcon) { if (!ico.isNull())
case QStyle::SP_TitleBarCloseButton: return ico;
case QStyle::SP_ToolBarHorizontalExtensionButton: return QProxyStyle::standardIcon(standardPixmap, opt, widget);
return QIcon(standardPixmap(standardIcon, option, widget));
default:
icon = baseStyle()->standardIcon(standardIcon, option, widget);
}
return icon;
} }
QPixmap ManhattanStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, QPixmap ManhattanStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
@@ -377,8 +376,13 @@ int ManhattanStyle::styleHint(StyleHint hint, const QStyleOption *option, const
void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) const QPainter *painter, const QWidget *widget) const
{ {
if (!panelWidget(widget)) if (!panelWidget(widget)) {
if (creatorTheme()->flag(Theme::DrawIndicatorBranch) && element == PE_IndicatorBranch) {
creatorTheme()->drawIndicatorBranch(painter, option->rect, option->state);
return;
}
return QProxyStyle::drawPrimitive(element, option, painter, widget); return QProxyStyle::drawPrimitive(element, option, painter, widget);
}
bool animating = (option->state & State_Animating); bool animating = (option->state & State_Animating);
int state = option->state; int state = option->state;
@@ -437,7 +441,7 @@ void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption
switch (element) { switch (element) {
case PE_IndicatorDockWidgetResizeHandle: case PE_IndicatorDockWidgetResizeHandle:
painter->fillRect(option->rect, Utils::StyleHelper::borderColor()); painter->fillRect(option->rect, creatorTheme()->color(Theme::DockWidgetResizeHandleColor));
break; break;
case PE_FrameDockWidget: case PE_FrameDockWidget:
QCommonStyle::drawPrimitive(element, option, painter, widget); QCommonStyle::drawPrimitive(element, option, painter, widget);
@@ -491,8 +495,7 @@ void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption
QColor highlight(255, 255, 255, 30); QColor highlight(255, 255, 255, 30);
painter->setPen(highlight); painter->setPen(highlight);
} else if (option->state & State_Enabled && option->state & State_MouseOver) { } else if (option->state & State_Enabled && option->state & State_MouseOver) {
QColor lighter(255, 255, 255, 37); painter->fillRect(rect, creatorTheme()->color(Theme::PanelButtonToolBackgroundColorHover));
painter->fillRect(rect, lighter);
} else if (widget && widget->property("highlightWidget").toBool()) { } else if (widget && widget->property("highlightWidget").toBool()) {
QColor shade(0, 0, 0, 128); QColor shade(0, 0, 0, 128);
painter->fillRect(rect, shade); painter->fillRect(rect, shade);
@@ -513,15 +516,19 @@ void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption
case PE_PanelStatusBar: case PE_PanelStatusBar:
{ {
painter->save(); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
QLinearGradient grad = Utils::StyleHelper::statusBarGradient(rect); painter->save();
painter->fillRect(rect, grad); QLinearGradient grad = Utils::StyleHelper::statusBarGradient(rect);
painter->setPen(QColor(255, 255, 255, 60)); painter->fillRect(rect, grad);
painter->drawLine(rect.topLeft() + QPoint(0,1), painter->setPen(QColor(255, 255, 255, 60));
rect.topRight()+ QPoint(0,1)); painter->drawLine(rect.topLeft() + QPoint(0,1),
painter->setPen(Utils::StyleHelper::borderColor().darker(110)); rect.topRight()+ QPoint(0,1));
painter->drawLine(rect.topLeft(), rect.topRight()); painter->setPen(Utils::StyleHelper::borderColor().darker(110)); //TODO: make themable
painter->restore(); painter->drawLine(rect.topLeft(), rect.topRight());
painter->restore();
} else {
painter->fillRect(rect, creatorTheme()->color(Theme::PanelStatusBarBackgroundColor));
}
} }
break; break;
@@ -639,13 +646,20 @@ void ManhattanStyle::drawControl(ControlElement element, const QStyleOption *opt
painter->save(); painter->save();
if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
QColor highlightOutline = Utils::StyleHelper::borderColor().lighter(120); QColor highlightOutline = Utils::StyleHelper::borderColor().lighter(120);
bool act = mbi->state & (State_Sunken | State_Selected); const bool act = mbi->state & (State_Sunken | State_Selected);
bool dis = !(mbi->state & State_Enabled); const bool dis = !(mbi->state & State_Enabled);
Utils::StyleHelper::menuGradient(painter, option->rect, option->rect);
if (creatorTheme()->widgetStyle() == Theme::StyleFlat)
painter->fillRect(option->rect, creatorTheme()->color(Theme::MenuBarItemBackgroundColor));
else
Utils::StyleHelper::menuGradient(painter, option->rect, option->rect);
QStyleOptionMenuItem item = *mbi; QStyleOptionMenuItem item = *mbi;
item.rect = mbi->rect; item.rect = mbi->rect;
QPalette pal = mbi->palette; QPalette pal = mbi->palette;
pal.setBrush(QPalette::ButtonText, dis ? Qt::gray : Qt::black); pal.setBrush(QPalette::ButtonText, dis
? creatorTheme()->color(Theme::MenuBarItemTextColorDisabled)
: creatorTheme()->color(Theme::MenuBarItemTextColorNormal));
item.palette = pal; item.palette = pal;
QCommonStyle::drawControl(element, &item, painter, widget); QCommonStyle::drawControl(element, &item, painter, widget);
@@ -725,13 +739,15 @@ void ManhattanStyle::drawControl(ControlElement element, const QStyleOption *opt
} }
text.prepend(option->fontMetrics.elidedText(cb->currentText, Qt::ElideRight, elideWidth)); text.prepend(option->fontMetrics.elidedText(cb->currentText, Qt::ElideRight, elideWidth));
if ((option->state & State_Enabled)) { if (creatorTheme()->flag(Theme::ComboBoxDrawTextShadow)
&& (option->state & State_Enabled))
{
painter->setPen(QColor(0, 0, 0, 70)); painter->setPen(QColor(0, 0, 0, 70));
painter->drawText(editRect.adjusted(1, 0, -1, 0), Qt::AlignLeft | Qt::AlignVCenter, text); painter->drawText(editRect.adjusted(1, 0, -1, 0), Qt::AlignLeft | Qt::AlignVCenter, text);
} else {
painter->setOpacity(0.8);
} }
painter->setPen(Utils::StyleHelper::panelTextColor()); if (option->state & State_Enabled)
painter->setOpacity(0.8);
painter->setPen(creatorTheme()->color(Theme::ComboBoxTextColor));
painter->drawText(editRect.adjusted(1, 0, -1, 0), Qt::AlignLeft | Qt::AlignVCenter, text); painter->drawText(editRect.adjusted(1, 0, -1, 0), Qt::AlignLeft | Qt::AlignVCenter, text);
painter->restore(); painter->restore();
@@ -775,12 +791,16 @@ void ManhattanStyle::drawControl(ControlElement element, const QStyleOption *opt
break; break;
case CE_MenuBarEmptyArea: { case CE_MenuBarEmptyArea: {
Utils::StyleHelper::menuGradient(painter, option->rect, option->rect); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
painter->save(); Utils::StyleHelper::menuGradient(painter, option->rect, option->rect);
painter->setPen(Utils::StyleHelper::borderColor()); painter->save();
painter->drawLine(option->rect.bottomLeft() + QPointF(0.5, 0.5), painter->setPen(Utils::StyleHelper::borderColor());
option->rect.bottomRight() + QPointF(0.5, 0.5)); painter->drawLine(option->rect.bottomLeft() + QPointF(0.5, 0.5),
painter->restore(); option->rect.bottomRight() + QPointF(0.5, 0.5));
painter->restore();
} else {
painter->fillRect(option->rect, creatorTheme()->color(Theme::MenuBarEmptyAreaBackgroundColor));
}
} }
break; break;
@@ -799,12 +819,22 @@ void ManhattanStyle::drawControl(ControlElement element, const QStyleOption *opt
bool drawLightColored = lightColored(widget); bool drawLightColored = lightColored(widget);
if (horizontal) if (horizontal)
Utils::StyleHelper::horizontalGradient(painter, gradientSpan, rect, drawLightColored); {
else // draws the background of the 'Type hierarchy', 'Projects' headers
Utils::StyleHelper::verticalGradient(painter, gradientSpan, rect, drawLightColored); if (creatorTheme()->widgetStyle() == Theme::StyleFlat)
painter->fillRect (rect, creatorTheme()->color(Theme::ToolBarBackgroundColor));
else
Utils::StyleHelper::horizontalGradient(painter, gradientSpan, rect, drawLightColored);
} else {
if (creatorTheme()->widgetStyle() == Theme::StyleFlat)
painter->fillRect (rect, creatorTheme()->color(Theme::ToolBarBackgroundColor));
else
Utils::StyleHelper::verticalGradient(painter, gradientSpan, rect, drawLightColored);
}
if (!drawLightColored) if (!drawLightColored) {
painter->setPen(Utils::StyleHelper::borderColor()); painter->setPen(Utils::StyleHelper::borderColor());
}
else else
painter->setPen(QColor(0x888888)); painter->setPen(QColor(0x888888));

View File

@@ -56,6 +56,7 @@ public:
SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = 0) const; SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = 0) const;
QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = 0) const; QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = 0) const;
QIcon standardIcon(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = 0) const;
int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const; int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const;
QRect itemRect(QPainter *p, const QRect &r, int flags, bool enabled, const QPixmap *pixmap, const QString &text, int len = -1) const; QRect itemRect(QPainter *p, const QRect &r, int flags, bool enabled, const QPixmap *pixmap, const QString &text, int len = -1) const;
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const; QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const;
@@ -71,9 +72,6 @@ public:
void unpolish(QWidget *widget); void unpolish(QWidget *widget);
void unpolish(QApplication *app); void unpolish(QApplication *app);
protected slots:
QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const;
private: private:
void drawButtonSeparator(QPainter *painter, const QRect &rect, bool reverse) const; void drawButtonSeparator(QPainter *painter, const QRect &rect, bool reverse) const;

View File

@@ -49,6 +49,7 @@
#include <utils/styledbar.h> #include <utils/styledbar.h>
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/theme/theme.h>
#include <QDebug> #include <QDebug>
@@ -65,6 +66,8 @@
#include <QToolButton> #include <QToolButton>
#include <QTimeLine> #include <QTimeLine>
using namespace Utils;
namespace Core { namespace Core {
namespace Internal { namespace Internal {
@@ -675,24 +678,44 @@ void OutputPaneToggleButton::paintEvent(QPaintEvent*)
styleOption.initFrom(this); styleOption.initFrom(this);
const bool hovered = !Utils::HostOsInfo::isMacHost() && (styleOption.state & QStyle::State_MouseOver); const bool hovered = !Utils::HostOsInfo::isMacHost() && (styleOption.state & QStyle::State_MouseOver);
QImage const* image = 0; const QImage *image = 0;
if (isDown()) if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
image = &panelButtonPressed; if (isDown())
else if (isChecked()) image = &panelButtonPressed;
image = hovered ? &panelButtonCheckedHover : &panelButtonChecked; else if (isChecked())
else image = hovered ? &panelButtonCheckedHover : &panelButtonChecked;
image = hovered ? &panelButtonHover : &panelButton; else
if (image) image = hovered ? &panelButtonHover : &panelButton;
Utils::StyleHelper::drawCornerImage(*image, &p, rect(), numberAreaWidth, buttonBorderWidth, buttonBorderWidth, buttonBorderWidth); if (image)
Utils::StyleHelper::drawCornerImage(*image, &p, rect(), numberAreaWidth, buttonBorderWidth, buttonBorderWidth, buttonBorderWidth);
} else {
QColor c;
if (isChecked()) {
c = creatorTheme()->color(hovered ? Theme::BackgroundColorHover
: Theme::BackgroundColorSelected);
} else if (isDown()) {
c = creatorTheme()->color(Theme::BackgroundColorSelected);
} else {
c = creatorTheme()->color(hovered ? Theme::BackgroundColorHover
: Theme::BackgroundColorDark);
}
p.fillRect(rect(), c);
}
if (m_flashTimer->state() == QTimeLine::Running) if (m_flashTimer->state() == QTimeLine::Running)
p.fillRect(rect().adjusted(numberAreaWidth, 1, -1, -1), QBrush(QColor(255, 0, 0, m_flashTimer->currentFrame()))); {
QColor c = creatorTheme()->color(Theme::OutputPaneButtonFlashColor);
c.setAlpha (m_flashTimer->currentFrame());
QRect r = (creatorTheme()->widgetStyle() == Theme::StyleFlat)
? rect() : rect().adjusted(numberAreaWidth, 1, -1, -1);
p.fillRect(r, c);
}
p.setFont(font()); p.setFont(font());
p.setPen(Qt::white); p.setPen(creatorTheme()->color(Theme::OutputPaneToggleButtonTextColorChecked));
p.drawText((numberAreaWidth - numberWidth) / 2, baseLine, m_number); p.drawText((numberAreaWidth - numberWidth) / 2, baseLine, m_number);
if (!isChecked()) if (!isChecked())
p.setPen(Qt::black); p.setPen(creatorTheme()->color(Theme::OutputPaneToggleButtonTextColorUnchecked));
int leftPart = numberAreaWidth + buttonBorderWidth; int leftPart = numberAreaWidth + buttonBorderWidth;
int labelWidth = 0; int labelWidth = 0;
if (!m_badgeNumberLabel.text().isEmpty()) { if (!m_badgeNumberLabel.text().isEmpty()) {
@@ -751,8 +774,10 @@ QSize OutputPaneManageButton::sizeHint() const
void OutputPaneManageButton::paintEvent(QPaintEvent*) void OutputPaneManageButton::paintEvent(QPaintEvent*)
{ {
QPainter p(this); QPainter p(this);
static const QImage button(Utils::StyleHelper::dpiSpecificImageFile(QStringLiteral(":/core/images/panel_manage_button.png"))); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
Utils::StyleHelper::drawCornerImage(button, &p, rect(), buttonBorderWidth, buttonBorderWidth, buttonBorderWidth, buttonBorderWidth); static const QImage button(Utils::StyleHelper::dpiSpecificImageFile(QStringLiteral(":/core/images/panel_manage_button.png")));
Utils::StyleHelper::drawCornerImage(button, &p, rect(), buttonBorderWidth, buttonBorderWidth, buttonBorderWidth, buttonBorderWidth);
}
QStyle *s = style(); QStyle *s = style();
QStyleOption arrowOpt; QStyleOption arrowOpt;
arrowOpt.initFrom(this); arrowOpt.initFrom(this);
@@ -775,13 +800,15 @@ void BadgeLabel::paint(QPainter *p, int x, int y, bool isChecked)
const QRectF rect(QRect(QPoint(x, y), m_size)); const QRectF rect(QRect(QPoint(x, y), m_size));
p->save(); p->save();
p->setBrush(isChecked ? QColor(0xe0, 0xe0, 0xe0) : Qt::darkGray); p->setBrush(creatorTheme()->color(isChecked? Theme::BadgeLabelBackgroundColorChecked
: Theme::BadgeLabelBackgroundColorUnchecked));
p->setPen(Qt::NoPen); p->setPen(Qt::NoPen);
p->setRenderHint(QPainter::Antialiasing, true); p->setRenderHint(QPainter::Antialiasing, true);
p->drawRoundedRect(rect, m_padding, m_padding, Qt::AbsoluteSize); p->drawRoundedRect(rect, m_padding, m_padding, Qt::AbsoluteSize);
p->setFont(m_font); p->setFont(m_font);
p->setPen(isChecked ? QColor(0x60, 0x60, 0x60) : Qt::white); p->setPen(creatorTheme()->color(isChecked ? Theme::BadgeLabelTextColorChecked
: Theme::BadgeLabelTextColorUnchecked));
p->drawText(rect, Qt::AlignCenter, m_text); p->drawText(rect, Qt::AlignCenter, m_text);
p->restore(); p->restore();

View File

@@ -32,6 +32,7 @@
#include "progressbar.h" #include "progressbar.h"
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/theme/theme.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QFutureWatcher> #include <QFutureWatcher>
@@ -48,6 +49,8 @@
const int notificationTimeout = 8000; const int notificationTimeout = 8000;
const int shortNotificationTimeout = 1000; const int shortNotificationTimeout = 1000;
using namespace Utils;
namespace Core { namespace Core {
class FutureProgressPrivate : public QObject class FutureProgressPrivate : public QObject
@@ -295,8 +298,12 @@ void FutureProgress::mousePressEvent(QMouseEvent *event)
void FutureProgress::paintEvent(QPaintEvent *) void FutureProgress::paintEvent(QPaintEvent *)
{ {
QPainter p(this); QPainter p(this);
QLinearGradient grad = Utils::StyleHelper::statusBarGradient(rect()); if (creatorTheme()->widgetStyle() == Theme::StyleFlat) {
p.fillRect(rect(), grad); p.fillRect(rect(), creatorTheme()->color(Theme::FutureProgressBackgroundColor));
} else {
QLinearGradient grad = Utils::StyleHelper::statusBarGradient(rect());
p.fillRect(rect(), grad);
}
} }
/*! /*!

View File

@@ -31,6 +31,7 @@
#include "progressbar.h" #include "progressbar.h"
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/theme/theme.h>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QPainter> #include <QPainter>
@@ -40,6 +41,7 @@
using namespace Core; using namespace Core;
using namespace Core::Internal; using namespace Core::Internal;
using namespace Utils;
static const int PROGRESSBAR_HEIGHT = 13; static const int PROGRESSBAR_HEIGHT = 13;
static const int CANCELBUTTON_WIDTH = 16; static const int CANCELBUTTON_WIDTH = 16;
@@ -277,7 +279,7 @@ void ProgressBar::paintEvent(QPaintEvent *)
p.setPen(QColor(0, 0, 0, 120)); p.setPen(QColor(0, 0, 0, 120));
p.drawText(textRect, alignment | Qt::AlignBottom, elidedtitle); p.drawText(textRect, alignment | Qt::AlignBottom, elidedtitle);
p.translate(0, -1); p.translate(0, -1);
p.setPen(Utils::StyleHelper::panelTextColor()); p.setPen(creatorTheme()->color(Theme::ProgressBarTitleColor));
p.drawText(textRect, alignment | Qt::AlignBottom, elidedtitle); p.drawText(textRect, alignment | Qt::AlignBottom, elidedtitle);
p.translate(0, 1); p.translate(0, 1);
} }
@@ -287,23 +289,23 @@ void ProgressBar::paintEvent(QPaintEvent *)
// draw outer rect // draw outer rect
const QRect rect(INDENT - 1, titleHeight + separatorHeight + (m_titleVisible ? 4 : 3), const QRect rect(INDENT - 1, titleHeight + separatorHeight + (m_titleVisible ? 4 : 3),
size().width() - 2 * INDENT + 1, m_progressHeight); size().width() - 2 * INDENT + 1, m_progressHeight);
Utils::StyleHelper::drawCornerImage(bar, &p, rect, 3, 3, 3, 3);
if (creatorTheme()->flag(Theme::DrawProgressBarSunken))
Utils::StyleHelper::drawCornerImage(bar, &p, rect, 3, 3, 3, 3);
// draw inner rect // draw inner rect
QColor c = Utils::StyleHelper::panelTextColor(); QColor c = creatorTheme()->color(Theme::ProgressBarColorNormal);
c.setAlpha(180);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
QRectF inner = rect.adjusted(2, 2, -2, -2); QRectF inner = rect.adjusted(2, 2, -2, -2);
inner.adjust(0, 0, qRound((percent - 1) * inner.width()), 0); inner.adjust(0, 0, qRound((percent - 1) * inner.width()), 0);
if (m_error) { if (m_error) {
QColor red(255, 60, 0, 210); c = creatorTheme()->color(Theme::ProgressBarColorError);
c = red;
// avoid too small red bar // avoid too small red bar
if (inner.width() < 10) if (inner.width() < 10)
inner.adjust(0, 0, 10 - inner.width(), 0); inner.adjust(0, 0, 10 - inner.width(), 0);
} else if (m_finished) { } else if (m_finished) {
c = QColor(90, 170, 60); c = creatorTheme()->color(Theme::ProgressBarColorFinished);
} }
// Draw line and shadow after the gradient fill // Draw line and shadow after the gradient fill
@@ -311,13 +313,18 @@ void ProgressBar::paintEvent(QPaintEvent *)
p.fillRect(QRect(inner.right(), inner.top(), 2, inner.height()), QColor(0, 0, 0, 20)); p.fillRect(QRect(inner.right(), inner.top(), 2, inner.height()), QColor(0, 0, 0, 20));
p.fillRect(QRect(inner.right(), inner.top(), 1, inner.height()), QColor(0, 0, 0, 60)); p.fillRect(QRect(inner.right(), inner.top(), 1, inner.height()), QColor(0, 0, 0, 60));
} }
QLinearGradient grad(inner.topLeft(), inner.bottomLeft());
grad.setColorAt(0, c.lighter(130));
grad.setColorAt(0.4, c.lighter(106));
grad.setColorAt(0.41, c.darker(106));
grad.setColorAt(1, c.darker(130));
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.setBrush(grad); if (creatorTheme()->widgetStyle() == Theme::StyleFlat) {
//draw the progress bar
p.setBrush (c);
} else {
QLinearGradient grad(inner.topLeft(), inner.bottomLeft());
grad.setColorAt(0, c.lighter(130));
grad.setColorAt(0.4, c.lighter(106));
grad.setColorAt(0.41, c.darker(106));
grad.setColorAt(1, c.darker(130));
p.setBrush(grad);
}
p.drawRect(inner); p.drawRect(inner);
p.setBrush(Qt::NoBrush); p.setBrush(Qt::NoBrush);
p.setPen(QPen(QColor(0, 0, 0, 30), 1)); p.setPen(QPen(QColor(0, 0, 0, 30), 1));

View File

@@ -43,6 +43,7 @@
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/theme/theme.h>
#include <QAction> #include <QAction>
#include <QEvent> #include <QEvent>
@@ -62,6 +63,7 @@ static const char kDetailsPinned[] = "DetailsPinned";
using namespace Core; using namespace Core;
using namespace Core::Internal; using namespace Core::Internal;
using namespace Utils;
/*! /*!
\mainclass \mainclass
@@ -703,6 +705,11 @@ ToggleButton::ToggleButton(QWidget *parent)
: QToolButton(parent) : QToolButton(parent)
{ {
setToolButtonStyle(Qt::ToolButtonIconOnly); setToolButtonStyle(Qt::ToolButtonIconOnly);
if (creatorTheme()->widgetStyle() == Theme::StyleFlat) {
QPalette p = palette();
p.setBrush(QPalette::Base, creatorTheme()->color(Theme::ToggleButtonBackgroundColor));
setPalette(p);
}
} }
QSize ToggleButton::sizeHint() const QSize ToggleButton::sizeHint() const

View File

@@ -0,0 +1,58 @@
/****************************************************************************
**
** 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 "colorrole.h"
#include "colorvariable.h"
namespace Core {
namespace Internal {
namespace ThemeEditor {
ColorRole::ColorRole(const QString &roleName, QSharedPointer<ColorVariable> colorVariable)
: m_roleName(roleName),
m_roleVariable(colorVariable)
{
m_roleVariable->addReference(this);
}
QSharedPointer<ColorVariable> ColorRole::colorVariable() const
{
return m_roleVariable;
}
void ColorRole::assignColorVariable(ColorVariable::Ptr namedColor)
{
namedColor->addReference(this);
m_roleVariable = namedColor;
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -0,0 +1,67 @@
/****************************************************************************
**
** 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 COLORROLE_H
#define COLORROLE_H
#include <QString>
#include <QColor>
#include <QSharedPointer>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ColorVariable;
class ThemeColors;
class ColorRole
{
public:
friend class ThemeColors;
typedef QSharedPointer<ColorRole> Ptr;
QString roleName() const { return m_roleName; }
QSharedPointer<ColorVariable> colorVariable() const;
void assignColorVariable(QSharedPointer<ColorVariable> colorVariable);
private:
explicit ColorRole(const QString &roleName, QSharedPointer<ColorVariable> colorVariable);
QString m_roleName;
QString m_roleDescription;
QSharedPointer<ColorVariable> m_roleVariable;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // COLORROLE_H

View File

@@ -0,0 +1,73 @@
/****************************************************************************
**
** 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 "colorvariable.h"
#include "colorrole.h"
#include <utils/qtcassert.h>
namespace Core {
namespace Internal {
namespace ThemeEditor {
ColorVariable::ColorVariable(const QColor &color, const QString &name)
: m_variableValue(color)
, m_variableName(name)
{
}
ColorVariable::~ColorVariable()
{
}
void ColorVariable::setColor(const QColor &newColor)
{
m_variableValue = newColor;
}
void ColorVariable::addReference(ColorRole *t)
{
m_references.insert(t);
}
void ColorVariable::removeReference(ColorRole *t)
{
QTC_ASSERT(m_references.contains(t), return);
m_references.remove(t);
}
QSet<ColorRole *> ColorVariable::references() const
{
return m_references;
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -0,0 +1,77 @@
/****************************************************************************
**
** 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 COLORVARIABLE_H
#define COLORVARIABLE_H
#include <QSharedPointer>
#include <QColor>
#include <QString>
#include <QSet>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ColorRole;
class ThemeColors;
class ColorVariable
{
public:
friend class ThemeColors;
typedef QSharedPointer<ColorVariable> Ptr;
~ColorVariable();
// name of this variable
QString variableName() const { return m_variableName; }
// value of this variable
QColor color() const { return m_variableValue; }
void setColor(const QColor &color);
// which theme colors are referencing this variable?
void addReference(ColorRole *t);
void removeReference(ColorRole *t);
QSet<ColorRole *> references() const;
private:
explicit ColorVariable(const QColor &color, const QString &variableName = QString());
QColor m_variableValue;
QString m_variableName;
QSet<ColorRole *> m_references;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // COLORVARIABLE_H

View File

@@ -0,0 +1,124 @@
/****************************************************************************
**
** 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 "sectionedtablemodel.h"
#include <QSize>
namespace Core {
namespace Internal {
namespace ThemeEditor {
SectionedTableModel::SectionedTableModel(QObject *parent) :
QAbstractTableModel(parent)
{
}
int SectionedTableModel::sectionHeader(int row) const
{
int currRow = 0;
int i = 0;
do {
if (row == currRow)
return i;
currRow += sectionRowCount(i) + 1; //account for next header
++i;
} while (i < sectionCount());
return -1;
}
int SectionedTableModel::inSectionBody(int row) const
{
int currRow = 0;
int i = 0;
do {
++currRow;
if (row >= currRow && row < currRow + sectionRowCount(i))
return i;
currRow += sectionRowCount(i);
++i;
} while (i < sectionCount());
return -1;
}
int SectionedTableModel::modelToSectionRow(int row) const
{
int currRow = 0;
for (int i = 0; i < sectionCount(); ++i) {
++currRow;
if (row >= currRow && row < currRow + sectionRowCount(i))
return row-currRow;
currRow += sectionRowCount(i);
}
return row;
}
QSize SectionedTableModel::span(const QModelIndex &index) const
{
if (sectionHeader(index.row()) >= 0 && index.column() == 0)
return QSize(1, columnCount(index));
return QSize(1, 1);
}
int SectionedTableModel::rowCount(const QModelIndex &index) const
{
if (index.isValid())
return 0;
int r = 0;
for (int i = 0; i < sectionCount(); ++i)
r += sectionRowCount(i) + 1;
return r;
}
QVariant SectionedTableModel::data(const QModelIndex &index, int role) const
{
int header = sectionHeader(index.row());
if (header >= 0)
return (index.column() == 0) ? sectionHeaderData(header, role)
: QVariant(QString());
return sectionBodyData(inSectionBody(index.row()),
modelToSectionRow(index.row()),
index.column(),
role);
}
Qt::ItemFlags SectionedTableModel::flags(const QModelIndex &index) const
{
if (int h = sectionHeader(index.row()) >= 0)
return sectionHeaderFlags(h);
return sectionBodyFlags(inSectionBody(index.row()),
modelToSectionRow(index.row()),
index.column());
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -0,0 +1,69 @@
/****************************************************************************
**
** 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 SECTIONEDTABLEMODEL_H
#define SECTIONEDTABLEMODEL_H
#include <QAbstractTableModel>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class SectionedTableModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit SectionedTableModel(QObject *parent = 0);
virtual int sectionRowCount(int section) const = 0;
virtual QVariant sectionBodyData(int section, int row, int column, int role) const = 0;
virtual QVariant sectionHeaderData(int section, int role) const = 0;
virtual Qt::ItemFlags sectionBodyFlags(int section, int row, int column) const = 0;
virtual Qt::ItemFlags sectionHeaderFlags(int section) const = 0;
virtual int sectionCount() const = 0;
QSize span(const QModelIndex &index) const Q_DECL_OVERRIDE;
int inSectionBody(int row) const;
int modelToSectionRow(int row) const;
int sectionHeader(int row) const;
protected:
int rowCount(const QModelIndex &index) const Q_DECL_OVERRIDE;
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // SECTIONEDTABLEMODEL_H

View File

@@ -0,0 +1,76 @@
/****************************************************************************
**
** 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 "themecolors.h"
#include "colorvariable.h"
#include <utils/qtcassert.h>
namespace Core {
namespace Internal {
namespace ThemeEditor {
QSharedPointer<ColorVariable> ThemeColors::createVariable(const QColor &variableColor, const QString &variableName)
{
ColorVariable::Ptr var(new ColorVariable(variableColor, variableName));
insert(var);
return var;
}
ColorRole::Ptr ThemeColors::createRole(const QString &roleName, QSharedPointer<ColorVariable> colorVariable)
{
ColorRole::Ptr role(new ColorRole(roleName, colorVariable));
insert(role);
return role;
}
void ThemeColors::insert(ColorRole::Ptr color)
{
m_colorRoles.append(color);
}
void ThemeColors::insert(ColorVariable::Ptr color)
{
m_colorVariables.insert(color);
}
QSet<QSharedPointer<ColorVariable> > ThemeColors::colorVariables()
{
return m_colorVariables;
}
void ThemeColors::removeVariable(QSharedPointer<ColorVariable> variable)
{
QTC_ASSERT(m_colorVariables.contains(variable), return);
m_colorVariables.remove(variable);
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -0,0 +1,71 @@
/****************************************************************************
**
** 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 THEMECOLORS_H
#define THEMECOLORS_H
#include "colorrole.h"
#include <QSet>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ColorVariable;
class ThemeColors
{
public:
typedef QSharedPointer<ThemeColors> Ptr;
int numColorRoles() const { return m_colorRoles.size(); }
ColorRole::Ptr const colorRole(int index) { return m_colorRoles.at(index); }
QSharedPointer<ColorVariable> createVariable(const QColor &variableColor, const QString &variableName = QString());
ColorRole::Ptr createRole(const QString &roleName, QSharedPointer<ColorVariable> colorVariable);
QSet<QSharedPointer<ColorVariable> > colorVariables();
void removeVariable(QSharedPointer<ColorVariable> variable);
private:
void insert(ColorRole::Ptr color);
void insert(QSharedPointer<ColorVariable> color);
QList<ColorRole::Ptr> m_colorRoles;
QSet<QSharedPointer<ColorVariable> > m_colorVariables;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // THEMECOLORS_H

View File

@@ -0,0 +1,62 @@
/****************************************************************************
**
** 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 "themecolorstableview.h"
#include "themesettingsitemdelegate.h"
#include "themesettingstablemodel.h"
#include <QMouseEvent>
namespace Core {
namespace Internal {
namespace ThemeEditor {
ThemeColorsTableView::ThemeColorsTableView(QWidget *parent)
: QTreeView(parent)
{
}
void ThemeColorsTableView::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
QModelIndex index = indexAt(event->pos());
if (model()->flags(index) & Qt::ItemIsEditable && index.column() == 1) {
setCurrentIndex(index);
edit(index);
// TODO: only applies to editing colors
static_cast<ThemeSettingsItemDelegate *>(itemDelegate())->popupMenu();
}
}
QTreeView::mousePressEvent(event);
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt-project.org/legal ** Contact: http://www.qt-project.org/legal
** **
** This file is part of Qt Creator. ** This file is part of Qt Creator.
@@ -28,11 +28,28 @@
** **
****************************************************************************/ ****************************************************************************/
import QtQuick 2.1 #ifndef THEMECOLORSTABLEVIEW_H
#define THEMECOLORSTABLEVIEW_H
QtObject { #include <QTreeView>
property color linkColor: "#328930"
//property color linkColor: "#70b332" namespace Core {
//property color strongForegroundColor: "#58595b" namespace Internal {
property color strongForegroundColor: "#328930" namespace ThemeEditor {
}
class ThemeColorsTableView : public QTreeView
{
Q_OBJECT
public:
ThemeColorsTableView(QWidget *parent = 0);
protected:
void mousePressEvent(QMouseEvent *event);
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // THEMECOLORSTABLEVIEW_H

View File

@@ -0,0 +1,142 @@
/****************************************************************************
**
** 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 "themeeditorwidget.h"
#include "ui_themeeditorwidget.h"
#include "colorvariable.h"
#include "colorrole.h"
#include "themecolors.h"
#include "themesettingstablemodel.h"
#include "themesettingsitemdelegate.h"
#include <QAbstractButton>
#include <QAbstractItemModel>
#include <QColorDialog>
#include <QDir>
#include <QFileInfo>
#include <QMetaEnum>
#include <QSortFilterProxyModel>
#include <QTimer>
#include <QSharedPointer>
#include <QWeakPointer>
namespace Core {
namespace Internal {
namespace ThemeEditor {
ThemeEditorWidget::ThemeEditorWidget(QWidget *parent) :
QWidget(parent),
m_ui(new Ui::ThemeEditorWidget),
m_readOnly(false),
m_model(0)
{
m_ui->setupUi(this);
m_proxyModel = new QSortFilterProxyModel(this);
m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
m_proxyModel->setFilterKeyColumn(0);
m_ui->tableView->setModel(m_proxyModel);
ThemeSettingsItemDelegate *cbid = new ThemeSettingsItemDelegate(this);
m_ui->tableView->setItemDelegate(cbid);
connect(m_ui->filter, &QLineEdit::textChanged, m_proxyModel,
static_cast<void (QSortFilterProxyModel:: *)(const QString &)>(&QSortFilterProxyModel::setFilterRegExp));
connect(m_ui->tableView, &QAbstractItemView::doubleClicked, this, &ThemeEditorWidget::changeColor);
}
ThemeEditorWidget::~ThemeEditorWidget()
{
delete m_ui;
}
void ThemeEditorWidget::changeColor(const QModelIndex &index)
{
if (m_model->inSectionBody(index.row()) != ThemeSettingsTableModel::SectionColors)
return;
if (index.column() == 1)
return;
int row = m_model->modelToSectionRow(index.row());
ColorRole::Ptr themeColor = m_model->colors()->colorRole(row);
QColor currentColor = themeColor->colorVariable()->color();
// FIXME: 'currentColor' is correct, but QColorDialog won't show
// it as the correct initial color. Why?
QColorDialog dlg(this);
dlg.setOption(QColorDialog::ShowAlphaChannel);
dlg.setCurrentColor(currentColor);
const int customCount = QColorDialog::customCount();
for (int i = 0; i < customCount; ++i)
QColorDialog::setCustomColor(i, Qt::transparent); // invalid
int i = 0;
foreach (ColorVariable::Ptr namedColor, m_model->colors()->colorVariables())
QColorDialog::setCustomColor(i++, namedColor->color().toRgb());
int ret = dlg.exec();
if (ret == QDialog::Accepted) {
themeColor->colorVariable()->setColor(dlg.currentColor());
m_model->markEverythingChanged();
}
}
void ThemeEditorWidget::setReadOnly(bool readOnly)
{
m_readOnly = readOnly;
m_ui->tableView->setEnabled(!readOnly);
m_ui->filter->setEnabled(!readOnly);
}
void ThemeEditorWidget::initFrom(Utils::Theme *theme)
{
if (m_model) {
m_model->setParent(0);
delete m_model;
}
m_model = new ThemeSettingsTableModel(this);
m_model->initFrom(theme);
m_proxyModel->setSourceModel(m_model);
m_ui->tableView->setColumnWidth(0, 400);
m_ui->tableView->setColumnWidth(1, 300);
}
ThemeSettingsTableModel *ThemeEditorWidget::model()
{
return m_model;
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -0,0 +1,78 @@
/****************************************************************************
**
** 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 THEMEEDITORWIDGET_H
#define THEMEEDITORWIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QSortFilterProxyModel;
QT_END_NAMESPACE
namespace Utils { class Theme; }
namespace Core {
namespace Internal {
namespace ThemeEditor {
namespace Ui { class ThemeEditorWidget; }
class ThemeSettingsTableModel;
class ThemeEditorWidget : public QWidget
{
Q_OBJECT
public:
explicit ThemeEditorWidget(QWidget *parent = 0);
~ThemeEditorWidget();
void initFrom(Utils::Theme *theme);
ThemeSettingsTableModel *model();
void setReadOnly(bool readOnly);
private slots:
void changeColor(const QModelIndex &index);
private:
Ui::ThemeEditorWidget *m_ui;
bool m_readOnly;
ThemeSettingsTableModel *m_model;
QSortFilterProxyModel *m_proxyModel;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // THEMEEDITORWIDGET_H

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Core::Internal::ThemeEditor::ThemeEditorWidget</class>
<widget class="QWidget" name="Core::Internal::ThemeEditor::ThemeEditorWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Theme Editor</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Filter:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="filter"/>
</item>
</layout>
</item>
<item>
<widget class="Core::Internal::ThemeEditor::ThemeColorsTableView" name="tableView"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Core::Internal::ThemeEditor::ThemeColorsTableView</class>
<extends>QTableView</extends>
<header location="global">coreplugin/themeeditor/themecolorstableview.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,227 @@
/****************************************************************************
**
** 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 "themesettingsitemdelegate.h"
#include "colorvariable.h"
#include "themesettingstablemodel.h"
#include <utils/qtcassert.h>
#include <utils/theme/theme.h>
#include <QAbstractProxyModel>
#include <QComboBox>
#include <QEvent>
#include <QInputDialog>
#include <QMetaEnum>
using namespace Utils;
static QAbstractItemModel *sourceModel(QAbstractItemModel *model)
{
if (QAbstractProxyModel *m = qobject_cast<QAbstractProxyModel *>(model))
return m->sourceModel();
return model;
}
static const QAbstractItemModel *sourceModel(const QAbstractItemModel *model)
{
if (const QAbstractProxyModel *m = qobject_cast<const QAbstractProxyModel *>(model))
return m->sourceModel();
return model;
}
static QIcon makeIcon(const QColor &color)
{
QImage img(QSize(24,24), QImage::Format_ARGB32);
img.fill(color.rgba());
QIcon ico = QIcon(QPixmap::fromImage(img));
return ico;
}
namespace Core {
namespace Internal {
namespace ThemeEditor {
ThemeSettingsItemDelegate::ThemeSettingsItemDelegate(QObject *parent)
: QStyledItemDelegate(parent),
m_comboBox(0)
{
}
QWidget *ThemeSettingsItemDelegate::createColorEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
const ThemeSettingsTableModel *model = qobject_cast<const ThemeSettingsTableModel*>(sourceModel(index.model()));
Q_UNUSED(option);
const int row = model->modelToSectionRow(index.row());
QComboBox *cb = new QComboBox(parent);
ColorRole::Ptr colorRole = model->m_colors->colorRole(row);
const bool isUnnamed = colorRole->colorVariable()->variableName().isEmpty();
const QColor currentColor = colorRole->colorVariable()->color();
int k = 0;
if (isUnnamed) {
cb->addItem(makeIcon(currentColor), tr("<unnamed> (current)"));
++k;
} else {
cb->addItem(makeIcon(currentColor),
colorRole->colorVariable()->variableName()+QString(tr(" (current)")));
++k;
}
foreach (ColorVariable::Ptr namedColor, model->m_colors->colorVariables()) {
if (namedColor->variableName().isEmpty())
continue;
if (colorRole->colorVariable() == namedColor) {
continue;
} else {
cb->addItem(makeIcon(namedColor->color()), namedColor->variableName());
m_actions[k++] = qMakePair(Action_ChooseNamedColor, namedColor);
}
}
if (!isUnnamed) {
cb->addItem(tr("Make unnamed"));
m_actions[k++] = qMakePair(Action_MakeUnnamed, QSharedPointer<ColorVariable>(0));
}
cb->addItem(tr("Create new name..."));
m_actions[k++] = qMakePair(Action_CreateNew, QSharedPointer<ColorVariable>(0));
connect(cb, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
this, [this, cb]() {
ThemeSettingsItemDelegate *me = const_cast<ThemeSettingsItemDelegate *>(this);
emit me->commitData(cb);
emit me->closeEditor(cb);
});
m_comboBox = cb;
return cb;
}
QWidget *ThemeSettingsItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
const ThemeSettingsTableModel *model = qobject_cast<const ThemeSettingsTableModel*>(sourceModel(index.model()));
const int section = model->inSectionBody(index.row());
QTC_ASSERT(section >= 0, return 0);
switch (section) {
case ThemeSettingsTableModel::SectionWidgetStyle: {
QComboBox *cb = new QComboBox(parent);
QMetaEnum e = Theme::staticMetaObject.enumerator(Theme::staticMetaObject.indexOfEnumerator("WidgetStyle"));
for (int i = 0, total = e.keyCount(); i < total; ++i)
cb->addItem(QLatin1String(e.key(i)));
connect(cb, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
this, [this, cb]() {
ThemeSettingsItemDelegate *me = const_cast<ThemeSettingsItemDelegate *>(this);
emit me->commitData(cb);
emit me->closeEditor(cb);
});
m_comboBox = cb;
return cb;
}
case ThemeSettingsTableModel::SectionColors: {
return createColorEditor(parent, option, index);
}
case ThemeSettingsTableModel::SectionFlags: {
return QStyledItemDelegate::createEditor(parent, option, index);
}
default: {
qWarning("unhandled section");
return 0;
}
} // switch
}
void ThemeSettingsItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QStyledItemDelegate::setEditorData(editor, index);
}
void ThemeSettingsItemDelegate::setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
ThemeSettingsTableModel *themeSettingsModel = qobject_cast<ThemeSettingsTableModel *>(sourceModel(model));
const int row = themeSettingsModel->modelToSectionRow(index.row());
const int section = themeSettingsModel->inSectionBody(index.row());
switch (section) {
case ThemeSettingsTableModel::SectionWidgetStyle:
if (QComboBox *cb = qobject_cast<QComboBox *>(editor))
themeSettingsModel->m_widgetStyle = static_cast<Theme::WidgetStyle>(cb->currentIndex());
return;
case ThemeSettingsTableModel::SectionColors: {
if (QComboBox *cb = qobject_cast<QComboBox *>(editor)) {
ColorRole::Ptr themeColor = themeSettingsModel->m_colors->colorRole(row);
Action act = m_actions[cb->currentIndex()].first;
ColorVariable::Ptr previousVariable = themeColor->colorVariable();
ColorVariable::Ptr newVariable = m_actions[cb->currentIndex()].second;
if (act == Action_NoAction) {
return;
} else if (act == Action_ChooseNamedColor) {
previousVariable->removeReference(themeColor.data());
QTC_ASSERT(newVariable, return);
themeColor->assignColorVariable(newVariable);
} else if (act == Action_MakeUnnamed) {
previousVariable->removeReference(themeColor.data());
if (previousVariable->references().size() == 0)
themeSettingsModel->m_colors->removeVariable(previousVariable);
ColorVariable::Ptr anonymousColor = themeSettingsModel->m_colors->createVariable(previousVariable->color());
themeColor->assignColorVariable(anonymousColor);
} else if (act == Action_CreateNew) {
QString name = QInputDialog::getText(editor, tr("New variable name"), tr("Variable name:"));
if (!name.isEmpty()) {
previousVariable->removeReference(themeColor.data());
// TODO: check for name collision
ColorVariable::Ptr newVariable = themeSettingsModel->m_colors->createVariable(previousVariable->color(), name);
themeColor->assignColorVariable(newVariable);
}
}
}
return;
}
default:
return QStyledItemDelegate::setModelData(editor, model, index);
}
}
void ThemeSettingsItemDelegate::popupMenu()
{
m_comboBox->showPopup();
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -0,0 +1,78 @@
/****************************************************************************
**
** 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 THEMESETTINGSITEMDELEGATE_H
#define THEMESETTINGSITEMDELEGATE_H
#include "themecolors.h"
#include "colorvariable.h"
#include <QStyledItemDelegate>
QT_BEGIN_NAMESPACE
class QComboBox;
QT_END_NAMESPACE
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ThemeSettingsItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
enum Action {
Action_NoAction,
Action_ChooseNamedColor,
Action_MakeUnnamed,
Action_CreateNew
};
public:
ThemeSettingsItemDelegate(QObject *parent);
QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE;
void popupMenu();
private:
QWidget *createColorEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
mutable QMap<int, QPair<Action, ColorVariable::Ptr> > m_actions;
mutable QComboBox *m_comboBox;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // THEMESETTINGSITEMDELEGATE_H

View File

@@ -0,0 +1,297 @@
/****************************************************************************
**
** 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 "themesettingstablemodel.h"
#include "colorvariable.h"
#include <utils/qtcassert.h>
#include <utils/theme/theme.h>
#include <utils/theme/theme_p.h>
#include <QApplication>
#include <QImage>
#include <QMetaEnum>
#include <QPainter>
#include <QPalette>
using namespace Utils;
namespace Core {
namespace Internal {
namespace ThemeEditor {
ThemeSettingsTableModel::ThemeSettingsTableModel(QObject *parent)
: SectionedTableModel(parent),
m_colors(new ThemeColors),
m_hasChanges(false)
{
}
int ThemeSettingsTableModel::columnCount(const QModelIndex &index) const
{
Q_UNUSED(index);
return 2;
}
int ThemeSettingsTableModel::sectionRowCount(int section) const
{
switch (static_cast<Section>(section)) {
case SectionWidgetStyle: return 1;
case SectionColors: return m_colors->numColorRoles();
case SectionFlags: return m_flags.size();
case SectionIconOverlays: return m_iconOverlays.size();
default: return 0;
}
}
QVariant ThemeSettingsTableModel::sectionBodyData(int section, int row, int column, int role) const
{
auto makeDecoration = [](const QColor &c) -> QImage {
QImage img(QSize(32,32), QImage::Format_ARGB32);
img.fill(Qt::transparent);
QPainter p(&img);
p.fillRect(QRect(4,4,24,24), c);
return img;
};
switch (static_cast<Section>(section)) {
case SectionWidgetStyle: {
if (role != Qt::DisplayRole)
return QVariant();
if (column == 0)
return QLatin1String("WidgetStyle");
else
return m_widgetStyle == Theme::StyleFlat ? QLatin1String("StyleFlat") : QLatin1String("StyleDefault");
}
case SectionColors: {
ColorRole::Ptr colorRole = m_colors->colorRole(row);
if (column == 0 && role == Qt::DecorationRole)
return QVariant::fromValue(makeDecoration(colorRole->colorVariable()->color()));
if (role == Qt::DisplayRole) {
if (column == 0)
return colorRole->roleName();
else
return colorRole->colorVariable()->variableName();
}
return QVariant();
}
case SectionFlags: {
if (column == 0 && role == Qt::DisplayRole)
return m_flags[row].first;
else if (column == 1 && role == Qt::CheckStateRole)
return m_flags[row].second ? Qt::Checked : Qt::Unchecked;
else if (column == 0 && role == Qt::DecorationRole)
return QVariant::fromValue(makeDecoration(Qt::transparent));
return QVariant();
}
case SectionIconOverlays: {
if (column == 0 && role == Qt::DisplayRole)
return m_iconOverlays[row].first;
else if (column == 1 && role == Qt::DisplayRole)
return m_iconOverlays[row].second;
else if (column == 0 && role == Qt::DecorationRole)
return QVariant::fromValue(makeDecoration(Qt::transparent));
return QVariant();
}
default:
return QVariant();
}
}
QVariant ThemeSettingsTableModel::sectionHeaderData(int section, int role) const
{
if (role == Qt::DisplayRole) {
switch (static_cast<Section>(section)) {
case SectionWidgetStyle: return tr("Widget Style");
case SectionColors: return tr("Colors");
case SectionFlags: return tr("Flags");
case SectionIconOverlays: return tr("Icon Overlays");
default: return QString();
}
}
if (role == Qt::FontRole) {
QFont font;
font.setPointSizeF(font.pointSizeF() * 1.25);
font.setBold(true);
return font;
}
if (role == Qt::SizeHintRole)
return QSize(50, 50);
return QVariant();
}
Qt::ItemFlags ThemeSettingsTableModel::sectionBodyFlags(int section, int row, int column) const
{
Q_UNUSED(row);
switch (static_cast<Section>(section)) {
case SectionWidgetStyle:
return (column == 0) ? Qt::ItemIsEnabled
: Qt::ItemIsEnabled | Qt::ItemIsEditable;
case SectionColors:
return (column == 0) ? Qt::ItemIsEnabled
: Qt::ItemIsEnabled | Qt::ItemIsEditable;
case SectionFlags:
return (column == 0) ? Qt::ItemIsEnabled
: Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
case SectionIconOverlays:
return Qt::ItemIsEnabled;
default: return Qt::ItemIsEnabled;
}
}
bool ThemeSettingsTableModel::setData(const QModelIndex &idx, const QVariant &value, int role)
{
m_hasChanges = true;
Q_UNUSED(role);
int section = inSectionBody(idx.row());
int row = modelToSectionRow(idx.row());
switch (static_cast<Section>(section)) {
case SectionFlags: {
Qt::CheckState checkState = static_cast<Qt::CheckState>(value.toInt());
bool checked = checkState == Qt::Checked;
m_flags[row].second = checked;
emit dataChanged(idx, idx);
return true;
}
default: {
// don't bother tracking changes, just mark the whole table as changed
markEverythingChanged();
return true;
}
} // switch
}
void ThemeSettingsTableModel::markEverythingChanged()
{
m_hasChanges = true;
QModelIndex i;
emit dataChanged(index(0, 0, i), index(rowCount(i), columnCount(i), i));
}
void ThemeSettingsTableModel::initFrom(Theme *theme)
{
const QMetaObject &metaObject = Theme::staticMetaObject;
// Colors
{
QMetaEnum e = metaObject.enumerator(metaObject.indexOfEnumerator("ColorRole"));
QMap<QString, ColorVariable::Ptr> varLookup;
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
QPair<QColor, QString> c = theme->d->colors[static_cast<Theme::ColorRole>(i)];
if (c.second.isEmpty()) {
ColorVariable::Ptr v = colors()->createVariable(c.first);
colors()->createRole(key, v);
} else if (varLookup.contains(c.second)) {
colors()->createRole(key, varLookup[c.second]);
} else {
ColorVariable::Ptr v = colors()->createVariable(c.first, c.second);
colors()->createRole(key, v);
varLookup[c.second] = v;
}
}
}
// Flags
{
QMetaEnum e = metaObject.enumerator(metaObject.indexOfEnumerator("Flag"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
m_flags.append(qMakePair(key, theme->flag(static_cast<Theme::Flag>(i))));
}
}
// IconOverlays
{
QMetaEnum e = metaObject.enumerator(metaObject.indexOfEnumerator("MimeType"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
m_iconOverlays.append(qMakePair(key, theme->iconOverlay(static_cast<Theme::MimeType>(i))));
}
}
m_widgetStyle = theme->widgetStyle();
m_name = theme->d->name;
}
void ThemeSettingsTableModel::toTheme(Theme *t) const
{
ThemePrivate *theme = t->d;
// Colors
{
QMetaEnum e = Theme::staticMetaObject.enumerator(Theme::staticMetaObject.indexOfEnumerator("ColorRole"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
ColorRole::Ptr role = colors()->colorRole(i);
ColorVariable::Ptr var = role->colorVariable();
theme->colors[i] = qMakePair(var->color(), var->variableName());
}
}
// Flags
{
QTC_ASSERT(theme->flags.size() == m_flags.size(), return);
for (int i = 0; i < theme->flags.size(); ++i)
theme->flags[i] = m_flags[i].second;
}
// IconOveralys
{
const int nOverlays = theme->iconOverlays.size();
QTC_ASSERT(nOverlays == m_iconOverlays.size(), return);
for (int i = 0; i < nOverlays; ++i)
theme->iconOverlays[i] = m_iconOverlays[i].second;
}
theme->widgetStyle = m_widgetStyle;
theme->name = m_name;
emit t->changed();
}
Qt::ItemFlags ThemeSettingsTableModel::sectionHeaderFlags(int section) const
{
Q_UNUSED(section);
return Qt::ItemIsEnabled;
}
int ThemeSettingsTableModel::sectionCount() const
{
return SectionInvalid;
}
QVariant ThemeSettingsTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole) {
if (orientation == Qt::Horizontal) {
if (section == 0)
return tr("Role");
return tr("Value");
}
}
return QVariant();
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -0,0 +1,94 @@
/****************************************************************************
**
** 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 THEMESETTINGSTABLEMODEL_H
#define THEMESETTINGSTABLEMODEL_H
#include <QAbstractTableModel>
#include "themecolors.h"
#include "sectionedtablemodel.h"
#include <utils/theme/theme.h>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ThemeSettingsTableModel : public SectionedTableModel
{
Q_OBJECT
public:
friend class ThemeSettingsItemDelegate;
enum Section {
SectionWidgetStyle,
SectionColors,
SectionFlags,
SectionIconOverlays,
SectionInvalid // end
};
ThemeSettingsTableModel(QObject *parent = 0);
bool setData(const QModelIndex &index, const QVariant &value, int role) Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex &index) const Q_DECL_OVERRIDE;
int sectionRowCount(int section) const Q_DECL_OVERRIDE;
QVariant sectionBodyData(int section, int row, int column, int role) const Q_DECL_OVERRIDE;
QVariant sectionHeaderData(int section, int role) const Q_DECL_OVERRIDE;
Qt::ItemFlags sectionBodyFlags(int section, int row, int column) const Q_DECL_OVERRIDE;
Qt::ItemFlags sectionHeaderFlags(int section) const Q_DECL_OVERRIDE;
int sectionCount() const Q_DECL_OVERRIDE;
ThemeColors::Ptr colors() const { return m_colors; }
bool hasChanges() const { return m_hasChanges; }
void markEverythingChanged();
void initFrom(Utils::Theme *theme);
void toTheme(Utils::Theme *theme) const;
QString m_name;
public:
ThemeColors::Ptr m_colors;
QList<QPair<QString, bool> > m_flags;
QList<QPair<QString, QString> > m_iconOverlays;
Utils::Theme::WidgetStyle m_widgetStyle;
bool m_hasChanges;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // THEMESETTINGSTABLEMODEL_H

View File

@@ -0,0 +1,465 @@
/****************************************************************************
**
** 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 "themesettings.h"
#include "coreconstants.h"
#include "icore.h"
#include "editormanager/editormanager_p.h"
#include "themeeditor/themesettingstablemodel.h"
#include <utils/qtcassert.h>
#include <QDebug>
#include <QDir>
#include <QInputDialog>
#include <QMessageBox>
#include <QSettings>
#include "ui_themesettings.h"
using namespace Utils;
namespace Core {
namespace Internal {
const char themeNameKey[] = "ThemeName";
static QString customThemesPath()
{
QString path = Core::ICore::userResourcePath();
path.append(QLatin1String("/themes/"));
return path;
}
static QString createThemeFileName(const QString &pattern)
{
const QString stylesPath = customThemesPath();
QString baseFileName = stylesPath;
baseFileName += pattern;
// Find an available file name
int i = 1;
QString fileName;
do {
fileName = baseFileName.arg((i == 1) ? QString() : QString::number(i));
++i;
} while (QFile::exists(fileName));
// Create the base directory when it doesn't exist
if (!QFile::exists(stylesPath) && !QDir().mkpath(stylesPath)) {
qWarning() << "Failed to create theme directory:" << stylesPath;
return QString();
}
return fileName;
}
struct ThemeEntry
{
ThemeEntry() {}
ThemeEntry(const QString &fileName, bool readOnly):
m_fileName(fileName),
m_readOnly(readOnly)
{ }
QString fileName() const { return m_fileName; }
QString name() const;
bool readOnly() const { return m_readOnly; }
private:
QString m_fileName;
bool m_readOnly;
};
QString ThemeEntry::name() const
{
QSettings settings(m_fileName, QSettings::IniFormat);
QString n = settings.value(QLatin1String(themeNameKey), QCoreApplication::tr("unnamed")).toString();
return m_readOnly ? QCoreApplication::tr("%1 (built-in)").arg(n) : n;
}
class ThemeListModel : public QAbstractListModel
{
public:
ThemeListModel(QObject *parent = 0):
QAbstractListModel(parent)
{
}
int rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : m_themes.size();
}
QVariant data(const QModelIndex &index, int role) const
{
if (role == Qt::DisplayRole)
return m_themes.at(index.row()).name();
return QVariant();
}
void removeTheme(int index)
{
beginRemoveRows(QModelIndex(), index, index);
m_themes.removeAt(index);
endRemoveRows();
}
void setThemes(const QList<ThemeEntry> &themes)
{
beginResetModel();
m_themes = themes;
endResetModel();
}
const ThemeEntry &themeAt(int index) const
{
return m_themes.at(index);
}
private:
QList<ThemeEntry> m_themes;
};
class ThemeSettingsPrivate
{
public:
ThemeSettingsPrivate();
~ThemeSettingsPrivate();
public:
ThemeListModel *m_themeListModel;
bool m_refreshingThemeList;
Ui::ThemeSettings *m_ui;
QPointer<QWidget> m_widget;
ThemeEntry m_currentTheme;
};
ThemeSettingsPrivate::ThemeSettingsPrivate()
: m_themeListModel(new ThemeListModel)
, m_refreshingThemeList(false)
, m_ui(0)
{
m_currentTheme = ThemeEntry(creatorTheme()->fileName(), true);
}
ThemeSettingsPrivate::~ThemeSettingsPrivate()
{
delete m_themeListModel;
}
ThemeSettings::ThemeSettings()
{
setId(Core::Constants::SETTINGS_ID_ENVIRONMENT);
setDisplayName(tr("Theme"));
setCategory(Core::Constants::SETTINGS_CATEGORY_CORE);
setDisplayCategory(QCoreApplication::translate("Core", Core::Constants::SETTINGS_TR_CATEGORY_CORE));
setCategoryIcon(QLatin1String(Core::Constants::SETTINGS_CATEGORY_CORE_ICON));
d = new ThemeSettingsPrivate();
}
ThemeSettings::~ThemeSettings()
{
delete d;
}
void ThemeSettings::refreshThemeList()
{
QList<ThemeEntry> themes;
QString resourcePath = Core::ICore::resourcePath();
QDir themeDir(resourcePath + QLatin1String("/themes"));
themeDir.setNameFilters(QStringList() << QLatin1String("*.creatortheme"));
themeDir.setFilter(QDir::Files);
int selected = 0;
QStringList themeList = themeDir.entryList();
QString defaultTheme = QFileInfo(defaultThemeFileName()).fileName();
if (themeList.removeAll(defaultTheme))
themeList.prepend(defaultTheme);
foreach (const QString &file, themeList) {
const QString fileName = themeDir.absoluteFilePath(file);
if (d->m_currentTheme.fileName() == fileName)
selected = themes.size();
themes.append(ThemeEntry(fileName, true));
}
if (themes.isEmpty())
qWarning() << "Warning: no themes found in path:" << themeDir.path();
themeDir.setPath(customThemesPath());
foreach (const QString &file, themeDir.entryList()) {
const QString fileName = themeDir.absoluteFilePath(file);
if (d->m_currentTheme.fileName() == fileName)
selected = themes.size();
themes.append(ThemeEntry(fileName, false));
}
d->m_currentTheme = themes[selected];
d->m_refreshingThemeList = true;
d->m_themeListModel->setThemes(themes);
d->m_ui->themeComboBox->setCurrentIndex(selected);
d->m_refreshingThemeList = false;
}
QString ThemeSettings::defaultThemeFileName(const QString &fileName)
{
QString defaultScheme = Core::ICore::resourcePath();
defaultScheme += QLatin1String("/themes/");
if (!fileName.isEmpty() && QFile::exists(defaultScheme + fileName))
defaultScheme += fileName;
else
defaultScheme += QLatin1String("default.creatortheme");
return defaultScheme;
}
void ThemeSettings::themeSelected(int index)
{
bool readOnly = true;
if (index != -1) {
// Check whether we're switching away from a changed theme
if (!d->m_refreshingThemeList)
maybeSaveTheme();
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
readOnly = entry.readOnly();
d->m_currentTheme = entry;
QSettings settings(entry.fileName(), QSettings::IniFormat);
Theme theme;
theme.readSettings(settings);
d->m_ui->editor->initFrom(&theme);
}
d->m_ui->copyButton->setEnabled(index != -1);
d->m_ui->deleteButton->setEnabled(!readOnly);
d->m_ui->renameButton->setEnabled(!readOnly);
d->m_ui->editor->setReadOnly(readOnly);
}
QWidget *ThemeSettings::widget()
{
if (!d->m_widget) {
d->m_widget = new QWidget;
d->m_ui = new Ui::ThemeSettings();
d->m_ui->setupUi(d->m_widget);
d->m_ui->themeComboBox->setModel(d->m_themeListModel);
connect(d->m_ui->themeComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &ThemeSettings::themeSelected);
connect(d->m_ui->copyButton, &QAbstractButton::clicked, this, &ThemeSettings::copyTheme);
connect(d->m_ui->renameButton, &QAbstractButton::clicked, this, &ThemeSettings::renameTheme);
connect(d->m_ui->deleteButton, &QAbstractButton::clicked, this, &ThemeSettings::confirmDeleteTheme);
refreshThemeList();
}
return d->m_widget;
}
void ThemeSettings::confirmDeleteTheme()
{
const int index = d->m_ui->themeComboBox->currentIndex();
if (index == -1)
return;
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
if (entry.readOnly())
return;
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
tr("Delete Theme"),
tr("Are you sure you want to delete the theme '%1' permanently?").arg(entry.name()),
QMessageBox::Discard | QMessageBox::Cancel,
d->m_ui->deleteButton->window());
// Change the text and role of the discard button
QPushButton *deleteButton = static_cast<QPushButton*>(messageBox->button(QMessageBox::Discard));
deleteButton->setText(tr("Delete"));
messageBox->addButton(deleteButton, QMessageBox::AcceptRole);
messageBox->setDefaultButton(deleteButton);
connect(deleteButton, &QAbstractButton::clicked, messageBox, &QDialog::accept);
connect(messageBox, &QDialog::accepted, this, &ThemeSettings::deleteTheme);
messageBox->setAttribute(Qt::WA_DeleteOnClose);
messageBox->open();
}
void ThemeSettings::deleteTheme()
{
const int index = d->m_ui->themeComboBox->currentIndex();
QTC_ASSERT(index != -1, return);
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
QTC_ASSERT(!entry.readOnly(), return);
if (QFile::remove(entry.fileName()))
d->m_themeListModel->removeTheme(index);
}
void ThemeSettings::copyTheme()
{
QInputDialog *dialog = new QInputDialog(d->m_ui->copyButton->window());
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setInputMode(QInputDialog::TextInput);
dialog->setWindowTitle(tr("Copy Theme"));
dialog->setLabelText(tr("Theme name:"));
//TODO
//dialog->setTextValue(tr("%1 (copy)").arg(d_ptr->m_value.colorScheme().displayName()));
connect(dialog, &QInputDialog::textValueSelected, this, &ThemeSettings::copyThemeByName);
dialog->open();
}
void ThemeSettings::maybeSaveTheme()
{
if (!d->m_ui->editor->model()->hasChanges())
return;
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
tr("Theme Changed"),
tr("The theme \"%1\" was modified, do you want to save the changes?")
.arg(d->m_currentTheme.name()),
QMessageBox::Discard | QMessageBox::Save,
d->m_ui->themeComboBox->window());
// Change the text of the discard button
QPushButton *discardButton = static_cast<QPushButton*>(messageBox->button(QMessageBox::Discard));
discardButton->setText(tr("Discard"));
messageBox->addButton(discardButton, QMessageBox::DestructiveRole);
messageBox->setDefaultButton(QMessageBox::Save);
if (messageBox->exec() == QMessageBox::Save) {
Theme newTheme;
d->m_ui->editor->model()->toTheme(&newTheme);
newTheme.writeSettings(d->m_currentTheme.fileName());
}
}
void ThemeSettings::renameTheme()
{
int index = d->m_ui->themeComboBox->currentIndex();
if (index == -1)
return;
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
maybeSaveTheme();
QInputDialog *dialog = new QInputDialog(d->m_ui->renameButton->window());
dialog->setInputMode(QInputDialog::TextInput);
dialog->setWindowTitle(tr("Rename Theme"));
dialog->setLabelText(tr("Theme name:"));
dialog->setTextValue(d->m_ui->editor->model()->m_name);
int ret = dialog->exec();
QString newName = dialog->textValue();
delete dialog;
if (ret != QDialog::Accepted || newName.isEmpty())
return;
// overwrite file with new name
Theme newTheme;
d->m_ui->editor->model()->toTheme(&newTheme);
newTheme.setName(newName);
newTheme.writeSettings(entry.fileName());
refreshThemeList();
}
void ThemeSettings::copyThemeByName(const QString &name)
{
int index = d->m_ui->themeComboBox->currentIndex();
if (index == -1)
return;
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
QString baseFileName = QFileInfo(entry.fileName()).completeBaseName();
baseFileName += QLatin1String("_copy%1.creatortheme");
QString fileName = createThemeFileName(baseFileName);
if (fileName.isEmpty())
return;
// Ask about saving any existing modifactions
maybeSaveTheme();
Theme newTheme;
d->m_ui->editor->model()->toTheme(&newTheme);
newTheme.setName(name);
newTheme.writeSettings(fileName);
d->m_currentTheme = ThemeEntry(fileName, true);
refreshThemeList();
}
void ThemeSettings::apply()
{
if (!d->m_ui) // wasn't shown, can't be changed
return;
{
d->m_ui->editor->model()->toTheme(creatorTheme());
QPalette newPalette = creatorTheme()->palette(qApp->palette());
qApp->setPalette(newPalette);
foreach (QWidget *w, QApplication::topLevelWidgets())
w->update();
}
// save definition of theme
if (!d->m_currentTheme.readOnly()) {
Theme newTheme;
d->m_ui->editor->model()->toTheme(&newTheme);
newTheme.writeSettings(d->m_currentTheme.fileName());
}
// save filename of selected theme in global config
QSettings *settings = Core::ICore::settings();
settings->setValue(QLatin1String(Core::Constants::SETTINGS_THEME), d->m_currentTheme.fileName());
}
void ThemeSettings::finish()
{
delete d->m_widget;
if (!d->m_ui) // page was never shown
return
delete d->m_ui;
d->m_ui = 0;
}
} // namespace Internal
} // namespace Core

View File

@@ -0,0 +1,72 @@
/****************************************************************************
**
** 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 THEMESETTINGS_H
#define THEMESETTINGS_H
#include <coreplugin/dialogs/ioptionspage.h>
namespace Core {
namespace Internal {
class ThemeSettingsPrivate;
class ThemeSettings : public IOptionsPage
{
Q_OBJECT
public:
ThemeSettings();
~ThemeSettings();
QWidget *widget();
void apply();
void finish();
static QString defaultThemeFileName(const QString &fileName = QString());
private slots:
void themeSelected(int index);
void copyTheme();
void renameTheme();
void copyThemeByName(const QString &);
void confirmDeleteTheme();
void deleteTheme();
void maybeSaveTheme();
private:
void refreshThemeList();
ThemeSettingsPrivate *d;
};
} // namespace Internal
} // namespace Core
#endif // THEMESETTINGS_H

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Core::Internal::ThemeSettings</class>
<widget class="QWidget" name="Core::Internal::ThemeSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>527</width>
<height>359</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="themeComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="renameButton">
<property name="text">
<string>Rename...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyButton">
<property name="text">
<string>Copy...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteButton">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Core::Internal::ThemeEditor::ThemeEditorWidget" name="editor" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Core::Internal::ThemeEditor::ThemeEditorWidget</class>
<extends>QWidget</extends>
<header location="global">coreplugin/themeeditor/themeeditorwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="core.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -4,5 +4,8 @@
<file>images/qt_h.png</file> <file>images/qt_h.png</file>
<file>CppEditor.mimetypes.xml</file> <file>CppEditor.mimetypes.xml</file>
<file>images/qt_c.png</file> <file>images/qt_c.png</file>
<file>images/dark_qt_cpp.png</file>
<file>images/dark_qt_h.png</file>
<file>images/dark_qt_c.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -59,11 +59,14 @@
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/theme/theme.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QStringList> #include <QStringList>
using namespace Core; using namespace Core;
using namespace TextEditor; using namespace TextEditor;
using namespace Utils;
namespace CppEditor { namespace CppEditor {
namespace Internal { namespace Internal {
@@ -103,9 +106,9 @@ public:
addHoverHandler(new CppHoverHandler); addHoverHandler(new CppHoverHandler);
if (!Utils::HostOsInfo::isMacHost() && !Utils::HostOsInfo::isWindowsHost()) { if (!Utils::HostOsInfo::isMacHost() && !Utils::HostOsInfo::isWindowsHost()) {
FileIconProvider::registerIconOverlayForMimeType(":/cppeditor/images/qt_cpp.png", Constants::CPP_SOURCE_MIMETYPE); FileIconProvider::registerIconOverlayForMimeType(creatorTheme()->iconOverlay(Theme::CppSourceMimetype).toLatin1().data(), Constants::CPP_SOURCE_MIMETYPE);
FileIconProvider::registerIconOverlayForMimeType(":/cppeditor/images/qt_c.png", Constants::C_SOURCE_MIMETYPE); FileIconProvider::registerIconOverlayForMimeType(creatorTheme()->iconOverlay(Theme::CSourceMimetype).toLatin1().data(), Constants::C_SOURCE_MIMETYPE);
FileIconProvider::registerIconOverlayForMimeType(":/cppeditor/images/qt_h.png", Constants::CPP_HEADER_MIMETYPE); FileIconProvider::registerIconOverlayForMimeType(creatorTheme()->iconOverlay(Theme::CppHeaderMimetype).toLatin1().data(), Constants::CPP_HEADER_MIMETYPE);
} }
} }
}; };

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

View File

@@ -76,6 +76,7 @@
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/styledbar.h> #include <utils/styledbar.h>
#include <utils/theme/theme.h>
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
@@ -101,6 +102,7 @@ static const char kExternalWindowStateKey[] = "Help/ExternalWindowState";
#define IMAGEPATH ":/help/images/" #define IMAGEPATH ":/help/images/"
using namespace Core; using namespace Core;
using namespace Utils;
HelpPlugin::HelpPlugin() HelpPlugin::HelpPlugin()
: m_mode(0), : m_mode(0),
@@ -565,8 +567,13 @@ void HelpPlugin::showContextHelp()
// No link found or no context object // No link found or no context object
viewer->setSource(QUrl(Help::Constants::AboutBlank)); viewer->setSource(QUrl(Help::Constants::AboutBlank));
viewer->setHtml(tr("<html><head><title>No Documentation</title>" viewer->setHtml(tr("<html><head><title>No Documentation</title>"
"</head><body><br/><center><b>%1</b><br/>No documentation " "</head><body><br/><center>"
"available.</center></body></html>").arg(idFromContext)); "<font color=\"%1\"><b>%2</b></font><br/>"
"<font color=\"%3\">No documentation available.</font>"
"</center></body></html>")
.arg(creatorTheme()->color(Theme::TextColorNormal).name())
.arg(idFromContext)
.arg(creatorTheme()->color(Theme::TextColorNormal).name()));
} else { } else {
const QUrl &oldSource = viewer->source(); const QUrl &oldSource = viewer->source();
if (source != oldSource) { if (source != oldSource) {

View File

@@ -32,6 +32,7 @@
#include "ui_doubletabwidget.h" #include "ui_doubletabwidget.h"
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/theme/theme.h>
#include <QRect> #include <QRect>
#include <QPainter> #include <QPainter>
@@ -42,6 +43,7 @@
#include <QDebug> #include <QDebug>
using namespace ProjectExplorer::Internal; using namespace ProjectExplorer::Internal;
using namespace Utils;
static const int MIN_LEFT_MARGIN = 50; static const int MIN_LEFT_MARGIN = 50;
static const int MARGIN = 12; static const int MARGIN = 12;
@@ -53,35 +55,45 @@ static const int OVERFLOW_DROPDOWN_WIDTH = Utils::StyleHelper::navigationWidgetH
static void drawFirstLevelSeparator(QPainter *painter, QPoint top, QPoint bottom) static void drawFirstLevelSeparator(QPainter *painter, QPoint top, QPoint bottom)
{ {
QLinearGradient grad(top, bottom); QLinearGradient grad(top, bottom);
grad.setColorAt(0, QColor(255, 255, 255, 20)); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
grad.setColorAt(0.4, QColor(255, 255, 255, 60)); grad.setColorAt(0, QColor(255, 0, 255, 20));
grad.setColorAt(0.7, QColor(255, 255, 255, 50)); grad.setColorAt(0.4, QColor(255, 0, 255, 60));
grad.setColorAt(1, QColor(255, 255, 255, 40)); grad.setColorAt(0.7, QColor(255, 0, 255, 50));
painter->setPen(QPen(grad, 0)); grad.setColorAt(1, QColor(255, 0, 255, 40));
painter->drawLine(top, bottom); painter->setPen(QPen(grad, 0));
grad.setColorAt(0, QColor(0, 0, 0, 30)); painter->drawLine(top, bottom);
grad.setColorAt(0.4, QColor(0, 0, 0, 70)); grad.setColorAt(0, QColor(0, 0, 0, 30));
grad.setColorAt(0.7, QColor(0, 0, 0, 70)); grad.setColorAt(0.4, QColor(0, 0, 0, 70));
grad.setColorAt(1, QColor(0, 0, 0, 40)); grad.setColorAt(0.7, QColor(0, 0, 0, 70));
painter->setPen(QPen(grad, 0)); grad.setColorAt(1, QColor(0, 0, 0, 40));
painter->drawLine(top - QPoint(1,0), bottom - QPoint(1,0)); painter->setPen(QPen(grad, 0));
painter->drawLine(top - QPoint(1,0), bottom - QPoint(1,0));
} else {
painter->setPen(QPen(creatorTheme()->color(Theme::DoubleTabWidget1stSeparatorColor), 0));
painter->drawLine(top, bottom);
}
} }
static void drawSecondLevelSeparator(QPainter *painter, QPoint top, QPoint bottom) static void drawSecondLevelSeparator(QPainter *painter, QPoint top, QPoint bottom)
{ {
QLinearGradient grad(top, bottom); QLinearGradient grad(top, bottom);
grad.setColorAt(0, QColor(255, 255, 255, 0)); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
grad.setColorAt(0.4, QColor(255, 255, 255, 100)); grad.setColorAt(0, QColor(255, 255, 255, 20));
grad.setColorAt(0.7, QColor(255, 255, 255, 100)); grad.setColorAt(0.4, QColor(255, 255, 255, 60));
grad.setColorAt(1, QColor(255, 255, 255, 0)); grad.setColorAt(0.7, QColor(255, 255, 255, 50));
painter->setPen(QPen(grad, 0)); grad.setColorAt(1, QColor(255, 255, 255, 40));
painter->drawLine(top, bottom); painter->setPen(QPen(grad, 0));
grad.setColorAt(0, QColor(0, 0, 0, 0)); painter->drawLine(top, bottom);
grad.setColorAt(0.4, QColor(0, 0, 0, 100)); grad.setColorAt(0, QColor(0, 0, 0, 0));
grad.setColorAt(0.7, QColor(0, 0, 0, 100)); grad.setColorAt(0.4, QColor(0, 0, 0, 100));
grad.setColorAt(1, QColor(0, 0, 0, 0)); grad.setColorAt(0.7, QColor(0, 0, 0, 100));
painter->setPen(QPen(grad, 0)); grad.setColorAt(1, QColor(0, 0, 0, 0));
painter->drawLine(top - QPoint(1,0), bottom - QPoint(1,0)); painter->setPen(QPen(grad, 0));
painter->drawLine(top - QPoint(1,0), bottom - QPoint(1,0));
} else {
painter->setPen(QPen(creatorTheme()->color(Theme::DoubleTabWidget2ndSeparatorColor), 0));
painter->drawLine(top, bottom);
}
} }
DoubleTabWidget::DoubleTabWidget(QWidget *parent) : DoubleTabWidget::DoubleTabWidget(QWidget *parent) :
@@ -352,16 +364,18 @@ void DoubleTabWidget::paintEvent(QPaintEvent *event)
// draw top level tab bar // draw top level tab bar
r.setHeight(Utils::StyleHelper::navigationWidgetHeight()); r.setHeight(Utils::StyleHelper::navigationWidgetHeight());
QPoint offset = window()->mapToGlobal(QPoint(0, 0)) - mapToGlobal(r.topLeft()); if (creatorTheme()->widgetStyle () == Theme::StyleDefault) {
QRect gradientSpan = QRect(offset, window()->size()); QPoint offset = window()->mapToGlobal(QPoint(0, 0)) - mapToGlobal(r.topLeft());
Utils::StyleHelper::horizontalGradient(&painter, gradientSpan, r); QRect gradientSpan = QRect(offset, window()->size());
Utils::StyleHelper::horizontalGradient(&painter, gradientSpan, r);
painter.setPen(Utils::StyleHelper::borderColor()); painter.setPen(Utils::StyleHelper::borderColor());
QColor lighter(255, 255, 255, 40);
QColor lighter(255, 255, 255, 40); painter.drawLine(r.bottomLeft(), r.bottomRight());
painter.drawLine(r.bottomLeft(), r.bottomRight()); painter.setPen(lighter);
painter.setPen(lighter); painter.drawLine(r.topLeft(), r.topRight());
painter.drawLine(r.topLeft(), r.topRight()); } else {
painter.fillRect(r, creatorTheme()->color(Theme::DoubleTabWidget1stEmptyAreaBackgroundColor));
}
QFontMetrics fm(font()); QFontMetrics fm(font());
int baseline = (r.height() + fm.ascent()) / 2 - 1; int baseline = (r.height() + fm.ascent()) / 2 - 1;
@@ -373,17 +387,23 @@ void DoubleTabWidget::paintEvent(QPaintEvent *event)
} }
QLinearGradient grad(QPoint(0, 0), QPoint(0, r.height() + OTHER_HEIGHT - 1)); QLinearGradient grad(QPoint(0, 0), QPoint(0, r.height() + OTHER_HEIGHT - 1));
grad.setColorAt(0, QColor(247, 247, 247)); if (creatorTheme()->widgetStyle() == Theme::StyleFlat) {
grad.setColorAt(1, QColor(205, 205, 205)); grad.setColorAt(0, creatorTheme()->color(Theme::DoubleTabWidget1stTabBackgroundColor));
} else {
grad.setColorAt(0, QColor(247, 247, 247));
grad.setColorAt(1, QColor(205, 205, 205));
}
// draw background of second bar // draw background of second bar
painter.fillRect(QRect(0, r.height(), r.width(), OTHER_HEIGHT), grad); painter.fillRect(QRect(0, r.height(), r.width(), OTHER_HEIGHT), grad);
painter.setPen(QColor(0x505050)); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
painter.drawLine(0, r.height() + OTHER_HEIGHT, painter.setPen(QColor(0x505050));
r.width(), r.height() + OTHER_HEIGHT); painter.drawLine(0, r.height() + OTHER_HEIGHT,
painter.setPen(Qt::white); r.width(), r.height() + OTHER_HEIGHT);
painter.drawLine(0, r.height(), painter.setPen(Qt::white);
r.width(), r.height()); painter.drawLine(0, r.height(),
r.width(), r.height());
}
// top level tabs // top level tabs
int x = m_title.isEmpty() ? 0 : int x = m_title.isEmpty() ? 0 :
@@ -464,26 +484,28 @@ void DoubleTabWidget::paintEvent(QPaintEvent *event)
r.height() + 1), r.height() + 1),
grad); grad);
if (actualIndex != 0) { if (actualIndex != 0 && creatorTheme()->widgetStyle() == Theme::StyleDefault) {
painter.setPen(QColor(255, 255, 255, 170)); painter.setPen(QColor(255, 255, 255, 170));
painter.drawLine(x, 0, x, r.height()); painter.drawLine(x, 0, x, r.height());
} }
x += MARGIN; x += MARGIN;
painter.setPen(Qt::black); painter.setPen(creatorTheme()->color(Theme::DoubleTabWidget1stTabActiveTextColor));
painter.drawText(x, baseline, tab.displayName()); painter.drawText(x, baseline, tab.displayName());
x += nameWidth.at(actualIndex); x += nameWidth.at(actualIndex);
x += MARGIN; x += MARGIN;
painter.setPen(Utils::StyleHelper::borderColor()); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
painter.drawLine(x, 0, x, r.height() - 1); painter.setPen(Utils::StyleHelper::borderColor());
painter.setPen(QColor(0, 0, 0, 20)); painter.drawLine(x, 0, x, r.height() - 1);
painter.drawLine(x + 1, 0, x + 1, r.height() - 1); painter.setPen(QColor(0, 0, 0, 20));
painter.setPen(QColor(255, 255, 255, 170)); painter.drawLine(x + 1, 0, x + 1, r.height() - 1);
painter.drawLine(x - 1, 0, x - 1, r.height()); painter.setPen(QColor(255, 255, 255, 170));
painter.drawLine(x - 1, 0, x - 1, r.height());
}
} else { } else {
if (i == 0) if (i == 0 && creatorTheme()->widgetStyle() == Theme::StyleDefault)
drawFirstLevelSeparator(&painter, QPoint(x, 0), QPoint(x, r.height()-1)); drawFirstLevelSeparator(&painter, QPoint(x, 0), QPoint(x, r.height()-1));
x += MARGIN; x += MARGIN;
painter.setPen(Utils::StyleHelper::panelTextColor()); painter.setPen(creatorTheme()->color(Theme::DoubleTabWidget1stTabInactiveTextColor));
painter.drawText(x + 1, baseline, tab.displayName()); painter.drawText(x + 1, baseline, tab.displayName());
x += nameWidth.at(actualIndex); x += nameWidth.at(actualIndex);
x += MARGIN; x += MARGIN;
@@ -512,14 +534,20 @@ void DoubleTabWidget::paintEvent(QPaintEvent *event)
x += MARGIN; x += MARGIN;
int textWidth = fm.width(subTabs.at(i)); int textWidth = fm.width(subTabs.at(i));
if (currentTab.currentSubTab == i) { if (currentTab.currentSubTab == i) {
painter.setPen(Qt::white); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
painter.drawPixmap(x, y, m_left); painter.drawPixmap(x, y, m_left);
painter.drawPixmap(QRect(x + SELECTION_IMAGE_WIDTH, y, painter.drawPixmap(QRect(x + SELECTION_IMAGE_WIDTH, y,
textWidth, imageHeight), textWidth, imageHeight),
m_mid, QRect(0, 0, m_mid.width(), m_mid.height())); m_mid, QRect(0, 0, m_mid.width(), m_mid.height()));
painter.drawPixmap(x + SELECTION_IMAGE_WIDTH + textWidth, y, m_right); painter.drawPixmap(x + SELECTION_IMAGE_WIDTH + textWidth, y, m_right);
} else {
painter.setBrush(creatorTheme()->color(Theme::DoubleTabWidget2ndTabBackgroundColor));
painter.setPen(Qt::NoPen);
painter.drawRoundedRect(QRect(x,y,2*SELECTION_IMAGE_WIDTH+textWidth, m_mid.height()), 5,5);
}
painter.setPen(creatorTheme()->color(Theme::DoubleTabWidget2ndTabActiveTextColor));
} else { } else {
painter.setPen(Qt::black); painter.setPen(creatorTheme()->color(Theme::DoubleTabWidget2ndTabInactiveTextColor));
} }
x += SELECTION_IMAGE_WIDTH; x += SELECTION_IMAGE_WIDTH;
painter.drawText(x, y + (imageHeight + fm.ascent()) / 2. - 1, painter.drawText(x, y + (imageHeight + fm.ascent()) / 2. - 1,

View File

@@ -37,6 +37,7 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/styledbar.h> #include <utils/styledbar.h>
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/theme/theme.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
@@ -89,6 +90,7 @@ static QIcon createCenteredIcon(const QIcon &icon, const QIcon &overlay)
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal; using namespace ProjectExplorer::Internal;
using namespace Utils;
static bool projectLesserThan(Project *p1, Project *p2) static bool projectLesserThan(Project *p1, Project *p2)
{ {
@@ -133,17 +135,21 @@ void TargetSelectorDelegate::paint(QPainter *painter,
selectionGradient.load(QLatin1String(":/projectexplorer/images/targetpanel_gradient.png")); selectionGradient.load(QLatin1String(":/projectexplorer/images/targetpanel_gradient.png"));
if (option.state & QStyle::State_Selected) { if (option.state & QStyle::State_Selected) {
QColor color =(option.state & QStyle::State_HasFocus) ? if (creatorTheme()->widgetStyle() == Theme::StyleFlat) {
option.palette.highlight().color() : painter->fillRect(option.rect, creatorTheme()->color(Theme::BackgroundColorSelected));
option.palette.dark().color(); } else {
painter->fillRect(option.rect, color.darker(140)); QColor color =(option.state & QStyle::State_HasFocus) ?
Utils::StyleHelper::drawCornerImage(selectionGradient, painter, option.rect.adjusted(0, 0, 0, -1), 5, 5, 5, 5); option.palette.highlight().color() :
painter->setPen(QColor(255, 255, 255, 60)); option.palette.dark().color();
painter->drawLine(option.rect.topLeft(), option.rect.topRight()); painter->fillRect(option.rect, color.darker(140));
painter->setPen(QColor(255, 255, 255, 30)); Utils::StyleHelper::drawCornerImage(selectionGradient, painter, option.rect.adjusted(0, 0, 0, -1), 5, 5, 5, 5);
painter->drawLine(option.rect.bottomLeft() - QPoint(0,1), option.rect.bottomRight() - QPoint(0,1)); painter->setPen(QColor(255, 255, 255, 60));
painter->setPen(QColor(0, 0, 0, 80)); painter->drawLine(option.rect.topLeft(), option.rect.topRight());
painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight()); painter->setPen(QColor(255, 255, 255, 30));
painter->drawLine(option.rect.bottomLeft() - QPoint(0,1), option.rect.bottomRight() - QPoint(0,1));
painter->setPen(QColor(0, 0, 0, 80));
painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
}
} }
QFontMetrics fm(option.font); QFontMetrics fm(option.font);
@@ -640,7 +646,7 @@ MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorActi
m_hideOnRelease(false) m_hideOnRelease(false)
{ {
QPalette p; QPalette p;
p.setColor(QPalette::Text, QColor(255, 255, 255, 160)); p.setColor(QPalette::Text, creatorTheme()->color(Theme::MiniProjectTargetSelectorTextColor));
setPalette(p); setPalette(p);
setProperty("panelwidget", true); setProperty("panelwidget", true);
setContentsMargins(QMargins(0, 1, 1, 8)); setContentsMargins(QMargins(0, 1, 1, 8));
@@ -654,7 +660,8 @@ MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorActi
m_summaryLabel = new QLabel(this); m_summaryLabel = new QLabel(this);
m_summaryLabel->setMargin(3); m_summaryLabel->setMargin(3);
m_summaryLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop); m_summaryLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
m_summaryLabel->setStyleSheet(QString::fromLatin1("background: #464646;")); m_summaryLabel->setStyleSheet(QString::fromLatin1("background: %1;")
.arg(creatorTheme()->color(Theme::MiniProjectTargetSelectorSummaryBackgroundColor).name()));
m_summaryLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); m_summaryLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
m_summaryLabel->setTextInteractionFlags(m_summaryLabel->textInteractionFlags() | Qt::LinksAccessibleByMouse); m_summaryLabel->setTextInteractionFlags(m_summaryLabel->textInteractionFlags() | Qt::LinksAccessibleByMouse);
@@ -1575,15 +1582,18 @@ void MiniProjectTargetSelector::updateSummary()
void MiniProjectTargetSelector::paintEvent(QPaintEvent *) void MiniProjectTargetSelector::paintEvent(QPaintEvent *)
{ {
QPainter painter(this); QPainter painter(this);
painter.setBrush(QBrush(QColor(160, 160, 160, 255))); painter.setBrush(creatorTheme()->color(Theme::MiniProjectTargetSelectorBackgroundColor));
painter.drawRect(rect()); painter.drawRect(rect());
painter.setPen(Utils::StyleHelper::borderColor()); painter.setPen(creatorTheme()->color(Theme::MiniProjectTargetSelectorBackgroundColor));
// draw border on top and right
painter.drawLine(rect().topLeft(), rect().topRight()); painter.drawLine(rect().topLeft(), rect().topRight());
painter.drawLine(rect().topRight(), rect().bottomRight()); painter.drawLine(rect().topRight(), rect().bottomRight());
if (creatorTheme()->flag(Theme::DrawTargetSelectorBottom)) {
QRect bottomRect(0, rect().height() - 8, rect().width(), 8); // draw thicker border on the bottom
static QImage image(QLatin1String(":/projectexplorer/images/targetpanel_bottom.png")); QRect bottomRect(0, rect().height() - 8, rect().width(), 8);
Utils::StyleHelper::drawCornerImage(image, &painter, bottomRect, 1, 1, 1, 1); static QImage image(QLatin1String(":/projectexplorer/images/targetpanel_bottom.png"));
Utils::StyleHelper::drawCornerImage(image, &painter, bottomRect, 1, 1, 1, 1);
}
} }
void MiniProjectTargetSelector::switchToProjectsMode() void MiniProjectTargetSelector::switchToProjectsMode()

View File

@@ -36,6 +36,7 @@
#include <QLabel> #include <QLabel>
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/theme/theme.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
namespace { namespace {
@@ -53,6 +54,7 @@ const int PANEL_LEFT_MARGIN = 70;
/// \brief The OnePixelBlackLine class /// \brief The OnePixelBlackLine class
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils;
namespace { namespace {
class OnePixelBlackLine : public QWidget class OnePixelBlackLine : public QWidget
@@ -69,8 +71,7 @@ public:
{ {
Q_UNUSED(e); Q_UNUSED(e);
QPainter p(this); QPainter p(this);
QColor fillColor = Utils::StyleHelper::mergedColors( QColor fillColor = creatorTheme()->color(Theme::PanelsWidgetSeparatorLineColor);
palette().button().color(), Qt::black, 80);
p.fillRect(contentsRect(), fillColor); p.fillRect(contentsRect(), fillColor);
} }
}; };
@@ -88,16 +89,19 @@ void RootWidget::paintEvent(QPaintEvent *e)
{ {
QWidget::paintEvent(e); QWidget::paintEvent(e);
QPainter painter(this); if (creatorTheme()->widgetStyle() == Theme::StyleDefault) {
QColor light = Utils::StyleHelper::mergedColors( // draw separator line to the right of the settings panel
palette().button().color(), Qt::white, 30); QPainter painter(this);
QColor dark = Utils::StyleHelper::mergedColors( QColor light = Utils::StyleHelper::mergedColors(
palette().button().color(), Qt::black, 85); palette().button().color(), Qt::white, 30);
QColor dark = Utils::StyleHelper::mergedColors(
palette().button().color(), Qt::black, 85);
painter.setPen(light); painter.setPen(light);
painter.drawLine(rect().topRight(), rect().bottomRight()); painter.drawLine(rect().topRight(), rect().bottomRight());
painter.setPen(dark); painter.setPen(dark);
painter.drawLine(rect().topRight() - QPoint(1,0), rect().bottomRight() - QPoint(1,0)); painter.drawLine(rect().topRight() - QPoint(1,0), rect().bottomRight() - QPoint(1,0));
}
} }
} }
@@ -176,6 +180,7 @@ void PanelsWidget::addPropertiesPanel(PropertiesPanel *panel)
nameLabel->setText(panel->displayName()); nameLabel->setText(panel->displayName());
QPalette palette = nameLabel->palette(); QPalette palette = nameLabel->palette();
for (int i = QPalette::Active; i < QPalette::NColorGroups; ++i ) { for (int i = QPalette::Active; i < QPalette::NColorGroups; ++i ) {
// FIXME: theming
QColor foregroundColor = palette.color(QPalette::ColorGroup(i), QPalette::Foreground); QColor foregroundColor = palette.color(QPalette::ColorGroup(i), QPalette::Foreground);
foregroundColor.setAlpha(110); foregroundColor.setAlpha(110);
palette.setBrush(QPalette::ColorGroup(i), QPalette::Foreground, foregroundColor); palette.setBrush(QPalette::ColorGroup(i), QPalette::Foreground, foregroundColor);

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

View File

@@ -42,6 +42,7 @@
#include <qtsupport/qtsupportconstants.h> #include <qtsupport/qtsupportconstants.h>
#include <texteditor/texteditoractionhandler.h> #include <texteditor/texteditoractionhandler.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/theme/theme.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QFileInfo> #include <QFileInfo>
@@ -49,6 +50,7 @@
#include <QTextBlock> #include <QTextBlock>
using namespace TextEditor; using namespace TextEditor;
using namespace Utils;
namespace QmakeProjectManager { namespace QmakeProjectManager {
namespace Internal { namespace Internal {
@@ -222,9 +224,9 @@ ProFileEditorFactory::ProFileEditorFactory()
addHoverHandler(new ProFileHoverHandler(keywords)); addHoverHandler(new ProFileHoverHandler(keywords));
setSyntaxHighlighterCreator([keywords]() { return new ProFileHighlighter(keywords); }); setSyntaxHighlighterCreator([keywords]() { return new ProFileHighlighter(keywords); });
Core::FileIconProvider::registerIconOverlayForSuffix(QtSupport::Constants::ICON_QT_PROJECT, "pro"); Core::FileIconProvider::registerIconOverlayForSuffix(creatorTheme()->iconOverlay(Theme::ProMimetype).toLatin1().data(), "pro");
Core::FileIconProvider::registerIconOverlayForSuffix(QtSupport::Constants::ICON_QT_PROJECT, "pri"); Core::FileIconProvider::registerIconOverlayForSuffix(creatorTheme()->iconOverlay(Theme::PriMimetype).toLatin1().data(), "pri");
Core::FileIconProvider::registerIconOverlayForSuffix(QtSupport::Constants::ICON_QT_PROJECT, "prf"); Core::FileIconProvider::registerIconOverlayForSuffix(creatorTheme()->iconOverlay(Theme::PrfMimetype).toLatin1().data(), "prf");
} }
} // namespace Internal } // namespace Internal

View File

@@ -60,6 +60,7 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <utils/theme/theme.h>
#include <proparser/prowriter.h> #include <proparser/prowriter.h>
#include <proparser/qmakevfs.h> #include <proparser/qmakevfs.h>
@@ -73,6 +74,7 @@
#include <utils/QtConcurrentTools> #include <utils/QtConcurrentTools>
using namespace Core; using namespace Core;
using namespace Utils;
// Static cached data in struct QmakeNodeStaticData providing information and icons // Static cached data in struct QmakeNodeStaticData providing information and icons
// for file types and the project. Do some magic via qAddPostRoutine() // for file types and the project. Do some magic via qAddPostRoutine()
@@ -150,7 +152,10 @@ QmakeNodeStaticData::QmakeNodeStaticData()
const QSize desiredSize = QSize(16, 16); const QSize desiredSize = QSize(16, 16);
for (unsigned i = 0 ; i < count; ++i) { for (unsigned i = 0 ; i < count; ++i) {
const QIcon overlayIcon = QIcon(QLatin1String(fileTypeDataStorage[i].icon)); QIcon overlayIcon;
QString iconFile = QString::fromLatin1(fileTypeDataStorage[i].icon);
iconFile = creatorTheme()->imageFile(iconFile);
overlayIcon = QIcon(iconFile);
const QPixmap folderPixmap = const QPixmap folderPixmap =
Core::FileIconProvider::overlayIcon(QStyle::SP_DirIcon, Core::FileIconProvider::overlayIcon(QStyle::SP_DirIcon,
overlayIcon, desiredSize); overlayIcon, desiredSize);
@@ -161,7 +166,8 @@ QmakeNodeStaticData::QmakeNodeStaticData()
desc, folderIcon)); desc, folderIcon));
} }
// Project icon // Project icon
const QIcon projectBaseIcon(QLatin1String(":/qtsupport/images/qt_project.png")); const QLatin1String fname(":/qtsupport/images/qt_project.png");
const QIcon projectBaseIcon(creatorTheme()->imageFile(fname));
const QPixmap projectPixmap = Core::FileIconProvider::overlayIcon(QStyle::SP_DirIcon, const QPixmap projectPixmap = Core::FileIconProvider::overlayIcon(QStyle::SP_DirIcon,
projectBaseIcon, projectBaseIcon,
desiredSize); desiredSize);

View File

@@ -6,5 +6,8 @@
<file>images/headers.png</file> <file>images/headers.png</file>
<file>images/sources.png</file> <file>images/sources.png</file>
<file>images/unknown.png</file> <file>images/unknown.png</file>
<file>images/dark_headers.png</file>
<file>images/dark_sources.png</file>
<file>images/dark_unknown.png</file>
</qresource> </qresource>
</RCC> </RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

View File

@@ -32,6 +32,7 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <utils/theme/theme.h>
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QTextCursor> #include <QTextCursor>
@@ -39,6 +40,7 @@
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace QtSupport; using namespace QtSupport;
using namespace Utils;
// "file" or "qrc", colon, optional '//', '/' and further characters // "file" or "qrc", colon, optional '//', '/' and further characters
#define QML_URL_REGEXP \ #define QML_URL_REGEXP \
@@ -181,8 +183,7 @@ void QtOutputFormatter::appendLine(QTextCursor &cursor, const LinkResult &lr,
cursor.insertText(line.left(lr.start), normalFormat); cursor.insertText(line.left(lr.start), normalFormat);
QTextCharFormat linkFormat = normalFormat; QTextCharFormat linkFormat = normalFormat;
const QColor textColor = plainTextEdit()->palette().color(QPalette::Text); linkFormat.setForeground(creatorTheme()->color(Theme::QtOutputFormatter_LinkTextColor));
linkFormat.setForeground(mixColors(textColor, QColor(Qt::blue)));
linkFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); linkFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
linkFormat.setAnchor(true); linkFormat.setAnchor(true);
linkFormat.setAnchorHref(lr.href); linkFormat.setAnchorHref(lr.href);

View File

@@ -4,6 +4,10 @@
<file>images/qml.png</file> <file>images/qml.png</file>
<file>images/qt_project.png</file> <file>images/qt_project.png</file>
<file>images/qt_qrc.png</file> <file>images/qt_qrc.png</file>
<file>images/dark_forms.png</file>
<file>images/dark_qml.png</file>
<file>images/dark_qt_project.png</file>
<file>images/dark_qt_qrc.png</file>
<file>QtSupport.mimetypes.xml</file> <file>QtSupport.mimetypes.xml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -100,6 +100,7 @@ const char IOS_PLATFORM_TR[] = QT_TRANSLATE_NOOP("QtSupport", "iOS");
const char QML_WIZARD_ICON[] = ":/qmlproject/images/qml_wizard.png"; const char QML_WIZARD_ICON[] = ":/qmlproject/images/qml_wizard.png";
const char ICON_QT_PROJECT[] = ":/qtsupport/images/qt_project.png"; const char ICON_QT_PROJECT[] = ":/qtsupport/images/qt_project.png";
const char DARK_ICON_QT_PROJECT[] = ":/qtsupport/images/dark_qt_project.png";
} // namepsace Constants } // namepsace Constants
} // namepsace QtSupport } // namepsace QtSupport

View File

@@ -2509,7 +2509,13 @@ bool TextEditorWidget::event(QEvent *e)
e->ignore(); // we are a really nice citizen e->ignore(); // we are a really nice citizen
d->m_maybeFakeTooltipEvent = false; d->m_maybeFakeTooltipEvent = false;
return true; return true;
break; case QEvent::ApplicationPaletteChange: {
// slight hack: ignore palette changes
// at this point the palette has changed already,
// so undo it by re-setting the palette:
applyFontSettings();
return true;
}
default: default:
break; break;
} }

View File

@@ -34,8 +34,12 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/theme/theme.h>
#include <QIcon> #include <QIcon>
using namespace Utils;
namespace Todo { namespace Todo {
namespace Internal { namespace Internal {
@@ -83,6 +87,10 @@ QVariant TodoItemsModel::data(const QModelIndex &index, int role) const
if (role == Qt::BackgroundColorRole) if (role == Qt::BackgroundColorRole)
return item.color; return item.color;
if (role == Qt::TextColorRole)
return creatorTheme()->color(Theme::TodoItemTextColor);
if (role == Qt::ForegroundRole)
return creatorTheme()->color(Theme::TodoItemTextColor);
switch (index.column()) { switch (index.column()) {

View File

@@ -44,6 +44,9 @@
#include <utils/styledbar.h> #include <utils/styledbar.h>
#include <utils/iwelcomepage.h> #include <utils/iwelcomepage.h>
#include <utils/theme/theme.h>
#include <utils/theme/welcometheme.h>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QMessageBox> #include <QMessageBox>
@@ -86,6 +89,8 @@ public:
// bool eventFilter(QObject *, QEvent *); // bool eventFilter(QObject *, QEvent *);
public slots: public slots:
void onThemeChanged();
void setActivePlugin(int pos) void setActivePlugin(int pos)
{ {
if (m_activePlugin != pos) { if (m_activePlugin != pos) {
@@ -108,11 +113,13 @@ private:
QuickContainer *m_welcomePage; QuickContainer *m_welcomePage;
QList<QObject*> m_pluginList; QList<QObject*> m_pluginList;
int m_activePlugin; int m_activePlugin;
WelcomeTheme *m_welcomeTheme;
}; };
// --- WelcomeMode // --- WelcomeMode
WelcomeMode::WelcomeMode() : WelcomeMode::WelcomeMode() :
m_activePlugin(0) m_activePlugin(0),
m_welcomeTheme(new WelcomeTheme(this))
{ {
setDisplayName(tr("Welcome")); setDisplayName(tr("Welcome"));
setIcon(QIcon(QLatin1String(":/welcome/images/mode_welcome.png"))); setIcon(QIcon(QLatin1String(":/welcome/images/mode_welcome.png")));
@@ -128,6 +135,7 @@ WelcomeMode::WelcomeMode() :
layout->setSpacing(0); layout->setSpacing(0);
m_welcomePage = new QuickContainer(); m_welcomePage = new QuickContainer();
onThemeChanged(); //initialize background color
m_welcomePage->setResizeMode(QuickContainer::SizeRootObjectToView); m_welcomePage->setResizeMode(QuickContainer::SizeRootObjectToView);
m_welcomePage->setObjectName(QLatin1String("WelcomePage")); m_welcomePage->setObjectName(QLatin1String("WelcomePage"));
@@ -154,6 +162,12 @@ WelcomeMode::WelcomeMode() :
setWidget(m_modeWidget); setWidget(m_modeWidget);
} }
void WelcomeMode::onThemeChanged()
{
m_welcomePage->setColor(creatorTheme()->color(Theme::BackgroundColorNormal));
m_welcomeTheme->notifyThemeChanged();
}
WelcomeMode::~WelcomeMode() WelcomeMode::~WelcomeMode()
{ {
QSettings *settings = Core::ICore::settings(); QSettings *settings = Core::ICore::settings();
@@ -243,6 +257,15 @@ void WelcomeMode::initPlugins()
ctx->setContextProperty(QLatin1String("pagesModel"), QVariant::fromValue(m_pluginList)); ctx->setContextProperty(QLatin1String("pagesModel"), QVariant::fromValue(m_pluginList));
connect(creatorTheme(), &Theme::changed, this, &WelcomeMode::onThemeChanged);
ctx->setContextProperty(QLatin1String("creatorTheme"), m_welcomeTheme);
// FIXME: pass theme class to QML somehow
if (creatorTheme()->widgetStyle() == Theme::StyleFlat)
ctx->setContextProperty(QLatin1String("theme"), QLatin1String("dark"));
else
ctx->setContextProperty(QLatin1String("theme"), QLatin1String("default"));
QString path = resourcePath() + QLatin1String("/welcomescreen/welcomescreen.qml"); QString path = resourcePath() + QLatin1String("/welcomescreen/welcomescreen.qml");
// finally, load the root page // finally, load the root page