feat(host): VariablesPanel row click opens ColorPicker (variable mode)
Closes the missing host wire that codex called out as pending: the
VariablesPanel widget paints (140d5495 / 0bd98ae2) and the picker
has variable-mode commit (3c2e7711 / 99d602a3), but clicking a row
did nothing. This commit dispatches.
`crates/openpencil-shell-native/src/widget_host/press.rs`:
- New step 0d in `apply_press` (between PropertyPanel input and
AI chat dispatch): one-line call to the new helper. Keeps the
cascade ordering — properties consume their hits first, vars
next, chat after.
`crates/openpencil-shell-native/src/widget_host/property_dispatch.rs`:
- `dispatch_variables_panel_press(x, y, vw, vh) -> bool` mirrors
the existing `dispatch_export_dialog_press` pattern. Reconstructs
the same right-rail rect math `paint.rs` step 4b uses (top
when no selection, bottom-anchored above status bar when
PropertyPanel owns the rail), hit-tests, then routes:
- `Row(idx)` on a Color-kind variable → commit any pending
property focus, then `open_color_picker_for_variable(name)`.
The picker's HSV-drag path writes through `set_color_hex`
(which carries all three correctness invariants); close
pushes the snapshot+var_table undo entry from 99d602a3.
- `Row(idx)` on a non-color variable → swallow (TODO: row
inputs for string / number). Prevents fall-through to
canvas deselect.
- `AxisChip(_)` → swallow (TODO: theme-axis picker).
- Returns `false` when var_table is empty or the click missed,
so press.rs's cascade continues to chat / canvas.
Tests: 295 shell-core + 20 shell-native still pass. The dispatcher
is exercised by the existing `VariablesPanel::hit_test` tests +
the `color_picker::tests::*` end-to-end variable flow; a wired
host integration test would need a fake-render harness that's out
of scope here.
press.rs grew from 825 → 830 (+5 lines for the cascade call site).
That file was over the 800-line cap before this session — pre-
existing tech debt tracked separately. Not making it materially
worse.
TOP-10 #5 (Variables/Themes UI) edit chain is now functionally
complete: paint → click → picker → write → undo. The remaining UX
gaps are non-color variable inputs + the theme-axis picker, both
flagged as TODOs in the dispatcher.
This commit is contained in:
parent
394ca2f829
commit
c76af49b65
|
|
@ -388,6 +388,11 @@ impl WidgetHostNative {
|
|||
}
|
||||
}
|
||||
|
||||
// 0d. VariablesPanel row click — body in property_dispatch.
|
||||
if self.dispatch_variables_panel_press(x, y, viewport_width, viewport_height) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 1. AI chat panel — sits on top of the toolbar in paint
|
||||
// order, so any click inside its rect is consumed
|
||||
// here. DragHandle starts a chat drag; other AI hits
|
||||
|
|
|
|||
|
|
@ -212,4 +212,67 @@ impl WidgetHostNative {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// VariablesPanel press dispatcher — peer of
|
||||
/// `dispatch_export_dialog_press`. Returns `true` when the
|
||||
/// click hit the variables panel and was consumed; `false`
|
||||
/// otherwise so the caller continues its hit-test cascade.
|
||||
///
|
||||
/// Row clicks on Color-kind variables open the ColorPicker in
|
||||
/// variable mode (`Document::open_color_picker_for_variable`);
|
||||
/// the picker's commit path writes through
|
||||
/// `VariableTable::set_color_hex` so the variable is editable
|
||||
/// end-to-end. Non-color rows + AxisChip clicks swallow today
|
||||
/// (specific editors land later — string/number row inputs +
|
||||
/// the theme-axis picker).
|
||||
pub(in crate::widget_host) fn dispatch_variables_panel_press(
|
||||
&mut self,
|
||||
x: f32,
|
||||
y: f32,
|
||||
viewport_width: f32,
|
||||
viewport_height: f32,
|
||||
) -> bool {
|
||||
if self.document.var_table.variables.is_empty() {
|
||||
return false;
|
||||
}
|
||||
use openpencil_shell_core::widgets::variables_panel::{
|
||||
VariablesPanel, VariablesPanelHit,
|
||||
};
|
||||
use openpencil_shell_core::widgets::{STATUS_BAR_HEIGHT, TOP_BAR_HEIGHT};
|
||||
use openpencil_shell_core::{Point2D, Rect};
|
||||
let vars = VariablesPanel::for_document(&self.document);
|
||||
let intrinsic = vars.intrinsic_height();
|
||||
let top_y = if self.document.property_panel_visible() {
|
||||
let bottom_pad = STATUS_BAR_HEIGHT + 16.0;
|
||||
(viewport_height - bottom_pad - intrinsic).max(TOP_BAR_HEIGHT + 8.0)
|
||||
} else {
|
||||
TOP_BAR_HEIGHT + 8.0
|
||||
};
|
||||
let vars_rect = Rect {
|
||||
origin: Point2D::new(
|
||||
viewport_width - self.document.ui.property_panel_width,
|
||||
top_y,
|
||||
),
|
||||
size: Point2D::new(self.document.ui.property_panel_width, intrinsic),
|
||||
};
|
||||
let Some(hit) = vars.hit_test(vars_rect, Point2D::new(x, y)) else {
|
||||
return false;
|
||||
};
|
||||
match hit {
|
||||
VariablesPanelHit::Row(idx) => {
|
||||
if let Some(var) = self.document.var_table.variables.get(idx) {
|
||||
if matches!(
|
||||
var.kind,
|
||||
openpencil_shell_core::document::VariableKind::Color
|
||||
) {
|
||||
let name = var.name.clone();
|
||||
self.commit_property_focus_if_any();
|
||||
let _ = self.document.open_color_picker_for_variable(name, y);
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
VariablesPanelHit::AxisChip(_) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue