feat(SQ/StatusImageSelector): Created new statusq component `StatusImageSelector`

Created new `StatusQ` component `StatusImageSelector`.

Closes #9629
This commit is contained in:
Noelia 2023-02-22 18:09:24 +01:00 committed by Noelia
parent 3441c2e182
commit aecb4816e0
5 changed files with 226 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -34,6 +34,7 @@
\li \l{StatusIconTextButton} \li \l{StatusIconTextButton}
\li \l{StatusIdenticonRing} \li \l{StatusIdenticonRing}
\li \l{StatusInput} \li \l{StatusInput}
\li \l{StatusImageSelector}
\li \l{StatusItemPicker} \li \l{StatusItemPicker}
\li \l{StatusPickerButton} \li \l{StatusPickerButton}
\li \l{StatusPinInput} \li \l{StatusPinInput}

View File

@ -0,0 +1,220 @@
import QtQuick 2.3
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.14
import QtQuick.Dialogs 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
/*!
\qmltype StatusImageSelector
\inherits Control
\inqmlmodule StatusQ.Controls
\since StatusQ.Components 0.1
\brief The It StatusImageSelector control provides a generic user image selector input
Example of how the component looks like:
\image status_image_selector.png
Example of how to use it:
\qml
StatusImageSelector {
Layout.preferredHeight: 500
Layout.preferredWidth: 500
labelText: qsTr("Artwork")
uploadText: qsTr("Drag and Drop or Upload Artwork")
additionalText: qsTr("Images only")
onFileSelected: d.artworkSource = file
}
\endqml
For a list of components available see StatusQ.
*/
Control {
id: root
/*!
\qmlproperty alias StatusImageSelector::labelText.
This property holds the label text for the file input.
*/
property alias labelText: label.text
/*!
\qmlproperty alias StatusImageSelector::uploadText.
This property holds the main image upload text value.
*/
property alias uploadText: uploadText.text
/*!
\qmlproperty alias StatusImageSelector::additionalText.
This property holds an additional text value.
*/
property alias additionalText: additionalText.text
/*!
\qmlproperty var StatusImageSelector::acceptedImageExtensions.
This property holds the list of possible image file extensions.
*/
property var acceptedImageExtensions: [".png", ".jpg", ".jpeg", ".heif", ".tif", ".tiff"]
/*!
\qmlproperty var StatusImageSelector::headerHeight.
This property holds the header height value including label heigh + spacing between label and image rectangle.
*/
readonly property int headerHeight: label.implicitHeight + rootImageSelector.spacing
/*!
\qmlproperty var StatusImageSelector::buttonsInsideOffset.
This property holds the plus button inside offset value.
*/
readonly property int buttonsInsideOffset: 10
/*!
\qmlsignal StatusImageSelector::fileSelected(url file)
This signal is emitted when a new file is selected.
*/
signal fileSelected(url file)
QtObject {
id: d
readonly property int imageSelectorPadding: 75
function loadFile(fileUrls) {
if (fileUrls.length > 0) {
// The first file is the one kept:
if(d.isValidFile(fileUrls[0])) {
image.source = fileUrls[0]
uploadTextPanel.visible = false
root.fileSelected(fileUrls[0])
}
}
}
function isValidFile(file) {
return root.acceptedImageExtensions.some(ext => file.toLowerCase().includes(ext))
}
function getExtensionsFilterText() {
var res = ""
for(var i = 0; i < root.acceptedImageExtensions.length; i++)
res += " *" + root.acceptedImageExtensions[i]
return res
}
}
contentItem: ColumnLayout {
id: rootImageSelector
spacing: 16
StatusBaseText {
id: label
elide: Text.ElideRight
font.pixelSize: Theme.primaryTextFontSize
}
Rectangle {
id: imageSelector
Layout.fillWidth: true
Layout.fillHeight: true
radius: 8
color: Theme.palette.baseColor2
states: [
State {
when: dropArea.containsDrag
PropertyChanges {target: imageSelector; border.color: Theme.palette.primaryColor1 }
},
State {
when: !dropArea.containsDrag
PropertyChanges {target: imageSelector; border.color: Theme.palette.baseColor2 }
}
]
DropArea {
id: dropArea
anchors.fill: parent
onDropped: d.loadFile(drop.urls)
}
StatusRoundButton {
id: addButton
z: 1
icon.name: "add"
type: StatusRoundButton.Type.Secondary
anchors {
top: parent.top
topMargin: - root.buttonsInsideOffset
right: parent.right
rightMargin: - root.buttonsInsideOffset
}
onClicked: fileDialog.open()
}
ColumnLayout {
id: uploadTextPanel
width: parent.width
anchors.centerIn: parent
StatusIcon {
icon: "images_icon"
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Layout.preferredWidth: 20
Layout.preferredHeight: 18
color: Theme.palette.baseColor1
fillMode: Image.PreserveAspectFit
}
StatusBaseText {
id: uploadText
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Layout.topMargin: 5
Layout.preferredWidth: parent.width - 2 * d.imageSelectorPadding
font.pixelSize: Theme.primaryTextFontSize
color: Theme.palette.baseColor1
wrapMode: Text.WordWrap
lineHeight: 1.2
horizontalAlignment: Text.AlignHCenter
}
StatusBaseText {
id: additionalText
visible: !!root.additionalText
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Layout.preferredWidth: parent.width - 2 * d.imageSelectorPadding
font.pixelSize: Theme.secondaryTextFontSize
color: Theme.palette.baseColor1
wrapMode: Text.WordWrap
lineHeight: 1.2
horizontalAlignment: Text.AlignHCenter
}
}
Image {
id: image
anchors.fill: parent
fillMode: Image.PreserveAspectFit
}
}
}
FileDialog {
id: fileDialog
folder: shortcuts.pictures
nameFilters: [ qsTr("Supported image formats (%1)").arg(d.getExtensionsFilterText())]
onAccepted: d.loadFile(fileUrls)
}
}

