Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
524 commits
Select commit Hold shift + click to select a range
58a897a
Qt IntField start implementation
anaselli Dec 31, 2025
10cdbb0
Honored stretching and label up
anaselli Dec 31, 2025
bcc8d1f
First gtk IntField implementation
anaselli Dec 31, 2025
5ffbe20
header
anaselli Dec 31, 2025
205a096
added size policy
anaselli Dec 31, 2025
5e0042c
ncurses intfield
anaselli Dec 31, 2025
f513963
avoid trunking last char
anaselli Dec 31, 2025
af61bb2
improved to insert also the value directly
anaselli Dec 31, 2025
6f89c44
Updated
anaselli Dec 31, 2025
bed4c4a
Multi Line Edit for QT
anaselli Dec 31, 2025
e61c112
use a better layout to test intfield
anaselli Dec 31, 2025
ce630a5
Improved stretching properties
anaselli Dec 31, 2025
3ef926a
fixed stretching properties
anaselli Dec 31, 2025
cf8e6aa
Multi Line Edit for Gtk
anaselli Dec 31, 2025
9ec60c3
Added Multi Line Edit for ncurses
anaselli Dec 31, 2025
0a5d720
Removed Q and q to exit, to avoid conflicts with text input fields
anaselli Dec 31, 2025
9684e02
Fixed horizontal stretching
anaselli Dec 31, 2025
223f0c7
Fixed Input field with label above
anaselli Dec 31, 2025
7754aca
updated
anaselli Dec 31, 2025
fd222bc
Update TODO list with skipped widgets information
anaselli Jan 1, 2026
fe3445c
Added setIcon
anaselli Jan 1, 2026
e6146b9
default app icon "manatools"!
anaselli Jan 2, 2026
1590a64
Label aligned to center
anaselli Jan 2, 2026
cbf817a
Wrong HV alignment and exit icon
anaselli Jan 2, 2026
bd97945
Added test spacing
anaselli Jan 2, 2026
87c3278
First attempt to produce YSpacing for Qt
anaselli Jan 2, 2026
a3e4833
First attempt to produce YSpacing for Gtk
anaselli Jan 2, 2026
6335b06
First attempt to produce YSpacing for ncurses
anaselli Jan 2, 2026
9758bb9
Forgot
anaselli Jan 2, 2026
a674420
Pixels
anaselli Jan 2, 2026
d94527e
In Pixels and fixed Horizontal stretching
anaselli Jan 2, 2026
c652b28
pixel as 0.125 chars
anaselli Jan 2, 2026
13d59d3
fixed last right widget with a stretchable spacyng behind
anaselli Jan 2, 2026
80936c0
Improved test spacing
anaselli Jan 2, 2026
174743a
Updated
anaselli Jan 2, 2026
de82f8b
Added create Spacing variants and MultiSelectionBox by using selection
anaselli Jan 3, 2026
5ace12d
logging information to help debugging
anaselli Jan 3, 2026
75f06d3
updated
anaselli Jan 3, 2026
589103a
First attempt to produce YImage
anaselli Jan 3, 2026
76b8508
Honoring stretching
anaselli Jan 3, 2026
421263c
Get image also from theme
anaselli Jan 3, 2026
eaba46f
tested also setImage from theme
anaselli Jan 3, 2026
d7c021a
stretchable and autoscale
anaselli Jan 3, 2026
d9a60a5
fixed initial image from theme
anaselli Jan 3, 2026
3f66a90
updated
anaselli Jan 3, 2026
d8f6357
removed duplicate item
anaselli Jan 3, 2026
aa789ae
next generation should be 1.0.0
anaselli Jan 4, 2026
6c2b754
Added Min Size
anaselli Jan 4, 2026
7969a68
Added askForExistingDirectory, askForExistingFile, askForSaveFileName
anaselli Jan 4, 2026
644e659
updated
anaselli Jan 4, 2026
7da1fe2
removed as we reached most of the goal
anaselli Jan 4, 2026
8614827
Don't change passed filter
anaselli Jan 4, 2026
493677f
Start implementin askForXXX dialogs
anaselli Jan 4, 2026
6d00865
Added first implementation of AskForXXX functions
anaselli Jan 4, 2026
963c86b
fixed askforsave, though starting directory does not work for ask for
anaselli Jan 5, 2026
4f2dd37
Improving drawing with more widgets
anaselli Jan 5, 2026
d829b36
Added some useful information from widgets
anaselli Jan 5, 2026
36e6508
wrong logging level and position
anaselli Jan 5, 2026
f10901f
forced weight boundaries
anaselli Jan 5, 2026
73c4ce1
fixed drawing and alignment issues, considered also weigth on drawing
anaselli Jan 5, 2026
286a181
Managed weight for Qt
anaselli Jan 5, 2026
b709354
Managed weigth for gtk too
anaselli Jan 5, 2026
00ad293
Fixed file and directory selection, unified browse code also for saving.
anaselli Jan 5, 2026
cf3493c
improved test case
anaselli Jan 5, 2026
cf3d00c
updated
anaselli Jan 5, 2026
df9f32d
Skipped moved to bottom
anaselli Jan 5, 2026
310af26
corrected alignment
anaselli Jan 5, 2026
3965bba
First attempt to have YDumpTab on curses
anaselli Jan 7, 2026
7e9604e
Added logging
anaselli Jan 7, 2026
3b1ab52
Dumptab on Qt
anaselli Jan 7, 2026
8a34789
exporting symbol
anaselli Jan 7, 2026
cc48f2c
and create
anaselli Jan 7, 2026
9ff9e90
Real DumbTab curses implementation
anaselli Jan 7, 2026
40a326c
First attempt to port YDumbTab on gtk4
anaselli Jan 7, 2026
eaf0aba
fix stretching management
anaselli Jan 7, 2026
53ecb55
Stretchable by default
anaselli Jan 7, 2026
857421d
fixed vertical stretching
anaselli Jan 7, 2026
8f4c3e2
a better test case for dumbtab widget
anaselli Jan 7, 2026
ab2a89c
Merge branch 'AUI-REWORKING' of github.com:anaselli/python-manatools …
anaselli Jan 7, 2026
4d9f289
updated
anaselli Jan 7, 2026
34980b6
Added header
anaselli Jan 7, 2026
c42a564
Slide porting to manatools
anaselli Jan 7, 2026
436e380
Aligned to gtk and qt to have an int input field, +,- move forward and
anaselli Jan 7, 2026
9f467cc
updated
anaselli Jan 7, 2026
b38390b
Let's show a name for any focused widget also those that don't have
anaselli Jan 8, 2026
8d2ba3a
Added DateField
anaselli Jan 8, 2026
20e9098
fixing end value
anaselli Jan 8, 2026
0fb5341
Fixed gtk behavior to look similar to qt
anaselli Jan 8, 2026
3c884a3
Leaving selectionbox style menubutton
anaselli Jan 8, 2026
0092613
removed unused code
anaselli Jan 8, 2026
e72816b
added the availability to insert date by hands
anaselli Jan 8, 2026
9c34426
updated
anaselli Jan 8, 2026
b9e9be1
added logging
anaselli Jan 8, 2026
570f1a5
First attempt to por YLogView
anaselli Jan 8, 2026
ababef2
Fixed strethable
anaselli Jan 8, 2026
ad5f843
Fixed stretching change
anaselli Jan 8, 2026
f0b0907
Added scrolling and focus
anaselli Jan 8, 2026
94b0746
Added a long line to see Horizontal scroll
anaselli Jan 8, 2026
ea80802
updated
anaselli Jan 8, 2026
a149960
better line explanation.
anaselli Jan 8, 2026
6582931
TimeField for Qt
anaselli Jan 9, 2026
b206b8c
added also timefield test and renamed
anaselli Jan 9, 2026
244dc74
Added header
anaselli Jan 9, 2026
26fd040
Do not stretch by default
anaselli Jan 9, 2026
aeb5ae4
fixed stretching
anaselli Jan 9, 2026
b9e4875
Added TimeField for gtk
anaselli Jan 9, 2026
a3f2b20
rinominato
anaselli Jan 9, 2026
ccc26e6
Fixed start value and setValue
anaselli Jan 9, 2026
b622d0f
TimeField on curses
anaselli Jan 9, 2026
a7a6e1f
Not stretchable by default
anaselli Jan 9, 2026
7f359c6
updated
anaselli Jan 9, 2026
9a87e47
Not stretchable
anaselli Jan 9, 2026
7dec535
Added application information
anaselli Jan 9, 2026
aa91da0
Correct EventType
anaselli Jan 9, 2026
a821865
better layout
anaselli Jan 9, 2026
462c7d7
Label is just in some widgets
anaselli Jan 9, 2026
0e1fb6b
fixed stretching value
anaselli Jan 9, 2026
ba38367
Added some aliases
anaselli Jan 9, 2026
337a015
Moving to manatools.aui
anaselli Jan 9, 2026
187fe56
moved to manatools.aui
anaselli Jan 9, 2026
25234f6
missing dependency
anaselli Jan 9, 2026
faf66ef
Added shortcut on menu and button converting '&' in '_'
anaselli Jan 9, 2026
9acff2d
Added shortcut for Menus and buttons
anaselli Jan 9, 2026
866f822
Added shortcuts
anaselli Jan 9, 2026
acc3dc0
updated
anaselli Jan 9, 2026
a1abcd5
Added a shortcut
anaselli Jan 9, 2026
8e66f64
Added isTextMode into app
anaselli Jan 10, 2026
3182e87
removed duplicate definition
anaselli Jan 10, 2026
bafaf8a
Added deleteAllDialogs()
anaselli Jan 10, 2026
417fcf7
Added alias to value/setValue as isChecked setChecked
anaselli Jan 10, 2026
bc7e5d0
Managed stretching
anaselli Jan 10, 2026
e2093d5
Improved stretching and autoscale
anaselli Jan 10, 2026
23399bc
Fixed addItem
anaselli Jan 10, 2026
67f13ed
remove old selection
anaselli Jan 10, 2026
e559c1b
FIxed addItem and added deleteAllItems
anaselli Jan 10, 2026
2366512
missing symbols
anaselli Jan 11, 2026
8828334
Exception logging
anaselli Jan 11, 2026
75bcbe9
Fixed setLabel at runtime
anaselli Jan 11, 2026
5ab879e
removed chatti debug log
anaselli Jan 11, 2026
e91ca88
tested deleteAllItems and addItems
anaselli Jan 11, 2026
bd30f98
removed chatty log
anaselli Jan 11, 2026
bd19599
managed stretching
anaselli Jan 11, 2026
7581c2f
created label only once
anaselli Jan 11, 2026
2664877
Caption label in upper position
anaselli Jan 11, 2026
4d88555
Added normal/busy cursor and createIconButton alias
anaselli Jan 11, 2026
712febe
preventing getting text child
anaselli Jan 11, 2026
dcafe75
Added createIconButton
anaselli Jan 11, 2026
9a4a25e
Added busy and norma cursor implementation
anaselli Jan 11, 2026
8f95b2a
less chatty
anaselli Jan 12, 2026
d4c092b
Added layout size constraint to get the children size hint, let's hope
anaselli Jan 15, 2026
71361a5
removed pollEvent by now
anaselli Jan 15, 2026
051301e
Non need to fix menu if widget has not been created yet
anaselli Jan 15, 2026
34bbc2b
Sped up addItems
anaselli Jan 15, 2026
5cc0606
Sped up addItems
anaselli Jan 15, 2026
efea319
disable cursor management by now
anaselli Jan 15, 2026
44b1de8
fix some module import issues
anaselli Jan 15, 2026
afeefa0
wrong indentation
anaselli Jan 15, 2026
4312c61
Added a starting handbook documentation for developers
anaselli Jan 17, 2026
e5c5fd6
Updated with missing tasks
anaselli Jan 17, 2026
5f24993
removed chatty log
anaselli Jan 17, 2026
9442676
improved addItems and deprecated rebuildTree
anaselli Jan 17, 2026
43f203f
updated
anaselli Jan 17, 2026
e4b8fc3
scrolling symbol as in Tree widget
anaselli Jan 17, 2026
c67a8c2
hide label if not passed
anaselli Jan 17, 2026
b808762
forced to bool
anaselli Jan 17, 2026
77de0b5
Added visibility attribute to YWidget to be managed in any widgets
anaselli Jan 17, 2026
fbe6818
Added visibility management and icon button only
anaselli Jan 17, 2026
fc39b93
Forgot to set visibility property
anaselli Jan 18, 2026
498346b
Manged visibility on widget creation
anaselli Jan 18, 2026
04fbea6
discard not visible children
anaselli Jan 18, 2026
3d14a56
using setVisible instead of hide and show
anaselli Jan 18, 2026
fa470f7
Managed visibility and label occupation if not present
anaselli Jan 18, 2026
9e21efb
show all the item text if there is enough room when expanded
anaselli Jan 18, 2026
b4618f9
get 2 more chars available
anaselli Jan 18, 2026
ce2db58
Added a kind of tooltip management by pressing F1
anaselli Jan 18, 2026
ecbb4ef
Fixing position for tool tip
anaselli Jan 18, 2026
37bc964
fixed position when label is missing and added visibility
anaselli Jan 18, 2026
1555ed7
Added visibility and fixed label occupation
anaselli Jan 18, 2026
2a51ac9
Fixed inputfield position if label is not present
anaselli Jan 24, 2026
18d6fc7
minimun length not 0
anaselli Jan 24, 2026
cd8f1eb
fixed missing definitions
anaselli Jan 24, 2026
518d947
tooltip position really on pushbutton
anaselli Jan 25, 2026
62532e2
Added visibility and tooltip
anaselli Jan 25, 2026
6429bdb
removing extra room for this widget
anaselli Jan 25, 2026
14366f7
added some logging in case of exceptions
anaselli Jan 25, 2026
0219495
Fixing table layout
anaselli Jan 26, 2026
1b0d1e2
do not show useless space if label is not set
anaselli Jan 31, 2026
4ed5e3e
manage visibility and tooltip
anaselli Jan 31, 2026
34d8c1c
added visibility
anaselli Jan 31, 2026
1f1cec5
tooltip and fixing visibility mangement
anaselli Jan 31, 2026
37a4b84
Added visibility and tooltip
anaselli Jan 31, 2026
45426d1
Added visibility and tooltip
anaselli Jan 31, 2026
6b1445b
used not deprecated widget getter and added logging on exceptions
anaselli Jan 31, 2026
22218d7
added _apply_size_policy to manage stretching properties
anaselli Jan 31, 2026
1cfb15a
added log
anaselli Jan 31, 2026
ded07d8
No foxus if not visible
anaselli Jan 31, 2026
e2f583e
Horizontal stretching by default
anaselli Jan 31, 2026
2cef0bd
No focus on widget if invisible
anaselli Jan 31, 2026
9e9fd2f
better richtext layout evaluation
anaselli Jan 31, 2026
faed57c
added _preferred_rows to manage later
anaselli Jan 31, 2026
1e6f8b7
First attempt to provide a paned for Qt
anaselli Jan 31, 2026
52c3524
First attempt to have dynamic panel on Gtk
anaselli Jan 31, 2026
b5d9b52
header file
anaselli Jan 31, 2026
69a2f42
first attempt to have a simplified (show/hide) dynamic pane for ncurses
anaselli Jan 31, 2026
6cb1328
Added more items
anaselli Jan 31, 2026
01b78bb
improved layout
anaselli Jan 31, 2026
0cc4a76
Paned on Gtk
anaselli Jan 31, 2026
cce7055
managing +/- to show/hide dynamic panel children
anaselli Jan 31, 2026
050758c
Added visibility
anaselli Jan 31, 2026
722df68
Fixed busy/normal cursor setting
anaselli Feb 1, 2026
066cbc9
Added busy/normal cursor testing
anaselli Feb 1, 2026
d047746
updated
anaselli Feb 1, 2026
adb929c
added manatools defautl icon
anaselli Feb 1, 2026
4a045bf
min image size 64x64
anaselli Feb 1, 2026
0a86fd4
Changed the warning dialog
anaselli Feb 1, 2026
3a36f45
improving basedialog min size management
anaselli Feb 1, 2026
a0499f4
Reviewed Info, Warning and Msg Boxes
anaselli Feb 1, 2026
998a9ca
improving exception management
anaselli Feb 1, 2026
edf3ead
Used Pango.WrapMode
anaselli Feb 1, 2026
83bb433
Worked on AskOkCancel and AskYesOrNo
anaselli Feb 7, 2026
fbf1a1c
worked also on msg boxes
anaselli Feb 7, 2026
07898f7
Centered ok button
anaselli Feb 7, 2026
8ab5fb6
Still working on dialogs
anaselli Feb 7, 2026
7729f3d
Managed title at top most dialog level as for gtk
anaselli Feb 7, 2026
47de38a
Title must be set after dlg is created so that only top most dialog
anaselli Feb 7, 2026
65525a1
Restored Tabbed About dialog
anaselli Feb 7, 2026
3c6d61e
improved testing/example case
anaselli Feb 7, 2026
e6d3886
deprecated info on AboutDialog using app() api to get app information
anaselli Feb 8, 2026
51a7306
Removed description caption into classic about dialog and fixed
anaselli Feb 8, 2026
59ac9fc
manage minimum size into all the common dialogs
anaselli Feb 8, 2026
b4d5a32
first attempt to manage default button
anaselli Feb 8, 2026
aab4fd7
Avoid loop on create widget
anaselli Feb 9, 2026
67bf55a
Fix action on default button if enter is pressed
anaselli Feb 9, 2026
b3515d1
Action added on default button
anaselli Feb 9, 2026
d9ab3ef
reworking on help dialog
anaselli Feb 9, 2026
369cdd5
Managed Height-for-Width in gtk
anaselli Feb 15, 2026
6be1c62
better axpect on qt size management
anaselli Feb 15, 2026
e788a45
Layout on help dialog
anaselli Feb 15, 2026
9339db7
Minimum size on dialogs to test it works
anaselli Feb 15, 2026
13c1a88
do not force 640x480 size
anaselli Feb 15, 2026
073c502
pass-through mode for unchanged/fill alignment
anaselli Feb 15, 2026
a6e9efa
Height for width to try improving gtk image no that success though
anaselli Feb 15, 2026
647d80b
Added logging
anaselli Feb 15, 2026
08ea447
changed layout
anaselli Feb 15, 2026
e60a1ac
changed layout
anaselli Feb 15, 2026
3f3e151
checkbox aligned correctly
anaselli Feb 15, 2026
3d57a34
updated
anaselli Feb 15, 2026
d12cc53
Updated
anaselli Feb 15, 2026
289ac07
Change windows title after dialog creation to avoid changing application
anaselli Feb 15, 2026
e2d5068
updated
anaselli Feb 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 198 additions & 0 deletions docs/manatools_aui_api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# manatools AUI - Application API (YUI.application)

