Changeset View
Standalone View
cuttlefish/package/contents/ui/Preview.qml
Show All 14 Lines | |||||
15 | * You should have received a copy of the GNU General Public License * | 15 | * You should have received a copy of the GNU General Public License * | ||
16 | * along with this program; if not, write to the * | 16 | * along with this program; if not, write to the * | ||
17 | * Free Software Foundation, Inc., * | 17 | * Free Software Foundation, Inc., * | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * | 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * | ||
19 | * * | 19 | * * | ||
20 | ***************************************************************************/ | 20 | ***************************************************************************/ | ||
21 | 21 | | |||
22 | import QtQuick 2.2 | 22 | import QtQuick 2.2 | ||
23 | import QtQuick.Controls 1.0 | 23 | import QtQuick.Controls 2.5 as QQC2 | ||
24 | import QtQuick.Layouts 1.0 | 24 | import QtQuick.Layouts 1.0 | ||
25 | import QtQuick.Dialogs 1.3 | ||||
25 | 26 | | |||
26 | import org.kde.plasma.core 2.0 as PlasmaCore | 27 | import org.kde.kirigami 2.8 as Kirigami | ||
27 | import org.kde.plasma.components 2.0 as PlasmaComponents | | |||
28 | import org.kde.plasma.extras 2.0 as PlasmaExtras | | |||
29 | | ||||
30 | 28 | | |||
31 | Rectangle { | 29 | Rectangle { | ||
32 | 30 | | |||
33 | id: preview | 31 | color: Kirigami.Theme.backgroundColor | ||
34 | | ||||
35 | color: PlasmaCore.ColorScope.backgroundColor | | |||
36 | | ||||
37 | property string iconName: "plasma" | | |||
38 | property string fullPath: "" | | |||
39 | property string category: "" | | |||
40 | property string fileName: "" | | |||
41 | property string type: "" | | |||
42 | property string iconTheme: "" | | |||
43 | property variant sizes: [] | | |||
44 | property bool scalable: true | | |||
45 | 32 | | |||
46 | function clipboard(text) { | 33 | function clipboard(text) { | ||
47 | if (!pickerMode) { | 34 | if (!pickerMode) { | ||
48 | clipboardHelper.text = text; | 35 | clipboardHelper.text = text; | ||
49 | clipboardHelper.selectAll(); | 36 | clipboardHelper.selectAll(); | ||
50 | clipboardHelper.copy(); | 37 | clipboardHelper.copy(); | ||
51 | } else { | 38 | } else { | ||
52 | iconModel.output(text); | 39 | iconModel.output(text); | ||
53 | } | 40 | } | ||
54 | 41 | | |||
55 | } | 42 | } | ||
56 | TextEdit { | 43 | TextEdit { | ||
57 | id: clipboardHelper | 44 | id: clipboardHelper | ||
58 | visible: false | 45 | visible: false | ||
59 | } | 46 | } | ||
60 | 47 | | |||
48 | FileDialog { | ||||
ngraham: A GridLayout with one column is just a ColumnLayout; use that instead | |||||
GB_2: Maybe add `wrapMode: Text.Wrap`, so the heading can have multiple lines. | |||||
49 | id: ssPicker | ||||
50 | selectExisting: false | ||||
51 | selectMultiple: false | ||||
52 | selectFolder: false | ||||
53 | onAccepted: { | ||||
54 | iconPreview.grabToImage(function(result) { | ||||
55 | ssPicker.resetColors() | ||||
56 | res = result.saveToFile(ssPicker.fileUrl.toString().slice(7)) | ||||
57 | }); | ||||
58 | } | ||||
59 | onRejected: { | ||||
60 | ssPicker.resetColors() | ||||
61 | } | ||||
ngraham: Center this button horizontally | |||||
62 | function resetColors() { | ||||
63 | iconPreview.screenshotting = false | ||||
64 | iconPreview.Kirigami.Theme.textColor = Kirigami.Theme.textColor | ||||
65 | iconPreview.Kirigami.Theme.backgroundColor = Kirigami.Theme.backgroundColor | ||||
66 | iconPreview.Kirigami.Theme.highlightColor = Kirigami.Theme.highlightColor | ||||
67 | iconPreview.Kirigami.Theme.highlightedTextColor = Kirigami.Theme.highlightedTextColor | ||||
68 | iconPreview.Kirigami.Theme.positiveTextColor = Kirigami.Theme.positiveTextColor | ||||
69 | iconPreview.Kirigami.Theme.neutralTextColor = Kirigami.Theme.neutralTextColor | ||||
70 | iconPreview.Kirigami.Theme.negativeTextColor = Kirigami.Theme.negativeTextColor | ||||
71 | iconPreview.Kirigami.Theme.inherit = true | ||||
72 | } | ||||
73 | nameFilters: [ "PNG screenshot files (*.png)" ] | ||||
74 | } | ||||
61 | 75 | | |||
62 | ColumnLayout { | 76 | GridLayout { | ||
63 | anchors.margins: units.gridUnit | | |||
64 | anchors.rightMargin: units.gridUnit * 2 | | |||
65 | anchors.fill: parent | 77 | anchors.fill: parent | ||
66 | spacing: units.gridUnit / 2 | 78 | columns: 2 | ||
79 | Rectangle { | ||||
80 | id: iconPreview | ||||
67 | 81 | | |||
68 | Item { height: units.gridUnit / 2 } | 82 | property bool screenshotting: false | ||
69 | 83 | | |||
70 | PlasmaExtras.Heading { | 84 | color: Kirigami.Theme.backgroundColor | ||
71 | level: 3 | 85 | Layout.fillHeight: true | ||
72 | elide: Text.ElideRight | | |||
73 | Layout.fillWidth: true | 86 | Layout.fillWidth: true | ||
74 | Layout.fillHeight: false | 87 | GridLayout { | ||
75 | wrapMode: Text.Wrap | 88 | id: previewGrid | ||
76 | text: iconName | 89 | anchors.centerIn: parent | ||
77 | } | 90 | columns: sizes.length | ||
78 | RowLayout { | 91 | rows: 2 | ||
79 | Layout.fillWidth: false | 92 | property var sizes: [8, 16, 22, 32, 48, 64, 128] | ||
80 | Layout.fillHeight: false | 93 | Repeater { | ||
81 | Layout.preferredHeight: indexToSize(4) | 94 | model: previewGrid.sizes.length | ||
82 | anchors.horizontalCenter: parent.horizontalCenter | 95 | delegate: Kirigami.Icon { | ||
83 | 96 | Layout.alignment: Qt.AlignBottom | |||
84 | PlasmaCore.IconItem { | 97 | source: preview.iconName | ||
85 | source: iconName | 98 | width: previewGrid.sizes[index] | ||
86 | usesPlasmaTheme: cuttlefish.usesPlasmaTheme | 99 | height: previewGrid.sizes[index] | ||
87 | colorGroup: PlasmaCore.ColorScope.colorGroup | 100 | } | ||
88 | Layout.preferredWidth: indexToSize(0) | 101 | } | ||
89 | Layout.preferredHeight: indexToSize(0) | 102 | Repeater { | ||
90 | } | 103 | model: previewGrid.sizes.length | ||
91 | PlasmaCore.IconItem { | 104 | delegate: QQC2.Label { | ||
92 | source: iconName | 105 | Layout.alignment: Qt.AlignTop | Qt.AlignHCenter | ||
93 | usesPlasmaTheme: cuttlefish.usesPlasmaTheme | 106 | text: previewGrid.sizes[index] | ||
94 | colorGroup: PlasmaCore.ColorScope.colorGroup | | |||
95 | Layout.preferredWidth: indexToSize(1) | | |||
96 | Layout.preferredHeight: indexToSize(1) | | |||
97 | } | | |||
98 | PlasmaCore.IconItem { | | |||
99 | source: iconName | | |||
100 | usesPlasmaTheme: cuttlefish.usesPlasmaTheme | | |||
101 | colorGroup: PlasmaCore.ColorScope.colorGroup | | |||
102 | Layout.preferredWidth: indexToSize(2) | | |||
103 | Layout.preferredHeight: indexToSize(2) | | |||
104 | } | | |||
105 | PlasmaCore.IconItem { | | |||
106 | source: iconName | | |||
107 | usesPlasmaTheme: cuttlefish.usesPlasmaTheme | | |||
108 | colorGroup: PlasmaCore.ColorScope.colorGroup | | |||
109 | Layout.preferredWidth: indexToSize(3) | | |||
110 | Layout.preferredHeight: indexToSize(3) | | |||
111 | } | | |||
112 | PlasmaCore.IconItem { | | |||
113 | source: iconName | | |||
114 | usesPlasmaTheme: cuttlefish.usesPlasmaTheme | | |||
115 | colorGroup: PlasmaCore.ColorScope.colorGroup | | |||
116 | Layout.preferredWidth: indexToSize(4) | | |||
117 | Layout.preferredHeight: indexToSize(4) | | |||
118 | } | 107 | } | ||
119 | } | 108 | } | ||
120 | | ||||
121 | PlasmaCore.IconItem { | | |||
122 | source: iconName | | |||
123 | usesPlasmaTheme: cuttlefish.usesPlasmaTheme | | |||
This feature will be missing. Despite still having the checkbox for it. davidedmundson: This feature will be missing. Despite still having the checkbox for it.
| |||||
124 | colorGroup: PlasmaCore.ColorScope.colorGroup | | |||
125 | Layout.fillHeight: false | | |||
126 | Layout.preferredWidth: parent.width | | |||
127 | Layout.preferredHeight: parent.width | | |||
128 | } | 109 | } | ||
110 | function shot(type) { | ||||
111 | iconPreview.screenshotting = true | ||||
112 | if (type == "normal") { | ||||
113 | iconPreview.Kirigami.Theme.inherit = false | ||||
114 | iconPreview.Kirigami.Theme.textColor = "#232629" | ||||
115 | iconPreview.Kirigami.Theme.backgroundColor = "#eff0f1" | ||||
116 | iconPreview.Kirigami.Theme.highlightColor = "#3daee9" | ||||
117 | iconPreview.Kirigami.Theme.highlightedTextColor = "#eff0f1" | ||||
118 | iconPreview.Kirigami.Theme.positiveTextColor = "#27ae60" | ||||
119 | iconPreview.Kirigami.Theme.neutralTextColor = "#f67400" | ||||
120 | iconPreview.Kirigami.Theme.negativeTextColor = "#da4453" | ||||
121 | } else if (type == "dark") { | ||||
122 | iconPreview.Kirigami.Theme.inherit = false | ||||
123 | iconPreview.Kirigami.Theme.textColor = "#eff0f1" | ||||
124 | iconPreview.Kirigami.Theme.backgroundColor = "#31363b" | ||||
125 | iconPreview.Kirigami.Theme.highlightColor = "#3daee9" | ||||
126 | iconPreview.Kirigami.Theme.highlightedTextColor = "#eff0f1" | ||||
127 | iconPreview.Kirigami.Theme.positiveTextColor = "#27ae60" | ||||
128 | iconPreview.Kirigami.Theme.neutralTextColor = "#f67400" | ||||
129 | iconPreview.Kirigami.Theme.negativeTextColor = "#da4453" | ||||
130 | } else if (type == "active") { | ||||
131 | iconPreview.Kirigami.Theme.inherit = true | ||||
132 | } | ||||
133 | ssPicker.open() | ||||
134 | } | ||||
135 | QQC2.ToolButton { | ||||
There's plenty of space for a button that has visible text. I'd recommend doing that instead of using a tiny icons-only button. ngraham: There's plenty of space for a button that has visible text. I'd recommend doing that instead of… | |||||
136 | visible: !iconPreview.screenshotting | ||||
137 | | ||||
138 | hoverEnabled: true | ||||
139 | | ||||
140 | QQC2.ToolTip.visible: hovered | ||||
141 | QQC2.ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval | ||||
142 | QQC2.ToolTip.text: i18n("Create screenshot of icon") | ||||
143 | | ||||
144 | icon.name: "camera-web-symbolic" | ||||
145 | text: i18n("Create screenshot of icon") | ||||
146 | | ||||
147 | anchors.margins: Kirigami.Units.smallSpacing | ||||
148 | anchors.bottom: parent.bottom | ||||
149 | anchors.right: parent.right | ||||
129 | 150 | | |||
130 | GridLayout { | 151 | onClicked: { | ||
131 | columns: 2 | 152 | screenshotActions.popup() | ||
153 | } | ||||
132 | 154 | | |||
133 | PlasmaComponents.Label { | 155 | QQC2.Menu { | ||
134 | text: i18n("Name:") | 156 | id: screenshotActions | ||
157 | QQC2.MenuItem { | ||||
158 | text: i18n("Screenshot with Breeze Colors") | ||||
159 | onTriggered: { | ||||
160 | iconPreview.shot("normal") | ||||
135 | } | 161 | } | ||
136 | PlasmaComponents.Label { | | |||
137 | text: iconName | | |||
138 | wrapMode: Text.Wrap | | |||
139 | } | 162 | } | ||
140 | PlasmaComponents.Label { | 163 | QQC2.MenuItem { | ||
141 | text: i18n("Filename:") | 164 | text: i18n("Screenshot with Breeze Dark Colors") | ||
165 | onTriggered: { | ||||
166 | iconPreview.shot("dark") | ||||
142 | } | 167 | } | ||
143 | PlasmaComponents.Label { | | |||
144 | text: fileName | | |||
145 | wrapMode: Text.Wrap | | |||
146 | verticalAlignment: Text.AlignVCenter | | |||
147 | } | 168 | } | ||
148 | PlasmaComponents.Label { | 169 | QQC2.MenuItem { | ||
149 | text: i18n("Category:") | 170 | text: i18n("Screenshot with Breeze (Normal) and Breeze Dark") | ||
171 | onTriggered: { | ||||
172 | dualMont.shot() | ||||
150 | } | 173 | } | ||
151 | PlasmaComponents.Label { | | |||
152 | text: category | | |||
153 | wrapMode: Text.WordWrap | | |||
154 | } | 174 | } | ||
155 | PlasmaComponents.Label { | 175 | QQC2.MenuItem { | ||
156 | text: i18n("Scalable:") | 176 | text: i18n("Screenshot with Active Colorscheme") | ||
177 | onTriggered: { | ||||
178 | iconPreview.shot("active") | ||||
157 | } | 179 | } | ||
158 | PlasmaComponents.Label { | | |||
159 | text: scalable ? i18n("yes") : i18n("no") | | |||
160 | } | 180 | } | ||
161 | PlasmaComponents.Label { | | |||
162 | text: i18n("Sizes:") | | |||
163 | } | 181 | } | ||
164 | PlasmaComponents.Label { | | |||
165 | text: (sizes != undefined) ? sizes.join(", ") : "" | | |||
166 | } | 182 | } | ||
183 | Row { | ||||
184 | visible: iconPreview.screenshotting | ||||
185 | anchors.top: parent.top | ||||
186 | anchors.left: parent.left | ||||
187 | anchors.margins: Kirigami.Units.smallSpacing | ||||
188 | Kirigami.Icon { | ||||
189 | height: 32 | ||||
190 | width: 32 | ||||
191 | source: "cuttlefish" | ||||
167 | } | 192 | } | ||
168 | Item { | 193 | QQC2.Label { | ||
169 | Layout.fillHeight: true | 194 | anchors.verticalCenter: parent.verticalCenter | ||
195 | text: "Montage made with Cuttlefish" | ||||
170 | } | 196 | } | ||
171 | PlasmaComponents.ToolButton { | | |||
172 | text: pickerMode ? i18n("Insert icon name") : i18n("Copy icon name to clipboard") | | |||
173 | iconSource: "edit-copy" | | |||
174 | Layout.fillWidth: true | | |||
175 | onClicked: clipboard(preview.iconName); | | |||
176 | } | 197 | } | ||
177 | PlasmaComponents.ToolButton { | 198 | } | ||
178 | text: pickerMode ? i18n("Insert QtQuick code") : i18n("Copy QtQuick code to clipboard") | 199 | DualMontage { id: dualMont } | ||
179 | iconSource: "edit-copy" | 200 | Rectangle { | ||
201 | color: "transparent" | ||||
202 | Layout.fillHeight: true | ||||
180 | Layout.fillWidth: true | 203 | Layout.fillWidth: true | ||
181 | onClicked: { | 204 | Kirigami.FormLayout { | ||
182 | var code = "/* Don't forget to import...\n\ | 205 | width: parent.width | ||
183 | import org.kde.plasma.core 2.0 as PlasmaCore\n\ | 206 | anchors.centerIn: parent | ||
184 | */\n\ | 207 | QQC2.ToolButton { | ||
185 | PlasmaCore.IconItem {\n\ | 208 | hoverEnabled: true | ||
186 | source: \"" + preview.iconName + "\"\n\ | 209 | | ||
187 | Layout.preferredWidth: units.iconSizes.medium\n\ | 210 | QQC2.ToolTip.visible: hovered | ||
188 | Layout.preferredHeight: units.iconSizes.medium\n\ | 211 | QQC2.ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval | ||
189 | }\n\ | 212 | QQC2.ToolTip.text: i18n("Copy icon name to clipboard") | ||
Needs a tooltip saying that this will copy the name to the clipboard (the icon isn't enough) ngraham: Needs a tooltip saying that this will copy the name to the clipboard (the icon isn't enough) | |||||
190 | "; | 213 | | ||
191 | clipboard(code); | 214 | Kirigami.FormData.label: i18n("Name:") | ||
215 | icon.name: "edit-copy" | ||||
This is going to shock people, but I might even suggest displaying a Kirigami PassiveNotification saying "<text> copied to clipboard" when this is clicked. Otherwise it looks like nothing happens when you click the button. ngraham: This is going to shock people, but I might even suggest displaying a Kirigami… | |||||
216 | text: preview.iconName | ||||
217 | onClicked: clipboard(preview.iconName) | ||||
218 | } | ||||
219 | QQC2.ToolButton { | ||||
220 | hoverEnabled: true | ||||
221 | | ||||
222 | QQC2.ToolTip.visible: hovered | ||||
Needs a tooltip saying that this will open the image in an external app (the icon isn't enough, though making it actually use the icon of the app that it will open with would help with that) ngraham: Needs a tooltip saying that this will open the image in an external app (the icon isn't enough… | |||||
223 | QQC2.ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval | ||||
224 | QQC2.ToolTip.text: i18n("Open icon with external program") | ||||
225 | | ||||
226 | Kirigami.FormData.label: i18n("Filename:") | ||||
227 | text: preview.fileName | ||||
228 | icon.name: "document-open" | ||||
ngraham: Colorscheme -> Color Scheme | |||||
229 | onClicked: Qt.openUrlExternally(preview.fullPath) | ||||
230 | } | ||||
231 | QQC2.Label { | ||||
232 | Kirigami.FormData.label: i18n("Category:") | ||||
233 | font.capitalization: Font.Capitalize | ||||
234 | text: preview.category | ||||
235 | } | ||||
236 | QQC2.Label { | ||||
237 | Kirigami.FormData.label: i18n("Scalable:") | ||||
238 | text: preview.scalable ? i18n("Yes") : i18n("No") | ||||
192 | } | 239 | } | ||
Use a Kirigami.FormLayout for this (if not using it was deliberate because of layout bugs, let's fix those) ngraham: Use a Kirigami.FormLayout for this (if not using it was deliberate because of layout bugs… | |||||
193 | } | 240 | } | ||
194 | PlasmaComponents.CheckBox { | | |||
195 | text: i18n("Update preview on hover") | | |||
196 | onCheckedChanged: hoveredHighlight = checked | | |||
197 | } | 241 | } | ||
198 | } | 242 | } | ||
199 | 243 | | |||
200 | Rectangle { | 244 | Kirigami.Separator { | ||
201 | color: theme.highlightColor | 245 | height: 1 | ||
202 | width: Math.round(units.gridUnit / 20) | | |||
203 | anchors { | 246 | anchors { | ||
204 | left: parent.left | 247 | left: parent.left | ||
248 | right: parent.right | ||||
205 | top: parent.top | 249 | top: parent.top | ||
206 | bottom: parent.bottom | | |||
207 | } | 250 | } | ||
208 | } | 251 | } | ||
209 | } | 252 | } |
A GridLayout with one column is just a ColumnLayout; use that instead