Commit 56bce74d authored by Yuya Nishihara's avatar Yuya Nishihara
Browse files

attach drag handles for each tile and add minimal interface to update rect

parent 19d5c5b0
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQml 2.15 // Binding.restoreMode
import MyTileExample 1.0
Control {
id: root
readonly property int majorOrientation: model.majorOrientation
readonly property int majorCount: model.majorCount
readonly property var minorCounts: model.minorCounts
property real handleWidth: 5
property real handleHeight: 5
// TODO: property var _majorPositions: _makeDefaultPositionsArray(majorCount)
// TODO: property var _minorPositions: _makeDefaultPositionsArray(Math.max(...minorCounts))
property TileListModel model
property Component delegate
// TODO
/*
function _makeDefaultPositionsArray(count) {
let positions = [];
for (let i = 0; i < count; ++i) {
positions.push(i / count);
}
return positions;
}
Component.onCompleted: {
// break binding
_majorPositions = _majorPositions;
_minorPositions = _minorPositions;
}
onMajorCountChanged: {
_majorPositions = _makeDefaultPositionsArray(majorCount);
}
onMinorCountsChanged: {
_minorPositions = _makeDefaultPositionsArray(Math.max(...minorCounts));
}
*/
contentItem: Item {
Item {
id: contentArea
......@@ -91,215 +58,87 @@ Control {
}
}
// TODO
/*
Item {
id: handleArea
anchors.fill: contentArea
Repeater {
model: root.majorOrientation !== Qt.Horizontal ? root.majorCount : 0
Item {
id: minorHandleAreaH
required property int index
readonly property real position: root._majorPositions[index]
readonly property real size: {
(index + 1 < root.majorCount ? root._majorPositions[index + 1] : 1) - position
}
anchors.left: parent.left
anchors.right: parent.right
y: contentArea.height * position
height: contentArea.height * size
Repeater {
model: root.minorCounts[minorHandleAreaH.index]
Rectangle {
id: minorHandleH
required property int index
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.topMargin: root.handleHeight / 2
anchors.bottomMargin: root.handleHeight / 2
width: root.handleWidth
visible: index > 0
color: "gray"
onXChanged: {
if (!minorDragHandlerH.active)
return;
let positions = root._minorPositions;
positions[index] = (x + width / 2) / minorHandleAreaH.width;
root._minorPositions = positions;
}
Binding on x {
when: !minorDragHandlerH.active
value: minorHandleAreaH.width * root._minorPositions[minorHandleH.index] - minorHandleH.width / 2
restoreMode: Binding.RestoreNone
}
HoverHandler {
cursorShape: Qt.SplitHCursor
}
DragHandler {
id: minorDragHandlerH
xAxis.enabled: root.majorOrientation !== Qt.Horizontal
yAxis.enabled: root.majorOrientation === Qt.Horizontal
// TODO: minimum/maximum
}
}
}
}
}
Repeater {
model: root.majorOrientation === Qt.Horizontal ? root.majorCount : 0
Item {
id: minorHandleAreaV
required property int index
readonly property real position: root._majorPositions[index]
readonly property real size: {
(index + 1 < root.majorCount ? root._majorPositions[index + 1] : 1) - position
}
anchors.top: parent.top
anchors.bottom: parent.bottom
x: contentArea.width * position
width: contentArea.width * size
Repeater {
model: root.minorCounts[minorHandleAreaV.index]
Rectangle {
id: minorHandleV
required property int index
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: root.handleWidth / 2
anchors.rightMargin: root.handleWidth / 2
height: root.handleHeight
visible: index > 0
color: "gray"
onYChanged: {
if (!minorDragHandlerV.active)
return;
let positions = root._minorPositions;
positions[index] = (y + height / 2) / minorHandleAreaV.height;
root._minorPositions = positions;
}
Binding on y {
when: !minorDragHandlerV.active
value: minorHandleAreaV.height * root._minorPositions[minorHandleV.index] - minorHandleV.height / 2
restoreMode: Binding.RestoreNone
}
HoverHandler {
cursorShape: Qt.SplitVCursor
}
DragHandler {
id: minorDragHandlerV
xAxis.enabled: false
yAxis.enabled: true
// TODO: minimum/maximum
}
}
}
}
}
model: root.model
Repeater {
model: root.majorOrientation === Qt.Horizontal ? root.majorCount : 0
Rectangle {
id: majorHandleH
id: hHandle
required property int index
required property int tileIndex
required property rect contentRect
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.topMargin: root.handleHeight / 2
anchors.bottomMargin: root.handleHeight / 2
x: parent.width * contentRect.x
y: parent.height * contentRect.y
width: root.handleWidth
visible: index > 0
height: parent.height * contentRect.height
visible: tileIndex >= 0 && contentRect.x > 0
color: "gray"
onXChanged: {
if (!majorDragHandlerH.active)
return;
let positions = root._majorPositions;
positions[index] = (x + width / 2) / contentArea.width;
root._majorPositions = positions;
}
Binding on x {
when: !majorDragHandlerH.active
value: contentArea.width * root._majorPositions[majorHandleH.index] - majorHandleH.width / 2
restoreMode: Binding.RestoreNone
}
HoverHandler {
cursorShape: Qt.SplitHCursor
}
DragHandler {
id: majorDragHandlerH
target: null
xAxis.enabled: true
yAxis.enabled: false
// TODO: minimum/maximum
onCentroidChanged: {
if (!active)
return;
let pos = hHandle.mapToItem(
handleArea,
centroid.position.x - centroid.pressPosition.x,
centroid.position.y - centroid.pressPosition.y);
root.model.moveHandle(
hHandle.index, Qt.Horizontal, pos.x / handleArea.width);
}
}
}
}
Repeater {
model: root.majorOrientation !== Qt.Horizontal ? root.majorCount : 0
model: root.model
Rectangle {
id: majorHandleV
id: vHandle
required property int index
required property int tileIndex
required property rect contentRect
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: root.handleWidth / 2
anchors.rightMargin: root.handleWidth / 2
x: parent.width * contentRect.x
y: parent.height * contentRect.y
width: parent.width * contentRect.width
height: root.handleHeight
visible: index > 0
visible: tileIndex >= 0 && contentRect.y > 0
color: "gray"
onYChanged: {
if (!majorDragHandlerV.active)
return;
let positions = root._majorPositions;
positions[index] = (y + height / 2) / contentArea.height;
root._majorPositions = positions;
}
Binding on y {
when: !majorDragHandlerV.active
value: contentArea.height * root._majorPositions[majorHandleV.index] - majorHandleV.height / 2
restoreMode: Binding.RestoreNone
}
HoverHandler {
cursorShape: Qt.SplitVCursor
}
DragHandler {
id: majorDragHandlerV
target: null
xAxis.enabled: false
yAxis.enabled: true
// TODO: minimum/maximum
onCentroidChanged: {
if (!active)
return;
let pos = vHandle.mapToItem(
handleArea,
centroid.position.x - centroid.pressPosition.x,
centroid.position.y - centroid.pressPosition.y);
root.model.moveHandle(
vHandle.index, Qt.Vertical, pos.y / handleArea.height);
}
}
}
}
}
*/
}
}
......@@ -151,6 +151,24 @@ void TileListModel::setTileIndex(int row, int tileIndex)
emit dataChanged(index(row), index(row), { TileIndexRole, ContentRectRole });
}
void TileListModel::moveHandle(int row, Qt::Orientation orientation, qreal position)
{
if (row < 0 || row >= static_cast<int>(m_tiles.size()))
return;
auto &tile = m_tiles.at(static_cast<size_t>(row));
if (tile.tileIndex < 0)
return;
// TODO: adjust adjacent tiles
if (orientation == Qt::Horizontal) {
tile.contentRect.setX(position);
} else {
tile.contentRect.setY(position);
}
emit dataChanged(index(row), index(row), { ContentRectRole });
}
QRectF TileListModel::defaultContentRectForTileAt(int tileIndex) const
{
if (tileIndex < 0)
......
......@@ -29,6 +29,8 @@ public:
Q_INVOKABLE void assignTileItem(const QString &name);
Q_INVOKABLE void setTileIndex(int row, int tileIndex);
Q_INVOKABLE void moveHandle(int row, Qt::Orientation orientation, qreal position);
signals:
void layoutReset();
......
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