QtDesignStudio Color Editor update

Palettes, Favorite colors, Recent colors, changed layout.

Change-Id: I6fca962923a3e7a230edebdab5a30bd0847c8ba9
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Aleksei German
2019-04-09 17:59:33 +02:00
committed by Thomas Hartmann
parent 7016aa5c02
commit 1927813ab1
21 changed files with 1365 additions and 190 deletions

View File

@@ -82,6 +82,9 @@ Item {
lightnessSlider.value = lightness
alphaSlider.value = alpha
redSlider.value = (color.r * 255)
greenSlider.value = (color.g * 255)
blueSlider.value = (color.b * 255)
block = false
}
@@ -242,7 +245,6 @@ Item {
anchors.margins: 6
y: 4
height: parent.height - 8
//value: colorButton.hue
onValueChanged: {
if (colorButton.hue !== value)
colorButton.hue = value
@@ -250,17 +252,133 @@ Item {
onClicked: colorButton.clicked()
}
Column {
Row {
anchors.left: hueSlider.right
anchors.margins: colorButton.sliderMargins
spacing: 10
Column {
spacing: 10
Row {
z: 3
spacing: 4
spacing: 1
Label {
text: "H:"
text: "R"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: redSlider
width: 64
stepSize: 1
minimumValue: 0
maximumValue: 255
decimals: 0
onValueChanged: {
if (color.r !== value && !colorButton.block) {
color.r = (value / 255.0)
colorButton.clicked()
}
}
}
}
Row {
z: 2
spacing: 1
Controls.Label {
text: "G"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: greenSlider
width: 64
stepSize: 1
minimumValue: 0
maximumValue: 255
decimals: 0
onValueChanged: {
if (color.g !== value && !colorButton.block) {
color.g = (value / 255.0)
colorButton.clicked()
}
}
}
}
Row {
z: 1
spacing: 1
Controls.Label {
text: "B"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: blueSlider
width: 64
stepSize: 1
minimumValue: 0
maximumValue: 255
decimals: 0
onValueChanged: {
if (color.b !== value && !colorButton.block) {
color.b = (value / 255.0)
colorButton.clicked()
}
}
}
}
Row {
z: 0
spacing: 1
Controls.Label {
text: "A"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: alphaSlider
width: 64
onValueChanged: {
if (colorButton.alpha !== value && !colorButton.block) {
colorButton.alpha = value
colorButton.clicked()
}
}
}
}
}
Column {
spacing: 10
Row {
z: 3
spacing: 1
Label {
text: "H"
width: 16
color: "#eee"
elide: Text.ElideRight
@@ -268,7 +386,7 @@ Item {
}
DoubleSpinBox {
id: hueSlider2
//value: colorButton.hue
width: 64
onValueChanged: {
if (colorButton.hue !== value && !colorButton.block) {
colorButton.hue = value
@@ -280,9 +398,9 @@ Item {
Row {
z: 2
spacing: 4
spacing: 1
Controls.Label {
text: "S:"
text: "S"
width: 16
color: "#eee"
elide: Text.ElideRight
@@ -291,7 +409,7 @@ Item {
DoubleSpinBox {
id: saturationSlider
//value: colorButton.saturation
width: 64
onValueChanged: {
if (colorButton.saturation !== value && !colorButton.block) {
colorButton.saturation = value
@@ -303,9 +421,9 @@ Item {
Row {
z: 1
spacing: 4
spacing: 1
Controls.Label {
text: "L:"
text: "L"
width: 16
color: "#eee"
elide: Text.ElideRight
@@ -313,7 +431,7 @@ Item {
}
DoubleSpinBox {
id: lightnessSlider
//value: colorButton.lightness
width: 64
onValueChanged: {
if (colorButton.lightness !== value && !colorButton.block) {
colorButton.lightness = value
@@ -322,29 +440,6 @@ Item {
}
}
}
Row {
z: 0
spacing: 4
Controls.Label {
text: "A:"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: alphaSlider
//value: colorButton.alpha
onValueChanged: {
if (colorButton.alpha !== value && !colorButton.block) {
colorButton.alpha = value
colorButton.clicked()
}
}
}
}
}
}

View File

@@ -25,19 +25,54 @@
import QtQuick 2.1
Item {
id: colorCheckButtonRoot
property bool checked: false
property alias buttonColor: checkBox.color
width: 30
height: 24
Rectangle {
id: backgroundBox
width: 24
height: 24
anchors.right: parent.right
color: "white"
border.color: "white"
border.width: 1
Rectangle {
id: checkBox
width: 18
height: 18
width: 22
height: 22
anchors.centerIn: parent
border.color: "black"
border.width: 1
}
}
property bool checked: false
Image {
id: arrowImage
width: 8
height: 4
source: "image://icons/down-arrow"
anchors.verticalCenter: parent.verticalCenter
anchors.right: backgroundBox.left
anchors.rightMargin: 2
opacity: colorToolTip.containsMouse ? 1 : 0.8
rotation: colorCheckButtonRoot.checked ? 0.0 : 270.0
}
MouseArea {
ToolTipArea {
id: colorToolTip
onClicked: checked = !checked
hoverEnabled: true
anchors.fill: parent
onClicked: checkBox.checked = !checkBox.checked
anchors.leftMargin: -arrowImage.width
tooltip: qsTr("Toggle color picker view")
}
}

View File

@@ -38,7 +38,7 @@ Column {
property bool supportGradient: false
property alias caption: label.text
property string caption: "Color"
property variant backendValue
@@ -50,8 +50,14 @@ Column {
property alias transparent: transparentButton.checked
property color originalColor
function isNotInGradientMode() {
return (buttonRow.checkedIndex !== 1)
return (buttonRow.checkedIndex === 0 || transparent)
}
function resetShapeColor() {
colorEditor.backendValue.resetValue()
}
onValueChanged: colorEditor.color = colorEditor.value
@@ -73,7 +79,7 @@ Column {
if (!gradientLine.isInValidState)
return;
if (supportGradient && gradientLine.hasGradient) {
if (colorEditor.supportGradient && gradientLine.hasGradient) {
textField.text = convertColorToString(color)
gradientLine.currentColor = color
}
@@ -84,23 +90,28 @@ Column {
}
}
ColorLine {
visible: {
return (colorEditor.supportGradient && isNotInGradientMode())
}
currentColor: colorEditor.color
width: parent.width
}
GradientLine {
property bool isInValidState: false
visible: {
if (colorEditor.shapeGradients) {
return buttonRow.checkedIndex > 0 && buttonRow.checkedIndex < 4
} else {
return buttonRow.checkedIndex === 1
}
return !(isNotInGradientMode())
}
id: gradientLine
width: parent.width
onCurrentColorChanged: {
if (supportGradient && gradientLine.hasGradient)
if (colorEditor.supportGradient && gradientLine.hasGradient) {
colorEditor.color = gradientLine.currentColor
}
}
onHasGradientChanged: {
if (!colorEditor.supportGradient)
@@ -125,11 +136,21 @@ Column {
buttonRow.initalChecked = 1
}
colorEditor.color = gradientLine.currentColor
} else if (colorEditor.transparent) {
buttonRow.initalChecked = 4
} else {
buttonRow.initalChecked = 0
colorEditor.color = colorEditor.value
}
buttonRow.checkedIndex = buttonRow.initalChecked
colorEditor.originalColor = colorEditor.color
}
onSelectedNodeChanged: {
if (colorEditor.supportGradient && gradientLine.hasGradient) {
colorEditor.originalColor = gradientLine.currentColor
}
}
Connections {
@@ -137,18 +158,26 @@ Column {
onSelectionToBeChanged: {
colorEditorTimer.stop()
gradientLine.isInValidState = false
if (colorEditor.originalColor !== colorEditor.color) {
if (colorEditor.color != "#ffffff"
&& colorEditor.color != "#000000"
&& colorEditor.color != "#00000000") {
colorPalette.addColorToPalette(colorEditor.color)
}
}
}
}
Connections {
target: modelNodeBackend
onSelectionChanged: {
if (supportGradient && gradientLine.hasGradient) {
if (colorEditor.supportGradient && gradientLine.hasGradient) {
colorEditor.color = gradientLine.currentColor
gradientLine.currentColor = color
textField.text = colorEditor.color
}
gradientLine.isInValidState = true
colorEditor.originalColor = colorEditor.color
}
}
@@ -156,29 +185,21 @@ Column {
SectionLayout {
width: parent.width
columnSpacing: 0
rowSpacing: checkButton.checked ? 8 : 2
rows: 5
//spacer 1
Item {
height: 0
width: 2
}
Item {
height: 0
width: 2
}
Label {
id: label
text: "Color"
height: 6
}
SecondColumnLayout {
ColorCheckButton {
id: checkButton
color: colorEditor.color
buttonColor: colorEditor.color
}
LineEdit {
@@ -217,64 +238,30 @@ Column {
iconSource: "images/icon_color_solid.png"
onClicked: {
if (colorEditor.supportGradient)
gradientLine.deleteGradient()
textField.text = colorEditor.color
colorEditor.backendValue.resetValue()
colorEditor.resetShapeColor()
}
tooltip: qsTr("Solid Color")
}
ButtonRowButton {
visible: supportGradient
visible: colorEditor.supportGradient
iconSource: "images/icon_color_gradient.png"
onClicked: {
colorEditor.backendValue.resetValue()
if (colorEditor.shapeGradients) {
gradientLine.deleteGradient()
colorEditor.resetShapeColor()
if (colorEditor.shapeGradients)
gradientLine.gradientTypeName = "LinearGradient"
}
else
gradientLine.gradientTypeName = "Gradient"
if (gradientLine.hasGradient)
gradientLine.updateGradient()
else {
gradientLine.deleteGradient()
gradientLine.addGradient()
}
GradientPresetList {
id: presetList
visible: false
function applyPreset() {
if (presetList.gradientData.presetType == 0) {
gradientLine.setPresetByID(presetList.gradientData.presetID);
}
else if (presetList.gradientData.presetType == 1) {
gradientLine.setPresetByStops(
presetList.gradientData.stops,
presetList.gradientData.colors,
presetList.gradientData.stopsCount);
}
else { console.log("INVALID GRADIENT TYPE: " + presetList.gradientData.presetType); }
}
onApply: {
if (presetList.gradientData.stopsCount > 0) {
applyPreset();
}
}
onSaved: {
gradientLine.savePreset();
presetList.updatePresets();
}
onAccepted: { //return key
if (presetList.gradientData.stopsCount > 0) {
applyPreset();
}
}
}
onDoubleClicked: {
presetList.open()
}
tooltip: qsTr("Linear Gradient")
@@ -345,16 +332,19 @@ Column {
}
}
ButtonRowButton {
visible: supportGradient && colorEditor.shapeGradients
visible: colorEditor.supportGradient && colorEditor.shapeGradients
iconSource: "images/icon_color_radial_gradient.png"
onClicked: {
colorEditor.backendValue.resetValue()
if (colorEditor.shapeGradients) {
gradientLine.deleteGradient()
colorEditor.resetShapeColor()
gradientLine.gradientTypeName = "RadialGradient"
}
if (gradientLine.hasGradient)
gradientLine.updateGradient()
else {
gradientLine.deleteGradient()
gradientLine.addGradient()
}
}
tooltip: qsTr("Radial Gradient")
@@ -442,18 +432,21 @@ Column {
}
}
ButtonRowButton {
visible: supportGradient && colorEditor.shapeGradients
visible: colorEditor.supportGradient && colorEditor.shapeGradients
iconSource: "images/icon_color_conical_gradient.png"
onClicked: {
colorEditor.backendValue.resetValue()
if (colorEditor.shapeGradients) {
gradientLine.deleteGradient()
colorEditor.resetShapeColor()
gradientLine.gradientTypeName = "ConicalGradient"
}
if (gradientLine.hasGradient)
gradientLine.updateGradient()
else {
gradientLine.deleteGradient()
gradientLine.addGradient()
}
}
tooltip: qsTr("Concial Gradient")
tooltip: qsTr("Conical Gradient")
GradientPopupIndicator {
@@ -513,18 +506,104 @@ Column {
id: transparentButton
iconSource: "images/icon_color_none.png"
onClicked: {
colorEditor.color = "#00000000"
if (colorEditor.supportGradient)
gradientLine.deleteGradient()
colorEditor.resetShapeColor()
colorEditor.color = "#00000000"
}
tooltip: qsTr("Transparent")
}
}
Rectangle {
id: gradientPickerButton
width: 20
height: 20
visible: colorEditor.supportGradient
color: "white"
border.color: "white"
border.width: 1
ToolTipArea {
anchors.fill: parent
id: toolTipArea
tooltip: qsTr("Gradient Picker Dialog")
}
GradientPresetList {
id: presetList
visible: false
function applyPreset() {
if (presetList.gradientData.presetType == 0) {
gradientLine.setPresetByID(presetList.gradientData.presetID);
}
else if (presetList.gradientData.presetType == 1) {
gradientLine.setPresetByStops(
presetList.gradientData.stops,
presetList.gradientData.colors,
presetList.gradientData.stopsCount);
}
else {
console.log("INVALID GRADIENT TYPE: " +
presetList.gradientData.presetType);
}
}
onApply: {
if (presetList.gradientData.stopsCount > 0) {
applyPreset();
}
}
onSaved: {
gradientLine.savePreset();
presetList.updatePresets();
}
onAccepted: { //return key
if (presetList.gradientData.stopsCount > 0) {
applyPreset();
}
}
}
Rectangle {
width: 18
height: 18
anchors.centerIn: parent
color: "steelblue"
border.color: "black"
border.width: 1
MouseArea {
anchors.fill: parent
onClicked: {
presetList.open()
}
}
}
}
ExpandingSpacer {
}
}
//empty spacer 2
Item {
height: 6
}
Item {
height: 6
}
//spacer 3
Item {
height: 6
}
ColorButton {
property color bindedColor: colorEditor.color
@@ -536,24 +615,101 @@ Column {
enabled: !colorEditor.transparent
opacity: checkButton.checked ? 1 : 0
id: colorButton
width: 116
height: checkButton.checked ? 116 : 0
Layout.preferredWidth: 116
Layout.preferredHeight: checkButton.checked ? 116 : 0
Layout.preferredWidth: 124
Layout.preferredHeight: checkButton.checked ? 124 : 0
sliderMargins: Math.max(0, label.width - colorButton.width) + 4
sliderMargins: 4
onClicked: colorEditor.color = colorButton.color
}
SecondColumnLayout {
//empty spacer 4
Item { height: 2 }
Item { height: 2 }
//spacer 5
Item {
height: 4
}
Item {
height: 4
width :4
id: colorBoxes
Layout.preferredWidth: 134
Layout.preferredHeight: checkButton.checked ? 70 : 0
visible: checkButton.checked
SecondColumnLayout {
spacing: 16
RowLayout {
spacing: 2
Column {
spacing: 5
Text {
text: qsTr("Original")
color: "#eee"
}
Rectangle {
id: originalColorRectangle
color: colorEditor.originalColor
height: 40
width: 67
border.width: 1
border.color: "#555555"
MouseArea {
anchors.fill: parent
onClicked: {
if (!colorEditor.transparent)
colorEditor.color = colorEditor.originalColor
}
}
}
}
Column {
spacing: 5
Text {
text: qsTr("New")
color: "#eee"
}
Rectangle {
id: newColorRectangle
color: colorEditor.color
height: 40
width: 67
border.width: 1
border.color: "#555555"
}
}
}
Column {
spacing: 5
Text {
text: qsTr("Recent")
color: "#eee"
elide: Text.ElideRight
}
SimpleColorPalette {
id: colorPalette
clickable: !colorEditor.transparent
onSelectedColorChanged: {
colorEditor.color = colorPalette.selectedColor;
}
}
}
ExpandingSpacer {
}
}
}
}
}

View File

@@ -0,0 +1,53 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import HelperWidgets 2.0
import QtQuick.Controls.Private 1.0 // showing a ToolTip
Item {
width: 300
height: 60
property alias currentColor : colorLine.color
Column {
anchors.fill: parent
Item {
width: 1
height: 40
}
Rectangle {
height: 16
width: parent.width
border.color: "#555555"
border.width: 1
id: colorLine
color: "white"
}
}
}

View File

@@ -40,6 +40,8 @@ Item {
property alias gradientPropertyName: gradientModel.gradientPropertyName
property alias gradientTypeName: gradientModel.gradientTypeName
signal selectedNodeChanged
onHasGradientChanged: {
colorLine.invalidate()
}
@@ -75,6 +77,10 @@ Item {
gradientModel.savePreset()
}
function updateGradient() {
gradientModel.updateGradient()
}
Connections {
target: modelNodeBackend
onSelectionChanged: {
@@ -105,6 +111,7 @@ Item {
gradientModel.lock()
currentColor = repeater.itemAt(index).item.color
gradientModel.unlock()
selectedNodeChanged()
}
function invalidate() {
@@ -134,6 +141,7 @@ Item {
height: 40
anchors.left: parent.left
anchors.right: parent.right
cursorShape: Qt.PointingHandCursor
onClicked: {
var currentPosition = mouseX / colorLine.effectiveWidth
@@ -321,6 +329,7 @@ Item {
drag.maximumX: colorLine.effectiveWidth
drag.minimumY: !readOnly ? 0 : 20
drag.maximumY: 20
cursorShape: Qt.PointingHandCursor
// using pressed property instead of drag.active which was not working
onExited: {

View File

@@ -0,0 +1,113 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 2.5
import HelperWidgets 2.0
import QtQuick.Controls.Private 1.0 // showing a ToolTip
Item {
property color selectedColor
property bool clickable : true
width: 200
height: 40
enabled: clickable
function addColorToPalette(colorCode)
{
paletteModel.addItem(colorCode)
}
Component {
id: colorItemDelegate
Rectangle {
id: backgroundColor
property var favorite : isFavorite
height: 27
width: 27
border.color: (backgroundColor.favorite ? "#ffd700" : "#555555")
border.width: (backgroundColor.favorite ? 2 : 1)
color: "white"
radius: 0
Rectangle {
id: colorRectangle
width: 25
height: 25
anchors.centerIn: parent
color: colorCode
border.color: "black"
border.width: 1
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if ((mouse.button === Qt.LeftButton) && clickable)
selectedColor = colorRectangle.color
}
onPressed: {
if (mouse.button === Qt.RightButton)
contextMenu.popup()
}
}
Menu {
id: contextMenu
modal: true
closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnEscape
MenuItem {
text: (backgroundColor.favorite
? qsTr("Remove from Favorites")
: qsTr("Add to Favorites"))
onTriggered: {
paletteModel.toggleFavorite(index)
}
}
Overlay.modal: Rectangle {
color: "transparent"
}
}
}
}
SimpleColorPaletteModel { id: paletteModel }
ListView {
id: colorPaletteView
model: paletteModel
delegate: colorItemDelegate
orientation: Qt.Horizontal
anchors.fill: parent
clip: true
interactive: false
spacing: 2
}
}

View File

@@ -9,6 +9,7 @@ CheckBox 2.0 CheckBox.qml
ColorButton 2.0 ColorButton.qml
ColorCheckButton 2.0 ColorCheckButton.qml
ColorEditor 2.0 ColorEditor.qml
ColorLine 2.0 ColorLine.qml
ColorLogic 2.0 ColorLogic.qml
ComboBox 2.0 ComboBox.qml
CustomCheckBoxStyle 2.0 CustomCheckBoxStyle.qml
@@ -33,6 +34,7 @@ ScrollView 2.0 ScrollView.qml
SecondColumnLayout 2.0 SecondColumnLayout.qml
Section 2.0 Section.qml
SectionLayout 2.0 SectionLayout.qml
SimpleColorPalette 2.0 SimpleColorPalette.qml
DoubleSpinBox 2.0 DoubleSpinBox.qml
SpinBox 2.0 SpinBox.qml
StandardTextSection 2.0 StandardTextSection.qml

View File

@@ -181,7 +181,7 @@ void GradientModel::addGradient()
setupModel();
if (m_gradientTypeName != "Gradient")
QTimer::singleShot(100, [this](){ view()->resetPuppet(); }); /*Unfortunately required */
QTimer::singleShot(1000, [this](){ view()->resetPuppet(); }); /*Unfortunately required */
emit hasGradientChanged();
emit gradientTypeChanged();
}
@@ -534,19 +534,20 @@ void GradientModel::setPresetByStops(const QList<qreal> &stopsPositions,
QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(
QByteArrayLiteral("GradientModel::setCustomPreset"));
//delete an old gradient without rewriter transaction
deleteGradientNode(false);
//create a new gradient:
if (!m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) {
try {
if (m_gradientTypeName != "Gradient")
ensureShapesImport();
QmlDesigner::ModelNode gradientNode = createGradientNode();
m_itemNode.modelNode()
.nodeProperty(gradientPropertyName().toUtf8())
.reparentHere(gradientNode);
//create stops and give them positions and colors based on value
for (int i = 0; i < stopsCount; i++) {
QmlDesigner::ModelNode gradientStopNode = createGradientStopNode();
gradientStopNode.variantProperty("position").setValue(stopsPositions.at(i));
@@ -560,6 +561,9 @@ void GradientModel::setPresetByStops(const QList<qreal> &stopsPositions,
}
setupModel();
if (m_gradientTypeName != "Gradient")
QTimer::singleShot(200, [this]() { view()->resetPuppet(); }); /*Unfortunately required */
emit hasGradientChanged();
emit gradientTypeChanged();
}
@@ -586,3 +590,16 @@ void GradientModel::savePreset()
items.append(item);
GradientPresetCustomListModel::storePresets(filename, items);
}
void GradientModel::updateGradient()
{
QList<qreal> stops;
QList<QString> colors;
int stopsCount = rowCount();
for (int i = 0; i < stopsCount; i++) {
stops.append(getPosition(i));
colors.append(getColor(i).name(QColor::HexArgb));
}
setPresetByStops(stops, colors, stopsCount);
}

View File

@@ -77,6 +77,8 @@ public:
Q_INVOKABLE void savePreset();
Q_INVOKABLE void updateGradient();
signals:
void anchorBackendChanged();
void hasGradientChanged();

View File

@@ -15,7 +15,10 @@ SOURCES += propertyeditorview.cpp \
gradientpresetitem.cpp \
gradientpresetlistmodel.cpp \
gradientpresetdefaultlistmodel.cpp \
gradientpresetcustomlistmodel.cpp
gradientpresetcustomlistmodel.cpp \
simplecolorpalette.cpp \
simplecolorpalettemodel.cpp \
simplecolorpalettesingleton.cpp
HEADERS += propertyeditorview.h \
qmlanchorbindingproxy.h \
@@ -32,6 +35,9 @@ HEADERS += propertyeditorview.h \
gradientpresetitem.h \
gradientpresetlistmodel.h \
gradientpresetdefaultlistmodel.h \
gradientpresetcustomlistmodel.h
gradientpresetcustomlistmodel.h \
simplecolorpalette.h \
simplecolorpalettemodel.h \
simplecolorpalettesingleton.h
QT += qml quick

View File

@@ -30,6 +30,7 @@
#include "gradientmodel.h"
#include "gradientpresetdefaultlistmodel.h"
#include "gradientpresetcustomlistmodel.h"
#include "simplecolorpalettemodel.h"
#include "qmlanchorbindingproxy.h"
#include "theme.h"
@@ -52,6 +53,7 @@ void Quick2PropertyEditorView::registerQmlTypes()
GradientModel::registerDeclarativeType();
GradientPresetDefaultListModel::registerDeclarativeType();
GradientPresetCustomListModel::registerDeclarativeType();
SimpleColorPaletteModel::registerDeclarativeType();
Internal::QmlAnchorBindingProxy::registerDeclarativeType();
}
}

View File

@@ -0,0 +1,113 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "simplecolorpalette.h"
#include "designersettings.h"
#include <QDebug>
namespace QmlDesigner {
PaletteColor::PaletteColor()
: m_color(QColor())
, m_colorCode(QColor().name())
, m_isFavorite(false)
{}
PaletteColor::PaletteColor(const QString &colorCode)
: m_color(colorCode)
, m_colorCode(colorCode)
, m_isFavorite(false)
{}
PaletteColor::PaletteColor(const QColor &value)
: m_color(color)
, m_colorCode(color.name(QColor::HexArgb))
, m_isFavorite(false)
{}
QVariant PaletteColor::getProperty(Property id) const
{
QVariant out;
switch (id) {
case objectNameRole:
out.setValue(QString());
break;
case colorRole:
out.setValue(color());
break;
case colorCodeRole:
out.setValue(colorCode());
break;
case isFavoriteRole:
out.setValue(isFavorite());
break;
default:
qWarning() << "PaletteColor Property switch default case";
break; //replace with assert before switch?
}
return out;
}
QColor PaletteColor::color() const
{
return m_color;
}
void PaletteColor::setColor(const QColor &value)
{
m_color = value;
m_colorCode = m_color.name(QColor::HexArgb);
}
QString PaletteColor::colorCode() const
{
return m_colorCode;
}
bool PaletteColor::isFavorite() const
{
return m_isFavorite;
}
void PaletteColor::setFavorite(bool favorite)
{
m_isFavorite = favorite;
}
bool PaletteColor::toggleFavorite()
{
return m_isFavorite = !m_isFavorite;
}
bool PaletteColor::operator==(const PaletteColor &other) const
{
return (m_color == other.m_color);
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,75 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QObject>
#include <QtQml/qqml.h>
#include <QColor>
namespace QmlDesigner {
class PaletteColor
{
Q_GADGET
Q_PROPERTY(QColor color READ color FINAL)
Q_PROPERTY(QString colorCode READ colorCode FINAL)
Q_PROPERTY(bool isFavorite READ isFavorite FINAL)
public:
PaletteColor();
PaletteColor(const QString &colorCode);
PaletteColor(const QColor &value);
~PaletteColor() = default;
enum Property {
objectNameRole = 0,
colorRole = 1,
colorCodeRole = 2,
isFavoriteRole = 3
};
QVariant getProperty(Property id) const;
QColor color() const;
void setColor(const QColor &value);
QString colorCode() const;
bool isFavorite() const;
void setFavorite(bool favorite);
bool toggleFavorite();
bool operator==(const PaletteColor &other) const;
private:
QColor m_color;
QString m_colorCode;
bool m_isFavorite;
};
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::PaletteColor)

View File

@@ -0,0 +1,146 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "simplecolorpalettemodel.h"
#include "simplecolorpalette.h"
#include "simplecolorpalettesingleton.h"
#include "designersettings.h"
#include <QHash>
#include <QByteArray>
#include <QDebug>
#include <QSettings>
namespace QmlDesigner {
SimpleColorPaletteModel::SimpleColorPaletteModel(QObject *parent)
: QAbstractListModel(parent)
{
connect(&SimpleColorPaletteSingleton::getInstance(),
&SimpleColorPaletteSingleton::paletteChanged,
this,
&SimpleColorPaletteModel::setPalette);
m_roleNames = {{static_cast<int>(PaletteColor::Property::objectNameRole), "objectName"},
{static_cast<int>(PaletteColor::Property::colorRole), "color"},
{static_cast<int>(PaletteColor::Property::colorCodeRole), "colorCode"},
{static_cast<int>(PaletteColor::Property::isFavoriteRole), "isFavorite"}};
setPalette();
}
SimpleColorPaletteModel::~SimpleColorPaletteModel()
{
clearItems();
}
int SimpleColorPaletteModel::rowCount(const QModelIndex & /*parent*/) const
{
return m_items.count();
}
QVariant SimpleColorPaletteModel::data(const QModelIndex &index, int role) const
{
if (index.isValid() && (index.row() >= 0) && (index.row() < m_items.count())) {
if (m_roleNames.contains(role)) {
QVariant value = m_items.at(index.row())
.getProperty(static_cast<PaletteColor::Property>(role));
if (auto model = qobject_cast<SimpleColorPaletteModel *>(value.value<QObject *>()))
return QVariant::fromValue(model);
return value;
}
qWarning() << Q_FUNC_INFO << "invalid role requested";
return QVariant();
}
qWarning() << Q_FUNC_INFO << "invalid index requested";
return QVariant();
}
QHash<int, QByteArray> SimpleColorPaletteModel::roleNames() const
{
return m_roleNames;
}
void SimpleColorPaletteModel::clearItems()
{
beginResetModel();
m_items.clear();
endResetModel();
}
void SimpleColorPaletteModel::addItem(const QString &item)
{
PaletteColor palette(item);
addItem(palette);
}
void SimpleColorPaletteModel::addItem(const PaletteColor &item)
{
SimpleColorPaletteSingleton::getInstance().addItem(item);
}
const QList<PaletteColor> &SimpleColorPaletteModel::items() const
{
return m_items;
}
void SimpleColorPaletteModel::sortItems()
{
SimpleColorPaletteSingleton::getInstance().sortItems();
}
void SimpleColorPaletteModel::registerDeclarativeType()
{
qmlRegisterType<SimpleColorPaletteModel>("HelperWidgets", 2, 0, "SimpleColorPaletteModel");
}
void SimpleColorPaletteModel::toggleFavorite(int id)
{
SimpleColorPaletteSingleton::getInstance().toggleFavorite(id);
}
void SimpleColorPaletteModel::setPalette()
{
beginResetModel();
m_items = SimpleColorPaletteSingleton::getInstance().getItems();
m_favoriteOffset = SimpleColorPaletteSingleton::getInstance().getFavoriteOffset();
m_paletteSize = SimpleColorPaletteSingleton::getInstance().getPaletteSize();
endResetModel();
}
bool SimpleColorPaletteModel::read()
{
return SimpleColorPaletteSingleton::getInstance().readPalette();
}
void SimpleColorPaletteModel::write()
{
SimpleColorPaletteSingleton::getInstance().writePalette();
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,77 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QAbstractListModel>
#include <QtQml/qqml.h>
#include <QList>
namespace QmlDesigner {
class PaletteColor;
class SimpleColorPaletteModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit SimpleColorPaletteModel(QObject *parent = nullptr);
~SimpleColorPaletteModel() override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
void clearItems();
Q_INVOKABLE void addItem(const QString &item);
void addItem(const PaletteColor &item);
const QList<PaletteColor> &items() const;
void sortItems();
static void registerDeclarativeType();
Q_INVOKABLE void toggleFavorite(int id);
bool read();
void write();
private slots:
void setPalette();
private:
void enqueue(const PaletteColor &item);
private:
int m_paletteSize;
int m_favoriteOffset;
QList<PaletteColor> m_items;
QHash<int, QByteArray> m_roleNames;
};
} // namespace QmlDesigner
QML_DECLARE_TYPE(QmlDesigner::SimpleColorPaletteModel)

View File

@@ -0,0 +1,185 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "simplecolorpalettesingleton.h"
#include "simplecolorpalette.h"
#include "designersettings.h"
#include <QDebug>
#include <QSettings>
namespace QmlDesigner {
SimpleColorPaletteSingleton::SimpleColorPaletteSingleton()
: m_items()
, m_favoriteOffset(0)
{
if (!readPalette()) {
for (int i = 0; i < m_paletteSize; i++)
m_items.append(PaletteColor());
}
}
SimpleColorPaletteSingleton &SimpleColorPaletteSingleton::getInstance()
{
static SimpleColorPaletteSingleton singleton;
return singleton;
}
void SimpleColorPaletteSingleton::addItem(const PaletteColor &item)
{
if (m_favoriteOffset >= m_paletteSize)
return;
if (item.isFavorite()) {
int contains = m_items.indexOf(item);
if (contains != -1) {
if (m_items.at(contains).isFavorite())
return;
else
m_items.removeAt(contains);
}
m_items.insert(0, item);
m_favoriteOffset++;
} else if (m_items.contains(item))
return;
else
m_items.insert(m_favoriteOffset, item);
while (m_items.size() > m_paletteSize) {
m_items.removeLast();
}
writePalette();
emit paletteChanged();
}
QList<PaletteColor> SimpleColorPaletteSingleton::getItems() const
{
return m_items;
}
int SimpleColorPaletteSingleton::getPaletteSize() const
{
return m_paletteSize;
}
int SimpleColorPaletteSingleton::getFavoriteOffset() const
{
return m_favoriteOffset;
}
void SimpleColorPaletteSingleton::sortItems()
{
auto itemSort = [](const PaletteColor &first, const PaletteColor &second) {
return (static_cast<int>(first.isFavorite()) < static_cast<int>(second.isFavorite()));
};
std::sort(m_items.begin(), m_items.end(), itemSort);
emit paletteChanged();
}
void SimpleColorPaletteSingleton::toggleFavorite(int id)
{
bool toggleResult = m_items[id].toggleFavorite();
if (toggleResult) {
m_favoriteOffset++;
m_items.move(id, 0);
} else {
m_favoriteOffset--;
m_items.move(id, m_favoriteOffset);
}
if (m_favoriteOffset < 0)
m_favoriteOffset = 0;
else if (m_favoriteOffset > m_paletteSize)
m_favoriteOffset = m_paletteSize;
emit paletteChanged();
}
bool SimpleColorPaletteSingleton::readPalette()
{
QList<PaletteColor> proxy;
const QStringList stringData = QmlDesigner::DesignerSettings::getValue(
QmlDesigner::DesignerSettingsKey::SIMPLE_COLOR_PALETTE_CONTENT)
.toStringList();
int favCounter = 0;
for (int i = 0; i < stringData.size(); i++) {
const QStringList strsep = stringData.at(i).split(";");
if (strsep.size() != 2) {
continue;
}
PaletteColor colorItem(strsep.at(0));
bool isFav = static_cast<bool>(strsep.at(1).toInt());
colorItem.setFavorite(isFav);
if (isFav)
favCounter++;
proxy.append(colorItem);
}
if (proxy.size() == 0) {
return false;
}
while (proxy.size() > m_paletteSize) {
proxy.removeLast();
}
while (proxy.size() < m_paletteSize) {
proxy.append(PaletteColor());
}
m_items.clear();
m_items = proxy;
m_favoriteOffset = favCounter;
return true;
}
void SimpleColorPaletteSingleton::writePalette()
{
QStringList output;
QString subres;
for (int i = 0; i < m_items.size(); i++) {
subres = m_items.at(i).color().name(QColor::HexArgb);
subres += ";";
subres += QString::number(static_cast<int>(m_items.at(i).isFavorite()));
output.push_back(subres);
subres.clear();
}
QmlDesigner::DesignerSettings::setValue(
QmlDesigner::DesignerSettingsKey::SIMPLE_COLOR_PALETTE_CONTENT, output);
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,72 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QObject>
#include <QAbstractListModel>
#include <QtQml/qqml.h>
#include <QList>
#include <QColor>
namespace QmlDesigner {
class PaletteColor;
class SimpleColorPaletteSingleton : public QObject
{
Q_OBJECT
public:
static SimpleColorPaletteSingleton &getInstance();
bool readPalette();
void writePalette();
void addItem(const PaletteColor &item);
QList<PaletteColor> getItems() const;
int getPaletteSize() const;
int getFavoriteOffset() const;
void sortItems();
void toggleFavorite(int id);
SimpleColorPaletteSingleton(const SimpleColorPaletteSingleton &) = delete;
void operator=(const SimpleColorPaletteSingleton &) = delete;
signals:
void paletteChanged();
private:
SimpleColorPaletteSingleton();
private:
QList<PaletteColor> m_items;
const int m_paletteSize = 6;
int m_favoriteOffset;
};
} // namespace QmlDesigner

View File

@@ -372,6 +372,13 @@ bool smartVeryFuzzyCompare(const QVariant &value1, const QVariant &value2)
return false;
}
bool smartColorCompare(const QVariant &value1, const QVariant &value2)
{
if ((value1.type() == QVariant::Color) || (value2.type() == QVariant::Color))
return value1.value<QColor>().rgba() == value2.value<QColor>().rgba();
return false;
}
bool equals(const QVariant &a, const QVariant &b)
{
if (a.canConvert<QmlDesigner::Enumeration>() && b.canConvert<QmlDesigner::Enumeration>())
@@ -380,6 +387,8 @@ bool equals(const QVariant &a, const QVariant &b)
return true;
if (smartVeryFuzzyCompare(a, b))
return true;
if (smartColorCompare(a, b))
return true;
return false;
}

View File

@@ -76,6 +76,7 @@ void DesignerSettings::fromSettings(QSettings *settings)
restoreValue(settings, DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS, true);
restoreValue(settings, DesignerSettingsKey::STANDALONE_MODE, false);
restoreValue(settings, DesignerSettingsKey::ENABLE_TIMELINEVIEW, false);
restoreValue(settings, DesignerSettingsKey::SIMPLE_COLOR_PALETTE_CONTENT, QStringList());
settings->endGroup();
settings->endGroup();

View File

@@ -65,6 +65,7 @@ const char REFORMAT_UI_QML_FILES[] = "ReformatUiQmlFiles"; /* These setti
const char IGNORE_DEVICE_PIXEL_RATIO[] = "IgnoreDevicePixelRaio"; /* The settings can be used to turn off the feature, if there are serious issues */
const char STANDALONE_MODE[] = "StandAloneMode";
const char ENABLE_TIMELINEVIEW[] = "EnableTimelineView";
const char SIMPLE_COLOR_PALETTE_CONTENT[] = "SimpleColorPaletteContent";
}
class DesignerSettings : public QHash<QByteArray, QVariant>

View File

@@ -588,6 +588,12 @@ Project {
"propertyeditor/qmlanchorbindingproxy.h",
"propertyeditor/qmlmodelnodeproxy.cpp",
"propertyeditor/qmlmodelnodeproxy.h",
"propertyeditor/simplecolorpalette.cpp",
"propertyeditor/simplecolorpalette.h",
"propertyeditor/simplecolorpalettemodel.cpp",
"propertyeditor/simplecolorpalettemodel.h",
"propertyeditor/simplecolorpalettesingleton.cpp",
"propertyeditor/simplecolorpalettesingleton.h",
"resources/resources.qrc",
"stateseditor/stateseditorimageprovider.cpp",
"stateseditor/stateseditorimageprovider.h",