refactor(dock): extract DockItem into items.py, remove TYPE_CHECKING

DockItem, DockModel, DockHitTest moved to items.py.
layout.py and animator.py now import directly — no circular deps.
This commit is contained in:
sankalp committed 2026-07-12 19:25:06 +05:45
1 parent 980734f465
commit 3142d70279
4 files changed
+85 -86

No files matched your search

+2 -5
View File
@@ -1,16 +1,13 @@
from typing import TYPE_CHECKING, Optional
from typing import Optional
from fabric.utils import GLib
from .constants import ANIM_INTERVAL_MS, IDLE_THRESHOLD, LERP_FACTOR
from .layout import DockLayout
if TYPE_CHECKING:
from .canvas import DockCanvas
class DockAnimator:
def __init__(self, canvas: "DockCanvas"):
def __init__(self, canvas):
self._canvas = canvas
self._timer_id: Optional[int] = None
self._running = False
+1 -74
View File
@@ -1,5 +1,4 @@
import math
from dataclasses import dataclass
from typing import Dict, List, Optional, Tuple
import cairo
@@ -52,81 +51,9 @@ from .constants import (
SEPARATOR_COLOR,
SEPARATOR_WIDTH,
)
from .items import DockHitTest, DockItem, DockModel
from .layout import DockLayout
@dataclass
class DockItem:
app_id: str
app_data: object
is_pinned: bool = False
is_trash: bool = False
is_running: bool = False
instance_address: Optional[str] = None
app_class: Optional[str] = None
client_data: Optional[dict] = None
workspace_id: Optional[int] = None
pixbuf: Optional[GdkPixbuf.Pixbuf] = None
tooltip: str = ""
current_scale: float = MIN_SCALE
target_scale: float = MIN_SCALE
render_x: float = 0.0
render_y: float = 0.0
render_w: float = 0.0
render_h: float = 0.0
drag_index: int = 0
is_dragging: bool = False
def hit(self, mx: float, my: float) -> bool:
return (
self.render_x <= mx <= self.render_x + self.render_w
and self.render_y <= my <= self.render_y + self.render_h
)
class DockModel:
def __init__(self):
self.items: List[DockItem] = []
def get_by_address(self, address: str) -> Optional[DockItem]:
for item in self.items:
if item.instance_address == address:
return item
return None
def get_by_id(self, app_id: str) -> Optional[DockItem]:
for item in self.items:
if item.app_id.lower() == app_id.lower():
return item
return None
def pinned_items(self) -> List[DockItem]:
return [i for i in self.items if i.is_pinned]
def running_only_items(self) -> List[DockItem]:
return [i for i in self.items if not i.is_pinned and not i.is_trash]
def has_running_only(self) -> bool:
return any(not i.is_pinned and not i.is_trash for i in self.items)
def has_pinned(self) -> bool:
return any(i.is_pinned for i in self.items)
class DockHitTest:
@staticmethod
def find_item(items: List[DockItem], mx: float, my: float) -> Optional[DockItem]:
for item in reversed(items):
if item.hit(mx, my):
return item
return None
_PIXBUF_CACHE_MAX = 64
+78
View File
@@ -0,0 +1,78 @@
from dataclasses import dataclass
from typing import Optional
from fabric.utils import GdkPixbuf
from .constants import MIN_SCALE
@dataclass
class DockItem:
app_id: str
app_data: object
is_pinned: bool = False
is_trash: bool = False
is_running: bool = False
instance_address: Optional[str] = None
app_class: Optional[str] = None
client_data: Optional[dict] = None
workspace_id: Optional[int] = None
pixbuf: Optional[GdkPixbuf.Pixbuf] = None
tooltip: str = ""
current_scale: float = MIN_SCALE
target_scale: float = MIN_SCALE
render_x: float = 0.0
render_y: float = 0.0
render_w: float = 0.0
render_h: float = 0.0
drag_index: int = 0
is_dragging: bool = False
def hit(self, mx: float, my: float) -> bool:
return (
self.render_x <= mx <= self.render_x + self.render_w
and self.render_y <= my <= self.render_y + self.render_h
)
class DockModel:
def __init__(self):
self.items: list[DockItem] = []
def get_by_address(self, address: str) -> Optional[DockItem]:
for item in self.items:
if item.instance_address == address:
return item
return None
def get_by_id(self, app_id: str) -> Optional[DockItem]:
for item in self.items:
if item.app_id.lower() == app_id.lower():
return item
return None
def pinned_items(self) -> list[DockItem]:
return [i for i in self.items if i.is_pinned]
def running_only_items(self) -> list[DockItem]:
return [i for i in self.items if not i.is_pinned and not i.is_trash]
def has_running_only(self) -> bool:
return any(not i.is_pinned and not i.is_trash for i in self.items)
def has_pinned(self) -> bool:
return any(i.is_pinned for i in self.items)
class DockHitTest:
@staticmethod
def find_item(items: list[DockItem], mx: float, my: float) -> Optional[DockItem]:
for item in reversed(items):
if item.hit(mx, my):
return item
return None
+4 -7
View File
@@ -1,5 +1,4 @@
import math
from typing import TYPE_CHECKING
from .constants import (
BG_PADDING_H,
@@ -10,15 +9,13 @@ from .constants import (
MIN_SCALE,
SIGMA_FACTOR,
)
if TYPE_CHECKING:
from .canvas import DockItem
from .items import DockItem
class DockLayout:
@staticmethod
def compute(
items: "list[DockItem]",
items: list[DockItem],
mouse_x: float,
_mouse_y: float,
base_icon_size: int,
@@ -72,11 +69,11 @@ class DockLayout:
@staticmethod
def background_rect(
items: "list[DockItem]",
items: list[DockItem],
base_icon_size: int,
canvas_w: int,
canvas_h: int,
) -> "tuple[float, float, float, float]":
) -> tuple[float, float, float, float]:
bg_h = base_icon_size + 2 * BG_PADDING_V
bg_y = canvas_h - INDICATOR_H - bg_h