From 1fcd63ddeb3ad2a5ec46780d3f9e84cdcdb1dfb7 Mon Sep 17 00:00:00 2001 From: notify Date: Tue, 1 Aug 2023 11:39:54 +0800 Subject: [PATCH] Modmaker (#230) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 今天的积木就搭到这里吧 MOD Maker道阻且跻啊 --- Fk/ModMaker/Block/Block.qml | 154 ++++++++++++++++++++++++++++++++ Fk/ModMaker/Block/Workspace.qml | 79 ++++++++++++++++ Fk/ModMaker/ModInit.qml | 11 +++ src/ui/mod.cpp | 4 +- 4 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 Fk/ModMaker/Block/Block.qml create mode 100644 Fk/ModMaker/Block/Workspace.qml diff --git a/Fk/ModMaker/Block/Block.qml b/Fk/ModMaker/Block/Block.qml new file mode 100644 index 00000000..7f2b3925 --- /dev/null +++ b/Fk/ModMaker/Block/Block.qml @@ -0,0 +1,154 @@ +import QtQuick + +Item { + id: root + property var parentBlock + property var childBlocks: [] // nested blocks inside this block + property var currentStack: [ root ] // the block stack that root is in + property var workspace // workspace + + property bool draggable: false + property alias dragging: drag.active + property real startX // only available when dragging + property real startY + + // TMP + property int idx + function toString() { return "Block #" + idx.toString(); } + // TMP + + Rectangle { + id: rect + anchors.fill: parent + color: drag.active ? "grey" : "snow" + border.width: 1 + radius: 0 + } + + Text { + text: idx + } + + DragHandler { + id: drag + enabled: root.draggable + grabPermissions: PointHandler.TakeOverForbidden + xAxis.enabled: true + yAxis.enabled: true + } + + onDraggingChanged: { + if (!dragging) { + finishDrag(); + } else { + startDrag(); + } + } + + onXChanged: { + if (dragging) { + updateChildrenPos(); + } + } + + onYChanged: { + if (dragging) { + updateChildrenPos(); + } + } + + function getStackParent() { + const idx = currentStack.indexOf(root); + if (idx <= 0) { + return null; + } + return currentStack[idx - 1]; + } + + function getStackChildren() { + const idx = currentStack.indexOf(root); + if (idx >= currentStack.length - 1) { + return []; + } + return currentStack.slice(idx + 1); + } + + function startDrag() { + startX = x; + startY = y; + let children = getStackChildren(); + children.push(...childBlocks); + children.forEach(b => { + b.startX = b.x; + b.startY = b.y; + }); + } + + function updateChildrenPos() { + const dx = root.x - root.startX; + const dy = root.y - root.startY; + let children = getStackChildren(); + children.push(...childBlocks); + children.forEach(b => { + b.x = b.startX + dx; + b.y = b.startY + dy; + }); + } + + function finishDrag() { + if (currentStack[0] !== root) { + tearFrom(getStackParent()); + } + + if (parentBlock) { + tearFrom(parentBlock); + } + + if (workspace) { + workspace.arrangeBlock(root); + } + } + + function pasteTo(dest, asParent) { + x = dest.x; + y = dest.y + dest.height; + updateChildrenPos(); + + if (!asParent) { + const stk = currentStack; + dest.currentStack.push(...stk); + + const p = dest.parentBlock; + let c = getStackChildren(); + c.push(root); + c.forEach(cc => { + cc.parentBlock = p; + cc.currentStack = dest.currentStack; + }); + } else { + // TODO + } + } + + function tearFrom(dest) { + const fromParent = dest === root.parentBlock; + if (!fromParent) { + const idx = currentStack.indexOf(root); + const newStack = currentStack.slice(idx); + let c = getStackChildren(); + + currentStack.splice(idx); + + c.push(root); + c.forEach(cc => { + cc.parentBlock = null; + cc.currentStack = newStack; + }); + } else { + // TODO + } + } + + Component.onCompleted: { + } +} diff --git a/Fk/ModMaker/Block/Workspace.qml b/Fk/ModMaker/Block/Workspace.qml new file mode 100644 index 00000000..556a4e8e --- /dev/null +++ b/Fk/ModMaker/Block/Workspace.qml @@ -0,0 +1,79 @@ +import QtQuick +import QtQuick.Controls + +Item { + id: root + property var blockComponent + property var allBlocks: [] + + // ====== TMP ====== + property int idx: 0 + Row { + Button { + text: "quit" + onClicked: modStack.pop(); + } + Button { + text: "New" + onClicked: newBlock(); + } + Button { + text: "Del" + onClicked: rmFirstBlock_(); + } + } + + function newBlock() { + let obj = blockComponent.createObject(root, { + width: 50, height: 50, + x: Math.random() * root.width, y: Math.random() * root.height, + workspace: root, draggable: true, + idx: ++idx, + }); + allBlocks.push(obj); + } + + function rmFirstBlock_() { + let obj = allBlocks[0]; + if (!obj) return; + obj.destroy(); + allBlocks.splice(0,1); + } + // ====== TMP ====== + + function getPasteBlock(block) { + let ret; + let min = Infinity; + const x = block.x; + const y = block.y; + allBlocks.forEach(b => { + if (b === block) return; + let dx = Math.abs(b.x - x); + let dy = y - b.y - b.height; + let tot = dx + dy; + if (dx < 60 && dy < 60 && dy > 0 && tot < 100) { + if (min > tot) { + if (!allBlocks.find(bb => bb.x === b.x && bb.y === b.y + b.height)) { + ret = b; + min = tot; + } + } + } + }); + return ret; + } + + function showPasteBlock(block) { + } + + function arrangeBlock(block) { + let b = getPasteBlock(block); + if (b) { + block.pasteTo(b); + } + } + + Component.onCompleted: { + blockComponent = Qt.createComponent('Block.qml'); + } +} diff --git a/Fk/ModMaker/ModInit.qml b/Fk/ModMaker/ModInit.qml index 0b2c5be6..80a6b569 100644 --- a/Fk/ModMaker/ModInit.qml +++ b/Fk/ModMaker/ModInit.qml @@ -20,6 +20,17 @@ Item { horizontalAlignment: Qt.AlignHCenter Layout.fillWidth: true } + Button { + text: "Test" + onClicked: { + const component = Qt.createComponent("Block/Workspace.qml"); + if (component.status !== Component.Ready) { + return; + } + const page = component.createObject(null); + modStack.push(page); + } + } ToolButton { icon.source: AppPath + "/image/modmaker/menu" onClicked: { diff --git a/src/ui/mod.cpp b/src/ui/mod.cpp index 940c393e..e1d0a794 100644 --- a/src/ui/mod.cpp +++ b/src/ui/mod.cpp @@ -16,12 +16,12 @@ ModMaker::ModMaker(QObject *parent) : QObject(parent) { QDir(".").mkdir("mymod"); } - db = OpenDatabase("mymod/packages.db", "packages/mymod.sql"); + // db = OpenDatabase("mymod/packages.db", "packages/mymod.sql"); } ModMaker::~ModMaker() { // git_libgit2_shutdown(); - sqlite3_close(db); + // sqlite3_close(db); } // copied from https://stackoverflow.com/questions/1011572/convert-pem-key-to-ssh-rsa-format