• Skip to content
  • Skip to link menu
Brand

API Documentation

  1. KDE API Reference
  2. Kirigami
  • KDE Home
  • Contact Us

Quick Links

Skip menu "Kirigami"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • File List
  • Related Pages

Class Picker

About

QtQuick plugins to build user interfaces based on the KDE UX guidelines

Maintainer
Marco Martin
Supported platforms
Android, Linux
Community
IRC: #plasma on Freenode
Mailing list: plasma-devel
Use with CMake
find_package(KF5Kirigami)
target_link_libraries(yourapp KF5::Kirigami)
Clone
git clone git://anongit.kde.org/kirigami1.git
Browse source
Kirigami on cgit.kde.org

Kirigami

  • src
  • controls
  • templates
controls/templates/OverlayDrawer.qml
1 /*
2  * Copyright 2012 Marco Martin <mart@kde.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Library General Public License as
6  * published by the Free Software Foundation; either version 2, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Library General Public License for more details
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 import QtQuick 2.1
21 import org.kde.kirigami 1.0
22 import "private"
23 
32 AbstractDrawer {
33  id: root
34 
35  z: modal ? (opened ? 100 : 99 ): 98
36 
37 //BEGIN Properties
43  default property alias page: mainPage.data
44 
49  property Item contentItem
50 
56  property Item background
57 
63  property alias opened: mainFlickable.open
64 
75  property int edge: Qt.LeftEdge
76 
83  property real position: 0
84 
90  property bool handleVisible: typeof(applicationWindow)===typeof(Function) && applicationWindow() ? applicationWindow().controlsVisible : true
91 
96  property int leftPadding: Units.smallSpacing
97 
102  property int topPadding: Units.smallSpacing
103 
108  property int rightPadding: Units.smallSpacing
109 
114  property int bottomPadding: Units.smallSpacing
115 
126  //property bool modal: true
127 //END Properties
128 
129 
130 //BEGIN Methods
136  function open () {
137  mainAnim.to = 0;
138  switch (root.edge) {
139  case Qt.RightEdge:
140  mainAnim.to = drawerPage.width;
141  break;
142  case Qt.BottomEdge:
143  mainAnim.to = drawerPage.height;
144  break;
145  case Qt.LeftEdge:
146  case Qt.TopEdge:
147  default:
148  mainAnim.to = 0;
149  break;
150  }
151  mainAnim.running = true;
152  mainFlickable.open = true;
153  }
154 
160  function close () {
161  switch (root.edge) {
162  case Qt.RightEdge:
163  case Qt.BottomEdge:
164  mainAnim.to = 0;
165  break;
166  case Qt.LeftEdge:
167  mainAnim.to = drawerPage.width;
168  break;
169  case Qt.TopEdge:
170  mainAnim.to = drawerPage.height;
171  break;
172  }
173  mainAnim.running = true;
174  mainFlickable.open = false;
175  }
176 
181 //END Methods
182 
183 //BEGIN Signal handlers
184  onBackgroundChanged: {
185  background.z = 1;
186  background.parent = mainItem;
187  background.anchors.fill = drawerPage;
188  }
189 
190  onPositionChanged: {
191  if (!mainFlickable.loopCheck) {
192  mainFlickable.loopCheck = true;
193  if (!mainFlickable.flicking && !mainFlickable.dragging && !mainAnim.running) {
194  switch (root.edge) {
195  case Qt.RightEdge:
196  mainFlickable.contentX = drawerPage.width * position;
197  break;
198  case Qt.LeftEdge:
199  mainFlickable.contentX = drawerPage.width * (1-position);
200  break;
201  case Qt.BottomEdge:
202  mainFlickable.contentY = drawerPage.height * position;
203  break;
204  }
205  }
206  mainFlickable.loopCheck = false;
207  }
208  }
209  onContentItemChanged: {
210  contentItem.parent = drawerPage
211  contentItem.anchors.fill = drawerPage
212  if (contentItem.flickableItem !== undefined) {
213  contentItem.anchors.topMargin = 0;
214  contentItem.anchors.leftMargin = 0;
215  contentItem.anchors.bottomMargin = 0;
216  contentItem.anchors.rightMargin = 0;
217  } else {
218  contentItem.anchors.topMargin = root.topPadding;
219  contentItem.anchors.leftMargin = root.leftPadding;
220  contentItem.anchors.bottomMargin = root.bottomPadding;
221  contentItem.anchors.rightMargin = root.rightPadding;
222  }
223  }
224 //END Signal handlers
225 
226  Item {
227  id: mainPage
228  anchors.fill: parent
229  onChildrenChanged: mainPage.children[0].anchors.fill = mainPage
230  }
231 
232  Rectangle {
233  anchors.fill: parent
234  color: "black"
235  opacity: 0.6 * mainFlickable.internalPosition
236  visible: root.modal
237  }
238 
239 
240  //NOTE: it's a PropertyAnimation instead of a NumberAnimation because
241  //NumberAnimation doesn't have NOTIFY signal on to property
242  PropertyAnimation {
243  id: mainAnim
244  target: mainFlickable
245  properties: (root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) ? "contentX" : "contentY"
246  duration: Units.longDuration
247  easing.type: mainAnim.to > 0 ? Easing.InQuad : Easing.OutQuad
248  }
249 
250  MouseArea {
251  id: edgeMouse
252  anchors {
253  right: root.edge == Qt.LeftEdge ? undefined : parent.right
254  left: root.edge == Qt.RightEdge ? undefined : parent.left
255  top: root.edge == Qt.BottomEdge ? undefined : parent.top
256  bottom: root.edge == Qt.TopEdge ? undefined : parent.bottom
257  }
258  z: 99
259  width: Units.smallSpacing * 3
260  height: Units.smallSpacing * 3
261  property int startMouseX
262  property real oldMouseX
263  property int startMouseY
264  property real oldMouseY
265  property bool startDragging: false
266 
267  function managePress(mouse) {
268  if (drawerPage.children.length == 0) {
269  mouse.accepted = false;
270  return;
271  }
272 
273  speedSampler.restart();
274  mouse.accepted = true;
275  oldMouseX = startMouseX = mouse.x;
276  oldMouseY = startMouseY = mouse.y;
277  startDragging = false;
278  }
279  onPressed: {
280  managePress(mouse)
281  }
282 
283  onPositionChanged: {
284  if (!root.contentItem) {
285  mouse.accepted = false;
286  return;
287  }
288 
289  if (Math.abs(mouse.x - startMouseX) > root.width / 5 ||
290  Math.abs(mouse.y - startMouseY) > root.height / 5) {
291  startDragging = true;
292  }
293  if (startDragging) {
294  switch (root.edge) {
295  case Qt.RightEdge:
296  mainFlickable.contentX = Math.min(mainItem.width - root.width, mainFlickable.contentX + oldMouseX - mouse.x);
297  break;
298  case Qt.LeftEdge:
299  mainFlickable.contentX = Math.max(0, mainFlickable.contentX + oldMouseX - mouse.x);
300  break;
301  case Qt.BottomEdge:
302  mainFlickable.contentY = Math.min(mainItem.height - root.height, mainFlickable.contentY + oldMouseY - mouse.y);
303  break;
304  case Qt.TopEdge:
305  mainFlickable.contentY = Math.max(0, mainFlickable.contentY + oldMouseY - mouse.y);
306  break;
307  }
308  }
309  oldMouseX = mouse.x;
310  oldMouseY = mouse.y;
311  }
312  onReleased: {
313  if (!startDragging) {
314  return;
315  }
316  speedSampler.running = false;
317  if (speedSampler.speed != 0) {
318  if (root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) {
319  mainFlickable.flick(speedSampler.speed, 0);
320  } else {
321  mainFlickable.flick(0, speedSampler.speed);
322  }
323  } else {
324  if (mainFlickable.internalPosition > 0.5) {
325  root.open();
326  } else {
327  root.close();
328  }
329  }
330  }
331  }
332 
333  MouseArea {
334  id: handleMouseArea
335  z:999
336  anchors {
337  right: root.edge == Qt.LeftEdge ? undefined : parent.right
338  left: root.edge == Qt.RightEdge ? undefined : parent.left
339  bottom: parent.bottom
340  leftMargin: root.opened ? drawerPage.width : 0
341  rightMargin: root.opened ? drawerPage.width : 0
342  }
343  visible: root.handleVisible && (root.edge == Qt.LeftEdge || root.edge == Qt.RightEdge)
344  width: Units.iconSizes.medium
345  height: width
346  onPressed: edgeMouse.managePress(mouse);
347  onPositionChanged: edgeMouse.positionChanged(mouse);
348  onReleased: edgeMouse.released(mouse);
349  onClicked: root.opened ? root.close() : root.open();
350  }
351 
352  Timer {
353  id: speedSampler
354  interval: 100
355  repeat: true
356  property real speed
357  property real oldContentX
358  property real oldContentY
359  onTriggered: {
360  if (root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) {
361  speed = (mainFlickable.contentX - oldContentX) * 10;
362  oldContentX = mainFlickable.contentX;
363  } else {
364  speed = (mainFlickable.contentY - oldContentY) * 10;
365  oldContentY = mainFlickable.contentY;
366  }
367  }
368  onRunningChanged: {
369  if (running) {
370  speed = 0;
371  oldContentX = mainFlickable.contentX;
372  oldContentY = mainFlickable.contentY;
373  } else {
374  if (root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) {
375  speed = (oldContentX - mainFlickable.contentX) * 10;
376  } else {
377  speed = (oldContentY - mainFlickable.contentY) * 10;
378  }
379  }
380  }
381  }
382 
383  MouseArea {
384  id: mainMouseArea
385  anchors.fill: parent
386  drag.filterChildren: true
387  onClicked: {
388  if ((root.edge == Qt.LeftEdge && mouse.x < drawerPage.width) ||
389  (root.edge == Qt.RightEdge && mouse.x > drawerPage.x - mainFlickable.contentX) ||
390  (root.edge == Qt.TopEdge && mouse.y < drawerPage.height) ||
391  (root.edge == Qt.BottomEdge && mouse.y > drawerPage.y - mainFlickable.contentY)) {
392  return;
393  }
394  root.clicked();
395  root.close();
396  }
397  enabled: (root.edge == Qt.LeftEdge && !mainFlickable.atXEnd) ||
398  (root.edge == Qt.RightEdge && !mainFlickable.atXBeginning) ||
399  (root.edge == Qt.TopEdge && !mainFlickable.atYEnd) ||
400  (root.edge == Qt.BottomEdge && !mainFlickable.atYBeginning) ||
401  mainFlickable.moving
402 
403  Flickable {
404  id: mainFlickable
405  property bool open
406  anchors.fill: parent
407  interactive: root.modal
408  onOpenChanged: {
409  if (open) {
410  root.open();
411  Qt.inputMethod.hide();
412  } else {
413  root.close();
414  }
415  }
416  enabled: parent.enabled
417  flickableDirection: root.edge == Qt.LeftEdge || root.edge == Qt.RightEdge ? Flickable.HorizontalFlick : Flickable.VerticalFlick
418  contentWidth: mainItem.width
419  contentHeight: mainItem.height
420  boundsBehavior: Flickable.StopAtBounds
421  readonly property real internalPosition: {
422  switch (root.edge) {
423  case Qt.RightEdge:
424  return mainFlickable.contentX/drawerPage.width;
425  case Qt.LeftEdge:
426  return 1 - (mainFlickable.contentX/drawerPage.width);
427  case Qt.BottomEdge:
428  return mainFlickable.contentY/drawerPage.height;
429  case Qt.TopEdge:
430  return 1 - (mainFlickable.contentY/drawerPage.height);
431  }
432  }
433  property bool loopCheck: false
434  onInternalPositionChanged: {
435  if (!loopCheck) {
436  loopCheck = true;
437  root.position = internalPosition;
438  loopCheck = false;
439  }
440  }
441 
442  onFlickingChanged: {
443  if (!flicking) {
444  if (internalPosition > 0.5) {
445  root.open();
446  } else {
447  root.close();
448  }
449  }
450  }
451  onMovingChanged: {
452  if (!moving) {
453  flickingChanged();
454  }
455  }
456 
457  Item {
458  id: mainItem
459  width: root.width + ((root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) ? drawerPage.width : 0)
460  height: root.height + ((root.edge == Qt.TopEdge || root.edge == Qt.BottomEdge) ? drawerPage.height : 0)
461  onWidthChanged: {
462  if (root.edge == Qt.LeftEdge) {
463  if (root.opened) {
464  mainFlickable.contentX = 0;
465  } else {
466  mainFlickable.contentX = drawerPage.width;
467  }
468  }
469  }
470  onHeightChanged: {
471  if (root.edge == Qt.TopEdge) {
472  mainFlickable.contentY = drawerPage.Height;
473  }
474  }
475 
476 
477  Item {
478  id: drawerPage
479  z: 3
480  anchors {
481  left: root.edge != Qt.RightEdge ? parent.left : undefined
482  right: root.edge != Qt.LeftEdge ? parent.right : undefined
483  top: root.edge != Qt.BottomEdge ? parent.top : undefined
484  bottom: root.edge != Qt.TopEdge ? parent.bottom : undefined
485  }
486 
487  clip: true
488  width: root.contentItem ? Math.min(root.contentItem.implicitWidth, root.width * 0.7) : 0
489  height: root.contentItem ? Math.min(root.contentItem.implicitHeight, root.height * 0.7) : 0
490  }
491  }
492  }
493  }
494 }
org::kde::kirigami::Units::smallSpacing
int smallSpacing
units.smallSpacing is the amount of spacing that should be used around smaller UI elements...
Definition: controls/Units.qml:56
org::kde::kirigami::Units::longDuration
int longDuration
units.longDuration should be used for longer, screen-covering animations, for opening and closing of ...
Definition: controls/Units.qml:75
org::kde::kirigami::Units
Definition: controls/Units.qml:24
org::kde::kirigami::Units::iconSizes
QtObject iconSizes
units.iconSizes provides access to platform-dependent icon sizing
Definition: controls/Units.qml:49
This file is part of the KDE documentation.
Documentation copyright © 1996-2017 The KDE developers.
Generated on Fri Feb 17 2017 11:09:23 by doxygen 1.8.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal