commit 79eff3c0f6d2cfb2915c4d582bc4c67646797c2f Author: erinn Date: Tue May 19 12:49:52 2020 -0700 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..86950b3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.qmlc diff --git a/Badge.qml b/Badge.qml new file mode 100644 index 0000000..6369eab --- /dev/null +++ b/Badge.qml @@ -0,0 +1,24 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import CustomQmlTypes 1.0 +import "../theme" + +Rectangle { + width: parent.width * 0.25 + height: width + radius: width/2 + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.margins: parent.width * 0.09 + property alias content: container.children + + Column { + id: container + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + } + +} diff --git a/Button.qml b/Button.qml new file mode 100644 index 0000000..c341334 --- /dev/null +++ b/Button.qml @@ -0,0 +1,79 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 + +import "../fonts/Twemoji.js" as T +import "../theme" +import "../fonts" + +Rectangle { + id: button + width: (text == undefined || text == "" ? 0 : buttonText.width) + (icon == undefined || icon == "" ? 0 : ico.width) + 24 * gcd.themeScale + Layout.minimumWidth: width + Layout.maximumWidth: width + height: 20 * gcd.themeScale + Layout.minimumHeight: height + Layout.maximumHeight: height + color: mousedown ? Theme.defaultButtonActiveColor : Theme.defaultButtonColor + border.color: mousedown ? Theme.defaultButtonActiveColor : Theme.defaultButtonColor + border.width: 1 + radius: override_radius + antialiasing: true + + property bool checked: false + property double override_radius: (height / 2.0) + property alias text: buttonText.text + property alias font: buttonText.font.family + property string icon + property bool mousedown + property string tooltip + signal clicked + + + RowLayout { + anchors.centerIn: parent + + Image { + anchors.left: parent.left + id: ico + source: icon!="" ? gcd.assetPath + "fontawesome/"+icon+".svg" : ""; + height: button.height / 2 + sourceSize.height: button.height / 2 + } + + Label { + id: buttonText + font.family: Fonts.applicationFontRegular.name + font.styleName: "ExtraBold" + font.pixelSize: button.height / 2 + color: Theme.defaultButtonTextColor + anchors.left: ico.right + anchors.leftMargin: 6 + visible: button.text != "" && button.text != undefined + } + + ToolTip.visible: tooltip != "" && mouseArea.containsMouse + ToolTip.text: tooltip + } + + + MouseArea { + id: mouseArea + anchors.fill: parent + + onClicked: { + parent.focus = true + parent.clicked() + } + + onPressed: mousedown = true + + onReleased: mousedown = false + + hoverEnabled: true + } + + Keys.onSpacePressed: clicked() +} diff --git a/ButtonTextField.qml b/ButtonTextField.qml new file mode 100644 index 0000000..9962ce2 --- /dev/null +++ b/ButtonTextField.qml @@ -0,0 +1,49 @@ +import QtQuick 2.7 + +import QtQuick.Controls 2.13 +import QtQuick.Controls.Styles 1.4 +import QtGraphicalEffects 1.12 +import "." as Widgets +import "../theme" + + +// ButtonTextField integrates a text field and a button +TextField { + id: tf + color: Theme.mainTextColor + font.pixelSize: Theme.secondaryTextSize * gcd.themeScale + width: parent.width - 20 + property string icon + property string button_text + signal clicked + smooth: true + property color dropShadowColor: Theme.dropShadowColor + + background: Rectangle { + radius: 10 + color: Theme.backgroundMainColor + border.color: Theme.backgroundMainColor + layer.enabled: true + layer.effect: DropShadow { + transparentBorder: true + horizontalOffset: 4 + verticalOffset: 4 + samples:10 + color: tf.dropShadowColor + } + } + + Widgets.Button { + icon: "" + text: button_text + anchors { top: parent.top; right: parent.right } + override_radius: 10 + height: parent.height; width: parent.height * 4 + + onClicked: { + parent.focus = true; + parent.clicked(); + } + } + +} diff --git a/ContactList.qml b/ContactList.qml new file mode 100644 index 0000000..2011784 --- /dev/null +++ b/ContactList.qml @@ -0,0 +1,171 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import "../theme" + +ColumnLayout { + id: root + + property alias dualPane: myprof.dualPane + + spacing: 10 + + MouseArea { + anchors.fill: parent + + onClicked: { + forceActiveFocus() + } + } + + MyProfile { // CURRENT PROFILE INFO AND CONTROL BAR + id: myprof + } + + + IconTextField { + id: searchAddText + anchors.horizontalCenter: parent.horizontalCenter + + Layout.minimumWidth: parent.width - 60 + Layout.maximumWidth: parent.width - 60 + + + + + //: ex: "... paste an address here to add a contact ..." + placeholderText: qsTr("paste-address-to-add-contact") + horizontalAlignment: TextInput.AlignHCenter + icon: gcd.assetPath + "core/search-24px.svg" + + + onTextChanged: { + if (text != "") { + gcd.importString(text) + text = "" + } + } + } + + + Flickable { // THE ACTUAL CONTACT LIST + id: sv + //Layout.alignment: Qt.AlignLeft | Qt.AlignTop + clip: true + Layout.minimumHeight: 100 + //Layout.maximumHeight: parent.height - 30 + Layout.fillHeight: true + Layout.minimumWidth: parent.width + Layout.maximumWidth: parent.width + contentWidth: colContacts.width + contentHeight: colContacts.height + boundsBehavior: Flickable.StopAtBounds + maximumFlickVelocity: 400 + + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AsNeeded + background: Rectangle { + implicitWidth: 6 + + color: Theme.backgroundMainColor + } + contentItem: Rectangle { + implicitWidth: 6 + implicitHeight:1 + color: Theme.backgroundPaneColor + } + } + + ColumnLayout { + id: colContacts + width: root.width + spacing: 0 + + Connections { // ADD/REMOVE CONTACT ENTRIES + target: gcd + + onAddContact: function(handle, displayName, image, badge, status, blocked, loading, lastMsgTs) { + + for (var i = 0; i < contactsModel.count; i++) { + if (contactsModel.get(i)["_handle"] == handle) { + return + } + } + + var index = contactsModel.count + for (var i = 0; i < contactsModel.count; i++) { + if (contactsModel.get(i)["_lastMsgTs"] < lastMsgTs) { + index = i + break + } + } + + var newContact = { + "_handle": handle, + "_displayName": displayName + (blocked ? " (blocked)" : "" ), + "_image": image, + "_badge": badge, + "_status": status, + "_blocked": blocked, + "_loading": loading, + "_loading": loading, + "_lastMsgTs": lastMsgTs + } + + contactsModel.insert(index, newContact) + } + + onRemoveContact: function(handle) { + for(var i = 0; i < contactsModel.count; i++){ + if(contactsModel.get(i)["_handle"] == handle) { + console.log("deleting contact " + contactsModel.get(i)["_handle"]) + contactsModel.remove(i) + return + } + } + } + + onIncContactUnreadCount: function(handle) { + var ts = Math.round((new Date()).getTime() / 1000); + for(var i = 0; i < contactsModel.count; i++){ + if(contactsModel.get(i)["_handle"] == handle) { + var contact = contactsModel.get(i) + contact["_lastMsgTs"] = ts + contactsModel.move(i, 0, 1) + } + } + } + + onResetProfile: function() { + contactsModel.clear() + } + } + + ListModel { // CONTACT OBJECTS ARE STORED HERE ... + id: contactsModel + } + + Repeater { + model: contactsModel // ... AND DISPLAYED HERE + delegate: ContactRow { + handle: _handle + displayName: _displayName + image: _image + badge: _badge + status: _status + blocked: _blocked + loading: _loading + } + } + + + } + } + + +} + + + diff --git a/ContactRow.qml b/ContactRow.qml new file mode 100644 index 0000000..bed4b98 --- /dev/null +++ b/ContactRow.qml @@ -0,0 +1,102 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import CustomQmlTypes 1.0 +import "../styles" +import "../widgets" as Widgets +import "../theme" +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +PortraitRow { + + property int status: 0 + property int badge + property bool loading + + badgeColor: Theme.portraitContactBadgeColor + badgeVisible: badge > 0 + + badgeContent: Label { + id: lblUnread + color: Theme.portraitContactBadgeTextColor + font.pixelSize: Theme.badgeTextSize * gcd.themeScale + font.weight: Font.Bold + text: badge > 99 ? "99+" : badge + } + + ProgressBar { // LOADING ? + id: loadingProgress + property bool running + running: loading + visible: loading + + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 1 * gcd.themeScale + anchors.rightMargin: 25 * gcd.themeScale + + height: parent.height * .1 + width: 100 * gcd.themeScale + + indeterminate: true + + style: ProgressBarStyle { + progress: CwtchProgress { running: loadingProgress.running} + } + } + + onClicked: function(handle) { + gcd.broadcast("ResetMessagePane") + isActive = true + theStack.pane = theStack.messagePane + gcd.loadMessagesPane(handle) + badge = 0 + if (handle.length == 32) { + gcd.requestGroupSettings(handle) + } + } + + Component.onCompleted: { setColors(status) } + + onStatusChanged: { setColors(status) } + + function setColors(status) { + //-2:WtfCodeError,-1:Error,0:Disconnected,1:Connecting,2:Connected,3:Authenticated,4:Synced,5:Failed,6:Killed + if (status == 4 || status == 3) { + portraitBorderColor = Theme.portraitOnlineBorderColor + portraitColor = Theme.portraitOnlineBackgroundColor + nameColor = Theme.portraitOnlineTextColor + onionColor = Theme.portraitOnlineTextColor + } else if (status == 2 || status == 1) { + portraitBorderColor = Theme.portraitConnectingBorderColor + portraitColor = Theme.portraitConnectingBackgroundColor + nameColor = Theme.portraitConnectingTextColor + onionColor = Theme.portraitConnectingTextColor + } else { + portraitBorderColor = Theme.portraitOfflineBorderColor + portraitColor = Theme.portraitOfflineBackgroundColor + nameColor = Theme.portraitOfflineTextColor + onionColor = Theme.portraitOfflineTextColor + } + } + + Connections { // UPDATE UNREAD MESSAGES COUNTER + target: gcd + + onUpdateContactStatus: function(_handle, _status, _loading) { + if (handle == _handle) { + status = _status + loadingProgress.visible = loadingProgress.running = loading = _loading + } + } + + onIncContactUnreadCount: function(handle) { + if (handle == _handle && gcd.selectedConversation != handle) { + badge++ + } + } + } +} diff --git a/EllipsisLabel.qml b/EllipsisLabel.qml new file mode 100644 index 0000000..a0d042c --- /dev/null +++ b/EllipsisLabel.qml @@ -0,0 +1,59 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import CustomQmlTypes 1.0 +import "../widgets" as Widgets +import "../theme" + + +// Needs the parent to have an onWidthChanged that calls .textResize() +Item { + anchors.right: parent.right + anchors.left: parent.left + + property string text + + property alias color: label.color + property alias pixelSize: label.font.pixelSize + property alias weight: label.font.weight + property alias strikeout: label.font.strikeout + property alias font: label.font + property int extraPadding: 0 + + property Item container: parent + + height: textMetric.height + width: textMetric.width + 10 + anchors.leftMargin: 10 + + Label { + id: label + textFormat: Text.PlainText + + elide: Text.ElideRight + text: textMetric.text + } + + TextMetrics { + id: textMetric + text: text + font: label.font + } + + onTextChanged: { + textResize() + } + + function textResize() { + textMetric.text = text + var i = 2 + var containerWidth = container != null ? container.width : 50 + // - 30 for padding + while (textMetric.width > containerWidth - ((30 + extraPadding) * gcd.themeScale) && containerWidth > 50) { + textMetric.text = text.slice(0, text.length - (i * 3)) + "..." + i++ + } + } + +} diff --git a/EmojiDrawer.qml b/EmojiDrawer.qml new file mode 100644 index 0000000..7bb9bba --- /dev/null +++ b/EmojiDrawer.qml @@ -0,0 +1,400 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.13 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import Qt.labs.folderlistmodel 2.13 +import QtQml.Models 2.13 + +import "../fonts/MutantStandard.js" as Mutant +import "controls" + +Item { + id: root + height: 0 + property int size: 24 + property int requestedHeight: size * 8 + property string morph: "clw" + property string color: "v1" + property bool narrowMode: width < (txtSearch.width + root.size * 14 + btnX.width) + signal picked(string shortcode) + signal slideopen() + signal slideclosed() + visible: height != 0 + + Rectangle { + color: windowItem.cwtch_dark_color + anchors.fill: parent + } + + PropertyAnimation { + id: animClose; + target: root; + properties: "height"; + to: 0; + duration: 400; + } + + PropertyAnimation { + id: animOpen; + target: root; + properties: "height"; + to: requestedHeight; + duration: 400; + } + + Button { + id: btnX + anchors.top: parent.top + anchors.right: parent.right + text: "x" + + onClicked: animClose.start() + } + + ColumnLayout { + anchors.fill: parent + + + RowLayout { + TextField { + id: txtSearch + //: Search... + placeholderText: qsTr("search") + onTextChanged: { + if (text == "") emojiModel.model = folder_expressions + else emojiModel.model = folder_search + emojiModel.updatefilters() + } + } + + ImageButton { + id: btnEmojiExpressionsGroup + visible: !root.narrowMode + //: Expressions + tooltip: qsTr("emojicat-expressions") + source: gcd.assetPath + "mutstd/smile.webp" + size: root.size + onClicked: emojiModel.model = folder_expressions + } + ImageButton { + visible: !root.narrowMode + //: Activities + tooltip: qsTr("emojicat-activities") + source: gcd.assetPath + "mutstd/artist_r1.webp" + size: root.size + onClicked: emojiModel.model = folder_activities_clothing + } + ImageButton { + visible: !root.narrowMode + //: Food, drink & herbs + tooltip: qsTr("emojicat-food") + source: gcd.assetPath + "mutstd/red_apple.webp" + size: root.size + onClicked: emojiModel.model = folder_food_drink_herbs + } + ImageButton { + visible: !root.narrowMode + //: Gender, relationships & sexuality + tooltip: qsTr("emojicat-gender") + size: root.size + source: gcd.assetPath + "mutstd/pride_100.webp" + onClicked: emojiModel.model = folder_gsr + } + ImageButton { + visible: !root.narrowMode + //: Nature and effects + tooltip: qsTr("emojicat-nature") + source: gcd.assetPath + "mutstd/sun_behind_small_cloud.webp" + size: root.size + onClicked: emojiModel.model = folder_nature + } + ImageButton { + visible: !root.narrowMode + //: Objects + tooltip: qsTr("emojicat-objects") + source: gcd.assetPath + "mutstd/crystal_ball.webp" + size: root.size + onClicked: emojiModel.model = folder_objects + } + ImageButton { + visible: !root.narrowMode + //: People and animals + tooltip: qsTr("emojicat-people") + source: gcd.assetPath + "mutstd/crow.webp" + size: root.size + onClicked: emojiModel.model = folder_people + } + ImageButton { + visible: !root.narrowMode + //: Symbols + tooltip: qsTr("emojicat-symbols") + source: gcd.assetPath + "mutstd/purple_heart.webp" + size: root.size + onClicked: emojiModel.model = folder_symbols + } + ImageButton { + visible: !root.narrowMode + //: Travel & places + tooltip: qsTr("emojicat-travel") + source: gcd.assetPath + "mutstd/airplane.webp" + size: root.size + onClicked: emojiModel.model = folder_travel_places + } + ImageButton { + visible: !root.narrowMode + //: Miscellaneous + tooltip: qsTr("emojicat-misc") + source: gcd.assetPath + "mutstd/hash_char.webp" + size: root.size + onClicked: emojiModel.model = folder_utils + } + ImageButton { + visible: !root.narrowMode + id: btnUndefinedGroup + // (no tooltip; this is a catchall group meant to detect unclassified emoji during development) + //TODO: remove this category upon finalizing the Emoji Drawer + source: gcd.assetPath + "mutstd/undefined_character.webp" + size: root.size + onClicked: emojiModel.model = folder_other + } + + Item { + visible: root.narrowMode + height: root.size + width: root.size + + Image { + id: imgCatRot + anchors.centerIn: parent + source: cats[index].source + property int index: 0 + property var cats: [ + {source: gcd.assetPath + "mutstd/smile.webp", model: folder_expressions}, + {source: gcd.assetPath + "mutstd/artist_r1.webp", model: folder_activities_clothing}, + {source: gcd.assetPath + "mutstd/red_apple.webp", model: folder_food_drink_herbs}, + {source: gcd.assetPath + "mutstd/pride_100.webp", model: folder_gsr}, + {source: gcd.assetPath + "mutstd/sun_behind_small_cloud.webp", model: folder_nature}, + {source: gcd.assetPath + "mutstd/crystal_ball.webp", model: folder_objects}, + {source: gcd.assetPath + "mutstd/crow.webp", model: folder_people}, + {source: gcd.assetPath + "mutstd/purple_heart.webp", model: folder_symbols}, + {source: gcd.assetPath + "mutstd/airplane.webp", model: folder_travel_places}, + {source: gcd.assetPath + "mutstd/hash_char.webp", model: folder_utils}, + {source: gcd.assetPath + "mutstd/undefined_character.webp", model: folder_other} + ] + height: root.size * (maCatRot.pressed ? 0.8 : 1.0) + width: root.size * (maCatRot.pressed ? 0.8 : 1.0) + + ToolTip.visible: maCatRot.containsMouse + ToolTip.text: gcd.os == "android" ? qsTr("cycle-cats-android") : qsTr("cycle-cats-desktop") + + MouseArea { + id: maCatRot + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + anchors.fill: parent; + + onClicked: { + if (mouse.button == Qt.RightButton) {//todo: long press on android + imgCatRot.index = 0 + } else { + imgCatRot.index = (imgCatRot.index + 1) % imgCatRot.cats.length + } + emojiModel.model = imgCatRot.cats[imgCatRot.index].model + //root.morph = Mutant.standard.morphs[imgMorph.index] + //emojiModel.updatefilters() + } + } + } + } + + Item { + height: root.size + width: root.size + + Image { + id: imgMorph + anchors.centerIn: parent + source: gcd.assetPath + "mutstd/hand_"+Mutant.standard.morphs[index]+"_"+root.color+".webp" + property int index: 0 + height: root.size + width: root.size + + ToolTip.visible: maMorph.containsMouse + ToolTip.text: gcd.os == "android" ? qsTr("cycle-morphs-android") : qsTr("cycle-morphs-desktop") + + MouseArea { + id: maMorph + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + anchors.fill: parent; + onClicked: { + if (mouse.button == Qt.RightButton) {//todo: long press on android + imgMorph.index = 0//TODO: saved morph + } else { + imgMorph.index = (imgMorph.index + 1) % Mutant.standard.morphs.length + } + root.morph = Mutant.standard.morphs[imgMorph.index] + emojiModel.updatefilters() + } + } + } + } + + Item { + height: root.size + width: root.size + + Image { + id: imgColor + anchors.centerIn: parent + source: gcd.assetPath + "mutstd/color_modifier_"+Mutant.standard.colorByIndex(index, root.morph)+".webp" + property int index: 0 + height: root.size + width: root.size + + ToolTip.visible: ma.containsMouse + ToolTip.text: gcd.os == "android" ? qsTr("cycle-colours-android") : qsTr("cycle-colours-desktop") + + MouseArea { + id: ma + anchors.fill: parent; + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onClicked: function(mouse){ + if (mouse.button == Qt.RightButton) {//todo: long press on android + imgColor.index = 0//todo: saved color + } else { + imgColor.index = (imgColor.index + 1) % Mutant.standard.numColors(root.morph) + } + root.color = Mutant.standard.colorByIndex(imgColor.index, root.morph) + emojiModel.updatefilters() + } + } + } + } + } + + GridView { + Layout.fillWidth: true + Layout.fillHeight: true + height: root.size * 3 + cellWidth: root.size + cellHeight: root.size + clip: true + ScrollBar.vertical: ScrollBar {} + maximumFlickVelocity: 1250 + boundsBehavior: GridView.StopAtBounds + + + model: emojiModel + } + } + + ListModel { id: folder_activities_clothing } + ListModel { id: folder_expressions } + ListModel { id: folder_food_drink_herbs } + ListModel { id: folder_gsr } + ListModel { id: folder_nature } + ListModel { id: folder_objects } + ListModel { id: folder_people } + ListModel { id: folder_symbols } + ListModel { id: folder_travel_places } + ListModel { id: folder_utils } + ListModel { id: folder_other } + ListModel { id: folder_search } + + DelegateModel { + id: emojiModel + model: folder_expressions + + delegate: Item { + width: root.size + height: root.size + + Image { + id: img + //source: "file://" + gcd.binaryPath + "/assets/mutstd/" + code + ".webp" + source: gcd.assetPath + "mutstd/" + code + ".webp" + width: root.size * (mouseArea.pressed ? 0.7 : 0.8) + height: width + anchors.centerIn: parent + property string shortcode: code + + ToolTip.visible: mouseArea.containsMouse + ToolTip.text: desc + "\n:" + shortcode + ":" + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + + onClicked: root.picked(img.shortcode) + } + } + } + + Component.onCompleted: updatefilters() + + function clearall() { + folder_activities_clothing.clear() + folder_expressions.clear() + folder_food_drink_herbs.clear() + folder_gsr.clear() + folder_nature.clear() + folder_objects.clear() + folder_people.clear() + folder_symbols.clear() + folder_travel_places.clear() + folder_utils.clear() + folder_other.clear() + folder_search.clear() + } + + function updatefilters() { + clearall() + + for (var i in Mutant.standard.manifest) { + if (typeof Mutant.standard.manifest[i].morph !== "undefined" && Mutant.standard.manifest[i].morph != root.morph) + continue; + + if (typeof Mutant.standard.manifest[i].color !== "undefined" && Mutant.standard.manifest[i].color != root.color) + continue; + + if (txtSearch.text != "" && !(Mutant.standard.manifest[i].code.includes(txtSearch.text) || Mutant.standard.manifest[i].desc.includes(txtSearch.text))) { + continue; + } + + var model = folder_other + if (txtSearch.text == "") { + switch(Mutant.standard.manifest[i].cat) { + case "activities_clothing": model = folder_activities_clothing; break; + case "expressions": model = folder_expressions; break; + case "symbols": model = folder_symbols; break; + case "food_drink_herbs": model = folder_food_drink_herbs; break; + case "gsr": model = folder_gsr; break; + case "nature": model = folder_nature; break; + case "objects": model = folder_objects; break; + case "people": model = folder_people; break; + case "travel_places": model = folder_travel_places; break; + case "utils": model = folder_utils; break; + } + } else { + model = folder_search + } + + model.append({ + cat: Mutant.standard.manifest[i].cat, + code: Mutant.standard.manifest[i].code, + color: Mutant.standard.manifest[i].color, + morph: Mutant.standard.manifest[i].morph, + desc: Mutant.standard.manifest[i].desc + }) + } + } + } + + onSlideopen: animOpen.start() + onSlideclosed: animClose.start() +} diff --git a/FontAwesome.qml b/FontAwesome.qml new file mode 100644 index 0000000..dcdaed1 --- /dev/null +++ b/FontAwesome.qml @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** The MIT License (MIT) +** +** Copyright (c) 2014 Ricardo do Valle Flores de Oliveira +** +** $BEGIN_LICENSE:MIT$ +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** $END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +import "controls" as Awesome + +Item { + id: awesome + + property alias icons: variables + property alias loaded: loader.loaded + property alias resource: loader.resource + + readonly property string family: "FontAwesome" + + Awesome.Loader { + id: loader + } + + Awesome.Variables { + id: variables + } +} diff --git a/HLine.qml b/HLine.qml new file mode 100644 index 0000000..33c342a --- /dev/null +++ b/HLine.qml @@ -0,0 +1,28 @@ +import QtQuick 2.12 +import "../theme" + +Column { + width: parent.width + anchors.horizontalCenter: parent.horizontalCenter + + Rectangle { + height: 10 + color:"transparent" + width: parent.width + } + + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + height: 1 + width: parent.width * 0.95 + color: Theme.dropShadowColor + } + + + Rectangle { + height: 10 + color:"transparent" + width: parent.width + } +} diff --git a/Icon.qml b/Icon.qml new file mode 100644 index 0000000..471a3a4 --- /dev/null +++ b/Icon.qml @@ -0,0 +1,63 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 + +import "../fonts/Twemoji.js" as T +import "." as Widgets +import "../theme" + +Rectangle { + id: root + + property color backgroundColor: parent.color + property color hilightBackgroundColor: backgroundColor + + property bool isHover: false + + color: isHover ? backgroundColor : hilightBackgroundColor + + property alias iconColor: iconColorOverlay.color + + property alias source: srcImg.source + + signal clicked() + + Image { + id: srcImg + anchors.fill: parent + antialiasing: true + smooth: true + visible: false + // Apparently qml can now only DOWN-SCALE/SHRINK the SVG, so with this hack it which won't cause blurriness/pixelation + sourceSize.width: root.width*2 + sourceSize.height: root.height*2 + } + + ColorOverlay{ + id: iconColorOverlay + anchors.fill: srcImg + source: srcImg + + antialiasing: true + smooth: true + } + + MouseArea { // Full row mouse area triggering onClick + id: ma + anchors.fill: parent + hoverEnabled: true + + onClicked: { root.clicked() } + + onEntered: { + isHover = true + } + + onExited: { + isHover = false + } + } + +} diff --git a/IconTextField.qml b/IconTextField.qml new file mode 100644 index 0000000..a1a8018 --- /dev/null +++ b/IconTextField.qml @@ -0,0 +1,49 @@ +import QtQuick 2.7 + +import QtQuick.Controls 2.13 +import QtQuick.Controls.Styles 1.4 +import QtGraphicalEffects 1.12 +import "." as Widgets +import "../theme" + +// IconTextField integrates a text field and an icon +TextField { + color: Theme.mainTextColor + font.pixelSize: Theme.secondaryTextSize * gcd.themeScale * gcd.themeScale + width: parent.width - 20 + property alias icon: icon_.source + signal clicked + smooth: true + placeholderTextColor: Theme.altTextColor + + + background: Rectangle { + radius: 10 + color: Theme.backgroundMainColor + border.color: Theme.backgroundMainColor + layer.enabled: true + layer.effect: DropShadow { + transparentBorder: true + horizontalOffset: 0 + verticalOffset: 0 + samples: 10 + radius: 8 + color: Theme.dropShadowColor + } + } + + Widgets.Icon { + id: icon_ + + anchors.right: parent.right + anchors.rightMargin: 4 + anchors.verticalCenter: parent.verticalCenter + + height: parent.height-4; + width: parent.height-4; + + iconColor: Theme.altTextColor + backgroundColor: Theme.backgroundMainColor + } + +} diff --git a/InplaceEditText.qml b/InplaceEditText.qml new file mode 100644 index 0000000..6cf68c6 --- /dev/null +++ b/InplaceEditText.qml @@ -0,0 +1,92 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import "../widgets" as Widgets + + + +Item { + id: root + height: lbl.visible ? lbl.height : txt.height + (gcd.os == "android" ? btn.height + 3 : 0) //lbl.height + implicitHeight: height //lbl.height + + property alias text: lbl.text + signal updated + + Text { // DISPLAY THE TEXT IN READONLY MODE + id: lbl + fontSizeMode: Text.HorizontalFit + font.pixelSize: 36 + minimumPixelSize: 8 + horizontalAlignment: Text.AlignHCenter + textFormat: Text.PlainText + anchors.horizontalCenter: parent.horizontalCenter + } + + Image { + id: img + anchors.left: lbl.right + anchors.leftMargin: 3 + source: gcd.assetPath + "fontawesome/solid/edit.svg" + height: 16 + sourceSize.height: 16 + } + + + MouseArea { + anchors.fill: lbl + + + onClicked: { + lbl.visible = img.visible = false + txt.visible = true + if (gcd.os == "android") btn.visible = true + txt.text = lbl.text + txt.selectAll() + txt.focus = true + } + } + + TextEdit { // MAKE IT AN EDITOR WHEN EDITING + id: txt + text: root.text + visible: false + selectByMouse: true + font.pixelSize: lbl.font.pixelSize + anchors.horizontalCenter: parent.horizontalCenter + + + onActiveFocusChanged: { + if (!activeFocus) { + save() + } + } + + Keys.onReturnPressed: { + if (event.modifiers == Qt.NoModifier) { + save() + } + } + + function save() { + root.text = txt.text + txt.visible = btn.visible = false + lbl.visible = img.visible = true + root.updated(txt.text) + } + } + + Widgets.Button { + id: btn + anchors.top: txt.bottom + anchors.topMargin: 3 + anchors.horizontalCenter: parent.horizontalCenter + visible: false + text: qsTr("Update") + + + onClicked: txt.save() + } +} diff --git a/Message.qml b/Message.qml new file mode 100644 index 0000000..d9f6e3c --- /dev/null +++ b/Message.qml @@ -0,0 +1,192 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 + +import "controls" as Awesome + +Item { + id: root + + anchors.left: fromMe ? undefined : parent.left + anchors.right: fromMe ? parent.right : undefined + height: Math.max(imgProfile.height, rectMessageBubble.height) + + property string message + property string rawMessage + property string from + property string handle + property string displayName + property string messageID + property bool fromMe + property bool ackd + property alias timestamp: ts.text + property alias image: imgProfile.source + property string error + + Connections { + target: gcd + + onAcknowledged: function(mid) { + if (mid == messageID) { + root.ackd = true + } + } + + onGroupSendError: function(mid, error) { + if (mid == messageID) { + root.error = error + } + } + } + + + Portrait { + id: imgProfile + anchors.left: parent.left + // TODO: currently unused? + //handle: root.from + visible: !fromMe + //showStatus: false + //highlight: ima.containsMouse + + ToolTip.visible: ima.containsMouse + //: Click to DM + ToolTip.text: qsTr("dm-tooltip") + + MouseArea { + id: ima + anchors.fill: parent + hoverEnabled: overlay.inGroup + + + onClicked: { + gcd.createContact(from) + gcd.broadcast("ResetMessagePane") + theStack.pane = theStack.messagePane + gcd.loadMessagesPane(from) + overlayStack.overlay = overlayStack.chatOverlay + } + } + + } + + Rectangle { // THIS IS JUST A PRETTY MESSAGE-HOLDING RECTANGLE + id: rectMessageBubble + height: colMessageBubble.height + 8 + width: colMessageBubble.width + 6 + color: fromMe ? "#B09CBC" : "#4B3557" + radius: 5 + + // the console will complain constantly about me setting these anchors, but qt only allows margins if they've been set to something + // a kludge to fix this would be to have spacers before/after and set the widths according to the side they're on ^ea + anchors.left: fromMe ? undefined : imgProfile.right //parent.left + anchors.right: fromMe ? parent.right : undefined + anchors.leftMargin: 5 + anchors.rightMargin: 9 + anchors.topMargin: 5 + + + ColumnLayout { + id: colMessageBubble + + + Column { // combine these into one element or else childrenRect won't play nicely + TextEdit { // this is used as a helper to calculate the message box width + id: dummy + visible: false + padding: 6 + leftPadding: 10 + font.pixelSize: gcd.themeScale * 12 + wrapMode: TextEdit.NoWrap + text: lbl.text + textFormat: Text.RichText + } + + TextEdit { // this is the actual text display + id: lbl + text: parse(message, 12, true) + color: "#FFFFFF" + padding: 6 + leftPadding: 10 + font.pixelSize: gcd.themeScale * 12 + selectByMouse: gcd.os != "android" + readOnly: true + width: Math.min(dummy.width, root.parent.width - (imgProfile.visible ? imgProfile.width : 0) - 40) + wrapMode: TextEdit.Wrap + textFormat: Text.RichText + } + } + + RowLayout { + id: rowBottom + anchors.left: parent.left + anchors.right: parent.right + + + Label { // TIMESTAMP + id: ts + color: "#FFFFFF" + font.pixelSize: 10 * gcd.themeScale + anchors.left: parent.left + leftPadding: 10 + } + + Label { // DISPLAY NAME FOR GROUPS + color: "#FFFFFF" + font.pixelSize: 10 * gcd.themeScale + anchors.right: parent.right + text: displayName.length > 12 ? displayName.substr(0,12) + "..." : displayName + visible: !fromMe + ToolTip.text: from + ToolTip.visible: ma2.containsMouse + ToolTip.delay: 200 + + MouseArea { + id: ma2 + anchors.fill: parent + hoverEnabled: true + } + } + + Image { // ACKNOWLEDGEMENT ICON + id: ack + anchors.right: parent.right + source: root.error != "" ? gcd.assetPath + "fontawesome/regular/window-close.svg" : (root.ackd ? gcd.assetPath + "fontawesome/regular/check-circle.svg" : gcd.assetPath + "fontawesome/regular/hourglass.svg") + height: 10 * gcd.themeScale + sourceSize.height: 10 * gcd.themeScale + visible: fromMe + ToolTip.visible: ma.containsMouse + ToolTip.delay: 200 + //: Could not send this message + ToolTip.text: root.error != "" ? qsTr("could-not-send-msg-error") + ":" + root.error : (root.ackd ? qsTr("acknowledged-label") : qsTr("pending-label")) + + + MouseArea { + id: ma + anchors.fill: parent + hoverEnabled: true + } + } + } + } + + TextEdit { + id: copyhelper + visible: false + text: root.rawMessage + } + + MouseArea { + anchors.fill: gcd.os == "android" ? parent : null + + + onPressAndHold: { + copyhelper.selectAll() + copyhelper.copy() + gcd.popup("message copied") + } + } + } +} diff --git a/MyProfile.qml b/MyProfile.qml new file mode 100644 index 0000000..a8937bf --- /dev/null +++ b/MyProfile.qml @@ -0,0 +1,155 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.3 +import QtQuick.Window 2.11 +import QtQuick.Controls 1.4 + +import "." as Widgets +import "../styles" +import "../theme" + +Item { + id: root + anchors.fill: parent + width: parent.width + + height: profile.height + implicitHeight: profile.height + + property string image + property string nick + property string onion + property string tag + property bool dualPane: false + + property real logscale: 4 * Math.log10(gcd.themeScale + 1) + + onDualPaneChanged: { realignProfile() } + + function realignProfile() { + if (dualPane) { + profile.height = 78 * logscale + + portrait.baseWidth = 78 * logscale + portrait.height = 78 * logscale + + portrait.anchors.horizontalCenter = undefined + portrait.anchors.left = profile.left + portrait.anchors.leftMargin = 25 * logscale + + nameRow.anchors.right = undefined + nameRow.anchors.left = portrait.right + + nameRow.anchors.top = undefined + nameRow.anchors.verticalCenter = portrait.verticalCenter + + nameCenter.anchors.horizontalCenter = undefined + nameCenter.anchors.left = nameRow.left + } else { + profile.height = (150 * logscale) + + portrait.baseWidth = 100 * logscale + portrait.height = 100 * logscale + + portrait.anchors.left = undefined + portrait.anchors.leftMargin = undefined + portrait.anchors.horizontalCenter = profile.horizontalCenter + + nameRow.anchors.left = profile.left + nameRow.anchors.right = profile.right + + nameRow.anchors.verticalCenter = undefined + nameRow.anchors.top = portrait.bottom + + nameCenter.anchors.left = undefined + nameCenter.anchors.horizontalCenter = nameRow.horizontalCenter + + } + } + + Rectangle { + + anchors.left: parent.left + anchors.right: parent.right + width: parent.width + id: profile + color: Theme.backgroundMainColor + + Portrait { + id: portrait + + source: root.image + + badgeColor: Theme.portraitProfileBadgeColor + portraitBorderColor: Theme.portraitOnlineBorderColor + portraitColor: Theme.portraitOnlineBackgroundColor + + badgeContent: Image {// Profle Type + id: profiletype + source: tag == "v1-userPassword" ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg" + height: Theme.badgeTextSize * gcd.themeScale + width: height + } + } + + Rectangle { + id: nameRow + height: name.height + onWidthChanged: { name.textResize() } + color: Theme.backgroundMainColor + + Rectangle { + id: nameCenter + width: name.width + addBtn.width + + EllipsisLabel { + id: name + + anchors.right: undefined + anchors.left: undefined + + color: Theme.portraitOnlineTextColor + pixelSize: Theme.usernameSize * gcd.themeScale + weight: Font.Bold + text: nick + extraPadding: addBtn.width + 30 + container: nameRow + } + + Widgets.Button { // Add Button + id: addBtn + + anchors.left: name.right + anchors.top: name.top + + icon: "solid/plus" + + height: name.height + width: height + radius: width * 0.3 + onClicked: { + + } + } + } + } + + } + + Connections { + target: gcd + + onUpdateMyProfile: function(_nick, _onion, _image, _tag) { + nick = _nick + onion = _onion + image = _image + tag = _tag + //realignProfile() + } + + onResetProfile: { realignProfile() } + } +} diff --git a/Portrait.qml b/Portrait.qml new file mode 100644 index 0000000..41728cd --- /dev/null +++ b/Portrait.qml @@ -0,0 +1,71 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import CustomQmlTypes 1.0 +import "../theme" + +Item { + id: imgProfile + implicitWidth: baseWidth + implicitHeight: baseWidth + + property string source + property alias badgeColor: badge.color + + property real logscale: 4 * Math.log10(gcd.themeScale + 1) + property int baseWidth: 78 * logscale + height: 78 * logscale + + property alias portraitBorderColor: mainImage.color + property alias portraitColor: imageInner.color + property alias badgeVisible: badge.visible + property alias badgeContent: badge.content + + + Rectangle { + id: mainImage + //anchors.leftMargin: baseWidth * 0.1 + anchors.horizontalCenter: parent.horizontalCenter + width: baseWidth * 0.8 + height: width + anchors.verticalCenter: parent.verticalCenter + color: Theme.portraitOfflineBorderColor + radius: width / 2 + + Rectangle { + id: imageInner + width: parent.width - 4 + height: width + color: Theme.portraitOfflineBorderColor + radius: width / 2 + anchors.centerIn:parent + + Image { // PROFILE IMAGE + id: img + source: gcd.assetPath + imgProfile.source + anchors.fill: parent + fillMode: Image.PreserveAspectFit + visible: false + } + + Image { // CIRCLE MASK + id: mask + fillMode: Image.PreserveAspectFit + visible: false + source: "qrc:/qml/images/extra/clipcircle.png" + } + + OpacityMask { + anchors.fill: img + source: img + maskSource: mask + } + } + } + + Badge { + id: badge + } +} diff --git a/PortraitRow.qml b/PortraitRow.qml new file mode 100644 index 0000000..ba65e88 --- /dev/null +++ b/PortraitRow.qml @@ -0,0 +1,141 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import CustomQmlTypes 1.0 +import "../styles" +import "../widgets" as Widgets +import "../theme" +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY + id: crItem + anchors.left: parent.left + anchors.right: parent.right + height: 78 * logscale + 3 + implicitHeight: 78 * logscale + 3 //height + + property real logscale: 4 * Math.log10(gcd.themeScale + 1) + property string displayName + property alias image: portrait.source + property string handle + property bool isActive + property bool isHover + property string tag // profile version/type + + property alias badgeColor: portrait.badgeColor + property alias portraitBorderColor: portrait.portraitBorderColor + property alias portraitColor: portrait.portraitColor + property alias nameColor: cn.color + property alias onionColor: onion.color + property alias onionVisible: onion.visible + property alias badgeVisible: portrait.badgeVisible + property alias badgeContent: portrait.badgeContent + property alias hoverEnabled: buttonMA.hoverEnabled + + property alias content: extraMeta.children + + // TODO: should be in ContactRow + property bool blocked + + signal clicked(string handle) + + Rectangle { // CONTACT ENTRY BACKGROUND COLOR + id: crRect + anchors.left: parent.left + anchors.right: parent.right + height: crItem.height + width: parent.width + color: isHover ? Theme.backgroundPaneColor : (isActive ? Theme.backgroundPaneColor : Theme.backgroundMainColor) + + Portrait { + id: portrait + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 25 * logscale + } + + ColumnLayout { + id: portraitMeta + + anchors.left: portrait.right + anchors.right: parent.right + anchors.leftMargin: 4 * logscale + anchors.verticalCenter: parent.verticalCenter + + spacing: 2 * gcd.themeScale + + + EllipsisLabel { // CONTACT NAME + id: cn + pixelSize: Theme.usernameSize * gcd.themeScale + weight: Font.Bold + strikeout: blocked + text: displayName + } + + EllipsisLabel { // Onion + id: onion + text: handle + pixelSize: Theme.secondaryTextSize * gcd.themeScale + strikeout: blocked + } + + onWidthChanged: { + cn.textResize() + onion.textResize() + } + + } + + Column { + id: extraMeta + anchors.left: portraitMeta.right + anchors.verticalCenter: parent.verticalCenter + } + } + + MouseArea { // Full row mouse area triggering onClick + id: buttonMA + anchors.fill: parent + hoverEnabled: true + + onClicked: { crItem.clicked(crItem.handle) } + + onEntered: { + isHover = true + } + + onExited: { + isHover = false + } + } + + Connections { // UPDATE UNREAD MESSAGES COUNTER + target: gcd + + onResetMessagePane: function() { + isActive = false + } + + onUpdateContactBlocked: function(_handle, _blocked) { + if (handle == _handle) { + blocked = _blocked + } + } + + onUpdateContactDisplayName: function(_handle, _displayName) { + if (handle == _handle) { + displayName = _displayName + (blocked == true ? " (blocked)" : "") + } + } + + onUpdateContactPicture: function(_handle, _image) { + if (handle == _handle) { + image = _image + } + } + } +} diff --git a/ProfileList.qml b/ProfileList.qml new file mode 100644 index 0000000..0e8618a --- /dev/null +++ b/ProfileList.qml @@ -0,0 +1,124 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import "../theme" + +ColumnLayout { + id: root + + MouseArea { + anchors.fill: parent + + onClicked: { + forceActiveFocus() + } + } + + Flickable { // Profile List + id: sv + clip: true + Layout.minimumHeight: 100 + Layout.fillHeight: true + Layout.minimumWidth: parent.width + Layout.maximumWidth: parent.width + contentWidth: colContacts.width + contentHeight: colContacts.height + boundsBehavior: Flickable.StopAtBounds + maximumFlickVelocity: 400 + + + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + } + + ColumnLayout { + id: colContacts + width: root.width + spacing: 0 + + Connections { // ADD/REMOVE CONTACT ENTRIES + target: gcd + + onAddProfile: function(handle, displayName, image, tag) { + + // don't add duplicates + for (var i = 0; i < profilesModel.count; i++) { + if (profilesModel.get(i)["_handle"] == handle) { + return + } + } + + // find index for insert (sort by onion) + var index = profilesModel.count + for (var i = 0; i < profilesModel.count; i++) { + if (profilesModel.get(i)["_handle"] > handle) { + index = i + break + } + } + + profilesModel.insert(index, + { + _handle: handle, + _displayName: displayName, + _image: image, + _tag: tag, + _status: 4, + }) + } + + /* + onRemoveProfile: function(handle) { + for(var i = 0; i < profilesModel.count; i++){ + if(profilesModel.get(i)["_handle"] == handle) { + console.log("deleting contact " + profilesModel.get(i)["_handle"]) + profilesModel.remove(i) + return + } + } + }*/ + + onResetProfileList: function() { + profilesModel.clear() + } + } + + ListModel { // Profile OBJECTS ARE STORED HERE ... + id: profilesModel + } + + Repeater { + id: profileList + model: profilesModel // ... AND DISPLAYED HERE + delegate: ProfileRow { + handle: _handle + displayName: _displayName + image: _image + blocked: false + tag: _tag + } + } + + PortraitRow { + handle: "" + displayName: qsTr("add-new-profile-btn") + nameColor: Theme.mainTextColor + image: "/fontawesome/regular/user.svg" + tag: "" + portraitBorderColor: Theme.portraitOnlineBorderColor + portraitColor: Theme.portraitOnlineBackgroundColor + badgeVisible: true + badgeContent: Image { + source: gcd.assetPath + "/fontawesome/solid/plus.svg" + height: Theme.badgeTextSize * gcd.themeScale + width: height + } + badgeColor: Theme.defaultButtonColor + + onClicked: function(handle) { profileAddEditPane.reset(); parentStack.pane = parentStack.addEditProfilePane } + } + } + } +} diff --git a/ProfileRow.qml b/ProfileRow.qml new file mode 100644 index 0000000..c70ee2d --- /dev/null +++ b/ProfileRow.qml @@ -0,0 +1,56 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import CustomQmlTypes 1.0 +import "../styles" +import "../widgets" as Widgets +import "../theme" +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +PortraitRow { + + badgeColor: Theme.portraitProfileBadgeColor + + portraitBorderColor: Theme.portraitOnlineBorderColor + portraitColor: Theme.portraitOnlineBackgroundColor + nameColor: Theme.portraitOnlineTextColor + onionColor: Theme.portraitOnlineTextColor + + badgeContent: Image {// Profle Type + id: profiletype + source: tag == "v1-userPassword" ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg" + height: Theme.badgeTextSize * gcd.themeScale + width: height + } + + Widgets.Button {// Edit BUTTON + id: btnEdit + icon: "solid/user-edit" + + anchors.right: parent.right + + //rectUnread.left + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 1 * gcd.themeScale + anchors.rightMargin: 20 * gcd.themeScale + height: parent.height * 0.75 + + + + onClicked: { + profileAddEditPane.load(handle, displayName, tag) + parentStack.pane = parentStack.addEditProfilePane + } + } + + onClicked: function openClick(handle) { + gcd.broadcast("ResetMessagePane"); + gcd.broadcast("ResetProfile"); + gcd.selectedProfile = handle + gcd.loadProfile(handle) + parentStack.pane = parentStack.profilePane + } +} diff --git a/RadioButton.qml b/RadioButton.qml new file mode 100644 index 0000000..5ce7b21 --- /dev/null +++ b/RadioButton.qml @@ -0,0 +1,27 @@ +import QtQuick 2.7 + +import QtQuick.Controls 2.13 + + +RadioButton { + id: control + + property real size: 12 + spacing: 0 + + indicator: Rectangle { + width: 16 * gcd.themeScale + height: 16 * gcd.themeScale + anchors.verticalCenter: parent.verticalCenter + radius: 9 + border.width: 1 + + Rectangle { + anchors.fill: parent + visible: control.checked + color: "black" + radius: 9 + anchors.margins: 4 + } + } +} diff --git a/ScalingLabel.qml b/ScalingLabel.qml new file mode 100644 index 0000000..e0471fd --- /dev/null +++ b/ScalingLabel.qml @@ -0,0 +1,15 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import QtQuick.Window 2.11 + + +Label { + font.pixelSize: gcd.themeScale * size + wrapMode: Text.WordWrap + color: "#000000" + textFormat: Text.PlainText + property real size: 12 +} diff --git a/Statusbar.qml b/Statusbar.qml new file mode 100644 index 0000000..38e4aaf --- /dev/null +++ b/Statusbar.qml @@ -0,0 +1,186 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.4 + +import "." as Widgets +import "../theme" + +// Statusbar is a app wide 10-25 tall bar that should be place at the bottom of the app that gives network health information +// it changes color and text/icon message based on network health. when netowrk is not healthy it is always in fullsized mode +// when network is health it reduces to a minimal color strip unless mouse overed / clicked to reveal the text/icons +Rectangle { + id: statusbar + + property int status: statusDisconnectedInternet + + readonly property int statusDisconnectedInternet: 0 + readonly property int statusDisconnectedTor: 1 + readonly property int statusConnecting: 2 + readonly property int statusOnline: 3 + + readonly property int openHeight: 25 + readonly property int hideHeight: 10 + + property bool isHover: false + + height: openHeight + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + + Text { + id: statusMessage + opacity: 0 + anchors.right: networkStatus.left + anchors.verticalCenter: parent.verticalCenter + anchors.rightMargin: 5 * gcd.themeScale + + font.pixelSize: Theme.statusTextSize * gcd.themeScale + } + + Icon { + id: networkStatus + opacity: 0 + anchors.right: connectionStatus.left + anchors.verticalCenter: parent.verticalCenter + anchors.rightMargin: 5 * gcd.themeScale + height: 18 + width: 18 + + } + + Icon { + id: connectionStatus + opacity: 0 + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.rightMargin: 10 * gcd.themeScale + height: 18 * gcd.themeScale + width: 18 * gcd.themeScale + } + + function changeStatus() { + if (status == statusDisconnectedInternet) { + statusbar.color = Theme.statusbarDisconnectedInternetColor + statusMessage.color = Theme.statusbarDisconnectedInternetFontColor + networkStatus.iconColor = Theme.statusbarDisconnectedInternetFontColor + networkStatus.source = gcd.assetPath + "core/signal_cellular_off-24px.svg" + connectionStatus.iconColor = Theme.statusbarDisconnectedInternetFontColor + connectionStatus.source = gcd.assetPath + "core/syncing-03.svg" + //: Disconnected from the internet, check your connection + statusMessage.text = qsTr("network-status-disconnected") + show() + } else if (status == statusDisconnectedTor) { + statusbar.color = Theme.statusbarDisconnectedTorColor + statusMessage.color = Theme.statusbarDisconnectedTorFontColor + networkStatus.iconColor = Theme.statusbarDisconnectedTorFontColor + networkStatus.source = gcd.assetPath + "core/signal_cellular_connected_no_internet_4_bar-24px.svg" + connectionStatus.iconColor = Theme.statusbarDisconnectedTorFontColor + connectionStatus.source = gcd.assetPath + "core/syncing-03.svg" + //: Attempting to connect to Tor network + statusMessage.text = qsTr("network-status-attempting-tor") + show() + } else if (status == statusConnecting) { + statusbar.color = Theme.statusbarConnectingColor + statusMessage.color = Theme.statusbarConnectingFontColor + networkStatus.iconColor = Theme.statusbarConnectingFontColor + networkStatus.source = gcd.assetPath + "core/signal_cellular_connected_no_internet_4_bar-24px.svg" + connectionStatus.iconColor = Theme.statusbarConnectingFontColor + connectionStatus.source = gcd.assetPath + "core/syncing-02.svg" + //: Connecting... + statusMessage.text = qsTr("network-status-connecting") + show() + } else { + statusbar.color = Theme.statusbarOnlineColor + statusMessage.color = Theme.statusbarOnlineFontColor + networkStatus.iconColor = Theme.statusbarOnlineFontColor + networkStatus.source = gcd.assetPath + "core/signal_cellular_4_bar-24px.svg" + connectionStatus.iconColor = Theme.statusbarOnlineFontColor + connectionStatus.source = gcd.assetPath + "core/syncing-01.svg" + //: Online + statusMessage.text = qsTr("network-status-online") + hide() + } + } + + MouseArea { + id: ma + anchors.fill: parent + hoverEnabled: true + + SequentialAnimation { + id: showAnim + PropertyAnimation { id: openStatus; target: statusbar; property: "height"; to: openHeight} + ParallelAnimation { + PropertyAnimation { id: showStatus; target: statusMessage; property: "opacity"; to: 1} + PropertyAnimation { id: showNetIcon; target: networkStatus; property: "opacity"; to: 1} + PropertyAnimation { id: showConnIcon; target: connectionStatus; property: "opacity"; to: 1} + } + } + + SequentialAnimation { + id: hideAnim + ParallelAnimation { + PropertyAnimation { id: hideStatus; target: statusMessage; property: "opacity"; to: 0} + PropertyAnimation { id: hideNetIcon; target: networkStatus; property: "opacity"; to: 0} + PropertyAnimation { id: hideConnIcon; target: connectionStatus; property: "opacity"; to: 0} + } + PropertyAnimation { id: closeStatus; target: statusbar; property: "height"; to: hideHeight; duration: 200 } + } + + onEntered: { + isHover = true + show() + } + + + onExited: { + isHover = false + hide() + } + + onPressed: { + isHover = true + show() + } + + onReleased: { + isHover = false + hide() + } + } + + function resetHeight() { + if (isHover || status != statusOnline) { + height = openHeight + } else { + height = hideHeight + } + } + + function show() { + if (isHover || status != statusOnline) { + hideAnim.stop() + showAnim.start() + } + } + + function hide() { + if (!isHover && status == statusOnline) { + showAnim.stop() + hideAnim.start() + } + } + + onStatusChanged: { changeStatus() } + + Component.onCompleted: { resetHeight() } + + Connections { + target: gcd + + onTorStatus: function(code) { + status = code + } + } + +} diff --git a/TextField.qml b/TextField.qml new file mode 100644 index 0000000..333f3bb --- /dev/null +++ b/TextField.qml @@ -0,0 +1,16 @@ +import QtQuick 2.7 + +import QtQuick.Controls 2.13 + + +TextField { + color: "black" + font.pointSize: 10 * gcd.themeScale + width: 100 + + background: Rectangle { + radius: 2 + color: windowItem.cwtch_background_color + border.color: windowItem.cwtch_color + } +} diff --git a/ToggleSwitch.qml b/ToggleSwitch.qml new file mode 100644 index 0000000..4c151aa --- /dev/null +++ b/ToggleSwitch.qml @@ -0,0 +1,32 @@ +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick 2.12 +import "../theme" + +// ToggleSwtch implements a stylized toggle switch. It requires the user create a function called onToggled to +// perform any additional operations needed to define the behavior of the toggle switch +Switch { + property bool isToggled + property var onToggled: function () { console.log("In Superclass") }; + + style: SwitchStyle { + handle: Rectangle { + implicitWidth: 25 + implicitHeight: 25 + radius: width*0.5 + color: Theme.toggleColor + border.color: isToggled ? Theme.toggleOnColor :Theme.toggleOffColor + border.width:5 + } + groove: Rectangle { + implicitWidth: 50 + implicitHeight: 25 + radius: 25*0.5 + color: isToggled ? Theme.toggleOnColor :Theme.toggleOffColor + } + } + + onClicked: function() {isToggled = !isToggled; onToggled()} +} + + diff --git a/Toolbar.qml b/Toolbar.qml new file mode 100644 index 0000000..70d373d --- /dev/null +++ b/Toolbar.qml @@ -0,0 +1,123 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 + +import "../fonts/Twemoji.js" as T +import "." as Widgets +import "../theme" + +Rectangle { // Global Toolbar + id: toolbar + + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + height: 35 * gcd.themeScale + + + Layout.minimumHeight: height + Layout.maximumHeight: height + color: Theme.backgroundMainColor + + property alias leftMenuVisible: btnLeftMenu.visible + property alias backVisible: btnLeftBack.visible + property alias rightMenuVisible: btnRightMenu.visible + + property alias titleWidth: paneArea.width + + + signal leftMenu() + signal back() + signal rightMenu() + + Icon { + id: btnLeftMenu + iconColor: Theme.toolbarIconColor + source: gcd.assetPath + "core/menu-24px.svg" + + + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + width: 30 + height: 30 + + onClicked: { leftMenu() } + } + + Icon { + id: btnLeftBack + iconColor: Theme.toolbarIconColor + source: gcd.assetPath + "core/chevron_left-24px.svg" + + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + width: 30 + height: 30 + + onClicked: { back() } + } + + + + Rectangle { + id: paneArea + anchors.right: parent.right + + EllipsisLabel { + id: paneTitle + + visible: true + anchors.left: undefined + anchors.right: undefined + anchors.horizontalCenter: parent.horizontalCenter + + color: Theme.mainTextColor + pixelSize: Theme.tabSize * gcd.themeScale + weight: Font.Bold + text: "global toolbar" + + //extraPadding: btnRightMenu.width + 10 + + } + + onWidthChanged: { paneTitle.textResize() } + } + + Icon { + id: btnRightMenu + iconColor: Theme.toolbarIconColor + source: gcd.assetPath + "core/more_vert-24px.svg" + + visible: false + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + width: 30 + height: 30 + + onClicked: { rightMenu() } + } + + function setTitle(text, width) { + paneTitle.text = text + paneArea.width = width + paneTitle.textResize() + paneTitle.visible = true + } + + function hideTitle() { + paneTitle.visible = false + } + + + Connections { + target: gcd + + onSetToolbarTitle: function(handle) { + setTitle(handle, theStack.width) + btnRightMenu.visible = true + } + } + +} diff --git a/UnderlineTextField.qml b/UnderlineTextField.qml new file mode 100644 index 0000000..c5d2661 --- /dev/null +++ b/UnderlineTextField.qml @@ -0,0 +1,34 @@ +import QtQuick 2.7 + +import QtQuick.Controls 2.13 +import QtQuick.Controls.Styles 1.4 +import QtGraphicalEffects 1.12 +import "." as Widgets +import "../theme" + +// UnderlineTextField is a textfield styled as just an underline +TextField { + property alias backgroundColor: bg.color + + color: Theme.mainTextColor + font.pixelSize: Theme.secondaryTextSize * gcd.themeScale * gcd.themeScale + signal clicked + smooth: true + placeholderTextColor: Theme.altTextColor + + background: Rectangle { + id: bg + anchors.fill: parent + color: Theme.backgroundMainColor + border.color: color + } + + Rectangle { + id: bottomBar + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + height: 2 + color: Theme.mainTextColor + } +} diff --git a/controls/FlagButton.qml b/controls/FlagButton.qml new file mode 100644 index 0000000..760ed21 --- /dev/null +++ b/controls/FlagButton.qml @@ -0,0 +1,43 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import QtQuick.Window 2.11 +import QtQuick.Controls 1.4 + +Rectangle { + width: img.width + 10 + height: img.height + 5 + property string emoji + color: selected ? windowItem.cwtch_color : windowItem.cwtch_background_color + property bool selected + property string locale + + + Image { + id: img + anchors.centerIn:parent + opacity: 1.0 + + + source: gcd.assetPath + "twemoji/72x72/" + emoji + ".png" + + + MouseArea { + anchors.fill: parent + + onClicked: { + gcd.setLocale(locale) + } + } + } + + Connections { + target: gcd + + onSupplySettings: function(zoom, newLocale) { + selected = newLocale == locale + } + } +} diff --git a/controls/ImageButton.qml b/controls/ImageButton.qml new file mode 100644 index 0000000..b7665c0 --- /dev/null +++ b/controls/ImageButton.qml @@ -0,0 +1,33 @@ +import QtQuick 2.4 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +Item { + id: root + property alias source: img.source + property int size: 24 + property string tooltip: "" + width: size + height: size + signal clicked() + + ToolTip.visible: tooltip != "" && ma.containsMouse + ToolTip.text: tooltip + + Image { + id: img + width: root.size * (ma.pressed ? 0.5 : 0.8) + height: root.size * (ma.pressed ? 0.5 : 0.8) + anchors.topMargin: ma.pressed ? 2 : 0 + anchors.leftMargin: anchors.topMargin + anchors.centerIn: parent + } + + MouseArea { + id: ma + anchors.fill: root + + onClicked: root.clicked() + hoverEnabled: tooltip != "" + } +} diff --git a/controls/Loader.qml b/controls/Loader.qml new file mode 100644 index 0000000..0aa7132 --- /dev/null +++ b/controls/Loader.qml @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** The MIT License (MIT) +** +** Copyright (c) 2014 Ricardo do Valle Flores de Oliveira +** +** $BEGIN_LICENSE:MIT$ +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** $END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +FontLoader { + property string resource + property bool loaded: false + + source: resource + onStatusChanged: (status === FontLoader.Ready) ? loaded = true : loaded = false +} diff --git a/controls/Variables.qml b/controls/Variables.qml new file mode 100644 index 0000000..c0f51db --- /dev/null +++ b/controls/Variables.qml @@ -0,0 +1,580 @@ +/**************************************************************************** +** +** The MIT License (MIT) +** +** Copyright (c) 2014 Ricardo do Valle Flores de Oliveira +** +** $BEGIN_LICENSE:MIT$ +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** $END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +QtObject { + readonly property string fa_adjust : "\uf042" + readonly property string fa_adn : "\uf170" + readonly property string fa_align_center : "\uf037" + readonly property string fa_align_justify : "\uf039" + readonly property string fa_align_left : "\uf036" + readonly property string fa_align_right : "\uf038" + readonly property string fa_ambulance : "\uf0f9" + readonly property string fa_anchor : "\uf13d" + readonly property string fa_android : "\uf17b" + readonly property string fa_angellist : "\uf209" + readonly property string fa_angle_double_down : "\uf103" + readonly property string fa_angle_double_left : "\uf100" + readonly property string fa_angle_double_right : "\uf101" + readonly property string fa_angle_double_up : "\uf102" + readonly property string fa_angle_down : "\uf107" + readonly property string fa_angle_left : "\uf104" + readonly property string fa_angle_right : "\uf105" + readonly property string fa_angle_up : "\uf106" + readonly property string fa_apple : "\uf179" + readonly property string fa_archive : "\uf187" + readonly property string fa_area_chart : "\uf1fe" + readonly property string fa_arrow_circle_down : "\uf0ab" + readonly property string fa_arrow_circle_left : "\uf0a8" + readonly property string fa_arrow_circle_o_down : "\uf01a" + readonly property string fa_arrow_circle_o_left : "\uf190" + readonly property string fa_arrow_circle_o_right : "\uf18e" + readonly property string fa_arrow_circle_o_up : "\uf01b" + readonly property string fa_arrow_circle_right : "\uf0a9" + readonly property string fa_arrow_circle_up : "\uf0aa" + readonly property string fa_arrow_down : "\uf063" + readonly property string fa_arrow_left : "\uf060" + readonly property string fa_arrow_right : "\uf061" + readonly property string fa_arrow_up : "\uf062" + readonly property string fa_arrows : "\uf047" + readonly property string fa_arrows_alt : "\uf0b2" + readonly property string fa_arrows_h : "\uf07e" + readonly property string fa_arrows_v : "\uf07d" + readonly property string fa_asterisk : "\uf069" + readonly property string fa_at : "\uf1fa" + readonly property string fa_automobile : "\uf1b9" + readonly property string fa_backward : "\uf04a" + readonly property string fa_ban : "\uf05e" + readonly property string fa_bank : "\uf19c" + readonly property string fa_bar_chart_o : "\uf080" + readonly property string fa_barcode : "\uf02a" + readonly property string fa_bars : "\uf0c9" + readonly property string fa_beer : "\uf0fc" + readonly property string fa_behance : "\uf1b4" + readonly property string fa_behance_square : "\uf1b5" + readonly property string fa_bell : "\uf0f3" + readonly property string fa_bell_o : "\uf0a2" + readonly property string fa_bell_slash : "\uf1f6" + readonly property string fa_bell_slash_o : "\uf1f7" + readonly property string fa_bicycle : "\uf206" + readonly property string fa_binoculars : "\uf1e5" + readonly property string fa_birthday_cake : "\uf1fd" + readonly property string fa_bitbucket : "\uf171" + readonly property string fa_bitbucket_square : "\uf172" + readonly property string fa_bitcoin : "\uf15a" + readonly property string fa_bold : "\uf032" + readonly property string fa_bolt : "\uf0e7" + readonly property string fa_bomb : "\uf1e2" + readonly property string fa_book : "\uf02d" + readonly property string fa_bookmark : "\uf02e" + readonly property string fa_bookmark_o : "\uf097" + readonly property string fa_briefcase : "\uf0b1" + readonly property string fa_btc : "\uf15a" + readonly property string fa_bug : "\uf188" + readonly property string fa_building : "\uf1ad" + readonly property string fa_building_o : "\uf0f7" + readonly property string fa_bullhorn : "\uf0a1" + readonly property string fa_bullseye : "\uf140" + readonly property string $fa_bus : "\uf207" + readonly property string fa_cab : "\uf1ba" + readonly property string $fa_calculator : "\uf1ec" + readonly property string fa_calendar : "\uf073" + readonly property string fa_calendar_o : "\uf133" + readonly property string fa_camera : "\uf030" + readonly property string fa_camera_retro : "\uf083" + readonly property string fa_car : "\uf1b9" + readonly property string fa_caret_down : "\uf0d7" + readonly property string fa_caret_left : "\uf0d9" + readonly property string fa_caret_right : "\uf0da" + readonly property string fa_caret_square_o_down : "\uf150" + readonly property string fa_caret_square_o_left : "\uf191" + readonly property string fa_caret_square_o_right : "\uf152" + readonly property string fa_caret_square_o_up : "\uf151" + readonly property string fa_caret_up : "\uf0d8" + readonly property string fa_cc : "\uf20a" + readonly property string fa_cc_amex : "\uf1f3" + readonly property string fa_cc_discover : "\uf1f2" + readonly property string fa_cc_mastercard : "\uf1f1" + readonly property string fa_cc_paypal : "\uf1f4" + readonly property string fa_cc_stripe : "\uf1f5" + readonly property string fa_cc_visa : "\uf1f0" + readonly property string fa_certificate : "\uf0a3" + readonly property string fa_chain : "\uf0c1" + readonly property string fa_chain_broken : "\uf127" + readonly property string fa_check : "\uf00c" + readonly property string fa_check_circle : "\uf058" + readonly property string fa_check_circle_o : "\uf05d" + readonly property string fa_check_square : "\uf14a" + readonly property string fa_check_square_o : "\uf046" + readonly property string fa_chevron_circle_down : "\uf13a" + readonly property string fa_chevron_circle_left : "\uf137" + readonly property string fa_chevron_circle_right : "\uf138" + readonly property string fa_chevron_circle_up : "\uf139" + readonly property string fa_chevron_down : "\uf078" + readonly property string fa_chevron_left : "\uf053" + readonly property string fa_chevron_right : "\uf054" + readonly property string fa_chevron_up : "\uf077" + readonly property string fa_child : "\uf1ae" + readonly property string fa_circle : "\uf111" + readonly property string fa_circle_o : "\uf10c" + readonly property string fa_circle_o_notch : "\uf1ce" + readonly property string fa_circle_thin : "\uf1db" + readonly property string fa_clipboard : "\uf0ea" + readonly property string fa_clock_o : "\uf017" + readonly property string fa_cloud : "\uf0c2" + readonly property string fa_cloud_download : "\uf0ed" + readonly property string fa_cloud_upload : "\uf0ee" + readonly property string fa_cny : "\uf157" + readonly property string fa_code : "\uf121" + readonly property string fa_code_fork : "\uf126" + readonly property string fa_codepen : "\uf1cb" + readonly property string fa_coffee : "\uf0f4" + readonly property string fa_cog : "\uf013" + readonly property string fa_cogs : "\uf085" + readonly property string fa_columns : "\uf0db" + readonly property string fa_comment : "\uf075" + readonly property string fa_comment_o : "\uf0e5" + readonly property string fa_comments : "\uf086" + readonly property string fa_comments_o : "\uf0e6" + readonly property string fa_compass : "\uf14e" + readonly property string fa_compress : "\uf066" + readonly property string fa_copy : "\uf0c5" + readonly property string fa_copyright : "\uf1f9" + readonly property string fa_credit_card : "\uf09d" + readonly property string fa_crop : "\uf125" + readonly property string fa_crosshairs : "\uf05b" + readonly property string fa_css3 : "\uf13c" + readonly property string fa_cube : "\uf1b2" + readonly property string fa_cubes : "\uf1b3" + readonly property string fa_cut : "\uf0c4" + readonly property string fa_cutlery : "\uf0f5" + readonly property string fa_dashboard : "\uf0e4" + readonly property string fa_database : "\uf1c0" + readonly property string fa_dedent : "\uf03b" + readonly property string fa_delicious : "\uf1a5" + readonly property string fa_desktop : "\uf108" + readonly property string fa_deviantart : "\uf1bd" + readonly property string fa_digg : "\uf1a6" + readonly property string fa_dollar : "\uf155" + readonly property string fa_dot_circle_o : "\uf192" + readonly property string fa_download : "\uf019" + readonly property string fa_dribbble : "\uf17d" + readonly property string fa_dropbox : "\uf16b" + readonly property string fa_drupal : "\uf1a9" + readonly property string fa_edit : "\uf044" + readonly property string fa_eject : "\uf052" + readonly property string fa_ellipsis_h : "\uf141" + readonly property string fa_ellipsis_v : "\uf142" + readonly property string fa_empire : "\uf1d1" + readonly property string fa_envelope : "\uf0e0" + readonly property string fa_envelope_o : "\uf003" + readonly property string fa_envelope_square : "\uf199" + readonly property string fa_eraser : "\uf12d" + readonly property string fa_eur : "\uf153" + readonly property string fa_euro : "\uf153" + readonly property string fa_exchange : "\uf0ec" + readonly property string fa_exclamation : "\uf12a" + readonly property string fa_exclamation_circle : "\uf06a" + readonly property string fa_exclamation_triangle : "\uf071" + readonly property string fa_expand : "\uf065" + readonly property string fa_external_link : "\uf08e" + readonly property string fa_external_link_square : "\uf14c" + readonly property string fa_eye : "\uf06e" + readonly property string fa_eye_slash : "\uf070" + readonly property string fa_eyedropper : "\uf1fb" + readonly property string fa_facebook : "\uf09a" + readonly property string fa_facebook_square : "\uf082" + readonly property string fa_fast_backward : "\uf049" + readonly property string fa_fast_forward : "\uf050" + readonly property string fa_fax : "\uf1ac" + readonly property string fa_female : "\uf182" + readonly property string fa_fighter_jet : "\uf0fb" + readonly property string fa_file : "\uf15b" + readonly property string fa_file_archive_o : "\uf1c6" + readonly property string fa_file_audio_o : "\uf1c7" + readonly property string fa_file_code_o : "\uf1c9" + readonly property string fa_file_excel_o : "\uf1c3" + readonly property string fa_file_image_o : "\uf1c5" + readonly property string fa_file_movie_o : "\uf1c8" + readonly property string fa_file_o : "\uf016" + readonly property string fa_file_pdf_o : "\uf1c1" + readonly property string fa_file_photo_o : "\uf1c5" + readonly property string fa_file_picture_o : "\uf1c5" + readonly property string fa_file_powerpoint_o : "\uf1c4" + readonly property string fa_file_sound_o : "\uf1c7" + readonly property string fa_file_text : "\uf15c" + readonly property string fa_file_text_o : "\uf0f6" + readonly property string fa_file_video_o : "\uf1c8" + readonly property string fa_file_word_o : "\uf1c2" + readonly property string fa_file_zip_o : "\uf1c6" + readonly property string fa_files_o : "\uf0c5" + readonly property string fa_film : "\uf008" + readonly property string fa_filter : "\uf0b0" + readonly property string fa_fire : "\uf06d" + readonly property string fa_fire_extinguisher : "\uf134" + readonly property string fa_flag : "\uf024" + readonly property string fa_flag_checkered : "\uf11e" + readonly property string fa_flag_o : "\uf11d" + readonly property string fa_flash : "\uf0e7" + readonly property string fa_flask : "\uf0c3" + readonly property string fa_flickr : "\uf16e" + readonly property string fa_floppy_o : "\uf0c7" + readonly property string fa_folder : "\uf07b" + readonly property string fa_folder_o : "\uf114" + readonly property string fa_folder_open : "\uf07c" + readonly property string fa_folder_open_o : "\uf115" + readonly property string fa_font : "\uf031" + readonly property string fa_forward : "\uf04e" + readonly property string fa_foursquare : "\uf180" + readonly property string fa_frown_o : "\uf119" + readonly property string fa_futbol_o : "\uf1e3" + readonly property string fa_gamepad : "\uf11b" + readonly property string fa_gavel : "\uf0e3" + readonly property string fa_gbp : "\uf154" + readonly property string fa_ge : "\uf1d1" + readonly property string fa_gear : "\uf013" + readonly property string fa_gears : "\uf085" + readonly property string fa_gift : "\uf06b" + readonly property string fa_git : "\uf1d3" + readonly property string fa_git_square : "\uf1d2" + readonly property string fa_github : "\uf09b" + readonly property string fa_github_alt : "\uf113" + readonly property string fa_github_square : "\uf092" + readonly property string fa_gittip : "\uf184" + readonly property string fa_glass : "\uf000" + readonly property string fa_globe : "\uf0ac" + readonly property string fa_google : "\uf1a0" + readonly property string fa_google_plus : "\uf0d5" + readonly property string fa_google_plus_square : "\uf0d4" + readonly property string fa_google_wallet : "\uf1ee" + readonly property string fa_graduation_cap : "\uf19d" + readonly property string fa_group : "\uf0c0" + readonly property string fa_h_square : "\uf0fd" + readonly property string fa_hacker_news : "\uf1d4" + readonly property string fa_hand_o_down : "\uf0a7" + readonly property string fa_hand_o_left : "\uf0a5" + readonly property string fa_hand_o_right : "\uf0a4" + readonly property string fa_hand_o_up : "\uf0a6" + readonly property string fa_hdd_o : "\uf0a0" + readonly property string fa_header : "\uf1dc" + readonly property string fa_headphones : "\uf025" + readonly property string fa_heart : "\uf004" + readonly property string fa_heart_o : "\uf08a" + readonly property string fa_history : "\uf1da" + readonly property string fa_home : "\uf015" + readonly property string fa_hospital_o : "\uf0f8" + readonly property string fa_html5 : "\uf13b" + readonly property string fa_ils : "\uf20b" + readonly property string fa_image : "\uf03e" + readonly property string fa_inbox : "\uf01c" + readonly property string fa_indent : "\uf03c" + readonly property string fa_info : "\uf129" + readonly property string fa_info_circle : "\uf05a" + readonly property string fa_inr : "\uf156" + readonly property string fa_instagram : "\uf16d" + readonly property string fa_institution : "\uf19c" + readonly property string fa_ioxhost : "\uf208" + readonly property string fa_italic : "\uf033" + readonly property string fa_joomla : "\uf1aa" + readonly property string fa_jpy : "\uf157" + readonly property string fa_jsfiddle : "\uf1cc" + readonly property string fa_key : "\uf084" + readonly property string fa_keyboard_o : "\uf11c" + readonly property string fa_krw : "\uf159" + readonly property string fa_language : "\uf1ab" + readonly property string fa_laptop : "\uf109" + readonly property string fa_lastfm : "\uf202" + readonly property string fa_lastfm_square : "\uf203" + readonly property string fa_leaf : "\uf06c" + readonly property string fa_legal : "\uf0e3" + readonly property string fa_lemon_o : "\uf094" + readonly property string fa_level_down : "\uf149" + readonly property string fa_level_up : "\uf148" + readonly property string fa_life_bouy : "\uf1cd" + readonly property string fa_life_buoy : "\uf1cd" + readonly property string fa_life_ring : "\uf1cd" + readonly property string fa_life_saver : "\uf1cd" + readonly property string fa_lightbulb_o : "\uf0eb" + readonly property string fa_line_chart : "\uf201" + readonly property string fa_link : "\uf0c1" + readonly property string fa_linkedin : "\uf0e1" + readonly property string fa_linkedin_square : "\uf08c" + readonly property string fa_linux : "\uf17c" + readonly property string fa_list : "\uf03a" + readonly property string fa_list_alt : "\uf022" + readonly property string fa_list_ol : "\uf0cb" + readonly property string fa_list_ul : "\uf0ca" + readonly property string fa_location_arrow : "\uf124" + readonly property string fa_lock : "\uf023" + readonly property string fa_long_arrow_down : "\uf175" + readonly property string fa_long_arrow_left : "\uf177" + readonly property string fa_long_arrow_right : "\uf178" + readonly property string fa_long_arrow_up : "\uf176" + readonly property string fa_magic : "\uf0d0" + readonly property string fa_magnet : "\uf076" + readonly property string fa_mail_forward : "\uf064" + readonly property string fa_mail_reply : "\uf112" + readonly property string fa_mail_reply_all : "\uf122" + readonly property string fa_male : "\uf183" + readonly property string fa_map_marker : "\uf041" + readonly property string fa_maxcdn : "\uf136" + readonly property string fa_meanpath : "\uf20c" + readonly property string fa_medkit : "\uf0fa" + readonly property string fa_meh_o : "\uf11a" + readonly property string fa_microphone : "\uf130" + readonly property string fa_microphone_slash : "\uf131" + readonly property string fa_minus : "\uf068" + readonly property string fa_minus_circle : "\uf056" + readonly property string fa_minus_square : "\uf146" + readonly property string fa_minus_square_o : "\uf147" + readonly property string fa_mobile : "\uf10b" + readonly property string fa_mobile_phone : "\uf10b" + readonly property string fa_money : "\uf0d6" + readonly property string fa_moon_o : "\uf186" + readonly property string fa_mortar_board : "\uf19d" + readonly property string fa_music : "\uf001" + readonly property string fa_navicon : "\uf0c9" + readonly property string fa_newspaper_o : "\uf1ea" + readonly property string fa_openid : "\uf19b" + readonly property string fa_outdent : "\uf03b" + readonly property string fa_pagelines : "\uf18c" + readonly property string fa_paint_brush : "\uf1fc" + readonly property string fa_paper_plane : "\uf1d8" + readonly property string fa_paper_plane_o : "\uf1d9" + readonly property string fa_paperclip : "\uf0c6" + readonly property string fa_paragraph : "\uf1dd" + readonly property string fa_paste : "\uf0ea" + readonly property string fa_pause : "\uf04c" + readonly property string fa_paw : "\uf1b0" + readonly property string fa_paypal : "\uf1ed" + readonly property string fa_pencil : "\uf040" + readonly property string fa_pencil_square : "\uf14b" + readonly property string fa_pencil_square_o : "\uf044" + readonly property string fa_phone : "\uf095" + readonly property string fa_phone_square : "\uf098" + readonly property string fa_photo : "\uf03e" + readonly property string fa_picture_o : "\uf03e" + readonly property string fa_pie_chart : "\uf200" + readonly property string fa_pied_piper : "\uf1a7" + readonly property string fa_pied_piper_alt : "\uf1a8" + readonly property string fa_pinterest : "\uf0d2" + readonly property string fa_pinterest_square : "\uf0d3" + readonly property string fa_plane : "\uf072" + readonly property string fa_play : "\uf04b" + readonly property string fa_play_circle : "\uf144" + readonly property string fa_play_circle_o : "\uf01d" + readonly property string fa_plug : "\uf1e6" + readonly property string fa_plus : "\uf067" + readonly property string fa_plus_circle : "\uf055" + readonly property string fa_plus_square : "\uf0fe" + readonly property string fa_plus_square_o : "\uf196" + readonly property string fa_power_off : "\uf011" + readonly property string fa_print : "\uf02f" + readonly property string fa_puzzle_piece : "\uf12e" + readonly property string fa_qq : "\uf1d6" + readonly property string fa_qrcode : "\uf029" + readonly property string fa_question : "\uf128" + readonly property string fa_question_circle : "\uf059" + readonly property string fa_quote_left : "\uf10d" + readonly property string fa_quote_right : "\uf10e" + readonly property string fa_ra : "\uf1d0" + readonly property string fa_random : "\uf074" + readonly property string fa_rebel : "\uf1d0" + readonly property string fa_recycle : "\uf1b8" + readonly property string fa_reddit : "\uf1a1" + readonly property string fa_reddit_square : "\uf1a2" + readonly property string fa_refresh : "\uf021" + readonly property string fa_remove : "\uf00d" + readonly property string fa_renren : "\uf18b" + readonly property string fa_reorder : "\uf0c9" + readonly property string fa_repeat : "\uf01e" + readonly property string fa_reply : "\uf112" + readonly property string fa_reply_all : "\uf122" + readonly property string fa_retweet : "\uf079" + readonly property string fa_rmb : "\uf157" + readonly property string fa_road : "\uf018" + readonly property string fa_rocket : "\uf135" + readonly property string fa_rotate_left : "\uf0e2" + readonly property string fa_rotate_right : "\uf01e" + readonly property string fa_rouble : "\uf158" + readonly property string fa_rss : "\uf09e" + readonly property string fa_rss_square : "\uf143" + readonly property string fa_rub : "\uf158" + readonly property string fa_ruble : "\uf158" + readonly property string fa_rupee : "\uf156" + readonly property string fa_save : "\uf0c7" + readonly property string fa_scissors : "\uf0c4" + readonly property string fa_search : "\uf002" + readonly property string fa_search_minus : "\uf010" + readonly property string fa_search_plus : "\uf00e" + readonly property string fa_send : "\uf1d8" + readonly property string fa_send_o : "\uf1d9" + readonly property string fa_share : "\uf064" + readonly property string fa_share_alt : "\uf1e0" + readonly property string fa_share_alt_square : "\uf1e1" + readonly property string fa_share_square : "\uf14d" + readonly property string fa_share_square_o : "\uf045" + readonly property string fa_shekel : "\uf20b" + readonly property string fa_sheqel : "\uf20b" + readonly property string fa_shield : "\uf132" + readonly property string fa_shopping_cart : "\uf07a" + readonly property string fa_sign_in : "\uf090" + readonly property string fa_sign_out : "\uf08b" + readonly property string fa_signal : "\uf012" + readonly property string fa_sitemap : "\uf0e8" + readonly property string fa_skype : "\uf17e" + readonly property string fa_slack : "\uf198" + readonly property string fa_sliders : "\uf1de" + readonly property string fa_slideshare : "\uf1e7" + readonly property string fa_smile_o : "\uf118" + readonly property string fa_soccer_ball_o : "\uf1e3" + readonly property string fa_sort : "\uf0dc" + readonly property string fa_sort_alpha_asc : "\uf15d" + readonly property string fa_sort_alpha_desc : "\uf15e" + readonly property string fa_sort_amount_asc : "\uf160" + readonly property string fa_sort_amount_desc : "\uf161" + readonly property string fa_sort_asc : "\uf0de" + readonly property string fa_sort_desc : "\uf0dd" + readonly property string fa_sort_down : "\uf0dd" + readonly property string fa_sort_numeric_asc : "\uf162" + readonly property string fa_sort_numeric_desc : "\uf163" + readonly property string fa_sort_up : "\uf0de" + readonly property string fa_soundcloud : "\uf1be" + readonly property string fa_space_shuttle : "\uf197" + readonly property string fa_spinner : "\uf110" + readonly property string fa_spoon : "\uf1b1" + readonly property string fa_spotify : "\uf1bc" + readonly property string fa_square : "\uf0c8" + readonly property string fa_square_o : "\uf096" + readonly property string fa_stack_exchange : "\uf18d" + readonly property string fa_stack_overflow : "\uf16c" + readonly property string fa_star : "\uf005" + readonly property string fa_star_half : "\uf089" + readonly property string fa_star_half_empty : "\uf123" + readonly property string fa_star_half_full : "\uf123" + readonly property string fa_star_half_o : "\uf123" + readonly property string fa_star_o : "\uf006" + readonly property string fa_steam : "\uf1b6" + readonly property string fa_steam_square : "\uf1b7" + readonly property string fa_step_backward : "\uf048" + readonly property string fa_step_forward : "\uf051" + readonly property string fa_stethoscope : "\uf0f1" + readonly property string fa_stop : "\uf04d" + readonly property string fa_strikethrough : "\uf0cc" + readonly property string fa_stumbleupon : "\uf1a4" + readonly property string fa_stumbleupon_circle : "\uf1a3" + readonly property string fa_subscript : "\uf12c" + readonly property string fa_suitcase : "\uf0f2" + readonly property string fa_sun_o : "\uf185" + readonly property string fa_superscript : "\uf12b" + readonly property string fa_support : "\uf1cd" + readonly property string fa_table : "\uf0ce" + readonly property string fa_tablet : "\uf10a" + readonly property string fa_tachometer : "\uf0e4" + readonly property string fa_tag : "\uf02b" + readonly property string fa_tags : "\uf02c" + readonly property string fa_tasks : "\uf0ae" + readonly property string fa_taxi : "\uf1ba" + readonly property string fa_tencent_weibo : "\uf1d5" + readonly property string fa_terminal : "\uf120" + readonly property string fa_text_height : "\uf034" + readonly property string fa_text_width : "\uf035" + readonly property string fa_th : "\uf00a" + readonly property string fa_th_large : "\uf009" + readonly property string fa_th_list : "\uf00b" + readonly property string fa_thumb_tack : "\uf08d" + readonly property string fa_thumbs_down : "\uf165" + readonly property string fa_thumbs_o_down : "\uf088" + readonly property string fa_thumbs_o_up : "\uf087" + readonly property string fa_thumbs_up : "\uf164" + readonly property string fa_ticket : "\uf145" + readonly property string fa_times : "\uf00d" + readonly property string fa_times_circle : "\uf057" + readonly property string fa_times_circle_o : "\uf05c" + readonly property string fa_tint : "\uf043" + readonly property string fa_toggle_down : "\uf150" + readonly property string fa_toggle_left : "\uf191" + readonly property string fa_toggle_off : "\uf204" + readonly property string fa_toggle_on : "\uf205" + readonly property string fa_toggle_right : "\uf152" + readonly property string fa_toggle_up : "\uf151" + readonly property string fa_trash : "\uf1f8" + readonly property string fa_trash_o : "\uf014" + readonly property string fa_tree : "\uf1bb" + readonly property string fa_trello : "\uf181" + readonly property string fa_trophy : "\uf091" + readonly property string fa_truck : "\uf0d1" + readonly property string fa_try : "\uf195" + readonly property string fa_tty : "\uf1e4" + readonly property string fa_tumblr : "\uf173" + readonly property string fa_tumblr_square : "\uf174" + readonly property string fa_turkish_lira : "\uf195" + readonly property string fa_twitch : "\uf1e8" + readonly property string fa_twitter : "\uf099" + readonly property string fa_twitter_square : "\uf081" + readonly property string fa_umbrella : "\uf0e9" + readonly property string fa_underline : "\uf0cd" + readonly property string fa_undo : "\uf0e2" + readonly property string fa_university : "\uf19c" + readonly property string fa_unlink : "\uf127" + readonly property string fa_unlock : "\uf09c" + readonly property string fa_unlock_alt : "\uf13e" + readonly property string fa_unsorted : "\uf0dc" + readonly property string fa_upload : "\uf093" + readonly property string fa_usd : "\uf155" + readonly property string fa_user : "\uf007" + readonly property string fa_user_md : "\uf0f0" + readonly property string fa_users : "\uf0c0" + readonly property string fa_video_camera : "\uf03d" + readonly property string fa_vimeo_square : "\uf194" + readonly property string fa_vine : "\uf1ca" + readonly property string fa_vk : "\uf189" + readonly property string fa_volume_down : "\uf027" + readonly property string fa_volume_off : "\uf026" + readonly property string fa_volume_up : "\uf028" + readonly property string fa_warning : "\uf071" + readonly property string fa_wechat : "\uf1d7" + readonly property string fa_weibo : "\uf18a" + readonly property string fa_weixin : "\uf1d7" + readonly property string fa_wheelchair : "\uf193" + readonly property string fa_wifi : "\uf1eb" + readonly property string fa_windows : "\uf17a" + readonly property string fa_won : "\uf159" + readonly property string fa_wordpress : "\uf19a" + readonly property string fa_wrench : "\uf0ad" + readonly property string fa_xing : "\uf168" + readonly property string fa_xing_square : "\uf169" + readonly property string fa_yahoo : "\uf19e" + readonly property string fa_yelp : "\uf1e9" + readonly property string fa_yen : "\uf157" + readonly property string fa_youtube : "\uf167" + readonly property string fa_youtube_play : "\uf16a" + readonly property string fa_youtube_square : "\uf166" +} diff --git a/styles/CwtchComboBoxStyle.qml b/styles/CwtchComboBoxStyle.qml new file mode 100644 index 0000000..b4536eb --- /dev/null +++ b/styles/CwtchComboBoxStyle.qml @@ -0,0 +1,7 @@ +import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 + + +ComboBoxStyle { + textColor: "#000" +} diff --git a/styles/CwtchExpandingButton.qml b/styles/CwtchExpandingButton.qml new file mode 100644 index 0000000..76e71d2 --- /dev/null +++ b/styles/CwtchExpandingButton.qml @@ -0,0 +1,21 @@ +import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 + +ButtonStyle { + background: Rectangle { + width:25 + height:25 + color: windowItem.cwtch_dark_color + border.color: windowItem.cwtch_color + } + + label: Text { + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: "Monospace" + font.pointSize: 8 + color: windowItem.cwtch_background_color + text: control.text + } +} diff --git a/styles/CwtchProgress.qml b/styles/CwtchProgress.qml new file mode 100644 index 0000000..711227c --- /dev/null +++ b/styles/CwtchProgress.qml @@ -0,0 +1,39 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.3 +import QtQuick.Window 2.11 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + + +Rectangle { + id: pb + border.color: "#FFFFFF" + border.width: 1 + + color: "#D2C0DD" + property bool running + + // Indeterminate animation by animating alternating stripes: + Item { + anchors.fill: parent + anchors.margins: 1 + visible: control.indeterminate + clip: true + Row { + Repeater { + Rectangle { + color: index % 2 ? "#D2C0DD" : "#b29dbe" + width: 20 ; height: control.height + } + model: control.width / 20 + 2 + } + XAnimator on x { + from: 0 ; to: -40 + loops: Animation.Infinite + running: pb.running + } + } + } +} diff --git a/styles/CwtchTextAreaStyle.qml b/styles/CwtchTextAreaStyle.qml new file mode 100644 index 0000000..4e0e584 --- /dev/null +++ b/styles/CwtchTextAreaStyle.qml @@ -0,0 +1,8 @@ +import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 + + +TextAreaStyle { + textColor: "black" + backgroundColor: windowItem.cwtch_background_color +} diff --git a/styles/CwtchTextFieldStyle.qml b/styles/CwtchTextFieldStyle.qml new file mode 100644 index 0000000..9175e21 --- /dev/null +++ b/styles/CwtchTextFieldStyle.qml @@ -0,0 +1,15 @@ +import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 + +TextFieldStyle { + id: root + textColor: "black" + font.pointSize: 10 * gcd.themeScale + property int width: parent.width + + background: Rectangle { + radius: 2 + color: windowItem.cwtch_background_color + border.color: windowItem.cwtch_color + } +} diff --git a/theme/CwtchDark.qml b/theme/CwtchDark.qml new file mode 100644 index 0000000..35f0442 --- /dev/null +++ b/theme/CwtchDark.qml @@ -0,0 +1,51 @@ + +ThemeType { + readonly property color darkGrayPurple: "#281831" + readonly property color deepPurple: "#422850" + readonly property color mauvePurple: "#8E64A5" + readonly property color purple: "#DFB9DE" + readonly property color whitePurple: "#FFFDFF" + readonly property color softPurple: "#FDF3FC" + readonly property color pink: "#E85DA1" + readonly property color hotPink: "#D01972" + + backgroundMainColor: darkGrayPurple + backgroundPaneColor: deepPurple + + mainTextColor: purple + altTextColor: mauvePurple + defaultButtonColor: mauvePurple + defaultButtonActiveColor: pink + defaultButtonTextColor: whitePurple + + portraitOnlineBorderColor: whitePurple + portraitOnlineBackgroundColor: darkGrayPurple + portraitOnlineTextColor: whitePurple + portraitConnectingBorderColor: mauvePurple + portraitConnectingBackgroundColor: darkGrayPurple + portraitConnectingTextColor: whitePurple + portraitOfflineBorderColor: deepPurple + portraitOfflineBackgroundColor: darkGrayPurple + portraitOfflineTextColor: softPurple + + portraitContactBadgeColor: hotPink + portraitContactBadgeTextColor: whitePurple + portraitProfileBadgeColor: mauvePurple + dropShadowColor: mauvePurple + dropShadowPaneColor: darkGrayPurple + + toggleColor: darkGrayPurple + toggleOnColor: whitePurple + toggleOffColor: mauvePurple + + toolbarIconColor: whitePurple + + statusbarDisconnectedInternetColor: whitePurple + statusbarDisconnectedInternetFontColor: deepPurple + statusbarDisconnectedTorColor: darkGrayPurple + statusbarDisconnectedTorFontColor: whitePurple + statusbarConnectingColor: deepPurple + statusbarConnectingFontColor: whitePurple + statusbarOnlineColor: mauvePurple + statusbarOnlineFontColor: whitePurple +} diff --git a/theme/CwtchLight.qml b/theme/CwtchLight.qml new file mode 100644 index 0000000..aac033e --- /dev/null +++ b/theme/CwtchLight.qml @@ -0,0 +1,51 @@ + +ThemeType { + readonly property color whitePurple: "#FFFDFF" + readonly property color softPurple: "#FDF3FC" + readonly property color purple: "#DFB9DE" + readonly property color brightPurple: "#760388" + readonly property color darkPurple: "#350052" + readonly property color greyPurple: "#775F84" + readonly property color pink: "#E85DA1" + readonly property color hotPink: "#D01972" + + backgroundMainColor: whitePurple + backgroundPaneColor: softPurple + + mainTextColor: darkPurple + altTextColor: purple + defaultButtonColor: hotPink + defaultButtonActiveColor: pink + defaultButtonTextColor: whitePurple + + portraitOnlineBorderColor: darkPurple + portraitOnlineBackgroundColor: darkPurple + portraitOnlineTextColor: darkPurple + portraitConnectingBorderColor: greyPurple + portraitConnectingBackgroundColor: greyPurple + portraitConnectingTextColor: greyPurple + portraitOfflineBorderColor: purple + portraitOfflineBackgroundColor: purple + portraitOfflineTextColor: purple + + portraitContactBadgeColor: hotPink + portraitContactBadgeTextColor: whitePurple + portraitProfileBadgeColor: brightPurple + dropShadowColor: purple + dropShadowPaneColor: purple + + toggleColor: whitePurple + toggleOnColor: hotPink + toggleOffColor: purple + + toolbarIconColor: darkPurple + + statusbarDisconnectedInternetColor: softPurple + statusbarDisconnectedInternetFontColor: darkPurple + statusbarDisconnectedTorColor: purple + statusbarDisconnectedTorFontColor: darkPurple + statusbarConnectingColor: greyPurple + statusbarConnectingFontColor: whitePurple + statusbarOnlineColor: darkPurple + statusbarOnlineFontColor: whitePurple +} diff --git a/theme/Theme.qml b/theme/Theme.qml new file mode 100644 index 0000000..7570b24 --- /dev/null +++ b/theme/Theme.qml @@ -0,0 +1,61 @@ +pragma Singleton + +import QtQuick 2.0 + +Item { + readonly property color backgroundMainColor: theme.backgroundMainColor + readonly property color backgroundPaneColor: theme.backgroundPaneColor + + readonly property color mainTextColor: theme.mainTextColor + readonly property color altTextColor: theme.altTextColor + readonly property color defaultButtonColor: theme.defaultButtonColor + readonly property color defaultButtonActiveColor: theme.defaultButtonActiveColor + readonly property color defaultButtonTextColor: theme.defaultButtonTextColor + + readonly property color dropShadowColor: theme.dropShadowColor + readonly property color dropShadowPaneColor: theme.dropShadowPaneColor + + readonly property color portraitOnlineBorderColor: theme.portraitOnlineBorderColor + readonly property color portraitOnlineBackgroundColor: theme.portraitOnlineBackgroundColor + readonly property color portraitOnlineTextColor: theme.portraitOnlineTextColor + readonly property color portraitConnectingBorderColor: theme.portraitConnectingBorderColor + readonly property color portraitConnectingBackgroundColor: theme.portraitConnectingBackgroundColor + readonly property color portraitConnectingTextColor: theme.portraitConnectingTextColor + readonly property color portraitOfflineBorderColor: theme.portraitOfflineBorderColor + readonly property color portraitOfflineBackgroundColor: theme.portraitOfflineBackgroundColor + readonly property color portraitOfflineTextColor: theme.portraitOfflineTextColor + + readonly property color portraitContactBadgeColor: theme.portraitContactBadgeColor + readonly property color portraitContactBadgeTextColor: theme.portraitContactBadgeTextColor + readonly property color portraitProfileBadgeColor: theme.portraitProfileBadgeColor + + readonly property color toggleColor: theme.toggleColor + readonly property color toggleOffColor: theme.toggleOffColor + readonly property color toggleOnColor: theme.toggleOnColor + + readonly property color toolbarIconColor: theme.toolbarIconColor + + readonly property color statusbarDisconnectedInternetColor: theme.statusbarDisconnectedInternetColor + readonly property color statusbarDisconnectedInternetFontColor: theme.statusbarDisconnectedInternetFontColor + readonly property color statusbarDisconnectedTorFontColor: theme.statusbarDisconnectedTorFontColor + readonly property color statusbarDisconnectedTorColor: theme.statusbarDisconnectedTorColor + readonly property color statusbarConnectingColor: theme.statusbarConnectingColor + readonly property color statusbarConnectingFontColor: theme.statusbarConnectingFontColor + readonly property color statusbarOnlineColor: theme.statusbarOnlineColor + readonly property color statusbarOnlineFontColor: theme.statusbarOnlineFontColor + + readonly property int headerSize: 50 + readonly property int usernameSize: 30 + readonly property int tabSize: 25 + readonly property int chatSize: 20 + readonly property int secondaryTextSize: 20 // address + readonly property int chatMetaTextSize: 15 + readonly property int badgeTextSize: 12 + readonly property int statusTextSize: 12 + + readonly property int sidePaneMinSize: 700 + readonly property int doublePaneMinSize: 1000 + + property ThemeType theme: CwtchLight { } + +} diff --git a/theme/ThemeType.qml b/theme/ThemeType.qml new file mode 100644 index 0000000..55dc9c2 --- /dev/null +++ b/theme/ThemeType.qml @@ -0,0 +1,46 @@ +import QtQuick 2.0 + +QtObject { + property color backgroundMainColor: "red" + property color backgroundPaneColor: "red" + + property color mainTextColor: "red" + property color altTextColor: "red" + property color defaultButtonColor: "red" + property color defaultButtonActiveColor: "red" + property color defaultButtonTextColor: "red" + + property color portraitOnlineBorderColor: "red" + property color portraitOnlineBackgroundColor: "red" + property color portraitOnlineTextColor: "red" + property color portraitConnectingBorderColor: "red" + property color portraitConnectingBackgroundColor: "red" + property color portraitConnectingTextColor: "red" + property color portraitOfflineBorderColor: "red" + property color portraitOfflineBackgroundColor: "red" + property color portraitOfflineTextColor: "red" + + property color portraitContactBadgeColor: "red" + property color portraitContactBadgeTextColor: "red" + property color portraitProfileBadgeColor: "red" + property color dropShadowColor: "black" + property color dropShadowPaneColor: "black" + property color toggleColor: "black" + property color toggleOnColor: "black" + property color toggleOffColor: "black" + + property color toolbarIconColor: "red" + + property color statusbarDisconnectedInternetColor: "red" + property color statusbarDisconnectedInternetFontColor: "red" + property color statusbarDisconnectedTorFontColor: "red" + property color statusbarDisconnectedTorColor: "red" + property color statusbarConnectingColor: "red" + property color statusbarConnectingFontColor: "red" + property color statusbarOnlineColor: "red" + property color statusbarOnlineFontColor: "red" + + // ... more to come + + +} diff --git a/theme/qmldir b/theme/qmldir new file mode 100644 index 0000000..4954041 --- /dev/null +++ b/theme/qmldir @@ -0,0 +1 @@ +singleton Theme 1.0 Theme.qml \ No newline at end of file