forked from 1b-agent/opencadstudio-upstream
Put the rest of the selection settings on the Options card
Options → Selection already carried the pick box, the selection-area effect and the grip visuals. Four settings behind it were finished, persisted and reachable only by typing a system variable, and one more was a constant. **Four that only needed a widget.** `SELECTIONEFFECT`, `SELECTIONPREVIEW`, `PICKADD` and `PICKDRAG` are all wired end to end already. `SELECTIONEFFECT` was the odd one: the card's own "Restore Defaults" button resets it, so it could be turned off by a button and only turned back on from the command line. `SELECTIONPREVIEW` is a bitmask and gets one checkbox per bit, which is why `set_preview_bit` exists rather than two inline expressions — the bits are the thing this change is most able to get backwards. The `PICKADD` checkbox is worded as AutoCAD words it, "use Shift to add to selection", which is the *inverse* of the stored flag. That inversion is commented at both ends; it reads as a bug otherwise. **`GRIPOBJLIMIT`.** The limit past which a selection gets no grips arrived with the selection work as a hardcoded 100, matching AutoCAD's default. It is now a setting, a slider and a system variable, following `PICKBOX`'s path exactly. AutoCAD's 0 means "no limit", which the old `>` comparison could not express, so the read now guards on it — with a test, because zero is the one value that would otherwise suppress every grip instead of allowing all of them. The slider covers 0..=1000, where every useful value lives; the sysvar takes AutoCAD's full 0..=32767, and a larger value set from the command line parks the handle at the end while the read-out keeps showing the real number. **`SelectionPrefs`** replaces the `pick_box` parameter rather than adding three more. `view_window` already took seventeen positional arguments, and `pick_add` / `pick_drag_rect` are two adjacent `bool`s that would swap silently at the call site. **Two fixes found on the way.** `OPTIONS` and `OP` were registered for autocomplete but never dispatched, so typing either answered "Unknown command" and the dialog could only be opened from the start page. And the `SELECTIONPREVIEW` doc comment had its bits the wrong way round — the code reads `& 1` for the idle rollover and `& 2` for the in-command one, as AutoCAD does — which would have put the two new checkboxes' labels backwards. **Not done, deliberately.** `PICKFIRST` and `PICKAUTO` exist but are always on, with no variable. `PICKSTYLE` is stored in the header and read by nobody — group expansion decides from the group's own `selectable` flag — so an "object grouping" checkbox would control nothing. Associative-hatch selection does not exist as a selection behaviour. Each needs a behaviour change rather than an exposure. Of the ten new strings, en-US and el-GR are translated; the other nineteen locales carry the English text. Composing them from existing keys, the way el-GR composes the neighbouring labels, only works for one of the ten — there is no existing key for "limit", "unlimited", "shift", "rectangle" or "lasso", and "Grips: Objects" as the label of a numeric limit would be worse than an untranslated string. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f9cacaec2b
commit
cabb20db45
33 files changed
+585
-37
No files matched your search
@@ -6103,6 +6103,50 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::GripObjectLimitChanged(limit) => {
|
||||
self.grip_object_limit = limit.clamp(0, 32767);
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::SelectionEffectToggled(enabled) => {
|
||||
self.model_space.selection_effect = enabled;
|
||||
self.sync_model_space_theme(false);
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
// SELECTIONPREVIEW is a bitmask and the two checkboxes own one bit
|
||||
// each: 1 = rollover while idle, 2 = rollover during a command.
|
||||
Message::SelectionPreviewIdleToggled(enabled) => {
|
||||
self.model_space.selection_preview =
|
||||
set_preview_bit(self.model_space.selection_preview, 1, enabled);
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::SelectionPreviewCommandToggled(enabled) => {
|
||||
self.model_space.selection_preview =
|
||||
set_preview_bit(self.model_space.selection_preview, 2, enabled);
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
// The checkbox is worded as AutoCAD words it — "use Shift to add"
|
||||
// — which is the opposite of PICKADD, so it is inverted here rather
|
||||
// than leaving a reader to work that out from the field name.
|
||||
Message::ShiftToAddToggled(shift_to_add) => {
|
||||
self.pick_add = !shift_to_add;
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::PickDragRectToggled(rectangle) => {
|
||||
self.pick_drag_rect = rectangle;
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::RestoreSelectionVisualDefaults => {
|
||||
self.model_space.selection_area = true;
|
||||
self.model_space.selection_opacity = 12;
|
||||
@@ -6115,6 +6159,10 @@ impl OpenCADStudio {
|
||||
self.model_space.grip_color = 0;
|
||||
self.model_space.grip_hot = 0;
|
||||
self.model_space.grip_hover = 0;
|
||||
// The button restores the *visual* defaults, which is why the
|
||||
// grip limit is here and PICKADD / PICKDRAG are not — those are
|
||||
// how selection behaves, not how it looks.
|
||||
self.grip_object_limit = crate::app::settings::DEFAULT_GRIP_OBJECT_LIMIT;
|
||||
self.sync_model_space_theme(false);
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
@@ -8627,3 +8675,37 @@ mod free_text_entry_tests {
|
||||
assert_eq!(app.text_entry_mode(), TextEntryMode::Command);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set or clear one bit of `SELECTIONPREVIEW`.
|
||||
///
|
||||
/// The variable is a bitmask — 1 = rollover while no command is running,
|
||||
/// 2 = rollover during a command — and the Options card gives each bit its own
|
||||
/// checkbox. Worth a named function rather than two inline `|` / `& !`
|
||||
/// expressions: the config comment used to describe these bits the wrong way
|
||||
/// round, so the one place that names them is the place to be careful.
|
||||
fn set_preview_bit(current: u8, bit: u8, enabled: bool) -> u8 {
|
||||
if enabled {
|
||||
current | bit
|
||||
} else {
|
||||
current & !bit
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod selection_preview_bit_tests {
|
||||
use super::set_preview_bit;
|
||||
|
||||
#[test]
|
||||
fn each_checkbox_owns_its_own_bit() {
|
||||
// Both on, then clear the idle bit: the in-command bit must survive.
|
||||
assert_eq!(set_preview_bit(3, 1, false), 2);
|
||||
assert_eq!(set_preview_bit(3, 2, false), 1);
|
||||
// Setting a bit that is already set changes nothing.
|
||||
assert_eq!(set_preview_bit(3, 1, true), 3);
|
||||
// From off, each bit turns on alone.
|
||||
assert_eq!(set_preview_bit(0, 1, true), 1);
|
||||
assert_eq!(set_preview_bit(0, 2, true), 2);
|
||||
// Clearing both reaches 0, which is SELECTIONPREVIEW off.
|
||||
assert_eq!(set_preview_bit(set_preview_bit(3, 1, false), 2, false), 0);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user