custom joint support
This commit is contained in:
@@ -37,7 +37,7 @@ import PySide6
|
||||
from PySide6.QtWidgets import (QApplication, QDoubleSpinBox, QFormLayout, QGraphicsItem, QGraphicsProxyWidget, QGraphicsTextItem, QLineEdit, QListWidget, QListWidgetItem, QMainWindow, QProgressDialog, QSizePolicy, QStyleOptionGraphicsItem, QTabBar, QWidget, QVBoxLayout, QGraphicsView, QGraphicsScene,
|
||||
QHBoxLayout, QSplitter, QLabel, QPushButton, QComboBox, QInputDialog, QGraphicsRectItem,
|
||||
QFileDialog, QScrollArea, QMessageBox, QSlider, QTextEdit, QGroupBox, QGridLayout, QCheckBox, QTabWidget, QProgressBar)
|
||||
from PySide6.QtCore import QEvent, Qt, QThread, Signal, QUrl, QRectF, QPointF, QRect, QSizeF, QTimer
|
||||
from PySide6.QtCore import QEvent, QObject, Qt, QThread, Signal, QUrl, QRectF, QPointF, QRect, QSizeF, QTimer
|
||||
from PySide6.QtGui import QCursor, QDoubleValidator, QGuiApplication, QPainter, QColor, QFont, QPen, QBrush, QAction, QKeySequence, QIcon, QTextOption, QImage, QPixmap, QTransform
|
||||
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput
|
||||
from PySide6.QtMultimediaWidgets import QGraphicsVideoItem
|
||||
@@ -3162,10 +3162,17 @@ from PySide6.QtWidgets import QGraphicsPathItem, QGraphicsSimpleTextItem
|
||||
from PySide6.QtWidgets import QGraphicsItem, QGraphicsSimpleTextItem, QInputDialog
|
||||
|
||||
|
||||
class BlockSignalProxy(QObject):
|
||||
nameChanged = Signal(str, str)
|
||||
|
||||
class PuzzleBlock(QGraphicsPathItem):
|
||||
|
||||
|
||||
def __init__(self, b_type, label, parent_item=None, fields=None):
|
||||
super().__init__(parent_item)
|
||||
|
||||
self.signals = BlockSignalProxy()
|
||||
|
||||
self.b_type = b_type # "begin", "middle", "end"
|
||||
self.label_text = label
|
||||
self.width = 160
|
||||
@@ -3322,8 +3329,7 @@ class PuzzleBlock(QGraphicsPathItem):
|
||||
if self.b_type == "begin":
|
||||
new_name, ok = QInputDialog.getText(None, "Rename Step", "Enter name:", text=self.label_text)
|
||||
if ok and new_name:
|
||||
self.label_text = new_name
|
||||
self.label_item.setText(new_name)
|
||||
self.finish_rename(new_name)
|
||||
super().mouseDoubleClickEvent(event)
|
||||
|
||||
|
||||
@@ -3383,6 +3389,20 @@ class PuzzleBlock(QGraphicsPathItem):
|
||||
return super().itemChange(change, value)
|
||||
|
||||
|
||||
def finish_rename(self, new_text):
|
||||
old_text = self.label_text
|
||||
print(f"[DEBUG - Block] Renaming '{old_text}' to '{new_text}'")
|
||||
|
||||
self.label_text = new_text
|
||||
if hasattr(self, 'label_item'):
|
||||
self.label_item.setText(new_text)
|
||||
|
||||
self.update()
|
||||
|
||||
if self.b_type == "begin":
|
||||
print(f"[DEBUG - Block] Emitting nameChanged signal...")
|
||||
self.signals.nameChanged.emit(old_text, new_text)
|
||||
|
||||
|
||||
class BlockLibrary(QListWidget):
|
||||
def __init__(self, parent_tab, stringy):
|
||||
@@ -3447,8 +3467,39 @@ class BlockLibrary(QListWidget):
|
||||
print(f"DEBUG: Drag finished with result: {result}")
|
||||
|
||||
|
||||
def add_dynamic_logic_item(self, block_item):
|
||||
"""
|
||||
Triggered when a 'begin' block is dropped on the canvas.
|
||||
Adds a corresponding 'logic' block to this library.
|
||||
"""
|
||||
# 1. Check for duplicates
|
||||
# We don't want to add "Joint 1" five times if they drag five 'begin' blocks
|
||||
|
||||
label = block_item.label_text
|
||||
|
||||
items = self.findItems(label, Qt.MatchExactly)
|
||||
for item in items:
|
||||
if item.data(Qt.UserRole) == "logic":
|
||||
print(f"DEBUG: {label} (logic) already exists in library. Skipping.")
|
||||
return
|
||||
|
||||
# 2. Add the item as a 'logic' type
|
||||
# In your system, logic blocks have no fields (they are just variables)
|
||||
print(f"DEBUG: Dynamically adding '{label}' as a logic block.")
|
||||
self.add_item(label, "logic", fields=[])
|
||||
|
||||
def update_item_name(self, old_name, new_name):
|
||||
print(f"[DEBUG - Library] Searching for items matching: '{old_name}'")
|
||||
items = self.findItems(old_name, Qt.MatchExactly)
|
||||
|
||||
if not items:
|
||||
print(f"[DEBUG - Library] No items found matching '{old_name}'")
|
||||
|
||||
for item in items:
|
||||
# Ensure we only rename the logic-type items
|
||||
if item.data(Qt.UserRole) == "logic":
|
||||
item.setText(new_name)
|
||||
print(f"[DEBUG - Library] Successfully updated sidebar item to '{new_name}'")
|
||||
|
||||
|
||||
from PySide6.QtWidgets import QGraphicsLineItem, QGraphicsRectItem, QGraphicsSimpleTextItem
|
||||
@@ -3456,12 +3507,40 @@ from PySide6.QtGui import QPen, QColor, QBrush
|
||||
|
||||
|
||||
class TopologyCanvas(QGraphicsView):
|
||||
|
||||
beginBlockDropped = Signal(object)
|
||||
|
||||
def __init__(self):
|
||||
self.scene = QGraphicsScene()
|
||||
super().__init__(self.scene)
|
||||
self.setAcceptDrops(True)
|
||||
self.block_library_ref = None
|
||||
self.scene.setSceneRect(0, 0, 2000, 2000)
|
||||
self.beginBlockDropped.connect(self.on_new_definition_created)
|
||||
|
||||
def on_new_definition_created(self, block_item):
|
||||
# Connect the block's rename signal to our canvas sync method
|
||||
print(f"[DEBUG - Canvas] Connecting signal for new block: {block_item.label_text}")
|
||||
block_item.signals.nameChanged.connect(self.sync_logic_blocks)
|
||||
|
||||
def sync_logic_blocks(self, old_name, new_name):
|
||||
print(f"[DEBUG - Canvas] Syncing. Old: {old_name}, New: {new_name}")
|
||||
|
||||
# 1. Update existing blocks on canvas (This is already working!)
|
||||
for item in self.scene.items():
|
||||
if isinstance(item, PuzzleBlock) and item.b_type == "logic":
|
||||
if item.label_text == old_name:
|
||||
item.label_text = new_name
|
||||
if hasattr(item, 'label_item'):
|
||||
item.label_item.setText(new_name)
|
||||
item.update()
|
||||
|
||||
# 2. Update Sidebar using the direct reference
|
||||
if self.block_library_ref:
|
||||
print("[DEBUG - Canvas] Found block_library_ref. Calling update...")
|
||||
self.block_library_ref.update_item_name(old_name, new_name)
|
||||
else:
|
||||
print("[DEBUG - Canvas] ERROR: block_library_ref is None. Ensure it is linked in main.py.")
|
||||
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
@@ -3546,6 +3625,9 @@ class TopologyCanvas(QGraphicsView):
|
||||
if not self.perform_snap(new_block, self.mapToScene(event.position().toPoint())):
|
||||
new_block.setPos(self.mapToScene(event.position().toPoint()))
|
||||
|
||||
if block_type == "begin":
|
||||
self.beginBlockDropped.emit(new_block)
|
||||
|
||||
event.acceptProposedAction()
|
||||
|
||||
|
||||
@@ -3958,6 +4040,10 @@ class ModelParameterConfigurationTab(QWidget):
|
||||
sidebar_layout = QVBoxLayout(sidebar_container)
|
||||
|
||||
self.block_library = BlockLibrary(parent_tab=self, stringy=self.mode)
|
||||
|
||||
self.canvas.block_library_ref = self.block_library
|
||||
|
||||
self.canvas.beginBlockDropped.connect(self.block_library.add_dynamic_logic_item)
|
||||
|
||||
# Reuse your existing Inspector logic
|
||||
self.inspector_scroll = QScrollArea()
|
||||
|
||||
Reference in New Issue
Block a user