Use messages for selecting tools/colors/characters

It's more code, but hopefully separating concerns will be worth it.
This commit is contained in:
Isaiah Odhner 2023-04-21 12:24:00 -04:00
parent cf9eb652a0
commit f69f2f0009

View File

@ -306,6 +306,12 @@ palette = [
class ToolsBox(Container): class ToolsBox(Container):
"""Widget containing tool buttons""" """Widget containing tool buttons"""
class ToolSelected(Message):
"""Message sent when a tool is selected."""
def __init__(self, tool: Tool) -> None:
self.tool = tool
super().__init__()
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
"""Add our buttons.""" """Add our buttons."""
for tool in Tool: for tool in Tool:
@ -314,18 +320,29 @@ class ToolsBox(Container):
button.can_focus = False button.can_focus = False
button.represented_tool = tool button.represented_tool = tool
yield button yield button
def on_button_pressed(self, event: Button.Pressed) -> None:
"""Called when a button is clicked."""
if "tool_button" in event.button.classes:
self.post_message(self.ToolSelected(event.button.represented_tool))
class CharInput(Input): class CharInput(Input):
"""Widget for entering a single character.""" """Widget for entering a single character."""
class CharSelected(Message):
"""Message sent when a character is selected."""
def __init__(self, char: str) -> None:
self.char = char
super().__init__()
def validate_value(self, value: str) -> str: def validate_value(self, value: str) -> str:
"""Limit the value to a single character.""" """Limit the value to a single character."""
return value[-1] if value else " " return value[-1] if value else " "
def watch_value(self, value: str) -> None: def watch_value(self, value: str) -> None:
"""Called when value changes.""" """Called when value changes."""
# TODO: use a Message instead of accessing the app directly self.post_message(self.CharSelected(value))
self.app.selected_char = value
def validate_cursor_position(self, position: int) -> int: def validate_cursor_position(self, position: int) -> int:
"""Force the cursor position to 0 so that it's over the character.""" """Force the cursor position to 0 so that it's over the character."""
@ -345,6 +362,12 @@ class CharInput(Input):
class ColorsBox(Container): class ColorsBox(Container):
"""Color palette widget.""" """Color palette widget."""
class ColorSelected(Message):
"""Message sent when a color is selected."""
def __init__(self, color: str) -> None:
self.color = color
super().__init__()
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
"""Add our selected color and color well buttons.""" """Add our selected color and color well buttons."""
with Container(id="palette_selection_box"): with Container(id="palette_selection_box"):
@ -360,6 +383,12 @@ class ColorsBox(Container):
button.represented_color = color button.represented_color = color
yield button yield button
def on_button_pressed(self, event: Button.Pressed) -> None:
"""Called when a button is clicked."""
if "color_button" in event.button.classes:
self.post_message(self.ColorSelected(event.button.represented_color))
debug_region_updates = False debug_region_updates = False
@ -1706,19 +1735,21 @@ class PaintApp(App):
def action_toggle_colors_box(self) -> None: def action_toggle_colors_box(self) -> None:
self.show_colors_box = not self.show_colors_box self.show_colors_box = not self.show_colors_box
def on_button_pressed(self, event: Button.Pressed) -> None: def on_tools_box_tool_selected(self, event: ToolsBox.ToolSelected) -> None:
"""Called when a button is clicked or activated with the keyboard.""" """Called when a tool is selected in the palette."""
self.selected_tool = event.tool
def on_char_input_char_selected(self, event: CharInput.CharSelected) -> None:
"""Called when a character is entered in the character input."""
self.selected_char = event.char
if "tool_button" in event.button.classes: def on_colors_box_color_selected(self, event: ColorsBox.ColorSelected) -> None:
self.selected_tool = event.button.represented_tool """Called when a color well is clicked in the palette."""
elif "color_button" in event.button.classes: # TODO: a way to select the foreground color
# TODO: a way to select the foreground color # if event.fg:
# Pressed event only gives the button that was pressed. # self.selected_fg_color = event.color
# Need to use MouseDown. # else:
# if event.shift: self.selected_bg_color = event.color
# self.selected_fg_color = event.button.represented_color
# else:
self.selected_bg_color = event.button.represented_color
def on_tree_node_highlighted(self, event: Tree.NodeHighlighted) -> None: def on_tree_node_highlighted(self, event: Tree.NodeHighlighted) -> None:
""" """