diff --git a/cuttlefish/package/contents/ui/DualMontage.qml b/cuttlefish/package/contents/ui/DualMontage.qml new file mode 100644 index 0000000..6d50277 --- /dev/null +++ b/cuttlefish/package/contents/ui/DualMontage.qml @@ -0,0 +1,139 @@ +/*************************************************************************** + * * + * Copyright 2019 Carson Black * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + * * + ***************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 2.5 as QQC2 +import QtQuick.Layouts 1.0 +import QtQuick.Dialogs 1.3 + +import org.kde.kirigami 2.8 as Kirigami + +Item { + id: dualMontage + visible: false + height: 512 + width: 512 + Kirigami.Theme.inherit: false + function shot() { + ssPicker.open() + } + FileDialog { + id: ssPicker + selectExisting: false + selectMultiple: false + selectFolder: false + onAccepted: { + dualMontage.grabToImage(function(result) { + res = result.saveToFile(ssPicker.fileUrl.toString().slice(7)) + }); + } + nameFilters: [ "PNG screenshot files (*.png)" ] + } + Column { + Rectangle { + height: 256 + width: 512 + color: Kirigami.Theme.backgroundColor + Kirigami.Theme.inherit: false + Kirigami.Theme.textColor: "#232629" + Kirigami.Theme.backgroundColor: "#eff0f1" + Kirigami.Theme.highlightColor: "#3daee9" + Kirigami.Theme.highlightedTextColor: "#eff0f1" + Kirigami.Theme.positiveTextColor: "#27ae60" + Kirigami.Theme.neutralTextColor: "#f67400" + Kirigami.Theme.negativeTextColor: "#da4453" + + GridLayout { + id: previewGrid + anchors.centerIn: parent + columns: sizes.length + rows: 2 + property var sizes: [8, 16, 22, 32, 48, 64, 128] + Repeater { + model: previewGrid.sizes.length + delegate: Kirigami.Icon { + Layout.alignment: Qt.AlignBottom + source: preview.iconName + width: previewGrid.sizes[index] + height: previewGrid.sizes[index] + } + } + Repeater { + model: previewGrid.sizes.length + delegate: QQC2.Label { + Layout.alignment: Qt.AlignTop | Qt.AlignHCenter + text: previewGrid.sizes[index] + } + } + } + Row { + anchors.top: parent.top + anchors.left: parent.left + anchors.margins: Kirigami.Units.smallSpacing + Kirigami.Icon { + height: 32 + width: 32 + source: "cuttlefish" + } + QQC2.Label { + anchors.verticalCenter: parent.verticalCenter + text: "Montage made with Cuttlefish" + } + } + } + Rectangle { + height: 256 + width: 512 + color: Kirigami.Theme.backgroundColor + Kirigami.Theme.inherit: false + Kirigami.Theme.textColor: "#eff0f1" + Kirigami.Theme.backgroundColor: "#31363b" + Kirigami.Theme.highlightColor: "#3daee9" + Kirigami.Theme.highlightedTextColor: "#eff0f1" + Kirigami.Theme.positiveTextColor: "#27ae60" + Kirigami.Theme.neutralTextColor: "#f67400" + Kirigami.Theme.negativeTextColor: "#da4453" + + GridLayout { + anchors.centerIn: parent + columns: sizes.length + rows: 2 + property var sizes: [8, 16, 22, 32, 48, 64, 128] + Repeater { + model: previewGrid.sizes.length + delegate: Kirigami.Icon { + Layout.alignment: Qt.AlignBottom + source: preview.iconName + width: previewGrid.sizes[index] + height: previewGrid.sizes[index] + } + } + Repeater { + model: previewGrid.sizes.length + delegate: QQC2.Label { + Layout.alignment: Qt.AlignTop | Qt.AlignHCenter + text: previewGrid.sizes[index] + } + } + } + } + } +} \ No newline at end of file diff --git a/cuttlefish/package/contents/ui/IconGrid.qml b/cuttlefish/package/contents/ui/GlobalMenuBar.qml similarity index 50% copy from cuttlefish/package/contents/ui/IconGrid.qml copy to cuttlefish/package/contents/ui/GlobalMenuBar.qml index 3c9acb1..c1936ba 100644 --- a/cuttlefish/package/contents/ui/IconGrid.qml +++ b/cuttlefish/package/contents/ui/GlobalMenuBar.qml @@ -1,59 +1,77 @@ +import QtQuick 2.5 +import Qt.labs.platform 1.0 + /*************************************************************************** * * - * Copyright 2014-2015 Sebastian Kügler * + * Copyright 2019 Carson Black * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ -import QtQuick 2.2 -// import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 - -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras - - -GridView { - id: iconGrid +MenuBar { + id: root - focus: true + signal quit() + signal zoomIn() + signal zoomOut() + signal montage(int type) - cellWidth: iconSize + units.gridUnit - cellHeight: cellWidth + Math.round(units.gridUnit * 2) - - cacheBuffer: 10000 - highlightMoveDuration: 0 - boundsBehavior: Flickable.StopAtBounds - model: iconModel - - highlight: Rectangle { - color: theme.highlightColor - //height: parent.height + units.gridUnit * 3 - anchors.bottomMargin: -units.gridUnit * 2 + Menu { + title: i18n("File") + Menu { + title: i18n("Export Montage with Color Scheme...") + MenuItem { + text: i18n("Active Color Scheme") + onTriggered: root.montage(0) + } + MenuItem { + text: i18n("Breeze (Normal)") + onTriggered: root.montage(1) + } + MenuItem { + text: i18n("Breeze Dark") + onTriggered: root.montage(2) + } + MenuItem { + text: i18n("Breeze (Normal) and Breeze Dark") + onTriggered: root.montage(0) + } + } + MenuSeparator {} + MenuItem { + iconName: "gtk-quit" + text: i18n("Quit") + shortcut: StandardKey.Quit + onTriggered: root.quit() + } } - - delegate: IconGridDelegate {} - - PlasmaComponents.BusyIndicator { - running: iconModel.loading - visible: running - anchors.centerIn: parent - width: units.gridUnit * 8 - height: width + Menu { + title: i18n("View") + MenuItem { + iconName: "zoom-in" + text: i18n("Zoom In") + shortcut: StandardKey.ZoomIn + onTriggered: root.zoomIn() + } + MenuItem { + iconName: "zoom-out" + text: i18n("Zoom Out") + shortcut: StandardKey.ZoomOut + onTriggered: root.zoomOut() + } } -} +} \ No newline at end of file diff --git a/cuttlefish/package/contents/ui/IconGrid.qml b/cuttlefish/package/contents/ui/IconGrid.qml index 3c9acb1..3d4a356 100644 --- a/cuttlefish/package/contents/ui/IconGrid.qml +++ b/cuttlefish/package/contents/ui/IconGrid.qml @@ -1,59 +1,51 @@ /*************************************************************************** * * * Copyright 2014-2015 Sebastian Kügler * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ -import QtQuick 2.2 -// import QtQuick.Controls 1.0 +import QtQuick 2.5 +import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras - +import org.kde.kirigami 2.8 as Kirigami GridView { id: iconGrid - focus: true - cellWidth: iconSize + units.gridUnit - cellHeight: cellWidth + Math.round(units.gridUnit * 2) + cellWidth: iconSize + Math.round(Kirigami.Units.gridUnit * 1.5) + cellHeight: cellWidth + Math.round(Kirigami.Units.gridUnit * 2) - cacheBuffer: 10000 + cacheBuffer: 20 highlightMoveDuration: 0 boundsBehavior: Flickable.StopAtBounds model: iconModel - highlight: Rectangle { - color: theme.highlightColor - //height: parent.height + units.gridUnit * 3 - anchors.bottomMargin: -units.gridUnit * 2 - } + highlight: Item {} delegate: IconGridDelegate {} - PlasmaComponents.BusyIndicator { + QQC2.BusyIndicator { running: iconModel.loading visible: running anchors.centerIn: parent - width: units.gridUnit * 8 + width: Kirigami.Units.gridUnit * 8 height: width } } diff --git a/cuttlefish/package/contents/ui/IconGridDelegate.qml b/cuttlefish/package/contents/ui/IconGridDelegate.qml index 606a4e4..6f2ac0f 100644 --- a/cuttlefish/package/contents/ui/IconGridDelegate.qml +++ b/cuttlefish/package/contents/ui/IconGridDelegate.qml @@ -1,112 +1,121 @@ /*************************************************************************** * * * Copyright 2014-2017 Sebastian Kügler * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ -import QtQuick 2.2 -// import QtQuick.Controls 1.0 +import QtQuick 2.5 +import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras - +import org.kde.kirigami 2.8 as Kirigami MouseArea { id: delegateRoot - width: iconSize - height: iconSize + Math.round(units.gridUnit * 1.25) - hoverEnabled: hoveredHighlight + width: iconSize + Kirigami.Units.gridUnit + height: cellWidth + Math.round(Kirigami.Units.gridUnit * 2) + acceptedButtons: Qt.LeftButton | Qt.RightButton function setAsPreview() { - print("preview() " + iconName + " " + fullPath); preview.fullPath = fullPath preview.iconName = iconName preview.fileName = fileName preview.category = category preview.type = type preview.iconTheme = iconTheme preview.sizes = sizes preview.scalable = scalable; } Rectangle { - color: theme.highlightColor - //height: parent.height + units.gridUnit * 3 - opacity: iconGrid.currentIndex == index ? 1.0 : 0.0 + color: Kirigami.Theme.highlightColor + opacity: iconGrid.currentIndex == index ? 0.5 : 0.0 visible: opacity != 0.0 Behavior on opacity { NumberAnimation { duration: units.shortDuration } } anchors { - bottomMargin: Math.round(-units.gridUnit * 1.25) - margins: -units.gridUnit / 2 fill: parent } + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor } - PlasmaCore.IconItem { + Kirigami.Icon { + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor id: delegateIcon width: iconSize height: width source: iconName - usesPlasmaTheme: cuttlefish.usesPlasmaTheme - colorGroup: PlasmaCore.ColorScope.colorGroup anchors { top: parent.top horizontalCenter: parent.horizontalCenter } } - PlasmaComponents.Label { + QQC2.Label { + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor font.pointSize: iconSize > 96 ? theme.defaultFont.pointSize : theme.smallestFont.pointSize text: iconName wrapMode: Text.Wrap -// elide: Text.ElideRight maximumLineCount: 3 horizontalAlignment: Text.AlignHCenter opacity: iconGrid.currentIndex == index ? 1.0 : 0.7 anchors { left: parent.left right: parent.right top: delegateIcon.bottom - //topMargin: Math.round(-units.gridUnit / 4) topMargin: 0 margins: Math.round(-units.gridUnit / 4) - //horizontalCenter: parent.horizontalCenter - //bottom: parent.bottom } } Connections { target: iconGrid onCurrentIndexChanged: { if (delegateRoot.GridView.isCurrentItem) { - print("index changed" + iconName + " " + fullPath) - //preview.fullPath = fullPath delegateRoot.setAsPreview(); } } } - onClicked: { + onClicked: (mouse) => { iconGrid.currentIndex = index; iconGrid.forceActiveFocus(); + if (mouse.button == Qt.RightButton) { + cuttlefish.itemRightClicked() + } } onEntered: { setAsPreview(); } } diff --git a/cuttlefish/src/view.h b/cuttlefish/package/contents/ui/Menu.qml similarity index 63% rename from cuttlefish/src/view.h rename to cuttlefish/package/contents/ui/Menu.qml index de2d9bf..542d4ff 100644 --- a/cuttlefish/src/view.h +++ b/cuttlefish/package/contents/ui/Menu.qml @@ -1,52 +1,48 @@ /*************************************************************************** * * - * Copyright 2014 Sebastian Kügler * + * Copyright 2019 Carson Black * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + * * ***************************************************************************/ -#ifndef CUTTEFISHVIEW_H -#define CUTTEFISHVIEW_H - -#include -#include -#include -#include - -#include - -namespace CuttleFish { - -class View : public QQuickView -{ - Q_OBJECT - -public: - explicit View(const QString &category, QCommandLineParser &parser, QWindow *parent = nullptr); - ~View() override; - -Q_SIGNALS: - void titleChanged(const QString&); - -private: - KPackage::Package m_package; - QQuickItem* m_browserRootItem; - KDirModel m_dirModel; -}; - -} - -#endif // BROWSERVIEW_H +import QtQuick 2.5 +import Qt.labs.platform 1.0 + +Menu { + id: root + Connections { + target: cuttlefish + onItemRightClicked: { + root.open() + } + } + MenuItem { + iconName: "edit-copy" + text: i18n("Copy icon name to clipboard") + onTriggered: { + previewPane.clipboard(iconName) + cuttlefish.showPassiveNotification(i18n("Icon name copied to clipboard"), "short") + } + } + MenuItem { + iconName: "document-open" + text: i18n("Open icon with external program") + onTriggered: { + Qt.openUrlExternally(preview.fullPath) + } + } +} \ No newline at end of file diff --git a/cuttlefish/package/contents/ui/Preview.qml b/cuttlefish/package/contents/ui/Preview.qml index f698fba..6377cd3 100644 --- a/cuttlefish/package/contents/ui/Preview.qml +++ b/cuttlefish/package/contents/ui/Preview.qml @@ -1,209 +1,322 @@ /*************************************************************************** * * * Copyright 2014-2017 Sebastian Kügler * + * Copyrihgt 2019 Carson Black * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ import QtQuick 2.2 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 +import QtQuick.Dialogs 1.3 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras - +import org.kde.kirigami 2.8 as Kirigami Rectangle { + property alias iconPreview: iconPreview + property alias dualMont: dualMont - id: preview - - color: PlasmaCore.ColorScope.backgroundColor + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor - property string iconName: "plasma" - property string fullPath: "" - property string category: "" - property string fileName: "" - property string type: "" - property string iconTheme: "" - property variant sizes: [] - property bool scalable: true + color: Kirigami.Theme.backgroundColor function clipboard(text) { if (!pickerMode) { clipboardHelper.text = text; clipboardHelper.selectAll(); clipboardHelper.copy(); } else { iconModel.output(text); } } TextEdit { id: clipboardHelper visible: false } + FileDialog { + id: ssPicker + selectExisting: false + selectMultiple: false + selectFolder: false + onAccepted: { + iconPreview.grabToImage(function(result) { + ssPicker.resetColors() + res = result.saveToFile(ssPicker.fileUrl.toString().slice(7)) + }); + } + onRejected: { + ssPicker.resetColors() + } + function resetColors() { + iconPreview.screenshotting = false + iconPreview.Kirigami.Theme.textColor = Kirigami.Theme.textColor + iconPreview.Kirigami.Theme.backgroundColor = Kirigami.Theme.backgroundColor + iconPreview.Kirigami.Theme.highlightColor = Kirigami.Theme.highlightColor + iconPreview.Kirigami.Theme.highlightedTextColor = Kirigami.Theme.highlightedTextColor + iconPreview.Kirigami.Theme.positiveTextColor = Kirigami.Theme.positiveTextColor + iconPreview.Kirigami.Theme.neutralTextColor = Kirigami.Theme.neutralTextColor + iconPreview.Kirigami.Theme.negativeTextColor = Kirigami.Theme.negativeTextColor + iconPreview.Kirigami.Theme.inherit = true + } + nameFilters: [ "PNG screenshot files (*.png)" ] + } ColumnLayout { - anchors.margins: units.gridUnit - anchors.rightMargin: units.gridUnit * 2 anchors.fill: parent - spacing: units.gridUnit / 2 - - Item { height: units.gridUnit / 2 } + spacing: Kirigami.Units.largeSpacing - PlasmaExtras.Heading { - level: 3 - elide: Text.ElideRight + Kirigami.Heading { + level: 1 Layout.fillWidth: true - Layout.fillHeight: false wrapMode: Text.Wrap - text: iconName + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + text: preview.iconName } - RowLayout { - Layout.fillWidth: false - Layout.fillHeight: false - Layout.preferredHeight: indexToSize(4) - anchors.horizontalCenter: parent.horizontalCenter - - PlasmaCore.IconItem { - source: iconName - usesPlasmaTheme: cuttlefish.usesPlasmaTheme - colorGroup: PlasmaCore.ColorScope.colorGroup - Layout.preferredWidth: indexToSize(0) - Layout.preferredHeight: indexToSize(0) - } - PlasmaCore.IconItem { - source: iconName - usesPlasmaTheme: cuttlefish.usesPlasmaTheme - colorGroup: PlasmaCore.ColorScope.colorGroup - Layout.preferredWidth: indexToSize(1) - Layout.preferredHeight: indexToSize(1) - } - PlasmaCore.IconItem { - source: iconName - usesPlasmaTheme: cuttlefish.usesPlasmaTheme - colorGroup: PlasmaCore.ColorScope.colorGroup - Layout.preferredWidth: indexToSize(2) - Layout.preferredHeight: indexToSize(2) + Kirigami.FormLayout { + Layout.fillWidth: true + Layout.topMargin: Kirigami.Units.largeSpacing + QQC2.Label { + Layout.maximumWidth: Kirigami.Units.gridUnit * 15 + Kirigami.FormData.label: i18n("File name:") + elide: Text.ElideRight + text: preview.fileName } - PlasmaCore.IconItem { - source: iconName - usesPlasmaTheme: cuttlefish.usesPlasmaTheme - colorGroup: PlasmaCore.ColorScope.colorGroup - Layout.preferredWidth: indexToSize(3) - Layout.preferredHeight: indexToSize(3) + QQC2.Label { + Kirigami.FormData.label: i18n("Category:") + font.capitalization: Font.Capitalize + text: preview.category } - PlasmaCore.IconItem { - source: iconName - usesPlasmaTheme: cuttlefish.usesPlasmaTheme - colorGroup: PlasmaCore.ColorScope.colorGroup - Layout.preferredWidth: indexToSize(4) - Layout.preferredHeight: indexToSize(4) + QQC2.Label { + Kirigami.FormData.label: i18n("Scalable:") + text: preview.scalable ? i18n("yes") : i18n("no") + font.capitalization: Font.Capitalize } } + Rectangle { + id: iconPreview + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor - PlasmaCore.IconItem { - source: iconName - usesPlasmaTheme: cuttlefish.usesPlasmaTheme - colorGroup: PlasmaCore.ColorScope.colorGroup - Layout.fillHeight: false - Layout.preferredWidth: parent.width - Layout.preferredHeight: parent.width - } + property bool screenshotting: false - GridLayout { - columns: 2 + color: Kirigami.Theme.backgroundColor - PlasmaComponents.Label { - text: i18n("Name:") - } - PlasmaComponents.Label { - text: iconName - wrapMode: Text.Wrap - } - PlasmaComponents.Label { - text: i18n("Filename:") - } - PlasmaComponents.Label { - text: fileName - wrapMode: Text.Wrap - verticalAlignment: Text.AlignVCenter - } - PlasmaComponents.Label { - text: i18n("Category:") + Behavior on color { + ColorAnimation { + duration: Kirigami.Units.longDuration + } } - PlasmaComponents.Label { - text: category - wrapMode: Text.WordWrap + Behavior on Layout.preferredHeight { + NumberAnimation { + duration: Kirigami.Units.longDuration + } } - PlasmaComponents.Label { - text: i18n("Scalable:") - } - PlasmaComponents.Label { - text: scalable ? i18n("yes") : i18n("no") + + Layout.fillWidth: true + Layout.preferredHeight: screenshotting ? previewGrid.height + (Kirigami.Units.gridUnit * 4) : previewGrid.height + + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.bottomMargin: Kirigami.Units.largeSpacing * 4 + + ColumnLayout { + id: previewGrid + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + property var sizes: [8, 16, 22, 32, 48, 64] + property var largeSizes: [128] + GridLayout { + Layout.alignment: Qt.AlignHCenter + rows: 2 + columns: previewGrid.sizes.length + Repeater { + model: previewGrid.sizes.length + delegate: Kirigami.Icon { + Layout.alignment: Qt.AlignBottom + source: preview.iconName + width: previewGrid.sizes[index] + height: previewGrid.sizes[index] + } + } + Repeater { + model: previewGrid.sizes.length + delegate: QQC2.Label { + Layout.alignment: Qt.AlignTop | Qt.AlignHCenter + text: previewGrid.sizes[index] + Behavior on color { + ColorAnimation { + duration: Kirigami.Units.longDuration + } + } + } + } + } + GridLayout { + Layout.alignment: Qt.AlignHCenter + rows: 2 + columns: previewGrid.largeSizes.length + Repeater { + model: previewGrid.largeSizes.length + delegate: Kirigami.Icon { + Layout.alignment: Qt.AlignBottom + source: preview.iconName + width: previewGrid.largeSizes[index] + height: previewGrid.largeSizes[index] + } + } + Repeater { + model: previewGrid.largeSizes.length + delegate: QQC2.Label { + Layout.alignment: Qt.AlignTop | Qt.AlignHCenter + text: previewGrid.largeSizes[index] + Behavior on color { + ColorAnimation { + duration: Kirigami.Units.longDuration + } + } + } + } + } } - PlasmaComponents.Label { - text: i18n("Sizes:") + Row { + opacity: iconPreview.screenshotting ? 1 : 0 + anchors.top: parent.top + anchors.left: parent.left + anchors.margins: Kirigami.Units.smallSpacing + Kirigami.Icon { + height: 32 + width: 32 + source: "cuttlefish" + } + QQC2.Label { + anchors.verticalCenter: parent.verticalCenter + text: "Montage made with Cuttlefish" + } + Behavior on opacity { + OpacityAnimator { + duration: Kirigami.Units.longDuration + } + } } - PlasmaComponents.Label { - text: (sizes != undefined) ? sizes.join(", ") : "" + function shot(type) { + iconPreview.screenshotting = true + if (type == "normal") { + iconPreview.Kirigami.Theme.inherit = false + iconPreview.Kirigami.Theme.textColor = "#232629" + iconPreview.Kirigami.Theme.backgroundColor = "#eff0f1" + iconPreview.Kirigami.Theme.highlightColor = "#3daee9" + iconPreview.Kirigami.Theme.highlightedTextColor = "#eff0f1" + iconPreview.Kirigami.Theme.positiveTextColor = "#27ae60" + iconPreview.Kirigami.Theme.neutralTextColor = "#f67400" + iconPreview.Kirigami.Theme.negativeTextColor = "#da4453" + } else if (type == "dark") { + iconPreview.Kirigami.Theme.inherit = false + iconPreview.Kirigami.Theme.textColor = "#eff0f1" + iconPreview.Kirigami.Theme.backgroundColor = "#31363b" + iconPreview.Kirigami.Theme.highlightColor = "#3daee9" + iconPreview.Kirigami.Theme.highlightedTextColor = "#eff0f1" + iconPreview.Kirigami.Theme.positiveTextColor = "#27ae60" + iconPreview.Kirigami.Theme.neutralTextColor = "#f67400" + iconPreview.Kirigami.Theme.negativeTextColor = "#da4453" + } else if (type == "active") { + iconPreview.Kirigami.Theme.inherit = true + } + ssPicker.open() } } - Item { - Layout.fillHeight: true + QQC2.Button { + Layout.alignment: Qt.AlignHCenter + text: i18n("Open icon with external program") + icon.name: "document-open" + onClicked: Qt.openUrlExternally(preview.fullPath) } - PlasmaComponents.ToolButton { - text: pickerMode ? i18n("Insert icon name") : i18n("Copy icon name to clipboard") - iconSource: "edit-copy" - Layout.fillWidth: true - onClicked: clipboard(preview.iconName); + QQC2.Button { + Layout.alignment: Qt.AlignHCenter + text: i18n("Copy icon name to clipboard") + icon.name: "edit-copy" + onClicked: { + clipboard(preview.iconName) + cuttlefish.showPassiveNotification(i18n("Icon name copied to clipboard"), "short") + } } - PlasmaComponents.ToolButton { - text: pickerMode ? i18n("Insert QtQuick code") : i18n("Copy QtQuick code to clipboard") - iconSource: "edit-copy" - Layout.fillWidth: true + QQC2.Button { + Layout.alignment: Qt.AlignHCenter + visible: !iconPreview.screenshotting + icon.name: "camera-web-symbolic" + text: i18n("Create screenshot of icon") + onClicked: { - var code = "/* Don't forget to import...\n\ -import org.kde.plasma.core 2.0 as PlasmaCore\n\ -*/\n\ - PlasmaCore.IconItem {\n\ - source: \"" + preview.iconName + "\"\n\ - Layout.preferredWidth: units.iconSizes.medium\n\ - Layout.preferredHeight: units.iconSizes.medium\n\ - }\n\ -"; - clipboard(code); + screenshotActions.popup() + } + + QQC2.Menu { + id: screenshotActions + QQC2.MenuItem { + text: i18n("Screenshot with Breeze Colors") + onTriggered: { + iconPreview.shot("normal") + } + } + QQC2.MenuItem { + text: i18n("Screenshot with Breeze Dark Colors") + onTriggered: { + iconPreview.shot("dark") + } + } + QQC2.MenuItem { + text: i18n("Screenshot with Breeze (Normal) and Breeze Dark") + onTriggered: { + dualMont.shot() + } + } + QQC2.MenuItem { + text: i18n("Screenshot with Active Color Scheme") + onTriggered: { + iconPreview.shot("active") + } + } } } - PlasmaComponents.CheckBox { - text: i18n("Update preview on hover") - onCheckedChanged: hoveredHighlight = checked + Item { + Layout.fillHeight: true } + DualMontage { id: dualMont } } - Rectangle { - color: theme.highlightColor - width: Math.round(units.gridUnit / 20) + Kirigami.Separator { + width: 1 anchors { left: parent.left - top: parent.top bottom: parent.bottom + top: parent.top } } } diff --git a/cuttlefish/package/contents/ui/ResponsivePreview.qml b/cuttlefish/package/contents/ui/ResponsivePreview.qml new file mode 100644 index 0000000..540dbbd --- /dev/null +++ b/cuttlefish/package/contents/ui/ResponsivePreview.qml @@ -0,0 +1,149 @@ +/*************************************************************************** + * * + * Copyright 2019 Carson Black * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + * * + ***************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Controls 2.5 as QQC2 +import QtQuick.Layouts 1.0 + +import org.kde.kirigami 2.8 as Kirigami + +Kirigami.GlobalDrawer { + id: root + edge: Qt.RightEdge + + handleOpenIcon.source: "dialog-close" + handleClosedIcon.source: "view-preview" + + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor + + focus: false + + function clipboard(text) { + if (!pickerMode) { + clipboardHelper.text = text; + clipboardHelper.selectAll(); + clipboardHelper.copy(); + } else { + iconModel.output(text); + } + } + + TextEdit { + id: clipboardHelper + visible: false + } + + actions: [ + Kirigami.Action { + text: i18n("Open icon with external program") + iconName: "document-open" + onTriggered: Qt.openUrlExternally(preview.fullPath) + }, + Kirigami.Action { + text: i18n("Copy icon name to clipboard") + iconName: "edit-copy" + onTriggered: { + root.clipboard(preview.iconName) + cuttlefish.showPassiveNotification(i18n("Icon name copied to clipboard"), "short") + } + }, + Kirigami.Action { + iconName: "camera-web-symbolic" + text: i18n("Create screenshot of icon with...") + Kirigami.Action { + text: i18n("Breeze Colors") + onTriggered: iconPreview.shot("normal") + } + Kirigami.Action { + text: i18n("Breeze Dark Colors") + onTriggered: iconPreview.shot("dark") + } + Kirigami.Action { + onTriggered: dualMont.shot() + text: i18n("Breeze (Normal) and Breeze Dark") + } + Kirigami.Action { + onTriggered: iconPreview.shot("active") + text: i18n("Active Color Scheme") + } + } + ] + Kirigami.Heading { + level: 1 + Layout.fillWidth: true + wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + text: preview.iconName + } + Kirigami.FormLayout { + Layout.fillWidth: true + Layout.topMargin: Kirigami.Units.largeSpacing + QQC2.Label { + Layout.maximumWidth: Kirigami.Units.gridUnit * 10 + Kirigami.FormData.label: i18n("File name:") + elide: Text.ElideRight + text: preview.fileName + } + QQC2.Label { + Kirigami.FormData.label: i18n("Category:") + font.capitalization: Font.Capitalize + text: preview.category + } + QQC2.Label { + Kirigami.FormData.label: i18n("Scalable:") + text: preview.scalable ? i18n("yes") : i18n("no") + font.capitalization: Font.Capitalize + } + } + GridLayout { + id: grid + columns: 2 + property var sizes: [8, 16, 22, 32, 48, 64] + Layout.alignment: Qt.AlignHCenter + Repeater { + model: parent.sizes.length + delegate: ColumnLayout { + Kirigami.Icon { + Layout.alignment: Qt.AlignBottom + source: preview.iconName + width: grid.sizes[index] + height: grid.sizes[index] + } + QQC2.Label { + Layout.alignment: Qt.AlignTop | Qt.AlignHCenter + text: grid.sizes[index] + Behavior on color { + ColorAnimation { + duration: Kirigami.Units.longDuration + } + } + } + } + } + } +} \ No newline at end of file diff --git a/cuttlefish/package/contents/ui/SvgGrid.qml b/cuttlefish/package/contents/ui/SvgGrid.qml index 694ed5a..8dfae62 100644 --- a/cuttlefish/package/contents/ui/SvgGrid.qml +++ b/cuttlefish/package/contents/ui/SvgGrid.qml @@ -1,128 +1,135 @@ /*************************************************************************** * * * Copyright 2014-2015 Sebastian Kügler * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ import QtQuick 2.2 -// import QtQuick.Controls 1.0 +import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras - +import org.kde.kirigami 2.8 as Kirigami GridView { id: iconGrid focus: true cellWidth: iconSize + units.gridUnit cellHeight: cellWidth + units.gridUnit cacheBuffer: 10000 highlightMoveDuration: 0 model: iconModel.svgIcons highlight: Rectangle { color: theme.highlightColor //height: parent.height + units.gridUnit * 3 anchors.bottomMargin: -units.gridUnit * 2 } delegate: MouseArea { id: delegateRoot width: iconSize height: iconSize + units.gridUnit hoverEnabled: hoveredHighlight function setAsPreview() { print("preview() " + modelData.iconName + " " + modelData.fileName); -// preview.fullPath = fullPath preview.iconName = modelData.iconName } Rectangle { + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor color: theme.highlightColor - //height: parent.height + units.gridUnit * 3 opacity: iconGrid.currentIndex == index ? 1.0 : 0 Behavior on opacity { NumberAnimation { duration: units.shortDuration } } anchors { bottomMargin: -units.gridUnit leftMargin: -units.gridUnit / 2 rightMargin: -units.gridUnit / 2 fill: parent } } - PlasmaCore.IconItem { + Kirigami.Icon { + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor id: delegateIcon width: iconSize height: width source: modelData.iconName anchors { top: parent.top horizontalCenter: parent.horizontalCenter } } - PlasmaComponents.Label { + QQC2.Label { + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor font.pointSize: iconSize > 96 ? theme.defaultFont.pointSize : theme.smallestFont.pointSize text: modelData.fileName + " " + modelData.iconName - wrapMode: Text.Wrap -// elide: Text.ElideRight + wrapMode: QQC2.Text.Wrap maximumLineCount: 3 - horizontalAlignment: Text.AlignHCenter + horizontalAlignment: QQC2.Text.AlignHCenter opacity: iconGrid.currentIndex == index ? 1.0 : 0.7 anchors { left: parent.left right: parent.right top: delegateIcon.bottom - //topMargin: Math.round(-units.gridUnit / 4) margins: Math.round(-units.gridUnit / 4) - //horizontalCenter: parent.horizontalCenter - //bottom: parent.bottom } } Connections { target: iconGrid onCurrentIndexChanged: { if (delegateRoot.GridView.isCurrentItem) { print("index changed" + modelData.iconName + " " + modelData.fileName) - //preview.fullPath = fullPath delegateRoot.setAsPreview(); } } } onClicked: { iconGrid.currentIndex = index; iconGrid.forceActiveFocus(); } onEntered: { setAsPreview(); } - Component.onCompleted: { -// print("ModelData.fileName:" + modelData.fileName) -// print("ModelData.iconName:" + modelData.iconName) - } } } diff --git a/cuttlefish/package/contents/ui/Tools.qml b/cuttlefish/package/contents/ui/Tools.qml index f97a3f1..8142ff2 100644 --- a/cuttlefish/package/contents/ui/Tools.qml +++ b/cuttlefish/package/contents/ui/Tools.qml @@ -1,138 +1,147 @@ /*************************************************************************** * * * Copyright 2014-2017 Sebastian Kügler * + * Copyrihgt 2019 Carson Black * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ -import QtQuick 2.2 -import QtQuick.Controls 2.0 +import QtQuick 2.5 +import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents - -PlasmaComponents.ToolBar { - - Rectangle { - color: theme.backgroundColor - height: units.gridUnit / 20 - width: preview.width - anchors { - right: parent.right - top: parent.bottom - } - } - tools: RowLayout { - - spacing: units.gridUnit / 2 - - PlasmaComponents.TextField { +import org.kde.kirigami 2.8 as Kirigami + +Rectangle { + id: root + width: parent.width + color: Kirigami.Theme.backgroundColor + signal colorschemeChanged(int index) + property alias slider: sizeslider + property alias currentIndex: colorcombo.currentIndex + + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor + + RowLayout { + anchors.fill: parent + anchors.leftMargin: Kirigami.Units.smallSpacing + anchors.rightMargin: Kirigami.Units.smallSpacing + anchors.verticalCenter: parent.verticalCenter + spacing: Kirigami.Units.largeSpacing + Kirigami.SearchField { id: filterInput Layout.fillWidth: true onTextChanged: typingtimer.restart() focus: true Timer { id: typingtimer running: false repeat: false interval: 100 onTriggered: { iconModel.filter = filterInput.text } } + Component.onCompleted: { + filterInput.forceActiveFocus() + } } - ComboBox { + QQC2.ComboBox { + id: catsCombo Layout.preferredWidth: units.gridUnit * 6 model: iconModel.categories onActivated: { if (currentText == "all") { iconModel.category = ""; } else if (currentText != "") { iconModel.category = currentText } + iconModel.sort() } + popup.modal: false } - Slider { + QQC2.Slider { + visible: cuttlefish.widescreen id: sizeslider Layout.preferredWidth: preview.width - units.gridUnit * 2 - to: 6.0 + to: 5.0 stepSize: 1.0 - snapMode: Slider.AlwaysSnap + snapMode: QQC2.Slider.SnapAlways value: 4.0 onValueChanged: { sizetimer.restart() pixelSizeInput.text = indexToSize(sizeslider.value) } Timer { id: sizetimer running: false repeat: false interval: 200 onTriggered: iconSize = indexToSize(sizeslider.value) } Component.onCompleted: { pixelSizeInput.text = indexToSize(sizeslider.value); } } - PlasmaComponents.TextField { + QQC2.Label { + visible: cuttlefish.widescreen id: pixelSizeInput Layout.preferredWidth: units.gridUnit * 3 - - onTextChanged: { - if (pixelSizeInput.activeFocus) { - pxSizetimer.restart() - } - } - - Timer { - id: pxSizetimer - running: false - repeat: false - interval: 100 - onTriggered: iconSize = pixelSizeInput.text - } } - - PlasmaComponents.CheckBox { - id: colorContextCheckbox - text: i18n("Inverted") - onCheckedChanged: darkScheme = checked + QQC2.Label { + visible: cuttlefish.widescreen + text: i18n("Color scheme:") } - - PlasmaComponents.CheckBox { - id: plasmaThemeCheckbox - text: i18n("Monochrome") - checked: true - onCheckedChanged: cuttlefish.usesPlasmaTheme = checked + QQC2.ComboBox { + id: colorcombo + visible: cuttlefish.widescreen + model: ["System Color Scheme", "Breeze (Normal)", "Breeze Dark"] + delegate: QQC2.ItemDelegate { + text: i18n(modelData) + width: parent.width + } + onActivated: (index) => { + root.colorschemeChanged(index) + } + popup.modal: false } - - Item { - Layout.preferredWidth: preview.width + } + Kirigami.Separator { + height: 1 + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom } } } diff --git a/cuttlefish/package/contents/ui/Tools.qml b/cuttlefish/package/contents/ui/ToolsResponsive.qml similarity index 50% copy from cuttlefish/package/contents/ui/Tools.qml copy to cuttlefish/package/contents/ui/ToolsResponsive.qml index f97a3f1..2837006 100644 --- a/cuttlefish/package/contents/ui/Tools.qml +++ b/cuttlefish/package/contents/ui/ToolsResponsive.qml @@ -1,138 +1,108 @@ /*************************************************************************** * * - * Copyright 2014-2017 Sebastian Kügler * + * Copyright 2019 Carson Black * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ -import QtQuick 2.2 -import QtQuick.Controls 2.0 +import QtQuick 2.5 +import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents - -PlasmaComponents.ToolBar { - - Rectangle { - color: theme.backgroundColor - height: units.gridUnit / 20 - width: preview.width +import org.kde.kirigami 2.8 as Kirigami + +Rectangle { + id: root + width: parent.width + color: Kirigami.Theme.backgroundColor + + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor + + property alias currentIndex: colorcombo.currentIndex + signal colorschemeChanged(int index) + Kirigami.Separator { + height: 1 anchors { + left: parent.left right: parent.right - top: parent.bottom + top: parent.top } } - tools: RowLayout { - - spacing: units.gridUnit / 2 - - PlasmaComponents.TextField { - id: filterInput - Layout.fillWidth: true - onTextChanged: typingtimer.restart() - focus: true - - Timer { - id: typingtimer - running: false - repeat: false - interval: 100 - onTriggered: { - iconModel.filter = filterInput.text - } - } - } - - ComboBox { - Layout.preferredWidth: units.gridUnit * 6 - model: iconModel.categories - onActivated: { - if (currentText == "all") { - iconModel.category = ""; - } else if (currentText != "") { - iconModel.category = currentText - } - } - } - - Slider { + RowLayout { + anchors.fill: parent + anchors.leftMargin: Kirigami.Units.smallSpacing + anchors.rightMargin: Kirigami.Units.smallSpacing + anchors.verticalCenter: parent.verticalCenter + spacing: Kirigami.Units.largeSpacing + QQC2.Slider { + visible: !cuttlefish.widescreen id: sizeslider - Layout.preferredWidth: preview.width - units.gridUnit * 2 + Layout.fillWidth: true - to: 6.0 + to: 5.0 stepSize: 1.0 - snapMode: Slider.AlwaysSnap + snapMode: QQC2.Slider.SnapAlways value: 4.0 onValueChanged: { sizetimer.restart() pixelSizeInput.text = indexToSize(sizeslider.value) } Timer { id: sizetimer running: false repeat: false interval: 200 onTriggered: iconSize = indexToSize(sizeslider.value) } Component.onCompleted: { pixelSizeInput.text = indexToSize(sizeslider.value); } } - PlasmaComponents.TextField { + QQC2.Label { + visible: !cuttlefish.widescreen id: pixelSizeInput - Layout.preferredWidth: units.gridUnit * 3 - - onTextChanged: { - if (pixelSizeInput.activeFocus) { - pxSizetimer.restart() - } + Layout.preferredWidth: units.gridUnit * 1 + } + QQC2.ComboBox { + id: colorcombo + visible: !cuttlefish.widescreen + model: ["System Color Scheme", "Breeze (Normal)", "Breeze Dark"] + delegate: QQC2.ItemDelegate { + text: i18n(modelData) + width: parent.width } - - Timer { - id: pxSizetimer - running: false - repeat: false - interval: 100 - onTriggered: iconSize = pixelSizeInput.text + onActivated: (index) => { + root.colorschemeChanged(index) } + popup.modal: false } - - PlasmaComponents.CheckBox { - id: colorContextCheckbox - text: i18n("Inverted") - onCheckedChanged: darkScheme = checked - } - - PlasmaComponents.CheckBox { - id: plasmaThemeCheckbox - text: i18n("Monochrome") - checked: true - onCheckedChanged: cuttlefish.usesPlasmaTheme = checked - } - Item { - Layout.preferredWidth: preview.width + width: Kirigami.Units.largeSpacing * 3 } } -} - +} \ No newline at end of file diff --git a/cuttlefish/package/contents/ui/cuttlefish.qml b/cuttlefish/package/contents/ui/cuttlefish.qml index 0a7e2ab..cce7d9b 100644 --- a/cuttlefish/package/contents/ui/cuttlefish.qml +++ b/cuttlefish/package/contents/ui/cuttlefish.qml @@ -1,100 +1,246 @@ /*************************************************************************** * * * Copyright 2014-2015 Sebastian Kügler * + * Copyrihgt 2019 Carson Black * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ import QtQuick 2.5 import QtQuick.Layouts 1.0 +import QtQuick.Controls 2.5 as QQC2 +import Qt.labs.settings 1.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras +import org.kde.kirigami 2.4 as Kirigami - -Item { +Kirigami.ApplicationWindow { id: cuttlefish objectName: "cuttlefish" - width: units.gridUnit * 60 - height: Math.round(width / 3 * 2) + signal itemRightClicked() + + minimumWidth: 400 + minimumHeight: 400 - property int iconSize: units.iconSizes.large - property bool hoveredHighlight: false + property bool widescreen: cuttlefish.width >= 800 + + property int iconSize: Kirigami.Units.iconSizes.large property bool darkScheme: false property bool usesPlasmaTheme: true + property var schemeStash + + property color textcolor: Kirigami.Theme.textColor + property color bgcolor: Kirigami.Theme.backgroundColor + property color highlightcolor: Kirigami.Theme.highlightColor + property color highlightedtextcolor: Kirigami.Theme.highlightedTextColor + property color positivetextcolor: Kirigami.Theme.positiveTextColor + property color neutraltextcolor: Kirigami.Theme.neutralTextColor + property color negativetextcolor: Kirigami.Theme.negativeTextColor + property color viewbgcolor: Kirigami.Theme.viewBackgroundColor + + Kirigami.Theme.textColor: cuttlefish.textcolor + Kirigami.Theme.backgroundColor: cuttlefish.bgcolor + Kirigami.Theme.highlightColor: cuttlefish.highlightcolor + Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor + Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor + Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor + Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor + + Loader { + // Use a Loader instead of creating a GMB directly, + // so if the GMB errors, it doesn't affect Cuttlefish's operation + id: loader + source: "GlobalMenuBar.qml" + } + Loader { + // Ditto for the right click context menu. + source: "Menu.qml" + } + Settings { + property alias x: cuttlefish.x + property alias y: cuttlefish.y + property alias width: cuttlefish.width + property alias height: cuttlefish.height + } + Connections { + target: loader.item + onQuit: { cuttlefish.close() } + onZoomIn: { tools.slider.value += 1 } + onZoomOut: { tools.slider.value -= 1 } + onMontage: { + switch(type) { + case 0: + previewPane.iconPreview.shot("active") + break; + case 1: + previewPane.iconPreview.shot("normal") + break; + case 2: + previewPane.iconPreview.shot("dark") + break; + case 3: + previewPane.dualMont.shot() + break; + } + } + } + function changeColors(index) { + switch(index) { + case 0: + cuttlefish.Kirigami.Theme.inherit = true + cuttlefish.textcolor = cuttlefish.schemeStash[0] + cuttlefish.bgcolor = cuttlefish.schemeStash[1] + cuttlefish.highlightcolor = cuttlefish.schemeStash[2] + cuttlefish.highlightedtextcolor = cuttlefish.schemeStash[3] + cuttlefish.positivetextcolor = cuttlefish.schemeStash[4] + cuttlefish.neutraltextcolor = cuttlefish.schemeStash[5] + cuttlefish.negativetextcolor = cuttlefish.schemeStash[6] + cuttlefish.viewbgcolor = cuttlefish.schemeStash[7] + break + case 1: + cuttlefish.Kirigami.Theme.inherit = false + cuttlefish.textcolor = "#232629" + cuttlefish.bgcolor = "#eff0f1" + cuttlefish.highlightcolor = "#3daee9" + cuttlefish.highlightedtextcolor = "#eff0f1" + cuttlefish.positivetextcolor = "#27ae60" + cuttlefish.neutraltextcolor = "#f67400" + cuttlefish.negativetextcolor = "#da4453" + cuttlefish.viewbgcolor = "#fcfcfc" + break + case 2: + cuttlefish.Kirigami.Theme.inherit = false + cuttlefish.textcolor = "#eff0f1" + cuttlefish.bgcolor = "#31363b" + cuttlefish.highlightcolor = "#3daee9" + cuttlefish.highlightedtextcolor = "#eff0f1" + cuttlefish.positivetextcolor = "#27ae60" + cuttlefish.neutraltextcolor = "#f67400" + cuttlefish.negativetextcolor = "#da4453" + cuttlefish.viewbgcolor = "#232629" + break + } + } function indexToSize(ix) { var sizes = new Array(); - sizes[0] = units.iconSizes.tiny; - sizes[1] = units.iconSizes.small; - sizes[2] = units.iconSizes.smallMedium; - sizes[3] = units.iconSizes.medium; - sizes[4] = units.iconSizes.large; - sizes[5] = units.iconSizes.huge; - sizes[6] = units.iconSizes.enormous; + sizes[0] = 8; + sizes[1] = 16; + sizes[2] = 22; + sizes[3] = 32; + sizes[4] = 64; + sizes[5] = 128; return sizes[ix]; } - - PlasmaCore.ColorScope { + Rectangle { + Kirigami.Theme.colorSet: Kirigami.Theme.View + color: tools.currentIndex != 0 ? cuttlefish.viewbgcolor : Kirigami.Theme.viewBackgroundColor anchors.fill: parent - colorGroup: darkScheme ? PlasmaCore.Theme.ComplementaryColorGroup : PlasmaCore.Theme.NormalColorGroup - Rectangle { - color: PlasmaCore.ColorScope.backgroundColor - anchors.fill: parent + } + ColumnLayout { + Shortcut { + sequence: StandardKey.ZoomIn + onActivated: tools.slider.value += 1 } + Shortcut { + sequence: StandardKey.ZoomOut + onActivated: tools.slider.value -= 1 + } + anchors.fill: parent + spacing: 0 - GridLayout { - columns: 2 - anchors.fill: parent - rowSpacing: - Math.round(units.gridUnit / 20) - - Tools { - Layout.columnSpan: 2 - Layout.fillWidth: true - Layout.preferredHeight: units.gridUnit * 2 - } + Tools { + id: tools + Layout.fillWidth: true + Layout.preferredHeight: (Kirigami.Units.gridUnit * 2) + Kirigami.Units.largeSpacing + } - PlasmaExtras.ScrollArea { + RowLayout { + QQC2.ScrollView { + id: grid Layout.fillWidth: true Layout.fillHeight: true + QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff IconGrid { id: iconGrid anchors.fill: parent + anchors.margins: Kirigami.Units.gridUnit footer: SvgGrid { id: svgGrid interactive: false } } } Preview { - id: preview - Layout.preferredWidth: Math.max(parent.width / 4, units.gridUnit * 12) + visible: cuttlefish.widescreen + id: previewPane + Layout.preferredWidth: Kirigami.Units.gridUnit * 22 Layout.fillHeight: true } } + ToolsResponsive { + visible: !cuttlefish.widescreen + id: toolsResponsive + Layout.fillWidth: true + Layout.preferredHeight: (Kirigami.Units.gridUnit * 2) + Kirigami.Units.largeSpacing + } + } + Loader { + active: !cuttlefish.widescreen + source: "ResponsivePreview.qml" + } + Connections { + target: tools + onColorschemeChanged: (index) => { + cuttlefish.changeColors(index) + toolsResponsive.currentIndex = index + } + } + Connections { + target: toolsResponsive + onColorschemeChanged: (index) => { + cuttlefish.changeColors(index) + tools.currentIndex = index + } + } + Item { + id: preview + property string iconName: "plasma" + property string fullPath: "" + property string category: "" + property string fileName: "" + property string type: "" + property string iconTheme: "" + property variant sizes: [] + property bool scalable: true } - Shortcut { - sequence: StandardKey.Quit - onActivated: Qt.quit() + Component.onCompleted: { + cuttlefish.schemeStash += Kirigami.Theme.textColor + cuttlefish.schemeStash += Kirigami.Theme.backgroundColor + cuttlefish.schemeStash += Kirigami.Theme.highlightColor + cuttlefish.schemeStash += Kirigami.Theme.highlightedTextColor + cuttlefish.schemeStash += Kirigami.Theme.positiveTextColor + cuttlefish.schemeStash += Kirigami.Theme.neutralTextColor + cuttlefish.schemeStash += Kirigami.Theme.negativeTextColor + cuttlefish.schemeStash += Kirigami.Theme.viewBackgroundColor + console.log(cuttlefish.schemeStash) } } diff --git a/cuttlefish/src/CMakeLists.txt b/cuttlefish/src/CMakeLists.txt index e922e14..00d75eb 100644 --- a/cuttlefish/src/CMakeLists.txt +++ b/cuttlefish/src/CMakeLists.txt @@ -1,26 +1,25 @@ set(cuttlefish_SRCS main.cpp - view.cpp iconmodel.cpp ) add_executable(cuttlefish ${cuttlefish_SRCS}) target_compile_definitions(cuttlefish PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}") target_link_libraries(cuttlefish Qt5::Quick Qt5::Gui Qt5::Widgets # for QDirModel KF5::Plasma KF5::KIOWidgets KF5::Declarative KF5::I18n KF5::IconThemes KF5::Package Qt5::DBus ) install(TARGETS cuttlefish ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) add_subdirectory(editorplugin) diff --git a/cuttlefish/src/iconmodel.cpp b/cuttlefish/src/iconmodel.cpp index 42d4692..f40b60c 100644 --- a/cuttlefish/src/iconmodel.cpp +++ b/cuttlefish/src/iconmodel.cpp @@ -1,480 +1,411 @@ /*************************************************************************** * * * Copyright 2014-2015 Sebastian Kügler * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ #include "iconmodel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include +#include #include using namespace CuttleFish; static QTextStream cout(stdout); IconModel::IconModel(QObject *parent) : QAbstractListModel(parent), m_theme(QStringLiteral("breeze")) , m_loading(false) { m_roleNames.insert(FileName, "fileName"); m_roleNames.insert(IconName, "iconName"); m_roleNames.insert(Icon, "icon"); m_roleNames.insert(FullPath, "fullPath"); m_roleNames.insert(Category, "category"); m_roleNames.insert(Scalable, "scalable"); m_roleNames.insert(Sizes, "sizes"); m_roleNames.insert(Theme, "iconTheme"); m_roleNames.insert(Type, "type"); connect(this, &IconModel::categoryChanged, this, &IconModel::load); KConfigGroup cg(KSharedConfig::openConfig("cuttlefishrc"), "CuttleFish"); const QString themeName = cg.readEntry("theme", "default"); Plasma::Theme theme; // qDebug() << "Setting Plasma theme" << themeName; theme.setUseGlobalSettings(false); theme.setThemeName(themeName); // needs to happen after setUseGlobalSettings, since that clears themeName QList themepackages = KPackage::PackageLoader::self()->listPackages(QString(), "plasma/desktoptheme"); foreach (const KPluginMetaData &pkg, themepackages) { m_plasmathemes << pkg.pluginId(); } - m_svgIcons[QStringLiteral("amarok")] = QStringList() << "amarok"; - m_svgIcons[QStringLiteral("audio")] = QStringList() << "audio-volume-muted" - << "audio-volume-low" - << "audio-volume-medium" - << "audio-volume-high" ; - - m_svgIcons[QStringLiteral("battery")] = QStringList() << "Battery" - << "Acadapter" - << "Unavailable" - << "Fill10" - << "Fill20" - << "Fill30" - << "Fill40" - << "Fill50" - << "Fill60" - << "Fill70" - << "Fill80" - << "Fill90" - << "Fill100"; - m_svgIcons[QStringLiteral("device")] = QStringList() << "device-notfier"; - m_svgIcons[QStringLiteral("juk")] = QStringList() << "juk"; - m_svgIcons[QStringLiteral("kget")] = QStringList() << "kget"; - m_svgIcons[QStringLiteral("klippper")] = QStringList() << "klippper"; - m_svgIcons[QStringLiteral("konversation")] = QStringList() << "konversation"; - m_svgIcons[QStringLiteral("kopete")] = QStringList() << "konversation" - << "kopete-offline"; - m_svgIcons[QStringLiteral("korgac")] = QStringList() << "korgac"; - m_svgIcons[QStringLiteral("ktorrent")] = QStringList() << "ktorrent"; - m_svgIcons[QStringLiteral("kget")] = QStringList() << "kget"; - - m_svgIcons[QStringLiteral("battery")] = QStringList() << "Battery" - << "Acadapter" - << "Unavailable" - << "Fill10" - << "Fill20" - << "Fill30" - << "Fill40" - << "Fill50" - << "Fill60" - << "Fill70" - << "Fill80" - << "Fill90" - << "Fill100"; - m_svgIcons[QStringLiteral("message-indicator")] = QStringList() << "normal" - << "new"; - - m_svgIcons[QStringLiteral("nepomuk")] = QStringList() << "nepomuk"; - m_svgIcons[QStringLiteral("network")] = QStringList() << "network-wired-activated" - << "network-wired" - << "network-wireless-available" - << "network-wireless-disconnected" - << "flightmode-off" - << "flightmode-on" - << "network-wireless-0" - << "network-wireless-20" - << "network-wireless-25" - << "network-wireless-40" - << "network-wireless-50" - << "network-wireless-60" - << "network-wireless-75" - << "network-wireless-80" - << "network-wireless-100" - << "network-mobile-20" - << "network-mobile-40" - << "network-mobile-60" - << "network-mobile-80" - << "network-mobile-100"; - m_svgIcons[QStringLiteral("preferences")] = QStringList() << "preferences-system-bluetooth" - << "preferences-system-bluetooth-inactive" - << "preferences-desktop-texttospeach" - << "preferences-desktop-display-randr" - << "preferences-activities"; - m_svgIcons[QStringLiteral("printer")] = QStringList() << "printer"; - m_svgIcons[QStringLiteral("quassel")] = QStringList() << "quassel" - << "quassel_inactive" - << "quassel_message"; - m_svgIcons[QStringLiteral("wallet")] = QStringList() << "wallet" - << "wallet-open" - << "wallet-closed"; - m_categories = QStringList() << "all" \ << "actions" << "animations" << "apps" << "categories" << "devices" << "emblems" << "emotes" << "filesystems" << "international" << "mimetypes" << "places" << "status"; load(); } QHash IconModel::roleNames() const { return m_roleNames; } int IconModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) if (m_data.size() <= 0) { return 0; } else { return m_data.size(); } } QVariant IconModel::data(const QModelIndex &index, int role) const { if (index.isValid()) { QString icon = m_icons.at(index.row()); switch (role) { case IconName: return icon; } return m_data[icon][key(role)]; } return QVariant(); } QString IconModel::key(int role) const { return QString::fromLocal8Bit(m_roleNames[role]); } void IconModel::add(const QFileInfo &info, const QString &cat) { QStringList cats; Q_FOREACH (auto c, m_categories) { cats << c.toLower(); } if (!cats.contains(cat)) { m_categories << cat; emit categoriesChanged(); } const QString fname = info.fileName(); bool scalable = false; QString icon = fname; if (fname.endsWith(".png")) { icon.remove(".png"); } else if (fname.endsWith(".svgz")) { icon.remove(".svgz"); scalable = true; } else if (fname.endsWith(".svg")) { icon.remove(".svg"); scalable = true; } QVariantMap &data = m_data[icon]; if (!m_icons.contains(icon)) { data["fullPath"] = info.absoluteFilePath(); data["iconName"] = icon; data["fileName"] = info.fileName(); data["category"] = cat; data["type"] = QStringLiteral("icon"); data["scalable"] = scalable; data["iconTheme"] = QStringLiteral("breeze"); m_icons << icon; } if (scalable && !data["scalable"].toBool()) { data["scalable"] = true; } QStringList _s = info.path().split('/'); if (_s.count() > 2) { QString size = _s[_s.count()-2]; // last but one is size, last is category if (size.indexOf("x") > 1) { size = size.split("x")[0]; QStringList sizes = data["sizes"].toStringList(); if (!sizes.contains(size)) { //qDebug() << "Size added" << sizes << size << data["iconName"]; sizes << size; data["sizes"] = sizes; } } } } QString IconModel::category() const { return m_category; } QStringList IconModel::categories() const { return m_categories; } void IconModel::setCategory(const QString& cat) { if (cat != m_category) { m_category = cat; emit categoryChanged(); } } QString IconModel::filter() const { return m_filter; } void IconModel::setFilter(const QString &filter) { //qDebug() << "Filter: " << filter; if (m_filter != filter) { m_filter = filter; load(); emit filterChanged(); emit svgIconsChanged(); } } void IconModel::load() { //qDebug() << "\n -- Loading (category / filter) : " << m_category << m_filter; m_loading = true; emit loadingChanged(); QElapsedTimer tt; tt.start(); const QDirIterator::IteratorFlags flags = QDirIterator::Subdirectories; const QStringList nameFilters = QStringList(); beginResetModel(); m_data.clear(); m_icons.clear(); //sm_categories.clear(); QString iconTheme; if (KIconLoader::global()) { iconTheme = KIconLoader::global()->theme()->internalName(); } else { return; } QStringList searchPaths; QStringList iconThemePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("icons/") + iconTheme, QStandardPaths::LocateDirectory); if (iconThemePaths.count() > 0) { searchPaths << iconThemePaths; } QStringList hicolorThemePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("icons/hicolor"), QStandardPaths::LocateDirectory); if (hicolorThemePaths.count() > 0) { searchPaths << hicolorThemePaths; } foreach (const QString &iconPath, searchPaths) { QDirIterator cats(iconPath, nameFilters, QDir::Dirs, QDirIterator::NoIteratorFlags); while (cats.hasNext()) { cats.next(); const QString fpath = cats.filePath(); const QString category = cats.fileName(); if (category != "." && category != "..") { QDirIterator it(fpath, nameFilters, QDir::Files, flags); while (it.hasNext()) { it.next(); const QFileInfo &info = it.fileInfo(); if (matchIcons(info)) { add(info, categoryFromPath(info.absoluteFilePath())); } } } } } svgIcons(); + + sort(); + endResetModel(); - //qDebug() << "Loading took" << tt.elapsed() << " msec"; + m_loading = false; emit loadingChanged(); } +void IconModel::sort() +{ + std::sort(m_icons.begin(), m_icons.end()); +} + bool IconModel::matchIcons(const QFileInfo& info) { bool ok = false; // Category is empty or all? Skip further matching. bool catmatch = m_category.isEmpty() || m_category == QStringLiteral("all"); // category match? if (!catmatch && m_category == categoryFromPath(info.absoluteFilePath())) { catmatch = true; } // name filter if (m_filter.isEmpty() || info.fileName().indexOf(m_filter) != -1) { if (catmatch) { ok = true; } } return ok; } QStringList IconModel::themes() const { return m_themes; } QString IconModel::theme() const { return m_theme; } void IconModel::setTheme(const QString& theme) { if (theme != m_theme) { m_theme = theme; load(); emit themeChanged(); } } QString IconModel::plasmaTheme() const { return m_plasmatheme; } void IconModel::setPlasmaTheme(const QString& ptheme) { if (m_plasmatheme != ptheme) { m_plasmatheme = ptheme; Plasma::Theme theme; theme.setThemeName(ptheme); load(); emit plasmaThemeChanged(); } } QStringList IconModel::plasmathemes() const { return m_plasmathemes; } void IconModel::svgIcons() { QVariantList out; foreach (const QString &file, m_svgIcons.keys()) { foreach (const QString &icon, m_svgIcons[file].toStringList()) { if (m_filter.isEmpty() || (file.indexOf(m_filter) != -1 || icon.indexOf(m_filter) != -1)) { QVariantMap &data = m_data[icon]; if (!m_icons.contains(icon)) { data["fullPath"] = ""; data["iconName"] = icon; data["fileName"] = file; data["category"] = "system"; data["type"] = QStringLiteral("svg"); data["scalable"] = true; data["iconTheme"] = m_plasmatheme; m_icons << icon; } QVariantMap vm; vm["fileName"] = file; vm["iconName"] = icon; out << vm; } } } + sort(); } QString IconModel::categoryFromPath(const QString& path) { QStringList cats; Q_FOREACH (auto c, m_categories) { cats << c.toLower(); } //cats << "actions" << "apps" << "places" << "status"; const QStringList _p1 = path.split("/icons/"); if (_p1.count() > 1) { foreach (const QString &cat, cats) { if (_p1[1].indexOf(cat) != -1) { return cat; } } } return QString(); } bool IconModel::loading() { return m_loading; } void IconModel::output(const QString& text) { cout << text.toLocal8Bit(); cout.flush(); } diff --git a/cuttlefish/src/iconmodel.h b/cuttlefish/src/iconmodel.h index 910a7ac..b1a7734 100644 --- a/cuttlefish/src/iconmodel.h +++ b/cuttlefish/src/iconmodel.h @@ -1,128 +1,129 @@ /*************************************************************************** * * * Copyright 2014-2015 Sebastian Kügler * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ #ifndef CUTTLEFISHICONMODEL_H #define CUTTLEFISHICONMODEL_H #include #include #include #include #include namespace CuttleFish { class IconModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged) Q_PROPERTY(QString category READ category WRITE setCategory NOTIFY categoryChanged) Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(QStringList themes READ themes CONSTANT) Q_PROPERTY(QStringList plasmathemes READ plasmathemes CONSTANT) Q_PROPERTY(QStringList categories READ categories NOTIFY categoriesChanged) Q_PROPERTY(QString plasmaTheme READ plasmaTheme WRITE setPlasmaTheme NOTIFY plasmaThemeChanged) Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged); public: enum Roles { FileName = Qt::UserRole + 1, IconName, Icon, FullPath, Category, Scalable, Sizes, Type, Theme }; explicit IconModel(QObject *parent = nullptr); QHash roleNames() const override; int rowCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; QString key(int role) const; bool matchIcons(const QFileInfo &info); void add(const QFileInfo &info, const QString &cat); void addSvgIcon(const QString &file, const QString &icon); void remove(const QString &iconFile); void setCategory(const QString &cat); QString category() const; void setFilter(const QString &filter); QString filter() const; void setTheme(const QString &theme); QString theme() const; QStringList themes() const; void setPlasmaTheme(const QString &ptheme); QString plasmaTheme() const; QStringList plasmathemes() const; QStringList categories() const; bool loading(); void svgIcons(); void load(); Q_INVOKABLE void output(const QString &text); + Q_INVOKABLE void sort(); Q_SIGNALS: void filterChanged(); void categoryChanged(); void categoriesChanged(); void themeChanged(); void svgIconsChanged(); void plasmaThemeChanged(); void loadingChanged(); private: QHash m_roleNames; QStringList m_icons; QString m_category; QStringList m_categories; QString m_theme; QString m_filter; QStringList m_themes; QStringList m_plasmathemes; QString m_plasmatheme; QHash m_data; QHash m_categoryTranslations; QVariantMap m_svgIcons; bool m_loading; QString categoryFromPath(const QString &path); }; } // namespace #endif // CUTTLEFISHICONMODEL_H diff --git a/cuttlefish/src/main.cpp b/cuttlefish/src/main.cpp index 970b9ee..7dd4617 100644 --- a/cuttlefish/src/main.cpp +++ b/cuttlefish/src/main.cpp @@ -1,76 +1,131 @@ /*************************************************************************** * * * Copyright 2014 Sebastian Kügler * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ // Qt #include #include #include #include #include +#include +#include // Frameworks #include +#include #include +#include #include // Own -#include "view.h" +#include "iconmodel.h" + +void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + if ((msg.contains("qt.svg") && msg.contains("Could not resolve property: #linearGradient")) || msg.contains("Could not resolve property: #pattern")) { + return; + } + + QByteArray localMsg = msg.toLocal8Bit(); + const char *file = context.file ? context.file : ""; + const char *function = context.function ? context.function : ""; + switch (type) { + case QtDebugMsg: + fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); + break; + case QtInfoMsg: + fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); + break; + case QtWarningMsg: + fprintf(stderr, "\u001b[33mWarning\u001b[0m: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); + break; + case QtCriticalMsg: + fprintf(stderr, "\u001b[33;1mCritical\u001b[0m: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); + break; + case QtFatalMsg: + fprintf(stderr, "\u001b[31;1mFatal\u001b[0m: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); + break; + } +} int main(int argc, char **argv) { + qInstallMessageHandler(messageOutput); + QApplication app(argc, argv); KLocalizedString::setApplicationDomain("cuttlefish"); app.setApplicationVersion(PROJECT_VERSION); app.setDesktopFileName(QStringLiteral("org.kde.cuttlefish")); + app.setOrganizationName("KDE"); + app.setOrganizationDomain("org.kde"); + app.setApplicationName("Cuttlefish"); + const static auto _category = QStringLiteral("category"); QCommandLineOption category = QCommandLineOption(QStringList() << QStringLiteral("c") << _category, i18n("Start with category"), i18n("category")); const static auto _f = QStringLiteral("fullscreen"); QCommandLineOption fullscreen = QCommandLineOption(QStringList() << QStringLiteral("f") << _f, i18n("Start full-screen")); const static auto _p = QStringLiteral("picker"); QCommandLineOption picker = QCommandLineOption(QStringList() << QStringLiteral("p") << _p, i18n("Run in icon-picker mode")); QCommandLineParser parser; parser.addVersionOption(); parser.setApplicationDescription("Cuttlefish Icon Browser"); parser.addHelpOption(); parser.addOption(category); parser.addOption(fullscreen); parser.addOption(picker); parser.process(app); QString _cc = parser.value(category); - auto settingsapp = new CuttleFish::View(_cc, parser); - QObject::connect(settingsapp->engine(), &QQmlEngine::quit, &app, &QApplication::quit); + QQmlApplicationEngine engine; + + KDeclarative::KDeclarative kdeclarative; + kdeclarative.setDeclarativeEngine(qobject_cast(&engine)); + kdeclarative.setTranslationDomain(QStringLiteral("cuttlefish")); + kdeclarative.setupBindings(); + + auto package = KPackage::PackageLoader::self()->loadPackage("Plasma/Generic"); + package.setPath("org.kde.plasma.cuttlefish"); - if (parser.isSet(fullscreen)) { - settingsapp->setVisibility(QWindow::FullScreen); + if (!package.isValid() || !package.metadata().isValid()) { + qWarning() << "Could not load package org.kde.plasma.cuttlefish:" << package.path(); + return -1; } + engine.load(QUrl::fromLocalFile(package.filePath("mainscript"))); + if (engine.rootObjects().isEmpty()) + return -1; + + auto iconModel = new CuttleFish::IconModel(engine.rootContext()); + engine.rootContext()->setContextProperty("iconModel", iconModel); + engine.rootContext()->setContextProperty("pickerMode", parser.isSet("picker")); + qmlRegisterType(); + return app.exec(); } diff --git a/cuttlefish/src/view.cpp b/cuttlefish/src/view.cpp deleted file mode 100644 index b85aa75..0000000 --- a/cuttlefish/src/view.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************** - * * - * Copyright 2014 Sebastian Kügler * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * - ***************************************************************************/ - -#include "view.h" -#include "iconmodel.h" - -#include -#include -#include -#include - -#include - -#include -#include - -using namespace CuttleFish; - -View::View(const QString &category, QCommandLineParser &parser, QWindow *parent) - : QQuickView(parent), - m_browserRootItem(nullptr) -{ - setResizeMode(QQuickView::SizeRootObjectToView); - QQuickWindow::setDefaultAlphaBuffer(true); - - KDeclarative::KDeclarative kdeclarative; - kdeclarative.setDeclarativeEngine(engine()); - kdeclarative.setTranslationDomain(QStringLiteral("cuttlefish")); - kdeclarative.setupBindings(); - - auto iconModel = new IconModel(this); - rootContext()->setContextProperty("iconModel", iconModel); - rootContext()->setContextProperty("pickerMode", parser.isSet("picker")); - qmlRegisterType(); - - m_package = KPackage::PackageLoader::self()->loadPackage("Plasma/Generic"); - m_package.setPath("org.kde.plasma.cuttlefish"); - - if (!m_package.isValid() || !m_package.metadata().isValid()) { - qWarning() << "Could not load package org.kde.plasma.cuttlefish:" << m_package.path(); - return; - } - - setIcon(QIcon::fromTheme(m_package.metadata().iconName())); - setTitle(m_package.metadata().name()); - - const QString qmlFile = m_package.filePath("mainscript"); - setSource(QUrl::fromLocalFile(m_package.filePath("mainscript"))); - show(); - - //qDebug() << "m_dirModel" << m_dirModel.rowCount(dirModel::index(KDirModel::Name); - -} - -View::~View() -{ -}