tuile 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +159 -49
- data/README.md +53 -17
- data/book/04-event-loop.md +12 -12
- data/book/05-focus.md +152 -22
- data/book/06-theming.md +105 -25
- data/book/07-components.md +531 -50
- data/book/08-testing.md +100 -20
- data/book/10-locale.md +216 -0
- data/book/README.md +19 -9
- data/examples/file_commander.rb +14 -5
- data/examples/hello_world.rb +17 -4
- data/examples/sampler.rb +654 -40
- data/lib/tuile/component/abstract_string_field.rb +114 -68
- data/lib/tuile/component/abstract_wrapping_field.rb +279 -0
- data/lib/tuile/component/big_decimal_field.rb +52 -79
- data/lib/tuile/component/button.rb +8 -8
- data/lib/tuile/component/checkbox.rb +9 -9
- data/lib/tuile/component/checkbox_group.rb +38 -21
- data/lib/tuile/component/combo_box.rb +102 -59
- data/lib/tuile/component/confirm_window.rb +7 -5
- data/lib/tuile/component/date_field.rb +347 -0
- data/lib/tuile/component/date_time_field.rb +275 -0
- data/lib/tuile/component/float_field.rb +57 -82
- data/lib/tuile/component/has_bad_input.rb +88 -0
- data/lib/tuile/component/has_caption.rb +8 -0
- data/lib/tuile/component/has_content.rb +32 -13
- data/lib/tuile/component/has_placeholder.rb +62 -0
- data/lib/tuile/component/has_validation.rb +115 -0
- data/lib/tuile/component/has_value.rb +28 -1
- data/lib/tuile/component/integer_field.rb +51 -78
- data/lib/tuile/component/label.rb +7 -39
- data/lib/tuile/component/layout/box.rb +90 -19
- data/lib/tuile/component/layout.rb +15 -5
- data/lib/tuile/component/list.rb +53 -38
- data/lib/tuile/component/list_dropdown.rb +7 -3
- data/lib/tuile/component/menu_bar/cascade.rb +5 -5
- data/lib/tuile/component/menu_bar.rb +18 -18
- data/lib/tuile/component/notification.rb +32 -18
- data/lib/tuile/component/overlay.rb +26 -8
- data/lib/tuile/component/picker_window.rb +27 -8
- data/lib/tuile/component/popup.rb +2 -2
- data/lib/tuile/component/progress_bar.rb +10 -4
- data/lib/tuile/component/radio_group.rb +41 -23
- data/lib/tuile/component/select.rb +23 -16
- data/lib/tuile/component/slot.rb +3 -3
- data/lib/tuile/component/tab_sheet.rb +6 -6
- data/lib/tuile/component/tabs.rb +11 -11
- data/lib/tuile/component/text_area.rb +26 -18
- data/lib/tuile/component/text_field.rb +55 -26
- data/lib/tuile/component/text_view.rb +40 -19
- data/lib/tuile/component/time_field.rb +479 -0
- data/lib/tuile/component/window.rb +26 -13
- data/lib/tuile/component.rb +635 -131
- data/lib/tuile/event_queue.rb +4 -4
- data/lib/tuile/fake_event_queue.rb +1 -1
- data/lib/tuile/fake_screen.rb +95 -3
- data/lib/tuile/final.rb +75 -0
- data/lib/tuile/locale.rb +851 -0
- data/lib/tuile/mouse/router.rb +217 -0
- data/lib/tuile/mouse.rb +177 -0
- data/lib/tuile/screen.rb +219 -68
- data/lib/tuile/screen_pane.rb +51 -42
- data/lib/tuile/styled_string.rb +5 -5
- data/lib/tuile/testing.rb +198 -0
- data/lib/tuile/theme.rb +110 -32
- data/lib/tuile/version.rb +1 -1
- data/lib/tuile/vertical_scroll_bar.rb +88 -12
- data/lib/tuile.rb +1 -0
- data/sig/tuile.rbs +4595 -825
- metadata +14 -9
- data/COMPARISON.md +0 -101
- data/DECISIONS.md +0 -5422
- data/TERMINOLOGY.md +0 -71
- data/ideas/arrow-key-navigation.md +0 -221
- data/ideas/modal-backdrop.md +0 -24
- data/ideas/new-components.md +0 -124
- data/ideas/per-component-buffers.md +0 -55
- data/lib/tuile/mouse_event.rb +0 -68
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tuile
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Martin Vysny
|
|
@@ -113,11 +113,8 @@ extra_rdoc_files: []
|
|
|
113
113
|
files:
|
|
114
114
|
- CHANGELOG.md
|
|
115
115
|
- CODE_OF_CONDUCT.md
|
|
116
|
-
- COMPARISON.md
|
|
117
|
-
- DECISIONS.md
|
|
118
116
|
- LICENSE.txt
|
|
119
117
|
- README.md
|
|
120
|
-
- TERMINOLOGY.md
|
|
121
118
|
- book/01-first-app.md
|
|
122
119
|
- book/02-repaint.md
|
|
123
120
|
- book/03-layout.md
|
|
@@ -127,14 +124,11 @@ files:
|
|
|
127
124
|
- book/07-components.md
|
|
128
125
|
- book/08-testing.md
|
|
129
126
|
- book/09-styled-text.md
|
|
127
|
+
- book/10-locale.md
|
|
130
128
|
- book/README.md
|
|
131
129
|
- examples/file_commander.rb
|
|
132
130
|
- examples/hello_world.rb
|
|
133
131
|
- examples/sampler.rb
|
|
134
|
-
- ideas/arrow-key-navigation.md
|
|
135
|
-
- ideas/modal-backdrop.md
|
|
136
|
-
- ideas/new-components.md
|
|
137
|
-
- ideas/per-component-buffers.md
|
|
138
132
|
- lib/tuile.rb
|
|
139
133
|
- lib/tuile/ansi.rb
|
|
140
134
|
- lib/tuile/buffer.rb
|
|
@@ -142,15 +136,21 @@ files:
|
|
|
142
136
|
- lib/tuile/color_depth.rb
|
|
143
137
|
- lib/tuile/component.rb
|
|
144
138
|
- lib/tuile/component/abstract_string_field.rb
|
|
139
|
+
- lib/tuile/component/abstract_wrapping_field.rb
|
|
145
140
|
- lib/tuile/component/big_decimal_field.rb
|
|
146
141
|
- lib/tuile/component/button.rb
|
|
147
142
|
- lib/tuile/component/checkbox.rb
|
|
148
143
|
- lib/tuile/component/checkbox_group.rb
|
|
149
144
|
- lib/tuile/component/combo_box.rb
|
|
150
145
|
- lib/tuile/component/confirm_window.rb
|
|
146
|
+
- lib/tuile/component/date_field.rb
|
|
147
|
+
- lib/tuile/component/date_time_field.rb
|
|
151
148
|
- lib/tuile/component/float_field.rb
|
|
149
|
+
- lib/tuile/component/has_bad_input.rb
|
|
152
150
|
- lib/tuile/component/has_caption.rb
|
|
153
151
|
- lib/tuile/component/has_content.rb
|
|
152
|
+
- lib/tuile/component/has_placeholder.rb
|
|
153
|
+
- lib/tuile/component/has_validation.rb
|
|
154
154
|
- lib/tuile/component/has_value.rb
|
|
155
155
|
- lib/tuile/component/info_window.rb
|
|
156
156
|
- lib/tuile/component/integer_field.rb
|
|
@@ -180,13 +180,17 @@ files:
|
|
|
180
180
|
- lib/tuile/component/text_area/wrapped_text.rb
|
|
181
181
|
- lib/tuile/component/text_field.rb
|
|
182
182
|
- lib/tuile/component/text_view.rb
|
|
183
|
+
- lib/tuile/component/time_field.rb
|
|
183
184
|
- lib/tuile/component/window.rb
|
|
184
185
|
- lib/tuile/event_queue.rb
|
|
185
186
|
- lib/tuile/fake_event_queue.rb
|
|
186
187
|
- lib/tuile/fake_screen.rb
|
|
188
|
+
- lib/tuile/final.rb
|
|
187
189
|
- lib/tuile/fraction.rb
|
|
188
190
|
- lib/tuile/keys.rb
|
|
189
|
-
- lib/tuile/
|
|
191
|
+
- lib/tuile/locale.rb
|
|
192
|
+
- lib/tuile/mouse.rb
|
|
193
|
+
- lib/tuile/mouse/router.rb
|
|
190
194
|
- lib/tuile/point.rb
|
|
191
195
|
- lib/tuile/rect.rb
|
|
192
196
|
- lib/tuile/screen.rb
|
|
@@ -194,6 +198,7 @@ files:
|
|
|
194
198
|
- lib/tuile/size.rb
|
|
195
199
|
- lib/tuile/styled_string.rb
|
|
196
200
|
- lib/tuile/terminal_background.rb
|
|
201
|
+
- lib/tuile/testing.rb
|
|
197
202
|
- lib/tuile/theme.rb
|
|
198
203
|
- lib/tuile/theme_def.rb
|
|
199
204
|
- lib/tuile/version.rb
|
data/COMPARISON.md
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
# COMPARISON.md
|
|
2
|
-
|
|
3
|
-
Tuile's neighbours: what else exists, and — the question this file exists to
|
|
4
|
-
answer — how much of it you can actually *reach from Ruby* on an ordinary Linux
|
|
5
|
-
box without building bindings first.
|
|
6
|
-
|
|
7
|
-
The short version: of the three alternatives the README names, **none** is
|
|
8
|
-
callable from Ruby via the distro package manager. What is callable is a pair
|
|
9
|
-
of curses bindings that sit *below* Tuile, and the tty-toolkit that Tuile is
|
|
10
|
-
already built on.
|
|
11
|
-
|
|
12
|
-
## The alternatives
|
|
13
|
-
|
|
14
|
-
The three the README points here for:
|
|
15
|
-
|
|
16
|
-
- **[tty-toolkit](https://ttytoolkit.org/)** (`tty-prompt`, `tty-cursor`, …) —
|
|
17
|
-
low-level building blocks, not a framework: no component tree, no event loop,
|
|
18
|
-
no invalidation. Tuile sits on top of `tty-cursor` / `tty-screen` and adds
|
|
19
|
-
the framework layer.
|
|
20
|
-
- **[vedeu](https://github.com/gavinlaking/vedeu)** — the closest Ruby
|
|
21
|
-
comparable, unmaintained since 2017.
|
|
22
|
-
- **[ratatui](https://github.com/ratatui/ratatui)** — the popular Rust TUI
|
|
23
|
-
framework; its immediate-mode API is closer to `tty-prompt` than to Tuile's
|
|
24
|
-
retained component tree.
|
|
25
|
-
|
|
26
|
-
Beyond those, DECISIONS.md surveys **Textual**, **urwid**, **brick**,
|
|
27
|
-
**Lipgloss**, **notcurses**, **FTXUI** and **Ink** — but as per-decision
|
|
28
|
-
precedent inside `D_` entries (`D_bg_inherit`, `D_key_dispatch`,
|
|
29
|
-
`D_box_layouts`, `D_list_items` are the dense ones), not as a roster. Look
|
|
30
|
-
there for "what does Textual do about focus-first key dispatch", not for
|
|
31
|
-
"should I use Textual".
|
|
32
|
-
|
|
33
|
-
## Reachable from Ruby, via apt
|
|
34
|
-
|
|
35
|
-
Surveyed on Ubuntu 26.04 (resolute) in 2026-08, against the distro's own
|
|
36
|
-
`/usr/bin/ruby` 3.3.8 — which matters, see the caveats below.
|
|
37
|
-
|
|
38
|
-
| Candidate | apt package | Callable from Ruby? |
|
|
39
|
-
|---|---|---|
|
|
40
|
-
| vedeu | *no package at all* | — |
|
|
41
|
-
| ratatui | `librust-ratatui-dev` (Rust source only) | no |
|
|
42
|
-
| Textual | `python3-textual` | no |
|
|
43
|
-
| urwid | `python3-urwid` | no |
|
|
44
|
-
| notcurses | `libnotcurses-dev`, `notcurses-bin` | no bindings — you would write the FFI |
|
|
45
|
-
| CDK, newt | `libcdk5-dev`, `libnewt-dev` | C and Python only |
|
|
46
|
-
| tty-toolkit | `ruby-tty-prompt`, `-cursor`, `-screen`, `-reader`, `-color`, `-pastel` | **yes** — but this is Tuile's own substrate |
|
|
47
|
-
| curses | `ruby-curses` | **yes** |
|
|
48
|
-
| ncurses + panel/form/menu | `ruby-ncurses` | **yes** — the closest of the lot |
|
|
49
|
-
|
|
50
|
-
`dialog` and `whiptail` are also packaged and can be shelled out to from Ruby,
|
|
51
|
-
but a subprocess that paints one dialog and exits is a different tool from a
|
|
52
|
-
framework that owns a running screen; they are out of scope here.
|
|
53
|
-
|
|
54
|
-
### The two curses bindings
|
|
55
|
-
|
|
56
|
-
Neither is in the README's list, and between them they are the only way to
|
|
57
|
-
reach anything Tuile-shaped from Ruby without a compiler and a binding project.
|
|
58
|
-
|
|
59
|
-
- **`ruby-curses`** — the [ruby/curses](https://github.com/ruby/curses) gem,
|
|
60
|
-
wide-char, shipping `curses.so` plus a gemspec under
|
|
61
|
-
`rubygems-integration`, so `gem "curses"` resolves under Bundler with no
|
|
62
|
-
build step. Strictly low-level: windows, `addstr`, `getch`. No widgets, no
|
|
63
|
-
tree, no invalidation — *below* tty-toolkit, not beside it.
|
|
64
|
-
- **`ruby-ncurses`** — the `ncursesw` gem
|
|
65
|
-
([sup-heliotrope fork](https://github.com/sup-heliotrope/ncursesw-ruby)), and
|
|
66
|
-
the interesting one. Its extension links `libpanelw`, `libformw` **and**
|
|
67
|
-
`libmenu`, and exports `new_form` / `new_menu` / `form_driver` /
|
|
68
|
-
`menu_driver`; `examples/form.rb` ships in the package. So you get
|
|
69
|
-
overlapping windows (Tuile's popup stack), field editing with validation, and
|
|
70
|
-
list selection, out of the box.
|
|
71
|
-
|
|
72
|
-
### Why `ruby-ncurses` still is not a substitute
|
|
73
|
-
|
|
74
|
-
The gap is the framework layer, and the framework layer is the whole of Tuile.
|
|
75
|
-
ncurses forms and menus are a *fixed* widget set driven by a
|
|
76
|
-
`form_driver(request)` call. What is missing, in Tuile's own terms:
|
|
77
|
-
|
|
78
|
-
- no `parent` / `children` tree you compose your own components into — you
|
|
79
|
-
cannot write a component, only configure theirs;
|
|
80
|
-
- no top-down layout: nothing assigns a child its `rect`, so every rectangle is
|
|
81
|
-
arithmetic you keep by hand (book ch3 for why Tuile made that a rule rather
|
|
82
|
-
than an engine);
|
|
83
|
-
- no invalidate-and-batch-repaint, so no minimal-diff flush — you decide when
|
|
84
|
-
to `refresh` and pay for whatever you redraw;
|
|
85
|
-
- no theme or inherited `bg_color`, no `HasValue` value seam a forms layer can
|
|
86
|
-
iterate, no `FakeScreen` to assert painted cells against.
|
|
87
|
-
|
|
88
|
-
You would be building Tuile *on top of* it, not replacing Tuile with it — and
|
|
89
|
-
since `ncursesw-ruby` is a 1.4.x mirror of the C API, whatever you built would
|
|
90
|
-
sit directly on `WINDOW*` semantics.
|
|
91
|
-
|
|
92
|
-
### Caveats on the apt route
|
|
93
|
-
|
|
94
|
-
- **`ruby-ncurses` and `ruby-curses` are built against the distro's Ruby** —
|
|
95
|
-
`Depends: libruby (<< 1:3.4~)` on resolute. They are invisible to any
|
|
96
|
-
rbenv/rvm/chruby Ruby, and they break on a distro Ruby upgrade. The gems
|
|
97
|
-
(`gem install curses` / `ncursesw`) compile against `libncurses-dev` and do
|
|
98
|
-
not have that problem.
|
|
99
|
-
- **The table above is a snapshot of one release.** Package availability is the
|
|
100
|
-
fastest-rotting fact in this file; re-run `apt-cache policy <pkg>` before
|
|
101
|
-
trusting a row.
|