Warning, /maui/mauikit/src/controls.5/GridBrowser.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 2.15 0021 import QtQuick.Controls 2.15 0022 0023 import org.mauikit.controls 1.3 as Maui 0024 0025 /** 0026 * GridBrowser 0027 * A global sidebar for the application window that can be collapsed. 0028 * 0029 * 0030 * 0031 * 0032 * 0033 * 0034 */ 0035 Item 0036 { 0037 id: control 0038 focus: true 0039 clip: false 0040 0041 implicitHeight: contentHeight + topPadding + bottomPadding 0042 implicitWidth: contentWidth + leftPadding + rightPadding 0043 0044 /** 0045 * itemSize : int 0046 */ 0047 property alias itemSize: controlView.itemSize 0048 0049 /** 0050 * itemWidth : int 0051 */ 0052 property alias itemWidth : controlView.itemWidth 0053 0054 /** 0055 * itemHeight : int 0056 */ 0057 property alias itemHeight : controlView.itemHeight 0058 0059 /** 0060 * cellWidth : int 0061 */ 0062 property alias cellWidth: controlView.cellWidth 0063 0064 /** 0065 * cellHeight : int 0066 */ 0067 property alias cellHeight: controlView.cellHeight 0068 0069 /** 0070 * model : var 0071 */ 0072 property alias model : controlView.model 0073 0074 /** 0075 * delegate : Component 0076 */ 0077 property alias delegate : controlView.delegate 0078 0079 /** 0080 * contentY : int 0081 */ 0082 property alias contentY: controlView.contentY 0083 0084 /** 0085 * currentIndex : int 0086 */ 0087 property alias currentIndex : controlView.currentIndex 0088 0089 /** 0090 * count : int 0091 */ 0092 property alias count : controlView.count 0093 0094 /** 0095 * cacheBuffer : int 0096 */ 0097 property alias cacheBuffer : controlView.cacheBuffer 0098 0099 /** 0100 * flickable : Flickable 0101 */ 0102 property alias flickable : controlView 0103 0104 /** 0105 * contentHeight : int 0106 */ 0107 property alias contentHeight : controlView.contentHeight 0108 0109 /** 0110 * contentWidth : int 0111 */ 0112 property alias contentWidth : controlView.contentWidth 0113 0114 property alias scrollView: _scrollView 0115 0116 /** 0117 * topPadding : int 0118 */ 0119 property alias topPadding: _scrollView.topPadding 0120 0121 /** 0122 * bottomPadding : int 0123 */ 0124 property alias bottomPadding: _scrollView.bottomPadding 0125 0126 /** 0127 * rightPadding : int 0128 */ 0129 property alias rightPadding: _scrollView.rightPadding 0130 0131 /** 0132 * leftPadding : int 0133 */ 0134 property alias leftPadding: _scrollView.leftPadding 0135 0136 /** 0137 * padding : int 0138 */ 0139 property alias padding: _scrollView.padding 0140 0141 property int verticalScrollBarPolicy: 0142 { 0143 if(control.orientation === ListView.Horizontal) 0144 return ScrollBar.AlwaysOff 0145 0146 switch(Maui.Style.scrollBarPolicy) 0147 { 0148 case Maui.Style.AlwaysOn: return ScrollBar.AlwaysOn; 0149 case Maui.Style.AlwaysOff: return ScrollBar.AlwaysOff; 0150 case Maui.Style.AsNeeded: return ScrollBar.AsNeeded; 0151 case Maui.Style.AutoHide: return ScrollBar.AsNeeded; 0152 } 0153 } 0154 0155 /** 0156 * horizontalScrollBarPolicy : ScrollBar.policy 0157 */ 0158 property int horizontalScrollBarPolicy: 0159 { 0160 if(control.orientation === ListView.Vertical) 0161 return ScrollBar.AlwaysOff 0162 0163 switch(Maui.Style.scrollBarPolicy) 0164 { 0165 case Maui.Style.AlwaysOn: return ScrollBar.AlwaysOn; 0166 case Maui.Style.AlwaysOff: return ScrollBar.AlwaysOff; 0167 case Maui.Style.AsNeeded: return ScrollBar.AsNeeded; 0168 case Maui.Style.AutoHide: return ScrollBar.AsNeeded; 0169 } 0170 } 0171 0172 /** 0173 * holder : Holder 0174 */ 0175 property alias holder : _holder 0176 0177 /** 0178 * adaptContent : bool 0179 */ 0180 property bool adaptContent: true 0181 0182 /** 0183 * enableLassoSelection : bool 0184 */ 0185 property bool enableLassoSelection : false 0186 0187 /** 0188 * selectionMode : bool 0189 */ 0190 property bool selectionMode: false 0191 0192 /** 0193 * lassoRec : Rectangle 0194 */ 0195 property alias lassoRec : selectLayer 0196 0197 /** 0198 * pinchEnabled : bool 0199 */ 0200 property bool pinchEnabled : false 0201 0202 property alias currentItem : controlView.currentItem 0203 0204 property alias header : controlView.header 0205 property alias footer : controlView.footer 0206 0207 property alias availableWidth: controlView.width 0208 0209 property alias availableHeight: controlView.height 0210 0211 property alias moving: updateContentDelay.running 0212 0213 /** 0214 * itemsSelected : 0215 */ 0216 signal itemsSelected(var indexes) 0217 0218 /** 0219 * areaClicked : 0220 */ 0221 signal areaClicked(var mouse) 0222 0223 /** 0224 * areaRightClicked : 0225 */ 0226 signal areaRightClicked() 0227 0228 /** 0229 * keyPress : 0230 */ 0231 signal keyPress(var event) 0232 0233 Keys.enabled : true 0234 Keys.forwardTo : controlView 0235 0236 onItemSizeChanged : 0237 { 0238 controlView.size_ = itemSize 0239 control.itemWidth = itemSize 0240 control.cellWidth = itemWidth 0241 if(adaptContent) 0242 control.adaptGrid() 0243 } 0244 0245 ScrollView 0246 { 0247 id: _scrollView 0248 anchors.fill: parent 0249 focus: true 0250 padding: Maui.Style.contentMargins 0251 0252 clip: control.clip 0253 0254 ScrollBar.horizontal.policy: control.horizontalScrollBarPolicy 0255 ScrollBar.vertical.policy: control.verticalScrollBarPolicy 0256 0257 GridView 0258 { 0259 id: controlView 0260 focus: true 0261 0262 /** 0263 * itemSize : int 0264 */ 0265 property int itemSize: 0 0266 0267 /** 0268 * itemWidth : int 0269 */ 0270 property int itemWidth : itemSize 0271 0272 /** 0273 * itemHeight : int 0274 */ 0275 property int itemHeight : itemSize 0276 0277 0278 property bool firstSelectionPress 0279 property var selectedIndexes : [] 0280 0281 //nasty trick 0282 property int size_ 0283 Component.onCompleted: 0284 { 0285 controlView.size_ = control.itemWidth 0286 } 0287 0288 flow: GridView.FlowLeftToRight 0289 clip: control.clip 0290 0291 displayMarginBeginning: Maui.Style.effectsEnabled ? Maui.Style.toolBarHeight * 4 : 0 0292 displayMarginEnd: displayMarginBeginning 0293 cacheBuffer: control.itemHeight * 4 0294 cellWidth: control.itemWidth 0295 cellHeight: control.itemHeight 0296 0297 boundsBehavior: Flickable.StopAtBounds 0298 0299 flickableDirection: Flickable.AutoFlickDirection 0300 snapMode: GridView.NoSnap 0301 highlightMoveDuration: 0 0302 interactive: Maui.Handy.isTouch 0303 onWidthChanged: if(adaptContent) control.adaptGrid() 0304 onCountChanged: if(adaptContent) control.adaptGrid() 0305 0306 keyNavigationEnabled : true 0307 keyNavigationWraps : true 0308 Keys.onPressed: control.keyPress(event) 0309 0310 Maui.Holder 0311 { 0312 id: _holder 0313 visible: false 0314 anchors.fill : parent 0315 anchors.topMargin: controlView.headerItem ? controlView.headerItem.height : 0 0316 anchors.bottomMargin: controlView.footerItem ? controlView.footerItem.height : 0 0317 } 0318 0319 onContentXChanged: 0320 { 0321 updateContentDelay.restart() 0322 } 0323 0324 onContentYChanged: 0325 { 0326 updateContentDelay.restart() 0327 } 0328 0329 Timer 0330 { 0331 id: updateContentDelay 0332 interval: 500 0333 repeat: false 0334 } 0335 0336 Loader 0337 { 0338 asynchronous: true 0339 active: control.pinchEnabled 0340 0341 anchors.fill: parent 0342 z: -1 0343 0344 sourceComponent: PinchArea 0345 { 0346 onPinchFinished: 0347 { 0348 resizeContent(pinch.scale) 0349 } 0350 } 0351 } 0352 0353 Loader 0354 { 0355 asynchronous: true 0356 z: -1 0357 active: !Maui.Handy.hasTransientTouchInput && !Maui.Handy.isMobile 0358 anchors.fill: parent 0359 0360 sourceComponent: MouseArea 0361 { 0362 id: _mouseArea 0363 0364 propagateComposedEvents: true 0365 // preventStealing: true 0366 acceptedButtons: Qt.RightButton | Qt.LeftButton 0367 0368 onClicked: 0369 { 0370 control.areaClicked(mouse) 0371 control.forceActiveFocus() 0372 0373 if(mouse.button === Qt.RightButton) 0374 { 0375 control.areaRightClicked() 0376 return 0377 } 0378 } 0379 0380 onWheel: 0381 { 0382 if (wheel.modifiers & Qt.ControlModifier) 0383 { 0384 if (wheel.angleDelta.y != 0) 0385 { 0386 var factor = 1 + wheel.angleDelta.y / 600; 0387 control.resizeContent(factor) 0388 } 0389 }else 0390 wheel.accepted = false 0391 } 0392 0393 onPositionChanged: 0394 { 0395 if(_mouseArea.pressed && control.enableLassoSelection && selectLayer.visible) 0396 { 0397 if(mouseX >= selectLayer.newX) 0398 { 0399 selectLayer.width = (mouseX + 10) < (control.x + control.width) ? (mouseX - selectLayer.x) : selectLayer.width; 0400 } else { 0401 selectLayer.x = mouseX < control.x ? control.x : mouseX; 0402 selectLayer.width = selectLayer.newX - selectLayer.x; 0403 } 0404 0405 if(mouseY >= selectLayer.newY) { 0406 selectLayer.height = (mouseY + 10) < (control.y + control.height) ? (mouseY - selectLayer.y) : selectLayer.height; 0407 if(!controlView.atYEnd && mouseY > (control.y + control.height)) 0408 controlView.contentY += 10 0409 } else { 0410 selectLayer.y = mouseY < control.y ? control.y : mouseY; 0411 selectLayer.height = selectLayer.newY - selectLayer.y; 0412 0413 if(!controlView.atYBeginning && selectLayer.y === 0) 0414 controlView.contentY -= 10 0415 } 0416 } 0417 } 0418 0419 onPressed: 0420 { 0421 if (mouse.source === Qt.MouseEventNotSynthesized) 0422 { 0423 if(control.enableLassoSelection && mouse.button === Qt.LeftButton && control.count > 0) 0424 { 0425 selectLayer.visible = true; 0426 selectLayer.x = mouseX; 0427 selectLayer.y = mouseY; 0428 selectLayer.newX = mouseX; 0429 selectLayer.newY = mouseY; 0430 selectLayer.width = 0 0431 selectLayer.height = 0; 0432 } 0433 } 0434 } 0435 0436 onPressAndHold: 0437 { 0438 if ( mouse.source !== Qt.MouseEventNotSynthesized && control.enableLassoSelection && !selectLayer.visible ) 0439 { 0440 selectLayer.visible = true; 0441 selectLayer.x = mouseX; 0442 selectLayer.y = mouseY; 0443 selectLayer.newX = mouseX; 0444 selectLayer.newY = mouseY; 0445 selectLayer.width = 0 0446 selectLayer.height = 0; 0447 0448 mouse.accepted = true 0449 }else 0450 { 0451 mouse.accepted = false 0452 } 0453 } 0454 0455 onReleased: 0456 { 0457 if(mouse.button !== Qt.LeftButton || !control.enableLassoSelection || !selectLayer.visible) 0458 { 0459 mouse.accepted = false 0460 return; 0461 } 0462 0463 if(selectLayer.y > controlView.contentHeight) 0464 { 0465 return selectLayer.reset(); 0466 } 0467 0468 var lassoIndexes = [] 0469 const limitX = mouse.x === lassoRec.x ? lassoRec.x+lassoRec.width : mouse.x 0470 const limitY = mouse.y === lassoRec.y ? lassoRec.y+lassoRec.height : mouse.y 0471 0472 for(var i =lassoRec.x; i < limitX; i+=(lassoRec.width/(controlView.cellWidth* 0.5))) 0473 { 0474 for(var y = lassoRec.y; y < limitY; y+=(lassoRec.height/(controlView.cellHeight * 0.5))) 0475 { 0476 const index = controlView.indexAt(i,y+controlView.contentY) 0477 if(!lassoIndexes.includes(index) && index>-1 && index< controlView.count) 0478 lassoIndexes.push(index) 0479 } 0480 } 0481 0482 if(lassoIndexes.length > 0) 0483 { 0484 control.itemsSelected(lassoIndexes) 0485 } 0486 0487 selectLayer.reset() 0488 } 0489 } 0490 } 0491 0492 Maui.Rectangle 0493 { 0494 id: selectLayer 0495 property int newX: 0 0496 property int newY: 0 0497 height: 0 0498 width: 0 0499 x: 0 0500 y: 0 0501 visible: false 0502 color: Qt.rgba(control.Maui.Theme.highlightColor.r,control.Maui.Theme.highlightColor.g, control.Maui.Theme.highlightColor.b, 0.2) 0503 opacity: 0.7 0504 0505 borderColor: control.Maui.Theme.highlightColor 0506 borderWidth: 2 0507 solidBorder: false 0508 0509 function reset() 0510 { 0511 selectLayer.x = 0; 0512 selectLayer.y = 0; 0513 selectLayer.newX = 0; 0514 selectLayer.newY = 0; 0515 selectLayer.visible = false; 0516 selectLayer.width = 0; 0517 selectLayer.height = 0; 0518 } 0519 } 0520 } 0521 } 0522 0523 /** 0524 * 0525 */ 0526 function resizeContent(factor) 0527 { 0528 const newSize= control.itemSize * factor 0529 0530 if(newSize > control.itemSize) 0531 { 0532 control.itemSize = newSize 0533 } 0534 else 0535 { 0536 if(newSize >= Maui.Style.iconSizes.small) 0537 control.itemSize = newSize 0538 } 0539 } 0540 0541 /** 0542 * 0543 */ 0544 function adaptGrid() 0545 { 0546 var fullWidth = controlView.width 0547 var realAmount = parseInt(fullWidth / controlView.size_, 0) 0548 var amount = parseInt(fullWidth / control.cellWidth, 0) 0549 0550 var leftSpace = parseInt(fullWidth - ( realAmount * controlView.size_ ), 0) 0551 var size = Math.min(amount, realAmount) >= control.count ? Math.max(control.cellWidth, control.itemSize) : parseInt((controlView.size_) + (parseInt(leftSpace/realAmount, 0)), 0) 0552 0553 control.cellWidth = size 0554 } 0555 }