Refactor keybindings and footer management: streamline keybinding processing and enhance footer item display with key-description pairs for improved clarity and usability.
This commit is contained in:
parent
3f0892fb7b
commit
6107b43ac5
3 changed files with 133 additions and 24 deletions
|
@ -147,26 +147,27 @@ class HostsManagerApp(App):
|
|||
|
||||
# Process keybindings and add to appropriate sections
|
||||
for binding in self.BINDINGS:
|
||||
# Skip tuple-style bindings and only process Binding objects
|
||||
if not hasattr(binding, "show"):
|
||||
continue
|
||||
|
||||
# Only show bindings marked with show=True
|
||||
if hasattr(binding, "show") and binding.show:
|
||||
if binding.show:
|
||||
# Get the display key
|
||||
key_display = getattr(binding, "key_display", None) or binding.key
|
||||
|
||||
# Get the description
|
||||
description = binding.description or binding.action
|
||||
|
||||
# Format the item
|
||||
item = f"{key_display}: {description}"
|
||||
|
||||
# Determine positioning from id attribute
|
||||
binding_id = getattr(binding, "id", None)
|
||||
if binding_id and binding_id.startswith("left:"):
|
||||
footer.add_left_item(item)
|
||||
footer.add_left_item(key_display, description)
|
||||
elif binding_id and binding_id.startswith("right:"):
|
||||
footer.add_right_item(item)
|
||||
footer.add_right_item(key_display, description)
|
||||
else:
|
||||
# Default to right if no specific positioning
|
||||
footer.add_right_item(item)
|
||||
footer.add_right_item(key_display, description)
|
||||
|
||||
# Status section will be updated by update_status
|
||||
self._update_footer_status()
|
||||
|
|
|
@ -11,6 +11,42 @@ from textual.app import ComposeResult
|
|||
from textual.containers import Horizontal
|
||||
from textual.widgets import Static
|
||||
from textual.widget import Widget
|
||||
from rich.text import Text
|
||||
|
||||
|
||||
class FooterKey(Widget):
|
||||
"""A key/action pair widget for the footer, styled similar to Textual's original FooterKey."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
FooterKey {
|
||||
width: auto;
|
||||
height: 1;
|
||||
content-align: center middle;
|
||||
padding: 0 1;
|
||||
}
|
||||
|
||||
.footer-key--key {
|
||||
text-style: bold;
|
||||
color: $text;
|
||||
}
|
||||
|
||||
.footer-key--description {
|
||||
color: $text-muted;
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, key: str, description: str, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.key = key
|
||||
self.description = description
|
||||
|
||||
def render(self) -> Text:
|
||||
"""Render the key-description pair with proper styling."""
|
||||
text = Text()
|
||||
text.append(f"{self.key}", style="bold")
|
||||
text.append(" ")
|
||||
text.append(self.description, style="dim")
|
||||
return text
|
||||
|
||||
|
||||
class CustomFooter(Widget):
|
||||
|
@ -39,7 +75,6 @@ class CustomFooter(Widget):
|
|||
.footer-left {
|
||||
width: auto;
|
||||
text-align: left;
|
||||
text-style: dim;
|
||||
height: 1;
|
||||
content-align: left middle;
|
||||
}
|
||||
|
@ -52,7 +87,6 @@ class CustomFooter(Widget):
|
|||
.footer-right {
|
||||
width: auto;
|
||||
text-align: right;
|
||||
text-style: dim;
|
||||
height: 1;
|
||||
content-align: right middle;
|
||||
}
|
||||
|
@ -73,12 +107,25 @@ class CustomFooter(Widget):
|
|||
height: 1;
|
||||
content-align: right middle;
|
||||
}
|
||||
|
||||
/* Enhanced styling for footer key components */
|
||||
.footer-left .footer-key--key,
|
||||
.footer-right .footer-key--key {
|
||||
text-style: bold;
|
||||
color: $text;
|
||||
}
|
||||
|
||||
.footer-left .footer-key--description,
|
||||
.footer-right .footer-key--description {
|
||||
color: $text-muted;
|
||||
text-style: dim;
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self._left_items = []
|
||||
self._right_items = []
|
||||
self._left_items = [] # List of FooterKey widgets
|
||||
self._right_items = [] # List of FooterKey widgets
|
||||
self._status_text = ""
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
|
@ -90,16 +137,43 @@ class CustomFooter(Widget):
|
|||
yield Static(" │ ", id="footer-separator", classes="footer-separator")
|
||||
yield Static("", id="footer-status", classes="footer-status")
|
||||
|
||||
def add_left_item(self, item: str) -> None:
|
||||
"""Add an item to the left section."""
|
||||
self._left_items.append(item)
|
||||
def add_left_item(self, key: str, description: str) -> None:
|
||||
"""Add a key-description pair to the left section."""
|
||||
footer_key = FooterKey(key, description)
|
||||
self._left_items.append(footer_key)
|
||||
self._update_left_section()
|
||||
|
||||
def add_right_item(self, item: str) -> None:
|
||||
"""Add an item to the right section."""
|
||||
self._right_items.append(item)
|
||||
def add_right_item(self, key: str, description: str) -> None:
|
||||
"""Add a key-description pair to the right section."""
|
||||
footer_key = FooterKey(key, description)
|
||||
self._right_items.append(footer_key)
|
||||
self._update_right_section()
|
||||
|
||||
def add_left_item_legacy(self, item: str) -> None:
|
||||
"""Add a legacy item (key: description format) to the left section."""
|
||||
if ": " in item:
|
||||
key, description = item.split(": ", 1)
|
||||
self.add_left_item(key, description)
|
||||
else:
|
||||
self.add_left_item(item, "")
|
||||
|
||||
def add_right_item_legacy(self, item: str) -> None:
|
||||
"""Add a legacy item (key: description format) to the right section."""
|
||||
if ": " in item:
|
||||
key, description = item.split(": ", 1)
|
||||
self.add_right_item(key, description)
|
||||
else:
|
||||
self.add_right_item(item, "")
|
||||
|
||||
# Backward compatibility - temporarily add the old single parameter methods
|
||||
def add_left_item_old(self, item: str) -> None:
|
||||
"""Backward compatibility method."""
|
||||
self.add_left_item_legacy(item)
|
||||
|
||||
def add_right_item_old(self, item: str) -> None:
|
||||
"""Backward compatibility method."""
|
||||
self.add_right_item_legacy(item)
|
||||
|
||||
def clear_left_items(self) -> None:
|
||||
"""Clear all items from the left section."""
|
||||
self._left_items.clear()
|
||||
|
@ -119,7 +193,19 @@ class CustomFooter(Widget):
|
|||
"""Update the left section display."""
|
||||
try:
|
||||
left_static = self.query_one("#footer-left", Static)
|
||||
left_static.update(" ".join(self._left_items))
|
||||
if self._left_items:
|
||||
# Combine all FooterKey renderings with spacing
|
||||
combined_text = Text()
|
||||
for i, footer_key in enumerate(self._left_items):
|
||||
if i > 0:
|
||||
combined_text.append(" ") # Add spacing between items
|
||||
# Render individual key-description pair with styling
|
||||
combined_text.append(footer_key.key, style="bold")
|
||||
combined_text.append(" ")
|
||||
combined_text.append(footer_key.description, style="dim")
|
||||
left_static.update(combined_text)
|
||||
else:
|
||||
left_static.update("")
|
||||
except Exception:
|
||||
pass # Widget not ready yet
|
||||
|
||||
|
@ -127,7 +213,19 @@ class CustomFooter(Widget):
|
|||
"""Update the right section display."""
|
||||
try:
|
||||
right_static = self.query_one("#footer-right", Static)
|
||||
right_static.update(" ".join(self._right_items))
|
||||
if self._right_items:
|
||||
# Combine all FooterKey renderings with spacing
|
||||
combined_text = Text()
|
||||
for i, footer_key in enumerate(self._right_items):
|
||||
if i > 0:
|
||||
combined_text.append(" ") # Add spacing between items
|
||||
# Render individual key-description pair with styling
|
||||
combined_text.append(footer_key.key, style="bold")
|
||||
combined_text.append(" ")
|
||||
combined_text.append(footer_key.description, style="dim")
|
||||
right_static.update(combined_text)
|
||||
else:
|
||||
right_static.update("")
|
||||
except Exception:
|
||||
pass # Widget not ready yet
|
||||
|
||||
|
|
|
@ -12,8 +12,20 @@ HOSTS_MANAGER_BINDINGS = [
|
|||
Binding("a", "add_entry", "Add new entry", show=True, id="left:add_entry"),
|
||||
Binding("d", "delete_entry", "Delete entry", show=True, id="left:delete_entry"),
|
||||
Binding("e", "edit_entry", "Edit entry", show=True, id="left:edit_entry"),
|
||||
Binding("space", "toggle_entry", "Toggle active/inactive", show=True, id="left:toggle_entry"),
|
||||
Binding("ctrl+e", "toggle_edit_mode", "Toggle edit mode", show=True, id="left:toggle_edit_mode"),
|
||||
Binding(
|
||||
"space",
|
||||
"toggle_entry",
|
||||
"Toggle active/inactive",
|
||||
show=True,
|
||||
id="left:toggle_entry",
|
||||
),
|
||||
Binding(
|
||||
"ctrl+e",
|
||||
"toggle_edit_mode",
|
||||
"Toggle edit mode",
|
||||
show=True,
|
||||
id="left:toggle_edit_mode",
|
||||
),
|
||||
Binding("c", "config", "Configuration", show=True, id="right:config"),
|
||||
Binding(
|
||||
"question_mark",
|
||||
|
@ -26,9 +38,7 @@ HOSTS_MANAGER_BINDINGS = [
|
|||
Binding("q", "quit", "Quit", show=True, id="right:quit"),
|
||||
Binding("r", "reload", "Reload hosts file", show=False),
|
||||
Binding("i", "sort_by_ip", "Sort by IP address", show=False),
|
||||
Binding(
|
||||
"h", "sort_by_hostname", "Sort by hostname", show=False
|
||||
),
|
||||
Binding("h", "sort_by_hostname", "Sort by hostname", show=False),
|
||||
Binding("ctrl+s", "save_file", "Save hosts file", show=False),
|
||||
Binding("shift+up", "move_entry_up", "Move entry up", show=False),
|
||||
Binding("shift+down", "move_entry_down", "Move entry down", show=False),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue