From af33391448d86f1fdef5ef2538cc673c54c852e6 Mon Sep 17 00:00:00 2001 From: cneben Date: Sun, 11 Aug 2024 18:54:42 +0200 Subject: [PATCH 01/10] #238 Test new group header layout + new group dnd policy... WIP. Signed-off-by: cneben --- CMakeLists.txt | 18 ++--- src/RectGroupTemplate.qml | 141 ++++++++++++++++++++------------------ 2 files changed, 85 insertions(+), 74 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4eaf2ac1..dbd7a903 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,15 +16,15 @@ add_subdirectory(src) option(QUICK_QANAVA_BUILD_SAMPLES "Build QuickQanava samples" OFF) if (${QUICK_QANAVA_BUILD_SAMPLES}) - add_subdirectory(samples/advanced) - add_subdirectory(samples/connector) - add_subdirectory(samples/cpp) - add_subdirectory(samples/dataflow) - add_subdirectory(samples/edges) + #add_subdirectory(samples/advanced) + #add_subdirectory(samples/connector) + #add_subdirectory(samples/cpp) + #add_subdirectory(samples/dataflow) + #add_subdirectory(samples/edges) add_subdirectory(samples/groups) - add_subdirectory(samples/navigable) + #add_subdirectory(samples/navigable) add_subdirectory(samples/nodes) - add_subdirectory(samples/selection) - add_subdirectory(samples/style) - add_subdirectory(samples/topology) + #add_subdirectory(samples/selection) + #add_subdirectory(samples/style) + #add_subdirectory(samples/topology) endif() diff --git a/src/RectGroupTemplate.qml b/src/RectGroupTemplate.qml index 17aa5f16..1d5c7518 100644 --- a/src/RectGroupTemplate.qml +++ b/src/RectGroupTemplate.qml @@ -70,80 +70,91 @@ Item { RectGradientBackground { // Node background and shadow with backOpacity and backRadius support id: groupBackground - anchors.fill: content // Note 20160328: Do not set as content child to avoid interferring + //anchors.fill: content // Note 20160328: Do not set as content child to avoid interferring + anchors.fill: parent style: template.groupItem ? template.groupItem.style: undefined // with content.childrenRect visible: !groupItem.collapsed } - Item { - id: content + + ColumnLayout { anchors.fill: parent - z: 3 - visible: !groupItem.collapsed - enabled: !groupItem.collapsed - } - RowLayout { - id: headerLayout - x: 0 - y: -2 - Math.max(collapser.height, // Shift header by the size of collapser button or the label - groupLabel.contentHeight, labelEditor.height) // height (for large font size) plus 2px margin - z: 2 - width: content.width; height: collapser.height - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - spacing: 0 - ToolButton { - id: collapser - padding: 0 - Layout.preferredWidth: 32 - Layout.preferredHeight: 32 - text: groupItem ? (groupItem.collapsed ? "+" : "-") : "-" - font.pixelSize: 13 - font.bold: true - onClicked: groupItem.collapsed = !groupItem.collapsed - } - Item { - id: labelEditorControl - clip: false + RowLayout { + id: headerLayout Layout.fillWidth: true - Layout.fillHeight: true - property int fontPointSize : groupItem.style.fontPointSize // Do not set pointSize for -1 value - onFontPointSizeChanged: { - if (fontPointSize != -1) - labelEditor.pixelSize = fontPointSize - groupLabel.font.pointSize = fontPointSize + Layout.fillHeight: false + Layout.alignment: Qt.AlignTop | Qt.AlignLeft + // x: 0 + // y: -2 - Math.max(collapser.height, // Shift header by the size of collapser button or the label + // groupLabel.contentHeight, labelEditor.height) // height (for large font size) plus 2px margin + // z: 2 + //width: content.width; height: collapser.height + //Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + spacing: 0 + ToolButton { + id: collapser + padding: 0 + Layout.preferredWidth: 32 + Layout.preferredHeight: 32 + text: groupItem ? (groupItem.collapsed ? "+" : "-") : "-" + font.pixelSize: 13 + font.bold: true + onClicked: groupItem.collapsed = !groupItem.collapsed } - LabelEditor { + Item { + id: labelEditorControl clip: false - id: labelEditor - anchors.top: parent.top; anchors.left: parent.left; anchors.right: parent.right - target: groupItem && groupItem.group ? groupItem.group : undefined - visible: false - bold: groupItem.style.fontBold - } - Label { - id: groupLabel - anchors.fill: parent - text: groupItem && - groupItem.group ? groupItem.group.label : - " " - visible: !labelEditor.visible - verticalAlignment: Text.AlignVCenter - font.bold: groupItem.style.fontBold - color: groupItem && - groupItem.style && - groupItem.style.labelColor ? groupItem.style.labelColor : "black" - elide: Text.ElideRight - MouseArea { + Layout.fillWidth: true + Layout.fillHeight: true + property int fontPointSize : groupItem.style.fontPointSize // Do not set pointSize for -1 value + onFontPointSizeChanged: { + if (fontPointSize != -1) + labelEditor.pixelSize = fontPointSize + groupLabel.font.pointSize = fontPointSize + } + LabelEditor { + clip: false + id: labelEditor + anchors.top: parent.top; anchors.left: parent.left; anchors.right: parent.right + target: groupItem && groupItem.group ? groupItem.group : undefined + visible: false + bold: groupItem.style.fontBold + } + Label { + id: groupLabel anchors.fill: parent - enabled: !groupItem.group.isProtected && - !groupItem.group.locked // Do not allow dragging of locked groups - preventStealing: true - propagateComposedEvents: true // Ensure event are forwarded to collapserArea - drag.target: groupItem.draggable ? groupItem : null - onDoubleClicked: labelEditor.visible = true + text: groupItem && + groupItem.group ? groupItem.group.label : + " " + visible: !labelEditor.visible + verticalAlignment: Text.AlignVCenter + font.bold: groupItem.style.fontBold + color: groupItem && + groupItem.style && + groupItem.style.labelColor ? groupItem.style.labelColor : "black" + elide: Text.ElideRight + MouseArea { + anchors.fill: parent + enabled: !groupItem.group.isProtected && + !groupItem.group.locked // Do not allow dragging of locked groups + preventStealing: true + propagateComposedEvents: true // Ensure event are forwarded to collapserArea + drag.target: groupItem.draggable ? groupItem : null + onDoubleClicked: labelEditor.visible = true + } } - } - } // labelEditor Item - } // RowLayout: collapser + label + } // labelEditor Item + } // RowLayout: collapser + label + Item { + id: content + Layout.fillWidth: true + Layout.fillHeight: true + //anchors.fill: parent + z: 3 + visible: !groupItem.collapsed + enabled: !groupItem.collapsed + } + } + // Emitted by qan::GroupItem when node dragging start function onNodeDragEnter() { /*groupBackground.backColor = Qt.binding( function() { return Qt.darker( template.groupItem.style.backColor, 1.05 ) } ) */} From 3552e906da02540178cd6457f4bbe76ce9fc2f3e Mon Sep 17 00:00:00 2001 From: cneben Date: Mon, 12 Aug 2024 11:14:07 +0200 Subject: [PATCH 02/10] #238 WIP. Signed-off-by: cneben --- src/RectGroupTemplate.qml | 15 +++++---------- src/qanDraggable.h | 3 --- src/qanDraggableCtrl.cpp | 20 +++++++++++++++++++- src/qanGroupItem.cpp | 11 +++++++++++ src/qanGroupItem.h | 27 +++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 14 deletions(-) diff --git a/src/RectGroupTemplate.qml b/src/RectGroupTemplate.qml index 1d5c7518..45935085 100644 --- a/src/RectGroupTemplate.qml +++ b/src/RectGroupTemplate.qml @@ -44,7 +44,7 @@ Item { default property alias children : content.children // Binded to Tpp.Group.container in Tpp.Group. - property alias content: content + property alias container: content property var groupItem: undefined @@ -70,9 +70,8 @@ Item { RectGradientBackground { // Node background and shadow with backOpacity and backRadius support id: groupBackground - //anchors.fill: content // Note 20160328: Do not set as content child to avoid interferring anchors.fill: parent - style: template.groupItem ? template.groupItem.style: undefined // with content.childrenRect + style: template.groupItem ? template.groupItem.style: undefined // with container.childrenRect visible: !groupItem.collapsed } @@ -83,12 +82,6 @@ Item { Layout.fillWidth: true Layout.fillHeight: false Layout.alignment: Qt.AlignTop | Qt.AlignLeft - // x: 0 - // y: -2 - Math.max(collapser.height, // Shift header by the size of collapser button or the label - // groupLabel.contentHeight, labelEditor.height) // height (for large font size) plus 2px margin - // z: 2 - //width: content.width; height: collapser.height - //Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft spacing: 0 ToolButton { id: collapser @@ -114,7 +107,9 @@ Item { LabelEditor { clip: false id: labelEditor - anchors.top: parent.top; anchors.left: parent.left; anchors.right: parent.right + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right target: groupItem && groupItem.group ? groupItem.group : undefined visible: false bold: groupItem.style.fontBold diff --git a/src/qanDraggable.h b/src/qanDraggable.h index b1d7ddbe..5e299b3d 100644 --- a/src/qanDraggable.h +++ b/src/qanDraggable.h @@ -34,9 +34,6 @@ #pragma once -// Std headers -#include - // Qt headers #include // Q_DECLARE_INTERFACE #include diff --git a/src/qanDraggableCtrl.cpp b/src/qanDraggableCtrl.cpp index 306246be..2e8cf5e7 100644 --- a/src/qanDraggableCtrl.cpp +++ b/src/qanDraggableCtrl.cpp @@ -159,7 +159,7 @@ void DraggableCtrl::handleMouseReleaseEvent(QMouseEvent* event) void DraggableCtrl::beginDragMove(const QPointF& sceneDragPos, bool dragSelection, bool notify) { - //qWarning() << "DraggableCtrl::beginDragMove(): target=" << getTargetItem() << " dragSelection=" << dragSelection << " notify=" << notify; + qWarning() << "DraggableCtrl::beginDragMove(): target=" << getTargetItem() << " dragSelection=" << dragSelection << " notify=" << notify; if (_targetItem == nullptr || _target == nullptr) return; @@ -167,6 +167,24 @@ void DraggableCtrl::beginDragMove(const QPointF& sceneDragPos, bool dragSelec _target->getLocked()) return; + if (_target->isGroup()) { + const auto groupItem = qobject_cast(_targetItem); + // Convert sceneDragPos to group item local coordinates + const auto groupItemDragPos = _targetItem->mapFromScene(sceneDragPos); + qWarning() << " groupItem=" << groupItem; + qWarning() << " groupItemDragPos=" << groupItemDragPos; + qWarning() << " groupItem->getContainer()=" << groupItem->getContainer(); + if (groupItem != nullptr) { + if ((groupItem->getDragPolicy() & qan::GroupItem::DragPolicy::Header) == qan::GroupItem::DragPolicy::Header) { + if (groupItemDragPos.y() > groupItem->getContainer()->y()) + return; + } else if ((groupItem->getDragPolicy() & qan::GroupItem::DragPolicy::Container) == qan::GroupItem::DragPolicy::Container) { + + } else + return; + } + } + const auto graph = getGraph(); if (graph == nullptr) return; diff --git a/src/qanGroupItem.cpp b/src/qanGroupItem.cpp index f852237b..c896e001 100644 --- a/src/qanGroupItem.cpp +++ b/src/qanGroupItem.cpp @@ -117,6 +117,17 @@ void GroupItem::setCollapsed(bool collapsed) noexcept //----------------------------------------------------------------------------- /* Group DnD Management *///--------------------------------------------------- +bool GroupItem::setDragPolicy(DragPolicy dragPolicy) noexcept +{ + if (dragPolicy != _dragPolicy) { + _dragPolicy = dragPolicy; + return true; + } + return false; +} +GroupItem::DragPolicy GroupItem::getDragPolicy() noexcept { return _dragPolicy; } +const GroupItem::DragPolicy GroupItem::getDragPolicy() const noexcept { return _dragPolicy; } + void GroupItem::groupMoved() { if (getCollapsed()) // Do not update edges when the group is collapsed diff --git a/src/qanGroupItem.h b/src/qanGroupItem.h index 441171a3..a2d231ee 100644 --- a/src/qanGroupItem.h +++ b/src/qanGroupItem.h @@ -92,6 +92,28 @@ class GroupItem : public qan::NodeItem /*! \name Dragging Support Management *///--------------------------------- //@{ +public: + //! FIXME #238 + enum class DragPolicy : unsigned int { + //! Undefined / No dragging. + Undefined = 0, + //! Allow dragging group in the group header. + Header = 2, + //! Allow dragging group in the group content. + Container = 2 + }; + Q_ENUM(DragPolicy) + + Q_PROPERTY(DragPolicy dragPolicy READ getDragPolicy WRITE setDragPolicy NOTIFY dragPolicyChanged FINAL) + virtual bool setDragPolicy(DragPolicy dragPolicy) noexcept; + DragPolicy getDragPolicy() noexcept; + const DragPolicy getDragPolicy() const noexcept; +protected: + DragPolicy _dragPolicy = DragPolicy::Header; +signals: + void dragPolicyChanged(); + + protected slots: //! Group is monitored for position change, since group's nodes edges should be updated manually in that case. void groupMoved(); @@ -175,6 +197,11 @@ protected slots: //------------------------------------------------------------------------- }; +// Define the bitwise AND operator for MyEnum +inline GroupItem::DragPolicy operator&(GroupItem::DragPolicy lhs, GroupItem::DragPolicy rhs) { + return static_cast(static_cast(lhs) & static_cast(rhs)); +} + } // ::qan QML_DECLARE_TYPE(qan::GroupItem) From 33e570e4d0e48571b85f711be9b845cb54f97f5a Mon Sep 17 00:00:00 2001 From: cneben Date: Mon, 12 Aug 2024 12:54:03 +0200 Subject: [PATCH 03/10] #238 Cosmetic + remove temporaries in RectGradientBackground. WIP. Signed-off-by: cneben --- src/Group.qml | 2 +- src/RectGradientBackground.qml | 28 ++++++++++++++-------------- src/RectGroupTemplate.qml | 13 ++++++++++++- src/qanDraggableCtrl.cpp | 19 +++++++++++-------- 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/Group.qml b/src/Group.qml index 9a9b45ec..2164cc06 100644 --- a/src/Group.qml +++ b/src/Group.qml @@ -46,7 +46,7 @@ Qan.GroupItem { height: 150 default property alias children : template - container: template.content // See qan::GroupItem::container property documentation + container: template.container // See qan::GroupItem::container property documentation //! Show or hide group top left label editor (default to visible). property alias labelEditorVisible : template.labelEditorVisible diff --git a/src/RectGradientBackground.qml b/src/RectGradientBackground.qml index 102e7729..176aaf81 100644 --- a/src/RectGradientBackground.qml +++ b/src/RectGradientBackground.qml @@ -42,14 +42,8 @@ import "qrc:/QuickQanava" as Qan */ Item { // PUBLIC ///////////////////////////////////////////////////////////////// - property var style: undefined - - property real backRadius: style ? style.backRadius : 4. - readonly property real backOpacity: style ? style.backOpacity : 0.8 - readonly property color baseColor: style ? style.baseColor: Qt.rgba(0., 0., 0., 0.) - readonly property color backColor: style ? style.backColor : Qt.rgba(0., 0., 0., 0.) - readonly property real borderWidth: style ? style.borderWidth : 1. - readonly property color borderColor: style ? style.borderColor : Qt.rgba(1., 1., 1., 0.) + property var style: undefined + readonly property real backRadius: style ? style.backRadius : 4. // PRIVATE //////////////////////////////////////////////////////////////// // Note: Top level item is used to isolate rendering of: @@ -62,13 +56,19 @@ Item { anchors.fill: parent radius: backRadius border.width: 0 // Do not draw border, just the background gradient (border is drawn in foreground) - opacity: backOpacity + opacity: style ? style.backOpacity : 0.8 // Note 20240105: Unfortunately we no longer have LinearGradient with Qt6, switching to a // vertical gradient... gradient: Gradient { - GradientStop { position: 0.0; color: baseColor } - GradientStop { position: 1.0; color: backColor } + GradientStop { + position: 0.0; + color: style ? style.baseColor: Qt.rgba(0., 0., 0., 0.) + } + GradientStop { + position: 1.0 + color: style ? style.backColor : Qt.rgba(0., 0., 0., 0.) + } } } Rectangle { @@ -76,9 +76,9 @@ Item { anchors.fill: parent // Background follow the content layout implicit size radius: backRadius color: Qt.rgba(0, 0, 0, 0) // Fully transparent - border.color: borderColor - border.width: borderWidth - antialiasing: true // Vertex antialiasing for borders + border.color: style ? style.borderColor : Qt.rgba(1., 1., 1., 0.) + border.width: style ? style.borderWidth : 1. + //antialiasing: true // Vertex antialiasing for borders // Note: Do not enable layer to avoid aliasing at high scale } } // Item diff --git a/src/RectGroupTemplate.qml b/src/RectGroupTemplate.qml index 45935085..880da863 100644 --- a/src/RectGroupTemplate.qml +++ b/src/RectGroupTemplate.qml @@ -77,11 +77,13 @@ Item { ColumnLayout { anchors.fill: parent + spacing: 0 RowLayout { id: headerLayout Layout.fillWidth: true Layout.fillHeight: false Layout.alignment: Qt.AlignTop | Qt.AlignLeft + z: 2 spacing: 0 ToolButton { id: collapser @@ -139,11 +141,20 @@ Item { } } // labelEditor Item } // RowLayout: collapser + label + Rectangle { + // FIXME #238 do not show for tables... + Layout.fillWidth: true + Layout.margins: 0 + height: 1 + border.width: 0 + color: groupItem?.style?.borderColor || Qt.rgba(1., 1., 1., 0.) + opacity: 0.8 + visible: !groupItem.collapsed + } Item { id: content Layout.fillWidth: true Layout.fillHeight: true - //anchors.fill: parent z: 3 visible: !groupItem.collapsed enabled: !groupItem.collapsed diff --git a/src/qanDraggableCtrl.cpp b/src/qanDraggableCtrl.cpp index 2e8cf5e7..a70157fd 100644 --- a/src/qanDraggableCtrl.cpp +++ b/src/qanDraggableCtrl.cpp @@ -166,8 +166,11 @@ void DraggableCtrl::beginDragMove(const QPointF& sceneDragPos, bool dragSelec if (_target->getIsProtected() || // Prevent dragging of protected or locked objects _target->getLocked()) return; + const auto graph = getGraph(); + if (graph == nullptr) + return; - if (_target->isGroup()) { + if (/*notify && */_target->isGroup()) { const auto groupItem = qobject_cast(_targetItem); // Convert sceneDragPos to group item local coordinates const auto groupItemDragPos = _targetItem->mapFromScene(sceneDragPos); @@ -175,19 +178,19 @@ void DraggableCtrl::beginDragMove(const QPointF& sceneDragPos, bool dragSelec qWarning() << " groupItemDragPos=" << groupItemDragPos; qWarning() << " groupItem->getContainer()=" << groupItem->getContainer(); if (groupItem != nullptr) { + bool drag = false; if ((groupItem->getDragPolicy() & qan::GroupItem::DragPolicy::Header) == qan::GroupItem::DragPolicy::Header) { - if (groupItemDragPos.y() > groupItem->getContainer()->y()) - return; + if (groupItemDragPos.y() < groupItem->getContainer()->y()) + drag = true; } else if ((groupItem->getDragPolicy() & qan::GroupItem::DragPolicy::Container) == qan::GroupItem::DragPolicy::Container) { - - } else + if (groupItemDragPos.y() >= groupItem->getContainer()->y()) + drag = true; + } + if (!drag) return; } } - const auto graph = getGraph(); - if (graph == nullptr) - return; //qWarning() << "qan::DraggableCtrl::beginDragMove(): dragSelection=" << dragSelection; //qWarning() << " graph->hasMultipleSelection()=" << graph->hasMultipleSelection(); //qWarning() << " notify=" << notify; From 7d7568e4336627b085f3358765ff2992d9399902 Mon Sep 17 00:00:00 2001 From: cneben Date: Mon, 12 Aug 2024 13:38:10 +0200 Subject: [PATCH 04/10] #238 Finally fix a hard to reproduce "dragging" issue (related to global / scene CS convertions). +Cosmetic / Still WIP. Signed-off-by: cneben --- src/RectGradientBackground.qml | 6 +++--- src/RectGroupTemplate.qml | 12 +++++------- src/TableGroup.qml | 2 +- src/qanDraggableCtrl.cpp | 21 ++++++++++++--------- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/RectGradientBackground.qml b/src/RectGradientBackground.qml index 176aaf81..c9f68e1c 100644 --- a/src/RectGradientBackground.qml +++ b/src/RectGradientBackground.qml @@ -34,7 +34,7 @@ import QtQuick -import QuickQanava 2.0 as Qan +import QuickQanava 2.0 as Qan import "qrc:/QuickQanava" as Qan /*! \brief Node or group background component with gradient fill, no effect and backOpacity style support @@ -42,8 +42,8 @@ import "qrc:/QuickQanava" as Qan */ Item { // PUBLIC ///////////////////////////////////////////////////////////////// - property var style: undefined - readonly property real backRadius: style ? style.backRadius : 4. + property var style: undefined + property real backRadius: style ? style.backRadius : 4. // PRIVATE //////////////////////////////////////////////////////////////// // Note: Top level item is used to isolate rendering of: diff --git a/src/RectGroupTemplate.qml b/src/RectGroupTemplate.qml index 880da863..5ebf11b3 100644 --- a/src/RectGroupTemplate.qml +++ b/src/RectGroupTemplate.qml @@ -36,7 +36,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts -import QuickQanava 2.0 as Qan +import QuickQanava 2.0 as Qan Item { id: template @@ -67,14 +67,12 @@ Item { } return true; } - - RectGradientBackground { // Node background and shadow with backOpacity and backRadius support + RectGradientBackground { // Apply node background styling id: groupBackground anchors.fill: parent - style: template.groupItem ? template.groupItem.style: undefined // with container.childrenRect + style: template.groupItem?.style visible: !groupItem.collapsed } - ColumnLayout { anchors.fill: parent spacing: 0 @@ -129,7 +127,7 @@ Item { groupItem.style && groupItem.style.labelColor ? groupItem.style.labelColor : "black" elide: Text.ElideRight - MouseArea { + /*MouseArea { anchors.fill: parent enabled: !groupItem.group.isProtected && !groupItem.group.locked // Do not allow dragging of locked groups @@ -137,7 +135,7 @@ Item { propagateComposedEvents: true // Ensure event are forwarded to collapserArea drag.target: groupItem.draggable ? groupItem : null onDoubleClicked: labelEditor.visible = true - } + }*/ } } // labelEditor Item } // RowLayout: collapser + label diff --git a/src/TableGroup.qml b/src/TableGroup.qml index 45bac8bb..097c9835 100644 --- a/src/TableGroup.qml +++ b/src/TableGroup.qml @@ -46,7 +46,7 @@ Qan.TableGroupItem { height: 150 default property alias children : template - container: template.content // See qan::GroupItem::container property documentation + container: template.container // See qan::GroupItem::container property documentation //! Show or hide group top left label editor (default to visible). property bool labelEditorVisible : false diff --git a/src/qanDraggableCtrl.cpp b/src/qanDraggableCtrl.cpp index a70157fd..8c5d546b 100644 --- a/src/qanDraggableCtrl.cpp +++ b/src/qanDraggableCtrl.cpp @@ -131,7 +131,7 @@ bool DraggableCtrl::handleMouseMoveEvent(QMouseEvent* event) const auto rootItem = getGraph()->getContainerItem(); if (rootItem != nullptr && // Root item exist, left button is pressed and the target item event->buttons().testFlag(Qt::LeftButton)) { // is draggable and not collapsed - const auto sceneDragPos = rootItem->mapFromGlobal(event->globalPos()); + const auto sceneDragPos = event->scenePosition(); if (!_targetItem->getDragged()) { // Project in scene rect (for example is a node is part of a group) beginDragMove(sceneDragPos, _targetItem->getSelected()); @@ -159,7 +159,7 @@ void DraggableCtrl::handleMouseReleaseEvent(QMouseEvent* event) void DraggableCtrl::beginDragMove(const QPointF& sceneDragPos, bool dragSelection, bool notify) { - qWarning() << "DraggableCtrl::beginDragMove(): target=" << getTargetItem() << " dragSelection=" << dragSelection << " notify=" << notify; + qWarning() << "DraggableCtrl::beginDragMove(): sceneDragPos=" << sceneDragPos << " target=" << getTargetItem() << " dragSelection=" << dragSelection << " notify=" << notify; if (_targetItem == nullptr || _target == nullptr) return; @@ -172,22 +172,25 @@ void DraggableCtrl::beginDragMove(const QPointF& sceneDragPos, bool dragSelec if (/*notify && */_target->isGroup()) { const auto groupItem = qobject_cast(_targetItem); + const auto groupItemContainer = groupItem ? groupItem->getContainer() : nullptr; // Convert sceneDragPos to group item local coordinates - const auto groupItemDragPos = _targetItem->mapFromScene(sceneDragPos); qWarning() << " groupItem=" << groupItem; - qWarning() << " groupItemDragPos=" << groupItemDragPos; - qWarning() << " groupItem->getContainer()=" << groupItem->getContainer(); - if (groupItem != nullptr) { + qWarning() << " groupItem->getContainer()=" << groupItemContainer; + if (groupItem != nullptr && groupItemContainer != nullptr) { + const auto groupItemDragPos = groupItemContainer->mapFromScene(sceneDragPos); + qWarning() << " groupItemDragPos=" << groupItemDragPos; bool drag = false; if ((groupItem->getDragPolicy() & qan::GroupItem::DragPolicy::Header) == qan::GroupItem::DragPolicy::Header) { - if (groupItemDragPos.y() < groupItem->getContainer()->y()) + if (groupItemDragPos.y() < 0) // Coords are in container CS drag = true; } else if ((groupItem->getDragPolicy() & qan::GroupItem::DragPolicy::Container) == qan::GroupItem::DragPolicy::Container) { - if (groupItemDragPos.y() >= groupItem->getContainer()->y()) + if (groupItemDragPos.y() >= 0) drag = true; } - if (!drag) + if (!drag) { + _targetItem->setDragged(false); return; + } } } From 2409a6d205051584c4a6a895490017307c737212 Mon Sep 17 00:00:00 2001 From: cneben Date: Mon, 12 Aug 2024 14:26:45 +0200 Subject: [PATCH 05/10] #238 more efficient labelEditorVisible / expandButtonVisible group item properties management from c++. WIP. Signed-off-by: cneben --- src/Group.qml | 8 ++------ src/LabelEditor.qml | 10 ++++++---- src/RectGroupTemplate.qml | 30 +++++++++++------------------- src/TableGroup.qml | 8 ++------ src/qanGroupItem.cpp | 8 +++++++- src/qanGroupItem.h | 30 +++++++++++++++++++++++++++++- 6 files changed, 57 insertions(+), 37 deletions(-) diff --git a/src/Group.qml b/src/Group.qml index 2164cc06..fab6d653 100644 --- a/src/Group.qml +++ b/src/Group.qml @@ -38,6 +38,7 @@ import QtQuick.Layouts import QuickQanava 2.0 as Qan import "qrc:/QuickQanava" as Qan +//! \brief Default delegate for `qan::GroupItem`. Qan.GroupItem { id: groupItem @@ -47,12 +48,7 @@ Qan.GroupItem { default property alias children : template container: template.container // See qan::GroupItem::container property documentation - - //! Show or hide group top left label editor (default to visible). - property alias labelEditorVisible : template.labelEditorVisible - - //! Show or hide group top left expand button (default to visible). - property alias expandButtonVisible : template.expandButtonVisible + labelEditorVisible: template.labelEditorVisible Qan.RectGroupTemplate { id: template diff --git a/src/LabelEditor.qml b/src/LabelEditor.qml index b4acd8de..711138ad 100644 --- a/src/LabelEditor.qml +++ b/src/LabelEditor.qml @@ -71,8 +71,7 @@ Loader { //! Editor target node or group (or any Qan primitive with a \c label property). property var target: undefined - property bool bold: false - property real pixelSize: 12 + property real fontPixelSize: 11 onVisibleChanged: { if (visible && !item) @@ -101,8 +100,8 @@ Loader { anchors.left: parent.left anchors.right: parent.right text: target ? target.label : "" - font.bold: labelEditorLoader.bold - font.pixelSize: labelEditorLoader.pixelSize + font.bold: false + font.pixelSize: 22 onAccepted: { if (target && text.length !== 0) @@ -115,6 +114,9 @@ Loader { text !== target.label) // Ensure that last edition text is removed text = target.label // for exemple if edition has been interrupted in a focus change } + background: Rectangle { + color: Qt.rgba(0., 0., 0., 0.) // Disable editor background + } Keys.onEscapePressed: { // Cancel edition on escape labelEditorLoader.visible = false; diff --git a/src/RectGroupTemplate.qml b/src/RectGroupTemplate.qml index 5ebf11b3..18ae8e76 100644 --- a/src/RectGroupTemplate.qml +++ b/src/RectGroupTemplate.qml @@ -49,10 +49,7 @@ Item { property var groupItem: undefined //! Show or hide group top left label editor (default to visible). - property alias labelEditorVisible : labelEditorControl.visible - - //! Show or hide group top left expand button (default to visible). - property alias expandButtonVisible : collapser.visible + readonly property alias labelEditorVisible: labelEditorControl.visible property alias header: headerLayout @@ -92,50 +89,45 @@ Item { font.pixelSize: 13 font.bold: true onClicked: groupItem.collapsed = !groupItem.collapsed + visible: groupItem?.expandButtonVisible } Item { id: labelEditorControl clip: false Layout.fillWidth: true Layout.fillHeight: true - property int fontPointSize : groupItem.style.fontPointSize // Do not set pointSize for -1 value - onFontPointSizeChanged: { - if (fontPointSize != -1) - labelEditor.pixelSize = fontPointSize - groupLabel.font.pointSize = fontPointSize - } + property int labelPointSize : groupItem?.style?.fontPointSize || Material.fontSize LabelEditor { - clip: false id: labelEditor + clip: false anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - target: groupItem && groupItem.group ? groupItem.group : undefined + target: groupItem?.group visible: false - bold: groupItem.style.fontBold + fontPixelSize: labelEditorControl.labelPointSize } Label { id: groupLabel anchors.fill: parent + anchors.leftMargin: collapser.visible ? 0 : 10 text: groupItem && groupItem.group ? groupItem.group.label : " " visible: !labelEditor.visible verticalAlignment: Text.AlignVCenter font.bold: groupItem.style.fontBold - color: groupItem && - groupItem.style && - groupItem.style.labelColor ? groupItem.style.labelColor : "black" + font.pointSize: labelEditorControl.labelPointSize + color: groupItem?.style?.labelColor || "black" elide: Text.ElideRight - /*MouseArea { + MouseArea { anchors.fill: parent enabled: !groupItem.group.isProtected && !groupItem.group.locked // Do not allow dragging of locked groups preventStealing: true propagateComposedEvents: true // Ensure event are forwarded to collapserArea - drag.target: groupItem.draggable ? groupItem : null onDoubleClicked: labelEditor.visible = true - }*/ + } } } // labelEditor Item } // RowLayout: collapser + label diff --git a/src/TableGroup.qml b/src/TableGroup.qml index 097c9835..46495769 100644 --- a/src/TableGroup.qml +++ b/src/TableGroup.qml @@ -37,7 +37,7 @@ import QtQuick import QuickQanava 2.0 as Qan import "qrc:/QuickQanava" as Qan -//! \brief Default delegate for `qan::TableGroup`. +//! \brief Default delegate for `qan::TableGroupItem`. Qan.TableGroupItem { id: tableGroupItem @@ -47,11 +47,7 @@ Qan.TableGroupItem { default property alias children : template container: template.container // See qan::GroupItem::container property documentation - - //! Show or hide group top left label editor (default to visible). - property bool labelEditorVisible : false - //! Show or hide group top left expand button (default to visible). - property bool expandButtonVisible : false + labelEditorVisible: template.labelEditorVisible Qan.RectGroupTemplate { id: template anchors.fill: parent diff --git a/src/qanGroupItem.cpp b/src/qanGroupItem.cpp index c896e001..3d0019ba 100644 --- a/src/qanGroupItem.cpp +++ b/src/qanGroupItem.cpp @@ -98,7 +98,7 @@ auto GroupItem::setRect(const QRectF& r) noexcept -> void //----------------------------------------------------------------------------- -/* Collapse Management *///---------------------------------------------------- +/* Collapse / Edition Management *///------------------------------------------ void GroupItem::setCollapsed(bool collapsed) noexcept { qan::NodeItem::setCollapsed(collapsed); @@ -114,6 +114,12 @@ void GroupItem::setCollapsed(bool collapsed) noexcept groupMoved(); // Force update of all adjacent edges } } + +void GroupItem::setExpandButtonVisible(bool expandButtonVisible) { _expandButtonVisible = expandButtonVisible; emit expandButtonVisibleChanged(); } +bool GroupItem::getExpandButtonVisible() const { return _expandButtonVisible; } + +void GroupItem::setLabelEditorVisible(bool labelEditorVisible) { _labelEditorVisible = labelEditorVisible; emit labelEditorVisibleChanged(); } +bool GroupItem::getLabelEditorVisible() const { return _labelEditorVisible; } //----------------------------------------------------------------------------- /* Group DnD Management *///--------------------------------------------------- diff --git a/src/qanGroupItem.h b/src/qanGroupItem.h index a2d231ee..b10988d8 100644 --- a/src/qanGroupItem.h +++ b/src/qanGroupItem.h @@ -83,10 +83,38 @@ class GroupItem : public qan::NodeItem //@} //------------------------------------------------------------------------- - /*! \name Collapse Management *///----------------------------------------- + /*! \name Collapse / Edition Management *///------------------------------- //@{ protected: virtual void setCollapsed(bool collapsed) noexcept override; + +public: + //! \copydoc getExpandButtonVisible() + Q_PROPERTY(bool expandButtonVisible READ getExpandButtonVisible WRITE setExpandButtonVisible NOTIFY expandButtonVisibleChanged FINAL) + //! \copydoc getExpandButtonVisible() + void setExpandButtonVisible(bool expandButtonVisible); + //! \brief Show / hide the group expand / collapse button. + bool getExpandButtonVisible() const; +private: + //! \copydoc getExpandButtonVisible() + bool _expandButtonVisible = true; +signals: + //! \copydoc getExpandButtonVisible() + void expandButtonVisibleChanged(); + +public: + //! \copydoc getLabelEditorVisible() + Q_PROPERTY(bool labelEditorVisible READ getLabelEditorVisible WRITE setLabelEditorVisible NOTIFY labelEditorVisibleChanged FINAL) + //! \copydoc getLabelEditorVisible() + void setLabelEditorVisible(bool labelEditorVisible); + //! \brief True when the group label in group editor is beeing edited. + bool getLabelEditorVisible() const; +private: + //! \copydoc getLabelEditorVisible() + bool _labelEditorVisible = false; +signals: + //! \copydoc getLabelEditorVisible() + void labelEditorVisibleChanged(); //@} //------------------------------------------------------------------------- From 7ffe7fc4587d827f859e76e79f5ddd4c1718a01f Mon Sep 17 00:00:00 2001 From: cneben Date: Mon, 12 Aug 2024 15:39:23 +0200 Subject: [PATCH 06/10] #238 Secure table layout. WIP. Signed-off-by: cneben --- src/RectGroupTemplate.qml | 9 ++-- src/TableBorder.qml | 15 +++---- src/qanDraggableCtrl.cpp | 10 +++-- src/qanTableGroupItem.cpp | 93 +++++++++++++++++++++++++++------------ 4 files changed, 81 insertions(+), 46 deletions(-) diff --git a/src/RectGroupTemplate.qml b/src/RectGroupTemplate.qml index 18ae8e76..ef44c648 100644 --- a/src/RectGroupTemplate.qml +++ b/src/RectGroupTemplate.qml @@ -120,13 +120,11 @@ Item { font.pointSize: labelEditorControl.labelPointSize color: groupItem?.style?.labelColor || "black" elide: Text.ElideRight - MouseArea { - anchors.fill: parent + TapHandler { enabled: !groupItem.group.isProtected && !groupItem.group.locked // Do not allow dragging of locked groups - preventStealing: true - propagateComposedEvents: true // Ensure event are forwarded to collapserArea - onDoubleClicked: labelEditor.visible = true + exclusiveSignals: TapHandler.DoubleTap + onTapped: labelEditor.visible = true } } } // labelEditor Item @@ -151,7 +149,6 @@ Item { } } - // Emitted by qan::GroupItem when node dragging start function onNodeDragEnter() { /*groupBackground.backColor = Qt.binding( function() { return Qt.darker( template.groupItem.style.backColor, 1.05 ) } ) */} // Emitted by qan::GroupItem when node dragging ends diff --git a/src/TableBorder.qml b/src/TableBorder.qml index 5aff17eb..33d52276 100644 --- a/src/TableBorder.qml +++ b/src/TableBorder.qml @@ -39,17 +39,16 @@ import "qrc:/QuickQanava" as Qan Qan.AbstractTableBorder { id: tableBorder - borderWidth: tableGroup && tableGroup.tableStyle ? tableGroup.tableStyle.borderWidth : - 3. + // FIXME #238 have a .? operator try here (but borderWidth might be 0.... + borderWidth: tableGroup?.tableStyle?.borderWidth ?? 3. Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter - width: parent.orientation == Qt.Vertical ? tableBorder.borderWidth : - tableBorder.width - height: parent.orientation == Qt.Vertical ? tableBorder.height : - tableBorder.borderWidth - color: tableGroup && tableGroup.tableStyle ? tableGroup.tableStyle.borderColor : - Qt.rgba(0., 0., 0., 1.) + width: tableBorder.orientation == Qt.Vertical ? tableBorder.borderWidth : + tableBorder.width + height: tableBorder.orientation == Qt.Vertical ? tableBorder.height : + tableBorder.borderWidth + color: tableGroup?.tableStyle?.borderColor ?? Qt.rgba(0., 0., 0., 1.) } } // Qan.AbstractTableBorder diff --git a/src/qanDraggableCtrl.cpp b/src/qanDraggableCtrl.cpp index 8c5d546b..19804da1 100644 --- a/src/qanDraggableCtrl.cpp +++ b/src/qanDraggableCtrl.cpp @@ -159,7 +159,7 @@ void DraggableCtrl::handleMouseReleaseEvent(QMouseEvent* event) void DraggableCtrl::beginDragMove(const QPointF& sceneDragPos, bool dragSelection, bool notify) { - qWarning() << "DraggableCtrl::beginDragMove(): sceneDragPos=" << sceneDragPos << " target=" << getTargetItem() << " dragSelection=" << dragSelection << " notify=" << notify; + //qWarning() << "DraggableCtrl::beginDragMove(): sceneDragPos=" << sceneDragPos << " target=" << getTargetItem() << " dragSelection=" << dragSelection << " notify=" << notify; if (_targetItem == nullptr || _target == nullptr) return; @@ -170,15 +170,17 @@ void DraggableCtrl::beginDragMove(const QPointF& sceneDragPos, bool dragSelec if (graph == nullptr) return; + // FIXME #238 multiple selection... if (/*notify && */_target->isGroup()) { const auto groupItem = qobject_cast(_targetItem); const auto groupItemContainer = groupItem ? groupItem->getContainer() : nullptr; // Convert sceneDragPos to group item local coordinates - qWarning() << " groupItem=" << groupItem; - qWarning() << " groupItem->getContainer()=" << groupItemContainer; + // FIXME #238 + //qWarning() << " groupItem=" << groupItem; + //qWarning() << " groupItem->getContainer()=" << groupItemContainer; if (groupItem != nullptr && groupItemContainer != nullptr) { const auto groupItemDragPos = groupItemContainer->mapFromScene(sceneDragPos); - qWarning() << " groupItemDragPos=" << groupItemDragPos; + //qWarning() << " groupItemDragPos=" << groupItemDragPos; bool drag = false; if ((groupItem->getDragPolicy() & qan::GroupItem::DragPolicy::Header) == qan::GroupItem::DragPolicy::Header) { if (groupItemDragPos.y() < 0) // Coords are in container CS diff --git a/src/qanTableGroupItem.cpp b/src/qanTableGroupItem.cpp index 6716ac85..19d4eb78 100644 --- a/src/qanTableGroupItem.cpp +++ b/src/qanTableGroupItem.cpp @@ -45,12 +45,6 @@ TableGroupItem::TableGroupItem(QQuickItem* parent) : qan::GroupItem{parent} { setObjectName(QStringLiteral("qan::TableGroupItem")); - - connect(this, &QQuickItem::widthChanged, - this, &TableGroupItem::layoutTable); - connect(this, &QQuickItem::heightChanged, - this, &TableGroupItem::layoutTable); - setItemStyle(qan::TableGroup::style(parent)); setStrictDrop(false); // Top left corner of a node is enought to allow a drop } @@ -62,7 +56,7 @@ TableGroupItem::~TableGroupItem() bool TableGroupItem::setContainer(QQuickItem* container) noexcept { - //qWarning() << "qan::TableGroupItem::setContainer(): container=" << container; + qWarning() << "qan::TableGroupItem::setContainer(): container=" << container; if (qan::GroupItem::setContainer(container)) { // Note: Force reparenting all borders and cell to container, it might be nullptr // at initialization. @@ -75,6 +69,14 @@ bool TableGroupItem::setContainer(QQuickItem* container) noexcept for (const auto cell: _cells) if (cell != nullptr) cell->setParentItem(container); + + connect(container, &QQuickItem::widthChanged, + this, &TableGroupItem::layoutTable); + connect(container, &QQuickItem::heightChanged, + this, &TableGroupItem::layoutTable); + + initializeTableLayout(); + layoutTable(); return true; } return false; @@ -103,7 +105,7 @@ void TableGroupItem::clearLayout() void TableGroupItem::initialize(int cols, int rows) { - //qWarning() << "qan::TableGroupItem::initialize(): rows=" << rows << " cols=" << cols; + qWarning() << "qan::TableGroupItem::initialize(): rows=" << rows << " cols=" << cols; if (rows <= 0 || cols <= 0) { qWarning() << "TableGroupItem::initialize(): Error, invalid rows or cols count."; return; @@ -209,8 +211,8 @@ void TableGroupItem::createBorders(int verticalBordersCount, int horizontalBo return; } - auto borderComponent = new QQmlComponent(engine, "qrc:/QuickQanava/TableBorder.qml", - QQmlComponent::PreferSynchronous, nullptr); + const auto borderComponent = new QQmlComponent(engine, "qrc:/QuickQanava/TableBorder.qml", + QQmlComponent::PreferSynchronous, nullptr); qan::TableBorder* prevBorder = nullptr; if (verticalBordersCount != static_cast(_verticalBorders.size())) { @@ -300,10 +302,25 @@ auto TableGroupItem::createFromComponent(QQmlComponent& component) -> QQuickItem void TableGroupItem::initializeTableLayout() { - //qWarning() << "qan::TableGroupItem::initializeTableLayout()"; + qWarning() << "qan::TableGroupItem::initializeTableLayout(): tableGroup=" << getTableGroup(); const auto tableGroup = getTableGroup(); if (tableGroup == nullptr) return; + + // FIXME #238 Add more security: _previousSize ? no cells / bordesr created ? + + // FIXME #238 use height = getContainer()->height(). Secure that... + const auto tableContainer = getContainer(); + if (tableContainer == nullptr) + return; + const auto tableWidth = tableContainer->width(); + const auto tableHeight = tableContainer->height(); + const auto tableSize = tableContainer->size(); + qWarning() << " tableWidth=" << tableWidth << " tableHeight" << tableHeight; + + if (tableWidth <= 0 || tableHeight <= 0) + return; + const int cols = tableGroup->getCols(); const int rows = tableGroup->getRows(); const auto spacing = tableGroup != nullptr ? tableGroup->getCellSpacing() : @@ -320,17 +337,16 @@ void TableGroupItem::initializeTableLayout() return; } - const auto cellWidth = width() > 0. ? (width() + const auto cellWidth = tableWidth > 0. ? (tableWidth - (2 * padding) - ((cols - 1) * spacing)) / cols : 0.; - const auto cellHeight = height() > 0. ? (height() + const auto cellHeight = tableHeight > 0. ? (tableHeight - (2 * padding) - ((rows - 1) * spacing)) / rows : 0.; - //qWarning() << "cellWidth=" << cellWidth; - //qWarning() << "cellHeight=" << cellHeight; + qWarning() << " cellWidth=" << cellWidth << " cellHeight=" << cellHeight; if (cellWidth < 0. || cellHeight < 0.) { qWarning() << "qan::TableGroupItem::initializeTableLayout(): Error, invalid cell width/height."; @@ -355,7 +371,7 @@ void TableGroupItem::initializeTableLayout() verticalBorder->setX(x - borderWidth2); verticalBorder->setY(0.); verticalBorder->setWidth(borderWidth); - verticalBorder->setHeight(height()); + verticalBorder->setHeight(tableHeight); } } else qWarning() << "qan::TableGoupItem::initializeTableLayout(): Invalid vertical border count."; @@ -372,17 +388,21 @@ void TableGroupItem::initializeTableLayout() (spacing / 2.); horizontalBorder->setX(0.); horizontalBorder->setY(y - borderHeight2); - horizontalBorder->setWidth(width()); + horizontalBorder->setWidth(tableWidth); horizontalBorder->setHeight(borderHeight); } } else qWarning() << "qan::TableGoupItem::initializeTableLayout(): Invalid horizontal border count."; + // FIXME #238 unclear... // Note: There is no need to manually call borders layoutCells() method // it will be called automatically when border are moved. // Note 20230406: In fact calling layout cell is necessary for rows==1, cols==1 // table that need special handling to dimension cells since there is no horiz/vert borders. layoutCells(); + + // FIXME #238 set _previousSize here !!!! + _previousSize = tableSize; } void TableGroupItem::layoutTable() @@ -391,21 +411,32 @@ void TableGroupItem::layoutTable() // New position is: // x = previousX * (actualWidth / previousWidth) // y = previousY * (actualHeight / previousHeight) + const auto tableContainer = getContainer(); + qWarning() << "TableGroupItem::layoutTable(): tableContainer=" << tableContainer << " _previousSize=" << _previousSize; + if (tableContainer == nullptr) + return; + + const auto tableSize = tableContainer->size(); + const auto tableWidth = tableContainer->width(); + const auto tableHeight = tableContainer->height(); + + // FIXME #238 there must be a way to detect invalid size / init here and call initializeTableLayout()... + // Pheraps if _previousSize est null ? + if (_previousSize.isNull()) { - qWarning() << "qan::TableGroupItem::layoutTable(): Invalid initial size."; - _previousSize = size(); + //qWarning() << "qan::TableGroupItem::layoutTable(): Invalid initial size."; + initializeTableLayout(); return; - } - if (_previousSize == size()) + } else if (_previousSize == tableSize) return; for (const auto verticalBorder: _verticalBorders) { if (verticalBorder == nullptr) continue; const auto previousX = verticalBorder->x(); - verticalBorder->setX(qRound(previousX * width() / _previousSize.width())); + verticalBorder->setX(qRound(previousX * tableWidth / _previousSize.width())); verticalBorder->setY(0.); - verticalBorder->setHeight(height()); + verticalBorder->setHeight(tableHeight); } for (const auto horizontalBorder: _horizontalBorders) { @@ -413,11 +444,11 @@ void TableGroupItem::layoutTable() continue; const auto previousY = horizontalBorder->y(); horizontalBorder->setX(0.); - horizontalBorder->setY(qRound(previousY * height() / _previousSize.height())); - horizontalBorder->setWidth(width()); + horizontalBorder->setY(qRound(previousY * tableHeight / _previousSize.height())); + horizontalBorder->setWidth(tableWidth); } - _previousSize = size(); + _previousSize = tableSize; layoutCells(); } @@ -432,6 +463,12 @@ void TableGroupItem::layoutCells() horizontalBorder->layoutCells(); } + const auto tableContainer = getContainer(); + if (tableContainer == nullptr) + return; + const auto tableWidth = tableContainer->width(); + const auto tableHeight = tableContainer->height(); + // Special handling for 1 row or 1 column table: since there is // no "moveable" border, calls to layoutCells() do not set either width/height // of cells. Manually set correct width / height: @@ -444,13 +481,13 @@ void TableGroupItem::layoutCells() for (const auto cell: _cells) if (cell != nullptr) { cell->setX(padding); - cell->setWidth(width() - padding2); + cell->setWidth(tableWidth - padding2); } } if (tableGroup->getRows() == 1) { for (const auto cell: _cells) if (cell != nullptr) { - cell->setHeight(height() - padding2); + cell->setHeight(tableHeight - padding2); cell->setY(padding); } } From 517e296bf8afec375708de359c49915508fcb95c Mon Sep 17 00:00:00 2001 From: cneben Date: Mon, 12 Aug 2024 15:49:26 +0200 Subject: [PATCH 07/10] #238 Fix a very serious table layout bug + secure layout init. Signed-off-by: cneben --- src/qanTableGroupItem.cpp | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/qanTableGroupItem.cpp b/src/qanTableGroupItem.cpp index 19d4eb78..e43cd869 100644 --- a/src/qanTableGroupItem.cpp +++ b/src/qanTableGroupItem.cpp @@ -56,7 +56,7 @@ TableGroupItem::~TableGroupItem() bool TableGroupItem::setContainer(QQuickItem* container) noexcept { - qWarning() << "qan::TableGroupItem::setContainer(): container=" << container; + //qWarning() << "qan::TableGroupItem::setContainer(): container=" << container; if (qan::GroupItem::setContainer(container)) { // Note: Force reparenting all borders and cell to container, it might be nullptr // at initialization. @@ -105,7 +105,7 @@ void TableGroupItem::clearLayout() void TableGroupItem::initialize(int cols, int rows) { - qWarning() << "qan::TableGroupItem::initialize(): rows=" << rows << " cols=" << cols; + //qWarning() << "qan::TableGroupItem::initialize(): rows=" << rows << " cols=" << cols; if (rows <= 0 || cols <= 0) { qWarning() << "TableGroupItem::initialize(): Error, invalid rows or cols count."; return; @@ -302,23 +302,18 @@ auto TableGroupItem::createFromComponent(QQmlComponent& component) -> QQuickItem void TableGroupItem::initializeTableLayout() { - qWarning() << "qan::TableGroupItem::initializeTableLayout(): tableGroup=" << getTableGroup(); + //qWarning() << "qan::TableGroupItem::initializeTableLayout(): tableGroup=" << getTableGroup(); const auto tableGroup = getTableGroup(); if (tableGroup == nullptr) return; - // FIXME #238 Add more security: _previousSize ? no cells / bordesr created ? - - // FIXME #238 use height = getContainer()->height(). Secure that... const auto tableContainer = getContainer(); if (tableContainer == nullptr) return; const auto tableWidth = tableContainer->width(); const auto tableHeight = tableContainer->height(); const auto tableSize = tableContainer->size(); - qWarning() << " tableWidth=" << tableWidth << " tableHeight" << tableHeight; - - if (tableWidth <= 0 || tableHeight <= 0) + if (qRound(tableWidth) <= 0 || qRound(tableHeight) <= 0) return; const int cols = tableGroup->getCols(); @@ -346,7 +341,7 @@ void TableGroupItem::initializeTableLayout() - ((rows - 1) * spacing)) / rows : 0.; - qWarning() << " cellWidth=" << cellWidth << " cellHeight=" << cellHeight; + //qWarning() << " cellWidth=" << cellWidth << " cellHeight=" << cellHeight; if (cellWidth < 0. || cellHeight < 0.) { qWarning() << "qan::TableGroupItem::initializeTableLayout(): Error, invalid cell width/height."; @@ -394,15 +389,13 @@ void TableGroupItem::initializeTableLayout() } else qWarning() << "qan::TableGoupItem::initializeTableLayout(): Invalid horizontal border count."; - // FIXME #238 unclear... // Note: There is no need to manually call borders layoutCells() method // it will be called automatically when border are moved. // Note 20230406: In fact calling layout cell is necessary for rows==1, cols==1 // table that need special handling to dimension cells since there is no horiz/vert borders. layoutCells(); - // FIXME #238 set _previousSize here !!!! - _previousSize = tableSize; + _previousSize = tableSize; // Set a correct initial size } void TableGroupItem::layoutTable() @@ -412,7 +405,7 @@ void TableGroupItem::layoutTable() // x = previousX * (actualWidth / previousWidth) // y = previousY * (actualHeight / previousHeight) const auto tableContainer = getContainer(); - qWarning() << "TableGroupItem::layoutTable(): tableContainer=" << tableContainer << " _previousSize=" << _previousSize; + //qWarning() << "TableGroupItem::layoutTable(): tableContainer=" << tableContainer << " _previousSize=" << _previousSize; if (tableContainer == nullptr) return; @@ -420,11 +413,7 @@ void TableGroupItem::layoutTable() const auto tableWidth = tableContainer->width(); const auto tableHeight = tableContainer->height(); - // FIXME #238 there must be a way to detect invalid size / init here and call initializeTableLayout()... - // Pheraps if _previousSize est null ? - if (_previousSize.isNull()) { - //qWarning() << "qan::TableGroupItem::layoutTable(): Invalid initial size."; initializeTableLayout(); return; } else if (_previousSize == tableSize) @@ -434,7 +423,7 @@ void TableGroupItem::layoutTable() if (verticalBorder == nullptr) continue; const auto previousX = verticalBorder->x(); - verticalBorder->setX(qRound(previousX * tableWidth / _previousSize.width())); + verticalBorder->setX((previousX / _previousSize.width()) * tableWidth); verticalBorder->setY(0.); verticalBorder->setHeight(tableHeight); } @@ -444,7 +433,7 @@ void TableGroupItem::layoutTable() continue; const auto previousY = horizontalBorder->y(); horizontalBorder->setX(0.); - horizontalBorder->setY(qRound(previousY * tableHeight / _previousSize.height())); + horizontalBorder->setY((previousY / _previousSize.height()) * tableHeight); horizontalBorder->setWidth(tableWidth); } @@ -496,8 +485,6 @@ void TableGroupItem::layoutCells() bool TableGroupItem::setGroup(qan::Group* group) noexcept { if (qan::GroupItem::setGroup(group)) { - //qWarning() << "qan::TableGroupItem::setGroup(): group=" << group; - auto tableGroup = qobject_cast(group); if (tableGroup != nullptr) { initialize(tableGroup->getCols(), From 5c596d0bd2869b21ae830209373b497fe7936551 Mon Sep 17 00:00:00 2001 From: cneben Date: Mon, 12 Aug 2024 16:07:21 +0200 Subject: [PATCH 08/10] #238 use null coaellish operator everywhere. Signed-off-by: cneben --- src/Edge.qml | 2 +- src/EdgeCurvedPath.qml | 8 ++------ src/EdgeDstArrowPath.qml | 3 +-- src/EdgeDstCirclePath.qml | 5 +---- src/EdgeDstRectPath.qml | 3 +-- src/EdgeOrthoPath.qml | 6 ++---- src/EdgeSrcArrowPath.qml | 3 +-- src/EdgeSrcCirclePath.qml | 3 +-- src/EdgeSrcRectPath.qml | 4 +--- src/EdgeStraightPath.qml | 8 ++------ src/EdgeTemplate.qml | 9 ++++----- src/Group.qml | 5 ----- src/RectGlowEffect.qml | 10 +++------- src/RectGradientBackground.qml | 14 +++++++------- src/RectGroupTemplate.qml | 11 +++-------- src/RectNodeTemplate.qml | 4 ++-- src/RectShadowEffect.qml | 13 ++++--------- src/RectSolidBackground.qml | 8 ++++---- src/TableBorder.qml | 1 - 19 files changed, 40 insertions(+), 80 deletions(-) diff --git a/src/Edge.qml b/src/Edge.qml index 35d322a3..f1766b16 100644 --- a/src/Edge.qml +++ b/src/Edge.qml @@ -41,7 +41,7 @@ Qan.EdgeItem { id: edgeItem // Private hack for visual connector edge color dynamic modification - property color color: style ? style.lineColor : Qt.rgba(0.,0.,0.,1.) + property color color: style?.lineColor ?? Qt.rgba(0.,0.,0.,1.) Qan.EdgeTemplate { anchors.fill: parent edgeItem: parent diff --git a/src/EdgeCurvedPath.qml b/src/EdgeCurvedPath.qml index 49c662da..e7354653 100644 --- a/src/EdgeCurvedPath.qml +++ b/src/EdgeCurvedPath.qml @@ -45,14 +45,10 @@ ShapePath { startX: edgeItem.p1.x startY: edgeItem.p1.y capStyle: ShapePath.FlatCap - strokeWidth: edgeItem && - edgeItem.style ? edgeItem.style.lineWidth : - 2 + strokeWidth: edgeItem?.style?.lineWidth ?? 2 strokeColor: edgeTemplate.color strokeStyle: edgeTemplate.dashed - dashPattern: edgeItem && - edgeItem.style ? edgeItem.style.dashPattern : - [4, 2] + dashPattern: edgeItem?.style?.dashPattern ?? [4, 2] fillColor: Qt.rgba(0,0,0,0) PathCubic { x: edgeItem.p2.x diff --git a/src/EdgeDstArrowPath.qml b/src/EdgeDstArrowPath.qml index 4a7c89ee..6f1126b6 100644 --- a/src/EdgeDstArrowPath.qml +++ b/src/EdgeDstArrowPath.qml @@ -48,8 +48,7 @@ ShapePath { strokeWidth: 2 // Fix to 2 to have "non sharp" edges // Adding lineWidth / 2. to vertices A1 (base top) and A3 (base bottom) to take into // account lineWidth in arrowLength - readonly property real lineWidth: edgeItem?.style ? edgeItem.style.lineWidth / 2. : - 1 + readonly property real lineWidth: edgeItem?.style?.lineWidth / 2. ?? 1 startX: edgeItem ? edgeItem.dstA1.x : 0 startY: edgeItem ? edgeItem.dstA1.y - lineWidth: 0 PathLine { diff --git a/src/EdgeDstCirclePath.qml b/src/EdgeDstCirclePath.qml index f7f12037..8aff09d1 100644 --- a/src/EdgeDstCirclePath.qml +++ b/src/EdgeDstCirclePath.qml @@ -50,10 +50,7 @@ ShapePath { return Qt.rgba(0.,0.,0.,0.); return edgeTemplate ? edgeTemplate.color : Qt.rgba(0,0,0,1) } - strokeWidth: edgeItem && - edgeItem.style ? edgeItem.style.lineWidth : - 2 - + strokeWidth: edgeItem?.style?.lineWidth ?? 2 startX: 0 startY: 0 PathArc { diff --git a/src/EdgeDstRectPath.qml b/src/EdgeDstRectPath.qml index 08deb21f..4a5392de 100644 --- a/src/EdgeDstRectPath.qml +++ b/src/EdgeDstRectPath.qml @@ -44,8 +44,7 @@ ShapePath { strokeColor: edgeTemplate.color fillColor: edgeItem.dstShape === Qan.EdgeStyle.RectOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color - strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : - 2 + strokeWidth: edgeItem?.style?.lineWidth ?? 2 startX: edgeItem.dstA1.x startY: edgeItem.dstA1.y diff --git a/src/EdgeOrthoPath.qml b/src/EdgeOrthoPath.qml index 55729e2d..756b7032 100644 --- a/src/EdgeOrthoPath.qml +++ b/src/EdgeOrthoPath.qml @@ -45,12 +45,10 @@ ShapePath { startX: edgeItem.p1.x startY: edgeItem.p1.y capStyle: ShapePath.FlatCap - strokeWidth: edgeItem && - edgeItem.style ? edgeItem.style.lineWidth : - 2 + strokeWidth: edgeItem?.style?.lineWidth ?? 2 strokeColor: edgeTemplate.color strokeStyle: edgeTemplate.dashed - dashPattern: edgeItem.style ? edgeItem.style.dashPattern : [4, 2] + dashPattern: edgeItem?.style?.dashPattern ?? [4, 2] fillColor: Qt.rgba(0,0,0,0) PathLine { x: edgeItem.c1.x diff --git a/src/EdgeSrcArrowPath.qml b/src/EdgeSrcArrowPath.qml index 6ef68136..f011775b 100644 --- a/src/EdgeSrcArrowPath.qml +++ b/src/EdgeSrcArrowPath.qml @@ -45,8 +45,7 @@ ShapePath { fillColor: edgeItem && edgeItem.srcShape === Qan.EdgeStyle.ArrowOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color - strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : - 2 + strokeWidth: edgeItem?.style?.lineWidth ?? 2 startX: edgeItem.srcA1.x startY: edgeItem.srcA1.y PathLine { x: edgeItem.srcA3.x; y: edgeItem.srcA3.y } diff --git a/src/EdgeSrcCirclePath.qml b/src/EdgeSrcCirclePath.qml index e39c5c42..c08ecebb 100644 --- a/src/EdgeSrcCirclePath.qml +++ b/src/EdgeSrcCirclePath.qml @@ -44,8 +44,7 @@ ShapePath { strokeColor: edgeTemplate.color fillColor: edgeItem.srcShape === Qan.EdgeStyle.CircleOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color - strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : - 2 + strokeWidth: edgeItem?.style?.lineWidth ?? 2 startX: 0 startY: 0 diff --git a/src/EdgeSrcRectPath.qml b/src/EdgeSrcRectPath.qml index 468543a4..e7afda72 100644 --- a/src/EdgeSrcRectPath.qml +++ b/src/EdgeSrcRectPath.qml @@ -45,9 +45,7 @@ ShapePath { fillColor: edgeItem && edgeItem.srcShape === Qan.EdgeStyle.RectOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color - strokeWidth: edgeItem && - edgeItem.style ? edgeItem.style.lineWidth : - 2 + strokeWidth: edgeItem?.style?.lineWidth ?? 2 startX: edgeItem.srcA1.x startY: edgeItem.srcA1.y diff --git a/src/EdgeStraightPath.qml b/src/EdgeStraightPath.qml index 2878734f..02ed40d6 100644 --- a/src/EdgeStraightPath.qml +++ b/src/EdgeStraightPath.qml @@ -45,14 +45,10 @@ ShapePath { startX: edgeItem.p1.x startY: edgeItem.p1.y capStyle: ShapePath.FlatCap - strokeWidth: edgeItem && - edgeItem.style ? edgeItem.style.lineWidth : - 2 + strokeWidth: edgeItem?.style?.lineWidth ?? 2 strokeColor: edgeTemplate.color strokeStyle: edgeTemplate.dashed - dashPattern: edgeItem && - edgeItem.style ? edgeItem.style.dashPattern : - [2, 2] + dashPattern: edgeItem?.style?.dashPattern ?? [2, 2] fillColor: Qt.rgba(0,0,0,0) PathLine { x: edgeItem.p2.x diff --git a/src/EdgeTemplate.qml b/src/EdgeTemplate.qml index 1f6c36d9..5901779f 100644 --- a/src/EdgeTemplate.qml +++ b/src/EdgeTemplate.qml @@ -41,11 +41,10 @@ Item { id: edgeTemplate property var edgeItem: undefined - property color color: edgeItem && - edgeItem.style ? edgeItem.style.lineColor : Qt.rgba(0.,0.,0.,1.) + property color color: edgeItem?.style?.lineColor ?? Qt.rgba(0.,0.,0.,1.) // Allow direct bypass of style - property var lineType: edgeItem.style ? edgeItem.style.lineType : Qan.EdgeStyle.Straight - property var dashed : edgeItem.style && style.dashed ? ShapePath.DashLine : ShapePath.SolidLine + property var lineType: edgeItem?.style?.lineType ?? Qan.EdgeStyle.Straight + property var dashed : edgeItem?.style?.dashed ? ShapePath.DashLine : ShapePath.SolidLine visible: edgeItem.visible && !edgeItem.hidden @@ -139,7 +138,7 @@ Item { property var straightLine : undefined property var orthoLine : undefined property var lineType: edgeTemplate.lineType - property var lineWidth: edgeItem && edgeItem.style ? edgeItem.style.lineWidth + 2. : 4. + property var lineWidth: edgeItem?.style?.lineWidth + 2. ?? 4. property var lineColor: edgeItem && edgeItem.graph ? edgeItem.graph.selectionColor : Qt.rgba(0.1176, 0.5647, 1., 1.) // dodgerblue=rgb(30, 144, 255) diff --git a/src/Group.qml b/src/Group.qml index fab6d653..5920bed0 100644 --- a/src/Group.qml +++ b/src/Group.qml @@ -56,9 +56,4 @@ Qan.GroupItem { groupItem: parent z: 1 } - - // Emitted by qan::GroupItem when node dragging start - onNodeDragEnter: { template.onNodeDragEnter() } - // Emitted by qan::GroupItem when node dragging ends - onNodeDragLeave: { template.onNodeDragLeave() } } diff --git a/src/RectGlowEffect.qml b/src/RectGlowEffect.qml index 44cd7f7f..bce4226a 100644 --- a/src/RectGlowEffect.qml +++ b/src/RectGlowEffect.qml @@ -47,19 +47,15 @@ Item { property var style: undefined // PRIVATE //////////////////////////////////////////////////////////////// - // Default settings for rect radius, shadow margin is the _maximum_ shadow radius (+vertical or horizontal offset). - readonly property real glowRadius: style ? style.effectRadius : 3. - readonly property color glowColor: style ? style.effectColor : Qt.rgba(0.7, 0.7, 0.7, 0.7) - readonly property real borderWidth: style ? style.borderWidth : 1. - readonly property real borderWidth2: borderWidth / 2. - readonly property real backRadius: style ? style.backRadius : 4. + readonly property real glowRadius: style?.effectRadius ?? 3. + readonly property real backRadius: style?.backRadius ?? 4. Rectangle { // Hidden item used to generate shadow id: border anchors.fill: parent anchors.margins: 1 radius: backRadius - color: glowColor + color: style?.effectColor ?? Qt.rgba(0.7, 0.7, 0.7, 0.7) clip: true visible: false } diff --git a/src/RectGradientBackground.qml b/src/RectGradientBackground.qml index c9f68e1c..805436d3 100644 --- a/src/RectGradientBackground.qml +++ b/src/RectGradientBackground.qml @@ -43,7 +43,7 @@ import "qrc:/QuickQanava" as Qan Item { // PUBLIC ///////////////////////////////////////////////////////////////// property var style: undefined - property real backRadius: style ? style.backRadius : 4. + property real backRadius: style?.backRadius ?? 4. // PRIVATE //////////////////////////////////////////////////////////////// // Note: Top level item is used to isolate rendering of: @@ -56,18 +56,18 @@ Item { anchors.fill: parent radius: backRadius border.width: 0 // Do not draw border, just the background gradient (border is drawn in foreground) - opacity: style ? style.backOpacity : 0.8 + opacity: style?.backOpacity ?? 0.8 // Note 20240105: Unfortunately we no longer have LinearGradient with Qt6, switching to a // vertical gradient... gradient: Gradient { GradientStop { position: 0.0; - color: style ? style.baseColor: Qt.rgba(0., 0., 0., 0.) + color: style?.baseColor ?? Qt.rgba(0., 0., 0., 0.) } GradientStop { position: 1.0 - color: style ? style.backColor : Qt.rgba(0., 0., 0., 0.) + color: style?.backColor ?? Qt.rgba(0., 0., 0., 0.) } } } @@ -76,9 +76,9 @@ Item { anchors.fill: parent // Background follow the content layout implicit size radius: backRadius color: Qt.rgba(0, 0, 0, 0) // Fully transparent - border.color: style ? style.borderColor : Qt.rgba(1., 1., 1., 0.) - border.width: style ? style.borderWidth : 1. - //antialiasing: true // Vertex antialiasing for borders + border.color: style?.borderColor ?? Qt.rgba(1., 1., 1., 0.) + border.width: style?.borderWidth ?? 1. + antialiasing: true // Vertex antialiasing for borders // Note: Do not enable layer to avoid aliasing at high scale } } // Item diff --git a/src/RectGroupTemplate.qml b/src/RectGroupTemplate.qml index ef44c648..5f09ef95 100644 --- a/src/RectGroupTemplate.qml +++ b/src/RectGroupTemplate.qml @@ -96,7 +96,7 @@ Item { clip: false Layout.fillWidth: true Layout.fillHeight: true - property int labelPointSize : groupItem?.style?.fontPointSize || Material.fontSize + property int labelPointSize : groupItem?.style?.fontPointSize ?? Material.fontSize LabelEditor { id: labelEditor clip: false @@ -118,7 +118,7 @@ Item { verticalAlignment: Text.AlignVCenter font.bold: groupItem.style.fontBold font.pointSize: labelEditorControl.labelPointSize - color: groupItem?.style?.labelColor || "black" + color: groupItem?.style?.labelColor ?? "black" elide: Text.ElideRight TapHandler { enabled: !groupItem.group.isProtected && @@ -135,7 +135,7 @@ Item { Layout.margins: 0 height: 1 border.width: 0 - color: groupItem?.style?.borderColor || Qt.rgba(1., 1., 1., 0.) + color: groupItem?.style?.borderColor ?? Qt.rgba(1., 1., 1., 0.) opacity: 0.8 visible: !groupItem.collapsed } @@ -148,9 +148,4 @@ Item { enabled: !groupItem.collapsed } } - - // Emitted by qan::GroupItem when node dragging start - function onNodeDragEnter() { /*groupBackground.backColor = Qt.binding( function() { return Qt.darker( template.groupItem.style.backColor, 1.05 ) } ) */} - // Emitted by qan::GroupItem when node dragging ends - function onNodeDragLeave() { /*groupBackground.backColor = Qt.binding( function() { return template.groupItem.style.backColor } ) */} } diff --git a/src/RectNodeTemplate.qml b/src/RectNodeTemplate.qml index b5cd6b29..76bc82d5 100644 --- a/src/RectNodeTemplate.qml +++ b/src/RectNodeTemplate.qml @@ -36,7 +36,7 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import QuickQanava 2.0 as Qan +import QuickQanava 2.0 as Qan /*! \brief Default template component for building a custom rectangular qan::Node item. * @@ -61,7 +61,7 @@ Item { nodeItem.setDefaultBoundingShape() } - readonly property real backRadius: nodeItem?.style ? nodeItem.style.backRadius : 4. + readonly property real backRadius: nodeItem?.style?.backRadius ?? 4. Loader { id: delegateLoader anchors.fill: parent diff --git a/src/RectShadowEffect.qml b/src/RectShadowEffect.qml index fb9e94bc..cff296eb 100644 --- a/src/RectShadowEffect.qml +++ b/src/RectShadowEffect.qml @@ -48,13 +48,8 @@ Item { property var style: undefined // PRIVATE //////////////////////////////////////////////////////////////// - // Default settings for rect radius, shadow margin is the _maximum_ shadow radius (+vertical or horizontal offset). - readonly property real borderWidth: style ? style.borderWidth : 1. - readonly property real borderWidth2: borderWidth / 2. - readonly property real shadowOffset: style ? style.effectOffset : 3. - readonly property real shadowRadius: style ? style.effectRadius : 3. - readonly property color shadowColor: style ? style.effectColor : Qt.rgba(0.7, 0.7, 0.7, 0.7) - readonly property real backRadius: style ? style.backRadius : 4. + readonly property real shadowOffset: style?.effectOffset ?? 3. + readonly property real backRadius: style?.backRadius ?? 4. Rectangle { // Hidden item used to generate shadow id: border @@ -75,9 +70,9 @@ Item { parent.width + shadowOffset, parent.height + shadowOffset) shadowEnabled: shadowEffect.style?.effectEnabled || false - shadowColor: shadowColor + shadowColor: style?.effectColor ?? Qt.rgba(0.7, 0.7, 0.7, 0.7) shadowBlur: 0.9 - blurMax: shadowRadius + blurMax: style?.effectRadius ?? 3. shadowHorizontalOffset: shadowOffset shadowVerticalOffset: shadowOffset diff --git a/src/RectSolidBackground.qml b/src/RectSolidBackground.qml index 3f9b576c..3a575de0 100644 --- a/src/RectSolidBackground.qml +++ b/src/RectSolidBackground.qml @@ -46,11 +46,11 @@ Rectangle { property var style: undefined // PUBLIC ///////////////////////////////////////////////////////////////// - radius: style ? style.backRadius : 4. + radius: style?.backRadius ?? 4. color: style?.backColor || Qt.rgba(0., 0., 0., 0.) - border.color: style ? style.borderColor : Qt.rgba(0., 0., 0., 0.) - border.width: style ? style.borderWidth : 1.0 + border.color: style?.borderColor ?? Qt.rgba(0., 0., 0., 0.) + border.width: style?.borderWidth ?? 1.0 antialiasing: true // Vertex antialiasing - opacity: style ? style.backOpacity : 0.8 + opacity: style?.backOpacity ?? 0.8 // Note: Do not enable layer to avoid aliasing at high scale } diff --git a/src/TableBorder.qml b/src/TableBorder.qml index 33d52276..a05270ec 100644 --- a/src/TableBorder.qml +++ b/src/TableBorder.qml @@ -39,7 +39,6 @@ import "qrc:/QuickQanava" as Qan Qan.AbstractTableBorder { id: tableBorder - // FIXME #238 have a .? operator try here (but borderWidth might be 0.... borderWidth: tableGroup?.tableStyle?.borderWidth ?? 3. Rectangle { anchors.verticalCenter: parent.verticalCenter From 454ec18bddfb523fa863c8b38b136dd78e2f83ed Mon Sep 17 00:00:00 2001 From: cneben Date: Mon, 12 Aug 2024 16:18:19 +0200 Subject: [PATCH 09/10] #238 Documentation + table style handling cosmetic. Signed-off-by: cneben --- src/RectGroupTemplate.qml | 3 +-- src/TableBorder.qml | 4 ++-- src/qanDraggableCtrl.cpp | 2 -- src/qanGroupItem.h | 9 +++++++-- src/qanTableGroup.cpp | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/RectGroupTemplate.qml b/src/RectGroupTemplate.qml index 5f09ef95..92a41e17 100644 --- a/src/RectGroupTemplate.qml +++ b/src/RectGroupTemplate.qml @@ -130,10 +130,9 @@ Item { } // labelEditor Item } // RowLayout: collapser + label Rectangle { - // FIXME #238 do not show for tables... Layout.fillWidth: true Layout.margins: 0 - height: 1 + height: groupItem?.style?.borderWidth ?? 1. border.width: 0 color: groupItem?.style?.borderColor ?? Qt.rgba(1., 1., 1., 0.) opacity: 0.8 diff --git a/src/TableBorder.qml b/src/TableBorder.qml index a05270ec..74356aec 100644 --- a/src/TableBorder.qml +++ b/src/TableBorder.qml @@ -39,7 +39,7 @@ import "qrc:/QuickQanava" as Qan Qan.AbstractTableBorder { id: tableBorder - borderWidth: tableGroup?.tableStyle?.borderWidth ?? 3. + borderWidth: tableGroup?.style?.borderWidth ?? 3. Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter @@ -48,6 +48,6 @@ Qan.AbstractTableBorder { tableBorder.width height: tableBorder.orientation == Qt.Vertical ? tableBorder.height : tableBorder.borderWidth - color: tableGroup?.tableStyle?.borderColor ?? Qt.rgba(0., 0., 0., 1.) + color: tableGroup?.style?.borderColor ?? Qt.rgba(0., 0., 0., 1.) } } // Qan.AbstractTableBorder diff --git a/src/qanDraggableCtrl.cpp b/src/qanDraggableCtrl.cpp index 19804da1..56bcc76a 100644 --- a/src/qanDraggableCtrl.cpp +++ b/src/qanDraggableCtrl.cpp @@ -174,8 +174,6 @@ void DraggableCtrl::beginDragMove(const QPointF& sceneDragPos, bool dragSelec if (/*notify && */_target->isGroup()) { const auto groupItem = qobject_cast(_targetItem); const auto groupItemContainer = groupItem ? groupItem->getContainer() : nullptr; - // Convert sceneDragPos to group item local coordinates - // FIXME #238 //qWarning() << " groupItem=" << groupItem; //qWarning() << " groupItem->getContainer()=" << groupItemContainer; if (groupItem != nullptr && groupItemContainer != nullptr) { diff --git a/src/qanGroupItem.h b/src/qanGroupItem.h index b10988d8..398e7c37 100644 --- a/src/qanGroupItem.h +++ b/src/qanGroupItem.h @@ -121,7 +121,7 @@ class GroupItem : public qan::NodeItem /*! \name Dragging Support Management *///--------------------------------- //@{ public: - //! FIXME #238 + //! Define a group "dragging" policy: either only from group header or content (default to Header, can be or'ed). enum class DragPolicy : unsigned int { //! Undefined / No dragging. Undefined = 0, @@ -131,14 +131,19 @@ class GroupItem : public qan::NodeItem Container = 2 }; Q_ENUM(DragPolicy) - + //! \copydoc DragPolicy Q_PROPERTY(DragPolicy dragPolicy READ getDragPolicy WRITE setDragPolicy NOTIFY dragPolicyChanged FINAL) + //! \copydoc DragPolicy virtual bool setDragPolicy(DragPolicy dragPolicy) noexcept; + //! \copydoc DragPolicy DragPolicy getDragPolicy() noexcept; + //! \copydoc DragPolicy const DragPolicy getDragPolicy() const noexcept; protected: + //! \copydoc DragPolicy DragPolicy _dragPolicy = DragPolicy::Header; signals: + //! \copydoc DragPolicy void dragPolicyChanged(); diff --git a/src/qanTableGroup.cpp b/src/qanTableGroup.cpp index 35caf61c..2dbc2a71 100644 --- a/src/qanTableGroup.cpp +++ b/src/qanTableGroup.cpp @@ -78,7 +78,7 @@ qan::NodeStyle* TableGroup::style(QObject* parent) noexcept qan_TableGroup_style->setFontPointSize(11); qan_TableGroup_style->setFontBold(true); qan_TableGroup_style->setLabelColor(QColor{"black"}); - qan_TableGroup_style->setBorderWidth(2.); + qan_TableGroup_style->setBorderWidth(3.); qan_TableGroup_style->setBackRadius(8.); qan_TableGroup_style->setBackOpacity(0.90); qan_TableGroup_style->setBaseColor(QColor(240, 245, 250)); From 1814e154713007fadf70eda42e33a556df2f8f23 Mon Sep 17 00:00:00 2001 From: cneben Date: Mon, 12 Aug 2024 16:19:47 +0200 Subject: [PATCH 10/10] #238 cosmetic. Signed-off-by: cneben --- src/qanDraggableCtrl.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/qanDraggableCtrl.cpp b/src/qanDraggableCtrl.cpp index 56bcc76a..1f6d57f3 100644 --- a/src/qanDraggableCtrl.cpp +++ b/src/qanDraggableCtrl.cpp @@ -170,15 +170,11 @@ void DraggableCtrl::beginDragMove(const QPointF& sceneDragPos, bool dragSelec if (graph == nullptr) return; - // FIXME #238 multiple selection... - if (/*notify && */_target->isGroup()) { + if (notify && _target->isGroup()) { const auto groupItem = qobject_cast(_targetItem); const auto groupItemContainer = groupItem ? groupItem->getContainer() : nullptr; - //qWarning() << " groupItem=" << groupItem; - //qWarning() << " groupItem->getContainer()=" << groupItemContainer; if (groupItem != nullptr && groupItemContainer != nullptr) { const auto groupItemDragPos = groupItemContainer->mapFromScene(sceneDragPos); - //qWarning() << " groupItemDragPos=" << groupItemDragPos; bool drag = false; if ((groupItem->getDragPolicy() & qan::GroupItem::DragPolicy::Header) == qan::GroupItem::DragPolicy::Header) { if (groupItemDragPos.y() < 0) // Coords are in container CS