Skip to content
Snippets Groups Projects

Refactor Cart into checkerboard table

Merged Mateusz Kudela requested to merge mkudela/issue-173 into develop
Compare and Show latest version
1 file
+ 33
35
Compare changes
  • Side-by-side
  • Inline
@@ -60,7 +60,7 @@ class CartItem(CliveCheckerboardTableRow, CliveWidget):
Binding("ctrl+down", "select_next", "Next"),
]
reactive_idx: reactive[int] = reactive(0)
reactive_idx: reactive[int] = reactive(0, init=False)
class Delete(Message):
def __init__(self, widget: CartItem) -> None:
@@ -68,18 +68,18 @@ class CartItem(CliveCheckerboardTableRow, CliveWidget):
super().__init__()
class Move(Message):
def __init__(self, from_idx: int, to_idx: int, focus_button: str | None) -> None:
def __init__(self, from_idx: int, to_idx: int, button_to_focus: str | None) -> None:
self.from_idx = from_idx
self.to_idx = to_idx
self.focus_button = focus_button
self.button_to_focus = button_to_focus
super().__init__()
class Focus(Message):
"""Message sent when other CartItem should be focused."""
def __init__(self, target_idx: int, focus_button: str | None) -> None:
def __init__(self, target_idx: int, button_to_focus: str | None) -> None:
self.target_idx = target_idx
self.focus_button = focus_button
self.button_to_focus = button_to_focus
super().__init__()
def __init__(self, operation_idx: int) -> None:
@@ -97,7 +97,7 @@ class CartItem(CliveCheckerboardTableRow, CliveWidget):
CliveCheckerBoardTableCell(self.get_operation_details(), classes="operation-details"),
CliveCheckerBoardTableCell(
Horizontal(
ButtonMoveUp(disabled=self.__is_first), ButtonMoveDown(disabled=self.__is_last), ButtonDelete()
ButtonMoveUp(disabled=self._is_first), ButtonMoveDown(disabled=self._is_last), ButtonDelete()
),
classes="actions",
),
@@ -108,9 +108,9 @@ class CartItem(CliveCheckerboardTableRow, CliveWidget):
def on_mount(self) -> None:
self.reactive_idx = self._idx
if self.__is_first:
if self._is_first:
self.unbind("ctrl+up")
elif self.__is_last:
elif self._is_last:
self.unbind("ctrl+down")
def watch_reactive_idx(self, idx: int) -> None:
@@ -119,24 +119,24 @@ class CartItem(CliveCheckerboardTableRow, CliveWidget):
self._index_cell.update_content(self.get_operation_index())
def is_valid(self, idx: int) -> bool:
return idx < self.__operations_count
return idx < self._operations_count
def get_operation_index(self) -> str:
return f"{self._idx + 1}." if self.is_valid(self.idx) else "?"
return f"{self._idx + 1}." if self.is_valid(self._idx) else "?"
def get_operation_name(self) -> str:
return humanize_operation_name(self.operation) if self.is_valid(self.idx) else "?"
return humanize_operation_name(self.operation) if self.is_valid(self._idx) else "?"
def action_select_previous(self) -> None:
focused = self.get_focused_button_or_none()
self.post_message(self.Focus(target_idx=self._idx - 1, focus_button=focused))
self.post_message(self.Focus(target_idx=self._idx - 1, button_to_focus=focused))
def action_select_next(self) -> None:
focused = self.get_focused_button_or_none()
self.post_message(self.Focus(target_idx=self._idx + 1, focus_button=focused))
self.post_message(self.Focus(target_idx=self._idx + 1, button_to_focus=focused))
def get_operation_details(self) -> str:
return humanize_operation_details(self.operation) if self.is_valid(self.idx) else "?"
return humanize_operation_details(self.operation) if self.is_valid(self._idx) else "?"
def get_focused_button_or_none(self) -> str | None:
buttons = self.query(CliveButton)
@@ -145,36 +145,32 @@ class CartItem(CliveCheckerboardTableRow, CliveWidget):
return button.id
return None
@property
def idx(self) -> int:
return self._idx
@property
def operation(self) -> OperationBaseClass:
assert self.is_valid(self._idx), "cannot get operation, position is invalid"
return self.profile.cart[self._idx]
@property
def __operations_count(self) -> int:
def _operations_count(self) -> int:
return len(self.profile.cart)
@property
def __is_first(self) -> bool:
def _is_first(self) -> bool:
return self._idx == 0
@property
def __is_last(self) -> bool:
return self._idx == self.__operations_count - 1
def _is_last(self) -> bool:
return self._idx == self._operations_count - 1
@on(CliveButton.Pressed, "#move-up-button")
def move_up(self) -> None:
focused = self.get_focused_button_or_none()
self.post_message(self.Move(from_idx=self._idx, to_idx=self._idx - 1, focus_button=focused))
self.post_message(self.Move(from_idx=self._idx, to_idx=self._idx - 1, button_to_focus=focused))
@on(CliveButton.Pressed, "#move-down-button")
def move_down(self) -> None:
focused = self.get_focused_button_or_none()
self.post_message(self.Move(from_idx=self._idx, to_idx=self._idx + 1, focus_button=focused))
self.post_message(self.Move(from_idx=self._idx, to_idx=self._idx + 1, button_to_focus=focused))
@on(CliveButton.Pressed, "#delete-button")
def delete(self) -> None:
@@ -215,6 +211,14 @@ class CartTable(CliveCheckerboardTable):
]
return self._rows
def _disable_appropriate_button(self, widget: CartItem) -> None:
if len(self.app.world.profile.cart) > 0 and widget.reactive_idx == 0:
# disable first ButtomMoveUp if first element was removed
self.query(ButtonMoveUp)[0].disabled = True
if 0 < len(self.app.world.profile.cart) == widget.reactive_idx:
# disable last ButtonMoveDown if only last element was removed
self.query(ButtonMoveDown)[-1].disabled = True
def _handle_remove_event(self, triggering_widget: CartItem) -> None:
def devalue_indexes(rows: Sequence[CartItem]) -> None:
for row in rows:
@@ -247,13 +251,7 @@ class CartTable(CliveCheckerboardTable):
self.profile.cart.remove(event.widget.operation)
self._handle_remove_event(triggering_widget=event.widget)
self.app.trigger_profile_watchers()
if len(self.app.world.profile.cart) > 0 and event.widget.reactive_idx == 0:
# disable first ButtomMoveUp if first element was removed
self.query(ButtonMoveUp)[0].disabled = True
if 0 < len(self.app.world.profile.cart) == event.widget.reactive_idx:
# disable last ButtonMoveDown if only last element was removed
self.query(ButtonMoveDown)[-1].disabled = True
self._disable_appropriate_button(event.widget)
@on(CartItem.Move)
async def move_item(self, event: CartItem.Move) -> None:
@@ -267,16 +265,16 @@ class CartTable(CliveCheckerboardTable):
for cart_item in self._rows:
if event.to_idx == cart_item.reactive_idx:
self.app.set_focus(cart_item)
if event.focus_button:
cart_item.query_one(f"#{event.focus_button}").focus()
if event.button_to_focus:
cart_item.query_one(f"#{event.button_to_focus}").focus()
@on(CartItem.Focus)
def focus_item(self, event: CartItem.Focus) -> None:
for cart_item in self._rows:
if event.target_idx == cart_item.reactive_idx:
self.app.set_focus(cart_item)
if event.focus_button:
cart_item.query_one(f"#{event.focus_button}").focus()
if event.button_to_focus:
cart_item.query_one(f"#{event.button_to_focus}").focus()
class Cart(BaseScreen):
Loading