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:
4 files changed
+85
-86
No files matched your search
@@ -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,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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in new issue
Block a user