Some small bugs fixed

This commit is contained in:
2025-08-01 21:24:54 +02:00
parent 8b4105a261
commit 430a3ac964
9 changed files with 114 additions and 39 deletions

BIN
negative_raw.nef Normal file

Binary file not shown.

BIN
negative_raw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 MiB

View File

@ -1,6 +1,8 @@
import threading
import queue
import logging
import inspect
import types
class EventBus:
@ -42,3 +44,14 @@ class EventBus:
callback(data)
except queue.Empty:
break
def unsubscribe_instance(self, instance):
for event_type, subs in list(self.subscribers.items()):
new_subs = []
for callback, main_thread in subs:
# if it's a bound method to our instance, skip it
if inspect.ismethod(callback) and callback.__self__ is instance:
continue
new_subs.append((callback, main_thread))
if len(new_subs) != len(subs):
self.subscribers[event_type] = new_subs

View File

@ -6,17 +6,19 @@ from .event_bus import EventBus
class ImagePipeline:
def __init__(self, bus: EventBus):
self.bus = bus
self.stages = []
self.id_counter = 0
self.stages = {}
self.stagedata = {}
def register_stage(self, name: str):
self.stages.append(name)
self.stagedata[name] = None
self.stages[self.id_counter] = name
self.stagedata[self.id_counter] = None
self.bus.publish_deferred("pipeline_stages", self.stages)
return len(self.stages) - 1
self.id_counter += 1
return self.id_counter-1
def rename_stage(self, id: int, name: str):
if id >= 0 and id < len(self.stages):
if id in self.stages:
self.stages[id] = name
self.bus.publish_deferred("pipeline_stages", self.stages)
@ -30,11 +32,16 @@ class ImagePipeline:
else:
return None
def get_stage_name(self, id:int):
def get_stage_name(self, id: int):
if id >= 0 and id < len(self.stages):
return self.stages[id]
return self.stages[id]
else:
return None
def republish_stages(self):
self.bus.publish_deferred("pipeline_stages", self.stages)
self.bus.publish_deferred("pipeline_stages", self.stages)
def remove_stage(self, id: int):
del self.stages[id]
del self.stagedata[id]
self.republish_stages()

View File

