diff --git a/demos/README.md b/demos/README.md new file mode 100644 index 0000000..bcc360f --- /dev/null +++ b/demos/README.md @@ -0,0 +1,96 @@ +# Reskinner Demos + +This directory contains demonstration programs showcasing various features and capabilities of the Reskinner library. + +## Available Demos + +
+all_elements.py + +Based on the standard PySimpleGUI All Elements Demo but customized for Reskinner-specific features. Shows how different GUI components appear and behave with custom theming. + +
+ +
+extended_layouts.py + +Shows how to create complex layouts and switch between different visual themes dynamically. Includes examples of advanced layout techniques. + +
+ +
+pin.py + +Specifically demonstrates the `sg.pin` element functionality and addresses the single pixel issue that can occur when using `shrink=True`. Includes interactive controls to toggle different pin behaviors. + +
+ +
+updated_table.py + +Shows how to work with table elements in Reskinner, including dynamic updates, extended selection modes, and theme integration. Demonstrates real-time data manipulation in table format. + +
+ +## Running Demos + +### Method 1: Interactive GUI Launcher + +Run the demos module directly to launch a graphical selection interface: + +```bash +python -m demos +``` + +This will open a window where you can select and run any available demo from a dropdown menu. + +### Method 2: Command Line + +Run a specific demo by name from the command line: + +```bash +python -m demos +``` + +Example: + +```bash +python -m demos all_elements +``` + +### Method 3: Direct Execution + +Run individual demo files directly: + +```bash +python demos/all_elements.py +``` + +## Requirements + +- **Repository clone required**: These demos are not included in the PyPI distribution. You must clone the repository to access them: + ```bash + git clone https://github.com/definite-d/reskinner.git + cd reskinner + ``` +- The demos automatically import the necessary modules from `reskinner` +- Some demos may require additional dependencies that are typically installed with Reskinner + +## Troubleshooting + +If you encounter issues running demos: + +1. Ensure you're in the project root directory +2. Verify that the Reskinner library is properly installed +3. Check that all required dependencies are available +4. Some demos may require specific display configurations + +## Contributing + +When adding new demos: + +1. Create a new Python file in this directory +2. Implement a `main()` function as the entry point +3. Follow the existing naming convention (lowercase with underscores) +4. Add a brief description to this README +5. Ensure the demo works with the launcher system by not starting with an underscore in the filename diff --git a/demos/extended_layouts.py b/demos/extended_layouts.py new file mode 100644 index 0000000..8ca5ea6 --- /dev/null +++ b/demos/extended_layouts.py @@ -0,0 +1,89 @@ +import FreeSimpleGUI as sg +from reskinner import reskin + +SIMPLEGUI_DARK_THEME = "Dark" +SIMPLEGUI_THEME = "Reddit" + +sg.theme(SIMPLEGUI_THEME) + + +def _make_row(text: str): + return [sg.Text(f"- {text}")] + + +def _theme_is_light() -> bool: + return sg.theme() == SIMPLEGUI_THEME + + +def main(): + layout = [ + [sg.Text("Extended Layout Demo", font="_ 16")], + [ + sg.Text( + 'Type in a value and click "Add Item" ' + "to extend the column below with text" + ) + ], + [ + sg.Column( + [], + size=(None, 200), + expand_x=True, + scrollable=True, + vertical_scroll_only=True, + key="container", + ) + ], + [ + sg.Input(key="data", expand_x=True), + sg.Button( + "Add Item", + key="add", + bind_return_key=True, + ), + ], + [sg.pin(sg.Text(key="warning", visible=False))], + [sg.Button("Toggle Theme", key="toggle_theme")], + ] + + window: sg.Window = sg.Window("Extended layouts demo", layout) + data: set[str] = set() + + container: sg.Column = window["container"] + warning: sg.Text = window["warning"] + + def _warn(message: str, timeout=3000): + locked = warning.metadata == "locked" + + warning.metadata = "locked" + warning.update( + f"Warning: {message}", + text_color="red" if _theme_is_light() else "#FF9A9A", + visible=True, + ) + + def _try_hide(): + warning.update(visible=False) + warning.metadata = None + + if window.TKroot and not locked: + window.TKroot.after(timeout, _try_hide) + + while not window.was_closed(): + e, v = window.read() + + if e == "add": + if v["data"]: + if v["data"] not in data: + window.extend_layout(container, [_make_row(v["data"])]) + container.contents_changed() + data.add(v["data"]) + window["data"].update(value="") + else: + _warn(f"{v['data']} already added.") + else: + _warn("No data to add.") + + elif e == "toggle_theme": + new_theme = SIMPLEGUI_DARK_THEME if _theme_is_light() else SIMPLEGUI_THEME + reskin(window, new_theme) diff --git a/demos/updated_table.py b/demos/updated_table.py new file mode 100644 index 0000000..2522a25 --- /dev/null +++ b/demos/updated_table.py @@ -0,0 +1,71 @@ +import FreeSimpleGUI as sg +from reskinner import reskin + +SIMPLEGUI_DARK_THEME = "Dark" +SIMPLEGUI_THEME = "Reddit" + +sg.theme(SIMPLEGUI_THEME) + + +def make_window() -> sg.Window: + layout = [ + [sg.Button("-THEME-")], + [ + sg.Table( + values=[[]], + headings=["A", "B", "C"], + auto_size_columns=True, + justification="left", + key="snapshot-list", + select_mode="extended", + size=(None, 10), + expand_x=True, + expand_y=True, + ) + ], + ] + + window = sg.Window( + "Window Title", + layout, + use_default_focus=False, + font="_ 15", + metadata=0, + size=(400, 300), + ) + + return window + + +snapshot_list = [ + ["Row 1", "Data", "More Data"], + ["Row 2", "Data", "More Data"], + ["Row 3", "Data", "More Data"], + ["Row 4", "Data", "More Data"], + ["Row 5", "Data", "More Data"], +] + + +def main(): + window = make_window() + window.finalize() + + window["snapshot-list"].update(snapshot_list) + + while not window.is_closed(): + event, values = window.read() # wake every hour + print(event, values) + if event == sg.WIN_CLOSED or event == "Exit": + break + if event == "-THEME-": + reskin( + window=window, + new_theme=SIMPLEGUI_DARK_THEME + if (sg.theme() == SIMPLEGUI_THEME) + else SIMPLEGUI_THEME, + ) + continue + + +if __name__ == "__main__": + main()