Skip to content

Commit 6b38174

Browse files
olearypatrickjourdain
authored andcommitted
fix(toolbar): reorder buttons, add separators, dropdown category, mutual exclusion
- Reorder toolbar: Scale | Diverging || Palette | Colorblind | Invert || Discrete | Custom Range - Add vertical divider separators between button groups - Static icons with primary-colored square outline for active state - Scale button always outlined, cycles stairs/log/wave icons - Replace category checkboxes with VMenu dropdown (single category, default Sequential) - Switching categories clears the search field - Mutual exclusion: delta disabled when Log or Custom Range; Custom Range disabled when delta - Leaving delta resets category to Sequential; palette disabled in delta mode - selected_categories changed from list to single string in dataclass - Update README with new toolbar docs and image placeholders - Update all tests for new button order and features
1 parent 8f2e28a commit 6b38174

12 files changed

Lines changed: 259 additions & 185 deletions

README.md

Lines changed: 53 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -94,18 +94,17 @@ a time — opening one automatically closes any other.
9494

9595
The control panel has three sections, top to bottom:
9696

97-
- **Toolbar** — A row of icon buttons across the top that toggle modes and
98-
settings (category filter, colorblind safe, invert, scale, diverging,
99-
custom range, and discrete banding). The current preset name doubles as a
100-
search field on the right, with a close button to dismiss the panel.
97+
- **Toolbar** — A row of icon buttons across the top that control scale,
98+
diverging mode, preset category, colorblind filtering, inversion, discrete
99+
banding, and custom range. A search field and close button sit on the right.
101100

102101
- **Settings panels** — Context-sensitive inputs that appear below the toolbar
103-
depending on which modes are active. These include category filter
104-
checkboxes, discrete color count, diverging mode controls (|max| and
105-
ε tolerance), and custom range inputs (Min / Max).
102+
depending on which modes are active. These include discrete color count,
103+
diverging mode controls (|max| and ε tolerance), and custom range inputs
104+
(Min / Max).
106105

107106
- **Preset list** — A scrollable list of colormap swatches filtered by the
108-
active categories, colorblind setting, and search text. Click any swatch
107+
active category, colorblind setting, and search text. Click any swatch
109108
to apply it immediately.
110109

111110
### Toolbar
@@ -114,29 +113,42 @@ The control panel has three sections, top to bottom:
114113

115114
The toolbar has three areas, left to right:
116115

117-
- **Icon buttons** — Seven toggle buttons that control filtering and display
118-
modes. Each button lights up or changes icon when its mode is active.
119-
Details on each button are covered below.
116+
- **Icon buttons** — Seven buttons separated into three groups by vertical
117+
dividers. Active toggles show a primary-colored square outline; the icon
118+
itself stays black. Details on each button below.
120119

121120
- **Search / preset name** — Shows the name of the currently active preset.
122121
Click into it to type and filter the preset list by name. Use the clear
123-
button to reset the search.
122+
button to reset the search. Switching categories clears the search.
124123

125124
- **Close button** (✕) — Dismisses the control panel.
126125

127126
#### Icon Buttons (left to right)
128127

129-
| # | Off | On | Toggle | Description |
130-
|---|-----|-----|--------|-------------|
131-
| 1 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/palette-outline.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/palette.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Category Filter | Shows/hides category checkboxes (Sequential, Multi-Sequential, Diverging, Cyclic) in the *Settings panel* to control which presets appear in the list. |
132-
| 2 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/blinds.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/blinds-open.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Colorblind Safe | Limits the *Preset list* to colorblind-safe presets only. Filters within the selected categories. |
133-
| 3 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/invert-colors-off.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/invert-colors.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Invert | Reverses the colormap direction (shown in the *Colorbar* and *Preset list*). |
134-
| 4a | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/stairs.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | | Scale: Linear | Click to switch to Log scale. In diverging mode, switches to SymLog. |
135-
| 4b | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/math-log.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | | Scale: Log | Click to switch to SymLog scale. **Note**: Not available in diverging mode. |
136-
| 4c | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/sine-wave.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | | Scale: SymLog | Click to return to Linear scale. |
137-
| 5 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/triangle-outline.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/triangle.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Δ Difference | Enters diverging mode: forces diverging-only presets in *Preset list*, symmetric range around zero, and exposes \|max\| and ε controls in *Settings panel*. |
138-
| 6 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/pencil.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/arrow-expand-horizontal.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Custom Range | Toggles between data-driven range and manual Min/Max inputs exposed in the *Settings panel*. Locked (not shown in *Settings panel*)in diverging mode. |
139-
| 7 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/gradient-horizontal.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/view-sequential.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Discrete | Switches between continuous gradient and discrete color banding. Exposes "Colors per tick interval" (Linear) or "Colors per magnitude" (Log/SymLog) control in *Settings panel*. |
128+
| # | Icon | Active | Name | Description |
129+
|---|------|--------|------|-------------|
130+
| 1a | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/stairs.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | always | Scale: Linear | Click to cycle to Log. In Δ mode, cycles to SymLog. |
131+
| 1b | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/math-log.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | always | Scale: Log | Click to cycle to SymLog. Not available in Δ mode. |
132+
| 1c | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/sine-wave.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | always | Scale: SymLog | Click to return to Linear. |
133+
| 2 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/triangle-outline.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/triangle-outline.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Δ Difference | Forces diverging-only presets, symmetric range, exposes \|max\| and ε. Disabled when Log scale or Custom Range is active. |
134+
| | | | | |
135+
| 3 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/palette.svg" width="24"> || Category | Opens a dropdown to select one preset category (Sequential, Multi-Sequential, Diverging, Cyclic). Default is Sequential. Disabled in Δ mode. |
136+
| 4 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/blinds.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/blinds.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Colorblind Safe | Limits the *Preset list* to colorblind-safe presets within the active category. |
137+
| 5 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/invert-colors.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/invert-colors.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Invert | Reverses the colormap direction (shown in the *Colorbar* and *Preset list*). |
138+
| | | | | |
139+
| 6 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/gradient-horizontal.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/gradient-horizontal.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Discrete | Switches between continuous gradient and discrete color banding. Exposes band count in *Settings panel*. |
140+
| 7 | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/pencil.svg" width="24"> | <img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/pencil.svg" width="24" style="border: 2px solid #1867C0; border-radius: 4px; padding: 2px;"> | Custom Range | Toggles between data-driven range and manual Min/Max inputs. Disabled in Δ mode. Cannot be active at the same time as Δ Difference. |
141+
142+
Empty rows in the table indicate the vertical separator dividers between
143+
button groups.
144+
145+
#### Mutual Exclusion Rules
146+
147+
- **Δ Difference** is disabled when Scale is Log or when Custom Range is on.
148+
You can always turn Δ Difference *off*.
149+
- **Custom Range** is disabled when Δ Difference is on.
150+
- **Category dropdown** is disabled when Δ Difference is on (presets forced
151+
to Diverging). When Δ is turned off, category resets to Sequential.
140152

141153
#### Scale Modes
142154

@@ -148,24 +160,23 @@ The toolbar has three areas, left to right:
148160
</tr>
149161
</table>
150162

151-
In all three screenshots, every mode except Δ Difference is active:
163+
In all three screenshots, Colorblind Safe, Invert, Custom Range, and
164+
Discrete are active (outlined). The category is set to Cyclic via the
165+
dropdown, and the search field contains "V":
152166

153-
- **Category Filter** — Only *Cyclic* is checked in the *Settings panel*;
154-
the *Preset list* shows only cyclic presets (vikO, brocO, corkO, …).
155-
- **Colorblind Safe** — Further limits the *Preset list* to colorblind-safe
156-
cyclic presets.
157-
- **Invert** — Preset swatches and the colorbar render reversed.
167+
- **Category** — Cyclic selected from dropdown; *Preset list* shows only
168+
cyclic presets (vikO, brocO, corkO, …).
169+
- **Colorblind Safe** — Further limits to colorblind-safe cyclic presets.
170+
- **Invert** — Preset swatches and colorbar render reversed.
158171
- **Custom Range***Settings panel* shows editable **Min** and **Max** fields.
159-
- **Discrete***Settings panel* shows the band count control. Its label
160-
adapts to the active scale: "Colors per tick interval" (Linear) or
161-
"Colors per order of magnitude" (Log / SymLog).
162-
- **Search** — The text field contains "V", filtering the *Preset list* to
163-
matching names. A clear button (✕) appears to reset the search.
172+
- **Discrete***Settings panel* shows band count. Label adapts: "Colors
173+
per tick interval" (Linear) or "Colors per order of magnitude" (Log/SymLog).
174+
- **Search** — Text field contains "V"; a clear button (✕) appears.
164175

165-
The only difference between the three images is the **Scale** button, which
176+
The only difference between the three images is the **Scale** icon, which
166177
cycles through Linear (<img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/stairs.svg" width="16">), Log (<img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/math-log.svg" width="16">), and SymLog (<img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/sine-wave.svg" width="16">).
167-
The colorbar tick labels at the bottom switch between decimal notation
168-
(Linear) and scientific notation (Log / SymLog).
178+
The colorbar tick labels switch between decimal (Linear) and scientific
179+
notation (Log/SymLog).
169180

170181
#### Δ Difference Mode
171182

@@ -176,18 +187,15 @@ The colorbar tick labels at the bottom switch between decimal notation
176187
</tr>
177188
</table>
178189

179-
When Δ Difference is active (<img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/triangle.svg" width="16"> filled):
190+
When Δ Difference is active (outlined with primary):
180191

181-
- **Preset list** is forced to diverging-only presets regardless of category
182-
selection (vik shown here).
192+
- **Preset list** is forced to diverging-only presets (vik shown here).
183193
- **Scale** only toggles between Linear (<img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/stairs.svg" width="16">) and SymLog (<img src="https://cdn.jsdelivr.net/npm/@mdi/svg/svg/sine-wave.svg" width="16">) — Log is
184194
not available.
185195
- **Settings panel** replaces Min/Max with **|max|** (symmetric range
186-
centered at zero) and **ε tolerance** (dead zone width around zero
187-
where the center color is held constant).
188-
- **Custom Range** button is locked — range is always driven by |max|.
189-
- **Category Filter** checkboxes are hidden since presets are forced to
190-
diverging.
196+
centered at zero) and **ε tolerance** (dead zone around zero).
197+
- **Custom Range** button is disabled — range is always driven by |max|.
198+
- **Category** dropdown is disabled — presets locked to Diverging.
191199

192200
## Public API
193201

-12.5 KB
Loading
-14.5 KB
Loading

docs/images/clicked-linear.png

-50.5 KB
Loading

docs/images/clicked-log.png

-48.9 KB
Loading

docs/images/clicked-symlog.png

-48.1 KB
Loading

docs/images/normal.png

-20.1 KB
Loading

docs/images/panelbar.png

-5.4 KB
Loading

src/trame_colormaps/dataclasses.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,7 @@ class ColormapConfig(StateDataModel):
137137
orientation: str = Sync(str, "horizontal")
138138
mapper_change: int = ServerOnly(int, 0)
139139
show_categories: bool = Sync(bool, False)
140-
selected_categories: list[str] = Sync(
141-
list, ["sequential", "multi-sequential", "diverging", "cyclic"]
142-
)
140+
selected_categories: str = Sync(str, "sequential")
143141

144142
def __init__(self, *args, mapper=None, data_array_fn=None, **kwargs):
145143
# Create and own the CTF
@@ -225,10 +223,9 @@ def _on_diverging_change(self, diverging):
225223
self._apply_symmetric_range()
226224
else:
227225
# Restore presets from category selection
228-
combined = set()
229-
for cat in self.selected_categories:
230-
combined |= _CATEGORY_SETS.get(cat, set())
231-
self.active_presets = sorted(combined) if combined else sorted(DEFAULT_PRESETS)
226+
self.selected_categories = "sequential"
227+
presets = _CATEGORY_SETS.get(self.selected_categories, set())
228+
self.active_presets = sorted(presets) if presets else sorted(DEFAULT_PRESETS)
232229
self._saved_active_presets = None
233230
if self._saved_log_scale is not None:
234231
self.use_log_scale = self._saved_log_scale
@@ -241,17 +238,15 @@ def _on_diverging_change(self, diverging):
241238

242239
@watch("selected_categories")
243240
def _on_categories_change(self, selected_categories):
244-
"""Rebuild active_presets from the selected category sets.
241+
"""Rebuild active_presets from the selected category.
245242
246243
In diverging mode, active_presets is always diverging-only
247244
regardless of category selection.
248245
"""
249246
if self.diverging:
250247
return
251-
combined = set()
252-
for cat in selected_categories:
253-
combined |= _CATEGORY_SETS.get(cat, set())
254-
self.active_presets = sorted(combined) if combined else sorted(DEFAULT_PRESETS)
248+
presets = _CATEGORY_SETS.get(selected_categories, set())
249+
self.active_presets = sorted(presets) if presets else sorted(DEFAULT_PRESETS)
255250

256251
@watch("epsilon")
257252
def _on_epsilon_change(self, epsilon):

0 commit comments

Comments
 (0)