Added scrolling as well

This commit is contained in:
2025-08-03 20:29:04 +02:00
parent 34cc28897d
commit a423ceb669
2 changed files with 63 additions and 24 deletions

View File

@ -13,8 +13,7 @@ from .layout_manager import LayoutManager
from .widgets.base_widget import BaseWidget from .widgets.base_widget import BaseWidget
logging.basicConfig(level=logging.INFO, logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -62,35 +61,39 @@ class EditorManager:
and cls is not ModuleBaseWidget and cls is not ModuleBaseWidget
and cls.register and cls.register
): ):
logging.info( logging.info(f" -> Found and registered widget: {name}")
f" -> Found and registered widget: {name}")
self._register_widget(name, cls) self._register_widget(name, cls)
except Exception as e: except Exception as e:
logging.error(f"Failed to import widget '{py_file.name}': {e}") logging.error(f"Failed to import widget '{py_file.name}': {e}")
def _register_widget(self, name: str, widget_class: object): def _register_widget(self, name: str, widget_class: object):
if name in self.widget_classes: if name in self.widget_classes:
logging.warning( logging.warning(f"Widget '{name}' is already registered. Overwriting.")
f"Widget '{name}' is already registered. Overwriting.")
self.widget_classes[name] = widget_class self.widget_classes[name] = widget_class
def _add_widget(self, widget_type: str, config:dict = {}): def _add_widget(self, widget_type: str, config: dict = {}):
WidgetClass = self.widget_classes[widget_type] WidgetClass = self.widget_classes[widget_type]
instance = WidgetClass(self, logger) instance = WidgetClass(self, logger)
logger.info(f'Created instance: {str(instance)}') logger.info(f"Created instance: {str(instance)}")
self.widgets.append(instance) self.widgets.append(instance)
instance.create() instance.create()
instance.set_config(config) instance.set_config(config)
def _on_drag(self, sender, app_data, user_data): def _on_drag(self, sender, app_data, user_data):
self.bus.publish_deferred("mouse_dragged", { self.bus.publish_deferred(
"button": ( "mouse_dragged",
"right" {
if app_data[0] == 0 "button": (
else ("left" if app_data[0] == 1 else ("middle")) "right"
), if app_data[0] == 0
"delta": (app_data[1], app_data[2]) else ("left" if app_data[0] == 1 else ("middle"))
}) ),
"delta": (app_data[1], app_data[2]),
},
)
def _on_scroll(self, sender, app_data, user_data):
self.bus.publish_deferred("mouse_scrolled", app_data)
def setup(self): def setup(self):
self._discover_and_register_widgets( self._discover_and_register_widgets(
@ -107,11 +110,12 @@ class EditorManager:
label="Save Layout", callback=self.layout_manager.save_layout label="Save Layout", callback=self.layout_manager.save_layout
) )
dpg.add_menu_item( dpg.add_menu_item(
label="Run full-res pipeline", callback=lambda: self.bus.publish_deferred("process_full_res", None) label="Run full-res pipeline",
) callback=lambda: self.bus.publish_deferred(
dpg.add_menu_item( "process_full_res", None
label="Quit", callback=lambda: dpg.stop_dearpygui() ),
) )
dpg.add_menu_item(label="Quit", callback=lambda: dpg.stop_dearpygui())
with dpg.menu(label="View"): with dpg.menu(label="View"):
for widget_name in sorted(self.widget_classes.keys()): for widget_name in sorted(self.widget_classes.keys()):
@ -120,11 +124,18 @@ class EditorManager:
callback=lambda s, a, ud: self._add_widget(ud), callback=lambda s, a, ud: self._add_widget(ud),
user_data=widget_name, user_data=widget_name,
) )
with dpg.handler_registry() as self.handler_registry: with dpg.handler_registry() as self.handler_registry:
dpg.add_mouse_drag_handler(callback=self._on_drag, threshold=1.0, button=0) dpg.add_mouse_drag_handler(
dpg.add_mouse_drag_handler(callback=self._on_drag, threshold=1.0, button=1) callback=self._on_drag, threshold=1.0, button=0
dpg.add_mouse_drag_handler(callback=self._on_drag, threshold=1.0, button=2) )
dpg.add_mouse_drag_handler(
callback=self._on_drag, threshold=1.0, button=1
)
dpg.add_mouse_drag_handler(
callback=self._on_drag, threshold=1.0, button=2
)
dpg.add_mouse_wheel_handler(callback=self._on_scroll)
def run(self): def run(self):
self.setup() self.setup()

View File

@ -21,6 +21,7 @@ class PipelineStageViewer(PipelineStageWidget):
self.image_position = (0, 0) self.image_position = (0, 0)
self.manager.bus.subscribe("mouse_dragged", self._on_mouse_drag, False) self.manager.bus.subscribe("mouse_dragged", self._on_mouse_drag, False)
self.manager.bus.subscribe("mouse_scrolled", self._on_mouse_scroll, False)
def create_pipeline_stage_content(self): def create_pipeline_stage_content(self):
# Create an empty dynamic texture # Create an empty dynamic texture
@ -96,6 +97,33 @@ class PipelineStageViewer(PipelineStageWidget):
}, },
) )
def _on_mouse_scroll(self, data):
mouse_x, mouse_y = dpg.get_mouse_pos(local=False)
canvas_x, canvas_y = dpg.get_item_rect_min(self.drawlist)
local_x = mouse_x - canvas_x
local_y = mouse_y - canvas_y
img_x, img_y = self.image_position
img_w, img_h = self.scaled_size
if (
local_x >= img_x
and local_x < img_x + img_w
and local_y >= img_y
and local_y < img_y + img_h
):
# calculate the image coordinate
x = int((local_x - img_x) * self.img.shape[1] / img_w)
y = int((local_y - img_y) * self.img.shape[0] / img_h)
self.manager.bus.publish_deferred(
"img_scrolled",
{
"stage_id": self.pipeline_stage_in_id,
"pos": (x, y),
"delta": data
},
)
def on_resize(self, width, height): def on_resize(self, width, height):
self.needs_update = True self.needs_update = True