Files
Berry/settings.py

183 lines
8.6 KiB
Python
Raw Normal View History

2025-10-29 13:11:51 +11:00
from textual.screen import ModalScreen
2025-10-30 17:45:30 +11:00
from textual.widgets import Label, Select, TabbedContent, TabPane, Switch, Input, Rule, Static
from textual.containers import Vertical, HorizontalGroup, VerticalGroup, VerticalScroll
2025-10-29 13:11:51 +11:00
from textual.binding import Binding
class SettingsScreen(ModalScreen):
border_title = "Settings"
DEFAULT_CSS = """
SettingsScreen {
align: center middle;
#window {
border: panel $primary;
background: $background;
width: 65%;
height: 65%;
padding: 1;
}
TabPane {
padding: 1;
}
2025-10-30 17:45:30 +11:00
Rule {
color: $boost;
}
.thingy {
margin-top: 2;
text-style: bold;
}
2025-10-29 13:11:51 +11:00
.setting {
padding: 0 2;
content-align: center middle;
2025-10-30 07:53:19 +11:00
margin-bottom: 1;
2025-10-29 13:11:51 +11:00
.setting-name {
text-style: bold;
}
2025-10-29 13:11:51 +11:00
.setting-desc {
text-style: dim;
2025-10-29 15:31:56 +11:00
width: 100%;
min-width: 30;
2025-10-29 13:11:51 +11:00
}
2025-10-29 13:11:51 +11:00
VerticalGroup {
2025-10-29 15:31:56 +11:00
width: 50%;
min-width: 20;
2025-10-30 07:53:19 +11:00
margin-right: 1;
2025-10-29 15:31:56 +11:00
}
2025-10-30 07:53:19 +11:00
Select, Input {
max-width: 30;
2025-10-29 13:11:51 +11:00
}
}
}
"""
BINDINGS = [
Binding("escape", "close", "Close")
]
2025-10-30 06:59:20 +11:00
def __init__(self):
super().__init__()
2025-10-29 13:11:51 +11:00
def action_close(self):
self.dismiss()
2025-10-30 06:59:20 +11:00
def on_switch_changed(self, event: Switch.Changed):
if event.switch.id == "word-wrap":
self.app.query_one("#code-editor").soft_wrap = event.value
self.app.config_handler.set("editor", "word_wrap", str(int(event.value)))
2025-10-31 07:34:52 +11:00
elif event.switch.id == "line-numbers":
self.app.query_one("#code-editor").show_line_numbers = event.value
self.app.config_handler.set("editor", "line_numbers", str(int(event.value)))
2025-10-30 07:53:19 +11:00
elif event.switch.id == "plugins-enabled":
self.app.config_handler.set("plugins", "enabled", str(int(event.value)))
self.notify("Restart for changes to apply.", title="Restart Required", severity="warning")
2025-10-30 12:38:14 +11:00
elif event.switch.id == "plugins-log":
self.app.config_handler.set("plugins", "log", str(int(event.value)))
2025-10-30 17:45:30 +11:00
elif event.switch.has_class("plugin-option"):
if event.switch.berry_changed_func != None:
event.switch.berry_changed_func(event.switch.value)
2025-10-30 06:59:20 +11:00
def on_select_changed(self, event: Select.Changed):
if event.select.id == "colour-theme":
self.app.theme = event.value
self.app.config_handler.set("appearance", "colour_theme", str(event.value))
2025-10-30 06:59:20 +11:00
2025-10-30 12:38:14 +11:00
def on_input_changed(self, event: Input.Changed):
if not event.input.is_valid: return
if event.input.id == "log-timeout":
self.app.config_handler.set("plugins", "log_timeout", str(event.input.value))
2025-10-30 17:45:30 +11:00
elif event.input.has_class("plugin-option"):
if event.input.berry_changed_func != None:
event.input.berry_changed_func(event.input.value)
2025-10-30 12:38:14 +11:00
2025-10-29 13:11:51 +11:00
def compose(self):
with Vertical(id="window") as window:
window.border_title = "Settings"
with TabbedContent():
2025-10-29 15:31:56 +11:00
with TabPane("Appearance"):
2025-10-30 17:45:30 +11:00
with VerticalScroll():
with HorizontalGroup(classes="setting"):
with VerticalGroup():
yield Label("Colour Theme", classes="setting-name")
yield Label("Colour theme used for the entire Berry app. You can get more themes with plugins!", classes="setting-desc")
2025-10-30 06:59:20 +11:00
2025-10-30 17:45:30 +11:00
yield Select.from_values(
(theme_name for theme_name in self.app._registered_themes.keys() if theme_name != "textual-ansi"),
allow_blank=False,
id="colour-theme",
value=self.app.theme
)
2025-10-30 06:59:20 +11:00
2025-10-29 13:11:51 +11:00
with TabPane("Editor"):
2025-10-30 17:45:30 +11:00
with VerticalScroll():
with HorizontalGroup(classes="setting"):
with VerticalGroup():
yield Label("Word Wrap", classes="setting-name")
yield Label("Enable word wrap in the code editor.", classes="setting-desc")
yield Switch(value=bool(int(self.app.config_handler.get("editor", "word_wrap"))), id="word-wrap")
2025-10-31 07:34:52 +11:00
with HorizontalGroup(classes="setting"):
with VerticalGroup():
yield Label("Line Numbers", classes="setting-name")
yield Label("Show line numbers in the editor.", classes="setting-desc")
yield Switch(value=bool(int(self.app.config_handler.get("editor", "line_numbers"))), id="line-numbers")
with TabPane("Plugins"):
2025-10-30 17:45:30 +11:00
with VerticalScroll():
with HorizontalGroup(classes="setting"):
with VerticalGroup():
yield Label("Plugins Enabled", classes="setting-name")
yield Label("Enable or disable Lua plugins. This requires a restart.", classes="setting-desc")
yield Switch(value=bool(int(self.app.config_handler.get("plugins", "enabled"))), id="plugins-enabled")
with HorizontalGroup(classes="setting"):
with VerticalGroup():
yield Label("Plugins Log", classes="setting-name")
yield Label("Show the plugin loader log on startup.", classes="setting-desc")
yield Switch(value=bool(int(self.app.config_handler.get("plugins", "log"))), id="plugins-log")
with HorizontalGroup(classes="setting"):
with VerticalGroup():
yield Label("Log Timeout", classes="setting-name")
yield Label("How many seconds before the log automatically closes. This gets overriden by the [b]Plugins Log[/] option. The window doesn't automatically close if there was an error. If this is set to -1, the log will not close automatically.", classes="setting-desc")
yield Input(value=self.app.config_handler.get("plugins", "log_timeout"), id="log-timeout", type="integer")
yield Static("Plugin-defined Settings", classes="thingy")
yield Rule(line_style="double")
2025-10-30 17:45:30 +11:00
for plugin_section, plugin_settings in self.app.config_handler.plugin_defined_settings.items():
yield Static(f"{plugin_section}", classes="thingy")
yield Rule()
for setting_name, setting in plugin_settings.items():
with HorizontalGroup(classes="setting"):
with VerticalGroup():
yield Label(setting_name, classes="setting-name")
yield Label(setting["description"], classes="setting-desc")
value = self.app.config_handler.get(f"plugin_{plugin_section}", setting["option_name"])
new_widget = None
if setting["type"] == bool:
value = bool(int(value))
new_widget = Switch(value=value)
elif setting["type"] == int:
new_widget = Input(value=value, type="integer", placeholder=setting["default_value"])
elif setting["type"] == float:
new_widget = Input(value=value, type="number", placeholder=setting["default_value"])
elif setting["type"] == str:
new_widget = Input(value=value, placeholder=setting["default_value"])
new_widget.add_class("plugin-option")
setattr(new_widget, "berry_changed_func", setting['on_changed_func'])
yield new_widget