Overview
--------
The object returned by `YUI.app()` / `YUI.application()` / `YUI.yApp()` is the backend-specific Application object (Qt, GTK, or NCurses). Obtain it via:

```python
from manatools.aui.yui import YUI
app = YUI.app() # backend-specific application object
# aliases: YUI.application(), YUI.yApp()
```

This document lists the common methods that application code should use in a backend-agnostic way and highlights differences and missing documentation.

Common public methods (backend-agnostic)
---------------------------------------
These methods are implemented by backend application classes (Qt, GTK, NCurses). Signatures below are the expected API the application code should rely on.

- setApplicationTitle(title: str)
- Set the application title. Backends attempt to propagate it to windows/dialogs (Qt: QApplication; GTK: active windows; NCurses: terminal window title escape codes).

- applicationTitle() -> str
- Return current application title.

- setApplicationIcon(icon_spec: str)
- Set application icon specification (theme name or file path). Backends attempt to resolve and apply the icon where possible. Behavior varies by backend.

- applicationIcon() -> str
- Return the currently configured icon specification.

- setIconBasePath(path: str) / iconBasePath()
- Provide a base path used when resolving icon file names prior to theme lookup.

- setProductName(name: str) / productName() -> str
- Set/read product name metadata used by dialogs or platform integration.

