Compare commits
111
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45d7d80755 | ||
|
|
7fc207f75f | ||
|
|
caaa2fc53b | ||
|
|
98aa6a4b27 | ||
|
|
b3ceb0aad9 | ||
|
|
fa16c32316 | ||
|
|
4282cc10c4 | ||
|
|
e5ddf28f02 | ||
|
|
4937681645 | ||
|
|
39b1bcfe6b | ||
|
|
56f36ed627 | ||
|
|
789b773649 | ||
|
|
ad962a6009 | ||
|
|
f09565a4fa | ||
|
|
d08339a7b0 | ||
|
|
5c24767310 | ||
|
|
737b9cfb3f | ||
|
|
10d312ec8f | ||
|
|
2a377533f8 | ||
|
|
25e3c5526a | ||
|
|
94e59e1bf0 | ||
|
|
3ac0187923 | ||
|
|
a563687bf5 | ||
|
|
40992f6718 | ||
|
|
9738890d9d | ||
|
|
9dc2b10448 | ||
|
|
9df658a574 | ||
|
|
4b4b0950a6 | ||
|
|
7b047a4b26 | ||
|
|
cff836280f | ||
|
|
e432efac28 | ||
|
|
4dec615cea | ||
|
|
f4bf830ae7 | ||
|
|
dbc0c1960a | ||
|
|
03fe75c875 | ||
|
|
26eaeb3ad5 | ||
|
|
462b905c5c | ||
|
|
4e048f724c | ||
|
|
e6be4d9bad | ||
|
|
e184348190 | ||
|
|
2270526071 | ||
|
|
d412fe208e | ||
|
|
0040a2d86b | ||
|
|
431aab7bb8 | ||
|
|
938ae6afd8 | ||
|
|
63c008571e | ||
|
|
08c53e2f52 | ||
|
|
64ec74117d | ||
|
|
e5ab0cd2a7 | ||
|
|
5f1df089eb | ||
|
|
b30f7b3ac5 | ||
|
|
ac37549f62 | ||
|
|
a60c44e387 | ||
|
|
694010da38 | ||
|
|
c0c240ed6a | ||
|
|
39c1ba4e66 | ||
|
|
3954d49266 | ||
|
|
7f99acf32d | ||
|
|
59b2fe4641 | ||
|
|
2f650dc745 | ||
|
|
795370086b | ||
|
|
c0057daa7a | ||
|
|
08f8cd60c4 | ||
|
|
bce53e9ccc | ||
|
|
930fa3daf0 | ||
|
|
bc5c86a2a4 | ||
|
|
ed6aaab441 | ||
|
|
442ffb9feb | ||
|
|
132cfda244 | ||
|
|
9b89e08294 | ||
|
|
df60ec047a | ||
|
|
c9931f95f0 | ||
|
|
6504543518 | ||
|
|
9b7772be3b | ||
|
|
21669aba17 | ||
|
|
113f700617 | ||
|
|
fb99107bae | ||
|
|
9b9b3fcfff | ||
|
|
f19f208b3c | ||
|
|
4fa885ccea | ||
|
|
e0fd627050 | ||
|
|
06fad29b63 | ||
|
|
e7b80a9ae2 | ||
|
|
24a0e7472d | ||
|
|
45d8990067 | ||
|
|
c0d434bbdf | ||
|
|
c697467c68 | ||
|
|
e2d42289f7 | ||
|
|
e781645a58 | ||
|
|
c98f144fd8 | ||
|
|
016a0eac46 | ||
|
|
29a61c7f5c | ||
|
|
a8b9020a4b | ||
|
|
8caf994220 | ||
|
|
7709810ae2 | ||
|
|
d8e3557f8f | ||
|
|
59143f7f34 | ||
|
|
cb4094b128 | ||
|
|
99457ee77f | ||
|
|
c41318d5e8 | ||
|
|
dbcf4565f4 | ||
|
|
9b1a033571 | ||
|
|
25600ec624 | ||
|
|
2b4398830a | ||
|
|
05250a6eab | ||
|
|
9a2e28f2a7 | ||
|
|
a35d3dca8c | ||
|
|
7363899a96 | ||
|
|
c921cf7280 | ||
|
|
e16804c4f0 | ||
|
|
f7c7f004e2 |
@@ -0,0 +1,3 @@
|
||||
[submodule "vendor/SortFilterProxyModel"]
|
||||
path = vendor/SortFilterProxyModel
|
||||
url = https://github.com/status-im/SortFilterProxyModel.git
|
||||
@@ -2,4 +2,22 @@ cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
project(StatusQ)
|
||||
|
||||
if (APPLE)
|
||||
set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=10.14)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||
endif()
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# https://doc.qt.io/qtcreator/creator-qml-modules-with-plugins.html#importing-qml-modules
|
||||
set(QML_IMPORT_PATH
|
||||
${CMAKE_SOURCE_DIR}/src;${QML_IMPORT_PATH}
|
||||
CACHE STRING "")
|
||||
|
||||
add_subdirectory(vendor/SortFilterProxyModel)
|
||||
add_subdirectory(sandbox)
|
||||
add_subdirectory(tests)
|
||||
|
||||
@@ -36,7 +36,7 @@ To make viewing and testing components easy, we've added a sandbox application t
|
||||
|
||||
### Using Qt Creator
|
||||
|
||||
The easiest way to run the sandbox application is to simply open the provided `sandbox.pro` file using Qt Creator.
|
||||
The easiest way to run the sandbox application is to simply open the provided `CMakeLists.txt` file using Qt Creator.
|
||||
|
||||
### Using command line interface
|
||||
|
||||
@@ -44,14 +44,13 @@ To run the sandbox from within a command line interface, run the following comma
|
||||
|
||||
```
|
||||
$ git clone https://github.com/status-im/StatusQ
|
||||
$ cd StatusQ/sandbox
|
||||
$ ./scripts/build
|
||||
$ cd StatusQ
|
||||
$ git submodule update --init
|
||||
$ ./sandbox/scripts/build
|
||||
```
|
||||
|
||||
Once that is done, the sandbox can be started with the generated executable:
|
||||
|
||||
```
|
||||
$ ./bin/sandbox
|
||||
$ ./build/sandbox/Sandbox
|
||||
```
|
||||
|
||||
More Documentation available on the [wiki](https://hackmd.io/@status-desktop/B1naRjxh_/%2FwFtiXvOiQqCdw2lk6gbOLA)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -20,6 +20,7 @@
|
||||
\li \l{StatusChatToolBar}
|
||||
\li \l{StatusContactRequestsIndicatorListItem}
|
||||
\li \l{StatusDescriptionListItem}
|
||||
\li \l{StatusItemSelector}
|
||||
\li \l{StatusLetterIdenticon}
|
||||
\li \l{StatusListItem}
|
||||
\li \l{StatusListPicker}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
\li \l{StatusChatInfoButton}
|
||||
\li \l{StatusChatListCategoryItemButton}
|
||||
\li \l{StatusColorSelector}
|
||||
\li \l{StatusDropdown}
|
||||
\li \l{StatusIconTabButton}
|
||||
\li \l{StatusNavBarTabButton}
|
||||
\li \l{StatusTabBarIconButton}
|
||||
@@ -30,6 +31,7 @@
|
||||
\li \l{StatusSlider}
|
||||
\li \l{StatusSelect}
|
||||
\li \l{StatusBaseInput}
|
||||
\li \l{StatusIconTextButton}
|
||||
\li \l{StatusIdenticonRing}
|
||||
\li \l{StatusInput}
|
||||
\li \l{StatusItemPicker}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
\list
|
||||
\li \l{StatusAppNavBarFilterModel}
|
||||
\li \l{StatusBaseText}
|
||||
\li \l{StatusFontSettings}
|
||||
\li \l{StatusIcon}
|
||||
\li \l{StatusIconBackgroundSettings}
|
||||
\li \l{StatusIconSettings}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
project(Sandbox)
|
||||
|
||||
find_package(
|
||||
Qt5
|
||||
COMPONENTS Core Quick QuickControls2
|
||||
REQUIRED)
|
||||
|
||||
file(GLOB_RECURSE QML_FILES "../*.qml")
|
||||
file(GLOB_RECURSE JS_FILES "../*.js")
|
||||
file(GLOB_RECURSE HEADERS *.h)
|
||||
if(APPLE)
|
||||
file(GLOB_RECURSE SOURCES *.cpp *.mm)
|
||||
else()
|
||||
file(GLOB_RECURSE SOURCES *.cpp)
|
||||
endif()
|
||||
|
||||
qt5_add_big_resources(QRC_FILES qml.qrc ../src/statusq.qrc ../src/assets.qrc)
|
||||
|
||||
add_executable(
|
||||
${PROJECT_NAME}
|
||||
${HEADERS}
|
||||
${SOURCES}
|
||||
${QRC_FILES}
|
||||
${QML_FILES}
|
||||
${JS_FILES})
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PRIVATE SRC_DIR="${CMAKE_CURRENT_LIST_DIR}")
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick Qt5::QuickControls2
|
||||
SortFilterProxyModel)
|
||||
|
||||
if (APPLE)
|
||||
find_library(AppKit AppKit)
|
||||
find_library(Foundation Foundation)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${AppKit} ${Foundation})
|
||||
endif()
|
||||
+1
-3
@@ -174,9 +174,7 @@ Rectangle {
|
||||
|
||||
StatusMenuItem {
|
||||
text: qsTr("Leave Community")
|
||||
icon.name: "arrow-right"
|
||||
icon.width: 14
|
||||
iconRotation: 180
|
||||
icon.name: "arrow-left"
|
||||
type: StatusMenuItem.Type.Danger
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,24 @@ Column {
|
||||
|
||||
horizontalItemAlignment: Grid.AlignHCenter
|
||||
|
||||
// Primary
|
||||
StatusButton {
|
||||
text: "Button"
|
||||
type: StatusBaseButton.Type.Primary
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Button"
|
||||
enabled: false
|
||||
type: StatusBaseButton.Type.Primary
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Button"
|
||||
loading: true
|
||||
type: StatusBaseButton.Type.Primary
|
||||
}
|
||||
|
||||
// Large
|
||||
StatusButton {
|
||||
text: "Button"
|
||||
@@ -343,4 +361,26 @@ Column {
|
||||
text: "Button with Emoji"
|
||||
icon.emoji: "🖼️️"
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 20
|
||||
|
||||
StatusIconTextButton {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
spacing: 0
|
||||
statusIcon: "next"
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
iconRotation: 180
|
||||
text: "Previous page"
|
||||
font.pixelSize: 15
|
||||
onClicked: testText.visible = !testText.visible
|
||||
}
|
||||
StatusBaseText {
|
||||
id: testText
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "Click and hide!"
|
||||
font.pixelSize: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,14 +32,14 @@ GridLayout {
|
||||
}
|
||||
|
||||
StatusIconTabButton {
|
||||
icon.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
icon.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
}
|
||||
|
||||
StatusIconTabButton {
|
||||
icon.color: Theme.palette.miscColor9
|
||||
// This icon source is flawed and demonstrates the fallback case
|
||||
// when the image source can't be loaded
|
||||
icon.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jp"
|
||||
icon.source: "https://httpstat.us/404"
|
||||
name: "Pascal"
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ GridLayout {
|
||||
}
|
||||
|
||||
StatusNavBarTabButton {
|
||||
icon.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
icon.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
tooltip.text: "Some Community"
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ GridLayout {
|
||||
title: "Iuri Matias"
|
||||
subTitle: "Contact"
|
||||
icon.color: Theme.palette.miscColor7
|
||||
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
type: StatusChatInfoButton.Type.OneToOneChat
|
||||
muted: true
|
||||
pinnedMessagesCount: 1
|
||||
@@ -137,7 +137,7 @@ GridLayout {
|
||||
title: "Iuri Matias elided"
|
||||
subTitle: "Contact"
|
||||
icon.color: Theme.palette.miscColor7
|
||||
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
type: StatusChatInfoButton.Type.OneToOneChat
|
||||
muted: true
|
||||
pinnedMessagesCount: 1
|
||||
@@ -152,7 +152,7 @@ GridLayout {
|
||||
title: "Iuri Matias big not elided"
|
||||
subTitle: "Contact"
|
||||
icon.color: Theme.palette.miscColor7
|
||||
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
type: StatusChatInfoButton.Type.OneToOneChat
|
||||
muted: true
|
||||
pinnedMessagesCount: 1
|
||||
|
||||
@@ -223,9 +223,7 @@ Column {
|
||||
|
||||
StatusMenuItem {
|
||||
text: qsTr("Leave Community")
|
||||
icon.name: "arrow-right"
|
||||
icon.width: 14
|
||||
iconRotation: 180
|
||||
icon.name: "arrow-left"
|
||||
type: StatusMenuItem.Type.Danger
|
||||
}
|
||||
}
|
||||
@@ -308,9 +306,7 @@ Column {
|
||||
|
||||
StatusMenuItem {
|
||||
text: qsTr("Leave Community")
|
||||
icon.name: "arrow-right"
|
||||
icon.width: 14
|
||||
iconRotation: 180
|
||||
icon.name: "arrow-left"
|
||||
type: StatusMenuItem.Type.Danger
|
||||
}
|
||||
}
|
||||
@@ -398,9 +394,7 @@ Column {
|
||||
|
||||
StatusMenuItem {
|
||||
text: qsTr("Leave Community")
|
||||
icon.name: "arrow-right"
|
||||
icon.width: 14
|
||||
iconRotation: 180
|
||||
icon.name: "arrow-left"
|
||||
type: StatusMenuItem.Type.Danger
|
||||
}
|
||||
}
|
||||
@@ -493,9 +487,7 @@ Column {
|
||||
|
||||
StatusMenuItem {
|
||||
text: qsTr("Leave Community")
|
||||
icon.name: "arrow-right"
|
||||
icon.width: 14
|
||||
iconRotation: 180
|
||||
icon.name: "arrow-left"
|
||||
type: StatusMenuItem.Type.Danger
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,13 +73,13 @@ GridLayout {
|
||||
|
||||
StatusChatListItem {
|
||||
name: "community-channel-with-image"
|
||||
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
type: StatusChatListItem.Type.CommunityChat
|
||||
}
|
||||
|
||||
StatusChatListItem {
|
||||
name: "Weird Crazy Otter"
|
||||
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
type: StatusChatListItem.Type.OneToOneChat
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ GridLayout {
|
||||
StatusListItem {
|
||||
title: "Title"
|
||||
subTitle: "Subtitle"
|
||||
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
}
|
||||
|
||||
StatusListItem {
|
||||
@@ -314,7 +314,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
|
||||
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
image.isIdenticon: true
|
||||
badge.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
badge.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
badge.primaryText: "CryptoKitties"
|
||||
badge.secondaryText: "#test"
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
StatusRoundedImage {
|
||||
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
}
|
||||
|
||||
StatusBadge {}
|
||||
@@ -57,5 +57,8 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusDatePicker {
|
||||
label: "Select date"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ 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 {
|
||||
@@ -110,7 +109,7 @@ Column {
|
||||
anchors.centerIn: parent
|
||||
header.title: "Some Title"
|
||||
header.subTitle: "Subtitle"
|
||||
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
header.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
}
|
||||
|
||||
StatusModal {
|
||||
@@ -118,12 +117,9 @@ Column {
|
||||
anchors.centerIn: parent
|
||||
header.title: "Some Title"
|
||||
header.subTitle: "Subtitle"
|
||||
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
header.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
leftButtons: [
|
||||
StatusRoundButton {
|
||||
icon.name: "arrow-right"
|
||||
rotation: 180
|
||||
}
|
||||
StatusBackButton { }
|
||||
]
|
||||
rightButtons: [
|
||||
StatusButton {
|
||||
@@ -140,7 +136,7 @@ Column {
|
||||
anchors.centerIn: parent
|
||||
header.title: "Some Title"
|
||||
header.subTitle: "Subtitle"
|
||||
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
header.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
|
||||
headerActionButton: StatusFlatRoundButton {
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
@@ -153,10 +149,7 @@ Column {
|
||||
}
|
||||
|
||||
leftButtons: [
|
||||
StatusRoundButton {
|
||||
icon.name: "arrow-right"
|
||||
rotation: 180
|
||||
}
|
||||
StatusBackButton { }
|
||||
]
|
||||
rightButtons: [
|
||||
StatusButton {
|
||||
@@ -171,7 +164,7 @@ Column {
|
||||
StatusModal {
|
||||
id: modalExample
|
||||
anchors.centerIn: parent
|
||||
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
header.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
header.title: "Header"
|
||||
header.subTitle: "SubTitle"
|
||||
rightButtons: [
|
||||
@@ -184,10 +177,7 @@ Column {
|
||||
]
|
||||
|
||||
leftButtons: [
|
||||
StatusRoundButton {
|
||||
icon.name: "arrow-right"
|
||||
rotation: 180
|
||||
}
|
||||
StatusBackButton { }
|
||||
]
|
||||
|
||||
contentItem: StatusBaseText {
|
||||
@@ -419,6 +409,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
height: button.height
|
||||
radius: 8
|
||||
visible: visibleIndices.includes(index)
|
||||
color: Theme.palette.statusAppLayout.backgroundColor
|
||||
StatusButton {
|
||||
id: button
|
||||
topPadding: 8
|
||||
|
||||
@@ -41,7 +41,7 @@ ListView {
|
||||
}
|
||||
messageText: model.message
|
||||
hasMention: model.hasMention
|
||||
isMutualContact: model.isMutualContact
|
||||
isContact: model.isContact
|
||||
trustIndicator: model.trustIndicator
|
||||
isPinned: model.isPinned
|
||||
pinnedBy: model.pinnedBy
|
||||
|
||||
@@ -20,6 +20,7 @@ Page {
|
||||
height: tagSelector.height
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 8
|
||||
spacing: 16
|
||||
|
||||
StatusTagSelector {
|
||||
id: tagSelector
|
||||
@@ -73,27 +74,43 @@ Page {
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
implicitWidth: 106
|
||||
implicitHeight: 44
|
||||
Layout.alignment: Qt.AlignTop
|
||||
enabled: (tagSelector.namesModel.count > 0)
|
||||
text: "Confirm"
|
||||
}
|
||||
|
||||
Item {
|
||||
implicitHeight: 32
|
||||
implicitWidth: 32
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
StatusActivityCenterButton {
|
||||
id: notificationButton
|
||||
anchors.right: parent.right
|
||||
unreadNotificationsCount: 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 68
|
||||
|
||||
StatusBaseText {
|
||||
visible: (contactsModel.count === 0)
|
||||
anchors.centerIn: parent
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 252
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 252
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -(headerRow.height/2)
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: 15
|
||||
visible: contactsModel.count === 0
|
||||
wrapMode: Text.WordWrap
|
||||
color: Theme.palette.baseColor1
|
||||
text: qsTr("You can only send direct messages to your Contacts. \n\n
|
||||
Send a contact request to the person you would like to chat with, you will be\n able to
|
||||
chat with them once they have accepted your contact request.")
|
||||
text: qsTr("You can only send direct messages to your Contacts.\n
|
||||
Send a contact request to the person you would like to chat with, you will be able to chat with them once they have accepted your contact request.")
|
||||
Component.onCompleted: {
|
||||
if (visible) {
|
||||
tagSelector.enabled = false;
|
||||
|
||||
@@ -13,7 +13,7 @@ StatusModal {
|
||||
|
||||
header.title: "Cryptokitties"
|
||||
header.subTitle: "Public Community"
|
||||
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
header.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
|
||||
contentItem: Column {
|
||||
width: root.width
|
||||
@@ -103,8 +103,7 @@ StatusModal {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
statusListItemTitle.font.pixelSize: 17
|
||||
title: "Leave community"
|
||||
icon.name: "arrow-right"
|
||||
icon.rotation: 180
|
||||
icon.name: "arrow-left"
|
||||
type: StatusListItem.Type.Secondary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,53 +16,78 @@ StatusAppThreePanelLayout {
|
||||
|
||||
leftPanel: Item {
|
||||
anchors.fill: parent
|
||||
|
||||
StatusNavigationPanelHeadline {
|
||||
id: headline
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 16
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: "Chat"
|
||||
}
|
||||
|
||||
anchors.margins: 16
|
||||
RowLayout {
|
||||
id: searchInputWrapper
|
||||
width: 288
|
||||
height: searchInput.height
|
||||
anchors.top: headline.bottom
|
||||
anchors.topMargin: 16
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width
|
||||
|
||||
StatusBaseInput {
|
||||
id: searchInput
|
||||
Layout.fillWidth: true
|
||||
StatusNavigationPanelHeadline {
|
||||
id: headline
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
implicitHeight: 36
|
||||
topPadding: 8
|
||||
bottomPadding: 8
|
||||
placeholderText: "Search"
|
||||
icon.name: "search"
|
||||
text: "Chat"
|
||||
}
|
||||
|
||||
StatusIconTabButton {
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
|
||||
StatusRoundButton {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.name: "public-chat"
|
||||
icon.color: Theme.palette.directColor1
|
||||
icon.height: editBtn.icon.height
|
||||
icon.width: editBtn.icon.width
|
||||
implicitWidth: editBtn.implicitWidth
|
||||
implicitHeight: editBtn.implicitHeight
|
||||
type: StatusRoundButton.Type.Tertiary
|
||||
StatusToolTip {
|
||||
text: qsTr("Join public chats")
|
||||
visible: parent.hovered
|
||||
orientation: StatusToolTip.Orientation.Bottom
|
||||
y: parent.height + 12
|
||||
}
|
||||
}
|
||||
|
||||
StatusIconTabButton {
|
||||
id: editBtn
|
||||
icon.name: "edit"
|
||||
icon.color: Theme.palette.directColor1
|
||||
checked: root.createChat
|
||||
highlighted: checked
|
||||
onClicked: {
|
||||
root.createChat = !root.createChat;
|
||||
}
|
||||
StatusToolTip {
|
||||
text: qsTr("Start chat")
|
||||
visible: parent.hovered
|
||||
orientation: StatusToolTip.Orientation.Bottom
|
||||
y: parent.height + 12
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
StatusInput {
|
||||
id: searchInput
|
||||
anchors.top: searchInputWrapper.bottom
|
||||
anchors.topMargin: 16
|
||||
width: parent.width
|
||||
maximumHeight: 36
|
||||
topPadding: 8
|
||||
bottomPadding: 8
|
||||
placeholderText: "Search"
|
||||
input.icon.name: "search"
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
anchors.top: searchInput.bottom
|
||||
anchors.topMargin: 16
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: 8
|
||||
|
||||
StatusContactRequestsIndicatorListItem {
|
||||
width: parent.width
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
title: "Contact requests"
|
||||
requestsCount: 3
|
||||
@@ -70,6 +95,7 @@ StatusAppThreePanelLayout {
|
||||
}
|
||||
|
||||
StatusChatList {
|
||||
width: parent.width
|
||||
model: Models.demoChatListItems
|
||||
highlightItem: !root.createChat
|
||||
onChatItemUnmuted: {
|
||||
@@ -173,9 +199,7 @@ StatusAppThreePanelLayout {
|
||||
|
||||
StatusMenuItem {
|
||||
text: "Leave Chat"
|
||||
icon.name: "arrow-right"
|
||||
icon.width: 14
|
||||
iconRotation: 180
|
||||
icon.name: "arrow-left"
|
||||
type: StatusMenuItem.Type.Danger
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import StatusQ.Components 0.1
|
||||
import "../demoapp/data" 1.0
|
||||
|
||||
|
||||
ScrollView {
|
||||
StatusScrollView {
|
||||
id: root
|
||||
|
||||
QtObject {
|
||||
|
||||
@@ -33,7 +33,7 @@ StatusAppThreePanelLayout {
|
||||
|
||||
chatInfoButton.title: "CryptoKitties"
|
||||
chatInfoButton.subTitle: "128 Members"
|
||||
chatInfoButton.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
chatInfoButton.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
chatInfoButton.icon.color: Theme.palette.miscColor6
|
||||
chatInfoButton.onClicked: { chatInfoButtonClicked(); }
|
||||
|
||||
@@ -59,7 +59,7 @@ StatusAppThreePanelLayout {
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
StatusScrollView {
|
||||
id: scrollView
|
||||
|
||||
anchors.top: statusChatInfoToolBar.bottom
|
||||
|
||||
@@ -3,6 +3,7 @@ import QtQuick.Controls 2.14
|
||||
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Layout 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import "data" 1.0
|
||||
@@ -21,7 +22,7 @@ StatusAppTwoPanelLayout {
|
||||
text: "Profile"
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
StatusScrollView {
|
||||
anchors.top: profileHeadline.bottom
|
||||
anchors.topMargin: 16
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
@@ -316,9 +316,9 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
//dummy search popup models
|
||||
property var searchResultsA: ListModel {
|
||||
ListElement { itemId: "i1"; titleId: "t1"; title: "@Flea"; sectionName: "Messages"; time: "18:55 AM"; content: "lorem ipsum <font color='#4360DF'>@Nick</font> dolor sit amet";
|
||||
image: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg";
|
||||
image: "qrc:/demoapp/data/profile-image-1.jpeg";
|
||||
color: "orange";
|
||||
badgeImage: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg";
|
||||
badgeImage: "qrc:/demoapp/data/profile-image-1.jpeg";
|
||||
badgePrimaryText: "CryptoKities";
|
||||
badgeSecondaryText: "";
|
||||
badgeIconColor: "";
|
||||
@@ -361,7 +361,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
ListElement {
|
||||
value: "sub_item_1_1"
|
||||
text: "Profile image item"
|
||||
imageSource: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
imageSource: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
iconName: ""
|
||||
iconColor: ""
|
||||
},
|
||||
@@ -375,7 +375,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
ListElement {
|
||||
value: "item_2"
|
||||
title: "Community item";
|
||||
imageSource: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
imageSource: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
iconName: ""
|
||||
iconColor: ""
|
||||
subItems: [
|
||||
@@ -446,7 +446,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f5789"
|
||||
isMutualContact: true
|
||||
isContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -475,7 +475,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f2333"
|
||||
isMutualContact: true
|
||||
isContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -503,7 +503,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAkUlEQVR4nOzYwQmDQBQG4SSkl3SQyizDyuzAavTi0cPK8sPwM9/Rw8rw4KH7eZUwhMYQGkNoDKGpCfmmDl63/bh7vvx/78T7aiZiCI0hNMMbJL2FZs+vmYghNIbQTG+cp9smtf1qJmIIjSEKqZmIITSG0Azfa6W/qfxDvBhCY4hCaiZiCI0hNIbQGEJzBgAA///3pSBjX42sYAAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f2333"
|
||||
isMutualContact: true
|
||||
isContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -531,7 +531,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f6789"
|
||||
isMutualContact: false
|
||||
isContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -560,7 +560,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: true
|
||||
isContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -589,7 +589,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
isContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -618,7 +618,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
isContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
hasMention: true
|
||||
editMode: false
|
||||
@@ -648,7 +648,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
isContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -678,7 +678,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
isContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -708,7 +708,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
isContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -738,7 +738,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
isContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -767,7 +767,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
isContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -795,7 +795,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: true
|
||||
isContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -823,7 +823,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: true
|
||||
isContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
hasMention: false
|
||||
editMode: false
|
||||
@@ -913,8 +913,19 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
notificationsCount: 0
|
||||
}
|
||||
ListElement {
|
||||
sectionId: "demoApp"
|
||||
sectionId: "examples"
|
||||
sectionType: 101
|
||||
name: "Examples"
|
||||
active: false
|
||||
image: ""
|
||||
icon: "show"
|
||||
color: ""
|
||||
hasNotification: false
|
||||
notificationsCount: 0
|
||||
}
|
||||
ListElement {
|
||||
sectionId: "demoApp"
|
||||
sectionType: 102
|
||||
name: "Demo Application"
|
||||
active: false
|
||||
image: ""
|
||||
@@ -1000,7 +1011,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "United States Dollar"
|
||||
shortName: "USD"
|
||||
symbol: "$"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b4.svg"
|
||||
category: ""
|
||||
selected: false
|
||||
}
|
||||
@@ -1009,7 +1020,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "British Pound"
|
||||
shortName: "GBP"
|
||||
symbol: "£"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b5.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b5.svg"
|
||||
category: ""
|
||||
selected: false
|
||||
}
|
||||
@@ -1018,7 +1029,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Euro"
|
||||
shortName: "EUR"
|
||||
symbol: "€"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b6.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b6.svg"
|
||||
category: ""
|
||||
selected: true
|
||||
}
|
||||
@@ -1027,7 +1038,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Shout Korean Won"
|
||||
shortName: "KRW"
|
||||
symbol: "₩"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b8.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b8.svg"
|
||||
category: ""
|
||||
selected: false
|
||||
}
|
||||
@@ -1036,7 +1047,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Ethereum"
|
||||
shortName: "ETH"
|
||||
symbol: "Ξ"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b7.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b7.svg"
|
||||
category: "Tokens"
|
||||
selected: true
|
||||
}
|
||||
@@ -1045,7 +1056,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Bitcoin"
|
||||
shortName: "BTC"
|
||||
symbol: "฿"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b4.svg"
|
||||
category: "Tokens"
|
||||
selected: false
|
||||
}
|
||||
@@ -1054,7 +1065,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Status Network Token"
|
||||
shortName: "SNT"
|
||||
symbol: ""
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b8.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b8.svg"
|
||||
category: "Tokens"
|
||||
selected: false
|
||||
}
|
||||
@@ -1064,7 +1075,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Emirati Dirham"
|
||||
shortName: "AED"
|
||||
symbol: "د.إ"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b4.svg"
|
||||
category: "Other Fiat"
|
||||
selected: false
|
||||
}
|
||||
@@ -1073,7 +1084,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Afghani"
|
||||
shortName: "AFN"
|
||||
symbol: "؋"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b7.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b7.svg"
|
||||
category: "Other Fiat"
|
||||
selected: false
|
||||
}
|
||||
@@ -1082,7 +1093,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Argentine Peso"
|
||||
shortName: "AFN"
|
||||
symbol: "$"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b4.svg"
|
||||
category: "Other Fiat"
|
||||
selected: false
|
||||
}
|
||||
@@ -1094,7 +1105,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "United States Dollar"
|
||||
shortName: "USD"
|
||||
symbol: "$"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b4.svg"
|
||||
category: ""
|
||||
selected: false
|
||||
}
|
||||
@@ -1103,7 +1114,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "British Pound"
|
||||
shortName: "GBP"
|
||||
symbol: "£"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b5.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b5.svg"
|
||||
category: ""
|
||||
selected: false
|
||||
}
|
||||
@@ -1112,7 +1123,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Euro"
|
||||
shortName: "EUR"
|
||||
symbol: "€"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b6.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b6.svg"
|
||||
category: ""
|
||||
selected: true
|
||||
}
|
||||
@@ -1121,7 +1132,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Shout Korean Won"
|
||||
shortName: "KRW"
|
||||
symbol: "₩"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b8.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b8.svg"
|
||||
category: ""
|
||||
selected: false
|
||||
}
|
||||
@@ -1130,7 +1141,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Ethereum"
|
||||
shortName: "ETH"
|
||||
symbol: "Ξ"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b7.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b7.svg"
|
||||
category: "Tokens"
|
||||
selected: true
|
||||
}
|
||||
@@ -1139,7 +1150,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Bitcoin"
|
||||
shortName: "BTC"
|
||||
symbol: "฿"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b4.svg"
|
||||
category: "Tokens"
|
||||
selected: false
|
||||
}
|
||||
@@ -1148,7 +1159,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Status Network Token"
|
||||
shortName: "SNT"
|
||||
symbol: ""
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b8.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b8.svg"
|
||||
category: "Tokens"
|
||||
selected: false
|
||||
}
|
||||
@@ -1158,7 +1169,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Emirati Dirham"
|
||||
shortName: "AED"
|
||||
symbol: "د.إ"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b4.svg"
|
||||
category: "Other Fiat"
|
||||
selected: false
|
||||
}
|
||||
@@ -1167,7 +1178,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Afghani"
|
||||
shortName: "AFN"
|
||||
symbol: "؋"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b7.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b7.svg"
|
||||
category: "Other Fiat"
|
||||
selected: false
|
||||
}
|
||||
@@ -1176,7 +1187,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
name: "Argentine Peso"
|
||||
shortName: "AFN"
|
||||
symbol: "$"
|
||||
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f4b4.svg"
|
||||
category: "Other Fiat"
|
||||
selected: false
|
||||
}
|
||||
@@ -1187,7 +1198,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
key: 0
|
||||
name: "English"
|
||||
shortName: "English"
|
||||
imageSource: "../../assets/twemoji/26x26/1f1ec-1f1e7.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f1ec-1f1e7.svg"
|
||||
category: ""
|
||||
selected: false
|
||||
}
|
||||
@@ -1195,7 +1206,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
key: 1
|
||||
name: "Korean"
|
||||
shortName: "한국어"
|
||||
imageSource: "../../assets/twemoji/26x26/1f1f0-1f1f7.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f1f0-1f1f7.svg"
|
||||
category: ""
|
||||
selected: false
|
||||
}
|
||||
@@ -1203,7 +1214,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
key: 2
|
||||
name: "Portuguese (Brazilian)"
|
||||
shortName: "Português"
|
||||
imageSource: "../../assets/twemoji/26x26/1f1e7-1f1f7.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f1e7-1f1f7.svg"
|
||||
category: ""
|
||||
selected: true
|
||||
}
|
||||
@@ -1211,7 +1222,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
key: 3
|
||||
name: "Dutch"
|
||||
shortName: "Nederlands"
|
||||
imageSource: "../../assets/twemoji/26x26/1f1f3-1f1f1.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f1f3-1f1f1.svg"
|
||||
category: "Beta Languages"
|
||||
selected: false
|
||||
}
|
||||
@@ -1219,7 +1230,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
key: 4
|
||||
name: "Indonesian"
|
||||
shortName: "Bahasa Indonesia"
|
||||
imageSource: "../../assets/twemoji/26x26/1f1ee-1f1e9.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f1ee-1f1e9.svg"
|
||||
category: "Beta Languages"
|
||||
selected: false
|
||||
}
|
||||
@@ -1227,7 +1238,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
key: 5
|
||||
name: "Spanish"
|
||||
shortName: "Español"
|
||||
imageSource: "../../assets/twemoji/26x26/1f1ea-1f1e6.png"
|
||||
imageSource: "../../assets/twemoji/svg/1f1ea-1f1e6.svg"
|
||||
category: "Beta Languages"
|
||||
selected: false
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,154 @@
|
||||
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
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
StatusIconTextButton {
|
||||
id: sortBtn
|
||||
|
||||
property int sortOrder: -1
|
||||
statusIcon: {
|
||||
if (sortOrder == Qt.AscendingOrder) return "chevron-down"
|
||||
if (sortOrder == Qt.DescendingOrder) return "chevron-up"
|
||||
return "remove"
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
var st = sortOrder + 1
|
||||
sortOrder = st > 1 ? -1 : st
|
||||
}
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: searchInput
|
||||
|
||||
Layout.fillWidth: true
|
||||
input.icon.name: "search"
|
||||
placeholderText: "nickname.."
|
||||
}
|
||||
|
||||
StatusIconTabButton {
|
||||
id: contactBtn
|
||||
|
||||
icon.name: "tiny/tiny-contact"
|
||||
identicon.icon.color: Theme.palette.primaryColor1
|
||||
onClicked: highlighted = !highlighted
|
||||
}
|
||||
|
||||
StatusIconTabButton {
|
||||
id: verifiedBtn
|
||||
|
||||
icon.name: "tiny/tiny-checkmark"
|
||||
identicon.icon.color: Theme.palette.primaryColor1
|
||||
onClicked: highlighted = !highlighted
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: contentItem.childrenRect.height
|
||||
spacing: 4
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: d.users
|
||||
sorters: StringSorter {
|
||||
enabled: sortBtn.sortOrder !== -1
|
||||
roleName: "nick"
|
||||
sortOrder: sortBtn.sortOrder
|
||||
}
|
||||
filters: [
|
||||
ExpressionFilter {
|
||||
expression: model.nick.startsWith(searchInput.text)
|
||||
},
|
||||
AllOf {
|
||||
enabled: contactBtn.highlighted || verifiedBtn.highlighted
|
||||
ValueFilter {
|
||||
enabled: contactBtn.highlighted
|
||||
roleName: "isContact"
|
||||
value: true
|
||||
}
|
||||
ValueFilter {
|
||||
enabled: verifiedBtn.highlighted
|
||||
roleName: "isVerified"
|
||||
value: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
delegate: StatusMemberListItem {
|
||||
width: parent.width
|
||||
userName: model.name
|
||||
nickName: model.nick
|
||||
isVerified: model.isVerified
|
||||
isContact: model.isContact
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property ListModel users: ListModel {
|
||||
ListElement {
|
||||
name: "Richard"
|
||||
nick: "Ricky"
|
||||
isVerified: true
|
||||
isContact: true
|
||||
}
|
||||
ListElement {
|
||||
name: "Susan"
|
||||
nick: "Sue"
|
||||
isVerified: false
|
||||
isContact: false
|
||||
}
|
||||
ListElement {
|
||||
name: "Edward"
|
||||
nick: "Ed"
|
||||
isVerified: true
|
||||
isContact: false
|
||||
}
|
||||
ListElement {
|
||||
name: "Toomas"
|
||||
nick: "Tommy"
|
||||
isVerified: false
|
||||
isContact: false
|
||||
}
|
||||
ListElement {
|
||||
name: "Elizabeth"
|
||||
nick: "Bess"
|
||||
isVerified: true
|
||||
isContact: true
|
||||
}
|
||||
ListElement {
|
||||
name: "Thomas"
|
||||
nick: "Tom"
|
||||
isVerified: false
|
||||
isContact: true
|
||||
}
|
||||
ListElement {
|
||||
name: "Fernando"
|
||||
nick: "Alonso"
|
||||
isVerified: false
|
||||
isContact: true
|
||||
}
|
||||
ListElement {
|
||||
name: "Alexander"
|
||||
nick: "Alex"
|
||||
isVerified: true
|
||||
isContact: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "handler.h"
|
||||
|
||||
Handler::Handler(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef HANDLER_H
|
||||
#define HANDLER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class Handler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Handler(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void restartQml();
|
||||
};
|
||||
|
||||
#endif // HANDLER_H
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "sandboxapp.h"
|
||||
|
||||
#include <qqmlsortfilterproxymodeltypes.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
@@ -12,6 +14,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
SandboxApp app(argc, argv);
|
||||
|
||||
qqsfpm::registerTypes();
|
||||
|
||||
qputenv("QT_QUICK_CONTROLS_HOVER_ENABLED", QByteArrayLiteral("1"));
|
||||
|
||||
app.setOrganizationName("Status");
|
||||
|
||||
+255
-199
@@ -4,6 +4,7 @@ import QtQuick.Controls 2.14
|
||||
import QtGraphicalEffects 1.13
|
||||
import QtQuick.Layouts 1.14
|
||||
import Qt.labs.settings 1.0
|
||||
import QtQml.Models 2.14
|
||||
|
||||
import Sandbox 0.1
|
||||
|
||||
@@ -14,6 +15,8 @@ import StatusQ.Components 0.1
|
||||
import StatusQ.Layout 0.1
|
||||
import StatusQ.Platform 0.1
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import "demoapp/data" 1.0
|
||||
|
||||
StatusWindow {
|
||||
@@ -44,7 +47,8 @@ StatusWindow {
|
||||
readonly property int nodeManagement: 4
|
||||
readonly property int profileSettings: 5
|
||||
readonly property int apiDocumentation: 100
|
||||
readonly property int demoApp: 101
|
||||
readonly property int examples: 101
|
||||
readonly property int demoApp: 102
|
||||
}
|
||||
|
||||
function setActiveItem(sectionId) {
|
||||
@@ -87,13 +91,16 @@ StatusWindow {
|
||||
if(model.sectionType === appSectionType.apiDocumentation)
|
||||
{
|
||||
stackView.push(libraryDocumentationCmp)
|
||||
rootWindow.setActiveItem(sectionId)
|
||||
}
|
||||
else if(model.sectionType === appSectionType.examples)
|
||||
{
|
||||
stackView.push(examplesCmp)
|
||||
}
|
||||
else if(model.sectionType === appSectionType.demoApp)
|
||||
{
|
||||
stackView.push(demoAppCmp)
|
||||
rootWindow.setActiveItem(model.sectionId)
|
||||
}
|
||||
rootWindow.setActiveItem(model.sectionId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,205 +139,206 @@ StatusWindow {
|
||||
storeSettings.fillPage = false
|
||||
}
|
||||
|
||||
leftPanel: Item {
|
||||
leftPanel: StatusScrollView {
|
||||
anchors.fill: parent
|
||||
ScrollView {
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
contentHeight: navigation.height + 56
|
||||
contentWidth: navigation.width
|
||||
clip: true
|
||||
Column {
|
||||
id: navigation
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 48
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: 0
|
||||
anchors.topMargin: 48
|
||||
|
||||
StatusListSectionHeadline { text: "StatusQ.Core" }
|
||||
StatusNavigationListItem {
|
||||
title: "Icons"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
}
|
||||
Column {
|
||||
id: navigation
|
||||
spacing: 0
|
||||
|
||||
StatusListSectionHeadline { text: "StatusQ.Layout" }
|
||||
StatusNavigationListItem {
|
||||
title: "Layouts"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title.substring(0, title.length - 1));
|
||||
}
|
||||
StatusListSectionHeadline { text: "StatusQ.Core" }
|
||||
StatusNavigationListItem {
|
||||
title: "Icons"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
}
|
||||
|
||||
StatusListSectionHeadline { text: "StatusQ.Controls" }
|
||||
StatusNavigationListItem {
|
||||
title: "Buttons"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusSwitchTab"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page("StatusTabSwitch");
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusChatCommandButton"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "Controls"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusTabBarButton"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusTabBarIconButton"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusInput"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusSelect"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusAccountSelector"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusAssetSelector"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusColorSelector"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusWalletColorButton"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusWalletColorSelect"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusPasswordStrengthIndicator"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusPinInput"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusListSectionHeadline { text: "StatusQ.Components" }
|
||||
StatusNavigationListItem {
|
||||
title: "StatusAddress"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "List Items"
|
||||
selected: viewLoader.source.toString().includes(title.replace(/\s+/g, ''))
|
||||
onClicked: mainPageView.control(title.replace(/\s+/g, ''));
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusChatInfoToolBar"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "Others"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusExpandableItem"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page("StatusExpandableSettingsItem");
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusTagSelector"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusToastMessage"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusWizardStepper"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusListPicker"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusCommunityCard"
|
||||
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"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusColorSelectorGrid"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusImageCropPanel"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title, true);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusColorSpace"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title, true);
|
||||
}
|
||||
StatusListSectionHeadline { text: "StatusQ.Layout" }
|
||||
StatusNavigationListItem {
|
||||
title: "Layouts"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title.substring(0, title.length - 1));
|
||||
}
|
||||
|
||||
StatusListSectionHeadline { text: "StatusQ.Controls" }
|
||||
StatusNavigationListItem {
|
||||
title: "Buttons"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusSwitchTab"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page("StatusTabSwitch");
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusChatCommandButton"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "Controls"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusTabBarButton"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusTabBarIconButton"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusInput"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusTextArea"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusSelect"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusComboBox"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusAccountSelector"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusColorSelector"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusWalletColorButton"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusWalletColorSelect"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusPasswordStrengthIndicator"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusPinInput"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusListSectionHeadline { text: "StatusQ.Components" }
|
||||
StatusNavigationListItem {
|
||||
title: "StatusAddress"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "List Items"
|
||||
selected: viewLoader.source.toString().includes(title.replace(/\s+/g, ''))
|
||||
onClicked: mainPageView.control(title.replace(/\s+/g, ''));
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusChatInfoToolBar"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "Others"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusExpandableItem"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page("StatusExpandableSettingsItem");
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusTagSelector"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusToastMessage"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusWizardStepper"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusListPicker"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusCommunityCard"
|
||||
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"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusColorSelectorGrid"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusImageCropPanel"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title, true);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusColorSpace"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title, true);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusCard"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,7 +347,7 @@ StatusWindow {
|
||||
id: rightPanel
|
||||
anchors.fill: parent
|
||||
|
||||
ScrollView {
|
||||
StatusScrollView {
|
||||
visible: !storeSettings.fillPage
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 64
|
||||
@@ -404,6 +412,53 @@ StatusWindow {
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: examplesCmp
|
||||
|
||||
StatusAppTwoPanelLayout {
|
||||
id: examplesView
|
||||
|
||||
function example(name) {
|
||||
examplesLoader.source = Qt.resolvedUrl("./examples/" + name + ".qml")
|
||||
storeSettings.selectedExample = examplesLoader.source
|
||||
}
|
||||
|
||||
readonly property string defaultExampleSource: example("FilteringSorting")
|
||||
|
||||
leftPanel: StatusScrollView {
|
||||
id: examplesLeftPanel
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 48
|
||||
|
||||
ColumnLayout {
|
||||
width: examplesLeftPanel.availableWidth
|
||||
spacing: 0
|
||||
|
||||
StatusNavigationListItem {
|
||||
Layout.fillWidth: true
|
||||
title: "FilteringSorting"
|
||||
selected: examplesLoader.source.toString().includes(title)
|
||||
onClicked: examplesView.example(title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rightPanel: StatusScrollView {
|
||||
id: examplesRightPanel
|
||||
anchors.fill: parent
|
||||
anchors.margins: 64
|
||||
anchors.topMargin: anchors.margins + 32
|
||||
|
||||
Loader {
|
||||
id: examplesLoader
|
||||
width: examplesRightPanel.availableWidth
|
||||
source: storeSettings.selectedExample !== "" ? storeSettings.selectedExample : examplesView.defaultExampleSource
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: demoAppCmp
|
||||
|
||||
@@ -498,6 +553,7 @@ StatusWindow {
|
||||
Settings {
|
||||
id: storeSettings
|
||||
property string selected: ""
|
||||
property string selectedExample: ""
|
||||
property bool lightTheme: true
|
||||
property bool fillPage: false
|
||||
}
|
||||
|
||||
@@ -8,57 +8,61 @@ import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
|
||||
Column {
|
||||
spacing: 8
|
||||
|
||||
StatusAccountSelector {
|
||||
id: accountSelector
|
||||
accounts: ListModel {
|
||||
ListElement {
|
||||
name: "Pascal"
|
||||
address: "0x1234567891011"
|
||||
path: ""
|
||||
color: "red"
|
||||
publicKey: ""
|
||||
walletType: "generated"
|
||||
isChat: ""
|
||||
currencyBalance: "1199.02"
|
||||
assets: []
|
||||
}
|
||||
ListElement {
|
||||
name: "Boris"
|
||||
address: "0x123"
|
||||
path: ""
|
||||
color: "red"
|
||||
publicKey: ""
|
||||
walletType: "generated"
|
||||
isChat: ""
|
||||
currencyBalance: "0"
|
||||
assets: []
|
||||
}
|
||||
ListElement {
|
||||
name: "Alexandra"
|
||||
address: "0x123"
|
||||
path: ""
|
||||
color: "yellow"
|
||||
publicKey: ""
|
||||
walletType: "generated"
|
||||
isChat: ""
|
||||
currencyBalance: "0"
|
||||
assets: []
|
||||
}
|
||||
ListElement {
|
||||
name: "Khushboo"
|
||||
address: "0x123"
|
||||
path: ""
|
||||
color: "blue"
|
||||
publicKey: ""
|
||||
walletType: "generated"
|
||||
isChat: ""
|
||||
currencyBalance: "0"
|
||||
assets: []
|
||||
}
|
||||
id: selector1
|
||||
width: 300
|
||||
accounts: accountsModel
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: accountsModel
|
||||
|
||||
ListElement {
|
||||
name: "Pascal"
|
||||
address: "0x1234567891011"
|
||||
path: ""
|
||||
color: "red"
|
||||
publicKey: ""
|
||||
walletType: "generated"
|
||||
isChat: ""
|
||||
currencyBalance: "1199.02"
|
||||
assets: []
|
||||
}
|
||||
ListElement {
|
||||
name: "Boris"
|
||||
address: "0x123"
|
||||
path: ""
|
||||
color: "red"
|
||||
publicKey: ""
|
||||
walletType: "generated"
|
||||
isChat: ""
|
||||
currencyBalance: "42.42"
|
||||
assets: []
|
||||
}
|
||||
ListElement {
|
||||
name: "Alexandra"
|
||||
address: "0x123"
|
||||
path: ""
|
||||
color: "yellow"
|
||||
publicKey: ""
|
||||
walletType: "generated"
|
||||
isChat: ""
|
||||
currencyBalance: "0"
|
||||
assets: []
|
||||
}
|
||||
ListElement {
|
||||
name: "Khushboo"
|
||||
address: "0x123"
|
||||
path: ""
|
||||
color: "blue"
|
||||
publicKey: ""
|
||||
walletType: "watch" // Will be automatically filtered by StatusAccountSelector
|
||||
isChat: ""
|
||||
currencyBalance: "0"
|
||||
assets: []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,24 +2,97 @@ import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
import Sandbox 0.1
|
||||
|
||||
Column {
|
||||
spacing: 8
|
||||
Item {
|
||||
id: root
|
||||
|
||||
StatusAddress {
|
||||
text: "0x9ce0056c5fc6bb9459a4dcfa35eaad8c1fee5ce9"
|
||||
}
|
||||
implicitWidth: mainLayout.implicitWidth
|
||||
implicitHeight: mainLayout.implicitHeight
|
||||
|
||||
Item {
|
||||
width: 200
|
||||
height: childrenRect.height
|
||||
GridLayout {
|
||||
id: mainLayout
|
||||
|
||||
columns: 2
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
columnSpacing: 15
|
||||
rowSpacing: 8
|
||||
|
||||
StatusBaseText { text: "StatusAddress\nsimple" }
|
||||
StatusAddress {
|
||||
text: "0x9ce0056c5fc6bb9459a4dcfa35eaad8c1fee5ce9"
|
||||
}
|
||||
|
||||
StatusBaseText { text: "StatusAddress\nclick-expandable" }
|
||||
StatusAddress {
|
||||
text: "0x9ce0056c5fc6bb9459a4dcfa35eaad8c1fee5ce9"
|
||||
|
||||
Layout.preferredWidth: 200
|
||||
|
||||
expandable: true
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
StatusBaseText { text: `StatusAddressPanel\nfont.pixelSize: 13, copyable, no frame`}
|
||||
StatusAddressPanel {
|
||||
address: "0xDC2c4826f6C56F61C1b9cC6Bb531d0Fe45402fC9"
|
||||
|
||||
font.pixelSize: 13
|
||||
font.weight: Font.Normal
|
||||
|
||||
showFrame: false
|
||||
|
||||
onDoCopy: copyAction.text = address
|
||||
}
|
||||
|
||||
StatusBaseText { text: `StatusAddressPanel\ncompact; width ${simpleAddressPanel.width}px ${simpleAddressPanel.height}px`}
|
||||
StatusAddressPanel {
|
||||
id: simpleAddressPanel
|
||||
address: "0xd8593DEACe2f44dF35dd23fD2BAFC2daeC2ae033"
|
||||
showCopy: false
|
||||
expanded: false
|
||||
onDoCopy: copyAction.text = address
|
||||
expandable: true
|
||||
}
|
||||
|
||||
StatusBaseText { text: "StatusAddressPanel\ncopy-icon, non-expandable" }
|
||||
StatusAddressPanel {
|
||||
address: "0xDd5A0755e99D66a583253372B569231968A6CF7b"
|
||||
onDoCopy: copyAction.text = address
|
||||
}
|
||||
|
||||
StatusBaseText { text: "StatusAddressPanel\ncopy hiden" }
|
||||
StatusAddressPanel {
|
||||
address: "0xd2D44C2A1E78975506e474Ecdc7E4F272D7e9A6c"
|
||||
autHideCopyIcon: true
|
||||
onDoCopy: copyAction.text = address
|
||||
expandable: true
|
||||
}
|
||||
StatusBaseText { text: "StatusAddressPanel\ncopy hiden, non-expandable" }
|
||||
StatusAddressPanel {
|
||||
address: "0xd2a44BA31E78975506e474Ecdc7E4F272D7F3BC5"
|
||||
autHideCopyIcon: true
|
||||
expanded: false
|
||||
onDoCopy: copyAction.text = address
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: "lightblue"
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: mainLayout.columns
|
||||
Layout.preferredHeight: 2
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Copy Action: ")
|
||||
}
|
||||
StatusBaseText {
|
||||
id: copyAction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
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.Popups 0.1
|
||||
|
||||
import Sandbox 0.1
|
||||
|
||||
Column {
|
||||
spacing: 8
|
||||
|
||||
StatusAssetSelector {
|
||||
getCurrencyBalanceString: function (currencyBalance) {
|
||||
return currencyBalance.toFixed(2) + " USD"
|
||||
}
|
||||
tokenAssetSourceFn: function (symbol) {
|
||||
return "../../assets/img/icons/snt.svg"
|
||||
}
|
||||
assets: ListModel {
|
||||
ListElement {
|
||||
address: "0x1234"
|
||||
name: "Status Network Token"
|
||||
balance: "20"
|
||||
symbol: "SNT"
|
||||
currencyBalance: 9992.01
|
||||
}
|
||||
ListElement {
|
||||
address: "0x1234"
|
||||
name: "DAI Token"
|
||||
balance: "15"
|
||||
symbol: "DAI"
|
||||
currencyBalance: 20.00001
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import Sandbox 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
Item {
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: 20
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
StatusCard {
|
||||
id: card
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
primaryText: "Mainnet"
|
||||
secondaryText: state === "unavailable" ? "No Gas" : "75"
|
||||
tertiaryText: state === "unpreferred" ? "UNPREFERRED" : "BALANCE: " + 250
|
||||
cardIconName: "status"
|
||||
advancedInputText: "75"
|
||||
disabledText: "Disabled"
|
||||
}
|
||||
|
||||
StatusComboBox {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.maximumWidth: 200
|
||||
label: "Card State"
|
||||
onCurrentValueChanged: card.state = currentValue
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
name: "default"
|
||||
}
|
||||
ListElement {
|
||||
name: "unavailable"
|
||||
}
|
||||
ListElement {
|
||||
name: "error"
|
||||
}
|
||||
ListElement {
|
||||
name: "unpreferred"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusCheckBox {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "advancedMode"
|
||||
font.family: Theme.palette.monoFont.name
|
||||
onClicked: {
|
||||
card.advancedMode = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 1
|
||||
width: 700
|
||||
color: "black"
|
||||
}
|
||||
|
||||
// Below is an example on how to implement the network routing using StatusCard and Canvas, also the function in Utils to draw an arrow
|
||||
Row {
|
||||
id: cards
|
||||
spacing: 200
|
||||
Column {
|
||||
id: leftColumn
|
||||
spacing: 20
|
||||
Repeater {
|
||||
model: fromNetworksList
|
||||
StatusCard {
|
||||
primaryText: name
|
||||
secondaryText: balance === 0 ? "No Balance" : !hasGas ? "No Gas" : tokensToSend
|
||||
tertiaryText: "BALANCE: " + balance
|
||||
state: balance === 0 || !hasGas ? "unavailable" : "default"
|
||||
cardIconName: iconName
|
||||
advancedMode: card.advancedMode
|
||||
advancedInputText: tokensToSend
|
||||
disabledText: "Disabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: rightColumn
|
||||
spacing: 20
|
||||
Repeater {
|
||||
model: toNetworksList
|
||||
StatusCard {
|
||||
primaryText: name
|
||||
secondaryText: tokensToReceive
|
||||
tertiaryText: ""
|
||||
state: preferred ? "default" : "unprefeered"
|
||||
cardIconName: iconName
|
||||
opacity: preferred ? 1 : 0
|
||||
advancedMode: card.advancedMode
|
||||
advancedInputText: tokensToReceive
|
||||
disabledText: "Disabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Canvas {
|
||||
id: canvas
|
||||
x: layout.x + leftColumn.x
|
||||
y: cards.y
|
||||
width: cards.width
|
||||
height: cards.height
|
||||
|
||||
function clear() {
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset()
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
// Get the canvas context
|
||||
var ctx = getContext("2d");
|
||||
|
||||
for(var i = 0; i< fromNetworksList.count; i++) {
|
||||
if(fromNetworksList.get(i).routedTo !== "") {
|
||||
for(var j = 0; j< toNetworksList.count; j++) {
|
||||
if(fromNetworksList.get(i).routedTo === toNetworksList.get(j).name) {
|
||||
Utils.drawArrow(ctx, leftColumn.children[i].x + leftColumn.children[i].width,
|
||||
leftColumn.children[i].y + leftColumn.children[i].height/2,
|
||||
rightColumn.x + rightColumn.children[j].x,
|
||||
rightColumn.children[j].y + rightColumn.children[j].height/2,
|
||||
'#627EEA')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ListModel {
|
||||
id: toNetworksList
|
||||
ListElement {
|
||||
name: "Mainnet"
|
||||
iconName: "status"
|
||||
tokensToReceive: 75
|
||||
preferred: true
|
||||
}
|
||||
ListElement {
|
||||
name: "Aztec"
|
||||
iconName: "status"
|
||||
tokensToReceive: 0
|
||||
preferred: false
|
||||
}
|
||||
ListElement {
|
||||
name: "Hermez"
|
||||
iconName: "status"
|
||||
tokensToReceive: 75
|
||||
preferred: true
|
||||
}
|
||||
ListElement {
|
||||
name: "Loppring"
|
||||
iconName: "status"
|
||||
tokensToReceive: 0
|
||||
preferred: true
|
||||
}
|
||||
ListElement {
|
||||
name: "Optimism"
|
||||
iconName: "status"
|
||||
tokensToReceive: 100
|
||||
preferred: true
|
||||
}
|
||||
ListElement {
|
||||
name: "zkSync"
|
||||
iconName: "status"
|
||||
tokensToReceive: 0
|
||||
preferred: false
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: fromNetworksList
|
||||
ListElement {
|
||||
name: "Mainnet"
|
||||
iconName: "status"
|
||||
tokensToSend: 75
|
||||
balance: 75
|
||||
routedTo: "Mainnet"
|
||||
hasGas: true
|
||||
}
|
||||
ListElement {
|
||||
name: "Aztec"
|
||||
iconName: "status"
|
||||
tokensToSend: 0
|
||||
balance: 75
|
||||
routedTo: ""
|
||||
hasGas: false
|
||||
}
|
||||
ListElement {
|
||||
name: "Hermez"
|
||||
iconName: "status"
|
||||
tokensToSend: 75
|
||||
balance: 75
|
||||
routedTo: "Hermez"
|
||||
hasGas: true
|
||||
}
|
||||
ListElement {
|
||||
name: "Loppring"
|
||||
iconName: "status"
|
||||
tokensToSend: 0
|
||||
balance: 0
|
||||
routedTo: ""
|
||||
hasGas: false
|
||||
}
|
||||
ListElement {
|
||||
name: "Optimism"
|
||||
iconName: "status"
|
||||
tokensToSend: 75
|
||||
balance: 75
|
||||
routedTo: "Optimism"
|
||||
hasGas: true
|
||||
}
|
||||
ListElement {
|
||||
name: "zkSync"
|
||||
iconName: "status"
|
||||
tokensToSend: 25
|
||||
balance: 25
|
||||
routedTo: "Optimism"
|
||||
hasGas: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ GridLayout {
|
||||
StatusChatInfoToolBar {
|
||||
chatInfoButton.title: "Cryptokitties"
|
||||
chatInfoButton.subTitle: "128 Members"
|
||||
chatInfoButton.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
chatInfoButton.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
chatInfoButton.icon.color: Theme.palette.miscColor6
|
||||
|
||||
popupMenu: StatusPopupMenu {
|
||||
|
||||
@@ -8,7 +8,7 @@ import StatusQ.Controls 0.1
|
||||
|
||||
import Sandbox 0.1
|
||||
|
||||
Column {
|
||||
Row {
|
||||
spacing: 8
|
||||
|
||||
StatusColorSelector {
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
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.Popups 0.1
|
||||
|
||||
import Sandbox 0.1
|
||||
|
||||
Column {
|
||||
spacing: 20
|
||||
|
||||
ListModel {
|
||||
id: commmonModel
|
||||
ListElement {
|
||||
name: "Pascal"
|
||||
}
|
||||
ListElement {
|
||||
name: "Khushboo"
|
||||
}
|
||||
ListElement {
|
||||
name: "Alexandra"
|
||||
}
|
||||
ListElement {
|
||||
name: "Eric"
|
||||
}
|
||||
}
|
||||
|
||||
StatusComboBox {
|
||||
id: combobox
|
||||
label: "ComboBox"
|
||||
model: commmonModel
|
||||
}
|
||||
|
||||
StatusComboBox {
|
||||
id: comboBox1
|
||||
label: "ComboBox with custom delegate"
|
||||
model: commmonModel
|
||||
delegate: StatusItemDelegate {
|
||||
width: comboBox1.control.width
|
||||
highlighted: comboBox1.control.highlightedIndex === index
|
||||
text: modelData
|
||||
font: comboBox1.control.font
|
||||
icon {
|
||||
name: "filled-account"
|
||||
color: Theme.palette.primaryColor1
|
||||
}
|
||||
enabled: index != 2
|
||||
}
|
||||
}
|
||||
|
||||
StatusComboBox {
|
||||
model: commmonModel
|
||||
label: "Disabled ComboBox"
|
||||
enabled: false
|
||||
}
|
||||
|
||||
StatusComboBox {
|
||||
model: commmonModel
|
||||
label: "ComboBox with validation error"
|
||||
validationError: "Validation failed example"
|
||||
}
|
||||
|
||||
StatusComboBox {
|
||||
model: commmonModel
|
||||
label: "Mirrored ComboBox"
|
||||
LayoutMirroring.enabled: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ Item {
|
||||
rightPadding: 0
|
||||
label: qsTr("Select tags that will fit your Community")
|
||||
input.icon.name: "search"
|
||||
input.placeholderText: qsTr("Search tags")
|
||||
placeholderText: qsTr("Search tags")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
@@ -80,4 +80,4 @@ Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ Column {
|
||||
|
||||
type: StatusExpandableItem.Type.Secondary
|
||||
expandable: true
|
||||
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
primaryText: "CryptoKitties"
|
||||
additionalText: "1456 USD"
|
||||
expandableComponent: notImplemented
|
||||
@@ -85,7 +85,7 @@ Column {
|
||||
|
||||
type: StatusExpandableItem.Type.Secondary
|
||||
expandable: true
|
||||
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
primaryText: "Adding Really long text to test scenario of having very long text along with tertiary text"
|
||||
additionalText: "564.90 USD"
|
||||
expandableComponent: notImplemented
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtQuick.Dialogs 1.3
|
||||
import QtQml 2.14
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
import QtGraphicalEffects 1.14
|
||||
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
@@ -15,6 +24,12 @@ Item {
|
||||
property var testControls: [ctrl1, ctrl2, ctrl3]
|
||||
|
||||
property bool globalStylePreferRound: true
|
||||
property var testImageList: ["qrc:/demoapp/data/logo-test-image.png",
|
||||
"qrc:/demoapp/data/profile-image-2.jpeg",
|
||||
"qrc:/demoapp/data/profile-image-1.jpeg"]
|
||||
property int testImageIndex: 0
|
||||
property int testSpacing: 0
|
||||
property int testFrameMargins: 10
|
||||
|
||||
ColumnLayout {
|
||||
id: mainLayout
|
||||
@@ -22,7 +37,12 @@ Item {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
spacing: root.testSpacing
|
||||
|
||||
ColumnLayout {
|
||||
spacing: root.testSpacing
|
||||
Layout.margins: root.testSpacing
|
||||
|
||||
Text {
|
||||
text: `AR: ${ctrl1.aspectRatio.toFixed(2)}`
|
||||
}
|
||||
@@ -32,8 +52,9 @@ Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
source: "qrc:/demoapp/data/logo-test-image.png"
|
||||
source: root.testImageList[root.testImageIndex]
|
||||
windowStyle: globalStylePreferRound ? StatusImageCrop.WindowStyle.Rounded : StatusImageCrop.WindowStyle.Rectangular
|
||||
margins: root.testFrameMargins
|
||||
}
|
||||
Text {
|
||||
text: `AR: ${ctrl2.aspectRatio.toFixed(2)}`
|
||||
@@ -43,13 +64,15 @@ Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
source: "qrc:/demoapp/data/logo-test-image.png"
|
||||
source: root.testImageList[root.testImageIndex]
|
||||
windowStyle: globalStylePreferRound ? StatusImageCrop.WindowStyle.Rectangular : StatusImageCrop.WindowStyle.Rounded
|
||||
aspectRatio: 16/9
|
||||
enableCheckers: true
|
||||
margins: root.testFrameMargins + 2
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.margins: root.testSpacing
|
||||
Text {
|
||||
text: `AR: ${ctrl3.aspectRatio.toFixed(2)}`
|
||||
}
|
||||
@@ -59,36 +82,178 @@ Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
source: "qrc:/demoapp/data/logo-test-image.png"
|
||||
source: root.testImageList[root.testImageIndex]
|
||||
windowStyle: globalStylePreferRound ? StatusImageCrop.WindowStyle.Rounded : StatusImageCrop.WindowStyle.Rectangular
|
||||
aspectRatio: 0.8
|
||||
|
||||
margins: root.testFrameMargins + 5.3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: StandardKey.ZoomIn
|
||||
onActivated: {
|
||||
for(let i in testControls) {
|
||||
const c = testControls[i]
|
||||
c.setCropRect(ctrl1.inflateRectBy(c.cropRect, -0.05))
|
||||
RowLayout {
|
||||
StatusButton {
|
||||
text: qsTr("Cycle image")
|
||||
onClicked: {
|
||||
let newIndex = root.testImageIndex
|
||||
newIndex++
|
||||
if(newIndex >= root.testImageList.length)
|
||||
newIndex = 0
|
||||
root.testImageIndex = newIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: StandardKey.ZoomOut
|
||||
onActivated: {
|
||||
for(let i in testControls) {
|
||||
const c = testControls[i]
|
||||
c.setCropRect(ctrl1.inflateRectBy(c.cropRect, 0.05))
|
||||
StatusButton {
|
||||
text: qsTr("Cycle spacing")
|
||||
onClicked: {
|
||||
root.testSpacing += (root.testSpacing/2) + 1
|
||||
if(root.testSpacing > 35)
|
||||
root.testSpacing = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequences: ["Ctrl+W"]
|
||||
onActivated: globalStylePreferRound = !globalStylePreferRound
|
||||
StatusButton {
|
||||
text: qsTr("Cycle frame margins")
|
||||
onClicked: {
|
||||
root.testFrameMargins += (root.testFrameMargins/2) + 1
|
||||
if(root.testFrameMargins > 50)
|
||||
root.testFrameMargins = 0
|
||||
}
|
||||
}
|
||||
StatusButton {
|
||||
text: qsTr("Load external image")
|
||||
onClicked: workflowLoader.active = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: workflowLoader
|
||||
|
||||
sourceComponent: workflowComponent
|
||||
active: false
|
||||
onStatusChanged: {
|
||||
if(status === Loader.Ready) {
|
||||
item.imageFileDialogTitle = qsTr("Test Title")
|
||||
item.title = "Test popup"
|
||||
item.acceptButtonText = "Load Custom Image"
|
||||
item.chooseImageToCrop()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: workflowLoader.item
|
||||
function onImageCropped(image, cropRect) {
|
||||
ctrl1.source = image
|
||||
ctrl2.source = image
|
||||
ctrl3.source = image
|
||||
}
|
||||
function onCanceled() {
|
||||
workflowLoader.active = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: workflowComponent
|
||||
|
||||
Item {
|
||||
id: workflowItem
|
||||
|
||||
property alias aspectRatio: imageCropper.aspectRatio
|
||||
property alias windowStyle: imageCropper.windowStyle
|
||||
/*required*/ property string imageFileDialogTitle: ""
|
||||
/*required*/ property string title: ""
|
||||
/*required*/ property string acceptButtonText: ""
|
||||
property bool roundedImage: true
|
||||
|
||||
signal imageCropped(var image, var cropRect)
|
||||
signal canceled()
|
||||
|
||||
function chooseImageToCrop() {
|
||||
fileDialog.open()
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
id: fileDialog
|
||||
|
||||
title: workflowItem.imageFileDialogTitle
|
||||
folder: workflowItem.userSelectedImage ? imageCropper.source.substr(0, imageCropper.source.lastIndexOf("/")) : shortcuts.pictures
|
||||
nameFilters: [qsTr("Supported image formats (%1)").arg("*.jpg *.jpeg *.jfif *.webp *.png *.heif")]
|
||||
onAccepted: {
|
||||
if (fileDialog.fileUrls.length > 0) {
|
||||
imageCropper.source = fileDialog.fileUrls[0]
|
||||
imageCropperModal.open()
|
||||
}
|
||||
}
|
||||
onRejected: workflowItem.canceled()
|
||||
} // FileDialog
|
||||
|
||||
StatusModal {
|
||||
id: imageCropperModal
|
||||
|
||||
header.title: workflowItem.title
|
||||
|
||||
anchors.centerIn: Overlay.overlay
|
||||
|
||||
width: workflowItem.roundedImage ? 480 : 580
|
||||
|
||||
onClosed: workflowItem.canceled()
|
||||
|
||||
StatusImageCropPanel {
|
||||
id: imageCropper
|
||||
|
||||
implicitHeight: workflowItem.roundedImage ? 350 : 370
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: 10 * 2
|
||||
rightMargin: 10 * 2
|
||||
topMargin: 15
|
||||
bottomMargin: 15
|
||||
}
|
||||
|
||||
margins: workflowItem.roundedImage ? 10 : 20
|
||||
windowStyle: workflowItem.roundedImage ? StatusImageCrop.WindowStyle.Rounded : StatusImageCrop.WindowStyle.Rectangular
|
||||
enableCheckers: true
|
||||
}
|
||||
|
||||
rightButtons: [
|
||||
StatusButton {
|
||||
text: workflowItem.acceptButtonText
|
||||
|
||||
enabled: imageCropper.sourceSize.width > 0 && imageCropper.sourceSize.height > 0
|
||||
|
||||
onClicked: {
|
||||
workflowItem.imageCropped(imageCropper.source, imageCropper.cropRect)
|
||||
imageCropperModal.close()
|
||||
}
|
||||
}
|
||||
]
|
||||
} // StatusModal
|
||||
} // Item
|
||||
}
|
||||
|
||||
|
||||
Shortcut {
|
||||
sequence: StandardKey.ZoomIn
|
||||
onActivated: {
|
||||
for(let i in testControls) {
|
||||
const c = testControls[i]
|
||||
c.setCropRect(ctrl1.inflateRectBy(c.cropRect, -0.05))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: StandardKey.ZoomOut
|
||||
onActivated: {
|
||||
for(let i in testControls) {
|
||||
const c = testControls[i]
|
||||
c.setCropRect(ctrl1.inflateRectBy(c.cropRect, 0.05))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequences: ["Ctrl+W"]
|
||||
onActivated: globalStylePreferRound = !globalStylePreferRound
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,22 +12,22 @@ Column {
|
||||
spacing: 8
|
||||
|
||||
StatusInput {
|
||||
input.placeholderText: "Placeholder"
|
||||
placeholderText: "Placeholder"
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
label: "Label"
|
||||
input.placeholderText: "Disabled"
|
||||
placeholderText: "Disabled"
|
||||
input.enabled: false
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
input.placeholderText: "Clearable"
|
||||
placeholderText: "Clearable"
|
||||
input.clearable: true
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
input.placeholderText: "Invalid"
|
||||
placeholderText: "Invalid"
|
||||
input.valid: false
|
||||
}
|
||||
|
||||
@@ -35,25 +35,25 @@ Column {
|
||||
label: "Label"
|
||||
|
||||
input.icon.name: "search"
|
||||
input.placeholderText: "Input with icon"
|
||||
placeholderText: "Input with icon"
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
label: "Label"
|
||||
input.placeholderText: "Placeholder"
|
||||
placeholderText: "Placeholder"
|
||||
input.clearable: true
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
charLimit: 30
|
||||
input.placeholderText: "Placeholder"
|
||||
placeholderText: "Placeholder"
|
||||
input.clearable: true
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
label: "Label"
|
||||
charLimit: 30
|
||||
input.placeholderText: "Placeholder"
|
||||
placeholderText: "Placeholder"
|
||||
input.clearable: true
|
||||
}
|
||||
|
||||
@@ -69,19 +69,34 @@ Column {
|
||||
textEdit.input.anchors.leftMargin: 16
|
||||
textEdit.input.anchors.rightMargin: 16
|
||||
textEdit.input.anchors.topMargin: 11
|
||||
textEdit.label: "Input with drop down selection list"
|
||||
textEdit.label: "Input with drop down selection list" + (insertedWord ? ` (${insertedWord})` : "")
|
||||
leftComponentText: "1"
|
||||
inputList: ListModel {
|
||||
ListElement {
|
||||
seedWord: "add"
|
||||
}
|
||||
ListElement {
|
||||
seedWord: "address"
|
||||
}
|
||||
ListElement {
|
||||
seedWord: "panda"
|
||||
}
|
||||
ListElement {
|
||||
seedWord: "posible"
|
||||
}
|
||||
ListElement {
|
||||
seedWord: "win"
|
||||
}
|
||||
ListElement {
|
||||
seedWord: "wine"
|
||||
}
|
||||
ListElement {
|
||||
seedWord: "wing"
|
||||
}
|
||||
}
|
||||
|
||||
property string insertedWord: ""
|
||||
onDoneInsertingWord: insertedWord = word
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +106,7 @@ Column {
|
||||
errorMessage: "Error message"
|
||||
input.clearable: true
|
||||
input.valid: false
|
||||
input.placeholderText: "Placeholder"
|
||||
placeholderText: "Placeholder"
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
@@ -106,15 +121,16 @@ Column {
|
||||
StatusInput {
|
||||
label: "Label"
|
||||
secondaryLabel: "secondary label"
|
||||
input.placeholderText: "Placeholder"
|
||||
input.implicitHeight: 56
|
||||
placeholderText: "Placeholder"
|
||||
minimumHeight: 56
|
||||
maximumHeight: 56
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: input
|
||||
label: "Label"
|
||||
charLimit: 30
|
||||
input.placeholderText: "Input with validator"
|
||||
placeholderText: "Input with validator"
|
||||
|
||||
validators: [
|
||||
StatusMinLengthValidator {
|
||||
@@ -132,7 +148,7 @@ Column {
|
||||
StatusInput {
|
||||
label: "Input with <i>StatusRegularExpressionValidator</i>"
|
||||
charLimit: 30
|
||||
input.placeholderText: `Must match regex(${validators[0].regularExpression.toString()}) and <= 30 chars`
|
||||
placeholderText: `Must match regex(${validators[0].regularExpression.toString()}) and <= 30 chars`
|
||||
validationMode: StatusInput.ValidationMode.IgnoreInvalidInput
|
||||
|
||||
validators: [
|
||||
@@ -145,7 +161,7 @@ Column {
|
||||
|
||||
StatusInput {
|
||||
label: "Label"
|
||||
input.placeholderText: "Input width component (right side)"
|
||||
placeholderText: "Input width component (right side)"
|
||||
input.rightComponent: StatusIcon {
|
||||
icon: "cancel"
|
||||
height: 16
|
||||
@@ -156,26 +172,27 @@ Column {
|
||||
|
||||
StatusInput {
|
||||
input.multiline: true
|
||||
input.placeholderText: "Multiline"
|
||||
placeholderText: "Multiline"
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
input.multiline: true
|
||||
input.placeholderText: "Multiline with static height"
|
||||
input.implicitHeight: 100
|
||||
placeholderText: "Multiline with static height"
|
||||
minimumHeight: 100
|
||||
maximumHeight: 100
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
input.multiline: true
|
||||
input.placeholderText: "Multiline with max/min"
|
||||
input.minimumHeight: 80
|
||||
input.maximumHeight: 200
|
||||
placeholderText: "Multiline with max/min"
|
||||
minimumHeight: 80
|
||||
maximumHeight: 200
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
property bool toggled: true
|
||||
label: "Input with emoji icon"
|
||||
input.placeholderText: "Enter Name"
|
||||
placeholderText: "Enter Name"
|
||||
input.icon.emoji: toggled ? "😁" : "🧸"
|
||||
input.icon.color: "blue"
|
||||
input.isIconSelectable: true
|
||||
@@ -187,7 +204,7 @@ Column {
|
||||
StatusInput {
|
||||
property bool toggled: true
|
||||
label: "Input with selectable icon which is not an emoji"
|
||||
input.placeholderText: "Enter Name"
|
||||
placeholderText: "Enter Name"
|
||||
input.icon.emoji: ""
|
||||
input.icon.name: toggled ? "filled-account" : "image"
|
||||
input.icon.color: "blue"
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 20
|
||||
StatusItemSelector {
|
||||
id: selector
|
||||
icon: "qrc:/images/SNT.png"
|
||||
iconSize: 24
|
||||
title: "Item Selector Title"
|
||||
defaultItemText: "Example: Empty items"
|
||||
andOperatorText: "and"
|
||||
orOperatorText: "or"
|
||||
popupItem: StatusDropdown {
|
||||
id: dropdown
|
||||
width: 200
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 10
|
||||
StatusInput {
|
||||
id: input
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
StatusButton {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "Add element"
|
||||
onClicked: {
|
||||
selector.addItem(input.text, "qrc:/images/SNT.png", selector.itemsModel.count > 0 ? Utils.Operators.Or : Utils.Operators.None)
|
||||
dropdown.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "Clear list"
|
||||
onClicked: { selector.itemsModel.clear() }
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ GridLayout {
|
||||
inputList: Models.languageNoImagePickerModel
|
||||
placeholderSearchText: qsTr("Search Languages")
|
||||
menuAlignment: StatusListPicker.MenuAlignment.Center
|
||||
multiSelection: true
|
||||
}
|
||||
|
||||
StatusListPicker {
|
||||
@@ -60,7 +61,7 @@ GridLayout {
|
||||
width: 500
|
||||
text: "4 different configurations for the `StatusListPicker` component:\n
|
||||
* Single selection. \n
|
||||
* Single selection but dynamically changed to multiple selection (model provides multiple selected items).\n
|
||||
* Multiple selection without images.\n
|
||||
* Multiple selection.\n
|
||||
* Multiple selection and displayed name is the symbol + shortName\n"
|
||||
color: Theme.palette.baseColor1
|
||||
|
||||
@@ -22,12 +22,17 @@ GridLayout {
|
||||
onClicked: complexMenu.popup()
|
||||
}
|
||||
|
||||
|
||||
StatusButton {
|
||||
id: customPopupButton
|
||||
text: "Menu with custom images and icons"
|
||||
onClicked: customMenu.popup()
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Menu with custom font settings"
|
||||
onClicked: differentFontMenu.popup()
|
||||
}
|
||||
|
||||
|
||||
StatusPopupMenu {
|
||||
id: simpleMenu
|
||||
@@ -46,7 +51,7 @@ GridLayout {
|
||||
|
||||
StatusPopupMenu {
|
||||
id: complexMenu
|
||||
subMenuItemIcons: [{ icon: 'info' }]
|
||||
// subMenuItemIcons: [{ icon: 'info' }]
|
||||
|
||||
StatusMenuItem {
|
||||
text: "One"
|
||||
@@ -63,10 +68,13 @@ GridLayout {
|
||||
StatusMenuItem {
|
||||
text: "Three"
|
||||
iconSettings.name: "info"
|
||||
enabled: false
|
||||
}
|
||||
|
||||
StatusPopupMenu {
|
||||
title: "Four"
|
||||
iconSettings.name: "info"
|
||||
|
||||
StatusMenuItem {
|
||||
text: "One"
|
||||
iconSettings.name: "info"
|
||||
@@ -80,17 +88,24 @@ GridLayout {
|
||||
|
||||
StatusPopupMenu {
|
||||
id: customMenu
|
||||
width: customPopupButton.width
|
||||
|
||||
subMenuItemIcons: [
|
||||
{ icon: "chat" },
|
||||
{
|
||||
source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
},
|
||||
{
|
||||
isLetterIdenticon: true,
|
||||
color: "red"
|
||||
}
|
||||
]
|
||||
// subMenuItemIcons: [
|
||||
// {
|
||||
// icon: "chat"
|
||||
// },
|
||||
// {
|
||||
// source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
// },
|
||||
// {
|
||||
// isLetterIdenticon: true,
|
||||
// color: "red"
|
||||
// }
|
||||
// ]
|
||||
|
||||
MenuItem {
|
||||
text: "Default MenuItem, action: " + action
|
||||
}
|
||||
|
||||
StatusMenuItem {
|
||||
text: "Anywhere"
|
||||
@@ -99,7 +114,8 @@ GridLayout {
|
||||
StatusMenuSeparator {}
|
||||
|
||||
StatusPopupMenu {
|
||||
title: "Chat"
|
||||
title: "Chat"
|
||||
iconSettings.name: "chat"
|
||||
|
||||
StatusMenuItem {
|
||||
text: "vitalik.eth"
|
||||
@@ -110,12 +126,13 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
|
||||
StatusMenuItem {
|
||||
text: "Pascal"
|
||||
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
}
|
||||
}
|
||||
|
||||
StatusPopupMenu {
|
||||
title: "Cryptokitties"
|
||||
imageSettings.source: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
|
||||
StatusMenuItem {
|
||||
text: "welcome"
|
||||
@@ -139,6 +156,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
|
||||
StatusPopupMenu {
|
||||
title: "Another community"
|
||||
iconSettings.isLetterIdenticon: true
|
||||
iconSettings.color: "red"
|
||||
|
||||
StatusMenuItem {
|
||||
text: "welcome"
|
||||
@@ -147,4 +166,22 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusPopupMenu {
|
||||
id: differentFontMenu
|
||||
StatusMenuItem {
|
||||
text: "Bold"
|
||||
fontSettings.bold: true
|
||||
}
|
||||
|
||||
StatusMenuItem {
|
||||
text: "Italic"
|
||||
fontSettings.italic: true
|
||||
}
|
||||
|
||||
StatusMenuItem {
|
||||
text: "16px"
|
||||
fontSettings.pixelSize: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,28 +8,39 @@ import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
import Sandbox 0.1
|
||||
|
||||
Column {
|
||||
spacing: 8
|
||||
spacing: 20
|
||||
|
||||
ListModel {
|
||||
id: commmonModel
|
||||
ListElement {
|
||||
name: "Pascal"
|
||||
}
|
||||
ListElement {
|
||||
name: "Khushboo"
|
||||
}
|
||||
ListElement {
|
||||
name: "Alexandra"
|
||||
}
|
||||
ListElement {
|
||||
name: "Eric"
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
font.pixelSize: 16
|
||||
color: Theme.palette.dangerColor1
|
||||
text: "This component should no longer be used.<br />Please, use `StatusComboBox` instead."
|
||||
textFormat: Text.MarkdownText
|
||||
}
|
||||
|
||||
StatusSelect {
|
||||
id: select
|
||||
label: "Some label"
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
name: "Pascal"
|
||||
}
|
||||
ListElement {
|
||||
name: "Khushboo"
|
||||
}
|
||||
ListElement {
|
||||
name: "Alexandra"
|
||||
}
|
||||
ListElement {
|
||||
name: "Eric"
|
||||
}
|
||||
}
|
||||
model: commmonModel
|
||||
|
||||
selectMenu.delegate: StatusMenuItemDelegate {
|
||||
statusPopupMenu: select
|
||||
action: StatusMenuItem {
|
||||
iconSettings.name: "filled-account"
|
||||
text: name
|
||||
@@ -38,6 +49,7 @@ Column {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectedItemComponent: Item {
|
||||
id: selectedItem
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -19,7 +19,7 @@ Item {
|
||||
ListElement {
|
||||
publicId: "0x1"
|
||||
name: "vitalikbuterin"
|
||||
icon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
icon: "qrc:/demoapp/data/profile-image-1.jpeg"
|
||||
isIdenticon: false
|
||||
onlineStatus: 1
|
||||
isReadonly: false
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Column {
|
||||
id: root
|
||||
|
||||
spacing: 8
|
||||
|
||||
Component.onCompleted: {
|
||||
focusedTextArea.forceActiveFocus()
|
||||
}
|
||||
|
||||
StatusTextArea {
|
||||
id: focusedTextArea
|
||||
width: parent.width
|
||||
placeholderText: "Initially focused text area"
|
||||
KeyNavigation.tab: unfocusedTextArea
|
||||
}
|
||||
|
||||
StatusTextArea {
|
||||
id: unfocusedTextArea
|
||||
width: parent.width
|
||||
placeholderText: "Unfocused text area (hover me to see the color change)"
|
||||
KeyNavigation.tab: invalidTextArea
|
||||
}
|
||||
|
||||
StatusTextArea {
|
||||
id: invalidTextArea
|
||||
width: parent.width
|
||||
valid: false
|
||||
placeholderText: "Invalid text area, should display red border"
|
||||
KeyNavigation.tab: longTextArea
|
||||
}
|
||||
|
||||
StatusScrollView {
|
||||
padding: 0 // use our own (StatusTextArea) padding
|
||||
width: parent.width
|
||||
height: 120
|
||||
TextArea.flickable: longTextArea
|
||||
StatusTextArea {
|
||||
id: longTextArea
|
||||
text: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer imperdiet lectus quis justo. Sed vel lectus. \
|
||||
Donec odio tempus molestie, porttitor ut, iaculis quis, sem. Morbi scelerisque luctus velit. Nunc auctor. Nullam at \
|
||||
arcu a est sollicitudin euismod. Cras elementum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, \
|
||||
per inceptos hymenaeos. Fusce aliquam vestibulum ipsum. Etiam sapien elit, consequat eget, tristique non, venenatis quis, ante. \
|
||||
Nullam sit amet magna in magna gravida vehicula. Cras pede libero, dapibus nec, pretium sit amet, tempor quis. Nullam faucibus \
|
||||
mi quis velit. Nam sed tellus id magna elementum tincidunt. Duis bibendum, lectus ut viverra rhoncus, dolor nunc faucibus libero, \
|
||||
eget facilisis enim ipsum id lacus. Maecenas aliquet accumsan leo. Aliquam erat volutpat."
|
||||
KeyNavigation.tab: focusedTextArea
|
||||
}
|
||||
}
|
||||
|
||||
StatusTextArea {
|
||||
enabled: false
|
||||
placeholderText: "Disabled text area"
|
||||
}
|
||||
}
|
||||
+52
-39
@@ -1,22 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
<file>pages/StatusAccountSelectorPage.qml</file>
|
||||
<file>pages/StatusAddressPage.qml</file>
|
||||
<file>pages/StatusAssetSelectorPage.qml</file>
|
||||
<file>pages/StatusChatCommandButtonPage.qml</file>
|
||||
<file>pages/StatusChatInfoToolBarPage.qml</file>
|
||||
<file>pages/StatusColorSelectorPage.qml</file>
|
||||
<file>pages/StatusExpandableSettingsItemPage.qml</file>
|
||||
<file>pages/StatusInputPage.qml</file>
|
||||
<file>pages/StatusMacNotificationPage.qml</file>
|
||||
<file>pages/StatusPopupMenuPage.qml</file>
|
||||
<file>pages/StatusSelectPage.qml</file>
|
||||
<file>pages/StatusTabBarIconButtonPage.qml</file>
|
||||
<file>pages/StatusTabSwitchPage.qml</file>
|
||||
<file>pages/StatusWalletColorButtonPage.qml</file>
|
||||
<file>pages/StatusWalletColorSelectPage.qml</file>
|
||||
<file>pages/StatusPasswordStrengthIndicatorPage.qml</file>
|
||||
<file>controls/Buttons.qml</file>
|
||||
<file>controls/Controls.qml</file>
|
||||
<file>controls/Icons.qml</file>
|
||||
@@ -24,49 +7,79 @@
|
||||
<file>controls/ListItems.qml</file>
|
||||
<file>controls/Others.qml</file>
|
||||
<file>controls/Popups.qml</file>
|
||||
<file>demoapp/data/logo-test-image.png</file>
|
||||
<file>demoapp/data/Models.qml</file>
|
||||
<file>demoapp/data/qmldir</file>
|
||||
<file>demoapp/ChatChannelView.qml</file>
|
||||
<file>demoapp/CreateChatView.qml</file>
|
||||
<file>demoapp/DemoCommunityDetailModal.qml</file>
|
||||
<file>demoapp/DemoContactRequestsModal.qml</file>
|
||||
<file>demoapp/StatusAppChatView.qml</file>
|
||||
<file>demoapp/StatusAppCommunitiesPortalView.qml</file>
|
||||
<file>demoapp/StatusAppCommunityView.qml</file>
|
||||
<file>demoapp/StatusAppProfileSettingsView.qml</file>
|
||||
<file>demoapp/data/Models.qml</file>
|
||||
<file>demoapp/data/qmldir</file>
|
||||
<file>demoapp/data/logo-test-image.png</file>
|
||||
<file>DemoApp.qml</file>
|
||||
<file>ThemeSwitch.qml</file>
|
||||
<file>pages/StatusColorSelectorGridPage.qml</file>
|
||||
<file>pages/StatusListPickerPage.qml</file>
|
||||
<file>pages/StatusPinInputPage.qml</file>
|
||||
<file>pages/StatusTagSelectorPage.qml</file>
|
||||
<file>pages/StatusToastMessagePage.qml</file>
|
||||
<file>pages/StatusWizardStepperPage.qml</file>
|
||||
<file>pages/StatusTabBarButtonPage.qml</file>
|
||||
<file>pages/StatusColorSpacePage.qml</file>
|
||||
<file>images/Coinbase.png</file>
|
||||
<file>images/CoinBaseCommunityBanner.png</file>
|
||||
<file>images/CommunityBanner1.png</file>
|
||||
<file>images/CryptoKitties.png</file>
|
||||
<file>images/CryptoPunks.png</file>
|
||||
<file>images/Dragonerum.png</file>
|
||||
<file>images/FriendsBenefits.png</file>
|
||||
<file>images/logo-test-image.png</file>
|
||||
<file>images/P2PCrypto.png</file>
|
||||
<file>images/SNT.png</file>
|
||||
<file>images/Socks.png</file>
|
||||
<file>images/StatusPunks.png</file>
|
||||
<file>images/CommunityBanner1.png</file>
|
||||
<file>images/Coinbase.png</file>
|
||||
<file>images/CoinBaseCommunityBanner.png</file>
|
||||
<file>images/DribbbleCommunityBanner.png</file>
|
||||
<file>images/Ethereum.png</file>
|
||||
<file>images/EthereumCommunityBanner.png</file>
|
||||
<file>images/Fluff.png</file>
|
||||
<file>images/FriendsBenefits.png</file>
|
||||
<file>images/logo-test-image.png</file>
|
||||
<file>images/P2PCrypto.png</file>
|
||||
<file>images/RARI.png</file>
|
||||
<file>images/Rarible.png</file>
|
||||
<file>images/RaribleCommunityBanner.png</file>
|
||||
<file>images/SNT.png</file>
|
||||
<file>images/Socks.png</file>
|
||||
<file>images/Spotify.png</file>
|
||||
<file>images/SpotifyCommunityBanner.png</file>
|
||||
<file>images/SR.png</file>
|
||||
<file>images/SRToken.png</file>
|
||||
<file>images/StatusPunks.png</file>
|
||||
<file>images/SuperRareCommunityBanner.png</file>
|
||||
<file>pages/StatusAccountSelectorPage.qml</file>
|
||||
<file>pages/StatusAddressPage.qml</file>
|
||||
<file>pages/StatusCardPage.qml</file>
|
||||
<file>pages/StatusChatCommandButtonPage.qml</file>
|
||||
<file>pages/StatusChatInfoToolBarPage.qml</file>
|
||||
<file>pages/StatusColorSelectorGridPage.qml</file>
|
||||
<file>pages/StatusColorSelectorPage.qml</file>
|
||||
<file>pages/StatusColorSpacePage.qml</file>
|
||||
<file>pages/StatusCommunityCardPage.qml</file>
|
||||
<file>pages/StatusCommunityTagsPage.qml</file>
|
||||
<file>pages/StatusDialogPage.qml</file>
|
||||
<file>pages/StatusExpandableSettingsItemPage.qml</file>
|
||||
<file>pages/StatusImageCropPanelPage.qml</file>
|
||||
<file>pages/StatusInputPage.qml</file>
|
||||
<file>pages/StatusItemSelectorPage.qml</file>
|
||||
<file>pages/StatusListPickerPage.qml</file>
|
||||
<file>pages/StatusMacNotificationPage.qml</file>
|
||||
<file>pages/StatusPasswordStrengthIndicatorPage.qml</file>
|
||||
<file>pages/StatusPinInputPage.qml</file>
|
||||
<file>pages/StatusPopupMenuPage.qml</file>
|
||||
<file>pages/StatusSelectPage.qml</file>
|
||||
<file>pages/StatusTabBarButtonPage.qml</file>
|
||||
<file>pages/StatusTabBarIconButtonPage.qml</file>
|
||||
<file>pages/StatusTabSwitchPage.qml</file>
|
||||
<file>pages/StatusTagSelectorPage.qml</file>
|
||||
<file>pages/StatusToastMessagePage.qml</file>
|
||||
<file>pages/StatusWalletColorButtonPage.qml</file>
|
||||
<file>pages/StatusWalletColorSelectPage.qml</file>
|
||||
<file>pages/StatusWizardStepperPage.qml</file>
|
||||
<file>DemoApp.qml</file>
|
||||
<file>main.qml</file>
|
||||
<file>ThemeSwitch.qml</file>
|
||||
<file>examples/FilteringSorting.qml</file>
|
||||
<file>images/RARI.png</file>
|
||||
<file>images/SRToken.png</file>
|
||||
<file>demoapp/data/profile-image-1.jpeg</file>
|
||||
<file>demoapp/data/profile-image-2.jpeg</file>
|
||||
<file>pages/StatusItemSelectorPage.qml</file>
|
||||
<file>pages/StatusComboBoxPage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
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.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
handler.cpp \
|
||||
main.cpp \
|
||||
sandboxapp.cpp \
|
||||
spellchecker.cpp \
|
||||
|
||||
!macx {
|
||||
SOURCES += statuswindow.cpp
|
||||
}
|
||||
|
||||
TARGET = sandboxapp
|
||||
DESTDIR = $$PWD/bin
|
||||
|
||||
DESTDIR = $$PWD/bin
|
||||
|
||||
macx {
|
||||
CONFIG -= app_bundle
|
||||
OBJECTIVE_SOURCES += \
|
||||
statuswindow_mac.mm
|
||||
|
||||
hunspellTarget.depends = FORCE
|
||||
hunspellTarget.commands = brew install hunspell
|
||||
QMAKE_EXTRA_TARGETS += hunspellTarget
|
||||
|
||||
exists (/usr/local/lib/libhunspell-1.7.a) {
|
||||
LIBS += -L"/usr/local/lib" -lhunspell-1.7
|
||||
INCLUDEPATH += /usr/local/include/hunspell
|
||||
DEFINES += USE_HUNSPELL
|
||||
message("hunspell exists in /usr/local/lib")
|
||||
}
|
||||
|
||||
copydata.commands = $(COPY_DIR) $$PWD/dictionaries $$DESTDIR
|
||||
first.depends = $(first) copydata
|
||||
export(first.depends)
|
||||
export(copydata.commands)
|
||||
QMAKE_EXTRA_TARGETS += first copydata
|
||||
}
|
||||
|
||||
ios {
|
||||
LIBS += -framework UIKit
|
||||
|
||||
QMAKE_TARGET_BUNDLE_PREFIX = "im.status"
|
||||
#QMAKE_XCODE_CODE_SIGN_IDENTITY = "iPhone Developer"
|
||||
MY_DEVELOPMENT_TEAM.name = "STATUS HOLDINGS PTE.LTD"
|
||||
MY_DEVELOPMENT_TEAM.value = "DTX7Z4U3YA"
|
||||
QMAKE_MAC_XCODE_SETTINGS += MY_DEVELOPMENT_TEAM
|
||||
|
||||
}
|
||||
|
||||
RESOURCES += qml.qrc \
|
||||
$$PWD/../statusq.qrc
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
#OTHER_FILES += $$files($$PWD/../src/*, true)
|
||||
|
||||
HEADERS += \
|
||||
handler.h \
|
||||
sandboxapp.h \
|
||||
statuswindow.h \
|
||||
spellchecker.h
|
||||
|
||||
OTHER_FILES += $$files($$PWD/../*.qml, true)
|
||||
OTHER_FILES += $$files($$PWD/*.qml, true)
|
||||
|
||||
android {
|
||||
|
||||
DISTFILES += \
|
||||
android/AndroidManifest.xml \
|
||||
android/build.gradle \
|
||||
android/gradle/wrapper/gradle-wrapper.jar \
|
||||
android/gradle/wrapper/gradle-wrapper.properties \
|
||||
android/gradlew \
|
||||
android/gradlew.bat \
|
||||
android/res/values/libs.xml
|
||||
|
||||
contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
|
||||
ANDROID_PACKAGE_SOURCE_DIR = \
|
||||
$$PWD/android
|
||||
}
|
||||
}
|
||||
+20
-10
@@ -3,15 +3,20 @@
|
||||
#include <QQmlContext>
|
||||
#include <QWindow>
|
||||
#include <QDebug>
|
||||
#include <QDirIterator>
|
||||
|
||||
#include "statuswindow.h"
|
||||
#include "spellchecker.h"
|
||||
|
||||
SandboxApp::SandboxApp(int &argc, char **argv)
|
||||
: QGuiApplication(argc, argv),
|
||||
m_handler(new Handler(this))
|
||||
: QGuiApplication(argc, argv)
|
||||
{
|
||||
connect(m_handler, &Handler::restartQml, this, &SandboxApp::restartEngine, Qt::QueuedConnection);
|
||||
#ifdef QT_DEBUG
|
||||
connect(&m_watcher, &QFileSystemWatcher::directoryChanged, [this](const QString&) {
|
||||
restartEngine();
|
||||
});
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void SandboxApp::startEngine()
|
||||
@@ -20,18 +25,23 @@ void SandboxApp::startEngine()
|
||||
qmlRegisterType<SpellChecker>("Sandbox", 0, 1, "Spellchecker");
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
const QUrl url = QUrl::fromLocalFile(applicationDirPath() + "/../main.qml");
|
||||
const QUrl url = QUrl::fromLocalFile(SRC_DIR + QStringLiteral("/main.qml"));
|
||||
m_watcher.addPath(applicationDirPath() + "/../");
|
||||
QDirIterator it(applicationDirPath() + "/../", QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
|
||||
while (it.hasNext()) {
|
||||
if (!it.filePath().isEmpty()) {
|
||||
m_watcher.addPath(it.filePath());
|
||||
}
|
||||
it.next();
|
||||
}
|
||||
#else
|
||||
const QUrl url(QStringLiteral("qrc:/main.qml"));
|
||||
#endif
|
||||
|
||||
m_engine.rootContext()->setContextProperty("app", m_handler);
|
||||
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
m_engine.addImportPath(applicationDirPath() + "/../../src");
|
||||
m_engine.addImportPath(SRC_DIR + QStringLiteral("/../src"));
|
||||
#else
|
||||
m_engine.addImportPath(QStringLiteral("qrc:/src"));
|
||||
m_engine.addImportPath(QStringLiteral(":/"));
|
||||
#endif
|
||||
qDebug() << m_engine.importPathList();
|
||||
QObject::connect(&m_engine, &QQmlApplicationEngine::objectCreated,
|
||||
@@ -44,7 +54,7 @@ void SandboxApp::startEngine()
|
||||
|
||||
void SandboxApp::restartEngine()
|
||||
{
|
||||
const QUrl url(applicationDirPath() + "/../main.qml");
|
||||
const QUrl url = QUrl::fromLocalFile(SRC_DIR + QStringLiteral("/main.qml"));
|
||||
QWindow *rootWindow = qobject_cast<QWindow*>(m_engine.rootObjects().at(0));
|
||||
if (rootWindow) {
|
||||
rootWindow->close();
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
#include "handler.h"
|
||||
#ifdef QT_DEBUG
|
||||
#include <QFileSystemWatcher>
|
||||
#endif
|
||||
|
||||
class SandboxApp : public QGuiApplication
|
||||
{
|
||||
@@ -18,7 +20,10 @@ public slots:
|
||||
|
||||
private:
|
||||
QQmlApplicationEngine m_engine;
|
||||
Handler *m_handler;
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
QFileSystemWatcher m_watcher;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // SANDBOXAPP_H
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
make clean
|
||||
if [[ $OSTYPE == 'darwin'* ]]
|
||||
then
|
||||
qmake sandbox.pro -spec macx-clang CONFIG+=debug CONFIG+=x86_64 && /usr/bin/make qmake_all
|
||||
else
|
||||
qmake sandbox.pro CONFIG+=debug CONFIG+=x86_64 && /usr/bin/make qmake_all
|
||||
fi
|
||||
make
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <QLocale>
|
||||
|
||||
#include <QRegularExpression>
|
||||
#include <QApplication>
|
||||
#include <QGuiApplication>
|
||||
#include <QDir>
|
||||
|
||||
SpellChecker::SpellChecker(QObject *parent)
|
||||
@@ -53,8 +53,8 @@ void SpellChecker::initHunspell()
|
||||
delete m_hunspell;
|
||||
}
|
||||
|
||||
QString dictFile = QApplication::applicationDirPath() + "/dictionaries/" + m_lang + "/index.dic";
|
||||
QString affixFile = QApplication::applicationDirPath() + "/dictionaries/" + m_lang + "/index.aff";
|
||||
QString dictFile = QGuiApplication::applicationDirPath() + "/dictionaries/" + m_lang + "/index.dic";
|
||||
QString affixFile = QGuiApplication::applicationDirPath() + "/dictionaries/" + m_lang + "/index.aff";
|
||||
QByteArray dictFilePathBA = dictFile.toLocal8Bit();
|
||||
QByteArray affixFilePathBA = affixFile.toLocal8Bit();
|
||||
m_hunspell = new Hunspell(affixFilePathBA.constData(),
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
#include "statuswindow.h"
|
||||
|
||||
StatusWindow::StatusWindow(QQuickWindow *parent)
|
||||
: QQuickWindow(parent)
|
||||
, m_isFullScreen(false)
|
||||
{
|
||||
removeTitleBar();
|
||||
|
||||
connect(this, &QQuickWindow::windowStateChanged, [&](Qt::WindowState windowState) {
|
||||
if (windowState == Qt::WindowNoState) {
|
||||
removeTitleBar();
|
||||
m_isFullScreen = false;
|
||||
emit isFullScreenChanged();
|
||||
} else if (windowState == Qt::WindowFullScreen) {
|
||||
m_isFullScreen = true;
|
||||
emit isFullScreenChanged();
|
||||
showTitleBar();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void StatusWindow::updatePosition()
|
||||
{
|
||||
auto point = QPoint(screen()->geometry().center().x() - geometry().width() / 2,
|
||||
screen()->geometry().center().y() - geometry().height() / 2);
|
||||
if (point != this->position()) {
|
||||
this->setPosition(point);
|
||||
}
|
||||
}
|
||||
|
||||
void StatusWindow::toggleFullScreen()
|
||||
{
|
||||
if (m_isFullScreen) {
|
||||
@@ -16,10 +44,26 @@ bool StatusWindow::isFullScreen() const
|
||||
|
||||
void StatusWindow::removeTitleBar()
|
||||
{
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
removeTitleBarWin();
|
||||
#elif defined Q_OS_MACOS
|
||||
removeTitleBarMac();
|
||||
#endif
|
||||
}
|
||||
|
||||
void StatusWindow::showTitleBar()
|
||||
{
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
showTitleBarWin();
|
||||
#elif defined Q_OS_MACOS
|
||||
showTitleBarMac();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
void StatusWindow::removeTitleBarWin()
|
||||
{}
|
||||
|
||||
void StatusWindow::showTitleBarWin()
|
||||
{}
|
||||
#endif
|
||||
|
||||
+9
-33
@@ -11,40 +11,11 @@ class StatusWindow: public QQuickWindow
|
||||
Q_PROPERTY(bool isFullScreen READ isFullScreen NOTIFY isFullScreenChanged)
|
||||
|
||||
public:
|
||||
struct EventCallbacks {
|
||||
std::function<void()> onResize;
|
||||
std::function<void()> willExitFullScreen;
|
||||
std::function<void()> didExitFullScreen;
|
||||
};
|
||||
|
||||
explicit StatusWindow(QWindow *parent = nullptr)
|
||||
: QQuickWindow(parent),
|
||||
m_isFullScreen(false)
|
||||
{
|
||||
removeTitleBar();
|
||||
|
||||
connect(this, &QQuickWindow::windowStateChanged, [&](Qt::WindowState windowState) {
|
||||
if (windowState == Qt::WindowNoState) {
|
||||
removeTitleBar();
|
||||
m_isFullScreen = false;
|
||||
emit isFullScreenChanged();
|
||||
} else if (windowState == Qt::WindowFullScreen) {
|
||||
m_isFullScreen = true;
|
||||
emit isFullScreenChanged();
|
||||
showTitleBar();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
explicit StatusWindow(QQuickWindow *parent = nullptr);
|
||||
|
||||
Q_INVOKABLE void toggleFullScreen();
|
||||
|
||||
Q_INVOKABLE void updatePosition() {
|
||||
auto point = QPoint(screen()->geometry().center().x() - geometry().width() / 2, screen()->geometry().center().y() - geometry().height() / 2);
|
||||
if (point != this->position()) {
|
||||
this->setPosition(point);
|
||||
}
|
||||
}
|
||||
Q_INVOKABLE void updatePosition();
|
||||
|
||||
bool isFullScreen() const;
|
||||
|
||||
@@ -54,10 +25,15 @@ signals:
|
||||
private:
|
||||
void removeTitleBar();
|
||||
void showTitleBar();
|
||||
void initCallbacks();
|
||||
#ifdef Q_OS_WIN
|
||||
void removeTitleBarWin();
|
||||
void showTitleBarWin();
|
||||
#elif defined Q_OS_MACOS
|
||||
void removeTitleBarMac();
|
||||
void showTitleBarMac();
|
||||
#endif
|
||||
|
||||
private:
|
||||
EventCallbacks m_callbacks;
|
||||
bool m_isFullScreen;
|
||||
};
|
||||
|
||||
|
||||
@@ -12,21 +12,7 @@
|
||||
#include <AppKit/NSButton.h>
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
void StatusWindow::toggleFullScreen()
|
||||
{
|
||||
if (m_isFullScreen) {
|
||||
showNormal();
|
||||
} else {
|
||||
showFullScreen();
|
||||
}
|
||||
}
|
||||
|
||||
bool StatusWindow::isFullScreen() const
|
||||
{
|
||||
return m_isFullScreen;
|
||||
}
|
||||
|
||||
void StatusWindow::removeTitleBar()
|
||||
void StatusWindow::removeTitleBarMac()
|
||||
{
|
||||
NSView *nsView = reinterpret_cast<NSView*>(this->winId());
|
||||
NSWindow *window = [nsView window];
|
||||
@@ -39,7 +25,7 @@ void StatusWindow::removeTitleBar()
|
||||
[titleBarContainerView setHidden:YES];
|
||||
}
|
||||
|
||||
void StatusWindow::showTitleBar()
|
||||
void StatusWindow::showTitleBarMac()
|
||||
{
|
||||
NSView *nsView = reinterpret_cast<NSView*>(this->winId());
|
||||
NSWindow *window = [nsView window];
|
||||
|
||||
@@ -4,6 +4,7 @@ import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
/// Forces size, hard to reuse it
|
||||
StatusBaseText {
|
||||
id: root
|
||||
|
||||
@@ -18,7 +19,6 @@ StatusBaseText {
|
||||
color: Theme.palette.baseColor1
|
||||
|
||||
Component.onCompleted: {
|
||||
maxWidth = width
|
||||
expanded = actualWidth <= maxWidth
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ StatusBaseText {
|
||||
|
||||
onClicked: {
|
||||
if (root.expanded) {
|
||||
width = root.width = root.maxWidth
|
||||
root.width = root.maxWidth
|
||||
} else {
|
||||
width = root.width = root.actualWidth
|
||||
root.width = root.actualWidth
|
||||
}
|
||||
root.expanded = !root.expanded
|
||||
}
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
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
|
||||
|
||||
/*!
|
||||
\qmltype StatusAddressPanel
|
||||
\inherits Item
|
||||
\inqmlmodule StatusQ.Components
|
||||
\since StatusQ.Components 0.1
|
||||
\brief Show an address as defined efined in design https://www.figma.com/file/FkFClTCYKf83RJWoifWgoX/Wallet-v2?node-id=4222%3A178403 and https://www.figma.com/file/h2Ab3k4wy1Y7SFHEvbcZZx/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop-(Copy)?node-id=1009%3A106451
|
||||
|
||||
Panel's components:
|
||||
- Address: displays the rquired \c address property
|
||||
- Frame: a rounded frame and the \c 0x icon prefix
|
||||
- Copy action: clickable copy icon. Activable using \c showCopy
|
||||
|
||||
\qmlproperty string address address to show
|
||||
\qmlproperty bool showCopy if \c true shows the copy action which triggers \c doCopy signal
|
||||
\qmlproperty bool autHideCopyIcon if \c true shows the copy action when hovered. \see showCopy
|
||||
\qmlproperty alias showFrame if \c true displays frame and \c 0x prefix
|
||||
\qmlproperty bool expandable if \c true user can toggle between expanded and compact version; \see expanded
|
||||
\qmlproperty bool expanded if \c true show address in full; if \c false show the address in compact mode eliding in the middle
|
||||
|
||||
\qmlproperty font: statusAddress.font
|
||||
|
||||
signal doCopy(string address)
|
||||
|
||||
\see StatusImageCrop for more details
|
||||
|
||||
Usage example:
|
||||
\qml
|
||||
StatusAddressPanel {
|
||||
address: currentAccount.mixedcaseAddress
|
||||
|
||||
autHideCopyIcon: true
|
||||
expanded: false
|
||||
|
||||
onDoCopy: (address) => root.store.copyToClipboard(address)
|
||||
}
|
||||
\endqml
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
Item {
|
||||
id: root
|
||||
|
||||
/*required*/ property string address: ""
|
||||
property bool showCopy: true
|
||||
property bool autHideCopyIcon: false
|
||||
property alias showFrame: frameRect.visible
|
||||
property bool expandable: false
|
||||
property bool expanded: true
|
||||
|
||||
property alias font: statusAddress.font
|
||||
|
||||
signal doCopy(string address)
|
||||
|
||||
implicitWidth: frameLayout.implicitWidth
|
||||
implicitHeight: frameLayout.implicitHeight
|
||||
|
||||
RowLayout {
|
||||
id: frameLayout
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: frameRect.visible ? 8 : undefined // Theme.geometry.halfPadding
|
||||
Layout.rightMargin: Layout.leftMargin
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
Layout.minimumWidth: 120
|
||||
Layout.preferredHeight: 32
|
||||
|
||||
spacing: 6
|
||||
|
||||
StatusIcon {
|
||||
icon: "address"
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredWidth: 19
|
||||
Layout.preferredHeight: 19
|
||||
|
||||
visible: frameRect.visible
|
||||
|
||||
color: Theme.palette.baseColor1
|
||||
opacity: 0.5
|
||||
}
|
||||
|
||||
// Ensure the eliding is done in the middle of the value not taking into account `0x`
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
StatusBaseText {
|
||||
text: "0x"
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
font: statusAddress.font
|
||||
color: statusAddress.color
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: statusAddress
|
||||
|
||||
text: root.address.replace("0x", "").replace("0X", "")
|
||||
|
||||
Layout.preferredWidth: expanded ? implicitWidth : (implicitWidth * 0.25).toFixed()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
font.family: Theme.palette.monoFont.name
|
||||
font.pixelSize: 15
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideMiddle
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
|
||||
StatusIcon {
|
||||
icon: "copy"
|
||||
|
||||
visible: root.autHideCopyIcon ? (mainMouseArea.containsMouse || copyMouseArea.containsMouse )
|
||||
: root.showCopy
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredWidth: (statusAddress.font.pixelSize * 1.2).toFixed()
|
||||
Layout.preferredHeight: Layout.preferredWidth
|
||||
|
||||
color: Theme.palette.baseColor1
|
||||
|
||||
MouseArea {
|
||||
id: copyMouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.ArrowCursor
|
||||
preventStealing: true
|
||||
|
||||
onClicked: root.doCopy(root.address)
|
||||
z: frameRect.z + 1
|
||||
}
|
||||
|
||||
StatusIcon {
|
||||
icon: parent.icon
|
||||
|
||||
x: 1
|
||||
y: 1
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
visible: copyMouseArea.containsMouse && !copyMouseArea.pressed
|
||||
|
||||
color: "black"
|
||||
opacity: 0.4
|
||||
z: parent.z + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: frameRect
|
||||
|
||||
anchors.fill: frameLayout
|
||||
|
||||
color: "transparent"
|
||||
border.width: 1
|
||||
border.color: Theme.palette.baseColor2
|
||||
radius: 36
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mainMouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
hoverEnabled: root.expandable || root.autHideCopyIcon
|
||||
enabled: (root.autHideCopyIcon && root.showCopy) || root.expandable
|
||||
acceptedButtons: root.expandable ? Qt.LeftButton : Qt.NoButton
|
||||
cursorShape: root.expandable ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
|
||||
onClicked: root.expanded = !root.expanded
|
||||
z: frameLayout.z - 1
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,8 @@ Rectangle {
|
||||
font.weight: Font.Medium
|
||||
color: Theme.palette.statusBadge.foregroundColor
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: statusBadge.border.width/4
|
||||
anchors.horizontalCenterOffset: statusBadge.border.width/4
|
||||
text: {
|
||||
if (statusBadge.value > 99) {
|
||||
return qsTr("99+");
|
||||
|
||||
@@ -0,0 +1,498 @@
|
||||
import QtQuick 2.13
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusCard
|
||||
\inherits Rectangle
|
||||
\inqmlmodule StatusQ.Components
|
||||
\since StatusQ.Components 0.1
|
||||
\brief This component represents a StatusCard as defined in design under https://www.figma.com/file/FkFClTCYKf83RJWoifWgoX/Wallet-v2?node-id=3161%3A171040
|
||||
|
||||
There is an advanced mode available where a StatusInput is provided for the user to be able to change values.
|
||||
|
||||
Example of how the component looks like:
|
||||
\image status_card.png
|
||||
|
||||
Example of how to use it:
|
||||
\qml
|
||||
StatusCard {
|
||||
id: card
|
||||
primaryText: "Mainnet"
|
||||
secondaryText: "75"
|
||||
tertiaryText: "BALANCE: " + 250
|
||||
cardIconName: "status"
|
||||
advancedMode: false
|
||||
}
|
||||
\endqml
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlproperty string StatusCard::disabledText
|
||||
This property is the text to be shown when the card is disabled
|
||||
*/
|
||||
property string disabledText: ""
|
||||
/*!
|
||||
\qmlproperty bool StatusCard::disabled
|
||||
This property holds if the card is disbaled
|
||||
*/
|
||||
property bool disabled: false
|
||||
|
||||
/*!
|
||||
\qmlproperty bool StatusCard::clickable
|
||||
This property holds if the card is clickable
|
||||
*/
|
||||
property bool clickable: true
|
||||
|
||||
/*!
|
||||
\qmlproperty bool StatusCard::advancedMode
|
||||
This property holds if advanced mode is on for the StatusCard component
|
||||
*/
|
||||
property bool advancedMode: false
|
||||
/*!
|
||||
\qmlproperty int StatusCard::lockTimeout
|
||||
This property enables user to customise the amount of time given to the user to enter a new value in
|
||||
advanced mode before it locked for any new changes
|
||||
*/
|
||||
property int lockTimeout: 1500
|
||||
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::primaryText
|
||||
Used to set Primary text in the StatusCard
|
||||
*/
|
||||
property alias primaryText: primaryText.text
|
||||
/*!
|
||||
\qmlproperty string StatusCard::secondaryText
|
||||
Used to set Secondary text in the StatusCard
|
||||
*/
|
||||
property string secondaryText: ""
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::tertiaryText
|
||||
Used to set Tertiary text in the StatusCard
|
||||
*/
|
||||
property alias tertiaryText: tertiaryText.text
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::advancedInputText
|
||||
Used to set text in the StatusInput in advancedMode
|
||||
*/
|
||||
property alias advancedInputText: advancedInput.text
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::errorIconName
|
||||
Used to assign an icon to the error icon in StatusCard
|
||||
*/
|
||||
property alias errorIconName: errorIcon.icon
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::cardIconName
|
||||
Used to assign an icon to the card icon in StatusCard
|
||||
*/
|
||||
property alias cardIconName: cardIcon.icon
|
||||
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::primaryLabel
|
||||
This property allows user to customize the primary label in the StatusCard
|
||||
*/
|
||||
property alias primaryLabel: primaryText
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::secondaryLabel
|
||||
This property allows user to customize the secondary label in the StatusCard
|
||||
*/
|
||||
property alias secondaryLabel: secondaryLabel
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::tertiaryLabel
|
||||
This property allows user to customize the tertiary label in the StatusCard
|
||||
*/
|
||||
property alias tertiaryLabel: tertiaryText
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::advancedInput
|
||||
This property allows user to customize the StatusInput in advanced mode
|
||||
*/
|
||||
property alias advancedInput: advancedInput
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::errorIcon
|
||||
This property allows user to customize the error icon in the StatusCard
|
||||
*/
|
||||
property alias errorIcon: errorIcon
|
||||
/*!
|
||||
\qmlproperty alias StatusCard::cardIcon
|
||||
This property allows user to customize the card icon in the StatusCard
|
||||
*/
|
||||
property alias cardIcon: cardIcon
|
||||
|
||||
/*!
|
||||
\qmlsignal StatusCard::clicked
|
||||
This signal is emitted when the card is clicked
|
||||
*/
|
||||
signal clicked()
|
||||
|
||||
/*!
|
||||
\qmlproperty string StatusCard::state
|
||||
This property holds the states of the StatusCard.
|
||||
Possible values are:
|
||||
\ "default" : Normal state
|
||||
\ "unavailable" : Unavailable state
|
||||
\ "unpreferred": Not preffered state
|
||||
\ "error" : Error state
|
||||
*/
|
||||
state: "default"
|
||||
|
||||
implicitHeight: advancedInput.visible ? 90 : 76
|
||||
implicitWidth: 128
|
||||
radius: 8
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton
|
||||
enabled: root.clickable && root.state !== "unavailable"
|
||||
onClicked: {
|
||||
disabled = !disabled
|
||||
root.clicked()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.leftMargin: 8
|
||||
anchors.rightMargin: 8
|
||||
anchors.topMargin: 8
|
||||
ColumnLayout {
|
||||
Layout.maximumWidth: root.width - cardIcon.width - 24
|
||||
StatusBaseText {
|
||||
id: primaryText
|
||||
Layout.maximumWidth: parent.width
|
||||
font.pixelSize: 15
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
RowLayout {
|
||||
id: basicInput
|
||||
StatusBaseText {
|
||||
id: secondaryLabel
|
||||
font.pixelSize: 13
|
||||
font.weight: Font.Medium
|
||||
}
|
||||
StatusIcon {
|
||||
id: errorIcon
|
||||
width: 14
|
||||
height: 14
|
||||
Layout.alignment: Qt.AlignTop
|
||||
icon: "tiny/warning"
|
||||
color: Theme.palette.pinColor1
|
||||
}
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: advancedInput
|
||||
property bool locked: false
|
||||
implicitWidth: 80
|
||||
maximumHeight: 32
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
leftPadding: 8
|
||||
rightPadding: 5
|
||||
input.edit.font.pixelSize: 13
|
||||
input.edit.readOnly: locked || disabled
|
||||
input.rightComponent: Row {
|
||||
width: implicitWidth
|
||||
spacing: 4
|
||||
StatusFlatRoundButton {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 12
|
||||
height: 12
|
||||
icon.name: advancedInput.locked ? "lock" : "unlock"
|
||||
icon.width: 12
|
||||
icon.height: 12
|
||||
icon.color: advancedInput.locked ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
enabled: !disabled
|
||||
onClicked: {
|
||||
advancedInput.locked = !advancedInput.locked
|
||||
waitTimer.restart()
|
||||
}
|
||||
}
|
||||
StatusFlatRoundButton {
|
||||
width: 14
|
||||
height: 14
|
||||
icon.name: "clear"
|
||||
icon.width: 14
|
||||
icon.height: 14
|
||||
icon.color: Theme.palette.baseColor1
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
onClicked: advancedInput.edit.clear()
|
||||
}
|
||||
}
|
||||
onTextChanged: {
|
||||
locked = false
|
||||
waitTimer.restart()
|
||||
}
|
||||
Timer {
|
||||
id: waitTimer
|
||||
interval: lockTimeout
|
||||
onTriggered: {
|
||||
if(advancedInput.edit.text)
|
||||
advancedInput.locked = true
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusBaseText {
|
||||
id: tertiaryText
|
||||
font.pixelSize: 10
|
||||
}
|
||||
}
|
||||
StatusIcon {
|
||||
id: cardIcon
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignRight
|
||||
Layout.preferredHeight: 32
|
||||
Layout.preferredWidth: 32
|
||||
mipmap: true
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "default"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
color: disabled ? Theme.palette.baseColor4 : "transparent"
|
||||
}
|
||||
PropertyChanges {
|
||||
target: root
|
||||
border.color: disabled ? "transparent" : Theme.palette.primaryColor2
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
visible: primaryText.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
color: disabled ? Theme.palette.directColor5: Theme.palette.primaryColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
visible: !advancedMode && secondaryLabel.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
text: disabled ? disabledText : secondaryText
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
color: Theme.palette.directColor5
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
visible: tertiaryText.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: cardIcon
|
||||
opacity: disabled ? 0.4 : 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: errorIcon
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
visible: advancedMode
|
||||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
edit.color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: basicInput
|
||||
visible: !advancedMode
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "error"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
color: disabled ? Theme.palette.baseColor4 : "transparent"
|
||||
}
|
||||
PropertyChanges {
|
||||
target: root
|
||||
border.color: disabled ? "transparent" : Theme.palette.primaryColor2
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
visible: primaryText.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
color: disabled ? Theme.palette.directColor5: Theme.palette.dangerColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
visible: !advancedMode && secondaryLabel.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
text: disabled ? disabledText : secondaryText
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
color: disabled ? Theme.palette.directColor5 : Theme.palette.dangerColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
visible: tertiaryText.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: cardIcon
|
||||
opacity: disabled ? 0.4 : 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: errorIcon
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
visible: advancedMode
|
||||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
edit.color: disabled ? Theme.palette.directColor5 : Theme.palette.dangerColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: basicInput
|
||||
visible: !advancedMode
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "unpreferred"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
color: disabled ? Theme.palette.baseColor4 : "transparent"
|
||||
}
|
||||
PropertyChanges {
|
||||
target: root
|
||||
border.color: disabled ? "transparent": Theme.palette.pinColor2
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
visible: primaryText.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
color: disabled ? Theme.palette.directColor5 : Theme.palette.pinColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
visible: !advancedMode && secondaryLabel.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
text: disabled ? disabledText : secondaryText
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
color: disabled ? Theme.palette.directColor5 : Theme.palette.pinColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
visible: tertiaryText.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: cardIcon
|
||||
opacity: disabled ? 0.4 : 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: errorIcon
|
||||
visible: !disabled && !advancedMode
|
||||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
visible: advancedMode
|
||||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
edit.color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: basicInput
|
||||
visible: !advancedMode
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "unavailable"
|
||||
PropertyChanges {
|
||||
target: root
|
||||
color: "transparent"
|
||||
}
|
||||
PropertyChanges {
|
||||
target: root
|
||||
border.color: "transparent"
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
color: Theme.palette.directColor5
|
||||
}
|
||||
PropertyChanges {
|
||||
target: primaryText
|
||||
visible: primaryText.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
color: Theme.palette.directColor5
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
visible: secondaryLabel.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: secondaryLabel
|
||||
text: secondaryText
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
color: Theme.palette.directColor5
|
||||
}
|
||||
PropertyChanges {
|
||||
target: tertiaryText
|
||||
visible: tertiaryText.text
|
||||
}
|
||||
PropertyChanges {
|
||||
target: cardIcon
|
||||
opacity: 0.4
|
||||
}
|
||||
PropertyChanges {
|
||||
target: errorIcon
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: advancedInput
|
||||
edit.color: Theme.palette.directColor1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: basicInput
|
||||
visible: true
|
||||
}
|
||||
}
|
||||
]}
|
||||
@@ -9,7 +9,7 @@ import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Column {
|
||||
id: statusChatList
|
||||
id: root
|
||||
|
||||
spacing: 4
|
||||
width: 288
|
||||
@@ -23,8 +23,6 @@ Column {
|
||||
|
||||
property Component popupMenu
|
||||
|
||||
property var filterFn
|
||||
|
||||
signal chatItemSelected(string categoryId, string id)
|
||||
signal chatItemUnmuted(string id)
|
||||
signal chatItemReordered(string id, int from, int to)
|
||||
@@ -35,22 +33,36 @@ Column {
|
||||
}
|
||||
}
|
||||
|
||||
onDraggableItemsChanged: delegateModel.items.setGroups(0, delegateModel.items.count, "unsorted")
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property int destinationPosition: -1
|
||||
}
|
||||
|
||||
DelegateModel {
|
||||
id: delegateModel
|
||||
model: statusChatList.model
|
||||
model: root.model
|
||||
|
||||
items.includeByDefault: !root.draggableItems
|
||||
|
||||
groups: DelegateModelGroup {
|
||||
id: unsortedItems
|
||||
|
||||
name: "unsorted"
|
||||
includeByDefault: root.draggableItems
|
||||
onChanged: Utils.delegateModelSort(unsortedItems, delegateModel.items,
|
||||
(a, b) => a.position < b.position)
|
||||
}
|
||||
|
||||
delegate: Item {
|
||||
id: draggable
|
||||
width: statusChatListItem.width
|
||||
objectName: model.name
|
||||
width: root.width
|
||||
height: statusChatListItem.height
|
||||
property alias chatListItem: statusChatListItem
|
||||
|
||||
visible: {
|
||||
if (!!statusChatList.filterFn) {
|
||||
return statusChatList.filterFn(model)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: dragSensor
|
||||
|
||||
@@ -58,7 +70,7 @@ Column {
|
||||
cursorShape: active ? Qt.ClosedHandCursor : Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
pressAndHoldInterval: 150
|
||||
enabled: statusChatList.draggableItems
|
||||
enabled: root.draggableItems
|
||||
|
||||
property bool active: false
|
||||
property real startY: 0
|
||||
@@ -74,8 +86,8 @@ Column {
|
||||
}
|
||||
onPressAndHold: active = true
|
||||
onReleased: {
|
||||
if (active) {
|
||||
statusChatList.chatItemReordered(statusChatListItem.chatId, statusChatListItem.originalOrder, statusChatListItem.originalOrder)
|
||||
if (active && d.destinationPosition !== -1 && statusChatListItem.originalOrder !== d.destinationPosition) {
|
||||
root.chatItemReordered(statusChatListItem.chatId, statusChatListItem.originalOrder, d.destinationPosition)
|
||||
}
|
||||
active = false
|
||||
}
|
||||
@@ -89,10 +101,12 @@ Column {
|
||||
active = true
|
||||
}
|
||||
}
|
||||
onActiveChanged: d.destinationPosition = -1
|
||||
|
||||
StatusChatListItem {
|
||||
id: statusChatListItem
|
||||
|
||||
width: parent.width
|
||||
opacity: dragSensor.active ? 0.0 : 1.0
|
||||
originalOrder: model.position
|
||||
chatId: model.itemId
|
||||
@@ -103,7 +117,7 @@ Column {
|
||||
hasUnreadMessages: model.hasUnreadMessages
|
||||
notificationsCount: model.notificationsCount
|
||||
highlightWhenCreated: !!model.highlight
|
||||
selected: (model.active && statusChatList.highlightItem)
|
||||
selected: (model.active && root.highlightItem)
|
||||
|
||||
icon.emoji: model.emoji
|
||||
icon.color: !!model.color ? model.color : Theme.palette.userCustomizationColors[model.colorId]
|
||||
@@ -112,10 +126,26 @@ Column {
|
||||
ringSettings.ringSpecModel: model.colorHash
|
||||
|
||||
sensor.cursorShape: dragSensor.cursorShape
|
||||
|
||||
Connections {
|
||||
target: statusChatListItem
|
||||
enabled: root.draggableItems
|
||||
|
||||
function onOriginalOrderChanged() {
|
||||
Qt.callLater(() => {
|
||||
if (!delegateModel)
|
||||
return
|
||||
|
||||
delegateModel.items.setGroups(0, delegateModel.items.count, "unsorted")
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
highlightWhenCreated = false
|
||||
|
||||
if (mouse.button === Qt.RightButton && !!statusChatList.popupMenu) {
|
||||
if (mouse.button === Qt.RightButton && !!root.popupMenu) {
|
||||
statusChatListItem.highlighted = true
|
||||
|
||||
let originalOpenHandler = popupMenuSlot.item.openHandler
|
||||
@@ -136,17 +166,17 @@ Column {
|
||||
}
|
||||
}
|
||||
|
||||
let p = statusChatListItem.mapToItem(statusChatList, mouse.x, mouse.y)
|
||||
let p = statusChatListItem.mapToItem(root, mouse.x, mouse.y)
|
||||
|
||||
popupMenuSlot.item.popup(p.x + 4, p.y + 6)
|
||||
popupMenuSlot.item.openHandler = originalOpenHandler
|
||||
return
|
||||
}
|
||||
if (!statusChatListItem.selected) {
|
||||
statusChatList.chatItemSelected(model.parentItemId, model.itemId)
|
||||
root.chatItemSelected(model.parentItemId, model.itemId)
|
||||
}
|
||||
}
|
||||
onUnmute: statusChatList.chatItemUnmuted(model.itemId)
|
||||
onUnmute: root.chatItemUnmuted(model.itemId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +187,6 @@ Column {
|
||||
keys: ["chat-item-category-" + statusChatListItem.categoryId]
|
||||
|
||||
onEntered: reorderDelay.start()
|
||||
onDropped: statusChatList.chatItemReordered(statusChatListItem.chatId, drag.source.originalOrder, statusChatListItem.DelegateModel.itemsIndex)
|
||||
|
||||
Timer {
|
||||
id: reorderDelay
|
||||
@@ -165,7 +194,7 @@ Column {
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if (dropArea.containsDrag) {
|
||||
dropArea.drag.source.chatListItem.originalOrder = statusChatListItem.originalOrder
|
||||
d.destinationPosition = delegateModel.model.get(draggable.DelegateModel.itemsIndex).position
|
||||
delegateModel.items.move(dropArea.drag.source.DelegateModel.itemsIndex, draggable.DelegateModel.itemsIndex)
|
||||
}
|
||||
}
|
||||
@@ -209,11 +238,12 @@ Column {
|
||||
|
||||
Repeater {
|
||||
id: statusChatListItems
|
||||
objectName: "chatListItems"
|
||||
model: delegateModel
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: popupMenuSlot
|
||||
active: !!statusChatList.popupMenu
|
||||
active: !!root.popupMenu
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,16 @@ import StatusQ.Components 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
Item {
|
||||
id: statusChatListAndCategories
|
||||
id: root
|
||||
|
||||
implicitHeight: chatListsAndCategories.height
|
||||
implicitWidth: chatListsAndCategories.width
|
||||
|
||||
property alias highlightItem: statusChatList.highlightItem
|
||||
|
||||
property StatusTooltipSettings categoryAddButtonToolTip: StatusTooltipSettings {
|
||||
text: qsTr("Add channel inside category")
|
||||
}
|
||||
@@ -49,11 +53,11 @@ Item {
|
||||
MouseArea {
|
||||
id: sensor
|
||||
anchors.top: parent.top
|
||||
width: statusChatListAndCategories.width
|
||||
height: statusChatListAndCategories.height
|
||||
width: root.width
|
||||
height: root.height
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: {
|
||||
if (mouse.button === Qt.RightButton && showPopupMenu && !!statusChatListAndCategories.popupMenu) {
|
||||
if (mouse.button === Qt.RightButton && showPopupMenu && !!root.popupMenu) {
|
||||
popupMenuSlot.item.popup(mouse.x + 4, mouse.y + 6)
|
||||
return
|
||||
}
|
||||
@@ -69,20 +73,44 @@ Item {
|
||||
StatusChatList {
|
||||
id: statusChatList
|
||||
visible: statusChatList.model.count > 0
|
||||
onChatItemSelected: statusChatListAndCategories.chatItemSelected(categoryId, id)
|
||||
onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
|
||||
onChatItemReordered: statusChatListAndCategories.chatItemReordered(categoryId, id, from, to)
|
||||
draggableItems: statusChatListAndCategories.draggableItems
|
||||
model: statusChatListAndCategories.model
|
||||
filterFn: function (model) {
|
||||
return !model.isCategory
|
||||
onChatItemSelected: root.chatItemSelected(categoryId, id)
|
||||
onChatItemUnmuted: root.chatItemUnmuted(id)
|
||||
onChatItemReordered: root.chatItemReordered(categoryId, id, from, to)
|
||||
draggableItems: root.draggableItems
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: root.model
|
||||
|
||||
filters: ValueFilter { roleName: "isCategory"; value: false }
|
||||
sorters: RoleSorter { roleName: "position" }
|
||||
}
|
||||
popupMenu: statusChatListAndCategories.chatListPopupMenu
|
||||
|
||||
popupMenu: root.chatListPopupMenu
|
||||
}
|
||||
|
||||
DelegateModel {
|
||||
id: delegateModel
|
||||
model: statusChatListAndCategories.model
|
||||
|
||||
property int destinationPosition: -1
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: root.model
|
||||
|
||||
filters: ValueFilter { roleName: "isCategory"; value: true }
|
||||
sorters: RoleSorter { roleName: "position" }
|
||||
}
|
||||
|
||||
items.includeByDefault: false
|
||||
|
||||
groups: DelegateModelGroup {
|
||||
id: unsortedItems
|
||||
|
||||
name: "unsorted"
|
||||
includeByDefault: true
|
||||
onChanged: Utils.delegateModelSort(unsortedItems, delegateModel.items,
|
||||
(a, b) => a.position < b.position)
|
||||
}
|
||||
|
||||
delegate: Item {
|
||||
id: draggable
|
||||
width: statusChatListCategory.width
|
||||
@@ -102,13 +130,13 @@ Item {
|
||||
dragSensor.drag.threshold: 0.1
|
||||
dragSensor.drag.filterChildren: true
|
||||
dragSensor.onPressAndHold: {
|
||||
if (statusChatListAndCategories.draggableCategories) {
|
||||
if (root.draggableCategories) {
|
||||
dragActive = true
|
||||
}
|
||||
}
|
||||
dragSensor.onReleased: {
|
||||
if (dragActive) {
|
||||
statusChatListAndCategories.chatListCategoryReordered(statusChatListCategory.categoryId, statusChatListCategory.originalOrder, statusChatListCategory.originalOrder)
|
||||
if (dragActive && delegateModel.destinationPosition !== -1 && statusChatListCategory.originalOrder !== delegateModel.destinationPosition) {
|
||||
root.chatListCategoryReordered(statusChatListCategory.categoryId, statusChatListCategory.originalOrder, delegateModel.destinationPosition)
|
||||
}
|
||||
dragActive = false
|
||||
}
|
||||
@@ -118,38 +146,44 @@ Item {
|
||||
startX = dragSensor.mouseX
|
||||
}
|
||||
dragSensor.onMouseYChanged: {
|
||||
if (statusChatListAndCategories.draggableCategories && (Math.abs(startY - dragSensor.mouseY) > 1) && dragSensor.pressed) {
|
||||
if (root.draggableCategories && (Math.abs(startY - dragSensor.mouseY) > 1) && dragSensor.pressed) {
|
||||
dragActive = true
|
||||
}
|
||||
}
|
||||
dragSensor.onMouseXChanged: {
|
||||
if (statusChatListAndCategories.draggableCategories && (Math.abs(startX - dragSensor.mouseX) > 1) && dragSensor.pressed) {
|
||||
if (root.draggableCategories && (Math.abs(startX - dragSensor.mouseX) > 1) && dragSensor.pressed) {
|
||||
dragActive = true
|
||||
}
|
||||
}
|
||||
onDragActiveChanged: delegateModel.destinationPosition = -1
|
||||
|
||||
addButton.tooltip: statusChatListAndCategories.categoryAddButtonToolTip
|
||||
menuButton.tooltip: statusChatListAndCategories.categoryMenuButtonToolTip
|
||||
addButton.tooltip: root.categoryAddButtonToolTip
|
||||
menuButton.tooltip: root.categoryMenuButtonToolTip
|
||||
|
||||
originalOrder: model.position
|
||||
categoryId: model.itemId
|
||||
name: model.name
|
||||
showActionButtons: statusChatListAndCategories.showCategoryActionButtons
|
||||
addButton.onClicked: statusChatListAndCategories.categoryAddButtonClicked(model.itemId)
|
||||
|
||||
chatList.model: model.subItems
|
||||
chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(categoryId, id)
|
||||
chatList.onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
|
||||
chatList.onChatItemReordered: statusChatListAndCategories.chatItemReordered(model.itemId, id, from, to)
|
||||
chatList.draggableItems: statusChatListAndCategories.draggableItems
|
||||
showActionButtons: root.showCategoryActionButtons
|
||||
addButton.onClicked: root.categoryAddButtonClicked(model.itemId)
|
||||
|
||||
popupMenu: statusChatListAndCategories.categoryPopupMenu
|
||||
chatListPopupMenu: statusChatListAndCategories.chatListPopupMenu
|
||||
chatList.model: SortFilterProxyModel {
|
||||
sourceModel: model.subItems
|
||||
sorters: RoleSorter { roleName: "position" }
|
||||
}
|
||||
|
||||
chatList.onChatItemSelected: root.chatItemSelected(categoryId, id)
|
||||
chatList.onChatItemUnmuted: root.chatItemUnmuted(id)
|
||||
chatList.onChatItemReordered: root.chatItemReordered(model.itemId, id, from, to)
|
||||
chatList.draggableItems: root.draggableItems
|
||||
|
||||
popupMenu: root.categoryPopupMenu
|
||||
chatListPopupMenu: root.chatListPopupMenu
|
||||
|
||||
// Used to set the initial value of "opened" when the
|
||||
// model is bound/changed.
|
||||
opened: {
|
||||
let openedState = statusChatListAndCategories.openedCategoryState[model.itemId]
|
||||
let openedState = root.openedCategoryState[model.itemId]
|
||||
return openedState !== undefined ? openedState : true // defaults to open
|
||||
}
|
||||
|
||||
@@ -158,7 +192,18 @@ Item {
|
||||
// as the state would be lost each time the model is
|
||||
// changed.
|
||||
onOpenedChanged: {
|
||||
statusChatListAndCategories.openedCategoryState[model.itemId] = statusChatListCategory.opened
|
||||
root.openedCategoryState[model.itemId] = statusChatListCategory.opened
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onOriginalOrderChanged() {
|
||||
Qt.callLater(() => {
|
||||
if (!delegateModel)
|
||||
return
|
||||
|
||||
delegateModel.items.setGroups(0, delegateModel.items.count, "unsorted")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +214,6 @@ Item {
|
||||
keys: ["chat-category"]
|
||||
|
||||
onEntered: reorderDelay.start()
|
||||
onDropped: statusChatListAndCategories.chatListCategoryReordered(statusChatListCategory.categoryId, drag.source.originalOrder, statusChatListCategory.DelegateModel.itemsIndex)
|
||||
|
||||
Timer {
|
||||
id: reorderDelay
|
||||
@@ -177,7 +221,7 @@ Item {
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if (dropArea.containsDrag) {
|
||||
dropArea.drag.source.chatListCategory.originalOrder = statusChatListCategory.originalOrder
|
||||
delegateModel.destinationPosition = delegateModel.model.get(draggable.DelegateModel.itemsIndex).position
|
||||
delegateModel.items.move(dropArea.drag.source.DelegateModel.itemsIndex, draggable.DelegateModel.itemsIndex)
|
||||
}
|
||||
}
|
||||
@@ -223,6 +267,6 @@ Item {
|
||||
|
||||
Loader {
|
||||
id: popupMenuSlot
|
||||
active: !!statusChatListAndCategories.popupMenu
|
||||
active: !!root.popupMenu
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ Column {
|
||||
StatusChatListCategoryItem {
|
||||
id: statusChatListCategoryItem
|
||||
title: statusChatListCategory.name
|
||||
visible: model.isCategory
|
||||
opened: statusChatListCategory.opened
|
||||
sensor.pressAndHoldInterval: 150
|
||||
|
||||
@@ -66,9 +65,6 @@ Column {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
visible: statusChatListCategory.opened
|
||||
categoryId: statusChatListCategory.categoryId
|
||||
filterFn: function (model) {
|
||||
return !!model.parentItemId && model.parentItemId === statusChatList.categoryId
|
||||
}
|
||||
|
||||
popupMenu: statusChatListCategory.chatListPopupMenu
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ Item {
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: menuButton
|
||||
objectName: "chatToolbarMoreOptionsButton"
|
||||
width: 32
|
||||
height: 32
|
||||
icon.name: "more"
|
||||
|
||||
@@ -13,21 +13,23 @@ Item {
|
||||
property alias model: repeater.model
|
||||
property alias contentWidth: flow.width
|
||||
|
||||
readonly property int itemsWidth: {
|
||||
let result = 0;
|
||||
for (let i = 0; i < repeater.count; ++i) {
|
||||
result += flow.spacing + repeater.itemAt(i).width;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
signal clicked(var item)
|
||||
|
||||
implicitWidth: flow.implicitWidth
|
||||
implicitHeight: flow.implicitHeight
|
||||
implicitWidth: itemsWidth
|
||||
implicitHeight: flow.height
|
||||
|
||||
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);
|
||||
}
|
||||
width: Math.min(parent.width, root.itemsWidth);
|
||||
spacing: 10
|
||||
|
||||
Repeater {
|
||||
@@ -38,7 +40,7 @@ Item {
|
||||
name: model.name
|
||||
visible: (root.showOnlySelected ? model.selected : !model.selected) &&
|
||||
(filterString == 0 || name.toUpperCase().indexOf(filterString.toUpperCase()) !== -1)
|
||||
width: visible ? implicitWidth : -10
|
||||
width: visible ? implicitWidth : -flow.spacing
|
||||
height: visible ? implicitHeight : 0
|
||||
removable: root.showOnlySelected && root.active
|
||||
onClicked: root.clicked(model)
|
||||
|
||||
@@ -6,7 +6,7 @@ import StatusQ.Core.Theme 0.1
|
||||
Row {
|
||||
id: root
|
||||
|
||||
property bool isMutualContact: false
|
||||
property bool isContact: false
|
||||
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
|
||||
property StatusIconSettings mutualConnectionIcon: StatusIconSettings {
|
||||
@@ -51,10 +51,10 @@ Row {
|
||||
}
|
||||
|
||||
spacing: 4
|
||||
visible: root.isMutualContact || (root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None)
|
||||
visible: root.isContact || (root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None)
|
||||
|
||||
StatusRoundIcon {
|
||||
visible: root.isMutualContact
|
||||
visible: root.isContact
|
||||
icon.name: root.mutualConnectionIcon.name
|
||||
icon.width: root.mutualConnectionIcon.width
|
||||
icon.height: root.mutualConnectionIcon.height
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import Qt.labs.calendar 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusDatePicker
|
||||
\inherits StatusQ.Controls.StatusComboBox
|
||||
\inqmlmodule StatusQ.Components
|
||||
\since StatusQ.Components 0.1
|
||||
\brief Displays a date picker based on a combobox with a calendar popup
|
||||
|
||||
The \c StatusDatePicker displays a date picker based on a combobox with a calendar popup.
|
||||
The property \p selectedDate reflects the currently chosen date (defaults to today).
|
||||
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
StatusComboBox {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlproperty string StatusDatePicker::dateFormat
|
||||
|
||||
This property specifies how the selected date will be displayed to the user.
|
||||
By default it is current locale's short date format. For a list of available types
|
||||
and formatting characters, see https://doc.qt.io/qt-5/qdate.html#toString-2
|
||||
*/
|
||||
property string dateFormat: Qt.locale().dateFormat(Locale.ShortFormat)
|
||||
|
||||
/*!
|
||||
\qmlproperty date StatusDatePicker::selectedDate
|
||||
|
||||
This property holds the currently selected date.
|
||||
\sa QtQml.Date
|
||||
*/
|
||||
property alias selectedDate: d.selectedDate
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property date selectedDate: new Date()
|
||||
}
|
||||
|
||||
control.delegate: null
|
||||
control.displayText: root.selectedDate.toLocaleDateString(Qt.locale(), root.dateFormat)
|
||||
control.popup.horizontalPadding: 8
|
||||
|
||||
control.popup.onAboutToShow: {
|
||||
// always open the popup showing the last (currently) selected date
|
||||
grid.year = d.selectedDate.getFullYear()
|
||||
grid.month = d.selectedDate.getMonth()
|
||||
}
|
||||
|
||||
control.popup.contentItem: Item {
|
||||
property alias grid: grid
|
||||
GridLayout {
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
spacing: 0
|
||||
StatusFlatButton {
|
||||
leftPadding: 8
|
||||
rightPadding: 8
|
||||
text: "<<"
|
||||
onClicked: grid.year = grid.year - 1
|
||||
StatusToolTip {
|
||||
text: qsTr("Previous year")
|
||||
visible: parent.hovered
|
||||
}
|
||||
}
|
||||
StatusFlatButton {
|
||||
leftPadding: 8
|
||||
rightPadding: 8
|
||||
text: "<"
|
||||
onClicked: {
|
||||
// switch to previous month (and optionally prev year in January)
|
||||
const date = new Date(grid.year, grid.month)
|
||||
date.setMonth(date.getMonth() - 1)
|
||||
grid.month = date.getMonth()
|
||||
grid.year = date.getFullYear()
|
||||
}
|
||||
StatusToolTip {
|
||||
text: qsTr("Previous month")
|
||||
visible: parent.hovered
|
||||
}
|
||||
}
|
||||
StatusFlatButton {
|
||||
Layout.fillWidth: true
|
||||
text: grid.title
|
||||
font.pixelSize: 18
|
||||
font.weight: Font.Medium
|
||||
onClicked: {
|
||||
const date = new Date()
|
||||
grid.month = date.getMonth()
|
||||
grid.year = date.getFullYear()
|
||||
}
|
||||
StatusToolTip {
|
||||
text: qsTr("Show current month")
|
||||
visible: parent.hovered
|
||||
}
|
||||
}
|
||||
StatusFlatButton {
|
||||
leftPadding: 8
|
||||
rightPadding: 8
|
||||
text: ">"
|
||||
onClicked: {
|
||||
// switch to next month (and optionally next year in December)
|
||||
const date = new Date(grid.year, grid.month)
|
||||
date.setMonth(date.getMonth() + 1)
|
||||
grid.month = date.getMonth()
|
||||
grid.year = date.getFullYear()
|
||||
}
|
||||
StatusToolTip {
|
||||
text: qsTr("Next month")
|
||||
visible: parent.hovered
|
||||
}
|
||||
}
|
||||
StatusFlatButton {
|
||||
leftPadding: 8
|
||||
rightPadding: 8
|
||||
text: ">>"
|
||||
onClicked: grid.year = grid.year + 1
|
||||
StatusToolTip {
|
||||
text: qsTr("Next year")
|
||||
visible: parent.hovered
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DayOfWeekRow {
|
||||
Layout.row: 1
|
||||
Layout.column: 1
|
||||
Layout.fillWidth: true
|
||||
delegate: StatusBaseText {
|
||||
text: model.shortName
|
||||
color: Theme.palette.directColor3
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
WeekNumberColumn {
|
||||
id: weekColumn
|
||||
month: grid.month
|
||||
year: grid.year
|
||||
Layout.fillHeight: true
|
||||
delegate: StatusBaseText {
|
||||
text: model.weekNumber
|
||||
color: Theme.palette.directColor3
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
MonthGrid {
|
||||
id: grid
|
||||
month: d.selectedDate.getMonth()
|
||||
year: d.selectedDate.getFullYear()
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
delegate: StatusFlatButton {
|
||||
readonly property bool selected: d.selectedDate.getFullYear() === model.year &&
|
||||
d.selectedDate.getMonth() === model.month &&
|
||||
d.selectedDate.getDate() === model.day
|
||||
opacity: model.month === grid.month ? 1 : 0.5
|
||||
text: model.day
|
||||
textColor: selected ? Theme.palette.primaryColor1 : Theme.palette.directColor1
|
||||
font.bold: selected || model.today
|
||||
onClicked: {
|
||||
d.selectedDate = model.date
|
||||
root.control.popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,12 +217,12 @@ Rectangle {
|
||||
Transition {
|
||||
from: "COLLAPSED"
|
||||
to: "EXPANDED"
|
||||
NumberAnimation { properties: "height"; duration: 200; running: visible }
|
||||
NumberAnimation { properties: "height"; duration: 200;}
|
||||
},
|
||||
Transition {
|
||||
from: "EXPANDED"
|
||||
to: "COLLAPSED"
|
||||
NumberAnimation { properties: "height"; duration: 200; running: visible }
|
||||
NumberAnimation { properties: "height"; duration: 200;}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusImageCropPanel
|
||||
@@ -127,12 +128,15 @@ Item {
|
||||
id: mainLayout
|
||||
|
||||
anchors.fill: parent
|
||||
spacing: 1
|
||||
|
||||
Item {
|
||||
id: cropSpaceItem
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 10
|
||||
Layout.rightMargin: 10
|
||||
|
||||
clip: true
|
||||
|
||||
@@ -142,6 +146,7 @@ Item {
|
||||
anchors.top: parent.top
|
||||
anchors.right: cropEditor.left
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: -1
|
||||
color: wallColor
|
||||
opacity: wallTransparency
|
||||
z: cropEditor.z + 1
|
||||
@@ -160,8 +165,9 @@ Item {
|
||||
StatusImageCrop {
|
||||
id: cropEditor
|
||||
anchors.centerIn: parent
|
||||
width: aspectRatio < cropSpaceItem.width/cropSpaceItem.height ? cropSpaceItem.height * aspectRatio : cropSpaceItem.width - root.margins * 2
|
||||
height: aspectRatio < cropSpaceItem.width/cropSpaceItem.height ? cropSpaceItem.height - root.margins * 2 : cropSpaceItem.width / aspectRatio
|
||||
readonly property bool cropARSmall: aspectRatio < cropSpaceItem.width/cropSpaceItem.height
|
||||
width: cropARSmall ? cropSpaceItem.height * aspectRatio : cropSpaceItem.width - root.margins * 2
|
||||
height: cropARSmall ? cropSpaceItem.height - root.margins * 2 : cropSpaceItem.width / aspectRatio
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -170,6 +176,7 @@ Item {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: -1
|
||||
color: wallColor
|
||||
opacity: wallTransparency
|
||||
z: cropEditor.z + 1
|
||||
@@ -181,6 +188,7 @@ Item {
|
||||
anchors.top: cropEditor.bottom
|
||||
anchors.right: rightOverlay.left
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: -1
|
||||
color: wallColor
|
||||
opacity: wallTransparency
|
||||
z: cropEditor.z + 1
|
||||
@@ -190,6 +198,7 @@ Item {
|
||||
Canvas {
|
||||
visible: root.enableCheckers
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: -1
|
||||
onPaint: {
|
||||
var ctx = getContext("2d")
|
||||
for(let xI = 0; xI < Math.ceil(width/10); xI++) {
|
||||
@@ -238,17 +247,20 @@ Item {
|
||||
|
||||
RowLayout {
|
||||
visible: root.interactive
|
||||
spacing: 10
|
||||
|
||||
StatusIcon {
|
||||
icon: "remove-circle"
|
||||
color: Theme.palette.baseColor1
|
||||
|
||||
Layout.preferredWidth: 20
|
||||
Layout.preferredHeight: 20
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredWidth: 24
|
||||
Layout.preferredHeight: 24
|
||||
}
|
||||
StatusSlider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
Layout.bottomMargin: 25
|
||||
Layout.topMargin: 10
|
||||
Layout.bottomMargin: 10
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
enabled: root.interactive
|
||||
@@ -261,9 +273,11 @@ Item {
|
||||
}
|
||||
StatusIcon {
|
||||
icon: "add-circle"
|
||||
color: Theme.palette.baseColor1
|
||||
|
||||
Layout.preferredWidth: 20
|
||||
Layout.preferredHeight: 20
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredWidth: 24
|
||||
Layout.preferredHeight: 24
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtQuick.Controls 2.14 as QC
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusItemSelector
|
||||
\inherits Rectangle
|
||||
\inqmlmodule StatusQ.Components
|
||||
\since StatusQ.Components 0.1
|
||||
\brief It allows to add items and display them as a tag item with an image and text. It also allows to store and display logical `and` / `or` operators into the list. Inherits \l{https://doc.qt.io/qt-6/qml-qtquick-rectangle.html}{Item}.
|
||||
|
||||
The \c StatusItemSelector is populated with a data model. The data model is commonly a JavaScript array or a ListModel object with specific expected roles.
|
||||
|
||||
Example of how the component looks like:
|
||||
\image status_item_selector.png
|
||||
|
||||
Example of how to use it:
|
||||
\qml
|
||||
StatusItemSelector {
|
||||
icon: Style.svg("contact_verified")
|
||||
title: qsTr("Who holds")
|
||||
defaultItemText: qsTr("Example: 10 SNT")
|
||||
andOperatorText: qsTr("and")
|
||||
orOperatorText: qsTr("or")
|
||||
popupItem: CustomPopup {
|
||||
id: customPopup
|
||||
onAddItem: {
|
||||
tokensSelector.addItem(itemText, itemImage, operator)
|
||||
customPopup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
Rectangle {
|
||||
id: root
|
||||
/*!
|
||||
\qmlproperty string StatusItemSelector::icon
|
||||
This property holds the icon name for the icon represented on top of the component as a title icon.
|
||||
*/
|
||||
property string icon
|
||||
/*!
|
||||
\qmlproperty int StatusItemSelector::iconSize
|
||||
This property holds the icon size for the icon represented on top of the component as a title icon.
|
||||
*/
|
||||
property int iconSize: 18
|
||||
/*!
|
||||
\qmlproperty string StatusItemSelector::title
|
||||
This property holds the titel shown on top of the component.
|
||||
*/
|
||||
property string title
|
||||
/*!
|
||||
\qmlproperty string StatusItemSelector::defaultItemText
|
||||
This property holds the default item text shown when the list of items is empty.
|
||||
*/
|
||||
property string defaultItemText
|
||||
/*!
|
||||
\qmlproperty url StatusItemSelector::defaultItemImageSource
|
||||
This property holds the default item icon shown when the list of items is empty.
|
||||
*/
|
||||
property url defaultItemImageSource: ""
|
||||
/*!
|
||||
\qmlproperty QC.Popup StatusItemSelector::popupItem
|
||||
This property holds a custom popup item to be opened near the `add` button in order to select new items.
|
||||
*/
|
||||
property QC.Popup popupItem
|
||||
/*!
|
||||
\qmlproperty ListModel StatusItemSelector::itemsModel
|
||||
This property holds the data that will be populated in the items selector.
|
||||
|
||||
Here an example of the model roles expected:
|
||||
\qml
|
||||
itemsModel: ListModel {
|
||||
ListElement {
|
||||
text: "Socks"
|
||||
imageSource: "qrc:imports/assets/png/tokens/SOCKS.png"
|
||||
operator: Utils.Operator.None
|
||||
}
|
||||
ListElement {
|
||||
text: "ZRX"
|
||||
imageSource: "qrc:imports/assets/png/tokens/ZRX.png"
|
||||
operator: Utils.Operator.Or
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
property ListModel itemsModel: ListModel { }
|
||||
/*!
|
||||
\qmlproperty string StatusItemSelector::andOperatorText
|
||||
This property holds the string text representation for an `AND` logical operator.
|
||||
*/
|
||||
property string andOperatorText: qsTr("and")
|
||||
/*!
|
||||
\qmlproperty string StatusItemSelector::orOperatorText
|
||||
This property holds the string text representation for an `OR` logical operator.
|
||||
*/
|
||||
property string orOperatorText: qsTr("or")
|
||||
/*
|
||||
\qmlmethod StatusItemSelector::addItem()
|
||||
It is used to add new items into the selector control. The expected arguments are:
|
||||
string `text`, url `imageSource` and int `operator` (None = 0, And = 1 and Or = 2)
|
||||
*/
|
||||
function addItem(text, imageSource, operator) {
|
||||
itemsModel.insert(itemsModel.count, { "text": text, "imageSource": imageSource.toString(), "operator": operator })
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
function operatorTextFormat(operator) {
|
||||
switch(operator)
|
||||
{
|
||||
case Utils.Operators.And:
|
||||
return root.andOperatorText
|
||||
case Utils.Operators.Or:
|
||||
return root.orOperatorText
|
||||
case Utils.Operators.None:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
color: Theme.palette.baseColor4
|
||||
implicitHeight: columnLayout.implicitHeight + columnLayout.anchors.topMargin + columnLayout.anchors.bottomMargin
|
||||
implicitWidth: 560
|
||||
radius: 16
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 12
|
||||
anchors.bottomMargin: anchors.topMargin
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 16
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 16
|
||||
spacing: 12
|
||||
clip: true
|
||||
RowLayout {
|
||||
id: headerRow
|
||||
spacing: 8
|
||||
Image {
|
||||
sourceSize.width: width || undefined
|
||||
sourceSize.height: height || undefined
|
||||
fillMode: Image.PreserveAspectFit
|
||||
mipmap: true
|
||||
antialiasing: true
|
||||
width: root.iconSize
|
||||
height: width
|
||||
source: root.icon
|
||||
}
|
||||
StatusBaseText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: root.title
|
||||
color: Theme.palette.directColor1
|
||||
font.pixelSize: 17
|
||||
}
|
||||
}
|
||||
Flow {
|
||||
id: flow
|
||||
Layout.fillWidth: true
|
||||
spacing: 6
|
||||
StatusListItemTag {
|
||||
visible: itemsModel.count === 0
|
||||
title: root.defaultItemText
|
||||
image.source: root.defaultItemImageSource
|
||||
color: Theme.palette.baseColor2
|
||||
closeButtonVisible: false
|
||||
titleText.color: Theme.palette.baseColor1
|
||||
titleText.font.pixelSize: 15
|
||||
}
|
||||
Repeater {
|
||||
model: itemsModel
|
||||
RowLayout {
|
||||
spacing: flow.spacing
|
||||
StatusBaseText {
|
||||
visible: model.operator !== Utils.Operators.None
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: d.operatorTextFormat(model.operator)
|
||||
color: Theme.palette.primaryColor1
|
||||
font.pixelSize: 17
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
// Switch operator
|
||||
if(model.operator === Utils.Operators.And)
|
||||
model.operator = Utils.Operators.Or
|
||||
else
|
||||
model.operator = Utils.Operators.And
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusListItemTag {
|
||||
title: model.text
|
||||
image.source: model.imageSource
|
||||
color: Theme.palette.primaryColor3
|
||||
closeButtonVisible: false
|
||||
titleText.color: Theme.palette.primaryColor1
|
||||
titleText.font.pixelSize: 15
|
||||
//onClicked: // TODO: Open remove or edit dialog
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusRoundButton {
|
||||
id: addItemButton
|
||||
implicitHeight: 32
|
||||
implicitWidth: implicitHeight
|
||||
height: width
|
||||
type: StatusRoundButton.Type.Secondary
|
||||
icon.name: "add"
|
||||
onClicked: {
|
||||
root.popupItem.x = addItemButton.x + addItemButton.width + 4 * flow.spacing
|
||||
root.popupItem.y = addItemButton.y + addItemButton.height
|
||||
root.popupItem.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ Rectangle {
|
||||
property string subTitle: ""
|
||||
property string tertiaryTitle: ""
|
||||
property string label: ""
|
||||
property string titleTextIcon: ""
|
||||
property real leftPadding: 16
|
||||
property real rightPadding: 16
|
||||
property bool enabled: true
|
||||
@@ -230,6 +231,16 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
StatusIcon {
|
||||
width: visible ? 12 : 0
|
||||
height: visible ? 12 : 0
|
||||
visible: !!statusListItem.titleTextIcon
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: statusListItemTitle.contentWidth + 6
|
||||
icon: statusListItem.titleTextIcon
|
||||
}
|
||||
|
||||
StatusToolTip {
|
||||
id: statusListItemTitleTooltip
|
||||
text: statusListItemTitle.text
|
||||
@@ -273,6 +284,7 @@ Rectangle {
|
||||
|
||||
StatusBaseText {
|
||||
id: statusListItemSubTitle
|
||||
objectName: "statusListItemSubTitle"
|
||||
anchors.top: statusListItemTitle.bottom
|
||||
width: parent.width
|
||||
text: statusListItem.subTitle
|
||||
|
||||
@@ -6,6 +6,8 @@ import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
/*!
|
||||
\qmltype StatusListPicker
|
||||
\inherits Item
|
||||
@@ -15,7 +17,7 @@ import StatusQ.Controls 0.1
|
||||
|
||||
The \c StatusListPicker is populated with a data model. The data model is commonly a JavaScript array or a ListModel object.
|
||||
|
||||
StatusListPicker can be made as a single or multiple options picker by setting its StatusListPicker::multiSelection property properly or will be auto-set if the model contains / provides more than one selected items.
|
||||
StatusListPicker can be made as a single or multiple options picker by setting its StatusListPicker::multiSelection property properly.
|
||||
The StatusPickerButton text holds the text of the current item selected in the list picker. If there is more than one item selected, a string composed will be displayed.
|
||||
The drop-down list incorporates a searcher by the following model roles: `name` or / and `shortName`.
|
||||
|
||||
@@ -44,6 +46,7 @@ Item {
|
||||
This property holds the data that will be populated in the list picker.
|
||||
|
||||
NOTE: This model property should not change so it is an in / out property where the selected role will be dynamically changed according to user actions.
|
||||
NOTE: Be sure provided model is compatible with StatusListPicker::multiSelection property.
|
||||
|
||||
Here an example of the model roles expected:
|
||||
\qml
|
||||
@@ -69,7 +72,9 @@ Item {
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
property ListModel inputList: ListModel { }
|
||||
property var inputList: ListModel { }
|
||||
|
||||
readonly property StatusListPickerProxies proxy: StatusListPickerProxies {}
|
||||
|
||||
/*!
|
||||
\qmlproperty string StatusListPicker::searchText
|
||||
@@ -151,94 +156,66 @@ Item {
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property var filteredModel: ListModel { }
|
||||
|
||||
// Used to set up component and the needed private properties
|
||||
function initialize() {
|
||||
if(filteredModel.count === 0) {
|
||||
// It is necessary to load the model, not loaded yet!
|
||||
var selected = 0
|
||||
var selectionText = ""
|
||||
for(var i = 0; i < root.inputList.count; i++) {
|
||||
var item = root.inputList.get(i)
|
||||
d.filteredModel.append(item)
|
||||
if(item.selected) selected++;
|
||||
}
|
||||
|
||||
// If the given model has more than one selected elements, the behaviour of the list picker will be as a multiple selector with checkboxes although it is
|
||||
// set in the radiobutton mode. Radiobutton mode is only for mutial-exclusion.
|
||||
if(selected > 1)
|
||||
multiSelection = true
|
||||
|
||||
// Update selected items text:
|
||||
d.getSelectedItemsText()
|
||||
readonly property SortFilterProxyModel selectedItems: SortFilterProxyModel {
|
||||
sourceModel: root.inputList
|
||||
// NOTE: ValueFilter would crash if source model does not contain given role
|
||||
// FIXME: use ValueFilter when its fixed
|
||||
filters: ExpressionFilter {
|
||||
expression: root.proxy.selected(model)
|
||||
}
|
||||
}
|
||||
|
||||
// Used to update model elements given a specific text by filtering them for its `name` and / or `shortName`.
|
||||
function applyFilter(text) {
|
||||
const input = text.toLowerCase()
|
||||
filteredModel.clear()
|
||||
for(var i = 0; i < root.inputList.count; i++) {
|
||||
let item = root.inputList.get(i)
|
||||
if(item.name.toLowerCase().includes(input) || item.shortName.toLowerCase().includes(input))
|
||||
filteredModel.append(item)
|
||||
readonly property string selectedItemsText: {
|
||||
function formatSymbolShortNameText(symbol, shortName) {
|
||||
var formattedText = ""
|
||||
if(root.printSymbol && symbol)
|
||||
formattedText = symbol + shortName
|
||||
else
|
||||
formattedText = shortName
|
||||
return formattedText
|
||||
}
|
||||
}
|
||||
|
||||
function formatSymbolShortNameText(symbol, shortName) {
|
||||
var formattedText = ""
|
||||
if(root.printSymbol && symbol)
|
||||
formattedText = symbol + shortName
|
||||
else
|
||||
formattedText = shortName
|
||||
return formattedText
|
||||
}
|
||||
|
||||
function getSelectedItemsText() {
|
||||
var res = ""
|
||||
for(var i = 0; i < root.inputList.count; i++) {
|
||||
var item = root.inputList.get(i)
|
||||
if(item.selected) {
|
||||
if(res != "")
|
||||
res += ", "
|
||||
res += d.formatSymbolShortNameText(item.symbol, item.shortName)
|
||||
}
|
||||
for(var i = 0; i < selectedItems.count; i++) {
|
||||
var item = selectedItems.get(i)
|
||||
if(res != "")
|
||||
res += ", "
|
||||
res += formatSymbolShortNameText(root.proxy.symbol(item), root.proxy.shortName(item))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Used to update the base input list model with the new selected property
|
||||
function updateInputListModel(key, selected, isSingleSelection) {
|
||||
// If it is a single selection we must ensure that when a new key is selected others are cleared.
|
||||
// It must be done manually because as there is the option of filterning, the model visualized changes
|
||||
// and it could be possible to have a filtered list without an element selected (but in the base model
|
||||
// it is) so, the binding to not selected will not be executed, as in the current filtered model
|
||||
// there are no changes to update, just only the selected one.
|
||||
for(var i = 0; i < root.inputList.count; i++) {
|
||||
if(root.inputList.get(i).key === key) {
|
||||
root.inputList.get(i).selected = selected
|
||||
}
|
||||
else if(isSingleSelection && selected) {
|
||||
// Clear all the list
|
||||
root.inputList.get(i).selected = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
width: 110
|
||||
height: 38
|
||||
|
||||
Component.onCompleted: d.initialize()
|
||||
Repeater {
|
||||
// Used to update the base input list model with the new selected property
|
||||
// If it is a single selection we must ensure that when a new key is selected others are cleared.
|
||||
id: itemsSelectorHelper
|
||||
|
||||
signal selectItem(var key, bool checked)
|
||||
|
||||
model: root.inputList
|
||||
delegate: Item {
|
||||
Connections {
|
||||
target: itemsSelectorHelper
|
||||
function onSelectItem(key, checked) {
|
||||
if (root.proxy.key(model) === key) root.proxy.setSelected(model, checked)
|
||||
else if (!root.multiSelection && checked) root.proxy.setSelected(model, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusPickerButton {
|
||||
id: btn
|
||||
anchors.fill: parent
|
||||
bgColor: Theme.palette.primaryColor3
|
||||
contentColor: Theme.palette.primaryColor1
|
||||
text: picker.selectedItemsText
|
||||
textPixelSize: 13
|
||||
text: d.selectedItemsText
|
||||
font.pixelSize: 13
|
||||
type: StatusPickerButton.Type.Down
|
||||
|
||||
onClicked: {
|
||||
@@ -253,8 +230,6 @@ Item {
|
||||
Rectangle {
|
||||
id: picker
|
||||
|
||||
property string selectedItemsText: ""
|
||||
|
||||
width: content.itemWidth
|
||||
height: Math.min(content.contentHeight + content.anchors.topMargin + content.anchors.bottomMargin, root.maxPickerHeight)
|
||||
anchors.left: root.menuAlignment === StatusListPicker.MenuAlignment.Left ? btn.left : undefined
|
||||
@@ -277,12 +252,23 @@ Item {
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: content
|
||||
id: content
|
||||
|
||||
property int itemHeight: 40
|
||||
property int itemWidth: 360
|
||||
|
||||
model: d.filteredModel
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: root.inputList
|
||||
delayed: true
|
||||
filters: ExpressionFilter {
|
||||
expression: {
|
||||
root.searchText // ensure expression is reevaluated when searchText changes
|
||||
return root.proxy.name(model).toLowerCase().includes(root.searchText.toLowerCase()) ||
|
||||
root.proxy.shortName(model).toLowerCase().includes(root.searchText.toLowerCase())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
width: itemWidth
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 8
|
||||
@@ -298,9 +284,9 @@ Item {
|
||||
color: Theme.palette.statusPopupMenu.backgroundColor
|
||||
z: 3 // Above delegate (z=1) and above section.delegate (z = 2)
|
||||
|
||||
StatusBaseInput {
|
||||
StatusInput {
|
||||
id: searchInput
|
||||
implicitHeight: 36
|
||||
maximumHeight: 36
|
||||
width: content.itemWidth - 2 * 18
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -308,12 +294,9 @@ Item {
|
||||
bottomPadding: 0
|
||||
placeholderText: root.placeholderSearchText
|
||||
text: root.searchText
|
||||
icon.name: "search"
|
||||
input.icon.name: "search"
|
||||
|
||||
onTextChanged: {
|
||||
d.applyFilter(text)
|
||||
root.searchText = text
|
||||
}
|
||||
onTextChanged: root.searchText = text
|
||||
}
|
||||
}// End of search input item
|
||||
delegate: StatusItemPicker {
|
||||
@@ -321,30 +304,24 @@ Item {
|
||||
height: content.itemHeight
|
||||
color: mouseArea.containsMouse ? Theme.palette.baseColor4 : "transparent"
|
||||
image: StatusImageSettings {
|
||||
source: model.imageSource ? model.imageSource : ""
|
||||
source: root.proxy.imageSource(model) ? root.proxy.imageSource(model) : ""
|
||||
width: 15
|
||||
height: 15
|
||||
isIdenticon: false
|
||||
}
|
||||
name: model.name
|
||||
shortName: model.shortName
|
||||
name: root.proxy.name(model)
|
||||
shortName: root.proxy.shortName(model)
|
||||
selectorType: root.multiSelection ? StatusItemPicker.SelectorType.CheckBox : StatusItemPicker.SelectorType.RadioButton
|
||||
selected: model.selected
|
||||
selected: root.proxy.selected(model)
|
||||
radioGroup: radioBtnGroup
|
||||
|
||||
onCheckedChanged: {
|
||||
d.updateInputListModel(model.key, checked, selectorType === StatusItemPicker.SelectorType.RadioButton)
|
||||
if(selectorType === StatusItemPicker.SelectorType.RadioButton && checked) {
|
||||
// Update selected item text
|
||||
picker.selectedItemsText = d.formatSymbolShortNameText(model.symbol, model.shortName)
|
||||
}
|
||||
else {
|
||||
// Update selected items text (multiple selection, text chain).
|
||||
picker.selectedItemsText = d.getSelectedItemsText()
|
||||
if (checked !== root.proxy.selected(model)) {
|
||||
itemsSelectorHelper.selectItem(root.proxy.key(model), checked)
|
||||
}
|
||||
|
||||
// Used to notify selected property changes in the specific item picker.
|
||||
itemPickerChanged(model.key, checked)
|
||||
itemPickerChanged(root.proxy.key(model), checked)
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
@@ -386,7 +363,7 @@ Item {
|
||||
// Not visual element to control mutual-exclusion of radiobuttons that are not sharing the same parent (inside list view)
|
||||
ButtonGroup {
|
||||
id: radioBtnGroup
|
||||
}
|
||||
}// End of Content
|
||||
}
|
||||
}// End of Content
|
||||
}// End of Rectangle picker
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import QtQuick 2.14
|
||||
|
||||
/*!
|
||||
Enables StatusListPicker to work with incompatible models.
|
||||
\qml
|
||||
StatusListPicker {
|
||||
id: currencyPicker
|
||||
inputList: ListModel {
|
||||
ListElement { incompatibleA: 0 ... incomatibleZ: false }
|
||||
ListElement { incompatibleA: 1 ... incomatibleZ: false }
|
||||
ListElement { incompatibleA: 2 ... incomatibleZ: false }
|
||||
}
|
||||
proxy { // StatusListPickerProxies
|
||||
key: (model) => model.incompatibleA
|
||||
...
|
||||
selected: (model) => model.incompatibleZ
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
QtObject {
|
||||
property var key: (model) => model.key
|
||||
property var name: (model) => model.name
|
||||
property var shortName: (model) => model.shortName
|
||||
property var symbol: (model) => model.symbol
|
||||
property var imageSource: (model) => model.imageSource
|
||||
property var category: (model) => model.category
|
||||
property var selected: (model) => model.selected
|
||||
property var setSelected: (model, val) => model.selected = val
|
||||
}
|
||||
@@ -111,7 +111,7 @@ StatusListItem {
|
||||
// root object settings:
|
||||
title: (root.nickName === "") ? root.userName : root.nickName
|
||||
statusListItemTitleIcons.sourceComponent: StatusContactVerificationIcons {
|
||||
isMutualContact: root.isContact
|
||||
isContact: root.isContact
|
||||
trustIndicator: {
|
||||
if (root.isVerified) return StatusContactVerificationIcons.TrustedType.Verified
|
||||
else if (root.isUntrustworthy) return StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
|
||||
@@ -100,7 +100,7 @@ Rectangle {
|
||||
displayName: messageDetails.displayName
|
||||
secondaryName: messageDetails.secondaryName
|
||||
tertiaryDetail: messageDetails.chatID
|
||||
isMutualContact: messageDetails.isMutualContact
|
||||
isContact: messageDetails.isContact
|
||||
trustIndicator: messageDetails.trustIndicator
|
||||
resendText: statusMessage.resendText
|
||||
showResendButton: messageDetails.hasExpired && messageDetails.amISender
|
||||
|
||||
@@ -17,7 +17,7 @@ QtObject {
|
||||
property string messageText: ""
|
||||
property int contentType: 0
|
||||
property string messageContent: ""
|
||||
property bool isMutualContact: false
|
||||
property bool isContact: false
|
||||
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
property bool hasMention: false
|
||||
property bool isPinned: false
|
||||
|
||||
@@ -79,6 +79,7 @@ Loader {
|
||||
Component {
|
||||
id: letterIdenticon
|
||||
StatusLetterIdenticon {
|
||||
objectName: "statusSmartIdenticonLetter"
|
||||
width: statusSmartIdenticon.icon.width
|
||||
height: statusSmartIdenticon.icon.height
|
||||
color: statusSmartIdenticon.icon.color
|
||||
|
||||
@@ -177,7 +177,7 @@ Item {
|
||||
"localNickname": entry.localNickname,
|
||||
"isVerified": entry.isVerified,
|
||||
"isUntrustworthy": entry.isUntrustworthy,
|
||||
"isContact": entry.isMutualContact,
|
||||
"isContact": entry.isContact,
|
||||
"ringSpecModel": entry.ringSpecModel,
|
||||
"icon": entry.icon,
|
||||
"onlineStatus": entry.onlineStatus,
|
||||
@@ -247,6 +247,7 @@ Item {
|
||||
StatusBaseText {
|
||||
Layout.preferredWidth: 22
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.baseColor1
|
||||
text: root.toLabelText
|
||||
visible: (parent.width>22)
|
||||
@@ -377,6 +378,7 @@ Item {
|
||||
}
|
||||
contentItem: ListView {
|
||||
id: userListView
|
||||
objectName: "tagSelectorUserList"
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: 16
|
||||
|
||||
@@ -26,9 +26,9 @@ Item {
|
||||
// To-Do: Move to StatusChatInput once its moved to StatusQ
|
||||
sourceComponent: StatusInput {
|
||||
width: editText.width
|
||||
input.placeholderText: ""
|
||||
placeholderText: ""
|
||||
input.text: msgText
|
||||
input.implicitHeight: 40
|
||||
maximumHeight: 40
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
|
||||
@@ -19,7 +19,7 @@ Item {
|
||||
property string tertiaryDetail: ""
|
||||
property string resendText: ""
|
||||
property bool showResendButton: false
|
||||
property bool isMutualContact: false
|
||||
property bool isContact: false
|
||||
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
|
||||
signal clicked()
|
||||
@@ -55,7 +55,7 @@ Item {
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
StatusContactVerificationIcons {
|
||||
isMutualContact: statusMessageHeader.isMutualContact
|
||||
isContact: statusMessageHeader.isContact
|
||||
trustIndicator: statusMessageHeader.trustIndicator
|
||||
}
|
||||
StatusBaseText {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module StatusQ.Components
|
||||
|
||||
StatusAddress 0.1 StatusAddress.qml
|
||||
StatusAddressPanel 0.1 StatusAddressPanel.qml
|
||||
StatusBadge 0.1 StatusBadge.qml
|
||||
StatusChatInfoToolBar 0.1 StatusChatInfoToolBar.qml
|
||||
StatusChatList 0.1 StatusChatList.qml
|
||||
@@ -37,3 +38,6 @@ StatusImageCropPanel 0.1 StatusImageCropPanel.qml
|
||||
StatusColorSpace 0.0 StatusColorSpace.qml
|
||||
StatusCommunityCard 0.1 StatusCommunityCard.qml
|
||||
StatusCommunityTags 0.1 StatusCommunityTags.qml
|
||||
StatusItemSelector 0.1 StatusItemSelector.qml
|
||||
StatusCard 0.1 StatusCard.qml
|
||||
StatusDatePicker 0.1 StatusDatePicker.qml
|
||||
|
||||
@@ -8,17 +8,17 @@ import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string label: "Choose account"
|
||||
property bool showAccountDetails: !!selectedAccount
|
||||
property var accounts
|
||||
property var selectedAccount
|
||||
property string currency: "usd"
|
||||
property alias selectField: select
|
||||
implicitWidth: 448
|
||||
height: select.height +
|
||||
(selectedAccountDetails.visible ? selectedAccountDetails.height + selectedAccountDetails.anchors.topMargin : 0)
|
||||
|
||||
// set to asset symbol to display asset's balance top right
|
||||
// NOTE: if this asset is not selected as a wallet token in the UI, then
|
||||
// nothing will be displayed
|
||||
@@ -27,10 +27,10 @@ Item {
|
||||
property double minRequiredAssetBalance: 0
|
||||
property int dropdownWidth: width
|
||||
property int chainId: 0
|
||||
property alias dropdownAlignment: select.menuAlignment
|
||||
property bool isValid: true
|
||||
property bool readOnly: false
|
||||
|
||||
|
||||
property var assetBalanceTextFn: function (foundValue) {
|
||||
return "Balance: " + (parseFloat(foundValue) === 0.0 ? "0" : Utils.stripTrailingZeros(foundValue))
|
||||
}
|
||||
@@ -51,18 +51,23 @@ Item {
|
||||
return root.isValid
|
||||
}
|
||||
|
||||
implicitWidth: 448
|
||||
implicitHeight: comboBox.height +
|
||||
(selectedAccountDetails.visible ? selectedAccountDetails.height + selectedAccountDetails.anchors.topMargin
|
||||
: 0)
|
||||
|
||||
onSelectedAccountChanged: {
|
||||
if (!selectedAccount) {
|
||||
return
|
||||
}
|
||||
if (selectedAccount.color) {
|
||||
selectedIconImg.color = Utils.getThemeAccountColor(selectedAccount.color, Theme.palette.userCustomizationColors) || Theme.palette.userCustomizationColors[0]
|
||||
d.selectedIconColor = Utils.getThemeAccountColor(selectedAccount.color, Theme.palette.userCustomizationColors) || Theme.palette.userCustomizationColors[0]
|
||||
}
|
||||
if (selectedAccount.name) {
|
||||
selectedTextField.text = selectedAccount.name
|
||||
d.selectedText = selectedAccount.name
|
||||
}
|
||||
if (selectedAccount.address) {
|
||||
textSelectedAddress.text = selectedAccount.address + " •"
|
||||
textSelectedAddress.text = selectedAccount.address
|
||||
}
|
||||
if (selectedAccount.currencyBalance) {
|
||||
textSelectedAddressFiatBalance.text = selectedAccount.currencyBalance + " " + currency.toUpperCase()
|
||||
@@ -87,14 +92,20 @@ Item {
|
||||
txtAssetSymbol.text = " " + assetFound.symbol
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property color selectedIconColor: "transparent"
|
||||
property string selectedText: ""
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: txtAssetBalance
|
||||
visible: root.assetFound !== undefined
|
||||
anchors.bottom: select.top
|
||||
anchors.bottom: comboBox.top
|
||||
anchors.bottomMargin: -18
|
||||
anchors.right: txtAssetSymbol.left
|
||||
anchors.left: select.left
|
||||
anchors.leftMargin: select.width / 2.5
|
||||
anchors.left: comboBox.left
|
||||
anchors.leftMargin: comboBox.width / 2.5
|
||||
|
||||
color: !root.isValid ? Theme.palette.dangerColor1 : Theme.palette.baseColor1
|
||||
elide: Text.ElideRight
|
||||
@@ -116,6 +127,7 @@ Item {
|
||||
onExited: assetTooltip.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: txtAssetSymbol
|
||||
visible: txtAssetBalance.visible
|
||||
@@ -126,152 +138,149 @@ Item {
|
||||
font.pixelSize: 13
|
||||
height: txtAssetBalance.height
|
||||
}
|
||||
StatusSelect {
|
||||
id: select
|
||||
|
||||
StatusComboBox {
|
||||
id: comboBox
|
||||
|
||||
label: root.label
|
||||
model: root.accounts
|
||||
width: parent.width
|
||||
menuAlignment: StatusSelect.MenuAlignment.Left
|
||||
selectMenu.delegate: menuItem
|
||||
selectMenu.width: dropdownWidth
|
||||
selectedItemComponent: Item {
|
||||
anchors.fill: parent
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: root.accounts
|
||||
filters: [
|
||||
ValueFilter {
|
||||
roleName: "walletType"
|
||||
value: root.watchWalletType
|
||||
inverted: true
|
||||
}
|
||||
]
|
||||
}
|
||||
contentItem: RowLayout {
|
||||
spacing: 8
|
||||
|
||||
StatusIcon {
|
||||
id: selectedIconImg
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 16
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 20
|
||||
height: 20
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredWidth: 20
|
||||
Layout.preferredHeight: 20
|
||||
icon: "filled-account"
|
||||
color: d.selectedIconColor
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: selectedTextField
|
||||
elide: Text.ElideRight
|
||||
anchors.left: selectedIconImg.right
|
||||
anchors.leftMargin: 8
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: select.selectedItemRightMargin
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
font.pixelSize: 15
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
height: 22
|
||||
color: Theme.palette.directColor1
|
||||
text: d.selectedText
|
||||
}
|
||||
}
|
||||
|
||||
delegate: StatusItemDelegate {
|
||||
highlighted: index === comboBox.control.highlightedIndex
|
||||
width: comboBox.width
|
||||
padding: 16
|
||||
|
||||
onClicked: {
|
||||
// WARNING: Settings comboBox value from delegate is wrong.
|
||||
// ComboBox must have a single role as "value"
|
||||
// This should be refactored later. Probably roleValue should be 'address'.
|
||||
// All other needed values should be retrived from model by the user of component.
|
||||
root.selectedAccount = { address, name, color: model.color, assets, currencyBalance };
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// WARNING: Same here, this is wrong, check comment above.
|
||||
if (!root.selectedAccount && index === 0) {
|
||||
root.selectedAccount = { address, name, color: model.color, assets, currencyBalance }
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: 0
|
||||
|
||||
StatusIcon {
|
||||
id: iconImg
|
||||
Layout.preferredWidth: 20
|
||||
Layout.preferredHeight: 20
|
||||
icon: "filled-account"
|
||||
color: Utils.getThemeAccountColor(model.color, Theme.palette.userCustomizationColors) ||
|
||||
Theme.palette.userCustomizationColors[0]
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: column
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 14
|
||||
Layout.rightMargin: 8
|
||||
spacing: 0
|
||||
|
||||
StatusBaseText {
|
||||
id: accountName
|
||||
Layout.fillWidth: true
|
||||
text: model.name
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: accountAddress
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: 80
|
||||
text: address
|
||||
elide: Text.ElideMiddle
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
StatusBaseText {
|
||||
id: txtFiatBalance
|
||||
Layout.rightMargin: 4
|
||||
font.pixelSize: 15
|
||||
text: currencyBalance
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
StatusBaseText {
|
||||
id: fiatCurrencySymbol
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.baseColor1
|
||||
text: root.currency.toUpperCase()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
RowLayout {
|
||||
id: selectedAccountDetails
|
||||
visible: root.showAccountDetails
|
||||
anchors.top: select.bottom
|
||||
anchors.top: comboBox.bottom
|
||||
anchors.topMargin: 8
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 2
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 4
|
||||
|
||||
spacing: 2
|
||||
|
||||
StatusBaseText {
|
||||
id: textSelectedAddress
|
||||
Layout.maximumWidth: 80
|
||||
font.pixelSize: 12
|
||||
elide: Text.ElideMiddle
|
||||
width: 90
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
StatusBaseText {
|
||||
id: textSelectedAddressFiatBalance
|
||||
font.pixelSize: 12
|
||||
color: Theme.palette.baseColor1
|
||||
text: "•"
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: menuItem
|
||||
MenuItem {
|
||||
id: itemContainer
|
||||
visible: walletType !== root.watchWalletType
|
||||
property bool isFirstItem: index === 0
|
||||
property bool isLastItem: index === accounts.rowCount() - 1
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!root.selectedAccount && isFirstItem) {
|
||||
root.selectedAccount = { address, name, color: model.color, assets, currencyBalance }
|
||||
}
|
||||
}
|
||||
|
||||
height: walletType === root.watchWalletType ? 0 : (accountName.height + 14 + accountAddress.height + 14)
|
||||
|
||||
StatusIcon {
|
||||
id: iconImg
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 16
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 20
|
||||
height: 20
|
||||
icon: "filled-account"
|
||||
color: Utils.getThemeAccountColor(model.color, Theme.palette.userCustomizationColors) || Theme.palette.userCustomizationColors[0]
|
||||
}
|
||||
|
||||
Column {
|
||||
id: column
|
||||
anchors.left: iconImg.right
|
||||
anchors.leftMargin: 14
|
||||
anchors.right: txtFiatBalance.left
|
||||
anchors.rightMargin: 8
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
StatusBaseText {
|
||||
id: accountName
|
||||
text: model.name
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: 15
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: 22
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: accountAddress
|
||||
text: address
|
||||
elide: Text.ElideMiddle
|
||||
width: 80
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: 12
|
||||
height: 16
|
||||
}
|
||||
}
|
||||
StatusBaseText {
|
||||
id: txtFiatBalance
|
||||
anchors.right: fiatCurrencySymbol.left
|
||||
anchors.rightMargin: 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 15
|
||||
height: 22
|
||||
text: currencyBalance
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
StatusBaseText {
|
||||
id: fiatCurrencySymbol
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 16
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 15
|
||||
height: 22
|
||||
color: Theme.palette.baseColor1
|
||||
text: root.currency.toUpperCase()
|
||||
}
|
||||
background: Rectangle {
|
||||
color: itemContainer.highlighted ? Theme.palette.statusSelect.menuItemHoverBackgroundColor : Theme.palette.statusSelect.menuItemBackgroundColor
|
||||
}
|
||||
MouseArea {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
anchors.fill: itemContainer
|
||||
onClicked: {
|
||||
root.selectedAccount = { address, name, color: model.color, assets, currencyBalance }
|
||||
select.selectMenu.close()
|
||||
}
|
||||
}
|
||||
StatusBaseText {
|
||||
id: textSelectedAddressFiatBalance
|
||||
Layout.fillWidth: true
|
||||
font.pixelSize: 12
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,20 +42,10 @@ StatusFlatRoundButton {
|
||||
|
||||
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
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -(icon.height/2.5)
|
||||
anchors.horizontalCenterOffset: (width/2.5)
|
||||
border.width: 2
|
||||
border.color: parent.hovered ? Theme.palette.baseColor2 : Theme.palette.statusAppLayout.backgroundColor
|
||||
}
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property var assets
|
||||
property var selectedAsset
|
||||
property string defaultToken: ""
|
||||
property var tokenAssetSourceFn: function (symbol) {
|
||||
return ""
|
||||
}
|
||||
// Define this in the usage to get balance in currency selected by user
|
||||
property var getCurrencyBalanceString: function (currencyBalance) { return "" }
|
||||
implicitWidth: 86
|
||||
implicitHeight: 32
|
||||
|
||||
function resetInternal() {
|
||||
assets = null
|
||||
selectedAsset = null
|
||||
}
|
||||
|
||||
onSelectedAssetChanged: {
|
||||
if (selectedAsset && selectedAsset.symbol) {
|
||||
iconImg.image.source = tokenAssetSourceFn(selectedAsset.symbol.toUpperCase())
|
||||
selectedTextField.text = selectedAsset.symbol.toUpperCase()
|
||||
}
|
||||
}
|
||||
|
||||
StatusSelect {
|
||||
id: select
|
||||
width: parent.width
|
||||
bgColor: "transparent"
|
||||
bgColorHover: Theme.palette.directColor8
|
||||
model: root.assets
|
||||
caretRightMargin: 0
|
||||
select.radius: 6
|
||||
select.height: root.height
|
||||
selectMenu.width: 342
|
||||
selectedItemComponent: Item {
|
||||
anchors.fill: parent
|
||||
StatusRoundedImage {
|
||||
id: iconImg
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 4
|
||||
width: 24
|
||||
height: 24
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
image.onStatusChanged: {
|
||||
if (iconImg.image.status === Image.Error) {
|
||||
iconImg.image.source = defaultToken
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusBaseText {
|
||||
id: selectedTextField
|
||||
anchors.left: iconImg.right
|
||||
anchors.leftMargin: 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 15
|
||||
height: 22
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
}
|
||||
selectMenu.delegate: menuItem
|
||||
}
|
||||
|
||||
Component {
|
||||
id: menuItem
|
||||
MenuItem {
|
||||
id: itemContainer
|
||||
property bool isFirstItem: index === 0
|
||||
property bool isLastItem: index === assets.rowCount() - 1
|
||||
|
||||
width: parent.width
|
||||
height: 72
|
||||
StatusRoundedImage {
|
||||
id: iconImg
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 16
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
image.source: root.tokenAssetSourceFn(symbol.toUpperCase())
|
||||
image.onStatusChanged: {
|
||||
if (iconImg.image.status === Image.Error) {
|
||||
iconImg.image.source = defaultToken
|
||||
}
|
||||
}
|
||||
}
|
||||
Column {
|
||||
anchors.left: iconImg.right
|
||||
anchors.leftMargin: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
StatusBaseText {
|
||||
text: symbol.toUpperCase()
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: name
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: 15
|
||||
}
|
||||
}
|
||||
Column {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 16
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
StatusBaseText {
|
||||
font.pixelSize: 15
|
||||
text: parseFloat(totalBalance).toFixed(4) + " " + symbol
|
||||
}
|
||||
StatusBaseText {
|
||||
font.pixelSize: 15
|
||||
anchors.right: parent.right
|
||||
text: getCurrencyBalanceString(totalCurrencyBalance)
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
color: itemContainer.highlighted ? Theme.palette.statusSelect.menuItemHoverBackgroundColor : Theme.palette.statusSelect.menuItemBackgroundColor
|
||||
}
|
||||
Component.onCompleted: {
|
||||
if(index === 0 ) {
|
||||
selectedAsset = { name: name, symbol: symbol, totalBalance: totalBalance, totalCurrencyBalance: totalCurrencyBalance}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
anchors.fill: itemContainer
|
||||
onClicked: {
|
||||
selectedAsset = {name: name, symbol: symbol, totalBalance: totalBalance, totalCurrencyBalance: totalCurrencyBalance}
|
||||
select.selectMenu.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import QtQuick 2.14
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
StatusRoundButton {
|
||||
icon.name: "arrow-left"
|
||||
}
|
||||
@@ -37,7 +37,7 @@ Column {
|
||||
*/
|
||||
property string statusText
|
||||
/*!
|
||||
\qmlproperty string StatusBanner::type
|
||||
\qmlproperty int StatusBanner::type
|
||||
This property holds type of banner. Possible values are:
|
||||
\qml
|
||||
enum Type {
|
||||
@@ -50,12 +50,12 @@ Column {
|
||||
*/
|
||||
property int type: StatusBanner.Type.Info
|
||||
/*!
|
||||
\qmlproperty string StatusBanner::textPixels
|
||||
\qmlproperty int StatusBanner::textPixels
|
||||
This property holds the pixels size of the text inside the banner.
|
||||
*/
|
||||
property int textPixels: 15
|
||||
/*!
|
||||
\qmlproperty string StatusBanner::statusBannerHeight
|
||||
\qmlproperty int StatusBanner::statusBannerHeight
|
||||
This property holds the height of the banner rectangle.
|
||||
*/
|
||||
property int statusBannerHeight: 38
|
||||
@@ -94,9 +94,12 @@ Column {
|
||||
StatusBaseText {
|
||||
id: statusTxt
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 8
|
||||
anchors.rightMargin: 8
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: statusBanner.textPixels
|
||||
elide: Text.ElideRight
|
||||
text: statusBanner.statusText
|
||||
color: d.fontColor
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ Rectangle {
|
||||
|
||||
enum Type {
|
||||
Normal,
|
||||
Danger
|
||||
Danger,
|
||||
Primary
|
||||
}
|
||||
|
||||
property StatusIconSettings icon: StatusIconSettings {
|
||||
@@ -80,9 +81,9 @@ Rectangle {
|
||||
|
||||
|
||||
/// Implementation
|
||||
implicitWidth: layout.width + statusBaseButton.leftPadding + statusBaseButton.rightPadding
|
||||
implicitHeight: layout.height + statusBaseButton.topPadding + statusBaseButton.bottomPadding
|
||||
|
||||
implicitWidth: sensor.width
|
||||
implicitHeight: sensor.height
|
||||
|
||||
radius: size !== StatusBaseButton.Size.Tiny ? 8 : 6
|
||||
|
||||
@@ -100,9 +101,7 @@ Rectangle {
|
||||
|
||||
MouseArea {
|
||||
id: sensor
|
||||
width: layout.width + statusBaseButton.leftPadding + statusBaseButton.rightPadding
|
||||
height: layout.height + statusBaseButton.topPadding + statusBaseButton.bottomPadding
|
||||
|
||||
anchors.fill: parent
|
||||
cursorShape: loading ? Qt.ArrowCursor
|
||||
: Qt.PointingHandCursor
|
||||
|
||||
@@ -110,8 +109,7 @@ Rectangle {
|
||||
enabled: !loading && statusBaseButton.enabled
|
||||
|
||||
Loader {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.centerIn: parent
|
||||
active: loading
|
||||
sourceComponent: StatusLoadingIndicator {
|
||||
color: d.textColor
|
||||
@@ -120,9 +118,7 @@ Rectangle {
|
||||
|
||||
Row {
|
||||
id: layout
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: statusBaseButton.leftPadding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
StatusIcon {
|
||||
id: statusIcon
|
||||
@@ -150,7 +146,7 @@ Rectangle {
|
||||
|
||||
color: d.textColor
|
||||
} // Text
|
||||
} // Ro
|
||||
} // Row
|
||||
|
||||
|
||||
onPressed: {
|
||||
@@ -177,5 +173,4 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
} // Sensor
|
||||
|
||||
}
|
||||
|
||||
@@ -174,17 +174,6 @@ Item {
|
||||
This property sets the tab key navigation item.
|
||||
*/
|
||||
property var tabNavItem: null
|
||||
|
||||
/*!
|
||||
\qmlproperty real StatusBaseInput::minimumHeight
|
||||
This property sets the minimum height.
|
||||
*/
|
||||
property real minimumHeight: 0
|
||||
/*!
|
||||
\qmlproperty alias StatusBaseInput::maximumHeight
|
||||
This property sets the maximum height.
|
||||
*/
|
||||
property real maximumHeight: 0
|
||||
/*!
|
||||
\qmlproperty int StatusBaseInput::maximumLength
|
||||
This property sets the text's maximum length.
|
||||
@@ -277,20 +266,10 @@ Item {
|
||||
*/
|
||||
signal editClicked()
|
||||
|
||||
implicitWidth: 448
|
||||
implicitHeight: multiline ? Math.min(Math.max(
|
||||
(edit.implicitHeight + topPadding + bottomPadding),
|
||||
44, root.minimumHeight), root.maximumHeight) : 44
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
width: parent.width
|
||||
height: maximumHeight != 0 ? Math.min(
|
||||
minimumHeight
|
||||
!= 0 ? Math.max(
|
||||
root.implicitHeight,
|
||||
minimumHeight) : root.implicitHeight,
|
||||
maximumHeight) : parent.height
|
||||
anchors.fill: parent
|
||||
color: root.showBackground ? Theme.palette.baseColor2
|
||||
: "transparent"
|
||||
radius: 8
|
||||
@@ -324,10 +303,10 @@ Item {
|
||||
root.editClicked()
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
spacing: 2
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: root.leftPadding
|
||||
leftMargin: root.leftPadding ? root.leftPadding : leftComponentLoader.item ? 6 : 16
|
||||
rightMargin: root.rightPadding
|
||||
}
|
||||
|
||||
@@ -346,12 +325,11 @@ Item {
|
||||
|
||||
Flickable {
|
||||
id: flick
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: !!leftComponentLoader.item ? 8 : 0
|
||||
Layout.topMargin: root.topPadding
|
||||
Layout.bottomMargin: root.bottomPadding
|
||||
|
||||
contentWidth: edit.paintedWidth
|
||||
contentHeight: edit.paintedHeight
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
@@ -374,10 +352,8 @@ Item {
|
||||
|
||||
TextEdit {
|
||||
id: edit
|
||||
|
||||
property string previousText: text
|
||||
property var keyEvent
|
||||
|
||||
width: flick.width
|
||||
height: flick.height
|
||||
verticalAlignment: TextEdit.AlignVCenter
|
||||
@@ -387,9 +363,8 @@ Item {
|
||||
focus: true
|
||||
font.pixelSize: 15
|
||||
font.family: Theme.palette.baseFont.name
|
||||
color: Theme.palette.directColor1
|
||||
color: root.enabled ? Theme.palette.directColor1 : Theme.palette.baseColor1
|
||||
wrapMode: root.multiline ? Text.WrapAtWordBoundaryOrAnywhere : TextEdit.NoWrap
|
||||
|
||||
Keys.onReturnPressed: event.accepted = !multiline && !acceptReturn
|
||||
Keys.onEnterPressed: event.accepted = !multiline && !acceptReturn
|
||||
Keys.forwardTo: [root]
|
||||
@@ -399,7 +374,6 @@ Item {
|
||||
edit.keyEvent = event.key
|
||||
root.keyPressed(event);
|
||||
}
|
||||
|
||||
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
|
||||
onActiveFocusChanged: if (root.pristine) root.pristine = false
|
||||
onTextChanged: {
|
||||
@@ -443,6 +417,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
verticalAlignment: parent.verticalAlignment
|
||||
font.pixelSize: 15
|
||||
wrapMode: root.multiline ? Text.WordWrap : Text.NoWrap
|
||||
elide: StatusBaseText.ElideRight
|
||||
font.family: Theme.palette.baseFont.name
|
||||
color: root.enabled ? Theme.palette.baseColor1 : Theme.palette.directColor6
|
||||
|
||||
@@ -5,13 +5,18 @@ import StatusQ.Core.Theme 0.1
|
||||
StatusBaseButton {
|
||||
id: statusButton
|
||||
|
||||
normalColor: type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor3
|
||||
: Theme.palette.dangerColor3
|
||||
hoverColor: type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor2
|
||||
: Theme.palette.dangerColor2
|
||||
normalColor: type === StatusBaseButton.Type.Primary ? Theme.palette.primaryColor1 :
|
||||
type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor3
|
||||
: Theme.palette.dangerColor3
|
||||
hoverColor: type === StatusBaseButton.Type.Primary ? Theme.palette.hoverColor(normalColor) :
|
||||
type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor2
|
||||
: Theme.palette.dangerColor2
|
||||
disaledColor: Theme.palette.baseColor2
|
||||
|
||||
textColor: type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor1
|
||||
: Theme.palette.dangerColor1
|
||||
textColor: type === StatusBaseButton.Type.Primary ? Theme.palette.white :
|
||||
type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor1
|
||||
: Theme.palette.dangerColor1
|
||||
disabledTextColor: Theme.palette.baseColor1
|
||||
|
||||
font.weight: type === StatusBaseButton.Type.Primary ? Font.Medium : Font.Normal
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import StatusQ.Components 0.1
|
||||
|
||||
Rectangle {
|
||||
id: statusChatInfoButton
|
||||
objectName: "chatInfoButton"
|
||||
|
||||
implicitWidth: identicon.width +
|
||||
Math.max(
|
||||
@@ -114,6 +115,7 @@ Rectangle {
|
||||
|
||||
StatusBaseText {
|
||||
id: chatName
|
||||
objectName: "statusChatInfoButtonNameText"
|
||||
|
||||
anchors.left: statusIcon.visible ? statusIcon.right : parent.left
|
||||
anchors.leftMargin: statusIcon.visible ? 1 : 0
|
||||
|
||||
@@ -32,6 +32,7 @@ CheckBox {
|
||||
|
||||
contentItem: StatusBaseText {
|
||||
text: statusCheckBox.text
|
||||
font.pixelSize: statusCheckBox.font.pixelSize
|
||||
opacity: enabled ? 1.0 : 0.3
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
@@ -8,19 +8,21 @@ RadioButton {
|
||||
|
||||
property string radioButtonColor: ""
|
||||
property string selectionColor: StatusColors.colors['white']
|
||||
property int diameter: 48
|
||||
property int selectorDiameter: 20
|
||||
|
||||
implicitWidth: 48
|
||||
implicitHeight: 48
|
||||
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 48
|
||||
implicitHeight: 48
|
||||
implicitWidth: control.diameter
|
||||
implicitHeight: control.diameter
|
||||
radius: width/2
|
||||
color: radioButtonColor
|
||||
|
||||
Rectangle {
|
||||
width: 20
|
||||
height: 20
|
||||
width: control.selectorDiameter
|
||||
height: control.selectorDiameter
|
||||
radius: width/2
|
||||
color: selectionColor
|
||||
border.color: StatusColors.colors['grey3']
|
||||
|
||||
@@ -2,36 +2,28 @@ import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string selectedColor
|
||||
property string label: "Color"
|
||||
property var model
|
||||
height: accountColorInput.height
|
||||
implicitWidth: 448
|
||||
StatusComboBox {
|
||||
id: root
|
||||
|
||||
StatusSelect {
|
||||
id: accountColorInput
|
||||
bgColor: selectedColor
|
||||
label: root.label
|
||||
model: root.model
|
||||
label: qsTr("Color")
|
||||
|
||||
selectMenu.delegate: Component {
|
||||
MenuItem {
|
||||
property bool isFirstItem: index === 0
|
||||
property bool isLastItem: index === root.model.length - 1
|
||||
height: 52
|
||||
width: parent.width
|
||||
padding: 10
|
||||
onTriggered: function () {
|
||||
const selectedColor = root.model[index]
|
||||
root.selectedColor = selectedColor
|
||||
}
|
||||
background: Rectangle {
|
||||
color: root.model[index] || "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
control.popup.horizontalPadding: 0
|
||||
|
||||
contentItem: null
|
||||
|
||||
control.background: Rectangle {
|
||||
implicitWidth: 448
|
||||
radius: 8
|
||||
color: root.control.currentValue
|
||||
}
|
||||
|
||||
delegate: StatusItemDelegate {
|
||||
width: parent.width
|
||||
background: Rectangle {
|
||||
width: parent.width
|
||||
implicitHeight: 52
|
||||
color: modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ Column {
|
||||
property alias title: title
|
||||
property alias columns: grid.columns
|
||||
|
||||
property int diameter: 48
|
||||
property int selectorDiameter: 20
|
||||
|
||||
property int selectedColorIndex: 0
|
||||
property string selectedColor: ""
|
||||
property var model:[ StatusColors.colors['black'],
|
||||
@@ -46,6 +49,10 @@ Column {
|
||||
Repeater {
|
||||
model: root.model
|
||||
delegate: StatusColorRadioButton {
|
||||
implicitWidth: root.diameter
|
||||
implicitHeight: root.diameter
|
||||
diameter: root.diameter
|
||||
selectorDiameter: root.selectorDiameter
|
||||
checked: index === selectedColorIndex
|
||||
radioButtonColor: root.model[index] || "transparent"
|
||||
onCheckedChanged: {
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Window 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
import QtQuick.Templates 2.14 as T
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property alias control: comboBox
|
||||
property alias model: comboBox.model
|
||||
property alias delegate: comboBox.delegate
|
||||
property alias contentItem: comboBox.contentItem
|
||||
|
||||
property alias currentIndex: comboBox.currentIndex
|
||||
property alias currentValue: comboBox.currentValue
|
||||
|
||||
property alias label: labelItem.text
|
||||
property alias validationError: validationErrorItem.text
|
||||
|
||||
implicitWidth: layout.implicitWidth
|
||||
implicitHeight: layout.implicitHeight
|
||||
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
StatusBaseText {
|
||||
id: labelItem
|
||||
Layout.fillWidth: true
|
||||
visible: !!text
|
||||
font.pixelSize: 15
|
||||
color: root.enabled ? Theme.palette.directColor1 : Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: comboBox
|
||||
|
||||
property color bgColor: Theme.palette.baseColor2
|
||||
property color bgColorHover: bgColor
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.topMargin: labelItem.visible ? 7 : 0
|
||||
|
||||
enabled: root.enabled
|
||||
|
||||
font.family: Theme.palette.baseFont.name
|
||||
font.pixelSize: 14
|
||||
|
||||
padding: 16
|
||||
spacing: 16
|
||||
|
||||
background: Rectangle {
|
||||
implicitHeight: 56
|
||||
implicitWidth: 448
|
||||
color: Theme.palette.baseColor2
|
||||
radius: 8
|
||||
border.width: !!root.validationError || comboBox.hovered || comboBox.down || comboBox.activeFocus ? 1 : 0
|
||||
border.color: !!root.validationError
|
||||
? Theme.palette.dangerColor1
|
||||
: comboBox.activeFocus
|
||||
? Theme.palette.primaryColor1
|
||||
: comboBox.hovered
|
||||
? Theme.palette.primaryColor2
|
||||
: "transparent"
|
||||
}
|
||||
|
||||
contentItem: StatusBaseText {
|
||||
font: comboBox.font
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
text: comboBox.displayText
|
||||
color: root.enabled ? Theme.palette.directColor1 : Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
indicator: StatusIcon {
|
||||
x: comboBox.mirrored ? comboBox.padding : comboBox.width - width - comboBox.padding
|
||||
y: comboBox.topPadding + (comboBox.availableHeight - height) / 2
|
||||
width: 24
|
||||
height: 24
|
||||
icon: "chevron-down"
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
popup: Popup {
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||
y: comboBox.height + 8
|
||||
|
||||
width: comboBox.width
|
||||
height: Math.min(implicitContentHeight + topPadding + bottomPadding,
|
||||
comboBox.Window.height - topMargin - bottomMargin)
|
||||
margins: 8
|
||||
|
||||
padding: 1
|
||||
verticalPadding: 8
|
||||
|
||||
background: Rectangle {
|
||||
id: backgroundItem
|
||||
color: Theme.palette.statusSelect.menuItemBackgroundColor
|
||||
radius: 8
|
||||
border.color: Theme.palette.baseColor2
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 4
|
||||
radius: 12
|
||||
samples: 25
|
||||
spread: 0.2
|
||||
color: Theme.palette.dropShadow
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: StatusListView {
|
||||
id: listView
|
||||
|
||||
implicitWidth: contentWidth
|
||||
implicitHeight: contentHeight
|
||||
|
||||
model: comboBox.popup.visible ? comboBox.delegateModel : null
|
||||
currentIndex: comboBox.highlightedIndex
|
||||
}
|
||||
}
|
||||
|
||||
delegate: StatusItemDelegate {
|
||||
width: comboBox.width
|
||||
highlighted: comboBox.highlightedIndex === index
|
||||
font: comboBox.font
|
||||
text: control.textRole ? (Array.isArray(control.model)
|
||||
? modelData[control.textRole]
|
||||
: model[control.textRole])
|
||||
: modelData
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StatusBaseText {
|
||||
id: validationErrorItem
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 11
|
||||
visible: !!text
|
||||
font.pixelSize: 12
|
||||
color: Theme.palette.dangerColor1
|
||||
horizontalAlignment: TextEdit.AlignRight
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,8 @@ Rectangle {
|
||||
anchors.centerIn: parent
|
||||
|
||||
StatusEmoji {
|
||||
width: 18
|
||||
height: 18
|
||||
emojiId: root.emoji != "" ? Emoji.iconHex(root.emoji) : ""
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
@@ -44,7 +46,9 @@ Rectangle {
|
||||
|
||||
StatusBaseText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 13
|
||||
font.pixelSize: 15
|
||||
font.weight: Font.DemiBold
|
||||
font.capitalization: Font.AllLowercase
|
||||
color: root.enabled ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
|
||||
text: root.name
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import QtQuick 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
import QtQuick.Controls 2.14 as QC
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusDropdown
|
||||
\inherits Popup
|
||||
\inqmlmodule StatusQ.Popups
|
||||
\since StatusQ.Popups 0.1
|
||||
\brief The StatusDropdown provides a template for creating dropdowns.
|
||||
|
||||
NOTE: Each consumer needs to set the x and y postion of the dropdown.
|
||||
|
||||
Example of how to use it:
|
||||
|
||||
\qml
|
||||
StatusDropdown {
|
||||
x: root.x + margins
|
||||
y: root.y + margins
|
||||
contentItem: ColumnLayout {
|
||||
...
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
QC.Popup {
|
||||
dim: false
|
||||
closePolicy: QC.Popup.CloseOnPressOutside | QC.Popup.CloseOnEscape
|
||||
background: Rectangle {
|
||||
id: border
|
||||
color: Theme.palette.statusPopupMenu.backgroundColor
|
||||
radius: 8
|
||||
border.color: "transparent"
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
source: border
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 4
|
||||
radius: 12
|
||||
samples: 25
|
||||
spread: 0.2
|
||||
color: Theme.palette.dropShadow
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,14 @@ import StatusQ.Popups 0.1
|
||||
Row {
|
||||
id: floatingButtons
|
||||
|
||||
/*!
|
||||
\qmlproperty repeater
|
||||
This property represents the repeater of selectable items shown to the user.
|
||||
Can be used to assign objectName to the repeater
|
||||
\endqml
|
||||
*/
|
||||
readonly property alias repeater: itemSelectionRepeater
|
||||
|
||||
/*!
|
||||
\qmlproperty delegate
|
||||
This property represents the delegate of selectable items shown to the user.
|
||||
@@ -99,6 +107,7 @@ Row {
|
||||
height: button.height
|
||||
radius: 8
|
||||
visible: floatingButtons.model.count > 3
|
||||
color: Theme.palette.statusAppLayout.backgroundColor
|
||||
StatusButton {
|
||||
id: button
|
||||
implicitHeight: 32
|
||||
@@ -106,7 +115,8 @@ Row {
|
||||
bottomPadding: 0
|
||||
defaultLeftPadding: 4
|
||||
defaultRightPadding: 4
|
||||
normalColor: "transparent"
|
||||
hoverColor: Theme.palette.statusFloatingButtonHighlight
|
||||
normalColor: Theme.palette.baseColor3
|
||||
icon.name: "more"
|
||||
icon.background.color: "transparent"
|
||||
onClicked: popupMenu.popup(parent.x, y + height + 8)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user