mirror of
https://github.com/1j01/textual-paint.git
synced 2025-01-02 20:04:36 +03:00
Use messages for selecting tools/colors/characters
It's more code, but hopefully separating concerns will be worth it.
This commit is contained in:
parent
cf9eb652a0
commit
f69f2f0009
59
paint.py
59
paint.py
@ -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:
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user