- setApplicationName(name: str) / applicationName() -> str
- setVersion(version: str) / version() -> str
- setAuthors(authors: str) / authors() -> str
- setDescription(desc: str) / description() -> str
- setLicense(text: str) / license() -> str
- setCredits(credits: str) / credits() -> str
- setInformation(info: str) / information() -> str
- setLogo(path: str) / logo() -> str
- About dialog and metadata setters/getters.

- isTextMode() -> bool
- Returns True for text-mode (NCurses) backend. Use to adapt UI or behavior.

- busyCursor() / normalCursor()
- Show/hide busy cursor. Implementations differ (Qt uses override cursor; GTK and NCurses may be no-op or best-effort).

File chooser helpers (common usage)
-----------------------------------
These functions present file/directory selection dialogs. Implementations differ across backends; calls should be treated as blocking helpers that return the selected path or an empty string when canceled.

- askForExistingDirectory(startDir: str, headline: str) -> str
- askForExistingFile(startWith: str, filter: str, headline: str) -> str
- askForSaveFileName(startWith: str, filter: str, headline: str) -> str

Notes:
- `filter` is typically a semicolon-separated list of patterns like `"*.txt;*.md"`.
- Qt uses QFileDialog (synchronous).
- GTK attempts Gtk.FileDialog (GTK4.10+) and supports portals/fallbacks.
- NCurses provides an in-UI browsing overlay; behavior and filter parsing are implemented in Python.

