Skip to content

Commit ed73ad9

Browse files
committed
Test
1 parent e2c0516 commit ed73ad9

File tree

5 files changed

+234
-29
lines changed

5 files changed

+234
-29
lines changed

Diff for: tools/config_editor/app.py

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env python
2+
3+
"""
4+
Arduino Static Libraries Configuration Editor
5+
"""
6+
7+
from rich.syntax import Syntax
8+
from rich.traceback import Traceback
9+
from rich.console import RenderableType
10+
11+
from textual.app import App, ComposeResult
12+
from textual.containers import Container
13+
from textual.widgets import Button, Footer, Header, RichLog, Label
14+
15+
from targets import TargetsScreen
16+
from editor import EditorScreen
17+
from compile import CompileScreen
18+
19+
target_dict = {}
20+
21+
class ConfigEditorApp(App):
22+
"""Textual config editor app."""
23+
24+
ENABLE_COMMAND_PALETTE = False
25+
CSS_PATH = "style.tcss"
26+
SCREENS = {
27+
"targets": TargetsScreen(),
28+
"compile": CompileScreen(),
29+
"editor": EditorScreen(),
30+
}
31+
BINDINGS = [
32+
("c", "push_screen('compile')", "Compile"),
33+
("t", "push_screen('targets', update_targets)", "Change Targets"),
34+
("o", "push_screen('editor')", "Change Options"),
35+
("l", "app.toggle_class('RichLog', '-hidden')", "Log"),
36+
("q", "quit", "Quit"),
37+
]
38+
39+
def log_print(self, renderable: RenderableType) -> None:
40+
self.query_one(RichLog).write(renderable)
41+
42+
def update_targets(self, targets: dict) -> None:
43+
"""Update the targets dictionary."""
44+
self.log_print("Updating targets")
45+
self.log_print(targets)
46+
if targets:
47+
target_dict = targets
48+
49+
def on_button_pressed(self, event: Button.Pressed) -> None:
50+
"""Event handler called when a button is pressed."""
51+
if event.button.id == "compile-button":
52+
self.log_print("Compile button pressed")
53+
self.push_screen('compile')
54+
elif event.button.id == "targets-button":
55+
self.log_print("Targets button pressed")
56+
self.push_screen('targets', self.update_targets)
57+
elif event.button.id == "options-button":
58+
self.log_print("Options button pressed")
59+
self.push_screen('editor')
60+
elif event.button.id == "quit-button":
61+
self.log_print("Quit button pressed")
62+
quit()
63+
64+
def compose(self) -> ComposeResult:
65+
"""Compose our UI."""
66+
yield Header()
67+
with Container(id="main-menu-container"):
68+
yield Label("ESP32 Arduino Static Libraries Configuration Editor", id="main-menu-title")
69+
yield Button("Compile", id="compile-button", classes="main-menu-button")
70+
yield Button("Select Targets", id="targets-button", classes="main-menu-button")
71+
yield Button("Change Configuration Options", id="options-button", classes="main-menu-button")
72+
yield Button("Quit", id="quit-button", classes="main-menu-button")
73+
yield RichLog(classes="-hidden", wrap=False, highlight=True, markup=True)
74+
yield Footer()
75+
76+
def on_mount(self) -> None:
77+
self.title = "Configurator"
78+
self.sub_title = "Main Menu"
79+
self.log_print("[b green]Welcome to the ESP32 Arduino Static Libraries Configuration Editor!")
80+
81+
def main() -> None:
82+
"""Run the app."""
83+
ConfigEditorApp().run()
84+
85+
if __name__ == "__main__":
86+
main()

Diff for: tools/config_editor/compile.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from textual.app import ComposeResult
2+
from textual.containers import Container
3+
from textual.screen import Screen
4+
from textual.widgets import Footer, Header, Static, RichLog
5+
6+
class CompileScreen(Screen):
7+
8+
def compose(self) -> ComposeResult:
9+
"""Compose our UI."""
10+
yield Header()
11+
with Container():
12+
yield Static("Compile", id="compile-title")
13+
yield Footer()
14+
15+
def on_mount(self) -> None:
16+
pass
17+
18+

Diff for: tools/config_editor/config_editor.py renamed to tools/config_editor/editor.py

+5-28
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,12 @@
1-
#!/usr/bin/env python
2-
3-
"""
4-
Arduino-esp32 Libraries Configuration Editor
5-
"""
6-
71
import sys
82

9-
from rich.syntax import Syntax
10-
from rich.traceback import Traceback
11-
12-
from textual.app import App, ComposeResult
3+
from textual.app import ComposeResult
134
from textual.containers import Container, VerticalScroll
5+
from textual.screen import Screen
146
from textual.reactive import var
15-
from textual.widgets import DirectoryTree, Footer, Header, Static
16-
17-
18-
class ConfigEditor(App):
19-
"""Textual config editor app."""
20-
21-
CSS_PATH = "style.tcss"
22-
BINDINGS = [
23-
("f", "toggle_files", "Toggle Files"),
24-
("q", "quit", "Quit"),
25-
]
7+
from textual.widgets import DirectoryTree, Footer, Header, Static, RichLog
268

9+
class EditorScreen(Screen):
2710
show_tree = var(True)
2811

2912
def watch_show_tree(self, show_tree: bool) -> None:
@@ -41,6 +24,7 @@ def compose(self) -> ComposeResult:
4124
yield Footer()
4225

4326
def on_mount(self) -> None:
27+
self.sub_title = "Select a file"
4428
self.query_one(DirectoryTree).focus()
4529

4630
def on_directory_tree_file_selected(
@@ -69,10 +53,3 @@ def action_toggle_files(self) -> None:
6953
"""Called in response to key binding."""
7054
self.show_tree = not self.show_tree
7155

72-
73-
def main() -> None:
74-
"""Run the app."""
75-
ConfigEditor().run()
76-
77-
if __name__ == "__main__":
78-
main()

Diff for: tools/config_editor/style.tcss

+69-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Screen {
1111
dock: left;
1212
}
1313

14-
ConfigEditor.-show-tree #tree-view {
14+
ConfigEditorApp.-show-tree #tree-view {
1515
display: block;
1616
max-width: 50%;
1717
}
@@ -24,3 +24,71 @@ ConfigEditor.-show-tree #tree-view {
2424
#code {
2525
width: auto;
2626
}
27+
28+
RichLog {
29+
background: $surface;
30+
color: $text;
31+
height: 50vh;
32+
dock: bottom;
33+
layer: notes;
34+
border-top: hkey $primary;
35+
offset-y: 0;
36+
padding: 0 1 1 1;
37+
}
38+
39+
RichLog:focus {
40+
offset: 0 0 !important;
41+
}
42+
43+
RichLog.-hidden {
44+
offset-y: 100%;
45+
}
46+
47+
Button.main-menu-button {
48+
min-width: 100%;
49+
max-width: 0.5fr;
50+
}
51+
52+
#main-menu-container {
53+
align: center middle;
54+
width: 1fr;
55+
}
56+
57+
#target-selection-container {
58+
align: center middle;
59+
width: 1fr;
60+
}
61+
62+
#target-scroll-container {
63+
align: center middle;
64+
max-width: 0.4fr;
65+
min-width: 100%;
66+
}
67+
68+
#target-button-container {
69+
width: 100%;
70+
max-height: 20%;
71+
min-height: 5;
72+
align: center middle;
73+
}
74+
75+
.target-button {
76+
margin: 1;
77+
min-width: 100%;
78+
max-width: 0.2fr;
79+
align: center middle;
80+
}
81+
82+
.target-checkbox {
83+
align: center middle;
84+
width: 100%;
85+
background: rgb(50, 50, 50);
86+
}
87+
88+
#main-menu-title {
89+
text-align: center;
90+
margin-bottom: 4;
91+
text-style: bold;
92+
color: green;
93+
width: 0.5fr;
94+
}

Diff for: tools/config_editor/targets.py

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from textual.app import ComposeResult
2+
from textual.containers import VerticalScroll, Container, Horizontal
3+
from textual.screen import Screen
4+
from textual.widgets import Footer, Header, Checkbox, Button
5+
6+
temp_target_dict = {
7+
"esp32": True,
8+
"esp32s2": True,
9+
"esp32s3": True,
10+
"esp32c2": True,
11+
"esp32c3": True,
12+
"esp32c6": True,
13+
"esp32h2": True
14+
}
15+
16+
class TargetsScreen(Screen[dict]):
17+
18+
def on_button_pressed(self, event: Button.Pressed) -> None:
19+
"""Event handler called when a button is pressed."""
20+
if event.button.id == "save-button":
21+
for checkbox in self.query("Checkbox"):
22+
target_text = checkbox.id[:-9]
23+
temp_target_dict[target_text] = checkbox.value
24+
self.dismiss(temp_target_dict)
25+
elif event.button.id == "select-all-button":
26+
for checkbox in self.query("Checkbox"):
27+
checkbox.value = True
28+
elif event.button.id == "select-none-button":
29+
for checkbox in self.query("Checkbox"):
30+
checkbox.value = False
31+
elif event.button.id == "cancel-button":
32+
self.dismiss({})
33+
34+
def compose(self) -> ComposeResult:
35+
yield Header()
36+
with Container(id="target-selection-container"):
37+
with VerticalScroll(id="target-scroll-container"):
38+
yield Checkbox("ESP32", temp_target_dict["esp32"], classes="target-checkbox", id="esp32-checkbox")
39+
yield Checkbox("ESP32-S2", temp_target_dict["esp32s2"], classes="target-checkbox", id="esp32s2-checkbox")
40+
yield Checkbox("ESP32-S3", temp_target_dict["esp32s3"], classes="target-checkbox", id="esp32s3-checkbox")
41+
yield Checkbox("ESP32-C2 (ESP8684)", temp_target_dict["esp32c2"], classes="target-checkbox", id="esp32c2-checkbox")
42+
yield Checkbox("ESP32-C3", temp_target_dict["esp32c3"], classes="target-checkbox", id="esp32c3-checkbox")
43+
yield Checkbox("ESP32-C6", temp_target_dict["esp32c6"], classes="target-checkbox", id="esp32c6-checkbox")
44+
yield Checkbox("ESP32-H2", temp_target_dict["esp32h2"], classes="target-checkbox", id="esp32h2-checkbox")
45+
with Horizontal(id="target-button-container"):
46+
yield Button("Save", id="save-button", classes="target-button")
47+
yield Button("Select All", id="select-all-button", classes="target-button")
48+
yield Button("Select None", id="select-none-button", classes="target-button")
49+
yield Button("Cancel", id="cancel-button", classes="target-button")
50+
yield Footer()
51+
52+
def on_mount(self) -> None:
53+
self.sub_title = "Target Selection"
54+
self.query_one("#esp32-checkbox", Checkbox).focus()
55+
56+

0 commit comments

Comments
 (0)