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 { | ||
30 | property alias iconPreview: iconPreview | ||||
31 | property alias dualMont: dualMont | ||||
32 | 32 | | |||
33 | id: preview | 33 | Kirigami.Theme.textColor: cuttlefish.textcolor | ||
34 | 34 | Kirigami.Theme.backgroundColor: cuttlefish.bgcolor | |||
35 | color: PlasmaCore.ColorScope.backgroundColor | 35 | Kirigami.Theme.highlightColor: cuttlefish.highlightcolor | ||
36 | Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor | ||||
37 | Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor | ||||
38 | Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor | ||||
39 | Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor | ||||
36 | 40 | | |||
37 | property string iconName: "plasma" | 41 | color: Kirigami.Theme.backgroundColor | ||
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 | 42 | | |||
46 | function clipboard(text) { | 43 | function clipboard(text) { | ||
47 | if (!pickerMode) { | 44 | if (!pickerMode) { | ||
48 | clipboardHelper.text = text; | 45 | clipboardHelper.text = text; | ||
49 | clipboardHelper.selectAll(); | 46 | clipboardHelper.selectAll(); | ||
50 | clipboardHelper.copy(); | 47 | clipboardHelper.copy(); | ||
51 | } else { | 48 | } else { | ||
52 | iconModel.output(text); | 49 | iconModel.output(text); | ||
53 | } | 50 | } | ||
54 | 51 | | |||
55 | } | 52 | } | ||
56 | TextEdit { | 53 | TextEdit { | ||
57 | id: clipboardHelper | 54 | id: clipboardHelper | ||
58 | visible: false | 55 | visible: false | ||
59 | } | 56 | } | ||
60 | 57 | | |||
58 | FileDialog { | ||||
59 | id: ssPicker | ||||
60 | selectExisting: false | ||||
61 | selectMultiple: false | ||||
62 | selectFolder: false | ||||
63 | onAccepted: { | ||||
64 | iconPreview.grabToImage(function(result) { | ||||
65 | ssPicker.resetColors() | ||||
66 | res = result.saveToFile(ssPicker.fileUrl.toString().slice(7)) | ||||
67 | }); | ||||
68 | } | ||||
69 | onRejected: { | ||||
70 | ssPicker.resetColors() | ||||
71 | } | ||||
72 | function resetColors() { | ||||
73 | iconPreview.screenshotting = false | ||||
74 | iconPreview.Kirigami.Theme.textColor = Kirigami.Theme.textColor | ||||
75 | iconPreview.Kirigami.Theme.backgroundColor = Kirigami.Theme.backgroundColor | ||||
76 | iconPreview.Kirigami.Theme.highlightColor = Kirigami.Theme.highlightColor | ||||
77 | iconPreview.Kirigami.Theme.highlightedTextColor = Kirigami.Theme.highlightedTextColor | ||||
78 | iconPreview.Kirigami.Theme.positiveTextColor = Kirigami.Theme.positiveTextColor | ||||
79 | iconPreview.Kirigami.Theme.neutralTextColor = Kirigami.Theme.neutralTextColor | ||||
80 | iconPreview.Kirigami.Theme.negativeTextColor = Kirigami.Theme.negativeTextColor | ||||
81 | iconPreview.Kirigami.Theme.inherit = true | ||||
82 | } | ||||
83 | nameFilters: [ "PNG screenshot files (*.png)" ] | ||||
84 | } | ||||
61 | 85 | | |||
62 | ColumnLayout { | 86 | ColumnLayout { | ||
63 | anchors.margins: units.gridUnit | | |||
64 | anchors.rightMargin: units.gridUnit * 2 | | |||
65 | anchors.fill: parent | 87 | anchors.fill: parent | ||
66 | spacing: units.gridUnit / 2 | 88 | spacing: Kirigami.Units.largeSpacing | ||
ngraham: A GridLayout with one column is just a ColumnLayout; use that instead | |||||
67 | | ||||
68 | Item { height: units.gridUnit / 2 } | | |||
69 | 89 | | |||
70 | PlasmaExtras.Heading { | 90 | Kirigami.Heading { | ||
71 | level: 3 | 91 | level: 1 | ||
GB_2: Maybe add `wrapMode: Text.Wrap`, so the heading can have multiple lines. | |||||
72 | elide: Text.ElideRight | | |||
73 | Layout.fillWidth: true | 92 | Layout.fillWidth: true | ||
74 | Layout.fillHeight: false | | |||
75 | wrapMode: Text.Wrap | 93 | wrapMode: Text.Wrap | ||
76 | text: iconName | 94 | horizontalAlignment: Text.AlignHCenter | ||
95 | elide: Text.ElideRight | ||||
96 | text: preview.iconName | ||||
77 | } | 97 | } | ||
78 | RowLayout { | 98 | Kirigami.FormLayout { | ||
79 | Layout.fillWidth: false | 99 | Layout.fillWidth: true | ||
80 | Layout.fillHeight: false | 100 | Layout.topMargin: Kirigami.Units.largeSpacing | ||
81 | Layout.preferredHeight: indexToSize(4) | 101 | QQC2.Label { | ||
82 | anchors.horizontalCenter: parent.horizontalCenter | 102 | Layout.maximumWidth: Kirigami.Units.gridUnit * 15 | ||
83 | 103 | Kirigami.FormData.label: i18n("File name:") | |||
84 | PlasmaCore.IconItem { | 104 | elide: Text.ElideRight | ||
85 | source: iconName | 105 | text: preview.fileName | ||
86 | usesPlasmaTheme: cuttlefish.usesPlasmaTheme | | |||
87 | colorGroup: PlasmaCore.ColorScope.colorGroup | | |||
88 | Layout.preferredWidth: indexToSize(0) | | |||
89 | Layout.preferredHeight: indexToSize(0) | | |||
90 | } | | |||
91 | PlasmaCore.IconItem { | | |||
92 | source: iconName | | |||
93 | usesPlasmaTheme: cuttlefish.usesPlasmaTheme | | |||
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 | } | 106 | } | ||
107 | QQC2.Label { | ||||
108 | Kirigami.FormData.label: i18n("Category:") | ||||
109 | font.capitalization: Font.Capitalize | ||||
110 | text: preview.category | ||||
111 | } | ||||
112 | QQC2.Label { | ||||
113 | Kirigami.FormData.label: i18n("Scalable:") | ||||
114 | text: preview.scalable ? i18n("yes") : i18n("no") | ||||
115 | font.capitalization: Font.Capitalize | ||||
116 | } | ||||
117 | } | ||||
118 | Rectangle { | ||||
119 | id: iconPreview | ||||
120 | Kirigami.Theme.textColor: cuttlefish.textcolor | ||||
121 | Kirigami.Theme.backgroundColor: cuttlefish.bgcolor | ||||
122 | Kirigami.Theme.highlightColor: cuttlefish.highlightcolor | ||||
123 | Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor | ||||
124 | Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor | ||||
125 | Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor | ||||
126 | Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor | ||||
ngraham: Center this button horizontally | |||||
127 | | ||||
128 | property bool screenshotting: false | ||||
129 | | ||||
130 | color: Kirigami.Theme.backgroundColor | ||||
131 | | ||||
132 | Behavior on color { | ||||
133 | ColorAnimation { | ||||
134 | duration: Kirigami.Units.longDuration | ||||
135 | } | ||||
136 | } | ||||
137 | Behavior on Layout.preferredHeight { | ||||
138 | NumberAnimation { | ||||
139 | duration: Kirigami.Units.longDuration | ||||
119 | } | 140 | } | ||
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 | } | 141 | } | ||
129 | 142 | | |||
130 | GridLayout { | 143 | Layout.fillWidth: true | ||
131 | columns: 2 | 144 | Layout.preferredHeight: screenshotting ? previewGrid.height + (Kirigami.Units.gridUnit * 4) : previewGrid.height | ||
145 | | ||||
146 | Layout.topMargin: Kirigami.Units.largeSpacing | ||||
147 | Layout.bottomMargin: Kirigami.Units.largeSpacing * 4 | ||||
132 | 148 | | |||
133 | PlasmaComponents.Label { | 149 | ColumnLayout { | ||
134 | text: i18n("Name:") | 150 | id: previewGrid | ||
151 | anchors.horizontalCenter: parent.horizontalCenter | ||||
152 | anchors.verticalCenter: parent.verticalCenter | ||||
153 | property var sizes: [8, 16, 22, 32, 48, 64] | ||||
154 | property var largeSizes: [128] | ||||
155 | GridLayout { | ||||
156 | Layout.alignment: Qt.AlignHCenter | ||||
157 | rows: 2 | ||||
158 | columns: previewGrid.sizes.length | ||||
159 | Repeater { | ||||
160 | model: previewGrid.sizes.length | ||||
161 | delegate: Kirigami.Icon { | ||||
162 | Layout.alignment: Qt.AlignBottom | ||||
163 | source: preview.iconName | ||||
164 | width: previewGrid.sizes[index] | ||||
165 | height: previewGrid.sizes[index] | ||||
166 | } | ||||
167 | } | ||||
168 | Repeater { | ||||
169 | model: previewGrid.sizes.length | ||||
170 | delegate: QQC2.Label { | ||||
171 | Layout.alignment: Qt.AlignTop | Qt.AlignHCenter | ||||
172 | text: previewGrid.sizes[index] | ||||
173 | Behavior on color { | ||||
174 | ColorAnimation { | ||||
175 | duration: Kirigami.Units.longDuration | ||||
135 | } | 176 | } | ||
136 | PlasmaComponents.Label { | | |||
137 | text: iconName | | |||
138 | wrapMode: Text.Wrap | | |||
139 | } | 177 | } | ||
140 | PlasmaComponents.Label { | | |||
141 | text: i18n("Filename:") | | |||
142 | } | 178 | } | ||
143 | PlasmaComponents.Label { | | |||
144 | text: fileName | | |||
145 | wrapMode: Text.Wrap | | |||
146 | verticalAlignment: Text.AlignVCenter | | |||
147 | } | 179 | } | ||
148 | PlasmaComponents.Label { | | |||
149 | text: i18n("Category:") | | |||
150 | } | 180 | } | ||
151 | PlasmaComponents.Label { | 181 | GridLayout { | ||
152 | text: category | 182 | Layout.alignment: Qt.AlignHCenter | ||
153 | wrapMode: Text.WordWrap | 183 | rows: 2 | ||
184 | columns: previewGrid.largeSizes.length | ||||
185 | Repeater { | ||||
186 | model: previewGrid.largeSizes.length | ||||
187 | delegate: Kirigami.Icon { | ||||
188 | Layout.alignment: Qt.AlignBottom | ||||
189 | source: preview.iconName | ||||
190 | width: previewGrid.largeSizes[index] | ||||
191 | height: previewGrid.largeSizes[index] | ||||
192 | } | ||||
193 | } | ||||
194 | Repeater { | ||||
195 | model: previewGrid.largeSizes.length | ||||
196 | delegate: QQC2.Label { | ||||
197 | Layout.alignment: Qt.AlignTop | Qt.AlignHCenter | ||||
198 | text: previewGrid.largeSizes[index] | ||||
199 | Behavior on color { | ||||
200 | ColorAnimation { | ||||
201 | duration: Kirigami.Units.longDuration | ||||
154 | } | 202 | } | ||
155 | PlasmaComponents.Label { | | |||
156 | text: i18n("Scalable:") | | |||
157 | } | 203 | } | ||
158 | PlasmaComponents.Label { | | |||
159 | text: scalable ? i18n("yes") : i18n("no") | | |||
160 | } | 204 | } | ||
161 | PlasmaComponents.Label { | | |||
162 | text: i18n("Sizes:") | | |||
163 | } | 205 | } | ||
164 | PlasmaComponents.Label { | | |||
165 | text: (sizes != undefined) ? sizes.join(", ") : "" | | |||
166 | } | 206 | } | ||
167 | } | 207 | } | ||
168 | Item { | 208 | Row { | ||
169 | Layout.fillHeight: true | 209 | opacity: iconPreview.screenshotting ? 1 : 0 | ||
210 | anchors.top: parent.top | ||||
211 | anchors.left: parent.left | ||||
212 | anchors.margins: Kirigami.Units.smallSpacing | ||||
213 | Kirigami.Icon { | ||||
214 | height: 32 | ||||
215 | width: 32 | ||||
216 | source: "cuttlefish" | ||||
217 | } | ||||
218 | QQC2.Label { | ||||
219 | anchors.verticalCenter: parent.verticalCenter | ||||
220 | text: "Montage made with Cuttlefish" | ||||
221 | } | ||||
222 | Behavior on opacity { | ||||
223 | OpacityAnimator { | ||||
224 | duration: Kirigami.Units.longDuration | ||||
225 | } | ||||
226 | } | ||||
227 | } | ||||
228 | function shot(type) { | ||||
229 | iconPreview.screenshotting = true | ||||
230 | if (type == "normal") { | ||||
231 | iconPreview.Kirigami.Theme.inherit = false | ||||
232 | iconPreview.Kirigami.Theme.textColor = "#232629" | ||||
233 | iconPreview.Kirigami.Theme.backgroundColor = "#eff0f1" | ||||
234 | iconPreview.Kirigami.Theme.highlightColor = "#3daee9" | ||||
235 | iconPreview.Kirigami.Theme.highlightedTextColor = "#eff0f1" | ||||
236 | iconPreview.Kirigami.Theme.positiveTextColor = "#27ae60" | ||||
237 | iconPreview.Kirigami.Theme.neutralTextColor = "#f67400" | ||||
238 | iconPreview.Kirigami.Theme.negativeTextColor = "#da4453" | ||||
239 | } else if (type == "dark") { | ||||
240 | iconPreview.Kirigami.Theme.inherit = false | ||||
241 | iconPreview.Kirigami.Theme.textColor = "#eff0f1" | ||||
242 | iconPreview.Kirigami.Theme.backgroundColor = "#31363b" | ||||
243 | iconPreview.Kirigami.Theme.highlightColor = "#3daee9" | ||||
244 | iconPreview.Kirigami.Theme.highlightedTextColor = "#eff0f1" | ||||
245 | iconPreview.Kirigami.Theme.positiveTextColor = "#27ae60" | ||||
246 | iconPreview.Kirigami.Theme.neutralTextColor = "#f67400" | ||||
247 | iconPreview.Kirigami.Theme.negativeTextColor = "#da4453" | ||||
248 | } else if (type == "active") { | ||||
249 | iconPreview.Kirigami.Theme.inherit = true | ||||
250 | } | ||||
251 | ssPicker.open() | ||||
252 | } | ||||
253 | } | ||||
254 | QQC2.Button { | ||||
255 | Layout.alignment: Qt.AlignHCenter | ||||
256 | text: i18n("Open icon with external program") | ||||
257 | icon.name: "document-open" | ||||
258 | onClicked: Qt.openUrlExternally(preview.fullPath) | ||||
259 | } | ||||
260 | QQC2.Button { | ||||
261 | Layout.alignment: Qt.AlignHCenter | ||||
262 | text: i18n("Copy icon name to clipboard") | ||||
263 | icon.name: "edit-copy" | ||||
264 | onClicked: { | ||||
265 | clipboard(preview.iconName) | ||||
266 | cuttlefish.showPassiveNotification(i18n("Icon name copied to clipboard"), "short") | ||||
170 | } | 267 | } | ||
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 | } | 268 | } | ||
177 | PlasmaComponents.ToolButton { | 269 | QQC2.Button { | ||
178 | text: pickerMode ? i18n("Insert QtQuick code") : i18n("Copy QtQuick code to clipboard") | 270 | Layout.alignment: Qt.AlignHCenter | ||
179 | iconSource: "edit-copy" | 271 | visible: !iconPreview.screenshotting | ||
180 | Layout.fillWidth: true | 272 | icon.name: "camera-web-symbolic" | ||
273 | text: i18n("Create screenshot of icon") | ||||
274 | | ||||
181 | onClicked: { | 275 | onClicked: { | ||
182 | var code = "/* Don't forget to import...\n\ | 276 | screenshotActions.popup() | ||
183 | import org.kde.plasma.core 2.0 as PlasmaCore\n\ | 277 | } | ||
184 | */\n\ | 278 | | ||
185 | PlasmaCore.IconItem {\n\ | 279 | QQC2.Menu { | ||
186 | source: \"" + preview.iconName + "\"\n\ | 280 | id: screenshotActions | ||
187 | Layout.preferredWidth: units.iconSizes.medium\n\ | 281 | QQC2.MenuItem { | ||
188 | Layout.preferredHeight: units.iconSizes.medium\n\ | 282 | text: i18n("Screenshot with Breeze Colors") | ||
189 | }\n\ | 283 | onTriggered: { | ||
190 | "; | 284 | iconPreview.shot("normal") | ||
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) | |||||
191 | clipboard(code); | 285 | } | ||
286 | } | ||||
287 | QQC2.MenuItem { | ||||
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… | |||||
288 | text: i18n("Screenshot with Breeze Dark Colors") | ||||
289 | onTriggered: { | ||||
290 | iconPreview.shot("dark") | ||||
192 | } | 291 | } | ||
193 | } | 292 | } | ||
194 | PlasmaComponents.CheckBox { | 293 | QQC2.MenuItem { | ||
195 | text: i18n("Update preview on hover") | 294 | text: i18n("Screenshot with Breeze (Normal) and Breeze Dark") | ||
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… | |||||
196 | onCheckedChanged: hoveredHighlight = checked | 295 | onTriggered: { | ||
296 | dualMont.shot() | ||||
197 | } | 297 | } | ||
198 | } | 298 | } | ||
299 | QQC2.MenuItem { | ||||
300 | text: i18n("Screenshot with Active Color Scheme") | ||||
ngraham: Colorscheme -> Color Scheme | |||||
301 | onTriggered: { | ||||
302 | iconPreview.shot("active") | ||||
303 | } | ||||
304 | } | ||||
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… | |||||
305 | } | ||||
306 | } | ||||
307 | Item { | ||||
308 | Layout.fillHeight: true | ||||
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… | |||||
309 | } | ||||
310 | DualMontage { id: dualMont } | ||||
311 | } | ||||
199 | 312 | | |||
200 | Rectangle { | 313 | Kirigami.Separator { | ||
201 | color: theme.highlightColor | 314 | width: 1 | ||
202 | width: Math.round(units.gridUnit / 20) | | |||
203 | anchors { | 315 | anchors { | ||
204 | left: parent.left | 316 | left: parent.left | ||
205 | top: parent.top | | |||
206 | bottom: parent.bottom | 317 | bottom: parent.bottom | ||
318 | top: parent.top | ||||
207 | } | 319 | } | ||
208 | } | 320 | } | ||
209 | } | 321 | } |
A GridLayout with one column is just a ColumnLayout; use that instead