Warning, /maui/mauikit/src/controls.5/TabView.qml is written in an unsupported language. File is not indexed.

0001 import QtQuick 2.15
0002 import QtQml 2.14
0003 
0004 import QtQuick.Controls 2.15
0005 import QtQuick.Layouts 1.10
0006 import QtGraphicalEffects 1.15
0007 import QtQuick.Window 2.15
0008 
0009 import org.mauikit.controls 1.3 as Maui
0010 
0011 Pane
0012 {
0013     id: control
0014 
0015     default property alias content: _listView.contentData
0016     property alias contentModel: _listView.contentModel
0017     property alias currentIndex: _listView.currentIndex
0018     property alias currentItem: _listView.currentItem
0019     property alias count: _listView.count
0020 
0021     property alias holder : _holder
0022     property bool mobile : control.width <= Maui.Style.units.gridUnit * 30
0023     property bool altTabBar : false
0024     property bool interactive: Maui.Handy.isTouch
0025 
0026     readonly property bool overviewMode :  _stackView.depth === 2
0027 
0028     property alias tabBar: _tabBar
0029 
0030     property alias menu :_menu
0031 
0032     property list<Action> menuActions
0033 
0034     property Component tabViewButton :  _tabButtonComponent
0035 
0036     onWidthChanged: _tabBar.positionViewAtIndex(control.currentIndex)
0037     onCurrentIndexChanged: _tabBar.positionViewAtIndex(control.currentIndex)
0038 
0039     spacing: 0
0040     padding: 0
0041 
0042     Component
0043     {
0044         id: _tabButtonComponent
0045 
0046         Maui.TabViewButton
0047         {
0048             id: _tabButton
0049             tabView: control
0050             closeButtonVisible: !control.mobile
0051 
0052             onClicked:
0053             {
0054                 if(_tabButton.mindex === control.currentIndex && control.count > 1)
0055                 {
0056                     control.openOverview()
0057                     return
0058                 }
0059 
0060                 _listView.setCurrentIndex(_tabButton.mindex)
0061             }
0062 
0063             onRightClicked:
0064             {
0065                 openTabMenu(_tabButton.mindex)
0066             }
0067 
0068             onCloseClicked:
0069             {
0070                 control.closeTabClicked(_tabButton.mindex)
0071             }
0072         }
0073     }
0074 
0075     signal newTabClicked()
0076     signal closeTabClicked(int index)
0077 
0078     Keys.enabled: true
0079     Keys.onPressed:
0080     {
0081         if((event.key === Qt.Key_H) && (event.modifiers & Qt.ControlModifier))
0082         {
0083             control.findTab()
0084         }
0085     }
0086 
0087     Maui.ContextualMenu
0088     {
0089         id: _menu
0090         parent: control
0091         property int index //tabindex
0092 
0093         Repeater
0094         {
0095             model: control.menuActions
0096             delegate: MenuItem
0097             {
0098                 action: modelData
0099             }
0100         }
0101 
0102         MenuItem
0103         {
0104             text: i18nd("mauikit", "Open")
0105             icon.name: "tab-new"
0106             onTriggered:
0107             {
0108                 _listView.setCurrentIndex(_menu.index)
0109                 control.closeOverview()
0110             }
0111         }
0112 
0113         MenuItem
0114         {
0115             text: i18nd("mauikit", "Close")
0116             icon.name: "tab-close"
0117             onTriggered:
0118             {
0119                 control.closeTabClicked(_menu.index)
0120             }
0121         }
0122     }
0123 
0124     data: Loader
0125     {
0126         id: _loader
0127     }
0128 
0129     Component
0130     {
0131         id: _quickSearchComponent
0132 
0133         Maui.PopupPage
0134         {
0135             id: _quickSearch
0136             persistent: false
0137             headBar.visible: true
0138 
0139             onOpened: _quickSearchField.forceActiveFocus()
0140 
0141             function find(query)
0142             {
0143                 for(var i = 0; i < control.count; i ++)
0144                 {
0145                     var obj = _listView.contentModel.get(i)
0146                     if(obj.Maui.TabViewInfo.tabTitle)
0147                     {
0148                         console.log("Trying to find tab", i, query, obj.Maui.TabViewInfo.tabTitle, String(obj.Maui.TabViewInfo.tabTitle).indexOf(query))
0149 
0150                         if(String(obj.Maui.TabViewInfo.tabTitle).toLowerCase().indexOf(query.toLowerCase()) !== -1)
0151                         {
0152                             return i
0153                         }
0154                     }
0155                 }
0156 
0157                 return -1
0158             }
0159 
0160             Timer
0161             {
0162                 id: _typingTimer
0163                 interval: 250
0164                 onTriggered:
0165                 {
0166                     var index = _quickSearch.find(_quickSearchField.text)
0167                     if(index > -1)
0168                     {
0169                         _filterTabsList.currentIndex = index
0170                     }
0171                 }
0172             }
0173 
0174             headBar.middleContent: TextField
0175             {
0176                 id: _quickSearchField
0177                 Layout.fillWidth: true
0178                 Layout.maximumWidth: 500
0179 
0180                 onTextChanged: _typingTimer.restart()
0181 
0182                 onAccepted:
0183                 {
0184                     control.setCurrentIndex(_filterTabsList.currentIndex)
0185                     _quickSearch.close()
0186                 }
0187 
0188                 Keys.enabled: true
0189 
0190                 Keys.onPressed:
0191                 {
0192                     if((event.key === Qt.Key_Up))
0193                     {
0194                         _filterTabsList.flickable.decrementCurrentIndex()
0195                     }
0196 
0197                     if((event.key === Qt.Key_Down))
0198                     {
0199                         _filterTabsList.flickable.incrementCurrentIndex()
0200                     }
0201                 }
0202             }
0203 
0204             stack: Maui.ListBrowser
0205             {
0206                 id: _filterTabsList
0207                 Layout.fillWidth: true
0208                 Layout.fillHeight: true
0209                 currentIndex: _listView.currentIndex
0210 
0211                 model: _listView.count
0212 
0213                 delegate: Maui.ListDelegate
0214                 {
0215                     width: ListView.view.width
0216 
0217                     label: _listView.contentModel.get(index).Maui.TabViewInfo.tabTitle
0218 
0219                     onClicked:
0220                     {
0221                         currentIndex =index
0222                         _listView.setCurrentIndex(index)
0223                         _quickSearch.close()
0224                     }
0225                 }
0226             }
0227         }
0228     }
0229 
0230     contentItem: Item
0231     {
0232         StackView
0233         {
0234             anchors.fill: parent
0235             id: _stackView
0236 
0237             initialItem:  Item
0238             {
0239                 Maui.TabBar
0240                 {
0241                     id: _tabBar
0242 
0243                     z : _listView.z+1
0244 
0245                     anchors.left: parent.left
0246                     anchors.right: parent.right
0247 
0248                     visible: _listView.count > 1
0249 
0250                     interactive: control.interactive
0251                     showNewTabButton: !control.mobile
0252 
0253                     onNewTabClicked: control.newTabClicked()
0254                     onNewTabFocused:
0255                     {
0256                         if(control.mobile)
0257                         {
0258                             _listView.setCurrentIndex(index)
0259                         }
0260                     }
0261 
0262                     position: control.altTabBar ? TabBar.Footer : TabBar.Header
0263 
0264                     Repeater
0265                     {
0266                         model: control.count
0267                         delegate: control.tabViewButton
0268                     }
0269 
0270                     // rightContent: Button
0271                     // {
0272                     //     visible: control.mobile && control.count > 1
0273                     //     text: control.count
0274                     //     onClicked: openOverview()
0275                     // }
0276 
0277                     Keys.onPressed:
0278                     {
0279                         if(event.key == Qt.Key_Return)
0280                         {
0281                             _listView.setCurrentIndex(currentIndex)
0282                         }
0283 
0284                         if(event.key == Qt.Key_Down)
0285                         {
0286                             _listView.currentItem.forceActiveFocus()
0287                         }
0288                     }
0289 
0290                     states: [  State
0291                         {
0292                             when: !control.altTabBar && control.tabBar.visible
0293 
0294                             AnchorChanges
0295                             {
0296                                 target: _tabBar
0297                                 anchors.top: parent.top
0298                                 anchors.bottom: undefined
0299                             }
0300 
0301                             PropertyChanges
0302                             {
0303                                 target: _tabBar
0304                                 position: TabBar.Header
0305                             }
0306                         },
0307 
0308                         State
0309                         {
0310                             when: control.altTabBar && control.tabBar.visible
0311 
0312                             AnchorChanges
0313                             {
0314                                 target: _tabBar
0315                                 anchors.top: undefined
0316                                 anchors.bottom: parent.bottom
0317                             }
0318 
0319                             PropertyChanges
0320                             {
0321                                 target: _tabBar
0322                                 position: ToolBar.Footer
0323                             }
0324                         } ]
0325                 }
0326 
0327                 SwipeView
0328                 {
0329                     id: _listView
0330                     anchors.fill: parent
0331 
0332                     anchors.bottomMargin: control.altTabBar && _tabBar.visible ? _tabBar.height : 0
0333                     anchors.topMargin: !control.altTabBar && _tabBar.visible ? _tabBar.height : 0
0334 
0335                     interactive: false
0336 
0337                     spacing: control.spacing
0338 
0339                     clip: control.clip
0340 
0341                     orientation: ListView.Horizontal
0342                     background: null
0343 
0344                     contentItem: ListView
0345                     {
0346                         id: _listView2
0347                         model: _listView.contentModel
0348                         interactive: false
0349                         currentIndex: _listView.currentIndex
0350 
0351                         spacing: _listView.spacing
0352 
0353                         clip: false
0354 
0355                         orientation: ListView.Horizontal
0356                         snapMode: ListView.SnapOneItem
0357 
0358                         boundsBehavior: Flickable.StopAtBounds
0359                         boundsMovement :Flickable.StopAtBounds
0360 
0361                         preferredHighlightBegin: 0
0362                         preferredHighlightEnd: width
0363 
0364                         highlightRangeMode: ListView.StrictlyEnforceRange
0365                         highlightMoveDuration: 0
0366                         highlightFollowsCurrentItem: true
0367                         highlightResizeDuration: 0
0368                         highlightMoveVelocity: -1
0369                         highlightResizeVelocity: -1
0370 
0371                         maximumFlickVelocity: 4 * width
0372 
0373                         cacheBuffer: _listView.count * width
0374                         keyNavigationEnabled : false
0375                         keyNavigationWraps : false
0376                     }
0377                 }
0378 
0379                 Maui.Holder
0380                 {
0381                     id: _holder
0382                     anchors.fill: parent
0383                     visible: !control.count
0384                     emojiSize: Maui.Style.iconSizes.huge
0385                 }
0386             }
0387 
0388             Component
0389             {
0390                 id: _overviewComponent
0391 
0392                 Pane
0393                 {
0394                     id: _pane
0395                     Maui.Theme.colorSet: Maui.Theme.View
0396                     Maui.Theme.inherit: false
0397 
0398                     background: Rectangle
0399                     {
0400                         color: Maui.Theme.backgroundColor
0401                         Loader
0402                         {
0403                             active: !Maui.Handy.isMobile
0404                             asynchronous: true
0405                             anchors.fill: parent
0406                             sourceComponent: Item
0407                             {
0408                                 DragHandler
0409                                 {
0410                                     acceptedDevices: PointerDevice.GenericPointer
0411                                     grabPermissions:  PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
0412                                     onActiveChanged: if (active) { control.Window.window.startSystemMove(); }
0413                                 }
0414                             }
0415                         }
0416                     }
0417 
0418                     contentItem: Maui.GridBrowser
0419                     {
0420                         id: _overviewGrid
0421                         model: control.count
0422 
0423                         currentIndex: control.currentIndex
0424 
0425                         itemSize: Math.min(200, availableWidth /2)
0426 
0427                         Loader
0428                         {
0429                             asynchronous: true
0430                             anchors.bottom: parent.bottom
0431                             anchors.right: parent.right
0432                             anchors.margins: Maui.Style.space.big
0433                             sourceComponent: Maui.FloatingButton
0434                             {
0435                                 icon.name: "list-add"
0436                                 onClicked: control.newTabClicked()
0437                             }
0438                         }
0439 
0440                         onAreaClicked:
0441                         {
0442                             control.closeOverview()
0443                         }
0444 
0445                         delegate: Item
0446                         {
0447                             height: GridView.view.cellHeight
0448                             width: GridView.view.cellWidth
0449 
0450                             Maui.GridBrowserDelegate
0451                             {
0452                                 id: _delegate
0453 
0454                                 anchors.fill: parent
0455                                 anchors.margins: Maui.Style.space.medium
0456 
0457                                 isCurrentItem : parent.GridView.isCurrentItem
0458                                 label1.text: _listView.contentModel.get(index).Maui.TabViewInfo.tabTitle
0459                                 template.labelSizeHint: 32
0460                                 iconSource: "tab-new"
0461                                 flat: false
0462 
0463                                 tooltipText:  _listView.contentModel.get(index).Maui.TabViewInfo.tabToolTipText
0464 
0465                                 Rectangle
0466                                 {
0467                                     parent: _delegate.background
0468                                     color:  _listView.contentModel.get(index).Maui.TabViewInfo.tabColor
0469                                     height: 2
0470                                     width: parent.width*0.9
0471                                     anchors.bottom: parent.bottom
0472                                     anchors.horizontalCenter: parent.horizontalCenter
0473                                 }
0474 
0475                                 onRightClicked:
0476                                 {
0477                                     _listView.setCurrentIndex(index)
0478                                     openTabMenu(_listView.currentIndex)
0479                                 }
0480 
0481                                 onClicked:
0482                                 {
0483                                     control.closeOverview()
0484                                     _listView.setCurrentIndex(index)
0485                                 }
0486 
0487                                 onPressAndHold:
0488                                 {
0489                                     _listView.setCurrentIndex(index)
0490                                     openTabMenu(control.currentIndex)
0491                                 }
0492 
0493                                 template.iconComponent: Item
0494                                 {
0495                                     clip: true
0496 
0497                                     ShaderEffectSource
0498                                     {
0499                                         id: _effect
0500 
0501                                         anchors.centerIn: parent
0502 
0503                                         readonly property double m_scale: Math.min(parent.height/sourceItem.height, parent.width/sourceItem.width)
0504 
0505                                         height: sourceItem.height * m_scale
0506                                         width: sourceItem.width * m_scale
0507                                         textureSize: Qt.size(width,height)
0508 
0509                                         hideSource: false
0510                                         live: false
0511 
0512                                         smooth: true
0513 
0514                                         sourceItem: _listView.contentModel.get(index)
0515                                         layer.enabled: Maui.Style.enableEffects
0516                                         layer.smooth: true
0517                                         layer.effect: OpacityMask
0518                                         {
0519                                             maskSource: Rectangle
0520                                             {
0521                                                 width: _effect.width
0522                                                 height: _effect.height
0523                                                 radius: Maui.Style.radiusV
0524                                             }
0525                                         }
0526                                     }
0527 
0528                                     Maui.CloseButton
0529                                     {
0530                                         id: _closeButton
0531                                         visible: _delegate.isCurrentItem || _delegate.hovered || Maui.Handy.isMobile
0532                                         anchors.top: parent.top
0533                                         anchors.right: parent.right
0534                                         //                                         anchors.margins: Maui.Style.space.small
0535 
0536                                         onClicked: control.closeTabClicked(index)
0537 
0538                                         background: Rectangle
0539                                         {
0540                                             radius: height/2
0541                                             color: _closeButton.hovered || _closeButton.containsPress ? Maui.Theme.negativeBackgroundColor : Maui.Theme.backgroundColor
0542 
0543                                             Behavior on color
0544                                             {
0545                                                 Maui.ColorTransition{}
0546                                             }
0547                                         }
0548                                     }
0549                                 }
0550                             }
0551                         }
0552                     }
0553                 }
0554             }
0555         }
0556     }
0557 
0558     function closeTab(index)
0559     {
0560         _listView.removeItem(_listView.itemAt(index))
0561         // _tabBar.removeItem(_tabBar.itemAt(index))
0562 
0563         _listView.currentItemChanged()
0564         _listView.currentItem.forceActiveFocus()
0565     }
0566 
0567     function addTab(component, properties, quiet = false) : Item
0568     {
0569         if(control.overviewMode)
0570         {
0571             control.closeOverview()
0572         }
0573 
0574             const object = component.createObject(control, properties);
0575 
0576             _listView.addItem(object)
0577 
0578             if(!quiet)
0579             {
0580                 _listView.setCurrentIndex(Math.max(_listView.count -1, 0))
0581                 object.forceActiveFocus()
0582             }
0583 
0584                 return object
0585             }
0586 
0587                 function findTab()
0588                 {
0589                     if(control.count > 1)
0590                     {
0591                         _loader.sourceComponent = _quickSearchComponent
0592                         _loader.item.open()
0593                     }
0594                     }
0595 
0596                         function openOverview()
0597                         {
0598                             if(_stackView.depth === 2)
0599                             {
0600                                 return
0601                             }
0602                             _stackView.push(_overviewComponent)
0603                         }
0604 
0605                             function closeOverview()
0606                             {
0607                                 if(_stackView.depth === 1)
0608                                 {
0609                                     return
0610                                 }
0611 
0612                                 _stackView.pop()
0613                             }
0614 
0615                                 function moveTab(from, to)
0616                                 {
0617                                     _listView.moveItem(from, to)
0618                                     _tabBar.moveItem(from, to)
0619 
0620                                     _listView.setCurrentIndex(to)
0621                                     _tabBar.setCurrentIndex(_listView.currentIndex)
0622 
0623                                     _listView2.positionViewAtIndex(_listView.currentIndex, ListView.Contain)
0624 
0625                                     _listView.currentItemChanged()
0626                                     _listView.currentItem.forceActiveFocus()
0627 
0628                                 }
0629 
0630                                     function setCurrentIndex(index)
0631                                     {
0632                                         _tabBar.setCurrentIndex(index)
0633                                         _listView.setCurrentIndex(index)
0634                                         _listView.currentItem.forceActiveFocus()
0635                                     }
0636 
0637                                         function tabAt(index)
0638                                         {
0639                                             return _listView.itemAt(index)
0640                                         }
0641 
0642                                             function openTabMenu(index)
0643                                             {
0644                                                 _menu.index = index
0645                                                 _menu.show()
0646                                             }
0647                                             }