feat(plugin-api): let add-ons ask for a visual style by name
Removing the binary wireframe event left add-ons with no way to set a visual style except by spelling out a command string. Give them the intent back, in the vocabulary everything else now speaks. The name is carried as text rather than the render-mode type: this crate is dependency-free by default and only pulls acadrust in behind the host feature, which is not a weight to add to the manifest contract for one enum. The host resolves it against the same list its ribbon, its picker and its commands read, so an add-on can offer exactly the styles the application does and no others. An unknown name says so and lists the ones that exist, from that same list. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
b5a1146966
commit
f7590b1aa8
3 changed files with 32 additions and 0 deletions
|
|
@ -17,6 +17,15 @@ pub enum ModuleEvent {
|
||||||
/// Remove all loaded models from the scene.
|
/// Remove all loaded models from the scene.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
ClearModels,
|
ClearModels,
|
||||||
|
/// Put the active viewport in a named visual style.
|
||||||
|
///
|
||||||
|
/// The name is one of the render modes the viewport can be drawn in:
|
||||||
|
/// `WIREFRAME2D`, `WIREFRAME3D`, `HIDDENLINE`, `FLATSHADED`,
|
||||||
|
/// `GOURAUDSHADED`, `FLATSHADEDWITHEDGES`, `GOURAUDSHADEDWITHEDGES`
|
||||||
|
/// (case-insensitive). The host resolves it against the same list its own
|
||||||
|
/// ribbon and commands read, so an add-on offers exactly the styles the
|
||||||
|
/// application does. An unknown name is reported and nothing changes.
|
||||||
|
SetVisualStyle(String),
|
||||||
/// Toggle the layer manager panel.
|
/// Toggle the layer manager panel.
|
||||||
ToggleLayers,
|
ToggleLayers,
|
||||||
/// Ask the host to open a native file picker. On selection the host
|
/// Ask the host to open a native file picker. On selection the host
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,21 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
|
||||||
self.tabs[i].properties = PropertiesPanel::empty();
|
self.tabs[i].properties = PropertiesPanel::empty();
|
||||||
self.command_line.push_output(crate::t!("Scene cleared.").as_ref());
|
self.command_line.push_output(crate::t!("Scene cleared.").as_ref());
|
||||||
}
|
}
|
||||||
|
ModuleEvent::SetVisualStyle(name) => {
|
||||||
|
use crate::modules::view::visual_style;
|
||||||
|
match visual_style::mode_for_keyword(&name) {
|
||||||
|
Some(mode) => return Task::done(Message::SetRenderMode(mode)),
|
||||||
|
None => {
|
||||||
|
// Name the styles that do exist, from the same
|
||||||
|
// list every other caller reads.
|
||||||
|
self.command_line.push_error(
|
||||||
|
crate::tf!("Unknown visual style \"{name}\".").as_ref(),
|
||||||
|
);
|
||||||
|
self.command_line
|
||||||
|
.push_info(visual_style::keyword_prompt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ModuleEvent::ToggleLayers => {
|
ModuleEvent::ToggleLayers => {
|
||||||
return Task::done(Message::ToggleLayers);
|
return Task::done(Message::ToggleLayers);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1122,6 +1122,14 @@ pub fn module_event_to_message(event: ModuleEvent) -> Message {
|
||||||
ModuleEvent::Command(cmd) => Message::Command(cmd),
|
ModuleEvent::Command(cmd) => Message::Command(cmd),
|
||||||
ModuleEvent::OpenFileDialog => Message::OpenFile,
|
ModuleEvent::OpenFileDialog => Message::OpenFile,
|
||||||
ModuleEvent::ClearModels => Message::ClearScene,
|
ModuleEvent::ClearModels => Message::ClearScene,
|
||||||
|
ModuleEvent::SetVisualStyle(name) => {
|
||||||
|
match crate::modules::view::visual_style::mode_for_keyword(&name) {
|
||||||
|
Some(mode) => Message::SetRenderMode(mode),
|
||||||
|
// Report through the command line rather than silently doing
|
||||||
|
// nothing, so a plugin author sees the typo.
|
||||||
|
None => Message::Command(format!("VISUALSTYLES {name}")),
|
||||||
|
}
|
||||||
|
}
|
||||||
ModuleEvent::ToggleLayers => Message::ToggleLayers,
|
ModuleEvent::ToggleLayers => Message::ToggleLayers,
|
||||||
// Needs the tool context + async picker — route through the normal
|
// Needs the tool context + async picker — route through the normal
|
||||||
// ribbon-click handler rather than a direct 1:1 message.
|
// ribbon-click handler rather than a direct 1:1 message.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue