From fec33e59fed08553eaa4b6863c41addb99ae1465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parodi=2C=20Eugenio=20=F0=9F=8C=B6?= Date: Tue, 4 Nov 2025 21:22:21 +0100 Subject: [PATCH] chore: add copilot instructions --- .github/copilot-instructions.md | 186 ++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..82f6e955 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,186 @@ +# pyTermTk Copilot Instructions + +## Project Overview + +pyTermTk is a Text-based User Interface (TUI) library for Python inspired by Qt5, GTK, and tkinter APIs. It creates cross-platform terminal applications with rich widgets, layouts, and an event-driven architecture. + +## Architecture + +### Core Structure +- **`libs/pyTermTk/TermTk/`** - Main library code organized into logical modules: + - `TTkCore/` - Core functionality (signals, colors, canvas, configuration) + - `TTkWidgets/` - All UI widgets inherit from `TTkWidget` base class + - `TTkLayouts/` - Layout managers (GridLayout, HBoxLayout, VBoxLayout) + - `TTkGui/` - GUI components (drag & drop, application management) + - `TTkTemplates/` - Mixin classes for event handling (`TKeyEvents`, `TMouseEvents`, `TDragEvents`) + +### Widget Inheritance Pattern +All widgets follow this pattern: +```python +class TTkMyWidget(TTkWidget): # Or TTkContainer for composite widgets + # Class-level styling + classStyle = { + 'default': {'color': TTkColor.fg("#dddd88"), 'borderColor': TTkColor.RST}, + 'hover': {'color': TTkColor.fg("#ffffff"), 'borderColor': TTkColor.BOLD}, + 'focus': {'borderColor': TTkColor.fg("#ffff00")}, + 'disabled': {'color': TTkColor.fg('#888888')} + } + + # Signal declarations + mySignal: pyTTkSignal + + __slots__ = ('_private_vars',) # Always use slots for performance + + def __init__(self, **kwargs): + self.mySignal = pyTTkSignal(int) # Define signals in __init__ + super().__init__(**kwargs|{'size': (w, h)}) # Merge kwargs, set default size +``` + +### Signal-Slot System (Qt-inspired) +Use type-safe signal-slot patterns: +```python +# Define signals with types +signal = pyTTkSignal(int) +# Define slots with decorators +@pyTTkSlot(int) +def my_slot(value: int): + pass +# Connect them +signal.connect(my_slot) +``` + +### Event Handling +Widgets handle events by overriding template methods: +- `keyEvent()`, `mousePressEvent()`, `paintEvent()` - Core events +- `focusInEvent()`, `focusOutEvent()` - Focus management +- `dropEvent()`, `dragEnterEvent()` - Drag & drop +- Always return `True` if event is handled, `False` to propagate + +## Development Workflows + +### Testing +- **Unit tests**: `pytest tests/pytest/` (run via Makefile: `make test`) +- **Performance tests**: `tests/timeit/` - Contains signal/slot benchmarks and optimization tests +- **Manual tests**: `tests/t.*/` - Interactive UI tests +- **CI**: Tests run on Python 3.9-3.14 with flake8 linting + +### Build & Deploy +- **Local build**: `pip install -e libs/pyTermTk` (uses `pip`) +- **Documentation**: `make doc` (Sphinx-based, outputs to `docs/source/_build/html/`) +- **Apps deployment**: Individual apps in `apps/` have their own `pyproject.toml` + +### Running Examples +- **Demo**: `python demo/demo.py -f` +- **Designer**: `pip install -e apps/ttkDesigner ; ttkDesigner` +- **Individual tests**: `python tests/t.ui/test.ui.036.datetime.01.py` + +## Project-Specific Patterns + +### Widget State Management +Many widgets use internal state classes (see `datetime_date_form.py`): +```python +class _TTkWidgetState: + __slots__ = ('_data', 'signal_name') + def __init__(self): + self.signal_name = pyTTkSignal() +``` + +### File Organization +- One widget per file in `TTkWidgets/` +- Use `__all__ = ['ClassName']` exports +- Import from `TermTk.TTkCore`, `TermTk.TTkWidgets` etc (not relative imports) +- Apps in `apps/` are self-contained with `pyproject.toml` + +### Color & Theming +Use `TTkColor` constants and theme system: +```python +TTkColor.fg("#ffffff") + TTkColor.bg("#000044") + TTkColor.BOLD +style = self.currentStyle() # Get theme-aware colors +``` + +### Cross-Platform Considerations +- Platform-specific code in `TTkCore/drivers/` +- Terminal compatibility testing in `tests/ansi.images.json` +- HTML5 export capabilities via `tools/webExporter/` + +### Documentation & Docstrings +Use **Sphinx-compatible docstring format** with Epytext-style field lists: +```python +def setGeometry(self, x: int, y: int, width: int, height: int): + ''' Resize and move the widget + + :param x: the horizontal position + :type x: int + :param y: the vertical position + :type y: int + :param width: the new width + :type width: int + :param height: the new height + :type height: int + ''' + +# For class/module docstrings include ASCII art examples: +class TTkButton(TTkWidget): + ''' TTkButton: + + Border = True + :: + + ┌────────┐ + │ Text │ + ╘════════╛ + + Demo: `formwidgets.py `_ + ''' + +# For signals, document parameters: +toggled:pyTTkSignal +''' +This signal is emitted whenever the button state changes if checkeable, +i.e., whenever the user checks or unchecks it. + +:param checked: True if checked otherwise False +:type checked: bool +''' +``` + +**Key conventions**: +- Use single quotes `'''` for docstrings +- Include ASCII art for visual widgets showing borders/layout +- Link to demo files with full GitHub URLs +- Use `:py:class:` for cross-references to other classes +- Document all parameters with `:param name:` and `:type name:` +- Include `:return:` and `:rtype:` for non-void methods +- Signal docstrings document emitted parameters, not the signal itself + +## Apps Ecosystem +The project includes several full applications demonstrating patterns: +- **ttkDesigner** - Visual UI designer (like Qt Designer) +- **ttkode** - Code editor with syntax highlighting +- **dumbPaintTool** - ASCII art editor +- **tlogg** - Log file viewer + +### Testing App Integration +Apps use the main library via path manipulation: +```python +sys.path.append(os.path.join(sys.path[0],'../../libs/pyTermTk')) +import TermTk as ttk +``` + +## Key Integration Points + +### Layout System +Use Qt-like layout managers: +```python +layout = TTkGridLayout() +layout.addWidget(widget, row, col, rowspan, colspan) +container.setLayout(layout) +``` + +### Focus & Input Handling +Set focus policy and handle keyboard navigation: +```python +self.setFocusPolicy(TTkK.ClickFocus | TTkK.TabFocus) +``` + +When implementing new widgets, study existing patterns in `TTkWidgets/` and ensure signal-slot integration follows the established type-safe patterns shown in `tests/pytest/test_004_signals_slots.py`. \ No newline at end of file