diff --git a/src/app/dragdrop.py b/src/app/dragdrop.py index bc8404906..f7b8b25b5 100644 --- a/src/app/dragdrop.py +++ b/src/app/dragdrop.py @@ -8,12 +8,14 @@ import abc from srctools.logger import get_logger + from trio_util import AsyncValue, RepeatedEvent import attrs from app import img, sound from async_util import EdgeTrigger from transtoken import TransToken +import utils __all__ = [ @@ -21,13 +23,14 @@ 'InfoCB', 'DragWin', 'FlexiCB', 'in_bbox', ] LOGGER = get_logger(__name__) +type Group = utils.SpecialID @attrs.frozen class DragInfo: """The information required to display drag/drop items.""" icon: img.Handle - group: str | None = None + group: Group | None = None # Set to the same as icon if not passed. group_icon: img.Handle = attrs.Factory(lambda self: self.icon, takes_self=True) @@ -318,14 +321,14 @@ def _display_item( image = self._info_cb(item).icon self._ui_set_icon(slot, image) - def _group_update(self, group: str | None) -> None: + def _group_update(self, slot_type: SlotType, group: Group | None) -> None: """Update all target items with this group.""" if group is None: # None to do. return group_slots = [ slot for slot in self._slots - if not slot.is_source + if slot.kind is slot_type if slot.contents_group == group ] @@ -480,7 +483,7 @@ class Slot[ItemT]: _contents: ItemT | None # The kind of slot. - type: SlotType + kind: SlotType man: ManagerBase[ItemT, Any] # Our drag/drop controller. def __init__(self, man: ManagerBase[ItemT, Any], kind: SlotType) -> None: @@ -535,17 +538,14 @@ def contents(self, value: ItemT | None) -> None: # Then set us. self._contents = value - if self.is_target: - # Update items in the previous group, so they gain the group icon - # if only one now exists. - if old_cont is not None: - self.man._group_update(self.man._info_cb(old_cont).group) - if value is not None: - new_group = self.man._info_cb(value).group - else: - new_group = None + # Update items in the previous group, so they gain the group icon + # if only one now exists. + if old_cont is not None: + self.man._group_update(self.kind, self.man._info_cb(old_cont).group) + + if value is not None: + new_group = self.man._info_cb(value).group else: - # Source pickers never group items. new_group = None if self.is_flexi and (old_cont is None) != (value is None): @@ -555,13 +555,13 @@ def contents(self, value: ItemT | None) -> None: if new_group is not None: # Update myself and the entire group to get the group # icon if required. - self.man._group_update(new_group) + self.man._group_update(self.kind, new_group) else: # Just update myself. self.man._display_item(self, value) @property - def contents_group(self) -> str | None: + def contents_group(self) -> Group | None: """If the item in this slot has a group, return it.""" if self._contents is not None: return self.man._info_cb(self._contents).group diff --git a/src/ui_tk/demo/dragdrop.py b/src/ui_tk/demo/dragdrop.py index 34e2d0bba..754c2cb8b 100644 --- a/src/ui_tk/demo/dragdrop.py +++ b/src/ui_tk/demo/dragdrop.py @@ -57,7 +57,7 @@ def demo_item( name: str, pak_id: utils.ObjectID, icon: str, - group: str | None = None, + group: utils.SpecialID | None = None, group_icon: str | None = None, ) -> str: """Simple implementation of the DND protocol.""" @@ -83,6 +83,8 @@ def demo_item( PAK_CLEAN = utils.obj_id('BEE2_CLEAN_STYLE') PAK_ELEM = utils.obj_id('VALVE_TEST_ELEM') + GROUP_CUBE = utils.obj_id('ITEM_CUBE') + GROUP_SPLAT = utils.obj_id('ITEM_CUBE') items = [ demo_item('Dropper', PAK_CLEAN, 'dropper'), demo_item('Entry', PAK_CLEAN, 'entry_door'), @@ -90,17 +92,17 @@ def demo_item( demo_item('Large Obs', PAK_CLEAN, 'large_obs_room'), demo_item('Faith Plate', PAK_ELEM, 'faithplate'), - demo_item('Standard Cube', PAK_ELEM, 'cube', 'ITEM_CUBE', 'cubes'), - demo_item('Companion Cube', PAK_ELEM, 'companion_cube', 'ITEM_CUBE', 'cubes'), - demo_item('Reflection Cube', PAK_ELEM, 'reflection_cube', 'ITEM_CUBE', 'cubes'), - demo_item('Edgeless Cube', PAK_ELEM, 'edgeless_safety_cube', 'ITEM_CUBE', 'cubes'), - demo_item('Franken Cube', PAK_ELEM, 'frankenturret', 'ITEM_CUBE', 'cubes'), - - demo_item('Repulsion Gel', PAK_ELEM, 'paintsplat_bounce', 'ITEM_PAINT_SPLAT', 'paints'), - demo_item('Propulsion Gel', PAK_ELEM, 'paintsplat_speed', 'ITEM_PAINT_SPLAT', 'paints'), - demo_item('Reflection Gel', PAK_ELEM, 'paintsplat_reflection', 'ITEM_PAINT_SPLAT', 'paints'), - demo_item('Conversion Gel', PAK_ELEM, 'paintsplat_portal', 'ITEM_PAINT_SPLAT', 'paints'), - demo_item('Cleansing Gel', PAK_ELEM, 'paintsplat_water', 'ITEM_PAINT_SPLAT', 'paints'), + demo_item('Standard Cube', PAK_ELEM, 'cube', GROUP_CUBE, 'cubes'), + demo_item('Companion Cube', PAK_ELEM, 'companion_cube', GROUP_CUBE, 'cubes'), + demo_item('Reflection Cube', PAK_ELEM, 'reflection_cube', GROUP_CUBE, 'cubes'), + demo_item('Edgeless Cube', PAK_ELEM, 'edgeless_safety_cube', GROUP_CUBE, 'cubes'), + demo_item('Franken Cube', PAK_ELEM, 'frankenturret', GROUP_CUBE, 'cubes'), + + demo_item('Repulsion Gel', PAK_ELEM, 'paintsplat_bounce', GROUP_SPLAT, 'paints'), + demo_item('Propulsion Gel', PAK_ELEM, 'paintsplat_speed', GROUP_SPLAT, 'paints'), + demo_item('Reflection Gel', PAK_ELEM, 'paintsplat_reflection', GROUP_SPLAT, 'paints'), + demo_item('Conversion Gel', PAK_ELEM, 'paintsplat_portal', GROUP_SPLAT, 'paints'), + demo_item('Cleansing Gel', PAK_ELEM, 'paintsplat_water', GROUP_SPLAT, 'paints'), ] for y in range(8): diff --git a/src/ui_tk/item_picker.py b/src/ui_tk/item_picker.py index efc70da80..9fb148eb0 100644 --- a/src/ui_tk/item_picker.py +++ b/src/ui_tk/item_picker.py @@ -26,7 +26,7 @@ class ItemPicker(ItemPickerBase[tk.Misc]): def __init__( self, pal_frame: tk.Frame, - picker_frame: tk.Frame, + picker_frame: ttk.Frame, selected_style: AsyncValue[utils.SpecialID], ) -> None: super().__init__(selected_style) diff --git a/src/ui_wx/demo/dragdrop.py b/src/ui_wx/demo/dragdrop.py index d9abcdff6..fa6fb3d08 100644 --- a/src/ui_wx/demo/dragdrop.py +++ b/src/ui_wx/demo/dragdrop.py @@ -65,7 +65,7 @@ def demo_item( name: str, pak_id: utils.ObjectID, icon: str, - group: str | None = None, + group: utils.SpecialID | None = None, group_icon: str | None = None, ) -> str: """Simple implementation of the DND protocol.""" @@ -91,6 +91,8 @@ def demo_item( PAK_CLEAN = utils.obj_id('BEE2_CLEAN_STYLE') PAK_ELEM = utils.obj_id('VALVE_TEST_ELEM') + GROUP_CUBE = utils.obj_id('ITEM_CUBE') + GROUP_SPLAT = utils.obj_id('ITEM_CUBE') items = [ demo_item('Dropper', PAK_CLEAN, 'dropper'), demo_item('Entry', PAK_CLEAN, 'entry_door'), @@ -98,17 +100,17 @@ def demo_item( demo_item('Large Obs', PAK_CLEAN, 'large_obs_room'), demo_item('Faith Plate', PAK_ELEM, 'faithplate'), - demo_item('Standard Cube', PAK_ELEM, 'cube', 'ITEM_CUBE', 'cubes'), - demo_item('Companion Cube', PAK_ELEM, 'companion_cube', 'ITEM_CUBE', 'cubes'), - demo_item('Reflection Cube', PAK_ELEM, 'reflection_cube', 'ITEM_CUBE', 'cubes'), - demo_item('Edgeless Cube', PAK_ELEM, 'edgeless_safety_cube', 'ITEM_CUBE', 'cubes'), - demo_item('Franken Cube', PAK_ELEM, 'frankenturret', 'ITEM_CUBE', 'cubes'), - - demo_item('Repulsion Gel', PAK_ELEM, 'paintsplat_bounce', 'ITEM_PAINT_SPLAT', 'paints'), - demo_item('Propulsion Gel', PAK_ELEM, 'paintsplat_speed', 'ITEM_PAINT_SPLAT', 'paints'), - demo_item('Reflection Gel', PAK_ELEM, 'paintsplat_reflection', 'ITEM_PAINT_SPLAT', 'paints'), - demo_item('Conversion Gel', PAK_ELEM, 'paintsplat_portal', 'ITEM_PAINT_SPLAT', 'paints'), - demo_item('Cleansing Gel', PAK_ELEM, 'paintsplat_water', 'ITEM_PAINT_SPLAT', 'paints'), + demo_item('Standard Cube', PAK_ELEM, 'cube', GROUP_CUBE, 'cubes'), + demo_item('Companion Cube', PAK_ELEM, 'companion_cube', GROUP_CUBE, 'cubes'), + demo_item('Reflection Cube', PAK_ELEM, 'reflection_cube', GROUP_CUBE, 'cubes'), + demo_item('Edgeless Cube', PAK_ELEM, 'edgeless_safety_cube', GROUP_CUBE, 'cubes'), + demo_item('Franken Cube', PAK_ELEM, 'frankenturret', GROUP_CUBE, 'cubes'), + + demo_item('Repulsion Gel', PAK_ELEM, 'paintsplat_bounce', GROUP_SPLAT, 'paints'), + demo_item('Propulsion Gel', PAK_ELEM, 'paintsplat_speed', GROUP_SPLAT, 'paints'), + demo_item('Reflection Gel', PAK_ELEM, 'paintsplat_reflection', GROUP_SPLAT, 'paints'), + demo_item('Conversion Gel', PAK_ELEM, 'paintsplat_portal', GROUP_SPLAT, 'paints'), + demo_item('Cleansing Gel', PAK_ELEM, 'paintsplat_water', GROUP_SPLAT, 'paints'), ] sizer_left = wx.GridSizer(4, 8, 15)