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 }