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

0001 /*
0002  *   Copyright 2020 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 QtQml
0022 import QtQuick.Controls
0023 import QtQuick.Layouts
0024 
0025 import org.mauikit.controls 1.3 as Maui
0026 
0027 import "private" as Private
0028 
0029 /**
0030  * 
0031  * @since org.mauikit.controls 1.2
0032  * 
0033  * @brief Views switcher component.
0034  * 
0035  * This controls inherits from MauiKit Page, to checkout its inherited properties refer to docs.
0036  * 
0037  * The AppViews control presents a set of children items as views - into an horizontal swipe view, that does not jump around when resizing the application window and that takes care of different gestures and keyboard shortcuts for switching/navigating between the views.
0038  * 
0039  * This component takes care of creating the button view-ports in its page header.
0040  * 
0041  * Each child element represents a view - and each one should have the AppView attached properties to give a title and icon to the view - so that it can be used as the text and icon  for the view-port buttons. Some of the supported attached properties to be used are:
0042  * - AppView.title
0043  * - AppView.iconName
0044  * - AppView.badgeText
0045  * 
0046  * The badge item is handled by a MauiKit Badge control.
0047  * @see Badge
0048  * 
0049  * @see AppView
0050  * 
0051  * @image html AppViews/viewports.png "The view ports as buttons in the header - the title is expanded for the current view on a wide mode, but compacted in a narrow space"
0052  * 
0053  * @code
0054  * AppViews
0055  * {
0056  *    id: _page
0057  *    anchors.fill: parent
0058  *    Controls.showCSD: true
0059  *    headBar.forceCenterMiddleContent: true
0060  * 
0061  *    Rectangle
0062  *    {
0063  *        AppView.title: "View1"
0064  *        AppView.iconName: "love"
0065  * 
0066  *        color: "blue"
0067  *    }
0068  * 
0069  *    Rectangle
0070  *    {
0071  *        AppView.title: "View2"
0072  *        AppView.iconName: "folder"
0073  *        AppView.badgeText: "30"
0074  *        color: "pink"
0075  *    }
0076  * 
0077  *    Rectangle
0078  *    {
0079  *        AppView.title: "View3"
0080  *        AppView.iconName: "tag"
0081  * 
0082  *        color: "blue"
0083  *    }
0084  * }
0085  * @endcode
0086  * 
0087  * @section notes Notes 
0088  * 
0089  * @subsection positioning Positioning & Behaviours
0090  * There is not need to set the size or position of the child elements aka "views" - this component will take care of positioning them in the order they have been declared.
0091  * 
0092  * If a child-item or a "view" is hidden via the visible property, then it is also hidden for the view port buttons.
0093  * 
0094  * By default this component is not interactive with touch gestures, in order to not steal focus from other horizontal flickable elements - however you can enable it manually.
0095  * @see interactive
0096  * 
0097  * @subsection performance Performance
0098  * Ideally do not add too many views, that are loaded simultaneously, since it will affect the application startup time. Instead you can load the views dinamically by using a Loader or the friend control AppViewLoader, which will take care of much of the loading task.
0099  * @see AppViewLoader
0100  * 
0101  * Besides taking longer to load - too many views - will also make the header bar too busy with the view-port buttons. This can also be tweaked by setting the maximum number of views visible - the other ones will be tucked away into an overflow menu.
0102  * @see maxViews
0103  * 
0104  * @subsection inheritance Inheritance & Shortcuts
0105  * This component inherits for the MauiKit Page control, so you can customize it by using the same properties that can be applied to a Page, such as moving the header to the bottom, adding extra toolbars, enabling the pull-back behaviours, etc.
0106  * @see Page
0107  * 
0108  * The first four [4] views can be navigated by using keyboard shortcuts: [Ctrl + 1] [Ctrl + 2] [Ctrl + 3] [Ctrl + 4]
0109  * 
0110  * <a href="https://invent.kde.org/maui/mauikit/-/blob/qt6-2/examples/AppViews.qml">You can find a more complete example at this link.</a> 
0111  * @inherit org::mauikit::controls::Page
0112  */
0113 Maui.Page
0114 {
0115     id: control
0116     
0117     /**
0118      * @brief All the child items declared will become part of the views. For each child element to be visible in the view port buttons, you need to use the AppView attached properties.
0119      * @see AppView
0120      * The content layout is handled by a swipe view.
0121      */
0122     default property alias content: _swipeView.contentData
0123         
0124         /**
0125          * @brief The index number of the current view.
0126          * @property int AppViews::currentIndex
0127          */
0128         property alias currentIndex : _swipeView.currentIndex
0129         
0130         /**
0131          * @brief The current item in the view.
0132          * @property Item AppViews::currentItem
0133          */
0134         property alias currentItem : _swipeView.currentItem
0135         
0136         /**
0137          * @brief The total amount of items/views. 
0138          * @property int AppViews::count
0139          */
0140         property alias count : _swipeView.count
0141         
0142         /**
0143          * @brief Sets the views to be interactive by using touch gestures to flick between them.
0144          * @property bool AppViews::interactive
0145          */
0146         property alias interactive : _swipeView.interactive
0147         
0148         focus: true
0149         
0150         /**
0151          * @brief Maximum number of views to be shown in the view port buttons at the header bar.
0152          * The rest of views buttons will be collapsed into a menu button.
0153          * By default the maximum number is set to 4.
0154          */
0155         property int maxViews : 4
0156         
0157         headBar.forceCenterMiddleContent: !isWide
0158         headBar.middleContent: Loader
0159         {
0160             asynchronous: true
0161             Layout.alignment: Qt.AlignCenter
0162             
0163             sourceComponent: Private.ActionGroup
0164             {
0165                 id: _actionGroup
0166                 currentIndex : _swipeView.currentIndex
0167                 display: ToolButton.TextUnderIcon
0168                 Binding on currentIndex 
0169                 {
0170                     value: _swipeView.currentIndex
0171                     restoreMode: Binding.RestoreValue
0172                 }
0173                 
0174                 onCurrentIndexChanged:
0175                 {
0176                     _swipeView.currentIndex = currentIndex
0177                     //                _actionGroup.currentIndex = control.currentIndex
0178                 }
0179                 
0180                 Component.onCompleted:
0181                 {
0182                     for(var i in _swipeView.contentChildren)
0183                     {
0184                         const obj = _swipeView.contentChildren[i]
0185                         
0186                         if(obj.Maui.AppView.title || obj.Maui.AppView.iconName)
0187                         {
0188                             if(_actionGroup.items.length < control.maxViews)
0189                             {
0190                                 _actionGroup.items.push(obj)
0191                             }else
0192                             {
0193                                 _actionGroup.hiddenItems.push(obj)
0194                             }
0195                         }
0196                     }
0197                 }
0198             }
0199         }
0200         
0201         SwipeView
0202         {
0203             id:_swipeView   
0204             anchors.fill: parent
0205             interactive: false
0206             
0207             onCurrentItemChanged:
0208             {
0209                 currentItem.forceActiveFocus()
0210                 _listView.positionViewAtIndex(control.currentIndex , ListView.SnapPosition)
0211                 history.push(_swipeView.currentIndex)
0212             }
0213             
0214             Keys.onBackPressed:
0215             {
0216                 control.goBack()
0217             }
0218             
0219             Shortcut
0220             {
0221                 sequence: StandardKey.Back
0222                 onActivated: control.goBack()
0223             }
0224             
0225             background: null
0226             padding: 0
0227             
0228             contentItem: ListView
0229             {
0230                 id: _listView
0231                 model: _swipeView.contentModel
0232                 interactive: _swipeView.interactive
0233                 currentIndex: _swipeView.currentIndex
0234                 spacing: _swipeView.spacing
0235                 orientation: _swipeView.orientation
0236                 snapMode: ListView.SnapOneItem
0237                 boundsBehavior: Flickable.StopAtBounds
0238                 clip: _swipeView.clip
0239                 
0240                 preferredHighlightBegin: 0
0241                 preferredHighlightEnd: width
0242                 
0243                 highlightRangeMode: ListView.StrictlyEnforceRange
0244                 highlightMoveDuration: 0
0245                 highlightFollowsCurrentItem: true
0246                 highlightResizeDuration: 0
0247                 highlightMoveVelocity: -1
0248                 highlightResizeVelocity: -1
0249                 
0250                 maximumFlickVelocity: 4 * (_swipeView.orientation === Qt.Horizontal ? width : height)
0251                 
0252                 property int lastPos: 0
0253                 
0254                 onCurrentIndexChanged:
0255                 {
0256                     _listView.lastPos = _listView.contentX
0257                 }            
0258             }
0259             
0260             Keys.enabled: true
0261             //     Keys.forwardTo:_listView
0262             Keys.onPressed:
0263             {
0264                 if((event.key == Qt.Key_1) && (event.modifiers & Qt.ControlModifier))
0265                 {
0266                     if(_swipeView.count > -1 )
0267                     {
0268                         _swipeView.currentIndex = 0
0269                     }
0270                 }
0271                 
0272                 if((event.key == Qt.Key_2) && (event.modifiers & Qt.ControlModifier))
0273                 {
0274                     if(_swipeView.count > 0 )
0275                     {
0276                         _swipeView.currentIndex = 1
0277                     }
0278                 }
0279                 
0280                 if((event.key == Qt.Key_3) && (event.modifiers & Qt.ControlModifier))
0281                 {
0282                     if(_swipeView.count > 1 )
0283                     {
0284                         _swipeView.currentIndex = 2
0285                     }
0286                 }
0287                 
0288                 if((event.key == Qt.Key_4) && (event.modifiers & Qt.ControlModifier))
0289                 {
0290                     if(_swipeView.count > 2 )
0291                     {
0292                         _swipeView.currentIndex = 3
0293                     }
0294                 }
0295             }        
0296         }
0297         
0298         /**
0299          * @brief The private object that handles the history workflow
0300          * @warning This is a private property and can not be accesed
0301          */
0302         property QtObject history : QtObject
0303         {
0304             property var historyIndexes : []
0305             
0306             function pop()
0307             {
0308                 historyIndexes.pop()
0309                 return historyIndexes.pop()
0310             }
0311             
0312             function push(index)
0313             {
0314                 historyIndexes.push(index)
0315             }
0316             
0317             function indexes()
0318             {
0319                 return historyIndexes
0320             }
0321         }
0322         
0323         /**
0324          * @brief A quick function to request the control to go back to the previously visited view.
0325          * A history of visited views is kept, and invoking this method will pop the history one by one .
0326          */
0327         function goBack()
0328         {
0329             _swipeView.setCurrentIndex(history.pop())
0330         }
0331         
0332 }