Commit 0bc612c3 authored by Ronan Abhamon's avatar Ronan Abhamon

fix(Paned): supports max limits

parent 325bf7c0
...@@ -9,11 +9,11 @@ import Utils 1.0 ...@@ -9,11 +9,11 @@ import Utils 1.0
// The division between the areas can be modified with a handle. // The division between the areas can be modified with a handle.
// //
// Each area can have a fixed or dynamic minimum width. // Each area can have a fixed or dynamic minimum width.
// See `leftLimit` and `rightLimit` attributes. // See `minimumLeftLimit` and `minimumRightLimit` attributes.
// //
// To create a dynamic minimum width, it's necessary to give // To create a dynamic minimum width, it's necessary to give
// a percentage to `leftLimit` or `rightLimit` like: // a percentage to `minmimumLeftLimit` or `minimumRightLimit` like:
// `leftLimit: '0.66%'`. // `minimumLeftLimit: '66%'`.
// The percentage is relative to the container width. // The percentage is relative to the container width.
// //
// =================================================================== // ===================================================================
...@@ -26,29 +26,44 @@ Item { ...@@ -26,29 +26,44 @@ Item {
property int closingEdge: Qt.LeftEdge property int closingEdge: Qt.LeftEdge
// User limits: string or int values. // User limits: string or int values.
property var leftLimit: 0 // By default: no limits.
property var rightLimit: 0 property var maximumLeftLimit
property var maximumRightLimit
property var minimumLeftLimit: 0
property var minimumRightLimit: 0
property bool _isClosed property bool _isClosed
property int _savedContentAWidth property int _savedContentAWidth
// Internal limits. // Internal limits.
property var _leftLimit property var _maximumLeftLimit
property var _rightLimit property var _maximumRightLimit
property var _minimumLeftLimit
property var _minimumRightLimit
function _getLimitValue (limit) { function _getLimitValue (limit) {
if (limit == null) {
return
}
return limit.isDynamic return limit.isDynamic
? width * limit.value ? width * limit.value
: limit.value : limit.value
} }
function _parseLimit (limit) { function _parseLimit (limit) {
if (limit == null) {
return
}
if (Utils.isString(limit)) { if (Utils.isString(limit)) {
var arr = limit.split('%') var arr = limit.split('%')
return { if (arr[1] === '') {
isDynamic: arr[1] === '', return {
value: +arr[0] isDynamic: true,
value: +arr[0] / 100
}
} }
} }
...@@ -58,17 +73,89 @@ Item { ...@@ -58,17 +73,89 @@ Item {
} }
function _applyLimits () { function _applyLimits () {
var rightLimit = _getLimitValue(_rightLimit) var maximumLeftLimit = _getLimitValue(_maximumLeftLimit)
var leftLimit = _getLimitValue(_leftLimit) var maximumRightLimit = _getLimitValue(_maximumRightLimit)
var minimumLeftLimit = _getLimitValue(_minimumLeftLimit)
var minimumRightLimit = _getLimitValue(_minimumRightLimit)
var theoreticalBWidth = container.width - contentA.width - handle.width
// If closed, set correctly the handle position to left or right.
if (_isClosed) {
contentA.width = (closingEdge === Qt.RightEdge)
? container.width - handle.width
: 0
}
// width(A) < minimum width(A). // width(A) < minimum width(A).
if (contentA.width < leftLimit) { else if (contentA.width < minimumLeftLimit) {
contentA.width = leftLimit contentA.width = minimumLeftLimit
}
// width(A) > maximum width(A).
else if (maximumLeftLimit != null && contentA.width > maximumLeftLimit) {
contentA.width = maximumLeftLimit
}
// width(B) < minimum width(B).
else if (theoreticalBWidth < minimumRightLimit) {
contentA.width = container.width - handle.width - minimumRightLimit
}
// width(B) > maximum width(B).
else if (maximumRightLimit != null && theoreticalBWidth > maximumRightLimit) {
contentA.width = container.width - handle.width - maximumRightLimit
} }
}
function _applyLimitsOnUserMove (offset) {
var minimumRightLimit = _getLimitValue(_minimumRightLimit)
var minimumLeftLimit = _getLimitValue(_minimumLeftLimit)
// One area is closed.
if (_isClosed) {
if (closingEdge === Qt.LeftEdge) {
if (offset > minimumLeftLimit / 2) {
_updateClosing()
}
} else {
if (-offset > minimumRightLimit / 2) {
_updateClosing()
}
}
return
}
// Check limits.
var maximumLeftLimit = _getLimitValue(_maximumLeftLimit)
var maximumRightLimit = _getLimitValue(_maximumRightLimit)
var theoreticalBWidth = container.width - offset - contentA.width - handle.width
// width(A) < minimum width(A).
if (contentA.width + offset < minimumLeftLimit) {
contentA.width = minimumLeftLimit
if (closingEdge === Qt.LeftEdge && -offset > minimumLeftLimit / 2) {
_updateClosing()
}
}
// width(A) > maximum width(A).
else if (maximumLeftLimit != null && contentA.width + offset > maximumLeftLimit) {
contentA.width = maximumLeftLimit
}
// width(B) < minimum width(B). // width(B) < minimum width(B).
else if (width - contentA.width - handle.width < rightLimit) { else if (theoreticalBWidth < minimumRightLimit) {
contentA.width = width - handle.width - rightLimit contentA.width = container.width - handle.width - minimumRightLimit
if (closingEdge === Qt.RightEdge && offset > minimumRightLimit / 2) {
_updateClosing()
}
}
// width(B) > maximum width(B).
else if (maximumRightLimit != null && theoreticalBWidth > maximumRightLimit) {
contentA.width = container.width - handle.width - maximumRightLimit
}
// Resize A/B.
else {
contentA.width = contentA.width + offset
} }
} }
...@@ -78,9 +165,11 @@ Item { ...@@ -78,9 +165,11 @@ Item {
_isClosed = true _isClosed = true
_savedContentAWidth = contentA.width _savedContentAWidth = contentA.width
contentA.width = (closingEdge !== Qt.LeftEdge) if (closingEdge === Qt.LeftEdge) {
? container.width - handle.width closingTransitionA.running = true
: 0 } else {
closingTransitionB.running = true
}
return return
} }
...@@ -92,13 +181,17 @@ Item { ...@@ -92,13 +181,17 @@ Item {
_applyLimits() _applyLimits()
} }
onWidthChanged: !_isClosed && _applyLimits() onWidthChanged: _applyLimits()
Component.onCompleted: { Component.onCompleted: {
_leftLimit = _parseLimit(leftLimit) // Unable to modify this properties after creation.
_rightLimit = _parseLimit(rightLimit) // It's a desired choice.
_maximumLeftLimit = _parseLimit(maximumLeftLimit)
contentA.width = _getLimitValue(_leftLimit) _maximumRightLimit = _parseLimit(maximumRightLimit)
_minimumLeftLimit = _parseLimit(minimumLeftLimit)
_minimumRightLimit = _parseLimit(minimumRightLimit)
contentA.width = _getLimitValue(_minimumLeftLimit)
} }
Item { Item {
...@@ -119,56 +212,8 @@ Item { ...@@ -119,56 +212,8 @@ Item {
width: PanedStyle.handle.width width: PanedStyle.handle.width
onDoubleClicked: _updateClosing() onDoubleClicked: _updateClosing()
onMouseXChanged: pressed &&
onMouseXChanged: { _applyLimitsOnUserMove(handle.mouseX - _mouseStart)
// Mouse is not pressed.
if (!pressed) {
return
}
var offset = mouseX - _mouseStart
var rightLimit = _getLimitValue(_rightLimit)
var leftLimit = _getLimitValue(_leftLimit)
// One area is closed.
if (_isClosed) {
if (closingEdge === Qt.LeftEdge) {
if (offset > leftLimit / 2) {
_updateClosing()
}
} else {
if (-offset > rightLimit / 2) {
_updateClosing()
}
}
return
}
// Check limits.
// width(B) < minimum width(B).
if (container.width - offset - contentA.width - width < rightLimit) {
contentA.width = container.width - width - rightLimit
if (closingEdge === Qt.RightEdge && offset > rightLimit / 2) {
_updateClosing()
}
}
// width(A) < minimum width(A).
else if (contentA.width + offset < leftLimit) {
contentA.width = leftLimit
if (closingEdge === Qt.LeftEdge && -offset > leftLimit / 2) {
_updateClosing()
}
}
// Resize A/B.
else {
contentA.width = contentA.width + offset
}
}
onPressed: _mouseStart = mouseX onPressed: _mouseStart = mouseX
...@@ -190,4 +235,22 @@ Item { ...@@ -190,4 +235,22 @@ Item {
height: parent.height height: parent.height
width: container.width - contentA.width - handle.width width: container.width - contentA.width - handle.width
} }
PropertyAnimation {
id: closingTransitionA
target: contentA
property: 'width'
to: 0
duration: 200
}
PropertyAnimation {
id: closingTransitionB
duration: 200
property: 'width'
target: contentA
to: container.width - handle.width
}
} }
...@@ -7,30 +7,45 @@ import Linphone 1.0 ...@@ -7,30 +7,45 @@ import Linphone 1.0
Window { Window {
minimumHeight: 480 minimumHeight: 480
minimumWidth: 640 minimumWidth: 780
id: window id: window
Paned { Paned {
anchors.fill: parent anchors.fill: parent
rightLimit: 50 maximumLeftLimit: 300
leftLimit: 100 minimumLeftLimit: 50
childA: Rectangle { childA: Rectangle {
anchors.fill: parent anchors.fill: parent
color: 'orange' color: 'yellow'
Text { Text {
text: 'hello' text: 'calls'
} }
} }
childB: Rectangle { childB: Paned {
anchors.fill: parent anchors.fill: parent
color: 'green' closingEdge: Qt.RightEdge
Text { minimumLeftLimit: '40%'
text: 'hello2' minimumRightLimit: 200
childA: Rectangle {
anchors.fill: parent
color: 'orange'
Text {
text: 'hello'
}
}
childB: Rectangle {
anchors.fill: parent
color: 'green'
Text {
text: 'hello2'
}
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment