tuile 0.15.0 → 0.17.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 +229 -80
- data/README.md +49 -24
- data/book/02-repaint.md +47 -19
- data/book/03-layout.md +98 -49
- data/book/04-event-loop.md +17 -16
- data/book/05-focus.md +106 -34
- data/book/06-theming.md +108 -38
- data/book/07-components.md +249 -46
- data/book/08-testing.md +134 -32
- data/book/10-locale.md +3 -3
- data/book/README.md +11 -10
- data/examples/file_commander.rb +52 -32
- data/examples/hello_world.rb +18 -5
- data/examples/sampler.rb +576 -146
- data/lib/tuile/buffer.rb +12 -1
- data/lib/tuile/canvas/backend.rb +46 -0
- data/lib/tuile/canvas.rb +212 -0
- data/lib/tuile/color.rb +38 -9
- data/lib/tuile/component/abstract_string_field.rb +96 -97
- data/lib/tuile/component/abstract_wrapping_field.rb +99 -58
- data/lib/tuile/component/big_decimal_field.rb +7 -6
- data/lib/tuile/component/button.rb +27 -19
- data/lib/tuile/component/checkbox.rb +21 -19
- data/lib/tuile/component/checkbox_group.rb +17 -18
- data/lib/tuile/component/combo_box.rb +69 -64
- data/lib/tuile/component/confirm_window.rb +34 -27
- data/lib/tuile/component/date_field.rb +50 -18
- data/lib/tuile/component/date_time_field.rb +319 -0
- data/lib/tuile/component/fill.rb +93 -0
- data/lib/tuile/component/float_field.rb +7 -6
- data/lib/tuile/component/form_item.rb +250 -0
- data/lib/tuile/component/form_layout.rb +206 -0
- data/lib/tuile/component/has_bad_input.rb +99 -28
- data/lib/tuile/component/has_caption.rb +14 -5
- data/lib/tuile/component/has_content.rb +8 -15
- data/lib/tuile/component/has_placeholder.rb +1 -1
- data/lib/tuile/component/has_validation.rb +40 -14
- data/lib/tuile/component/has_value.rb +71 -17
- data/lib/tuile/component/integer_field.rb +7 -6
- data/lib/tuile/component/label.rb +8 -15
- data/lib/tuile/component/layout/absolute.rb +86 -0
- data/lib/tuile/component/layout/box.rb +38 -60
- data/lib/tuile/component/layout.rb +127 -13
- data/lib/tuile/component/list.rb +233 -120
- data/lib/tuile/component/list_dropdown.rb +151 -91
- data/lib/tuile/component/menu_bar/cascade.rb +102 -32
- data/lib/tuile/component/menu_bar.rb +102 -82
- data/lib/tuile/component/notification.rb +76 -49
- data/lib/tuile/component/overlay.rb +217 -58
- data/lib/tuile/component/password_field.rb +1 -8
- data/lib/tuile/component/picker_window.rb +41 -17
- data/lib/tuile/component/popup.rb +15 -26
- data/lib/tuile/component/progress_bar.rb +17 -11
- data/lib/tuile/component/radio_group.rb +16 -17
- data/lib/tuile/component/scroller.rb +266 -0
- data/lib/tuile/component/select.rb +26 -43
- data/lib/tuile/component/slot.rb +4 -5
- data/lib/tuile/component/tab_sheet.rb +27 -34
- data/lib/tuile/component/tabs.rb +49 -34
- data/lib/tuile/component/text_area/wrapped_text.rb +1 -1
- data/lib/tuile/component/text_area.rb +32 -28
- data/lib/tuile/component/text_field.rb +68 -50
- data/lib/tuile/component/text_view.rb +157 -89
- data/lib/tuile/component/time_field.rb +51 -21
- data/lib/tuile/component/vertical_scroll_bar.rb +257 -0
- data/lib/tuile/component/window.rb +27 -26
- data/lib/tuile/component.rb +653 -323
- data/lib/tuile/component_background.rb +177 -0
- data/lib/tuile/component_util.rb +43 -0
- data/lib/tuile/event.rb +29 -0
- data/lib/tuile/event_queue.rb +18 -4
- data/lib/tuile/fake_event_queue.rb +1 -1
- data/lib/tuile/fake_screen.rb +120 -7
- data/lib/tuile/keys.rb +15 -6
- data/lib/tuile/layout_pass.rb +180 -0
- data/lib/tuile/listeners.rb +219 -0
- data/lib/tuile/mouse/router.rb +233 -0
- data/lib/tuile/mouse.rb +244 -0
- data/lib/tuile/point.rb +6 -0
- data/lib/tuile/rect.rb +33 -0
- data/lib/tuile/screen.rb +510 -138
- data/lib/tuile/screen_pane.rb +185 -67
- data/lib/tuile/strict_layout.rb +127 -0
- data/lib/tuile/styled_string.rb +144 -14
- data/lib/tuile/testing/gestures.rb +35 -0
- data/lib/tuile/testing.rb +316 -42
- data/lib/tuile/theme.rb +192 -53
- data/lib/tuile/theme_def.rb +4 -0
- data/lib/tuile/version.rb +1 -1
- data/lib/tuile.rb +53 -0
- data/sig/tuile.rbs +6084 -1507
- metadata +19 -17
- data/COMPARISON.md +0 -101
- data/DECISIONS.md +0 -8562
- data/TERMINOLOGY.md +0 -85
- data/ideas/arrow-key-navigation.md +0 -221
- data/ideas/binder.md +0 -177
- data/ideas/composite-field.md +0 -77
- data/ideas/focus-accent.md +0 -116
- data/ideas/form-layout.md +0 -151
- data/ideas/hover/probe.rb +0 -241
- data/ideas/hover/probe_spec.rb +0 -82
- data/ideas/hover.md +0 -909
- data/ideas/modal-backdrop.md +0 -24
- data/ideas/new-components.md +0 -144
- data/ideas/per-component-buffers.md +0 -55
- data/lib/tuile/mouse_event.rb +0 -68
- data/lib/tuile/vertical_scroll_bar.rb +0 -122
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.17.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
|
|
@@ -132,20 +129,11 @@ files:
|
|
|
132
129
|
- examples/file_commander.rb
|
|
133
130
|
- examples/hello_world.rb
|
|
134
131
|
- examples/sampler.rb
|
|
135
|
-
- ideas/arrow-key-navigation.md
|
|
136
|
-
- ideas/binder.md
|
|
137
|
-
- ideas/composite-field.md
|
|
138
|
-
- ideas/focus-accent.md
|
|
139
|
-
- ideas/form-layout.md
|
|
140
|
-
- ideas/hover.md
|
|
141
|
-
- ideas/hover/probe.rb
|
|
142
|
-
- ideas/hover/probe_spec.rb
|
|
143
|
-
- ideas/modal-backdrop.md
|
|
144
|
-
- ideas/new-components.md
|
|
145
|
-
- ideas/per-component-buffers.md
|
|
146
132
|
- lib/tuile.rb
|
|
147
133
|
- lib/tuile/ansi.rb
|
|
148
134
|
- lib/tuile/buffer.rb
|
|
135
|
+
- lib/tuile/canvas.rb
|
|
136
|
+
- lib/tuile/canvas/backend.rb
|
|
149
137
|
- lib/tuile/color.rb
|
|
150
138
|
- lib/tuile/color_depth.rb
|
|
151
139
|
- lib/tuile/component.rb
|
|
@@ -158,7 +146,11 @@ files:
|
|
|
158
146
|
- lib/tuile/component/combo_box.rb
|
|
159
147
|
- lib/tuile/component/confirm_window.rb
|
|
160
148
|
- lib/tuile/component/date_field.rb
|
|
149
|
+
- lib/tuile/component/date_time_field.rb
|
|
150
|
+
- lib/tuile/component/fill.rb
|
|
161
151
|
- lib/tuile/component/float_field.rb
|
|
152
|
+
- lib/tuile/component/form_item.rb
|
|
153
|
+
- lib/tuile/component/form_layout.rb
|
|
162
154
|
- lib/tuile/component/has_bad_input.rb
|
|
163
155
|
- lib/tuile/component/has_caption.rb
|
|
164
156
|
- lib/tuile/component/has_content.rb
|
|
@@ -169,6 +161,7 @@ files:
|
|
|
169
161
|
- lib/tuile/component/integer_field.rb
|
|
170
162
|
- lib/tuile/component/label.rb
|
|
171
163
|
- lib/tuile/component/layout.rb
|
|
164
|
+
- lib/tuile/component/layout/absolute.rb
|
|
172
165
|
- lib/tuile/component/layout/box.rb
|
|
173
166
|
- lib/tuile/component/layout/horizontal.rb
|
|
174
167
|
- lib/tuile/component/layout/vertical.rb
|
|
@@ -185,6 +178,7 @@ files:
|
|
|
185
178
|
- lib/tuile/component/popup.rb
|
|
186
179
|
- lib/tuile/component/progress_bar.rb
|
|
187
180
|
- lib/tuile/component/radio_group.rb
|
|
181
|
+
- lib/tuile/component/scroller.rb
|
|
188
182
|
- lib/tuile/component/select.rb
|
|
189
183
|
- lib/tuile/component/slot.rb
|
|
190
184
|
- lib/tuile/component/tab_sheet.rb
|
|
@@ -194,27 +188,35 @@ files:
|
|
|
194
188
|
- lib/tuile/component/text_field.rb
|
|
195
189
|
- lib/tuile/component/text_view.rb
|
|
196
190
|
- lib/tuile/component/time_field.rb
|
|
191
|
+
- lib/tuile/component/vertical_scroll_bar.rb
|
|
197
192
|
- lib/tuile/component/window.rb
|
|
193
|
+
- lib/tuile/component_background.rb
|
|
194
|
+
- lib/tuile/component_util.rb
|
|
195
|
+
- lib/tuile/event.rb
|
|
198
196
|
- lib/tuile/event_queue.rb
|
|
199
197
|
- lib/tuile/fake_event_queue.rb
|
|
200
198
|
- lib/tuile/fake_screen.rb
|
|
201
199
|
- lib/tuile/final.rb
|
|
202
200
|
- lib/tuile/fraction.rb
|
|
203
201
|
- lib/tuile/keys.rb
|
|
202
|
+
- lib/tuile/layout_pass.rb
|
|
203
|
+
- lib/tuile/listeners.rb
|
|
204
204
|
- lib/tuile/locale.rb
|
|
205
|
-
- lib/tuile/
|
|
205
|
+
- lib/tuile/mouse.rb
|
|
206
|
+
- lib/tuile/mouse/router.rb
|
|
206
207
|
- lib/tuile/point.rb
|
|
207
208
|
- lib/tuile/rect.rb
|
|
208
209
|
- lib/tuile/screen.rb
|
|
209
210
|
- lib/tuile/screen_pane.rb
|
|
210
211
|
- lib/tuile/size.rb
|
|
212
|
+
- lib/tuile/strict_layout.rb
|
|
211
213
|
- lib/tuile/styled_string.rb
|
|
212
214
|
- lib/tuile/terminal_background.rb
|
|
213
215
|
- lib/tuile/testing.rb
|
|
216
|
+
- lib/tuile/testing/gestures.rb
|
|
214
217
|
- lib/tuile/theme.rb
|
|
215
218
|
- lib/tuile/theme_def.rb
|
|
216
219
|
- lib/tuile/version.rb
|
|
217
|
-
- lib/tuile/vertical_scroll_bar.rb
|
|
218
220
|
- sig/tuile.rbs
|
|
219
221
|
homepage: https://github.com/mvysny/tuile
|
|
220
222
|
licenses:
|
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.
|