Warning, /frameworks/kirigami/src/controls/templates/OverlayDrawer.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  *  SPDX-FileCopyrightText: 2012 Marco Martin <mart@kde.org>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 import QtQuick
0008 import QtQuick.Templates as T
0009 import QtQuick.Controls as QQC2
0010 import org.kde.kirigami as Kirigami
0011 import "private" as KTP
0012 
0013 /**
0014  * Overlay Drawers are used to expose additional UI elements needed for
0015  * small secondary tasks for which the main UI elements are not needed.
0016  * For example in Okular Mobile, an Overlay Drawer is used to display
0017  * thumbnails of all pages within a document along with a search field.
0018  * This is used for the distinct task of navigating to another page.
0019  *
0020  * @inherit QtQuick.Controls.Drawer
0021  */
0022 T.Drawer {
0023     id: root
0024 
0025 //BEGIN properties
0026     /**
0027      * @brief This property tells whether the drawer is open and visible.
0028      *
0029      * default: ``false``
0030      */
0031     property bool drawerOpen: false
0032 
0033     /**
0034      * @brief This property tells whether the drawer is in a state between open
0035      * and closed.
0036      *
0037      * The drawer is visible but not completely open. This is usually the case when
0038      * the user is dragging the drawer from a screen edge, so the user is "peeking"
0039      * at what's in the drawer.
0040      *
0041      * default: ``false``
0042      */
0043     property bool peeking: false
0044 
0045     /**
0046      * @brief This property tells whether the drawer is currently opening or closing itself.
0047      */
0048     readonly property bool animating : enterAnimation.animating || exitAnimation.animating || positionResetAnim.running
0049 
0050     /**
0051      * @brief This property holds whether the drawer can be collapsed to a
0052      * very thin, usually icon only sidebar.
0053      *
0054      * Only modal drawers are collapsible. Collapsible is not supported in
0055      * the mobile mode.
0056      *
0057      * @since 2.5
0058      */
0059     property bool collapsible: false
0060 
0061     /**
0062      * @brief This property tells whether the drawer is collapsed to a
0063      * very thin sidebar, usually icon only.
0064      *
0065      * When true, the drawer will be collapsed to a very thin sidebar,
0066      * usually icon only.
0067      *
0068      * default: ``false``
0069      *
0070      * @see collapsible Only collapsible drawers can be collapsed.
0071      */
0072     property bool collapsed: false
0073 
0074     /**
0075      * @brief This property holds the size of the collapsed drawer.
0076      *
0077      * For vertical drawers this will be the width of the drawer and for horizontal
0078      * drawers this will be the height of the drawer.
0079      *
0080      * default: ``Units.iconSizes.medium``, just enough to accommodate medium sized icons
0081      */
0082     property int collapsedSize: Kirigami.Units.iconSizes.medium
0083 
0084     /**
0085      * @brief This property holds the options for handle's open icon.
0086      *
0087      * This is a grouped property with following components:
0088      *
0089      * * ``source: var``: The name of a freedesktop-compatible icon.
0090      * * ``color: color``: An optional tint color for the icon.
0091      *
0092      * If no custom icon is set, a menu icon is shown for the application globalDrawer
0093      * and an overflow menu icon is shown for the contextDrawer.
0094      * That's the default for the GlobalDrawer and ContextDrawer components respectively.
0095      *
0096      * For OverlayDrawer the default is view-right-close or view-left-close depending on
0097      * the drawer location
0098      *
0099      * @since 2.5
0100      */
0101     readonly property KTP.IconPropertiesGroup handleOpenIcon: KTP.IconPropertiesGroup {
0102         source: root.edge === Qt.RightEdge ? "view-right-close" : "view-left-close"
0103     }
0104 
0105     /**
0106      * @brief This property holds the options for the handle's close icon.
0107      *
0108      * This is a grouped property with the following components:
0109      * * ``source: var``: The name of a freedesktop-compatible icon.
0110      * * ``color: color``: An optional tint color for the icon.
0111      *
0112      * If no custom icon is set, an X icon is shown,
0113      * which will morph into the Menu or overflow icons.
0114      *
0115      * For OverlayDrawer the default is view-right-new or view-left-new depending on
0116      * the drawer location.
0117      *
0118      * @since 2.5
0119      */
0120     property KTP.IconPropertiesGroup handleClosedIcon: KTP.IconPropertiesGroup {
0121         source: root.edge === Qt.RightEdge ? "view-right-new" : "view-left-new"
0122     }
0123 
0124     /**
0125      * @brief This property holds the tooltip displayed when the drawer is open.
0126      * @since 2.15
0127      */
0128     property string handleOpenToolTip: qsTr("Close drawer")
0129 
0130     /**
0131      * @brief This property holds the tooltip displayed when the drawer is closed.
0132      * @since 2.15
0133      */
0134     property string handleClosedToolTip: qsTr("Open drawer")
0135 
0136     /**
0137      * @brief This property holds whether the handle is visible, to make opening the
0138      * drawer easier.
0139      *
0140      * Currently supported only on left and right drawers.
0141      */
0142     property bool handleVisible: {
0143         if (typeof applicationWindow === "function") {
0144             const w = applicationWindow();
0145             if (w) {
0146                 return w.controlsVisible;
0147             }
0148         }
0149         // For a generic-purpose OverlayDrawer its handle is visible by default
0150         return true;
0151     }
0152 
0153     /**
0154      * @brief Readonly property that points to the item that will act as a physical
0155      * handle for the Drawer.
0156      * @property MouseArea handle
0157      **/
0158     readonly property Item handle: KTP.DrawerHandle {
0159         drawer: root
0160     }
0161 //END properties
0162 
0163     interactive: modal
0164 
0165     z: Kirigami.OverlayZStacking.z
0166 
0167     Kirigami.Theme.inherit: false
0168     Kirigami.Theme.colorSet: modal ? Kirigami.Theme.View : Kirigami.Theme.Window
0169     Kirigami.Theme.onColorSetChanged: {
0170         contentItem.Kirigami.Theme.colorSet = Kirigami.Theme.colorSet
0171         background.Kirigami.Theme.colorSet = Kirigami.Theme.colorSet
0172     }
0173 
0174 //BEGIN reassign properties
0175     //default paddings
0176     leftPadding: Kirigami.Units.smallSpacing
0177     topPadding: Kirigami.Units.smallSpacing
0178     rightPadding: Kirigami.Units.smallSpacing
0179     bottomPadding: Kirigami.Units.smallSpacing
0180 
0181     y: modal ? 0 : ((T.ApplicationWindow.menuBar ? T.ApplicationWindow.menuBar.height : 0) + (T.ApplicationWindow.header ? T.ApplicationWindow.header.height : 0))
0182 
0183     height: parent && (root.edge === Qt.LeftEdge || root.edge === Qt.RightEdge) ? (modal ? parent.height : (parent.height - y - (T.ApplicationWindow.footer ? T.ApplicationWindow.footer.height : 0))) : implicitHeight
0184 
0185     parent: modal || edge === Qt.LeftEdge || edge === Qt.RightEdge ? T.ApplicationWindow.overlay : T.ApplicationWindow.contentItem
0186 
0187     edge: Qt.LeftEdge
0188     modal: true
0189     dim: modal
0190     QQC2.Overlay.modal: Rectangle {
0191         color: Qt.rgba(0, 0, 0, 0.35)
0192     }
0193 
0194     dragMargin: enabled && (edge === Qt.LeftEdge || edge === Qt.RightEdge) ? Math.min(Kirigami.Units.gridUnit, Qt.styleHints.startDragDistance) : 0
0195 
0196     contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
0197     contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)
0198 
0199     implicitWidth: contentWidth + leftPadding + rightPadding
0200     implicitHeight: contentHeight + topPadding + bottomPadding
0201 
0202     enter: Transition {
0203         SequentialAnimation {
0204             id: enterAnimation
0205             /* NOTE: why this? the running status of the enter transition is not relaible and
0206              * the SmoothedAnimation is always marked as non running,
0207              * so the only way to get to a reliable animating status is with this
0208              */
0209             property bool animating
0210             ScriptAction {
0211                 script: {
0212                     enterAnimation.animating = true
0213                     // on non modal dialog we don't want drawers in the overlay
0214                     if (!root.modal) {
0215                         root.background.parent.parent = applicationWindow().overlay.parent
0216                     }
0217                 }
0218             }
0219             SmoothedAnimation {
0220                 velocity: 5
0221             }
0222             ScriptAction {
0223                 script: enterAnimation.animating = false
0224             }
0225         }
0226     }
0227 
0228     exit: Transition {
0229         SequentialAnimation {
0230             id: exitAnimation
0231             property bool animating
0232             ScriptAction {
0233                 script: exitAnimation.animating = true
0234             }
0235             SmoothedAnimation {
0236                 velocity: 5
0237             }
0238             ScriptAction {
0239                 script: exitAnimation.animating = false
0240             }
0241         }
0242     }
0243 //END reassign properties
0244 
0245 
0246 //BEGIN signal handlers
0247     onCollapsedChanged: {
0248         if (Kirigami.Settings.isMobile) {
0249             collapsed = false;
0250         }
0251         if (!__internal.completed) {
0252             return;
0253         }
0254         if ((!collapsible || modal) && collapsed) {
0255             collapsed = true;
0256         }
0257     }
0258     onCollapsibleChanged: {
0259         if (Kirigami.Settings.isMobile) {
0260             collapsible = false;
0261         }
0262         if (!__internal.completed) {
0263             return;
0264         }
0265         if (!collapsible) {
0266             collapsed = false;
0267         } else if (modal) {
0268             collapsible = false;
0269         }
0270     }
0271     onModalChanged: {
0272         if (!__internal.completed) {
0273             return;
0274         }
0275         if (modal) {
0276             collapsible = false;
0277         }
0278     }
0279 
0280     onPositionChanged: {
0281         if (peeking) {
0282             visible = true
0283         }
0284     }
0285     onVisibleChanged: {
0286         if (peeking) {
0287             visible = true
0288         } else {
0289             drawerOpen = visible;
0290         }
0291     }
0292     onPeekingChanged:  {
0293         if (peeking) {
0294             root.enter.enabled = false;
0295             root.exit.enabled = false;
0296         } else {
0297             drawerOpen = position > 0.5 ? 1 : 0;
0298             positionResetAnim.running = true
0299             root.enter.enabled = true;
0300             root.exit.enabled = true;
0301         }
0302     }
0303     onDrawerOpenChanged: {
0304         // sync this property only when the component is properly loaded
0305         if (!__internal.completed) {
0306             return;
0307         }
0308         positionResetAnim.running = false;
0309         if (drawerOpen) {
0310             open();
0311         } else {
0312             close();
0313         }
0314         Qt.callLater(() => root.handle.displayToolTip = true)
0315     }
0316 
0317     Component.onCompleted: {
0318         // if defined as drawerOpen by default in QML, don't animate
0319         if (root.drawerOpen) {
0320             root.enter.enabled = false;
0321             root.visible = true;
0322             root.position = 1;
0323             root.enter.enabled = true;
0324         }
0325         __internal.completed = true;
0326         contentItem.Kirigami.Theme.colorSet = Kirigami.Theme.colorSet;
0327         background.Kirigami.Theme.colorSet = Kirigami.Theme.colorSet;
0328     }
0329 //END signal handlers
0330 
0331     // this is as hidden as it can get here
0332     property QtObject __internal: QtObject {
0333         //here in order to not be accessible from outside
0334         property bool completed: false
0335         property SequentialAnimation positionResetAnim: SequentialAnimation {
0336             id: positionResetAnim
0337             property alias to: internalAnim.to
0338             NumberAnimation {
0339                 id: internalAnim
0340                 target: root
0341                 to: drawerOpen ? 1 : 0
0342                 property: "position"
0343                 duration: (root.position)*Kirigami.Units.longDuration
0344             }
0345             ScriptAction {
0346                 script: {
0347                     root.drawerOpen = internalAnim.to !== 0;
0348                 }
0349             }
0350         }
0351         readonly property Item statesItem: Item {
0352             states: [
0353                 State {
0354                     when: root.collapsed
0355                     PropertyChanges {
0356                         target: root
0357                         implicitWidth: edge === Qt.TopEdge || edge === Qt.BottomEdge ? applicationWindow().width : Math.min(collapsedSize + leftPadding + rightPadding, Math.round(applicationWindow().width*0.8))
0358 
0359                         implicitHeight: edge === Qt.LeftEdge || edge === Qt.RightEdge ? applicationWindow().height : Math.min(collapsedSize + topPadding + bottomPadding, Math.round(applicationWindow().height*0.8))
0360                     }
0361                 },
0362                 State {
0363                     when: !root.collapsed
0364                     PropertyChanges {
0365                         target: root
0366                         implicitWidth: edge === Qt.TopEdge || edge === Qt.BottomEdge ? applicationWindow().width : Math.min(contentItem.implicitWidth, Math.round(applicationWindow().width*0.8))
0367 
0368                         implicitHeight: edge === Qt.LeftEdge || edge === Qt.RightEdge ? applicationWindow().height : Math.min(contentHeight + topPadding + bottomPadding, Math.round(applicationWindow().height*0.4))
0369 
0370                         contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
0371                         contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)
0372                     }
0373                 }
0374             ]
0375             transitions: Transition {
0376                 reversible: true
0377                 NumberAnimation {
0378                     properties: root.edge === Qt.TopEdge || root.edge === Qt.BottomEdge ? "implicitHeight" : "implicitWidth"
0379                     duration: Kirigami.Units.longDuration
0380                     easing.type: Easing.InOutQuad
0381                 }
0382             }
0383         }
0384     }
0385 }