Warning, /maui/mauikit/src/controls.6/ListBrowser.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 * Copyright 2018 Camilo Higuita <milo.h@aol.com>
0003 *
0004 * This program is free software; you can redistribute it and/or modify
0005 * it under the terms of the GNU Library General Public License as
0006 * published by the Free Software Foundation; either version 2, or
0007 * (at your option) any later version.
0008 *
0009 * This program is distributed in the hope that it will be useful,
0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0012 * GNU General Public License for more details
0013 *
0014 * You should have received a copy of the GNU Library General Public
0015 * License along with this program; if not, write to the
0016 * Free Software Foundation, Inc.,
0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0018 */
0019
0020 import QtQuick
0021 import QtQuick.Controls
0022
0023 import org.mauikit.controls 1.3 as Maui
0024
0025 /**
0026 * @inherit QtQuick.Item
0027 * @brief A browser view with a list layout.
0028 * <a href="https://doc.qt.io/qt-6/qml-qtquick-controls-item.html">This controls inherits from QQC2 Item, to checkout its inherited properties refer to the Qt Docs.</a>
0029 *
0030 * This component might seem similar to QQC2 ListView - and it does uses it underneath - but this one includes a few more predefined elements, such as a placeholder element, pinch to zoom gestures, lasso selection support, and some predefined behaviour.
0031 *
0032 * @section structure Structure
0033 * The browser has a dedicated placeholder element handled by MauiKit Holder, where a message can be set when the view is on a determined state the user should be warned about, such as if the view is empty, or not search results were found.
0034 * @see Holder
0035 *
0036 * The lasso selection feature works with a mouse or a track-pad, and allows to select multiple items in the browser-view that are under the lasso rectangle area. A signal is emitted when the selection has been triggered - this is when the lasso rectangle is released - sending as an argument an array of numbers representing the indexes of the selected items.
0037 * @see itemsSelected
0038 *
0039 * @note Consider using as the delegate elements the MauiKit ListBrowserDelegate.
0040 *
0041 * To position the delegates you can use the ListView attached properties, such as `ListView.view.width` to set the width of the delegate correctly.
0042 *
0043 * @image html Browsers/listbrowser.png
0044 *
0045 * @code
0046 * Maui.ListBrowser
0047 * {
0048 * anchors.fill: parent
0049 * model: 60
0050 *
0051 * enableLassoSelection: true
0052 * onItemsSelected: (indexes) => console.log(indexes)
0053 *
0054 * delegate: Maui.ListBrowserDelegate
0055 * {
0056 * width: ListView.view.width
0057 * label1.text: "An example delegate."
0058 * label2.text: "Using the MauiKit ListBrowser."
0059 *
0060 * iconSource: "folder"
0061 * }
0062 * }
0063 * @endcode
0064 *
0065 * <a href="https://invent.kde.org/maui/mauikit/-/blob/qt6-2/examples/ListBrowser.qml">You can find a more complete example at this link.</a>
0066 */
0067 Item
0068 {
0069 id: control
0070 focus: true
0071 clip: false
0072
0073 implicitHeight: contentHeight + topPadding + bottomPadding
0074 implicitWidth: contentWidth + leftPadding + rightPadding
0075
0076 /**
0077 * @brief The model to be used to populate the browsing view.
0078 * @property var ListBrowser::model
0079 */
0080 property alias model : _listView.model
0081
0082 /**
0083 * @brief The component to be used as the delegate.
0084 * @note Consider using the MauiKit delegate controls, such as ListBrowserDelegate, ListDelegate or LabelDelegate.
0085 * @property Component ListBrowser::delegate
0086 */
0087 property alias delegate : _listView.delegate
0088
0089 /**
0090 * @brief The section group property to set the ListView sections.
0091 * Refer to the Qt documentation on the ListView section.
0092 * @property section ListBrowser::section
0093 */
0094 property alias section : _listView.section
0095
0096 /**
0097 * @brief The position of the view contents on the Y axis.
0098 * @property double ListBrowser::contentY
0099 */
0100 property alias contentY: _listView.contentY
0101
0102 /**
0103 * @brief The position of the view contents on the X axis.
0104 * @property double ListBrowser::contentY
0105 */
0106 property alias contentX: _listView.contentX
0107
0108 /**
0109 * @brief The index number of the current element selected.
0110 * @note To no break any binding, use the `setCurrentIndex` function.
0111 * @property int ListBrowser::currentIndex
0112 */
0113 property alias currentIndex : _listView.currentIndex
0114
0115 /**
0116 * @brief The current item selected.
0117 * @property Item ListBrowser::currentItem
0118 */
0119 property alias currentItem : _listView.currentItem
0120
0121 /**
0122 * @brief The total amount of elements listed in the view.
0123 * @property int ListBrowser::count
0124 */
0125 property alias count : _listView.count
0126
0127 /**
0128 * @brief The cache buffer.
0129 * Refer to the QQC2 ListView for proper documentation.
0130 * @property int ListBrowser::cacheBuffer
0131 */
0132 property alias cacheBuffer : _listView.cacheBuffer
0133
0134 /**
0135 * @brief The orientation of the list view.
0136 * By default this is set to `ListView.Vertical`.
0137 * @property enum ListBrowser::orientation
0138 */
0139 property alias orientation: _listView.orientation
0140
0141 /**
0142 * @brief How to snap the elements of the list view while scrolling.
0143 * @note See Qt documentation.
0144 * @property enum ListBrowser::snapMode
0145 */
0146 property alias snapMode: _listView.snapMode
0147
0148 /**
0149 * @brief The spacing between the elements in the list view.
0150 * By default this is set to `Style.defaultSpacing`
0151 * @property int ListBrowser::spacing
0152 */
0153 property alias spacing: _listView.spacing
0154
0155 /**
0156 * @brief An alias to access the QQC2 ListView.
0157 * @property ListView ListBrowser::flickable
0158 */
0159 readonly property alias flickable : _listView
0160
0161 /**
0162 * @brief An alias to access the QQC2 ScrollView.
0163 * @property ScrollView ListBrowser::scrollView
0164 */
0165 readonly property alias scrollView : _scrollView
0166
0167 /**
0168 * @brief The total height of all the elements listed in the view.
0169 * @property int ListBrowser::contentHeight
0170 */
0171 property alias contentHeight : _listView.contentHeight
0172
0173 /**
0174 * @brief The total width of all the elements.
0175 * @property int ListBrowser::contentWidth
0176 */
0177 property alias contentWidth : _listView.contentWidth
0178
0179 /**
0180 * @brief Whether the view is positioned at the end on the Y axis.
0181 * Meant to be used if the view `orientation` has been set to vertical.
0182 * @property bool ListBrowser::atYEnd
0183 */
0184 readonly property alias atYEnd : _listView.atYEnd
0185
0186 /**
0187 * @brief Whether the view is positioned at the beginning on the Y axis.
0188 * Meant to be used if the view `orientation` has been set to vertical.
0189 * @property bool ListBrowser::atYBeginning
0190 */
0191 readonly property alias atYBeginning : _listView.atYBeginning
0192
0193 /**
0194 * @brief The top padding.
0195 * @see padding
0196 * @property int ListBrowser::topPadding
0197 */
0198 property alias topPadding: _scrollView.topPadding
0199
0200 /**
0201 * @brief The bottom padding.
0202 * @see padding
0203 * @property int ListBrowser::bottomPadding
0204 */
0205 property alias bottomPadding: _scrollView.bottomPadding
0206
0207 /**
0208 * @brief The right padding.
0209 * @see padding
0210 * @property int ListBrowser::rightPadding
0211 */
0212 property alias rightPadding: _scrollView.rightPadding
0213
0214 /**
0215 * @brief The left padding.
0216 * @see padding
0217 * @property int ListBrowser::leftPadding
0218 */
0219 property alias leftPadding: _scrollView.leftPadding
0220
0221 /**
0222 * @brief The total padding all around the list view. The padding is added to the ScrollView.
0223 * This is the same as setting `scrollView.padding`.
0224 * @property int ListBrowser::padding
0225 */
0226 property alias padding: _scrollView.padding
0227
0228 /**
0229 * @brief The policy of the vertical scroll bar from the scroll view.
0230 * @see scrollView
0231 * The default value of this is picked based on the Style property `Style.scrollBarPolicy`, unless the orientation of the view is set to horizontal, in which case this is set to 'ScrollBar.AlwaysOff`.
0232 * Possible values are:
0233 * - ScrollBar.AlwaysOff
0234 * - ScrollBar.AlwaysOn
0235 * - ScrollBar.AsNeeded
0236 */
0237 property int verticalScrollBarPolicy:
0238 {
0239 if(control.orientation === ListView.Horizontal)
0240 return ScrollBar.AlwaysOff
0241
0242 switch(Maui.Style.scrollBarPolicy)
0243 {
0244 case Maui.Style.AlwaysOn: return ScrollBar.AlwaysOn;
0245 case Maui.Style.AlwaysOff: return ScrollBar.AlwaysOff;
0246 case Maui.Style.AsNeeded: return ScrollBar.AsNeeded;
0247 case Maui.Style.AutoHide: return ScrollBar.AsNeeded;
0248 }
0249 }
0250
0251 /**
0252 * @brief The policy of the horizontal scroll bar from the scroll view.
0253 * @see scrollView
0254 * The default value of this is picked based on the Style property `Style.scrollBarPolicy`, unless the orientation of the view is set to vertical, in which case this is set to 'ScrollBar.AlwaysOff`.
0255 * Possible values are:
0256 * - ScrollBar.AlwaysOff
0257 * - ScrollBar.AlwaysOn
0258 * - ScrollBar.AsNeeded
0259 */
0260 property int horizontalScrollBarPolicy:
0261 {
0262 if(control.orientation === ListView.Vertical)
0263 return ScrollBar.AlwaysOff
0264
0265 switch(Maui.Style.scrollBarPolicy)
0266 {
0267 case Maui.Style.AlwaysOn: return ScrollBar.AlwaysOn;
0268 case Maui.Style.AlwaysOff: return ScrollBar.AlwaysOff;
0269 case Maui.Style.AsNeeded: return ScrollBar.AsNeeded;
0270 case Maui.Style.AutoHide: return ScrollBar.AsNeeded;
0271 }
0272 }
0273
0274 /**
0275 * @brief An alias to access the placeholder properties. This is handled by a MauiKit Holder.
0276 * @see Holder::title
0277 * @see Holder::body
0278 *
0279 * @property Holder ListBrowser::holder
0280 */
0281 property alias holder : _holder
0282
0283 /**
0284 * @brief Whether to enable the lasso selection, to select multiple items.
0285 * By default this is set to `false`.
0286 * @see itemsSelected
0287 */
0288 property bool enableLassoSelection : false
0289
0290 /**
0291 * @brief
0292 */
0293 property bool selectionMode: false
0294
0295 /**
0296 * @brief An alias to the lasso rectangle.
0297 * @property Rectangle ListBrowser::lassoRec
0298 */
0299 readonly property alias lassoRec : selectLayer
0300
0301 /**
0302 * @brief The header section of the ListView element.
0303 * @see flickable
0304 * @property Component ListBrowser::header
0305 */
0306 property alias header : _listView.header
0307
0308 /**
0309 * @brief The footer section of the ListView element
0310 * @see flickable
0311 * @property Component ListBrowser::footer
0312 */
0313 property alias footer : _listView.footer
0314
0315 /**
0316 * @brief The actual width of the view-port. This is the actual width without any padding.
0317 * @property int ListBrowser::availableWidth
0318 */
0319 readonly property alias availableWidth: _listView.width
0320
0321 /**
0322 * @brief The actual height of the view-port. This is the actual height without any padding.
0323 * @property int ListBrowser::availableHeight
0324 */
0325 readonly property alias availableHeight: _listView.height
0326
0327 /**
0328 * @brief Emitted when the lasso selection has been released.
0329 * @param indexes A array of index numbers is sent as the argument, representing the index value of the items under the lasso rectangle area.
0330 */
0331 signal itemsSelected(var indexes)
0332
0333 /**
0334 * @brief Emitted when an empty space of the background area has been clicked.
0335 * @param mouse Object with information about the click event.
0336 */
0337 signal areaClicked(var mouse)
0338
0339 /**
0340 * @brief Emitted when an empty space of the area area background has been right clicked.
0341 */
0342 signal areaRightClicked()
0343
0344 /**
0345 * @brief Emitted when a physical key from the device has been pressed.
0346 * @param event The object with information about the event.
0347 */
0348 signal keyPress(var event)
0349
0350 Keys.enabled : true
0351 Keys.forwardTo : _listView
0352
0353 ScrollView
0354 {
0355 id: _scrollView
0356 anchors.fill: parent
0357 clip: control.clip
0358 focus: true
0359 padding: Maui.Style.contentMargins
0360 orientation: _listView.orientation
0361
0362 ScrollBar.horizontal.policy: control.horizontalScrollBarPolicy
0363 ScrollBar.vertical.policy: control.verticalScrollBarPolicy
0364
0365 contentHeight: _listView.contentHeight
0366 contentWidth: availableWidth
0367
0368 ListView
0369 {
0370 id: _listView
0371 focus: true
0372 clip: control.clip
0373
0374 property var selectedIndexes : []
0375
0376
0377 spacing: Maui.Style.defaultSpacing
0378
0379 snapMode: ListView.NoSnap
0380
0381 displayMarginBeginning: Maui.Style.toolBarHeight * 4
0382 displayMarginEnd: Maui.Style.toolBarHeight * 4
0383
0384 boundsBehavior: Flickable.StopAtBounds
0385 boundsMovement: Flickable.StopAtBounds
0386
0387 // interactive: Maui.Handy.isTouch
0388 interactive: false
0389 highlightFollowsCurrentItem: true
0390 highlightMoveDuration: 0
0391 highlightResizeDuration : 0
0392
0393 keyNavigationEnabled : true
0394 keyNavigationWraps : true
0395 Keys.onPressed: (event) => control.keyPress(event)
0396
0397 Maui.Holder
0398 {
0399 id: _holder
0400 visible: false
0401 anchors.fill : parent
0402
0403 anchors.topMargin: _listView.headerItem ? _listView.headerItem.height : 0
0404 anchors.bottomMargin: _listView.footerItem ? _listView.footerItem.height : 0
0405 }
0406
0407 Item
0408 {
0409 anchors.fill: parent
0410 z: parent.z-1
0411 clip: false
0412
0413 Loader
0414 {
0415 asynchronous: true
0416 anchors.fill: parent
0417 // active: !Maui.Handy.hasTransientTouchInput && !Maui.Handy.isMobile
0418
0419 sourceComponent: MouseArea
0420 {
0421 id: _mouseArea
0422
0423 propagateComposedEvents: true
0424 preventStealing: true
0425 acceptedButtons: Qt.RightButton | Qt.LeftButton
0426
0427 onClicked: (mouse) =>
0428 {
0429 console.log("Area clicked")
0430
0431 control.areaClicked(mouse)
0432 control.forceActiveFocus()
0433
0434 if(mouse.button === Qt.RightButton)
0435 {
0436 control.areaRightClicked()
0437 return
0438 }
0439 }
0440
0441 onPositionChanged: (mouse) =>
0442 {
0443 if(_mouseArea.pressed && control.enableLassoSelection && selectLayer.visible)
0444 {
0445 if(mouseX >= selectLayer.newX)
0446 {
0447 selectLayer.width = (mouseX + 10) < (control.x + control.width) ? (mouseX - selectLayer.x) : selectLayer.width;
0448 } else {
0449 selectLayer.x = mouseX < control.x ? control.x : mouseX;
0450 selectLayer.width = selectLayer.newX - selectLayer.x;
0451 }
0452
0453 if(mouseY >= selectLayer.newY) {
0454 selectLayer.height = (mouseY + 10) < (control.y + control.height) ? (mouseY - selectLayer.y) : selectLayer.height;
0455 if(!_listView.atYEnd && mouseY > (control.y + control.height))
0456 _listView.contentY += 10
0457 } else {
0458 selectLayer.y = mouseY < control.y ? control.y : mouseY;
0459 selectLayer.height = selectLayer.newY - selectLayer.y;
0460
0461 if(!_listView.atYBeginning && selectLayer.y === 0)
0462 _listView.contentY -= 10
0463 }
0464 }
0465 }
0466
0467 onPressed: (mouse) =>
0468 {
0469 if (mouse.source === Qt.MouseEventNotSynthesized && control.enableLassoSelection && mouse.button === Qt.LeftButton && control.count > 0)
0470 {
0471 selectLayer.visible = true;
0472 selectLayer.x = mouseX;
0473 selectLayer.y = mouseY;
0474 selectLayer.newX = mouseX;
0475 selectLayer.newY = mouseY;
0476 selectLayer.width = 0
0477 selectLayer.height = 0;
0478 }
0479 }
0480
0481 onPressAndHold: (mouse) =>
0482 {
0483 if ( mouse.source !== Qt.MouseEventNotSynthesized && control.enableLassoSelection && !selectLayer.visible && !Maui.Handy.hasTransientTouchInput && !Maui.Handy.isAndroid)
0484 {
0485 selectLayer.visible = true;
0486 selectLayer.x = mouseX;
0487 selectLayer.y = mouseY;
0488 selectLayer.newX = mouseX;
0489 selectLayer.newY = mouseY;
0490 selectLayer.width = 0
0491 selectLayer.height = 0;
0492 mouse.accepted = true
0493 }else
0494 {
0495 mouse.accepted = false
0496 }
0497 }
0498
0499 onReleased: (mouse) =>
0500 {
0501 if(mouse.button !== Qt.LeftButton || !control.enableLassoSelection || !selectLayer.visible)
0502 {
0503 mouse.accepted = false
0504 return;
0505 }
0506
0507 if(selectLayer.y > _listView.contentHeight)
0508 {
0509 return selectLayer.reset();
0510 }
0511
0512 var lassoIndexes = []
0513 var limitY = mouse.y === lassoRec.y ? lassoRec.y+lassoRec.height : mouse.y
0514 var y = lassoRec.y
0515 for(y; y < limitY; y+=10)
0516 {
0517 const index = _listView.indexAt(_listView.width/2,y+_listView.contentY)
0518 if(!lassoIndexes.includes(index) && index>-1 && index< _listView.count)
0519 lassoIndexes.push(index)
0520 }
0521
0522 control.itemsSelected(lassoIndexes)
0523 console.log("INDEXES << " , lassoIndexes, lassoRec.y, limitY)
0524 selectLayer.reset()
0525 }
0526 }
0527 }
0528 }
0529
0530 Maui.Rectangle
0531 {
0532 id: selectLayer
0533 property int newX: 0
0534 property int newY: 0
0535 height: 0
0536 width: 0
0537 x: 0
0538 y: 0
0539 visible: false
0540 color: Qt.rgba(control.Maui.Theme.highlightColor.r,control.Maui.Theme.highlightColor.g, control.Maui.Theme.highlightColor.b, 0.2)
0541 opacity: 0.7
0542
0543 borderColor: control.Maui.Theme.highlightColor
0544 borderWidth: 2
0545 solidBorder: false
0546
0547 function reset()
0548 {
0549 selectLayer.x = 0;
0550 selectLayer.y = 0;
0551 selectLayer.newX = 0;
0552 selectLayer.newY = 0;
0553 selectLayer.visible = false;
0554 selectLayer.width = 0;
0555 selectLayer.height = 0;
0556 }
0557 }
0558 }
0559 }
0560 }
0561
0562