View File

@ -55,3 +55,4 @@ StatusBackButton 0.1 StatusBackButton.qml
StatusPasswordInput 0.1 StatusPasswordInput.qml StatusPasswordInput 0.1 StatusPasswordInput.qml
StatusTextWithLoadingState 0.1 StatusTextWithLoadingState.qml StatusTextWithLoadingState 0.1 StatusTextWithLoadingState.qml
StatusLinkText 0.1 StatusLinkText.qml StatusLinkText 0.1 StatusLinkText.qml
StatusImageSelector 0.1 StatusImageSelector.qml

View File

@ -0,0 +1,4 @@
<svg width="20" height="18" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.5 6.5C16.5 8.15685 15.1569 9.5 13.5 9.5C11.8431 9.5 10.5 8.15685 10.5 6.5C10.5 4.84315 11.8431 3.5 13.5 3.5C15.1569 3.5 16.5 4.84315 16.5 6.5ZM15 6.5C15 7.32843 14.3284 8 13.5 8C12.6716 8 12 7.32843 12 6.5C12 5.67157 12.6716 5 13.5 5C14.3284 5 15 5.67157 15 6.5Z" fill="#939BA1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 0C1.79086 0 0 1.79086 0 4V14C0 16.2091 1.79086 18 4 18H16C18.2091 18 20 16.2091 20 14V4C20 1.79086 18.2091 0 16 0H4ZM16 1.5H4C2.61929 1.5 1.5 2.61929 1.5 4V7.23223C1.5 7.67768 2.03857 7.90077 2.35355 7.58579L3.76256 6.17678C4.44598 5.49336 5.55402 5.49336 6.23744 6.17678L16.3181 16.2575C16.4372 16.3765 16.6094 16.4311 16.7695 16.3793C17.7737 16.0548 18.5 15.1122 18.5 14V4C18.5 2.61929 17.3807 1.5 16 1.5ZM1.53033 10.5303C1.51153 10.5491 1.5 10.5742 1.5 10.6008V14C1.5 15.3807 2.61929 16.5 4 16.5H13.2322C13.6777 16.5 13.9008 15.9614 13.5858 15.6464L5.17678 7.23744C5.07914 7.1398 4.92085 7.13981 4.82322 7.23744L1.53033 10.5303Z" fill="#939BA1"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB