widget gallery and compositor test bench
README.md (7.5K)
1 # cce-gallery
2
3 A widget gallery and compositor-behaviour test bench for the `cce` desktop
4 environment. It is a single `cce-ui` client (a real Wayland surface, drawn as
5 GPU primitives) that shows the toolkit's widgets, in every style each can take,
6 on one page, and doubles as the binary behind a set of test windows of
7 different shell types. It ships a `.desktop` entry under Utility/Development,
8 so it appears in the launcher.
9
10 It is a *visual* test harness: you look at what it draws and what the
11 compositor does with the windows it spawns. It has no automated test suite.
12
13 ## The page
14
15 One page, the widget gallery: one of each widget `cce_ui::widget` exports
16 that stands on its own. Inputs: Button, ButtonStrip, Checkbox, Toggle, Slider and
17 RangeSlider (bands that swell at the value, the one slider style), Slider2D,
18 Spinbox, Float3, TextBox, KeybindRecorder,
19 ColorSelector, FontSelector, Trackpad. Display: ProgressBar, UsageBar,
20 StatusDot, Separator, Splitter, InfoBox, InteractiveListItem, Breadcrumb,
21 TreeList, Plate, BevelPreview, RampPreview, Ramp. The MenuBar and StatusBar
22 frame it.
23
24 After those come the variants: every further look a widget can take, one
25 exhibit each, labelled `<Widget> (<style>)`. The toolkit's own variants are a
26 constructor (`Button::new_reset`, `new_list_row`, `new_menu_item`,
27 `new_copy_icon`), a builder (`with_readout` on Slider; `with_multiline`,
28 `with_draw_bg_border(false)` and `with_password` on TextBox; `with_vertical`
29 on ButtonStrip, and the Paginator built on it), or a per-widget override of a
30 config-wide style (`Slider::with_band`, the `style.control.slider.style`
31 look). ColorSelector shows its alpha swatch, and the four StatusDot statuses and the
32 plain Label round it off. When a widget gains a style, it gains an exhibit
33 here.
34
35 The relief-off look is not a variant. The header's `Style` dropdown, beside
36 `Layout`, switches every control between `Relief` and `Flat` at once
37 (`cce_ui::layout::set_control_relief`, what `control_relief = 0` configures
38 DE-wide): the toolkit reads the switch live, so each exhibit shows both looks
39 in place and no widget appears twice for its style alone. A widget that does
40 not follow the switch is a toolkit bug — every control's `with_raised` /
41 `with_recessed` is an override on top of the live default, not a copy of it.
42
43 Two `Group` lassos lie over the named exhibits — `Group`, loose around the
44 FontSelector and the StatusDot, and `Group (fitted)` around the top row,
45 fitted to the exhibit area's edges. The exhibits are laid out at that fit's
46 seat — a padding in from the sides, the lasso's headroom down — so the tab
47 stays inside the area and the row has the same padding on every side. A lasso is laid out by its members, not
48 by the strategy: under Mosaic it is the hull of wherever they landed.
49
50 Every exhibit is drawn at its toolkit default size — the control's configured
51 `style.control.<name>.height`, or the intrinsic size the widget declares — so
52 the page is a record of the defaults; only the draw-in canvases (Trackpad,
53 Plate, TreeList, the previews, the Ramp) are sized here. The `Layout` dropdown
54 lays the exhibits out with the toolkit's own `ContainerLayout` strategies —
55 Vertical, Columns, Grid, Adaptive Grid, Mosaic, Reverse Mosaic, Overlay — at
56 their default spacing (`layout::CONTROL_GAP`, one control height, the one gap
57 every strategy and row builder uses in both axes), so what you see is what a
58 container using that strategy does: a strategy places controls' CONTENT boxes,
59 a detached label hangs in the gap above its control, mixed labeled and
60 unlabeled controls line up by content (a strategy reserves the label row for
61 every child of a labeled container), every detached label is the adapter's — the
62 one label convention: drawn in the strip above the control at the same
63 `DETACHED_LABEL_INSET`, never inside the control's well (no control carves a
64 tab for its label; the recess is the control alone) — and every well, trough and raised plateau is carved
65 inside its widget's rect (`layout::carve_inside`) so a widget's footprint is
66 its rect. The exhibit
67 area below the dropdowns is a well sunk into the root plate (`well_floor` under
68 the exhibits, `well_rim` over them; flat, the shared hairline frame): the
69 exhibits are laid out on its floor inside the wall, and the area scrolls (wheel,
70 or the scrollbar at its right edge) when a layout runs past the window — an
71 exhibit scrolled to the edge slides under the wall, its text cut at the wall's
72 foot. `Color Ramp...` and `Ramp...` open the
73 ColorRamp and Ramp editors in their own child windows.
74
75 ## Child windows
76
77 The editors, and a set of test windows with no button of their own, are the
78 same binary run with `--child`:
79
80 ```
81 cce-gallery --child --type <Floating|Fullscreen|Utility|LayerTop|LayerOverlay|LayerBackground|Status|Ramp|ColorRamp>
82 [--width N --height N]
83 [--opacity --transparency 0.0-1.0]
84 [--no-border | --border-width N [--border-bevel]]
85 [--root-plate] [--menubar] [--statusbar]
86 ```
87
88 `--type Ramp` and `--type ColorRamp` host the toolkit's `Ramp` and `ColorRamp`
89 widgets on a root plate; the gallery's two buttons spawn them. The other seven
90 are the kinds of surface a toolkit client can be under cce, kept for driving
91 the compositor from a shadow session: Fullscreen sets the toplevel's
92 fullscreen flag, Utility answers the toolkit's `utility` hook, the three Layer
93 kinds answer its `layer` hook with a `LayerSettings` (Top anchored
94 left-top-right with an exclusive zone of its height, Overlay unanchored,
95 Background on every edge), and Status uses the app_id `cce-status-right-gallery`
96 so the compositor docks it into the bar. Every other kind's app_id is
97 `cce-gallery-child-<type>`, with `-noborder` appended when the border is
98 disabled, so `mode_rule`s can target it. The main window's `app_id` is
99 `cce-gallery`. A test window shows a one-line description, a `Close` button,
100 and the optional menu bar and status bar; `--border-width` and `--border-bevel`
101 are accepted but the child does not draw a bevel.
102
103 ## The bevel ramp file
104
105 The bevel cross-section is shared between the Ramp editor window and the main
106 window through `~/.config/cce/bevel_ramp.kdl` (next to the shared
107 `config.kdl`):
108
109 ```kdl
110 keys {
111 key pos=0 val=0
112 key pos=0.5 val=1
113 key pos=1 val=0
114 }
115 line_type "linear" // or "bezier"
116 ```
117
118 The Ramp child writes the file on every edit; the compositor and the other
119 apps that draw bevels read it.
120
121 ## Keybindings
122
123 Escape quits, unless a widget consumed it first (a dropdown closing its menu,
124 for example). Nothing else is bound; the `cce-gallery` domain of
125 `~/.config/cce/input.kdl` is free for the toolkit-wide chords.
126
127 ## Layout of the source
128
129 - `src/main.rs` — the `Application` impl. The gallery is a concretely typed
130 roster of 32 named slots (`GallerySlots`) followed by the variant exhibits
131 (`variant_exhibits`, a `Vec<Exhibit>` of boxed widgets), all addressed by
132 numeric index in the layout tables, visibility filters and dispatch loops;
133 child windows use the five-slot `ChildSlots`. `demo_positions` and
134 `child_positions` are the layout tables.
135 - `src/gallery_widgets.rs` — lookalikes of the retired toolkit `Plate` (an
136 exhibit) and root plate (the child windows' background).
137
138 ## Building and installing
139
140 This crate is one member of the `cce` multi-repo workspace; it builds
141 standalone or from the workspace root. Installation goes through `ccebuild`
142 (see `cce-compositor/WORKSPACE.md`):
143
144 ```sh
145 cargo build --release -p cce-gallery
146 ccebuild install --no-build cce-gallery # what `make install` runs
147 ```
148
149 Run it from the workspace with `cargo run -p cce-gallery`, or from the
150 launcher once installed.