11 import org.kde.plasma.components 2.0
12 import org.kde.plasma.core 2.0 as PlasmaCore
14 import "../components/private/PageStack.js" as
Engine
22 width: parent ? parent.width : 0
23 height: parent ? parent.height : 0
26 property int depth:
Engine.getDepth()
27 property Item currentPage:
null
29 property var initialPage
31 property int columnWidth: Math.round(parent.width/(PlasmaCore.Theme.mSize(PlasmaCore.Theme.defaultFont).width*30)) > 0 ? parent.width/Math.round(parent.width/(PlasmaCore.Theme.mSize(PlasmaCore.Theme.defaultFont).width*30)) : width
32 property alias clip: scrollArea.clip
35 property bool busy:
internal.ongoingTransitionCount > 0
51 function push(page, properties, immediate)
53 var item =
Engine.push(page, properties,
false, immediate)
62 function pop(page, immediate)
64 return Engine.pop(page, immediate);
69 function replace(page, properties, immediate)
71 var item =
Engine.push(page, properties,
true, immediate);
92 function scrollToLevel(level)
94 if (level < 0 || level > depth || root.width < width) {
98 scrollAnimation.to = Math.max(0, Math.min(Math.max(0, columnWidth * level - columnWidth), mainFlickable.contentWidth))
99 scrollAnimation.running =
true
104 target: mainFlickable
105 properties:
"contentX"
106 duration:
internal.transitionDuration
107 easing.type: Easing.InOutQuad
113 internal.setPageStatus(currentPage, visible ? PageStatus.Active : PageStatus.Inactive);
115 currentPage.visible = currentPage.parent.visible =
true;
119 onInitialPageChanged: {
120 if (!
internal.completed) {
126 push(initialPage,
null,
true)
127 }
else if (depth == 1) {
128 replace(initialPage,
null,
true)
130 console.log(
"Cannot update PageStack.initialPage")
136 internal.completed =
true
137 if (initialPage && depth == 0)
138 push(initialPage,
null,
true)
145 property int ongoingTransitionCount: 0
148 property bool completed:
false
151 property int transitionDuration: PlasmaCore.Units.longDuration
154 function setPageStatus(page,
status)
157 if (page.status !== undefined) {
158 if (
status == PageStatus.Active && page.status == PageStatus.Inactive)
159 page.status = PageStatus.Activating;
160 else if (
status == PageStatus.Inactive && page.status == PageStatus.Active)
161 page.status = PageStatus.Deactivating;
175 interactive: root.width > width
176 boundsBehavior: Flickable.StopAtBounds
177 contentWidth: root.width
178 contentHeight: height
182 width: Math.max((depth-1+children[children.length-1].takenColumns) * columnWidth, childrenRect.width - 100)
184 height: parent.height
187 duration:
internal.transitionDuration
188 easing.type: Easing.InOutQuad
193 scrollToLevel(Math.round(contentX/columnWidth)+1)
199 id: svgShadowComponent
201 property Item container
203 svg: PlasmaCore.Svg {imagePath:
"widgets/scrollwidget"}
204 elementId:
"border-left"
205 width: naturalSize.width
206 opacity: container.pageDepth == actualRoot.depth ? 1 : 0.7
208 left: container.pageParent.
right
209 top: container.pageParent.top
210 bottom: container.pageParent.bottom
212 Behavior on opacity {
214 duration:
internal.transitionDuration
215 easing.type: Easing.InOutQuad
223 id: containerComponent
228 implicitWidth: actualContainer.width + 100
230 height: parent ? parent.height : 0
235 property Item pageParent: actualContainer
237 property int pageDepth: 0
239 pageDepth =
Engine.getDepth() + 1
240 container.z = -
Engine.getDepth()
247 property Item page:
null
250 property Item owner:
null
253 property int stackWidth: Math.max(actualRoot.width, actualRoot.height)
257 property bool cleanupAfterTransition:
false
260 property bool transitionAnimationRunning:
false
263 property string pendingState:
"none"
266 property alias takenColumns: actualContainer.takenColumns
272 if (transitionAnimationRunning)
281 bottom: parent.bottom
286 property int takenColumns: Math.max(1, Math.round(container.page ? container.page.implicitWidth/columnWidth : 1));
288 width: (container.pageDepth >= actualRoot.depth ? Math.min(actualRoot.width, takenColumns*columnWidth) : columnWidth)
293 source:
"image://appbackgrounds/shadow-right"
294 fillMode: Image.TileVertically
295 opacity: container.pageDepth == actualRoot.depth ? 1 : 0.7
297 left: actualContainer.
right
298 top: actualContainer.top
299 bottom: actualContainer.bottom
301 Behavior on opacity {
303 duration:
internal.transitionDuration
304 easing.type: Easing.InOutQuad
308 if (
status == Image.Error) {
309 var shadow = svgShadowComponent.createObject(container)
310 shadow.container = container
317 onTransitionAnimationRunningChanged: {
318 if (!transitionAnimationRunning && pendingState !=
"none") {
319 state = pendingState;
320 pendingState =
"none";
325 function setState(newState)
327 if (transitionAnimationRunning)
328 pendingState = newState;
334 function pushEnter(immediate, orientationChanges)
341 if (actualRoot.visible && immediate)
342 internal.setPageStatus(page, PageStatus.Active);
346 function pushExit(replace, immediate, orientationChanges)
349 setState(immediate ?
"Hidden" :
"Left");
352 if (actualRoot.visible && immediate)
353 internal.setPageStatus(page, PageStatus.Inactive);
358 cleanupAfterTransition =
true;
363 function popEnter(immediate, orientationChanges)
367 if (actualRoot.visible && immediate)
368 internal.setPageStatus(page, PageStatus.Active);
372 function popExit(immediate, orientationChanges)
374 setState(immediate ?
"Hidden" :
"Left");
376 if (actualRoot.visible && immediate)
377 internal.setPageStatus(page, PageStatus.Inactive);
381 cleanupAfterTransition =
true;
385 function transitionStarted()
387 container.clip =
true
388 transitionAnimationRunning =
true;
389 internal.ongoingTransitionCount++;
390 if (actualRoot.visible) {
391 internal.setPageStatus(page, (state ==
"") ? PageStatus.Activating : PageStatus.Deactivating);
396 function transitionEnded()
398 container.clip =
false
401 if (actualRoot.visible)
402 internal.setPageStatus(page, (state ==
"") ? PageStatus.Active : PageStatus.Inactive);
404 internal.ongoingTransitionCount--;
405 transitionAnimationRunning =
false;
407 if (cleanupAfterTransition) {
416 PropertyChanges { target: container; visible:
true; opacity: 1 }
417 PropertyChanges { target: container; width: container.implicitWidth}
422 PropertyChanges { target: container; opacity: 0 }
423 PropertyChanges { target: container; width: 100}
428 PropertyChanges { target: container; opacity: 0 }
429 PropertyChanges { target: container; width: 100}
434 PropertyChanges { target: container; visible:
false }
435 PropertyChanges { target: container; width: container.implicitWidth}
443 SequentialAnimation {
444 ScriptAction { script: transitionStarted() }
446 PropertyAnimation { properties:
"width"; easing.type: Easing.InQuad; duration:
internal.transitionDuration }
447 PropertyAnimation { properties:
"opacity"; easing.type: Easing.InQuad; duration:
internal.transitionDuration }
449 ScriptAction { script: transitionEnded() }
455 SequentialAnimation {
456 ScriptAction { script: transitionStarted() }
458 PropertyAnimation { properties:
"width"; easing.type: Easing.OutQuad; duration:
internal.transitionDuration }
459 PropertyAnimation { properties:
"opacity"; easing.type: Easing.InQuad; duration:
internal.transitionDuration }
461 ScriptAction { script: transitionEnded() }
466 from:
""; to:
"Right"
467 SequentialAnimation {
468 ScriptAction { script: transitionStarted() }
470 PropertyAnimation { properties:
"width"; easing.type: Easing.InQuad; duration:
internal.transitionDuration }
471 PropertyAnimation { properties:
"opacity"; easing.type: Easing.InQuad; duration:
internal.transitionDuration }
476 ScriptAction { script: transitionEnded() }
481 from:
"Right"; to:
""
482 SequentialAnimation {
483 ScriptAction { script: transitionStarted() }
485 PropertyAnimation { properties:
"width"; easing.type: Easing.OutQuad; duration:
internal.transitionDuration }
486 PropertyAnimation { properties:
"opacity"; easing.type: Easing.InQuad; duration:
internal.transitionDuration }
488 ScriptAction { script: transitionEnded() }
497 if (page.status == PageStatus.Active) {
498 internal.setPageStatus(page, PageStatus.Inactive)
500 if (owner != container) {
502 page.visible =
false;
503 page.anchors.fill = undefined
507 container.parent =
null;
508 container.visible =
false;