From 624e0bf64e96f71f2ff20319fc081bd30c59a502 Mon Sep 17 00:00:00 2001 From: Bionus Date: Sun, 1 Nov 2020 16:22:06 +0100 Subject: [PATCH] Use Material design for Android application --- .../resources/images/icons/palette.png | Bin 0 -> 267 bytes .../resources/images/icons/palette@2x.png | Bin 0 -> 460 bytes .../resources/images/icons/palette@3x.png | Bin 0 -> 652 bytes .../resources/images/icons/palette@4x.png | Bin 0 -> 872 bytes src/gui-qml/resources/resources.qrc | 4 + .../src/components/AddSourceScreen.qml | 4 +- src/gui-qml/src/components/ImageScreen.qml | 4 +- src/gui-qml/src/components/LogScreen.qml | 3 +- src/gui-qml/src/components/SearchField.qml | 6 - src/gui-qml/src/components/SearchScreen.qml | 168 ++++++++++-------- .../src/components/settings/Setting.qml | 6 +- .../src/components/settings/SettingItem.qml | 7 +- .../src/components/settings/SettingTitle.qml | 4 +- .../src/components/settings/Settings.qml | 21 +++ .../components/settings/SettingsScreen.qml | 41 +++++ src/gui-qml/src/main-screen.qml | 15 ++ src/gui-qml/src/qtquickcontrols2.conf | 2 +- 17 files changed, 194 insertions(+), 91 deletions(-) create mode 100644 src/gui-qml/resources/images/icons/palette.png create mode 100644 src/gui-qml/resources/images/icons/palette@2x.png create mode 100644 src/gui-qml/resources/images/icons/palette@3x.png create mode 100644 src/gui-qml/resources/images/icons/palette@4x.png diff --git a/src/gui-qml/resources/images/icons/palette.png b/src/gui-qml/resources/images/icons/palette.png new file mode 100644 index 0000000000000000000000000000000000000000..0a11c666336636e18f562e521e6cd888dc88c13c GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjmpok@Ln;{GUT9=H6d=*|(7=Hs z)`^4hkbsgygF%a)BFhV!i9xyqw2;p9`$)EV8!TbI>izUG4d-KV^k(^lxVO?`90ouii7 zh({s%kW8+k^{cz9kK8s+@!wlGwPLoDikaAz+bl-e2L(6rJX2`rk7Oy{(B8)s!EE?! z#aZX3U6R*6T+oo0pHa|Sto@U-oae!u_0OCd!afNoII$gOcHRDt27!E^#Aq*je01yy{FbqQo0S*BIgb;=h0)!C4a0np`!w^Ckh9QJu7~UR) zd^G*eI!Y$KYE(8nAm7$QRrK{~(- z%+qw;KP165tYjlJvC>lHuwNE%Xh5!^-Eo1w_Z)Jk+8r0@d+#CF*Y3DL-}?f&p?1dw`ra|*CfXer=zAy7((kxH z-#dVuMdS{0Q&=R9JU$_Udq)Df92S8V3YEbEyF}rduz;?Sz^gadnvKyxDV@RAV1g%{ zpoY>)@KNG5$xz2yYr{N!AVshq{jW*bQqLD#55a4Ad|rH_hTt_k{)r4xloos@-Vjx7 z@x;C&x)PlI^Nrm>)HRVI#|TpxzR*L04XdiEs_Gl%LLt)=HVP*I0000J}Lm0qd5e8up1_45ZK?s9ESPTY(um}*sVi6!L!T<(g5FiXf2#ZAs4Ot|pJK6CEEbE!VzG1T689Klf*F?B{k;NqM_wJp zY>o^a6kZz{%)wPvG3#(Z1BF$?9_Hpe5!$L*ho4ALNDCND@I^UR&N>X>z1t&Bg6o|B zO__4m;eaZK~MXrqFYRKey1 zU#=Zoq7?OD1$ja#Tf;niMQLl`0Q2Y$ImM4!9i?yN^=1mB8O(!c1kr`ZC#i*;;>Yb5 z5(HBZ2bfS3LDj$-Ch~wF>tPe$LHSkC#~yZs6c-4-1Z_-^!d#Hy79X+(2AE=wHFhw( mV~!h~XR%l;7K_DVvDhCJTmqk{Ds;7>40u2qAE<%7|2;m}x5QcCO0)!!ii!g)`!bKQ{5JDJ+VHk$t zy$^zNyPej3zjNC6fA|3$hs`5` z9dFgZ6b59v-u$Z`Nv**1eiryl-iCRt7ho4(rp5;@+Y^M=^I9*!96Lz9bxdG^))CsS z=XwF=*g~?E7nt9Cq?-470j8;5%tc(oKB$b)R{YlsGDZbSbpl(!CPLftUoTh}$yA3e zsDseDS*{nLjwHH;EohEf;CVgIa=icp6cM#;*e5+;<(;Eq6l1*r`-oOC^rm! zfhuU=H0F8%CisRZwP6xxR8hhRR*>KN_Q$sZuL9;Ma+LM)Gj*NEJ8<6b0GYMzKaY3d zzu$FaQrCYT@4$b*+sLG`|2*D-|9*eKy-ojlyc7TZ{)BtG{_}Vz{`QG^^Kv-V&DV2Bbjs{s=L-;rrWOko8% zLX<9GId_3*wO~1Ri87*9#tfE29VF2WEJw!JLB{EEbcSP8kW>{+U`y%|r>G*?4wmT0 zR3BG3LJeP{5{9tE%+bXT*09vI6FfTV$W28I5}Hb`B6l@m3D`&cay*`>BDa;%kNb|l zs$vxJ{8vTpq^`Cmieq+y{I1HVr~}Hi>etvqFzD0s+{4E zwI`@IYGyDydVu;zMYJ)D`^JJQ;lSaawKhJGs$dT{nCSwJTNy1}Ebs>2{r{basv;WL yLkH)$#sH&Nm+k>dP)aGKlu}A5rIb=C$^HP}5OOdEK?`#L0000images/icons/play@2x.png images/icons/play@3x.png images/icons/play@4x.png + images/icons/palette.png + images/icons/palette@2x.png + images/icons/palette@3x.png + images/icons/palette@4x.png diff --git a/src/gui-qml/src/components/AddSourceScreen.qml b/src/gui-qml/src/components/AddSourceScreen.qml index 85b6585e7..6b13bcd18 100644 --- a/src/gui-qml/src/components/AddSourceScreen.qml +++ b/src/gui-qml/src/components/AddSourceScreen.qml @@ -39,7 +39,7 @@ Page { ColumnLayout { anchors.fill: parent - Text { + Label { Layout.fillWidth: true text: qsTr("Type") } @@ -49,7 +49,7 @@ Page { model: backend.sources } - Text { + Label { Layout.fillWidth: true text: qsTr("URL") } diff --git a/src/gui-qml/src/components/ImageScreen.qml b/src/gui-qml/src/components/ImageScreen.qml index 881df6e4d..e2ebd3d32 100644 --- a/src/gui-qml/src/components/ImageScreen.qml +++ b/src/gui-qml/src/components/ImageScreen.qml @@ -119,10 +119,10 @@ Page { clip: true padding: 8 - Text { + Label { + anchors.fill: parent text: modelData.tags.join("
") textFormat: Text.RichText - lineHeight: 1.1 onLinkActivated: { root.closed() diff --git a/src/gui-qml/src/components/LogScreen.qml b/src/gui-qml/src/components/LogScreen.qml index 11ef49c77..bf18d05d6 100644 --- a/src/gui-qml/src/components/LogScreen.qml +++ b/src/gui-qml/src/components/LogScreen.qml @@ -27,11 +27,10 @@ Page { ScrollView { anchors.fill: parent clip: true + padding: 6 Label { anchors.fill: parent - padding: 6 - lineHeight: 1.1 text: log textFormat: Text.RichText } diff --git a/src/gui-qml/src/components/SearchField.qml b/src/gui-qml/src/components/SearchField.qml index e33920471..779d8ec82 100644 --- a/src/gui-qml/src/components/SearchField.qml +++ b/src/gui-qml/src/components/SearchField.qml @@ -10,13 +10,7 @@ FocusScope { property alias text: textInput.text property alias placeholderText: placeholder.text - anchors.right: parent.right - anchors.rightMargin: 40 - anchors.left: parent.left - anchors.top: parent.top activeFocusOnTab: true - implicitHeight: 40 - implicitWidth: Math.round(parent.width) Rectangle { anchors.fill: editbg diff --git a/src/gui-qml/src/components/SearchScreen.qml b/src/gui-qml/src/components/SearchScreen.qml index e0da8833b..bfaf2f76b 100644 --- a/src/gui-qml/src/components/SearchScreen.qml +++ b/src/gui-qml/src/components/SearchScreen.qml @@ -1,6 +1,7 @@ import QtQml 2.12 import QtQuick 2.12 import QtQuick.Controls 2.5 +import QtQuick.Controls.Material 2.12 import QtQuick.Layouts 1.12 import "../vendor" @@ -52,96 +53,121 @@ Page { } } - ScrollView { - anchors.bottomMargin: 40 - anchors.topMargin: 40 + ColumnLayout { + spacing: 0 anchors.fill: parent - contentHeight: resultsLayout.contentHeight - ColumnFlow { - id: resultsLayout - anchors.fill: parent - columns: gSettings.resultsColumnCount.value - model: results - - onColumnsChanged: resultsRefresher.restart() + RowLayout { + spacing: 0 + Layout.fillWidth: true + Layout.fillHeight: false - delegate: Image { - source: modelData.previewUrl - fillMode: Image.PreserveAspectFit + SearchField { + id: textFieldSearch - onHeightChanged: resultsRefresher.restart() + text: "" + placeholderText: qsTr("Search...") + Layout.fillHeight: true + Layout.fillWidth: true - MouseArea { - anchors.fill: parent - onClicked: mainStackView.push(imageScreen, { index: index }) - } + onEnterPressed: searchTab.load() } - } - Timer { - id: resultsRefresher - interval: 100 - running: false - repeat: false + Button { + id: searchButton + + width: 40 + background.anchors.fill: searchButton + text: qsTr("Go") + Layout.fillHeight: true + Material.elevation: 0 - onTriggered: resultsLayout.reEvalColumns() + onClicked: searchTab.load() + } } - } - Button { - width: 40 - text: "<" - anchors.left: parent.left - anchors.bottom: parent.bottom - enabled: query !== "" && page > 1 + ScrollView { + Layout.fillHeight: true + Layout.fillWidth: true + contentHeight: resultsLayout.contentHeight + clip: true - onClicked: { - page-- - searchTab.load() - } - } + ColumnFlow { + id: resultsLayout + anchors.fill: parent + columns: gSettings.resultsColumnCount.value + model: results - Button { - width: 40 - text: ">" - anchors.right: parent.right - anchors.bottom: parent.bottom - enabled: query !== "" + onColumnsChanged: resultsRefresher.restart() - onClicked: { - page++ - searchTab.load() - } - } + delegate: Image { + source: modelData.previewUrl + fillMode: Image.PreserveAspectFit + + onHeightChanged: resultsRefresher.restart() - SearchField { - id: textFieldSearch + MouseArea { + anchors.fill: parent + onClicked: mainStackView.push(imageScreen, { index: index }) + } + } + } - text: "" - placeholderText: qsTr("Search...") + Timer { + id: resultsRefresher + interval: 100 + running: false + repeat: false - onEnterPressed: searchTab.load() - } + onTriggered: resultsLayout.reEvalColumns() + } + } - Button { - text: qsTr("Sources") - anchors.bottom: parent.bottom - anchors.right: parent.right - anchors.rightMargin: 40 - anchors.left: parent.left - anchors.leftMargin: 40 + RowLayout { + spacing: 0 + Layout.fillWidth: true + Layout.fillHeight: false + + Button { + id: prevButton + background.anchors.fill: prevButton + width: 40 + text: "<" + enabled: query !== "" && page > 1 + Layout.fillHeight: true + Material.elevation: 0 + + onClicked: { + page-- + searchTab.load() + } + } - onClicked: searchTab.openSources() - } + Button { + id: sourcesButton + background.anchors.fill: sourcesButton + text: qsTr("Sources") + Layout.fillWidth: true + Layout.fillHeight: true + Material.elevation: 0 - Button { - id: searchButton - width: 40 - text: qsTr("Go") - anchors.right: parent.right - anchors.top: parent.top + onClicked: searchTab.openSources() + } - onClicked: searchTab.load() + Button { + id: nextButton + background.anchors.fill: nextButton + width: 40 + text: ">" + enabled: query !== "" + Layout.fillHeight: true + Material.elevation: 0 + + onClicked: { + page++ + searchTab.load() + } + } + } } } diff --git a/src/gui-qml/src/components/settings/Setting.qml b/src/gui-qml/src/components/settings/Setting.qml index 5ecb158be..ddfded8dc 100644 --- a/src/gui-qml/src/components/settings/Setting.qml +++ b/src/gui-qml/src/components/settings/Setting.qml @@ -6,10 +6,12 @@ Item { property string key property var def property var obj: settings + property var parser: null - property var value: root.obj + property var value: parser !== null ? parser(rawValue) : rawValue + property var rawValue: root.obj ? root.obj.value(root.key, root.def) - : (typeof def === "boolean" ? false : (typeof def === "number" ? 0 : "")) + : root.def function setValue(val) { root.obj.setValue(root.key, val, root.def) diff --git a/src/gui-qml/src/components/settings/SettingItem.qml b/src/gui-qml/src/components/settings/SettingItem.qml index f2fa88ede..9e82f0842 100644 --- a/src/gui-qml/src/components/settings/SettingItem.qml +++ b/src/gui-qml/src/components/settings/SettingItem.qml @@ -1,6 +1,7 @@ import QtQuick 2.12 import QtQuick.Controls 2.5 import QtQuick.Controls.impl 2.5 +import QtQuick.Controls.Material 2.12 import QtQuick.Layouts 1.12 Rectangle { @@ -33,14 +34,14 @@ Rectangle { width: parent.width spacing: 2 - Text { + Label { text: name } - Text { + Label { visible: !!subtitle text: subtitle font.italic: true - color: Qt.rgba(0, 0, 0, 0.8) + color: Material.secondaryTextColor } } } diff --git a/src/gui-qml/src/components/settings/SettingTitle.qml b/src/gui-qml/src/components/settings/SettingTitle.qml index dc73fe6bf..4db3b37f3 100644 --- a/src/gui-qml/src/components/settings/SettingTitle.qml +++ b/src/gui-qml/src/components/settings/SettingTitle.qml @@ -1,6 +1,6 @@ -import QtQuick 2.12 +import QtQuick.Controls 2.12 -Text { +Label { font.bold: true padding: 8 bottomPadding: 4 diff --git a/src/gui-qml/src/components/settings/Settings.qml b/src/gui-qml/src/components/settings/Settings.qml index acad7f26a..3803b811b 100644 --- a/src/gui-qml/src/components/settings/Settings.qml +++ b/src/gui-qml/src/components/settings/Settings.qml @@ -1,4 +1,5 @@ import QtQuick 2.12 +import QtQuick.Controls.Material 2.12 import Qt.labs.platform 1.1 Item { @@ -121,6 +122,26 @@ Item { obj: root.obj } + // Appearance + property Setting appearance_materialTheme: Setting { + key: "Appearance/materialTheme" + def: Material.System + obj: root.obj + parser: (v) => globals.materialThemes[Number(v)] + } + property Setting appearance_materialPrimary: Setting { + key: "Appearance/materialPrimary" + def: Material.Blue + obj: root.obj + parser: (v) => globals.materialColors[Number(v)] + } + property Setting appearance_materialAccent: Setting { + key: "Appearance/materialAccent" + def: Material.Amber + obj: root.obj + parser: (v) => globals.materialColors[Number(v)] + } + // Mobile-specific settings property Setting mobile_confirmExit: Setting { key: "Mobile/confirmExit" diff --git a/src/gui-qml/src/components/settings/SettingsScreen.qml b/src/gui-qml/src/components/settings/SettingsScreen.qml index 292543635..9eb12d448 100644 --- a/src/gui-qml/src/components/settings/SettingsScreen.qml +++ b/src/gui-qml/src/components/settings/SettingsScreen.qml @@ -1,5 +1,6 @@ import QtQuick 2.12 import QtQuick.Controls 2.5 +import QtQuick.Controls.Material 2.12 import QtQuick.Layouts 1.12 Page { @@ -42,6 +43,10 @@ Page { name: qsTr("Interface") icon: "/images/icons/interface.png" } + ListElement { + name: qsTr("Appearance") + icon: "/images/icons/palette.png" + } ListElement { name: qsTr("Save") icon: "/images/icons/download.png" @@ -122,6 +127,42 @@ Page { } } + ColumnLayout { + width: parent.width + spacing: 0 + visible: false + + SettingTitle { + Layout.fillWidth: true + text: qsTr("Appearance") + } + ComboSetting { + name: qsTr("Theme") + options: globals.materialThemesStr + values: globals.materialThemes + setting: gSettings.appearance_materialTheme + Layout.fillWidth: true + } + ComboSetting { + name: qsTr("Primary color") + options: globals.materialColorsStr + values: globals.materialColors + setting: gSettings.appearance_materialPrimary + Layout.fillWidth: true + } + ComboSetting { + name: qsTr("Accent color") + options: globals.materialColorsStr + values: globals.materialColors + setting: gSettings.appearance_materialAccent + Layout.fillWidth: true + } + + Item { + Layout.fillHeight: true + } + } + ColumnLayout { width: parent.width spacing: 0 diff --git a/src/gui-qml/src/main-screen.qml b/src/gui-qml/src/main-screen.qml index 8738dee70..d56273377 100644 --- a/src/gui-qml/src/main-screen.qml +++ b/src/gui-qml/src/main-screen.qml @@ -1,6 +1,7 @@ import QtQuick 2.12 import QtQuick.Controls 2.5 import QtQuick.Layouts 1.12 +import QtQuick.Controls.Material 2.12 import "components" import "components/settings" @@ -16,10 +17,24 @@ ApplicationWindow { property string site: "danbooru.donmai.us" property string currentPage: "search" + Material.theme: gSettings.appearance_materialTheme.value + Material.primary: gSettings.appearance_materialPrimary.value + Material.accent: gSettings.appearance_materialAccent.value + Settings { id: gSettings } + Item { + id: globals + + property var materialThemes: [Material.Light, Material.Dark, Material.System] + property var materialThemesStr: ["Light", "Dark", "System"] + + property var materialColors: [Material.Red, Material.Pink, Material.Purple, Material.DeepPurple, Material.Indigo, Material.Blue, Material.LightBlue, Material.Cyan, Material.Teal, Material.Green, Material.LightGreen, Material.Lime, Material.Yellow, Material.Amber, Material.Orange, Material.DeepOrange, Material.Brown, Material.Grey, Material.BlueGrey] + property var materialColorsStr: ["Red", "Pink", "Purple", "Deep purple", "Indigo", "Blue", "Light blue", "Cyan", "Teal", "Green", "Light green", "Lime", "Yellow", "Amber", "Orange", "Deep orange", "Brown", "Grey", "Blue grey"] + } + MainDrawer { id: drawer diff --git a/src/gui-qml/src/qtquickcontrols2.conf b/src/gui-qml/src/qtquickcontrols2.conf index 75b2cb8ff..535b22caa 100644 --- a/src/gui-qml/src/qtquickcontrols2.conf +++ b/src/gui-qml/src/qtquickcontrols2.conf @@ -3,4 +3,4 @@ ; http://doc.qt.io/qt-5/qtquickcontrols2-configuration.html [Controls] -Style=Default +Style=Material