Practical examples
------------------
Set title and icon (backend-agnostic):

```python
app = YUI.app()
app.setApplicationTitle("MyApp")
app.setIconBasePath("/usr/share/myapp/icons")
app.setApplicationIcon("myapp-icon") # theme name or absolute path
```

Open a file chooser:

```python
fn = app.askForExistingFile("/home/user", "*.iso;*.img", "Open image")
if fn:
print("Selected:", fn)
```

## Factory createXXX methods

The widget factory (returned by `YUI.ui().widgetFactory()` / `YUI_ui().widgetFactory()`) provides unified constructors for UI widgets across backends. Use the factory to create dialogs, layout containers and widgets in a backend-agnostic way.

General pattern:
- Call `factory.createXxx(parent, ...)` to create widget X.
- The returned object is a YWidget subclass; call widget methods (setValue, setLabel, addItem, etc.) and use `dialog.waitForEvent()` loop to handle events.

Common factory methods (signatures and brief notes)

- createMainDialog(color_mode=YDialogColorMode.YDialogNormalColor)
- Returns a main dialog (blocking UI container).
- createPopupDialog(color_mode=YDialogColorMode.YDialogNormalColor)
- Returns a popup dialog.

Layout containers
- createVBox(parent)
- createHBox(parent)
- Vertical / horizontal layout containers (parent is a dialog or another container).

