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