Repository navigation
Conversation
`app.plugins = [Standard(), Camera()]` adds toolbar rows to the viewer; by default there are none. A `Plugin` subclass names its built frontend (`static/plugin.js`), handles what its buttons send with `@action`, and answers with `send()`; `send(..., key=...)` is also replayed to browsers that connect later. The App serves each plugin at /plugins/<name>/ and lists them at /plugins.json for the viewer page to load. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`plugin.hide("display")` / `show` / `disable("scale")` / `enable` take the ids
of button groups or single buttons. The state is sent as one persisted
`plugin_buttons` message, so browsers that connect later get it too, and
state set before the plugin is added to an App is sent when it is. A plugin
may list its `ids`, so a misspelled one raises.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`attached()` runs once a plugin is added to an App, sending state set before that (hidden/disabled buttons; subclasses add their own, like Standard's locks). `find_geometry(guid)` gives plugins the geometry the frontend names by guid. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A plugin is one object for all workspaces (browser tabs), so it needs to know which tab is talking to it: - @action handlers and on() callbacks are called with (data, workspace), the Workspace of the tab the message came from. - Inside a handler, Plugin.send answers that tab; elsewhere it goes to main, and send(..., workspace=) picks one. Plugin.send_all reaches every tab; its keyed messages are replayed to tabs opened later, in any workspace (AppServer.shared_state, workspace_id=None). - Button state is sent with send_all, so tabs other than main get it. - Workspace.plugins: the subset of App.plugins a workspace's tabs show, served at /plugins.json?workspace=<id>. Messages for a plugin the workspace doesn't show are dropped. - Workspace.url. BREAKING CHANGE: plugin handlers take (data, workspace) instead of (data). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Set up a workspace a browser tab asks for before it exists (e.g. one a plugin opened with viewer.workspaceUrl), before the tab loads its plugins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A picked object's metadata travels as a protobuf map, which loses the order of its fields: they showed in the viewer in any order. The message now carries that order as "__order__", for the viewer to show them in. Sending no longer writes "dispatch" into the registered Metadata object itself: the message is a copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces a new plugin system to the COMPAS Three.js viewer, enabling toolbar and workspace extensibility through Python and frontend plugins. The changes add a robust API for managing plugins, toolbar buttons, and workspace-specific behaviors, and lay the groundwork for multi-workspace applications. Below are the most important changes grouped by theme:
Plugin System Core:
Pluginbase class and the@actiondecorator incompas_threejs.viewer, allowing Python plugins to define toolbar buttons and actions that communicate with their frontend counterparts. (src/compas_threejs/viewer/__init__.py,CHANGELOG.md) [1] [2]App.pluginsproperty to manage the viewer's plugins in toolbar order, with validation for unique plugin names and type safety. Plugins are now served to the frontend via/plugins.json, and each plugin can be attached to the app before startup. (src/compas_threejs/viewer/app.py,CHANGELOG.md) [1] [2]Workspace and Plugin Interaction:
@actionhandlers and allowing plugins to respond to specific tabs. AddedWorkspace.pluginsfor per-workspace plugin lists andApp.on_new_workspace()/Plugin.new_workspace()hooks for dynamic workspace setup. (src/compas_threejs/viewer/app.py,CHANGELOG.md) [1] [2]src/compas_threejs/viewer/inbox.py) [1] [2]Documentation and Design Proposals:
PLUGIN_PROPOSALS.md, a comprehensive document outlining the current state, design proposals, and future directions for the plugin system, including multi-workspace support, panels, and ideas for new plugins.These changes collectively provide a foundation for a flexible, extensible viewer architecture, supporting both general-purpose and domain-specific plugins, and enabling advanced multi-workspace workflows.