Common leaf widgets
- createPushButton(parent, label)
- Button widget. Use `setNotify()`, `setIcon()`, `setStretchable()`.
- createIconButton(parent, iconName, fallbackTextLabel)
- Convenience: pushbutton with icon.
- createLabel(parent, text, isHeading=False, isOutputField=False)
- createHeading(parent, label)
- Label / heading above controls.

Input and selection
- createInputField(parent, label, password_mode=False)
- Single-line text input.
- createMultiLineEdit(parent, label)
- createIntField(parent, label, minVal, maxVal, initialVal)
- createCheckBox(parent, label, is_checked=False)
- createPasswordField(parent, label)
- createComboBox(parent, label, editable=False)
- Combo/select widget. Supports addItem/addItems/deleteAllItems and icons where supported.
- createSelectionBox(parent, label)
- createMultiSelectionBox(parent, label)
- Single- or multi-selection lists. Use `addItem`, `addItems`, `deleteAllItems`, `selectItem`, `selectedItems()`.

Progress/visual widgets
- createProgressBar(parent, label, max_value=100)
- createImage(parent, imageFileName)
- Backends may support autoscale/stretch; icon/image loading depends on backend.
- createTree(parent, label, multiselection=False, recursiveselection=False)
- createTable(parent, header: YTableHeader, multiSelection=False)
- createRichText(parent, text="", plainTextMode=False)
- createLogView(parent, label, visibleLines, storedLines=0)

