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 }