@ -12,7 +12,7 @@ from .layout_manager import LayoutManager
from .widgets.base_widget import BaseWidget
logging.basicConfig(level=logging.DEBUG,
logging.basicConfig(level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)
@ -76,6 +76,7 @@ class EditorManager:
def _add_widget(self, widget_type: str):
WidgetClass = self.widget_classes[widget_type]
instance = WidgetClass(self, logger)
logger.info(f'Created instance: {str(instance)}')
self.widgets.append(instance)
instance.create()

View File

@ -1,5 +1,6 @@
import dearpygui.dearpygui as dpg
import logging
import gc
from typing import TYPE_CHECKING
@ -40,9 +41,10 @@ class BaseWidget:
dpg.add_item_resize_handler(
callback=self._on_window_resize, parent=self.window_handler
)
dpg.bind_item_handler_registry(self.window_tag, self.window_handler)
self.create_content()
dpg.bind_item_handler_registry(self.window_tag, self.window_handler)
def create_content(self):
"""Must be implemented by the widget, creates the content of the window"""
@ -65,14 +67,24 @@ class BaseWidget:
# Callbacks
def _on_window_close(self):
try:
dpg.delete_item(self.window_tag)
self.manager.widgets.remove(self)
except ValueError:
pass
"""Some cleanup after closing a window"""
self.manager.bus.unsubscribe_instance(self)
dpg.delete_item(self.window_tag)
dpg.delete_item(self.window_handler)
self.manager.widgets.remove(self)
self.manager = None
self.logger = None
gc.collect()
def _on_window_resize(self, data):
win_w, win_h = dpg.get_item_rect_size(self.window_tag)
self.window_height = win_h
self.window_width = win_w
self.on_resize(win_w, win_h)
def __del__(self):
print("Widget deleted")

View File

@ -22,6 +22,7 @@ class PipelineStageWidget(BaseWidget):
self.pipeline_stage_in_id = None
self.pipeline_stage_out_id = None
self.pipeline_config_group_tag = dpg.generate_uuid()
self.stage_in_combo = dpg.generate_uuid()
if self.has_pipeline_out:
self.pipeline_stage_out_id = self.manager.pipeline.register_stage(
@ -38,11 +39,12 @@ class PipelineStageWidget(BaseWidget):
def create_content(self):
with dpg.group(tag=self.pipeline_config_group_tag):
if self.has_pipeline_in:
self.stage_in_combo = dpg.add_combo(
dpg.add_combo(
label="Stage In",
items=[],
callback=self._on_stage_in_select,
default_value=f"{self.manager.pipeline.get_stage_name(0)} : 0",
tag=self.stage_in_combo
)
if self.has_pipeline_out:
dpg.add_input_text(
@ -72,9 +74,14 @@ class PipelineStageWidget(BaseWidget):
# Callbacks
def _on_window_close(self):
if self.has_pipeline_out:
self.manager.pipeline.remove_stage(self.pipeline_stage_out_id)
return super()._on_window_close()
def _on_stage_list(self, stagelist):
if self.has_pipeline_in:
stages = [f"{stage} : {id}" for id, stage in enumerate(stagelist)]
stages = [f"{stage} : {id}" for id, stage in stagelist.items()]
dpg.configure_item(self.stage_in_combo, items=stages)
def _on_stage_in_select(self, sender, selected_stage: str):

View File

@ -32,6 +32,7 @@ class PipelineStageViewer(PipelineStageWidget):
def update_texture(self, img: np.ndarray):
"""Only call from update function"""
# TODO show a smaller version of the image to speed things up
if img is None:
dpg.configure_item(self.image_item, show=False)
return

View File

@ -1,6 +1,6 @@
[Window][WindowOverViewport_11111111]
Pos=0,19
Size=1109,809
Size=800,581
Collapsed=0
[Window][Debug##Default]
@ -20,9 +20,10 @@ Size=300,200
Collapsed=0
[Window][###34]
Pos=434,65
Size=300,200
Pos=0,480
Size=250,120
Collapsed=0
DockId=0x00000010,0
[Window][###33]
Pos=0,445
@ -50,9 +51,9 @@ DockId=0x00000008,0
[Window][###23]
Pos=0,19
Size=250,424
Size=250,459
Collapsed=0
DockId=0x0000000D,0
DockId=0x00000017,0
[Window][###32]
Pos=0,376
@ -84,20 +85,53 @@ Size=857,809
Collapsed=0
DockId=0x00000002,0
[Docking][Data]
DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1109,809 Split=X
DockNode ID=0x00000009 Parent=0x7C6B3D9B SizeRef=250,581 Split=Y Selected=0xD36850C8
DockNode ID=0x0000000B Parent=0x00000009 SizeRef=147,355 Split=Y Selected=0xD36850C8
DockNode ID=0x0000000D Parent=0x0000000B SizeRef=250,304 Selected=0xD36850C8
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=250,275 Selected=0x1834836D
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=147,224 Selected=0x2554AADD
DockNode ID=0x0000000A Parent=0x7C6B3D9B SizeRef=548,581 Split=X
DockNode ID=0x00000005 Parent=0x0000000A SizeRef=288,581 Split=Y Selected=0xEE087978
DockNode ID=0x00000007 Parent=0x00000005 SizeRef=147,427 Selected=0xEE087978
DockNode ID=0x00000008 Parent=0x00000005 SizeRef=147,152 Selected=0x62F4D00D
DockNode ID=0x00000006 Parent=0x0000000A SizeRef=510,581 Split=X
DockNode ID=0x00000001 Parent=0x00000006 SizeRef=299,581 Split=Y Selected=0xA4B861D9
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=299,379 Selected=0xA4B861D9
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=299,200 Selected=0xEDB425AD
DockNode ID=0x00000002 Parent=0x00000006 SizeRef=499,581 CentralNode=1 Selected=0x7FF1E0B5
[Window][###42]
Pos=252,19
Size=548,581
Collapsed=0
DockId=0x00000002,0
[Window][###57]
Pos=0,400
Size=250,200
Collapsed=0
DockId=0x00000018,0
[Window][###65]
Pos=0,400
Size=250,200
Collapsed=0
DockId=0x00000016,0
[Window][###73]
Pos=237,120
Size=300,200
Collapsed=0
[Docking][Data]
DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=800,581 Split=X
DockNode ID=0x00000009 Parent=0x7C6B3D9B SizeRef=250,581 Split=Y Selected=0xD36850C8
DockNode ID=0x0000000B Parent=0x00000009 SizeRef=147,355 Split=Y Selected=0xD36850C8
DockNode ID=0x0000000D Parent=0x0000000B SizeRef=250,304 Split=Y Selected=0xD36850C8
DockNode ID=0x0000000F Parent=0x0000000D SizeRef=250,459 Split=Y Selected=0xD36850C8
DockNode ID=0x00000011 Parent=0x0000000F SizeRef=250,379 Split=Y Selected=0xD36850C8
DockNode ID=0x00000013 Parent=0x00000011 SizeRef=250,379 Split=Y Selected=0xD36850C8
DockNode ID=0x00000015 Parent=0x00000013 SizeRef=250,379 Split=Y Selected=0xD36850C8
DockNode ID=0x00000017 Parent=0x00000015 SizeRef=250,379 Selected=0xD36850C8
DockNode ID=0x00000018 Parent=0x00000015 SizeRef=250,200 Selected=0x3BEDC6B0
DockNode ID=0x00000016 Parent=0x00000013 SizeRef=250,200 Selected=0xC7B9E77E
DockNode ID=0x00000014 Parent=0x00000011 SizeRef=250,200 Selected=0x3BEDC6B0
DockNode ID=0x00000012 Parent=0x0000000F SizeRef=250,200 Selected=0x83A5C17B
DockNode ID=0x00000010 Parent=0x0000000D SizeRef=250,120 Selected=0xAA145F7D
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=250,275 Selected=0x1834836D
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=147,224 Selected=0x2554AADD
DockNode ID=0x0000000A Parent=0x7C6B3D9B SizeRef=548,581 Split=X
DockNode ID=0x00000005 Parent=0x0000000A SizeRef=288,581 Split=Y Selected=0xEE087978
DockNode ID=0x00000007 Parent=0x00000005 SizeRef=147,427 Selected=0xEE087978
DockNode ID=0x00000008 Parent=0x00000005 SizeRef=147,152 Selected=0x62F4D00D
DockNode ID=0x00000006 Parent=0x0000000A SizeRef=510,581 Split=X
DockNode ID=0x00000001 Parent=0x00000006 SizeRef=299,581 Split=Y Selected=0xA4B861D9
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=299,379 Selected=0xA4B861D9
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=299,200 Selected=0xEDB425AD
DockNode ID=0x00000002 Parent=0x00000006 SizeRef=499,581 CentralNode=1 Selected=0x38519A65