Grouping / frames / special widgets
- createFrame(parent, label="")
- createCheckBoxFrame(parent, label="", checked=False)
- createRadioButton(parent, label="", isChecked=False)
- createReplacePoint(parent)
- createDumbTab(parent)

Layout helpers
- createSpacing(parent, dim: YUIDimension, stretchable: bool = False, size_px: int = 0)
- createHStretch(parent), createVStretch(parent)
- createHSpacing(parent, size_px=8), createVSpacing(parent, size_px=16)

Misc
- createMenuBar(parent)
- createSlider(parent, label, minVal, maxVal, initialVal)
- createDateField(parent, label)
- createTimeField(parent, label)

Notes and backend differences
- All `createXXX` methods return backend-specific widget objects implementing the YWidget API. Call generic methods (setLabel, setValue, addItem, deleteAllItems, setStretchable, setWeight) on those objects.
- Not all backends support icons, autoscaling or the same filter semantics; the factory hides creation differences but some features are best-effort per backend.
- For selection widgets (ComboBox / SelectionBox / Tree / Table):
- Use addItem/addItems/deleteAllItems at runtime to keep the widget and backend in sync.
- Only one item should be selected in single-selection widgets; when selecting programmatically ensure previous selection is cleared (most backends handle this if you use widget.setValue or item.setSelected()).
- Icons, if provided via YItem.iconName(), are displayed on GUI backends (GTK/Qt) when supported; ncurses ignores icons.

