Skip to content

Commit

Permalink
Introduce gui.add_html() (#387)
Browse files Browse the repository at this point in the history
* Introduce `gui.add_html()`

* Docs

* add Html.tsx
  • Loading branch information
brentyi authored Feb 3, 2025
1 parent 82f5a6b commit 382ce3c
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/source/gui_handles.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

.. autoclass:: viser.GuiMarkdownHandle()

.. autoclass:: viser.GuiHtmlHandle()

.. autoclass:: viser.GuiPlotlyHandle()

.. autoclass:: viser.GuiTabGroupHandle()
Expand Down
1 change: 1 addition & 0 deletions src/viser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from ._gui_handles import GuiDropdownHandle as GuiDropdownHandle
from ._gui_handles import GuiEvent as GuiEvent
from ._gui_handles import GuiFolderHandle as GuiFolderHandle
from ._gui_handles import GuiHtmlHandle as GuiHtmlHandle
from ._gui_handles import GuiImageHandle as GuiImageHandle
from ._gui_handles import GuiInputHandle as GuiInputHandle
from ._gui_handles import GuiMarkdownHandle as GuiMarkdownHandle
Expand Down
39 changes: 39 additions & 0 deletions src/viser/_gui_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
GuiDropdownHandle,
GuiEvent,
GuiFolderHandle,
GuiHtmlHandle,
GuiImageHandle,
GuiMarkdownHandle,
GuiModalHandle,
Expand Down Expand Up @@ -631,6 +632,44 @@ def add_markdown(
handle.content = content
return handle

def add_html(
self,
content: str,
order: float | None = None,
visible: bool = True,
) -> GuiHtmlHandle:
"""Add HTML to the GUI.
Args:
content: HTML content to display.
order: Optional ordering, smallest values will be displayed first.
visible: Whether the component is visible.
Returns:
A handle that can be used to interact with the GUI element.
"""
message = _messages.GuiHtmlMessage(
uuid=_make_uuid(),
container_uuid=self._get_container_uuid(),
props=_messages.GuiHtmlProps(
order=_apply_default_order(order),
content=content,
visible=visible,
),
)
self._websock_interface.queue_message(message)

handle = GuiHtmlHandle(
_GuiHandleState(
message.uuid,
self,
None,
props=message.props,
parent_container_id=message.container_uuid,
),
)
return handle

def add_image(
self,
image: np.ndarray,
Expand Down
5 changes: 5 additions & 0 deletions src/viser/_gui_handles.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
GuiCloseModalMessage,
GuiDropdownProps,
GuiFolderProps,
GuiHtmlProps,
GuiImageProps,
GuiMarkdownProps,
GuiMultiSliderProps,
Expand Down Expand Up @@ -797,6 +798,10 @@ def content(self, content: str) -> None:
self._markdown = _parse_markdown(content, self._image_root)


class GuiHtmlHandle(_GuiHandle[None], GuiHtmlProps):
"""Handling for updating and removing HTML elements."""


class GuiPlotlyHandle(_GuiHandle[None], GuiPlotlyProps):
"""Handle for updating and removing Plotly figures."""

Expand Down
16 changes: 16 additions & 0 deletions src/viser/_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,22 @@ class GuiMarkdownMessage(_CreateGuiComponentMessage):
props: GuiMarkdownProps


@dataclasses.dataclass
class GuiHtmlProps:
order: float
"""Order value for arranging GUI elements. Synchronized automatically when assigned."""
content: str
"""HTML content to be displayed. Synchronized automatically when assigned."""
visible: bool
"""Visibility state of the markdown element. Synchronized automatically when assigned."""


@dataclasses.dataclass
class GuiHtmlMessage(_CreateGuiComponentMessage):
container_uuid: str
props: GuiHtmlProps


@dataclasses.dataclass
class GuiProgressBarProps:
order: float
Expand Down
3 changes: 3 additions & 0 deletions src/viser/client/src/ControlPanel/Generated.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import MultiSliderComponent from "../components/MultiSlider";
import UploadButtonComponent from "../components/UploadButton";
import ProgressBarComponent from "../components/ProgressBar";
import ImageComponent from "../components/Image";
import HtmlComponent from "../components/Html";

/** Root of generated inputs. */
export default function GeneratedGuiContainer({
Expand Down Expand Up @@ -101,6 +102,8 @@ function GeneratedInput(props: { guiUuid: string }) {
return <TabGroupComponent {...conf} />;
case "GuiMarkdownMessage":
return <MarkdownComponent {...conf} />;
case "GuiHtmlMessage":
return <HtmlComponent {...conf} />;
case "GuiPlotlyMessage":
return <PlotlyComponent {...conf} />;
case "GuiImageMessage":
Expand Down
13 changes: 13 additions & 0 deletions src/viser/client/src/WebsocketMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,16 @@ export interface GuiMarkdownMessage {
container_uuid: string;
props: { order: number; _markdown: string; visible: boolean };
}
/** GuiHtmlMessage(uuid: 'str', container_uuid: 'str', props: 'GuiHtmlProps')
*
* (automatically generated)
*/
export interface GuiHtmlMessage {
type: "GuiHtmlMessage";
uuid: string;
container_uuid: string;
props: { order: number; content: string; visible: boolean };
}
/** GuiProgressBarMessage(uuid: 'str', value: 'float', container_uuid: 'str', props: 'GuiProgressBarProps')
*
* (automatically generated)
Expand Down Expand Up @@ -1207,6 +1217,7 @@ export type Message =
| RemoveSceneNodeMessage
| GuiFolderMessage
| GuiMarkdownMessage
| GuiHtmlMessage
| GuiProgressBarMessage
| GuiPlotlyMessage
| GuiImageMessage
Expand Down Expand Up @@ -1290,6 +1301,7 @@ export type SceneNodeMessage =
export type GuiComponentMessage =
| GuiFolderMessage
| GuiMarkdownMessage
| GuiHtmlMessage
| GuiProgressBarMessage
| GuiPlotlyMessage
| GuiImageMessage
Expand Down Expand Up @@ -1339,6 +1351,7 @@ export function isSceneNodeMessage(
const typeSetGuiComponentMessage = new Set([
"GuiFolderMessage",
"GuiMarkdownMessage",
"GuiHtmlMessage",
"GuiProgressBarMessage",
"GuiPlotlyMessage",
"GuiImageMessage",
Expand Down
8 changes: 8 additions & 0 deletions src/viser/client/src/components/Html.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { GuiHtmlMessage } from "../WebsocketMessages";

function HtmlComponent({ props }: GuiHtmlMessage) {
if (!props.visible) return <></>;
return <div dangerouslySetInnerHTML={{ __html: props.content }} />;
}

export default HtmlComponent;

0 comments on commit 382ce3c

Please sign in to comment.