Compare commits

..
Author SHA1 Message Date
Igor Sirotin 2a8f4127ee fix(StatusSwitch): Removed running property on transition animation 2022-07-06 15:52:18 +04:00
Patryk Osmaczko c4421d3552 feat(StatusDialog): introduce StatusDialog
closes: #725
2022-07-06 11:48:11 +02:00
Lukáš Tinkl cdf3059d3d fix(sandbox): enable the hover effects by default (#751)
Similar to what we did in status desktop under
d0a26a326e95a14a6a8a5634c0d30cd6dc648b54

- since Qt 5.xy, hover is not enabled by default for QQC2, so enable it
unconditionally as we are a desktop app anyway
- this fixes several hover effects being broken, mostly for builtin
components like MenuItem and some buttons (eg. the leftmost NavBar)
where we haven't enabled those with `hoverEnabled: true` explicitely
2022-07-04 17:09:00 +02:00
Lukáš Tinkl 5e590056ff fix(@sandbox): greatly speed up (re)build times (#746)
since most of the compilation time is spent on creating the QRC bundle
and the resulting binary is quite huge, advice the `rcc` compiler to add
support for "big resources"
(cf https://doc.qt.io/qt-6/resources.html#embedding-large-files)

Also pass the env $LDFLAGS to qmake (to be able to link e.g. with mold,
which again greatly reduces the time to link the binary)

this leads to 6-10x faster time when recompiling
(Linux, gcc 12.1.1, mold 1.3.0)

BEFORE:
Clean build:
real	0m57,256s
user	1m25,869s
sys	0m40,963s

Incremental build, one file touched:
real	0m54,323s
user	0m54,012s
sys	0m2,934s

AFTER:
Clean build:
real	0m7,276s
user	0m21,001s
sys	0m37,256s

Incremental build, one file touched:
real	0m5,569s
user	0m4,850s
sys	0m0,840s
2022-07-01 10:18:09 +02:00
Mikhail Rogachev 7b8cf2ffb5 feat(StatusStackModal): add subheader and remove explicit width (#747) 2022-06-30 20:35:20 +03:00
Igor Sirotin 6da838c81f fix(icons): Updated arrows icons (#735) 2022-06-30 09:24:04 +04:00
Mikhail Rogachev a2e9f813a5 Fix(StatusStackModal): fix height calculation (#745) 2022-06-29 14:04:17 -04:00
Iuri Matias 64d6beb4a0 bug(@status-q): only run animations when they are visible to avoid cpu issues (#744)
bug(@status-q): only run animations when they are visible to avoid cpu issues

remove prop that doesn't exist
2022-06-28 11:03:17 -04:00
Mikhail Rogachev 84c529d58d feat(StatusStackModal): Component to replace nested StausModals (#733) 2022-06-27 12:23:36 -04:00
Noelia fe355eebf8 fix(StatusChatToolBar): Updated activity center button size
Activity center button has now the same size than the other toolbar buttons.

Fixes https://github.com/status-im/status-desktop/issues/6216
2022-06-27 07:52:14 +02:00
Noelia b064f9ebd8 feat(StatusRoundButton): Added Tertiary type
- Transparent background but when hovered, like Primary type in idle state.

- Updated sandbox with the new type.
2022-06-27 07:50:22 +02:00
Sale Djenic 604bb7a74c fix(StatusToastMessage): clicked signal added 2022-06-23 19:52:23 +02:00
Jonathan Rainville 7d064d6c6e chore(StatusFlatRoundButon): fix warning related to hovered property 2022-06-23 11:44:06 -04:00
Noelia 1730fe756d fix(StatusCommunityCard): Added implicit width and height (#739)
Fixes https://github.com/status-im/status-desktop/issues/6206
2022-06-22 16:48:10 -04:00
Igor Sirotin 996717885d feat(icons): Added unpin icon (#738) 2022-06-22 16:47:51 +03:00
Igor Sirotin 34c223b581 feat(StatusListItem): Added loading and loadingFailed properties (#736) 2022-06-22 10:40:17 +03:00
Mikhail Rogachev 7b35be6691 fix(StatusCommunityTag): fix StatusCommunityTag and and ETH icon (#734) 2022-06-20 18:09:38 +03:00
Igor Sirotin 2186259c06 fix(contributing.md): Added Popup sizing guidelines (#728) 2022-06-17 14:37:52 +03:00
Mikhail Rogachev 69b5cb1988 feat(StatusCommunityTags): Add community tags component (#718) 2022-06-14 16:23:18 +03:00
Boris Melnik cb900fe494 feat(StatusQ.Controls): Introduce StatusActivityCenterButton (#705) 2022-06-14 13:01:08 +03:00
Igor Sirotin 1d618f72f7 fix(StatusBaseButton): Passed icon.rotation property to the icon component (#727) 2022-06-14 12:21:53 +03:00
Khushboo-dev-cpp d5df8b42a7 feat(StatusFloatingButtonsSelector): Implements the floating buttons selector widget (#681)
To be used in with StatusModal or independently
2022-06-14 11:07:08 +05:30
Igor Sirotin c0639d8b8e fix(StatusTabButton): Hide bottom dash in disabled state (#729) 2022-06-13 17:53:30 +03:00
65 changed files with 1631 additions and 93 deletions
+24
View File
@@ -174,6 +174,25 @@ Column {
loading: true
}
// transparent
StatusRoundButton {
type: StatusRoundButton.Type.Tertiary
icon.name: "info"
}
StatusRoundButton {
type: StatusRoundButton.Type.Tertiary
icon.name: "info"
enabled: false
}
StatusRoundButton {
type: StatusRoundButton.Type.Tertiary
icon.name: "info"
loading: true
}
// Rounded blue
StatusFlatRoundButton {
@@ -319,4 +338,9 @@ Column {
}
}
// Button with emoji
StatusButton {
text: "Button with Emoji"
icon.emoji: "🖼️"
}
}
+29
View File
@@ -445,4 +445,33 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
isAdmin: true
isUntrustworthy: true
}
StatusBaseText {
Layout.fillWidth: true
Layout.topMargin: 16
text: "Loading features:"
font.pixelSize: 17
}
StatusListItem {
title: "Nokia 3310"
subTitle: "Incoming device"
label: "loading: true"
icon.emoji: "😁"
icon.color: "hotpink"
icon.letterSize: 14
icon.isLetterIdenticon: true
loading: true
}
StatusListItem {
title: "Nokia 3310"
subTitle: "Device"
label: "loadingFailed: true"
icon.emoji: "😁"
icon.color: "hotpink"
icon.letterSize: 14
icon.isLetterIdenticon: true
loadingFailed: true
}
}
+57 -1
View File
@@ -4,6 +4,9 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
import StatusQ.Core.Utils 0.1
Column {
spacing: 20
@@ -83,6 +86,12 @@ Column {
onClicked: advancedHeaderFooterModal.open()
}
StatusButton {
text: "Modal with Floating header Buttons"
onClicked: floatingHeaderModal.open()
}
StatusModal {
id: simpleModal
anchors.centerIn: parent
@@ -394,10 +403,57 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
}
}
StatusModal {
id: floatingHeaderModal
anchors.centerIn: parent
height: 200
showHeader: false
showFooter: false
showAdvancedHeader: true
hasFloatingButtons: true
advancedHeaderComponent: StatusFloatingButtonsSelector {
id: floatingHeader
model: dummyAccountsModel
delegate: Rectangle {
width: button.width
height: button.height
radius: 8
visible: visibleIndices.includes(index)
StatusButton {
id: button
topPadding: 8
bottomPadding: 0
implicitHeight: 32
defaultLeftPadding: 4
text: name
icon.emoji: !!emoji ? emoji: ""
icon.emojiSize: Emoji.size.middle
icon.name: !emoji ? "filled-account": ""
normalColor: "transparent"
highlighted: index === floatingHeader.currentIndex
onClicked: {
floatingHeader.currentIndex = index
}
}
}
popupMenuDelegate: StatusListItem {
implicitWidth: 272
title: name
onClicked: floatingHeader.itemSelected(index)
visible: !visibleIndices.includes(index)
}
}
}
ListModel {
id: dummyAccountsModel
ListElement{name: "Account 1"; iconName: "filled-account"}
ListElement{name: "Account 1"; iconName: "filled-account"; emoji: "🥑"}
ListElement{name: "Account 2"; iconName: "filled-account"}
ListElement{name: "Account 3"; iconName: "filled-account"}
ListElement{name: "Account 4"; iconName: "filled-account"}
ListElement{name: "Account 5"; iconName: "filled-account"}
ListElement{name: "Account 6"; iconName: "filled-account"}
ListElement{name: "Account 7"; iconName: "filled-account"}
}
StatusSpellcheckingMenuItems {
+2
View File
@@ -1478,4 +1478,6 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
ListElement { name: "enviroment"; emoji: "☠️"}
ListElement { name: "privacy"; emoji: "👻"}
}
property var communityTags :{"Activism":"✊","Art":"🎨","Blockchain":"🔗","Books & blogs":"📚","Career":"💼","Collaboration":"🤝","Commerce":"🛒","Crypto":"Ξ","Culture":"🎎","DAO":"🚀","DIY":"🔨","DeFi":"📈","Design":"🧩","Education":"🎒","Entertainment":"🍿","Environment":"🌿","Event":"🗓","Fantasy":"🧙‍♂️","Fashion":"🧦","Food":"🌶","Gaming":"🎮","Global":"🌍","Health":"🧠","Hobby":"📐","Innovation":"🧪","Language":"📜","Lifestyle":"✨","Local":"📍","Love":"❤️","Markets":"💎","Movies & TV":"🎞","Music":"🎶","NFT":"🖼","NSFW":"🍆","News":"🗞","Non-profit":"🙏","Org":"🏢","Pets":"🐶","Play":"🎲","Podcast":"🎙️","Politics":"🗳️","Privacy":"👻","Product":"🍱","Psyche":"🍁","Security":"🔒","Social":"☕","Software dev":"👩‍💻","Sports":"⚽️","Tech":"📱","Travel":"🗺","Vehicles":"🚕","Web3":"🌐"}
}
+2
View File
@@ -12,6 +12,8 @@ int main(int argc, char *argv[])
SandboxApp app(argc, argv);
qputenv("QT_QUICK_CONTROLS_HOVER_ENABLED", QByteArrayLiteral("1"));
app.setOrganizationName("Status");
app.setOrganizationDomain("status.im");
app.setApplicationName("Sandbox");
+10 -1
View File
@@ -289,18 +289,27 @@ StatusWindow {
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusCommunityTags"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusListSectionHeadline { text: "StatusQ.Popup" }
StatusNavigationListItem {
title: "StatusPopupMenu"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusModal"
selected: viewLoader.source.toString().includes("Popups")
onClicked: mainPageView.control("Popups");
}
StatusNavigationListItem {
title: "StatusDialog"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusListSectionHeadline { text: "StatusQ.Platform" }
StatusNavigationListItem {
title: "StatusMacNotification"
+83
View File
@@ -0,0 +1,83 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import Sandbox 0.1
import "../demoapp/data" 1.0
Item {
property int cntSelectedTags: 0
property int maxSelectedTags: 4
property ListModel tagsModel: ListModel {}
Component.onCompleted: {
tagsModel.clear();
for (const key of Object.keys(Models.communityTags)) {
tagsModel.append({ name: key, emoji: Models.communityTags[key], selected: false });
}
}
ColumnLayout {
id: column
anchors.centerIn: parent
width: 600
height: 500
spacing: 20
StatusInput {
id: tagsFilter
leftPadding: 0
rightPadding: 0
label: qsTr("Select tags that will fit your Community")
input.icon.name: "search"
input.placeholderText: qsTr("Search tags")
Layout.fillWidth: true
}
StatusCommunityTags {
filterString: tagsFilter.text
model: tagsModel
enabled: cntSelectedTags < maxSelectedTags
onClicked: {
cntSelectedTags++;
item.selected = true;
}
Layout.fillWidth: true
}
RowLayout {
StatusBaseText {
text: qsTr("Selected tags")
font.pixelSize: 15
Layout.fillWidth: true
}
StatusBaseText {
text: cntSelectedTags + "/" + maxSelectedTags
color: Theme.palette.baseColor1
font.pixelSize: 13
}
}
StatusCommunityTags {
model: tagsModel
showOnlySelected: true
onClicked: {
cntSelectedTags--;
item.selected = false;
}
Layout.fillWidth: true
}
Item {
Layout.fillHeight: true
}
}
}
+282
View File
@@ -0,0 +1,282 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import QtQml.Models 2.14
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups.Dialog 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
ColumnLayout {
id: root
StatusButton {
text: "Content"
onClicked: contentDialog.open()
StatusDialog {
id: contentDialog
standardButtons: Dialog.ApplyRole
StatusBaseText {
anchors.fill: parent
text: "Content"
}
}
}
StatusButton {
text: "Title and content"
onClicked: titleContentDialog.open()
StatusDialog {
id: titleContentDialog
title: "Title"
StatusBaseText {
anchors.fill: parent
text: "Content"
}
}
}
StatusButton {
text: "No buttons"
onClicked: noButtonsDialog.open()
StatusDialog {
id: noButtonsDialog
title: "No buttons"
standardButtons: Dialog.NoButton
StatusBaseText {
anchors.fill: parent
text: "Content"
}
}
}
StatusButton {
text: "Long title"
onClicked: longTitleDialog.open()
StatusDialog {
id: longTitleDialog
title: "Long title long title Long title long title Long title long title"
StatusBaseText {
anchors.fill: parent
text: "Content"
}
}
}
StatusButton {
text: "Long title elided"
onClicked: longTitleElidedDialog.open()
StatusDialog {
id: longTitleElidedDialog
title: "Long title long title Long title long title Long title long title"
width: 400
StatusBaseText {
anchors.fill: parent
text: "Content"
}
}
}
StatusButton {
text: "Title subtitle"
onClicked: titleSubtitleDialog.open()
StatusDialog {
id: titleSubtitleDialog
title: "This title will be ignored"
header: StatusDialogHeader {
headline.title: "Title"
headline.subtitle: "Subtitle"
actions.closeButton.onClicked: titleSubtitleDialog.close()
}
StatusBaseText {
anchors.fill: parent
text: "Content"
}
}
}
StatusButton {
text: "Auto adjustable"
onClicked: autoAdjustableDialog.open()
StatusDialog {
id: autoAdjustableDialog
header: StatusDialogHeader {
headline.title: "Dialog size will auto adapt"
headline.subtitle: "To conent size"
actions.closeButton.onClicked: autoAdjustableDialog.close()
}
footer: StatusDialogFooter {
leftButtons: ObjectModel {
StatusRoundButton {
icon.name: "arrow-left"
onClicked: autoAdjustableDialogContent.implicitWidth -= 100
}
StatusRoundButton {
icon.name: "arrow-right"
onClicked: autoAdjustableDialogContent.implicitWidth += 100
}
}
rightButtons: ObjectModel {
StatusRoundButton {
icon.name: "arrow-down"
onClicked: autoAdjustableDialogContent.implicitHeight -= 100
}
StatusRoundButton {
icon.name: "arrow-up"
onClicked: autoAdjustableDialogContent.implicitHeight += 100
}
}
}
Rectangle {
id: autoAdjustableDialogContent
anchors.fill: parent
implicitWidth: 200
implicitHeight: 200
color: Theme.palette.primaryColor3
StatusBaseText {
anchors.centerIn: parent
text: "W: %1 H: %2\nIW: %3 IH: %4".arg(parent.width).arg(parent.height).arg(parent.implicitWidth).arg(parent.implicitHeight)
}
}
}
}
StatusButton {
text: "Complex dialog"
onClicked: complexDialog.open()
StatusDialog {
id: complexDialog
header: StatusDialogHeader {
id: dialogHeader
headline.title: "Complex dialog"
headline.subtitle: "identicon, title subtitle, custom actions"
leftComponent: StatusLetterIdenticon {
name: dialogHeader.headline.title
}
actions {
infoButton.visible: true
customButtons: ObjectModel {
StatusFlatRoundButton {
icon.name: "warning"
icon.width: 20
icon.height: 20
}
}
closeButton.onClicked: complexDialog.close()
}
}
footer: StatusDialogFooter {
leftButtons: ObjectModel {
StatusRoundButton {
icon.name: "arrow-left"
}
}
rightButtons: ObjectModel {
StatusButton {
text: "Custom cancel action"
type: StatusButton.Danger
}
StatusButton {
text: "Custom approve action"
}
}
}
ColumnLayout {
anchors.fill: parent
StatusBaseText {
text: "Content A"
}
StatusBaseText {
text: "Content B"
}
StatusBaseText {
text: "Content C"
}
}
}
}
StatusButton {
text: "Custom header/footer"
onClicked: customHeaderAndFooter.open()
StatusDialog {
id: customHeaderAndFooter
title: "No buttons"
header: Rectangle {
implicitHeight: customHeaderText.height * 2
implicitWidth: customHeaderText.width * 2
border.width: 2
color: Theme.palette.statusPopupMenu.hoverBackgroundColor
StatusBaseText {
id: customHeaderText
anchors.centerIn: parent
text: "Custom header"
}
}
footer: Rectangle {
implicitHeight: customHeaderText.height * 2
implicitWidth: customHeaderText.width * 2
border.width: 2
color: Theme.palette.statusPopupMenu.hoverBackgroundColor
StatusBaseText {
id: customFooter
anchors.centerIn: parent
text: "Custom footer"
}
}
StatusBaseText {
anchors.fill: parent
text: "Content"
}
}
}
}
+3
View File
@@ -35,6 +35,9 @@ Item {
onClose: {
console.warn("toast closed: ", modelData.title)
}
onClicked: {
console.warn("toast clicked")
}
}
}
}
+2
View File
@@ -1,11 +1,13 @@
QT += quick svg
CONFIG += c++11 warn_on qtquickcompiler
CONFIG += resources_big
QML_IMPORT_PATH= $$PWD/../src
DEFINES += QT_DEPRECATED_WARNINGS
QMAKE_LFLAGS += $$(LDFLAGS)
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
@@ -0,0 +1,30 @@
import QtQuick 2.14
import QtGraphicalEffects 1.14
Item {
id: root
property Item mask
property color color: "#F6F8FA"
Rectangle {
id: gradient
anchors.fill: parent
visible: false
gradient: Gradient {
orientation: Gradient.Horizontal
SkeletonGradientStop { color: "transparent"; from: -3; }
SkeletonGradientStop { color: "transparent"; from: -2; }
SkeletonGradientStop { color: root.color; from: -1 ; }
SkeletonGradientStop { color: "transparent"; from: 0; }
SkeletonGradientStop { color: "transparent"; from: 1; }
}
}
OpacityMask {
anchors.fill: parent
source: gradient
maskSource: root.mask
}
}
@@ -0,0 +1,24 @@
import QtQuick 2.14
import QtGraphicalEffects 1.14
/*
TODO: This component should be implemented as inline component of `SkeletonAnimation.qml`
when we use Qt > 5.15
*/
GradientStop {
id: root
property real from: 0
color: "transparent"
NumberAnimation on position {
easing.type: Easing.Linear
loops: Animation.Infinite
running: visible
from: root.from
to: from + 4
duration: 2000
}
}
+4
View File
@@ -0,0 +1,4 @@
module StatusQ.Animations
SkeletonAnimation 0.1 SkeletonAnimation.qml
SkeletonGradientStop 0.1 SkeletonGradientStop.qml
@@ -73,6 +73,7 @@ Item {
duration: 150
direction: RotationAnimation.Clockwise
easing.type: Easing.InCubic
running: visible
}
},
Transition {
@@ -82,6 +83,7 @@ Item {
duration: 150
direction: RotationAnimation.Counterclockwise
easing.type: Easing.OutCubic
running: visible
}
}
]
+3 -34
View File
@@ -135,43 +135,12 @@ Item {
(menuButton.visible || membersButton.visible || searchButton.visible)
}
StatusFlatRoundButton {
StatusActivityCenterButton {
id: notificationButton
width: 32
height: 32
icon.name: "notification"
icon.height: 21
type: StatusFlatRoundButton.Type.Secondary
// initializing the tooltip
tooltip.text: qsTr("Activity")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
height: width
unreadNotificationsCount: statusChatToolBar.notificationCount
onClicked: statusChatToolBar.notificationButtonClicked()
StatusBadge {
id: statusBadge
visible: value > 0
anchors.top: parent.top
anchors.left: parent.right
anchors.topMargin: -3
anchors.leftMargin: {
if (statusBadge.value > 99) {
return -22
}
if (statusBadge.value > 9) {
return -21
}
return -18
}
value: statusChatToolBar.notificationCount
border.width: 2
border.color: parent.hovered ? Theme.palette.baseColor2 : Theme.palette.statusAppLayout.backgroundColor
}
}
}
}
@@ -160,8 +160,8 @@ Rectangle {
}
}
width: d.cardWidth
height: d.totalHeigth
implicitWidth: d.cardWidth
implicitHeight: d.totalHeigth
radius: d.bannerRadius
color: "transparent"
layer.enabled: true
@@ -0,0 +1,48 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
Item {
id: root
property string filterString
property bool showOnlySelected: false
property bool active: true
property alias model: repeater.model
property alias contentWidth: flow.width
signal clicked(var item)
implicitWidth: flow.implicitWidth
implicitHeight: flow.implicitHeight
Flow {
id: flow
anchors.centerIn: parent
width: {
let itemsWidth = 0;
for (let i = 0; i < repeater.count; ++i) {
itemsWidth += spacing + repeater.itemAt(i).width;
}
return Math.min(parent.width, itemsWidth);
}
spacing: 10
Repeater {
id: repeater
delegate: StatusCommunityTag {
emoji: model.emoji
name: model.name
visible: (root.showOnlySelected ? model.selected : !model.selected) &&
(filterString == 0 || name.toUpperCase().indexOf(filterString.toUpperCase()) !== -1)
width: visible ? implicitWidth : -10
height: visible ? implicitHeight : 0
removable: root.showOnlySelected && root.active
onClicked: root.clicked(model)
}
}
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ Image {
id: root
property string emojiId: ""
width: 14
height: 14
sourceSize.width: width
@@ -217,12 +217,12 @@ Rectangle {
Transition {
from: "COLLAPSED"
to: "EXPANDED"
NumberAnimation { properties: "height"; duration: 200 }
NumberAnimation { properties: "height"; duration: 200; running: visible }
},
Transition {
from: "EXPANDED"
to: "COLLAPSED"
NumberAnimation { properties: "height"; duration: 200 }
NumberAnimation { properties: "height"; duration: 200; running: visible }
}
]
}
+46 -1
View File
@@ -5,6 +5,10 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Animations 0.1
import QtGraphicalEffects 1.14
import "private"
Rectangle {
id: statusListItem
@@ -27,6 +31,8 @@ Rectangle {
property Component bottomDelegate
property var tagsModel: []
property Component tagsDelegate
property bool loading: false
property bool loadingFailed: false
property StatusIconSettings icon: StatusIconSettings {
height: isLetterIdenticon ? 40 : 20
@@ -134,6 +140,7 @@ Rectangle {
anchors.leftMargin: statusListItem.leftPadding
anchors.top: parent.top
anchors.topMargin: 12
visible: !iconOrImageLoadingOverlay.visible
image: statusListItem.image
icon: statusListItem.icon
name: statusListItem.title
@@ -145,6 +152,20 @@ Rectangle {
ringSettings: statusListItem.ringSettings
}
Rectangle {
id: iconOrImageLoadingOverlay
visible: statusListItem.loading || statusListItem.loadingFailed
anchors.fill: iconOrImage
radius: width / 2
color: statusListItem.loadingFailed ? Theme.palette.dangerColor2 : Theme.palette.baseColor1
SkeletonAnimation {
anchors.fill: parent
mask: parent
visible: statusListItem.loading && !statusListItem.loadingFailed
}
}
Item {
id: statusListItemTitleArea
@@ -164,8 +185,29 @@ Rectangle {
height: childrenRect.height
Rectangle {
id: titleLoadingOverlay
visible: statusListItem.loading || statusListItem.loadingFailed
anchors {
left: statusListItemTitle.left
top: statusListItemTitle.top
bottom: statusListItemTitle.bottom
}
width: Math.max(95, statusListItemTitle.width)
radius: 4
color: statusListItem.loadingFailed ? Theme.palette.dangerColor2 : Theme.palette.baseColor1
SkeletonAnimation {
anchors.fill: parent
mask: parent
visible: statusListItem.loading && !statusListItem.loadingFailed
}
}
StatusBaseText {
id: statusListItemTitle
opacity: titleLoadingOverlay.visible ? 0 : 1
text: statusListItem.title
font.pixelSize: 15
height: visible ? contentHeight : 0
@@ -235,7 +277,10 @@ Rectangle {
width: parent.width
text: statusListItem.subTitle
font.pixelSize: 15
color: !statusListItem.enabled || !statusListItem.tertiaryTitle ? Theme.palette.baseColor1 : Theme.palette.directColor1
color: statusListItem.loadingFailed ? Theme.palette.dangerColor1
: !statusListItem.enabled || !statusListItem.tertiaryTitle
? Theme.palette.baseColor1
: Theme.palette.directColor1
height: visible ? contentHeight : 0
visible: !!statusListItem.subTitle
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
@@ -11,7 +11,7 @@ StatusIcon {
from: 0;
to: 360;
duration: 1200
running: true
running: visible
loops: Animation.Infinite
}
}
@@ -125,6 +125,11 @@ Control {
root.open = true;
}
/*!
\qmlsignal
This signal is emitted when the ToastMessage is clicked.
*/
signal clicked()
/*!
\qmlsignal
This signal is emitted when the ToastMessage is closed (after animation).
@@ -214,6 +219,9 @@ Control {
onMouseXChanged: {
root.open = (mouseX < (root.width/3));
}
onClicked: {
root.clicked();
}
}
RowLayout {
anchors.fill: parent
@@ -115,6 +115,7 @@ Rectangle {
properties: "scale";
duration: 100;
easing.type: Easing.InOutQuad
running: visible
}
}
+1
View File
@@ -36,3 +36,4 @@ StatusWizardStepper 0.1 StatusWizardStepper.qml
StatusImageCropPanel 0.1 StatusImageCropPanel.qml
StatusColorSpace 0.0 StatusColorSpace.qml
StatusCommunityCard 0.1 StatusCommunityCard.qml
StatusCommunityTags 0.1 StatusCommunityTags.qml
@@ -0,0 +1,62 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
/*!
\qmltype StatusActivityCenterButton
\inherits StatusFlatRoundButton
\inqmlmodule StatusQ.Controls
\since StatusQ.Controls 0.1
\brief The StatusActivityCenterButton provides the button for Activity Center popup
Example of how to use it:
\qml
StatusActivityCenterButton {
unreadNotificationsCount: activityCenter.unreadNotificationsCount
onClicked: activityCenterPopup.open()
}
\endqml
For a list of components available see StatusQ.
*/
StatusFlatRoundButton {
id: notificationButton
/*!
\qmlproperty int StatusActivityCenterButton::unreadNotificationsCount
This property holds the count of notifications.
*/
property alias unreadNotificationsCount: statusBadge.value
icon.name: "notification"
icon.height: 21
type: StatusFlatRoundButton.Type.Secondary
// initializing the tooltip
tooltip.text: qsTr("Activity")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
StatusBadge {
id: statusBadge
visible: value > 0
anchors.top: parent.top
anchors.left: parent.right
anchors.topMargin: -3
anchors.leftMargin: {
if (statusBadge.value > 99) {
return -22
}
if (statusBadge.value > 9) {
return -21
}
return -18
}
border.width: 2
border.color: parent.hovered ? Theme.palette.baseColor2 : Theme.palette.statusAppLayout.backgroundColor
}
}
@@ -2,6 +2,7 @@ import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1
Rectangle {
id: statusBaseButton
@@ -128,11 +129,19 @@ Rectangle {
width: statusBaseButton.icon.width
height: statusBaseButton.icon.height
icon: statusBaseButton.icon.name
rotation: statusBaseButton.icon.rotation
anchors.verticalCenter: parent.verticalCenter
opacity: !loading && statusBaseButton.icon.name !== ""
visible: statusBaseButton.icon.name !== ""
color: d.textColor
} // Icon
StatusEmoji {
width: statusBaseButton.icon.width
height: statusBaseButton.icon.height
anchors.verticalCenter: parent.verticalCenter
visible: statusBaseButton.icon.emoji
emojiId: Emoji.iconId(statusBaseButton.icon.emoji, statusBaseButton.icon.emojiSize) || ""
} // Emoji
StatusBaseText {
id: label
opacity: !loading
@@ -14,7 +14,18 @@ Column {
property int selectedColorIndex: 0
property string selectedColor: ""
property var model: Theme.palette.userCustomizationColors
property var model:[ StatusColors.colors['black'],
StatusColors.colors['grey'],
StatusColors.colors['blue2'],
StatusColors.colors['purple'],
StatusColors.colors['cyan'],
StatusColors.colors['violet'],
StatusColors.colors['red2'],
StatusColors.colors['yellow'],
StatusColors.colors['green2'],
StatusColors.colors['moss'],
StatusColors.colors['brown'],
StatusColors.colors['brown2'] ]
signal colorSelected(color color)
@@ -32,7 +43,6 @@ Column {
columns: 6
rowSpacing: 16
columnSpacing: 32
Repeater {
model: root.model
delegate: StatusColorRadioButton {
@@ -0,0 +1,58 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
Rectangle {
id: root
property string emoji
property string name
property bool removable: false
signal clicked()
implicitHeight: 32
implicitWidth: row.width + 20
radius: height / 2
border.color: Theme.palette.baseColor2
border.width: 1
color: mouseArea.containsMouse ? Theme.palette.primaryColor2 : "transparent"
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: root.clicked()
}
Row {
id: row
anchors.centerIn: parent
StatusEmoji {
emojiId: root.emoji != "" ? Emoji.iconHex(root.emoji) : ""
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: 5
height: width
}
StatusBaseText {
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 13
color: root.enabled ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
text: root.name
}
StatusIcon {
visible: removable
color: root.enabled ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
icon: "close"
}
}
}
@@ -172,6 +172,6 @@ Rectangle {
StatusToolTip {
id: statusToolTip
visible: !!text && parent.hovered
visible: !!text && statusFlatRoundButton.hovered
} // Tooltip
} // Rectangle
@@ -0,0 +1,133 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
/*!
\qmltype StatusModalFloatingButtonsSelector
\inherits Row
\inqmlmodule StatusQ.Controls
\since StatusQ.Controls 0.1
\brief The StatusModalFloatingButtonsSelector provides a template for creating a selectable buttons list
this list can be parially hidden and the rest of the items are shown under the more button in a popup
Example of how to use it:
\qml
StatusModalFloatingButtonsSelector {
id: floatingHeader
model: dummyAccountsModel
delegate: StatusAccountSelectorTag {
title: "name"
icon.name: "iconName"
isSelected: floatingHeader.currentIndex === index
visible: visibleIndices.includes(index)
onClicked: floatingHeader.currentIndex = index
}
popupMenuDelegate: StatusListItem {
implicitWidth: 272
title: "name"
onClicked: floatingHeader.itemSelected(index)
visible: !visibleIndices.includes(index)
}
}
\endqml
For a list of components available see StatusQ.
*/
Row {
id: floatingButtons
/*!
\qmlproperty delegate
This property represents the delegate of selectable items shown to the user.
Can be used to assign delegate to the buttons selector
\endqml
*/
property alias delegate: itemSelectionRepeater.delegate
/*!
\qmlproperty popupMenuDelegate
This property represents the delegate of popupmenu fropm which items can be selected by the user.
Can be used to assign delegate to the popupmenu
\endqml
*/
property alias popupMenuDelegate: popupMenuSelectionRepeater.delegate
/*!
\qmlproperty model
This property represents the model of selectable items shown to the user.
Can be used to assign selectable items in the buttons selector
\endqml
*/
property var model
/*!
\qmlproperty visibleIndices
This property represents the indices from the selectable items that will visible to the user
Can be used to set visible items in the buttons selector
\endqml
*/
property var visibleIndices: [0,1,2]
/*!
\qmlproperty currentIndex
This property represents the index of the currently selected item
Can be used to set the currnetly selected item in the buttons selector
\endqml
*/
property int currentIndex: 0
function itemSelected(index) {
visibleIndices = [0,1,index]
floatingButtons.currentIndex = index
popupMenu.close()
}
height: 32
spacing: 12
clip: true
Repeater {
id: itemSelectionRepeater
model: floatingButtons.model
}
Rectangle {
width: button.width
height: button.height
radius: 8
visible: floatingButtons.model.count > 3
StatusButton {
id: button
implicitHeight: 32
topPadding: 8
bottomPadding: 0
defaultLeftPadding: 4
defaultRightPadding: 4
normalColor: "transparent"
icon.name: "more"
icon.background.color: "transparent"
onClicked: popupMenu.popup(parent.x, y + height + 8)
}
}
// Empty item to fill up empty space
Item {
Layout.preferredHeight: parent.height
Layout.fillWidth: true
}
StatusPopupMenu {
id: popupMenu
width: layout.width
ColumnLayout {
id: layout
Repeater {
id: popupMenuSelectionRepeater
model: floatingButtons.model
}
}
}
}
+3 -2
View File
@@ -211,8 +211,9 @@ Item {
SequentialAnimation {
id: blinkingAnimation
loops: Animation.Infinite
NumberAnimation { target: inner; property: "opacity"; to: 0; duration: 800 }
NumberAnimation { target: inner; property: "opacity"; to: 1; duration: 800 }
running: visible
NumberAnimation { target: inner; property: "opacity"; to: 0; duration: 800; running: visible }
NumberAnimation { target: inner; property: "opacity"; to: 1; duration: 800; running: visible }
}
}
}
+27 -3
View File
@@ -12,14 +12,27 @@ Rectangle {
height: 23
rotation: 0
property color hoverColor: {
switch(statusRoundButton.type) {
case StatusRoundButton.Type.Primary:
return Theme.palette.primaryColor1;
case StatusRoundButton.Type.Secondary:
return Theme.palette.indirectColor1;
case StatusRoundButton.Type.Tertiary:
return Theme.palette.primaryColor1;
}
}
color: {
switch(statusRoundButton.type) {
case StatusRoundButton.Type.Primary:
return Theme.palette.primaryColor1;
case StatusRoundButton.Type.Secondary:
return Theme.palette.indirectColor1;
case StatusRoundButton.Type.Tertiary:
return Theme.palette.baseColor1;
}
}
}
disabledColor: {
switch(statusRoundButton.type) {
@@ -27,6 +40,8 @@ Rectangle {
return Theme.palette.baseColor1;
case StatusRoundButton.Type.Secondary:
return Theme.palette.indirectColor1;
case StatusRoundButton.Type.Tertiary:
return Theme.palette.baseColor1;
}
}
}
@@ -46,7 +61,8 @@ Rectangle {
enum Type {
Primary,
Secondary
Secondary,
Tertiary
}
/// Implementation
@@ -59,6 +75,8 @@ Rectangle {
return Theme.palette.primaryColor3;
case StatusRoundButton.Type.Secondary:
return Theme.palette.primaryColor1;
case StatusRoundButton.Type.Tertiary:
return "transparent";
}
}
@@ -68,6 +86,8 @@ Rectangle {
return Theme.palette.primaryColor2;
case StatusRoundButton.Type.Secondary:
return Theme.palette.miscColor1;
case StatusRoundButton.Type.Tertiary:
return Theme.palette.primaryColor3;
}
}
@@ -77,13 +97,17 @@ Rectangle {
return Theme.palette.baseColor2;
case StatusRoundButton.Type.Secondary:
return Theme.palette.baseColor1;
case StatusRoundButton.Type.Tertiary:
return "transparent";
}
}
}
QtObject {
id: d
readonly property color iconColor: statusRoundButton.enabled ? statusRoundButton.icon.color : statusRoundButton.icon.disabledColor
readonly property color iconColor: !statusRoundButton.enabled ? statusRoundButton.icon.disabledColor :
(statusRoundButton.enabled && statusRoundButton.hovered) ? statusRoundButton.icon.hoverColor :
statusRoundButton.icon.color
}
implicitWidth: 44
+1 -1
View File
@@ -52,7 +52,7 @@ Switch {
transitions: Transition {
reversible: true
NumberAnimation { properties: "x"; easing.type: Easing.Linear; duration: 120; }
NumberAnimation { properties: "x"; easing.type: Easing.Linear; duration: 120 }
}
}
}
+1 -1
View File
@@ -66,7 +66,7 @@ TabButton {
Rectangle {
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
visible: root.checked || root.hovered
visible: root.enabled && (root.checked || root.hovered)
implicitWidth: 24
implicitHeight: 2
radius: 4
@@ -108,6 +108,7 @@ RowLayout {
Behavior on color {
ColorAnimation {
running: visible
}
}
@@ -155,7 +156,7 @@ RowLayout {
from: 0
to: parent.width
duration: 800
running: mouseArea.containsPress
running: visible && mouseArea.containsPress
onStopped: {
if (pressIndicator.width == parent.width) {
+3
View File
@@ -18,6 +18,7 @@ StatusButton 0.1 StatusButton.qml
StatusFlatButton 0.1 StatusFlatButton.qml
StatusRoundButton 0.1 StatusRoundButton.qml
StatusFlatRoundButton 0.1 StatusFlatRoundButton.qml
StatusCommunityTag 0.1 StatusCommunityTag.qml
StatusSwitch 0.1 StatusSwitch.qml
StatusRadioButton 0.1 StatusRadioButton.qml
StatusCheckBox 0.1 StatusCheckBox.qml
@@ -42,3 +43,5 @@ StatusWalletColorSelect 0.1 StatusWalletColorSelect.qml
StatusColorSelectorGrid 0.1 StatusColorSelectorGrid.qml
StatusSeedPhraseInput 0.1 StatusSeedPhraseInput.qml
StatusImageCrop 0.1 StatusImageCrop.qml
StatusFloatingButtonsSelector 0.1 StatusFloatingButtonsSelector.qml
StatusActivityCenterButton 0.1 StatusActivityCenterButton.qml
+80
View File
@@ -0,0 +1,80 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
StackLayout {
id: root
property int previousIndex: 0
property int duration: 300
property var items: children
readonly property var previousItem: items[previousIndex]
readonly property var currentItem: items[currentIndex]
clip: true
Component.onCompleted: {
previousIndex = currentIndex
for(var i = 1; i < count; ++i) {
children[i].opacity = 0
}
}
Component {
id: crossFader
ParallelAnimation {
property Item fadeOutTarget
property Item fadeInTarget
readonly property bool direct: previousIndex < currentIndex
NumberAnimation {
target: fadeOutTarget
property: "opacity"
to: 0
duration: root.duration
}
NumberAnimation {
target: fadeInTarget
property: "opacity"
to: 1
duration: root.duration
}
NumberAnimation {
target: fadeOutTarget
property: "x"
from: 0
to: direct ? -root.width : root.width
duration: root.duration
}
NumberAnimation {
target: fadeInTarget
property: "x"
from: direct ? root.width : -root.width
to: 0
duration: root.duration
}
}
}
onCurrentIndexChanged: {
items = root.children;
if (previousItem && currentItem && (previousItem != currentItem)) {
previousItem.visible = true;
currentItem.visible = true;
var crossFaderAnim = crossFader.createObject(parent,
{
fadeOutTarget: previousItem,
fadeInTarget: currentItem
});
crossFaderAnim.restart();
}
previousIndex = currentIndex;
}
}
@@ -147,6 +147,21 @@ ThemePalette {
miscColor11: getColor('yellow2')
miscColor12: getColor('green6')
userCustomizationColors: [
"#AAC6FF",
"#887AF9",
"#51D0F0",
"#D37EF4",
"#FA6565",
"#FFCA0F",
"#93DB33",
"#10A88E",
"#AD4343",
"#EAD27B",
"silver", // update me when figma is ready
"darkgrey", // update me when figma is ready
]
identiconRingColors: ["#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00",
"#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00",
"#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099",
@@ -145,6 +145,21 @@ ThemePalette {
miscColor11: getColor('brown2')
miscColor12: getColor('green5')
userCustomizationColors: [
"#2946C4",
"#887AF9",
"#51D0F0",
"#D37EF4",
"#FA6565",
"#FFCA0F",
"#7CDA00",
"#26A69A",
"#8B3131",
"#9B832F",
"silver", // update me when figma is ready
"darkgrey", // update me when figma is ready
]
identiconRingColors: ["#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00",
"#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00",
"#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099",
+1 -14
View File
@@ -90,20 +90,7 @@ QtObject {
property color miscColor11
property color miscColor12
property var userCustomizationColors: [
getColor('black', 0.8),
getColor('grey'),
getColor('blue2'),
getColor('purple'),
getColor('cyan'),
getColor('violet'),
getColor('red2'),
getColor('yellow'),
getColor('green2'),
getColor('moss'),
getColor('brown'),
getColor('brown2'),
]
property var userCustomizationColors: []
property var identiconRingColors: []
+4
View File
@@ -48,6 +48,10 @@ QtObject {
const match = parsed.match('src=".*\/(.+?).svg');
return (match && match.length >= 2) ? match[1] : undefined;
}
// NOTE: doing the same thing as iconId but without checking Twemoji internal checks
function iconHex(text) {
return text.codePointAt(0).toString(16);
}
function fromCodePoint(value) {
return Twemoji.twemoji.convert.fromCodePoint(value)
}
+1
View File
@@ -9,3 +9,4 @@ StatusImageSettings 0.1 StatusImageSettings.qml
StatusModalHeaderSettings 0.1 StatusModalHeaderSettings.qml
StatusTooltipSettings 0.1 StatusTooltipSettings.qml
StatusAppNavBarFilterModel 0.1 StatusAppNavBarFilterModel.qml
StatusAnimatedStack 0.1 StatusAnimatedStack.qml
+104
View File
@@ -0,0 +1,104 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import QtQml.Models 2.14
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Dialog {
id: root
anchors.centerIn: Overlay.overlay
padding: 16
margins: 64
modal: true
standardButtons: Dialog.Cancel | Dialog.Ok
Overlay.modal: Rectangle {
color: Theme.palette.backdropColor
}
background: Rectangle {
color: Theme.palette.statusModal.backgroundColor
radius: 8
}
header: StatusDialogHeader {
visible: root.title
headline.title: root.title
actions.closeButton.onClicked: root.close()
}
footer: StatusDialogFooter {
id: footerItem
readonly property int rejectRoleFlags: Dialog.Cancel | Dialog.Close | Dialog.Abort
readonly property int noRoleFlags: Dialog.No | Dialog.NoToAll
readonly property int acceptRoleFlags: Dialog.Ok | Dialog.Open | Dialog.Save | Dialog.SaveAll | Dialog.Retry | Dialog.Ignore
readonly property int yesRoleFlags: Dialog.Yes | Dialog.YesToAll
visible: rightButtons &&
root.standardButtons & (rejectRoleFlags | noRoleFlags | acceptRoleFlags | yesRoleFlags | Dialog.ApplyRole)
rightButtons: ObjectModel {
StatusButton {
visible: root.standardButtons & footerItem.rejectRoleFlags
type: StatusButton.Danger
text: {
if (root.standardButtons & Dialog.Close) return qsTr("Close")
if (root.standardButtons & Dialog.Abort) return qsTr("Abort")
return qsTr("Cancel")
}
onClicked: root.reject()
}
StatusButton {
visible: root.standardButtons & footerItem.noRoleFlags
type: StatusButton.Danger
text: {
if (root.standardButtons & Dialog.NoToAll) return qsTr("No to all")
return qsTr("No")
}
onClicked: root.reject()
}
StatusButton {
visible: root.standardButtons & footerItem.acceptRoleFlags
text: {
if (root.standardButtons & Dialog.Open) return qsTr("Open")
if (root.standardButtons & Dialog.Save) return qsTr("Save")
if (root.standardButtons & Dialog.SaveAll) return qsTr("Save all")
if (root.standardButtons & Dialog.Retry) return qsTr("Retry")
if (root.standardButtons & Dialog.Ignore) return qsTr("Ignore")
return qsTr("Ok")
}
onClicked: root.accept()
}
StatusButton {
visible: root.standardButtons & footerItem.yesRoleFlags
type: StatusButton.Danger
text: {
if (root.standardButtons & Dialog.YesToAll) return qsTr("Yes to all")
return qsTr("Yes")
}
onClicked: root.accept()
}
StatusButton {
visible: root.standardButtons & Dialog.ApplyRole
text: qsTr("Apply")
onClicked: root.applied()
}
}
}
}
@@ -0,0 +1,8 @@
import QtQuick 2.14
import StatusQ.Core.Theme 0.1
Rectangle {
color: Theme.palette.baseColor2
implicitHeight: 1
}
@@ -0,0 +1,48 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import QtQml.Models 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Rectangle {
id: root
property ObjectModel leftButtons
property ObjectModel rightButtons
color: Theme.palette.statusModal.backgroundColor
radius: 8
implicitHeight: layout.implicitHeight + layout.anchors.topMargin + layout.anchors.bottomMargin
implicitWidth: layout.implicitWidth + layout.anchors.leftMargin + layout.anchors.rightMargin
RowLayout {
id: layout
clip: true
anchors {
fill: parent
margins: 16
}
Repeater {
model: root.leftButtons
onItemAdded: item.Layout.fillHeight = true
}
Item {
Layout.fillWidth: true
}
Repeater {
model: root.rightButtons
onItemAdded: item.Layout.fillHeight = true
}
}
StatusDialogDivider {
width: parent.width
}
}
@@ -0,0 +1,58 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Rectangle {
id: root
readonly property alias headline: headline
readonly property alias actions: actions
property alias leftComponent: leftComponentLoader.sourceComponent
color: Theme.palette.statusModal.backgroundColor
radius: 8
implicitHeight: layout.implicitHeight + layout.anchors.topMargin + layout.anchors.bottomMargin
implicitWidth: layout.implicitWidth + layout.anchors.leftMargin + layout.anchors.rightMargin
RowLayout {
id: layout
clip: true
anchors {
fill: parent
margins: 16
}
spacing: 8
Loader {
id: leftComponentLoader
Layout.fillHeight: true
visible: sourceComponent
}
StatusTitleSubtitle {
id: headline
Layout.fillWidth: true
Layout.fillHeight: true
}
StatusHeaderActions {
id: actions
Layout.alignment: Qt.AlignTop
}
}
StatusDialogDivider {
anchors.bottom: parent.bottom
width: parent.width
}
}
@@ -0,0 +1,70 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import QtQml.Models 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
Item {
id: root
property ObjectModel customButtons
readonly property alias closeButton: closeButton
readonly property alias infoButton: infoButton
implicitHeight: layout.implicitHeight
implicitWidth: layout.implicitWidth
QtObject {
id: d
readonly property int buttonSize: 32
readonly property int iconSize: 20
}
RowLayout {
id: layout
anchors.fill: parent
Repeater {
model: root.customButtons
onItemAdded: {
item.Layout.fillHeight = true
item.Layout.preferredHeight = d.buttonSize
item.Layout.preferredWidth = d.buttonSize
}
}
StatusFlatRoundButton {
id: infoButton
Layout.fillHeight: true
Layout.preferredHeight: d.buttonSize
Layout.preferredWidth: d.buttonSize
visible: false
type: StatusFlatRoundButton.Type.Secondary
icon.name: "info"
icon.color: Theme.palette.directColor1
icon.width: d.iconSize
icon.height: d.iconSize
}
StatusFlatRoundButton {
id: closeButton
Layout.fillHeight: true
Layout.preferredHeight: d.buttonSize
Layout.preferredWidth: d.buttonSize
type: StatusFlatRoundButton.Type.Secondary
icon.name: "close"
icon.color: Theme.palette.directColor1
icon.width: d.iconSize
icon.height: d.iconSize
}
}
}
@@ -0,0 +1,50 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
property alias title: title.text
property alias subtitle: subtitle.text
implicitHeight: layout.implicitHeight
implicitWidth: layout.implicitWidth
ColumnLayout {
id: layout
anchors.fill: parent
spacing: 0
StatusBaseText {
id: title
Layout.fillWidth: true
color: Theme.palette.directColor1
font {
family: Theme.palette.baseFont.name
pixelSize: 17
bold: true
}
elide: Text.ElideMiddle
}
StatusBaseText {
id: subtitle
Layout.fillWidth: true
visible: text !== ""
color: Theme.palette.baseColor1
font {
family: Theme.palette.baseFont.name
pixelSize: 15
}
elide: Text.ElideMiddle
}
}
}
+8
View File
@@ -0,0 +1,8 @@
module StatusQ.Popups.Dialog
StatusDialog 0.1 StatusDialog.qml
StatusDialogDivider 0.1 StatusDialogDivider.qml
StatusDialogFooter 0.1 StatusDialogFooter.qml
StatusDialogHeader 0.1 StatusDialogHeader.qml
StatusHeaderActions 0.1 StatusHeaderActions.qml
StatusTitleSubtitle 0.1 StatusTitleSubtitle.qml
+13 -3
View File
@@ -50,6 +50,9 @@ import "statusModal" as Spares
For a list of components available see StatusQ.
*/
// Deprecation annotations come with Qt6.2
// @Deprecated { reason: "Use StatusDialog instead, see reasoning: https://github.com/status-im/StatusQ/issues/720" }
QC.Popup {
id: statusModal
@@ -186,6 +189,12 @@ QC.Popup {
\endqml
*/
property alias hasCloseButton: headerImpl.hasCloseButton
/*!
\qmlproperty hasFloatingButtons
This property decides whether the advanced header has floating buttons on top of the Modal
\endqml
*/
property bool hasFloatingButtons: false
signal editButtonClicked()
signal headerImageClicked()
@@ -193,6 +202,7 @@ QC.Popup {
parent: QC.Overlay.overlay
width: 480
// implicitHeight: headerImpl.implicitHeight + contentItem.implicitHeight + footerImpl.implicitHeight
padding: 0
topPadding: padding + headerImpl.implicitHeight
@@ -208,7 +218,6 @@ QC.Popup {
color: Theme.palette.backdropColor
}
background: Rectangle {
color: Theme.palette.statusModal.backgroundColor
radius: 8
@@ -237,8 +246,9 @@ QC.Popup {
Loader {
id: advancedHeader
anchors.top: parent.top
anchors.topMargin: hasFloatingButtons ? -18 - height : 0
width: visible ? parent.width : 0
active: showAdvancedHeader
active: statusModal.showAdvancedHeader
}
Spares.StatusModalFooter {
@@ -252,7 +262,7 @@ QC.Popup {
id: advancedFooter
anchors.bottom: parent.bottom
width: visible ? parent.width : 0
active: showAdvancedFooter
active: statusModal.showAdvancedFooter
}
}
}
+109
View File
@@ -0,0 +1,109 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
StatusModal {
id: root
property string stackTitle: qsTr("StackModal")
property int subHeaderPadding: 16
property alias stackItems: stackLayout.children
property alias currentIndex: stackLayout.currentIndex
property alias replaceItem: replaceLoader.sourceComponent
property alias subHeaderItem: subHeaderLoader.sourceComponent
readonly property int itemsCount: stackLayout.children.length
readonly property var currentItem: stackLayout.currentItem
property Item nextButton: StatusButton {
text: qsTr("Next")
onClicked: root.currentIndex++
}
property Item finishButton: StatusButton {
text: qsTr("Finish")
onClicked: root.close()
}
function replace(item) { replaceItem = item; }
function updateRightButtons() {
if (replaceItem) {
nextButton.visible = false;
finishButton.visible = false;
} else if (currentIndex < itemsCount - 1) {
nextButton.visible = true;
finishButton.visible = false;
} else {
nextButton.visible = false;
finishButton.visible = true;
}
}
onCurrentIndexChanged: updateRightButtons()
onReplaceItemChanged: updateRightButtons()
header.title: replaceLoader.item && typeof(replaceLoader.item.title) != "undefined"
? replaceLoader.item.title : stackTitle
padding: 16
leftButtons: StatusRoundButton {
id: backButton
icon.name: "arrow-right"
icon.width: 20
icon.height: 16
rotation: 180
visible: replaceItem || stackLayout.currentIndex > 0
onClicked: {
if (replaceItem)
replaceItem = null;
else
stackLayout.currentIndex--;
}
}
rightButtons: [ nextButton, finishButton ]
Item {
id: content
anchors.fill: parent
implicitWidth: Math.max(stackLayout.implicitWidth, subHeaderLoader.implicitWidth, replaceLoader.implicitWidth)
implicitHeight: Math.max(stackLayout.implicitHeight +
(subHeaderLoader.item && subHeaderLoader.item.visible ? subHeaderLoader.height + root.subHeaderPadding : 0),
replaceLoader.implicitHeight)
Loader {
id: subHeaderLoader
anchors.top: parent.top
width: parent.width
clip: true
}
StatusAnimatedStack {
id: stackLayout
anchors.top: subHeaderLoader.bottom
anchors.topMargin: subHeaderLoader.item && subHeaderLoader.item.visible ? root.subHeaderPadding : 0
anchors.bottom: parent.bottom
width: parent.width
visible: !replaceItem
clip: true
}
Loader {
id: replaceLoader
anchors.fill: parent
visible: item
clip: true
onItemChanged: {
root.rightButtons = item ? item.rightButtons : [ nextButton, finishButton ]
if (!item && root.itemsCount == 0) {
root.close();
}
}
}
}
}
+2
View File
@@ -6,6 +6,8 @@ StatusMenuItem 0.1 StatusMenuItem.qml
StatusMenuItemDelegate 0.1 StatusMenuItemDelegate.qml
StatusMenuHeadline 0.1 StatusMenuHeadline.qml
StatusModal 0.1 StatusModal.qml
StatusStackModal 0.1 StatusStackModal.qml
StatusDialog 0.1 StatusDialog.qml
StatusSearchPopup 0.1 StatusSearchPopup.qml
StatusModalDivider 0.1 StatusModalDivider.qml
StatusSearchPopupMenuItem 0.1 StatusSearchPopupMenuItem.qml
+2 -2
View File
@@ -1,3 +1,3 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.875 3.5C8.875 3.01675 8.48325 2.625 8 2.625C7.51675 2.625 7.125 3.01675 7.125 3.5V11.5976L5.06946 9.83567C4.70255 9.52117 4.15016 9.56366 3.83567 9.93057C3.52117 10.2975 3.56366 10.8499 3.93057 11.1644L7.42712 14.1614C7.57031 14.2855 7.75421 14.3639 7.95611 14.3739C7.98615 14.3754 8.01625 14.3754 8.04628 14.3738C8.23907 14.3638 8.41535 14.2913 8.55528 14.1763C8.56004 14.1724 8.56476 14.1684 8.56946 14.1644L12.0695 11.1644C12.4364 10.8499 12.4789 10.2975 12.1644 9.93057C11.8499 9.56366 11.2975 9.52117 10.9306 9.83567L8.875 11.5976V3.5Z" fill="black"/>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.53033 13.4697C6.23744 13.1768 5.76256 13.1768 5.46967 13.4697C5.17678 13.7626 5.17678 14.2374 5.46967 14.5303L11.4697 20.5303C11.7626 20.8232 12.2374 20.8232 12.5303 20.5303L18.5303 14.5303C18.8232 14.2374 18.8232 13.7626 18.5303 13.4697C18.2374 13.1768 17.7626 13.1768 17.4697 13.4697L13.6036 17.3358C13.2886 17.6508 12.75 17.4277 12.75 16.9822L12.75 4C12.75 3.58579 12.4142 3.25 12 3.25C11.5858 3.25 11.25 3.58579 11.25 4L11.25 16.9822C11.25 17.4277 10.7114 17.6508 10.3964 17.3358L6.53033 13.4697Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 672 B

After

Width:  |  Height:  |  Size: 632 B

+2 -2
View File
@@ -1,3 +1,3 @@
<svg width="12" height="10" viewBox="0 0 12 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.0203 1.35355C5.21556 1.15829 5.21556 0.841709 5.0203 0.646447C4.82504 0.451184 4.50846 0.451184 4.31319 0.646447L0.313195 4.64645C0.117933 4.84171 0.117933 5.15829 0.313195 5.35355L4.31319 9.35355C4.50846 9.54882 4.82504 9.54882 5.0203 9.35355C5.21556 9.15829 5.21556 8.84171 5.0203 8.64645L2.44289 6.06904C2.2329 5.85905 2.38162 5.5 2.67859 5.5H11.3334C11.6096 5.5 11.8334 5.27614 11.8334 5C11.8334 4.72386 11.6096 4.5 11.3334 4.5H2.67859C2.38162 4.5 2.2329 4.14095 2.44289 3.93096L5.0203 1.35355Z" fill="#4360DF"/>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5303 6.53033C10.8232 6.23744 10.8232 5.76256 10.5303 5.46967C10.2374 5.17678 9.76256 5.17678 9.46967 5.46967L3.46967 11.4697C3.17678 11.7626 3.17678 12.2374 3.46967 12.5303L9.46967 18.5303C9.76256 18.8232 10.2374 18.8232 10.5303 18.5303C10.8232 18.2374 10.8232 17.7626 10.5303 17.4697L6.66421 13.6036C6.34923 13.2886 6.57232 12.75 7.01777 12.75H20C20.4142 12.75 20.75 12.4142 20.75 12C20.75 11.5858 20.4142 11.25 20 11.25H7.01777C6.57231 11.25 6.34923 10.7114 6.66421 10.3964L10.5303 6.53033Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 632 B

After

Width:  |  Height:  |  Size: 625 B

+2 -2
View File
@@ -1,3 +1,3 @@
<svg width="22" height="16" viewBox="0 0 22 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.7145 1.61872C12.3727 1.27701 12.3727 0.72299 12.7145 0.381282C13.0562 0.0395728 13.6102 0.0395728 13.9519 0.381282L20.9519 7.38128C21.2936 7.72299 21.2936 8.27701 20.9519 8.61872L13.9519 15.6187C13.6102 15.9604 13.0562 15.9604 12.7145 15.6187C12.3727 15.277 12.3727 14.723 12.7145 14.3813L17.2249 9.87081C17.5924 9.50333 17.3321 8.875 16.8124 8.875H1.6665C1.18326 8.875 0.791504 8.48325 0.791504 8C0.791504 7.51675 1.18326 7.125 1.6665 7.125H16.8124C17.3321 7.125 17.5924 6.49667 17.2249 6.12919L12.7145 1.61872Z" fill="#4360DF"/>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.4697 6.53033C13.1768 6.23744 13.1768 5.76256 13.4697 5.46967C13.7626 5.17678 14.2374 5.17678 14.5303 5.46967L20.5303 11.4697C20.8232 11.7626 20.8232 12.2374 20.5303 12.5303L14.5303 18.5303C14.2374 18.8232 13.7626 18.8232 13.4697 18.5303C13.1768 18.2374 13.1768 17.7626 13.4697 17.4697L17.3358 13.6036C17.6508 13.2886 17.4277 12.75 16.9822 12.75H4C3.58579 12.75 3.25 12.4142 3.25 12C3.25 11.5858 3.58579 11.25 4 11.25H16.9822C17.4277 11.25 17.6508 10.7114 17.3358 10.3964L13.4697 6.53033Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 647 B

After

Width:  |  Height:  |  Size: 620 B

Before

Width:  |  Height:  |  Size: 637 B

After

Width:  |  Height:  |  Size: 637 B

-3
View File
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.53033 13.4697C6.23744 13.1768 5.76256 13.1768 5.46967 13.4697C5.17678 13.7626 5.17678 14.2374 5.46967 14.5303L11.4697 20.5303C11.7626 20.8232 12.2374 20.8232 12.5303 20.5303L18.5303 14.5303C18.8232 14.2374 18.8232 13.7626 18.5303 13.4697C18.2374 13.1768 17.7626 13.1768 17.4697 13.4697L13.6036 17.3358C13.2886 17.6508 12.75 17.4277 12.75 16.9822L12.75 4C12.75 3.58579 12.4142 3.25 12 3.25C11.5858 3.25 11.25 3.58579 11.25 4L11.25 16.9822C11.25 17.4277 10.7114 17.6508 10.3964 17.3358L6.53033 13.4697Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 632 B

-3
View File
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5303 6.53033C10.8232 6.23744 10.8232 5.76256 10.5303 5.46967C10.2374 5.17678 9.76256 5.17678 9.46967 5.46967L3.46967 11.4697C3.17678 11.7626 3.17678 12.2374 3.46967 12.5303L9.46967 18.5303C9.76256 18.8232 10.2374 18.8232 10.5303 18.5303C10.8232 18.2374 10.8232 17.7626 10.5303 17.4697L6.66421 13.6036C6.34923 13.2886 6.57232 12.75 7.01777 12.75H20C20.4142 12.75 20.75 12.4142 20.75 12C20.75 11.5858 20.4142 11.25 20 11.25H7.01777C6.57231 11.25 6.34923 10.7114 6.66421 10.3964L10.5303 6.53033Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 625 B

-3
View File
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.4697 6.53033C13.1768 6.23744 13.1768 5.76256 13.4697 5.46967C13.7626 5.17678 14.2374 5.17678 14.5303 5.46967L20.5303 11.4697C20.8232 11.7626 20.8232 12.2374 20.5303 12.5303L14.5303 18.5303C14.2374 18.8232 13.7626 18.8232 13.4697 18.5303C13.1768 18.2374 13.1768 17.7626 13.4697 17.4697L17.3358 13.6036C17.6508 13.2886 17.4277 12.75 16.9822 12.75H4C3.58579 12.75 3.25 12.4142 3.25 12C3.25 11.5858 3.58579 11.25 4 11.25H16.9822C17.4277 11.25 17.6508 10.7114 17.3358 10.3964L13.4697 6.53033Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 620 B

+5
View File
@@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.37002 1.97C3.07691 1.67733 2.60203 1.67769 2.30936 1.9708C2.01669 2.26391 2.01704 2.73879 2.31016 3.03146L5.92499 6.64087C6.04311 6.75882 6.09312 6.92771 6.06808 7.09274C6.02321 7.38862 5.99994 7.6916 5.99994 8.00001C5.99994 10.9077 8.06828 13.3323 10.8139 13.8828C11.0612 13.9324 11.2499 14.1429 11.2499 14.3951V21C11.2499 21.4142 11.5857 21.75 11.9999 21.75C12.4141 21.75 12.7499 21.4142 12.7499 21V14.3951C12.7499 14.2383 12.8229 14.0976 12.9375 14.0017C13.0673 13.8931 13.2515 13.9564 13.3713 14.076L20.3136 21.0079C20.6067 21.3005 21.0816 21.3002 21.3743 21.0071C21.6669 20.714 21.6666 20.2391 21.3735 19.9464L14.7524 13.3353C14.7516 13.3345 14.7518 13.3331 14.7528 13.3326C14.7538 13.3321 14.754 13.3308 14.7532 13.33L13.6224 12.2009C13.6214 12.1999 13.6199 12.1996 13.6186 12.2001C13.6172 12.2006 13.6157 12.2003 13.6147 12.1993L7.79821 6.39155C7.7972 6.39054 7.79688 6.38903 7.79739 6.3877C7.7979 6.38637 7.79758 6.38486 7.79657 6.38385L6.6658 5.25477C6.66501 5.25398 6.66368 5.25419 6.66317 5.25518C6.66266 5.25617 6.66134 5.25638 6.66055 5.25559L3.37002 1.97ZM10.8735 11.582C11.1968 11.9048 10.9547 12.402 10.5231 12.2521C9.22795 11.8023 8.20173 10.7775 7.75007 9.48315C7.59954 9.05177 8.09632 8.80894 8.41963 9.13176L10.8735 11.582Z" fill="black"/>
<path d="M16.4999 8.00001C16.4999 9.07008 16.1264 10.0529 15.5027 10.8253C15.3285 11.041 15.3253 11.3576 15.5215 11.5535L15.8748 11.9063C16.0696 12.1008 16.3868 12.1025 16.5655 11.8932C17.46 10.8453 17.9999 9.48569 17.9999 8.00001C17.9999 4.6863 15.3136 2.00001 11.9999 2.00001C10.511 2.00001 9.14876 2.54235 8.09994 3.44025C7.89082 3.61929 7.89302 3.93647 8.08782 4.13099L8.44113 4.48376C8.63734 4.67968 8.95397 4.67604 9.16942 4.5015C9.94257 3.87521 10.9274 3.50001 11.9999 3.50001C14.4852 3.50001 16.4999 5.51473 16.4999 8.00001Z" fill="black"/>
<path d="M14.8955 7.28455C14.8955 6.45613 14.2473 5.60893 13.4477 5.39228C12.6481 5.17564 11.9999 5.67158 11.9999 6.50001C11.9999 7.32844 12.6481 8.17564 13.4477 8.39228C14.2473 8.60893 14.8955 8.11298 14.8955 7.28455Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

+8
View File
@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">
<path d="M17.9962 1.51313L7.87688 18.3056L17.9962 13.7063V1.51313Z" fill="#8A92B2"/>
<path d="M17.9962 13.7063L7.87688 18.3056L17.9962 24.2888V13.7063Z" fill="#62688F"/>
<path d="M28.1175 18.3056L17.9962 1.51313V13.7063L28.1175 18.3056Z" fill="#62688F"/>
<path d="M17.9962 24.2888L28.1175 18.3056L17.9962 13.7063V24.2888Z" fill="#454A75"/>
<path d="M7.87688 20.2256L17.9962 34.4869V26.205L7.87688 20.2256Z" fill="#8A92B2"/>
<path d="M17.9962 26.205V34.4869L28.1231 20.2256L17.9962 26.205Z" fill="#62688F"/>
</svg>

After

Width:  |  Height:  |  Size: 575 B

+36 -3
View File
@@ -30,8 +30,8 @@ Consider that design follows user-friendlier principles.
- Have transition if possible
- Use Qt's property animation for states
- Avoid often and radical size changes to items in views/layouts. Radical size change confuses users.
- If the content is not available, consider having placeholders using the estimated size
(delegates, dummy items)
- If the content is not available, consider having placeholders using the estimated size
(delegates, dummy items)
Have the base control as the component's root. This way, control inherits all the interface and reduce the code.
If it doesn't map to an existing one, use a base control like `Item`.
@@ -46,6 +46,7 @@ If it doesn't map to an existing one, use a base control like `Item`.
[Positioners and Layouts In QML](https://doc.qt.io/qt-6/qtquick-usecase-layouts.html)
- Define size hints appropriately. Define implicit properties (`impicitWidth` and `implicitHeight`)
- They are used to break polishing binding loops for adaptive control
- All the containers use the implicit size for deriving the initial size (Layouts, Popups, Delegates, GridView, ListView ...). Size hints combined with resize adaptability are the appropriate way to have reactive controls.
- For complex controls, look if layouts are the choice as the main position driver. [Layouts](###Layouts)
@@ -96,6 +97,7 @@ Use `Layout.preferredWidth` and `Layout.preferredHeight` attached properties to
Follow [Qt's recommendations](https://doc.qt.io/qt-5/qtqml-documents-scope.html) if appropriate
- Avoid dynamic scoping in out-of-line components, see more: https://doc.qt.io/qt-5/qtqml-documents-scope.html#component-instance-hierarchy
- Example
```qml
@@ -115,6 +117,37 @@ Follow [Qt's recommendations](https://doc.qt.io/qt-5/qtqml-documents-scope.html)
- If in doubt, explicitly use an instance variable to access properties
- If the scope is clear and there is no ambiguity, use the property directly for readability
### Popups content sizing
As stated in Qt documentation on Popup content sizing:
1. `Popup` size is as calculated internally as `contentItem.implicitSize + paddings`
2. The size of `contentItem` is managed by the popup to fit the Popup and paddings
It's important to understand that `Popup.contentItem` is an internal invisible Item. Any user items will be parented to the `contentItem`, not the `Popup` itself.
Knowing this, we make a simple rule to choose one of 2 ways for popup content sizing:
1. Replace the `contentItem` with your item, but don't explicitly anchor or bind it's sizes, because the size of `contentItem` is managed by the popup.
```qml
Popup {
contentItem: ColumnLayout {
// no anchoring or binding
}
}
```
2. Don't touch the `contentItem` property, but create a single child to the popup and **anchor it to `parent`**.
```qml
Popup {
ColumnLayout {
anchors.fill: parent // parent is contentItem, not Popup
}
}
```
## Testing
Test in isolation
@@ -130,7 +163,7 @@ Integration tests
Try scenarios
- Embed in Layouts with different properties: fixed size, min-max, not size set
```qml
Window {
width: mainLayout.implicitWidth
+11 -4
View File
@@ -221,7 +221,6 @@
<file>src/assets/img/icons/delete.svg</file>
<file>src/assets/img/icons/desktop.svg</file>
<file>src/assets/img/icons/double-checkmark.svg</file>
<file>src/assets/img/icons/down.svg</file>
<file>src/assets/img/icons/download.svg</file>
<file>src/assets/img/icons/edit.svg</file>
<file>src/assets/img/icons/emojis.svg</file>
@@ -253,7 +252,6 @@
<file>src/assets/img/icons/keycard.svg</file>
<file>src/assets/img/icons/language.svg</file>
<file>src/assets/img/icons/ledger.svg</file>
<file>src/assets/img/icons/left.svg</file>
<file>src/assets/img/icons/link.svg</file>
<file>src/assets/img/icons/loading.svg</file>
<file>src/assets/img/icons/location.svg</file>
@@ -291,7 +289,6 @@
<file>src/assets/img/icons/remove-contact.svg</file>
<file>src/assets/img/icons/remove.svg</file>
<file>src/assets/img/icons/reply.svg</file>
<file>src/assets/img/icons/right.svg</file>
<file>src/assets/img/icons/rotate.svg</file>
<file>src/assets/img/icons/search.svg</file>
<file>src/assets/img/icons/secret.svg</file>
@@ -370,7 +367,6 @@
<file>src/assets/img/icons/travel-and-places.svg</file>
<file>src/assets/img/icons/tributeToTalk.svg</file>
<file>src/assets/img/icons/union.svg</file>
<file>src/assets/img/icons/up.svg</file>
<file>src/assets/img/icons/username.svg</file>
<file>src/assets/img/icons/wallet.svg</file>
<file>src/assets/img/icons/warning.svg</file>
@@ -10502,5 +10498,16 @@
<file>src/assets/twemoji/LICENSE</file>
<file>src/StatusQ/Controls/StatusTabBar.qml</file>
<file>src/StatusQ/Controls/StatusTagItem.qml</file>
<file>src/StatusQ/Animations/SkeletonAnimation.qml</file>
<file>src/StatusQ/Animations/SkeletonGradientStop.qml</file>
<file>src/StatusQ/Animations/qmldir</file>
<file>src/assets/img/icons/arrow-up.svg</file>
<file>src/StatusQ/Popups/Dialog/qmldir</file>
<file>src/StatusQ/Popups/Dialog/StatusDialog.qml</file>
<file>src/StatusQ/Popups/Dialog/StatusTitleSubtitle.qml</file>
<file>src/StatusQ/Popups/Dialog/StatusHeaderActions.qml</file>
<file>src/StatusQ/Popups/Dialog/StatusDialogHeader.qml</file>
<file>src/StatusQ/Popups/Dialog/StatusDialogFooter.qml</file>
<file>src/StatusQ/Popups/Dialog/StatusDialogDivider.qml</file>
</qresource>
</RCC>