Minimal example
```python
# create a dialog with a combo and a button (backend-agnostic)
ui = YUI_ui()
factory = ui.widgetFactory()
dlg = factory.createMainDialog()
vbox = factory.createVBox(dlg)
combo = factory.createComboBox(vbox, "Choose:", editable=False)
combo.addItems([YItem("One"), YItem("Two", selected=True), YItem("Three")])
btn = factory.createPushButton(vbox, "OK")

# basic event loop
while True:
ev = dlg.waitForEvent()
if ev.eventType() == YEventType.CancelEvent:
dlg.destroy()
break
if ev.eventType() == YEventType.WidgetEvent and ev.widget() == btn:
print("Selected:", combo.value())
dlg.destroy()
break
```

Backend differences and caveats
-------------------------------
- Icon resolution: backends first try icon base path, then theme lookup. Icons may not be available or may be treated differently (GTK uses GdkPixbuf, Qt uses QIcon, NCurses ignores icons).
- File dialogs:
- GTK uses Gtk.FileDialog on modern GTK4; availability depends on GTK version and platform (portal fallbacks exist).
- NCurses dialog is implemented with an internal overlay; features (filters, navigation) differ from GUI backends.
- Cursor APIs and certain visual behaviors are backend-specific and may be no-op in text mode.
- Methods that interact with windows/views (e.g., applying an icon to open dialogs) perform best-effort updates and may silently fail if no dialog/window is available.


License and contribution
------------------------
This document is provided to help developers use the cross-backend Application API. Please update the code docstrings and this document when API changes occur.
Empty file added manatools/aui/__init__.py
Empty file.
36 changes: 36 additions & 0 deletions manatools/aui/backends/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""
manatools.aui.backends package initializer.

Provides a small, lazy-loading shim so callers can import submodules
(e.g. 'from manatools.aui.backends.gtk import ...') while keeping the
package import lightweight and well-logged.
"""
import importlib
import logging
from types import ModuleType

_logger = logging.getLogger("manatools.aui.backends")

# advertised subpackages (may be absent if not installed)
__all__ = ["gtk", "qt", "ncurses"]

def __getattr__(name: str) -> ModuleType:
"""
Lazy-import backend submodules on attribute access (PEP 562).
Raises AttributeError if submodule cannot be imported.
"""
if name in __all__:
full = f"{__name__}.{name}"
try:
mod = importlib.import_module(full)
globals()[name] = mod
return mod
except Exception:
_logger.debug("Failed to import backend submodule %s", full, exc_info=True)
# re-raise as AttributeError to match import semantics
raise AttributeError(f"cannot import name {name!r} from {__name__}") from None
raise AttributeError(f"module {__name__} has no attribute {name!r}")

def __dir__():
# expose advertised backends plus any already imported names
return sorted(list(__all__) + [k for k in globals().keys() if not k.startswith("_")])
62 changes: 62 additions & 0 deletions manatools/aui/backends/curses/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from .dialogcurses import YDialogCurses
from .checkboxcurses import YCheckBoxCurses
from .hboxcurses import YHBoxCurses
from .vboxcurses import YVBoxCurses
from .labelcurses import YLabelCurses
from .pushbuttoncurses import YPushButtonCurses
from .treecurses import YTreeCurses
from .alignmentcurses import YAlignmentCurses
from .comboboxcurses import YComboBoxCurses
from .framecurses import YFrameCurses
from .inputfieldcurses import YInputFieldCurses
from .selectionboxcurses import YSelectionBoxCurses
from .checkboxframecurses import YCheckBoxFrameCurses
from .progressbarcurses import YProgressBarCurses
from .radiobuttoncurses import YRadioButtonCurses
from .tablecurses import YTableCurses
from .richtextcurses import YRichTextCurses
from .menubarcurses import YMenuBarCurses
from .replacepointcurses import YReplacePointCurses
from .intfieldcurses import YIntFieldCurses
from .datefieldcurses import YDateFieldCurses
from .multilineeditcurses import YMultiLineEditCurses
from .spacingcurses import YSpacingCurses
from .imagecurses import YImageCurses
from .dumbtabcurses import YDumbTabCurses
from .slidercurses import YSliderCurses
from .logviewcurses import YLogViewCurses
from .timefieldcurses import YTimeFieldCurses
from .panedcurses import YPanedCurses

__all__ = [
"YDialogCurses",
"YFrameCurses",
"YVBoxCurses",
"YHBoxCurses",
"YTreeCurses",
"YSelectionBoxCurses",
"YLabelCurses",
"YPushButtonCurses",
"YInputFieldCurses",
"YCheckBoxCurses",
"YComboBoxCurses",
"YAlignmentCurses",
"YCheckBoxFrameCurses",
"YProgressBarCurses",
"YRadioButtonCurses",
"YTableCurses",
"YRichTextCurses",
"YMenuBarCurses",
"YReplacePointCurses",
"YIntFieldCurses",
"YDateFieldCurses",
"YMultiLineEditCurses",
"YSpacingCurses",
"YImageCurses",
"YDumbTabCurses",
"YSliderCurses",
"YLogViewCurses",
"YTimeFieldCurses",
"YPanedCurses",
# ... add new widgets here ...
]
Loading