Skip to content

Commit 9873b4e

Browse files
author
Emanuel Kozerski
committed
Smaller UX improvements for the properties panels, specially Logic Graph Nodes panels.
1 parent c7d375d commit 9873b4e

File tree

17 files changed

+158
-41
lines changed

17 files changed

+158
-41
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4949
- Set build jobs to run against GPU agents
5050
- Fixed code formatting and lint errors across multiple extensions
5151
- REMIX-4593: Fixed logic graph and particle properties panel not preserving expansion state across refreshes
52+
- Improved a few UX issues with the Logic Properties pane
5253

5354
### Removed
5455
- Removed Waypoint support based on deprecated kit sample waypoint extension

source/extensions/lightspeed.trex.properties_pane.logic.widget/config/extension.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
version = "1.2.1"
2+
version = "1.2.2"
33
authors = ["Nicolas Kendall-Bar <[email protected]>"]
44
title = "Remix Logic Properties Widget"
55
description = "Properties panel for RemixLogic prim types"
@@ -18,6 +18,7 @@ icon = "data/images/icon.png"
1818
"lightspeed.trex.utils.common" = {}
1919
"lightspeed.trex.logic.core" = {}
2020
"lightspeed.trex.logic.ogn" = {}
21+
"omni.flux.info_icon.widget" = {}
2122
"omni.flux.property_widget_builder.model.usd" = {}
2223
"omni.flux.property_widget_builder.widget" = {}
2324
"omni.flux.utils.common" = {}

source/extensions/lightspeed.trex.properties_pane.logic.widget/docs/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
22
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
33

4+
## [1.2.2]
5+
### Changed
6+
- Improved node type description display in properties panel
7+
48
## [1.2.1]
59
### Added
610
- Added StagePrimPicker integration for OmniGraph target relationship inputs

source/extensions/lightspeed.trex.properties_pane.logic.widget/lightspeed/trex/properties_pane/logic/widget/setup_ui.py

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
from lightspeed.common.constants import OMNI_GRAPH_NODE_TYPE, REGEX_MESH_TO_INSTANCE_SUB, GlobalEventNames
3232
from lightspeed.events_manager import get_instance as _get_event_manager_instance
3333
from lightspeed.trex.logic.core.graphs import LogicGraphCore
34+
from omni.flux.info_icon.widget import InfoIconWidget
35+
from omni.flux.property_widget_builder.delegates.string_value.file_picker import FilePicker
3436
from omni.flux.property_widget_builder.model.usd import USDAttributeItem, USDAttrListItem
3537
from omni.flux.property_widget_builder.model.usd import USDDelegate as _USDPropertyDelegate
3638
from omni.flux.property_widget_builder.model.usd import USDModel as _USDPropertyModel
@@ -39,13 +41,14 @@
3941
USDRelationshipItem,
4042
get_usd_listener_instance,
4143
)
44+
from omni.flux.property_widget_builder.model.usd.field_builders.ogn import is_ogn_node_attr
4245
from omni.flux.property_widget_builder.model.usd.utils import is_property_relationship
4346
from omni.flux.property_widget_builder.widget import FieldBuilder, ItemGroup
4447
from omni.flux.utils.common import Event, EventSubscription
4548
from omni.flux.utils.common.icons import get_prim_type_icons as _get_prim_type_icons
4649
from pxr import Sdf, Usd
4750

48-
LOGIC_ATTR_GROUP_ORDER = ("Inputs", "Outputs", "State", "Node", "Other")
51+
LOGIC_ATTR_GROUP_ORDER = ("Inputs", "Outputs", "State", "Other")
4952
LOGIC_ATTR_GROUP_FALLBACK = "Other"
5053

5154
# Attribute name prefixes
@@ -55,6 +58,18 @@
5558
OGN_ATTR_PREFIX_STATE = "state:"
5659
OGN_ATTR_PREFIX_UI = "ui:"
5760

61+
62+
def _is_const_asset_path_value(item) -> bool:
63+
"""Check if item is ConstAssetPath.value attribute."""
64+
return is_ogn_node_attr(item, "lightspeed.trex.logic.ConstAssetPath", "inputs:value")
65+
66+
67+
# Field builder for ConstAssetPath.value - uses FilePicker instead of string field
68+
CONST_ASSET_PATH_FIELD_BUILDER = FieldBuilder(
69+
claim_func=_is_const_asset_path_value,
70+
build_func=FilePicker().build_ui,
71+
)
72+
5873
_SPACING_SM = 4
5974
_SPACING_MD = 8
6075
_ICON_SIZE = 16
@@ -142,6 +157,7 @@ def __init__(
142157

143158
self._node_type_label_text: str = ""
144159
self._node_type_label_description_text: str = ""
160+
self._node_type_tooltip_text: str = ""
145161

146162
self._context_name = context_name
147163
self._context = omni.usd.get_context(context_name)
@@ -159,7 +175,12 @@ def __init__(
159175

160176
self._lookup_table = lookup_table or {}
161177

162-
self.__create_ui(field_builders=field_builders)
178+
# Add ConstAssetPath file picker to field builders
179+
all_field_builders = [CONST_ASSET_PATH_FIELD_BUILDER]
180+
if field_builders:
181+
all_field_builders.extend(field_builders)
182+
183+
self.__create_ui(field_builders=all_field_builders)
163184

164185
def _refresh_done(self) -> None:
165186
"""Call the event object that has the list of functions."""
@@ -320,13 +341,12 @@ def _build_dynamic_content(self) -> None:
320341
ui.Line(name="PropertiesPaneSectionTitle")
321342
ui.Spacer(height=ui.Pixel(_SPACING_MD))
322343

323-
with ui.VStack(height=0, spacing=ui.Pixel(_SPACING_MD)):
324-
ui.Label(f"Node Type: {self._node_type_label_text}", name="PropertiesWidgetLabel")
325-
if self._node_type_label_description_text:
326-
ui.Label(
327-
self._node_type_label_description_text,
328-
word_wrap=True,
329-
)
344+
with ui.HStack(height=0, spacing=ui.Pixel(_SPACING_SM)):
345+
ui.Label("Node Type: ", name="PropertiesWidgetLabel", width=0)
346+
ui.Label(self._node_type_label_text, name="PropertiesWidgetLabel", width=0)
347+
if self._node_type_tooltip_text:
348+
InfoIconWidget(self._node_type_tooltip_text, max_width=500)
349+
ui.Spacer()
330350
ui.Spacer(height=ui.Pixel(_SPACING_MD))
331351

332352
def refresh(
@@ -380,6 +400,7 @@ async def _deferred_refresh(
380400

381401
self._node_type_label_text = "No valid node type selected"
382402
self._node_type_label_description_text = ""
403+
self._node_type_tooltip_text = ""
383404

384405
node_types: list[og.NodeType] = []
385406

@@ -410,16 +431,33 @@ async def _deferred_refresh(
410431
# Filter for logic graph relevant attributes
411432
if attr_name.startswith(OGN_ATTR_PREFIX_UI):
412433
continue
434+
# Skip node: attributes (type, version info shown in tooltip instead)
435+
if attr_name.startswith(OGN_ATTR_PREFIX_NODE):
436+
continue
413437

414438
# Group attributes by name across all prims
415439
attr_added.setdefault(attr_name, []).append((prim, attr))
416440

417-
# Get text for the node type description
441+
# Get text for the node type info
418442
# Dedupe with a set of node type names because node type is not hashable
419443
node_type_names = {node_type.get_node_type() for node_type in node_types}
420444
if len(node_type_names) == 1:
421-
self._node_type_label_text = node_types[0].get_metadata(ogn.MetadataKeys.UI_NAME)
422-
self._node_type_label_description_text = node_types[0].get_metadata(ogn.MetadataKeys.DESCRIPTION)
445+
node_type = node_types[0]
446+
self._node_type_label_text = node_type.get_metadata(ogn.MetadataKeys.UI_NAME)
447+
# Build tooltip with description and node type info
448+
description = node_type.get_metadata(ogn.MetadataKeys.DESCRIPTION) or ""
449+
self._node_type_label_description_text = description
450+
full_type_name = node_type.get_node_type()
451+
# Get version from node:typeVersion attribute on the prim
452+
version = stage.GetPrimAtPath(valid_paths[0]).GetAttribute("node:typeVersion").Get(0)
453+
# Build tooltip text
454+
tooltip_parts = []
455+
if description:
456+
tooltip_parts.append(description)
457+
tooltip_parts.append("\n---\n")
458+
tooltip_parts.append(f"Node Internal Name: {full_type_name}")
459+
tooltip_parts.append(f"Node Version: {version}")
460+
self._node_type_tooltip_text = "\n".join(tooltip_parts)
423461
elif len(node_type_names) > 1:
424462
self._node_type_label_text = "Multiple node types selected"
425463

@@ -461,8 +499,6 @@ async def _deferred_refresh(
461499
group_name = "Outputs"
462500
elif attr_name.startswith(OGN_ATTR_PREFIX_STATE):
463501
group_name = "State"
464-
elif attr_name.startswith(OGN_ATTR_PREFIX_NODE):
465-
group_name = "Node"
466502
else:
467503
group_name = LOGIC_ATTR_GROUP_FALLBACK
468504
if not tooltip:

source/extensions/lightspeed.trex.properties_pane.logic.widget/lightspeed/trex/properties_pane/logic/widget/tests/e2e/test_prim_picker_ui.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ async def test_ui_creates_relationship_item_and_renders_picker(self):
144144
# Arrange
145145
context = omni.usd.get_context()
146146
stage = context.get_stage()
147-
148147
controller = og.Controller(undoable=False)
149148
_, (node,), _, _ = controller.edit(
150149
"/World/LogicGraph",
@@ -155,7 +154,6 @@ async def test_ui_creates_relationship_item_and_renders_picker(self):
155154
},
156155
)
157156
await controller.evaluate()
158-
159157
window = ui.Window("TestUI", height=600, width=400)
160158
with window.frame:
161159
with ui.Frame(width=400, height=600):
@@ -194,7 +192,6 @@ async def test_ui_multiselect_different_targets_shows_mixed(self):
194192
# Arrange
195193
context = omni.usd.get_context()
196194
stage = context.get_stage()
197-
198195
controller = og.Controller(undoable=False)
199196
_, (node1, node2), _, _ = controller.edit(
200197
"/World/LogicGraph",
@@ -218,7 +215,6 @@ async def test_ui_multiselect_different_targets_shows_mixed(self):
218215
with ui.Frame(width=400, height=600):
219216
widget = LogicPropertyWidget("")
220217
widget.show(True)
221-
222218
# Act
223219
widget.refresh([node1_prim, node2_prim])
224220
await omni.kit.app.get_app().next_update_async()
@@ -250,7 +246,6 @@ async def test_ui_multiselect_set_value_updates_both_nodes(self):
250246
context = omni.usd.get_context()
251247
stage = context.get_stage()
252248
stage.DefinePrim("/World/CommonMesh", "Mesh")
253-
254249
controller = og.Controller(undoable=False)
255250
_, (node1, node2), _, _ = controller.edit(
256251
"/World/LogicGraph",
@@ -262,7 +257,6 @@ async def test_ui_multiselect_set_value_updates_both_nodes(self):
262257
},
263258
)
264259
await controller.evaluate()
265-
266260
window = ui.Window("TestUI", height=600, width=400)
267261
with window.frame:
268262
with ui.Frame(width=400, height=600):
@@ -304,7 +298,6 @@ async def test_ui_set_target_and_verify_persistence(self):
304298
context = omni.usd.get_context()
305299
stage = context.get_stage()
306300
stage.DefinePrim("/World/TestMesh", "Mesh")
307-
308301
controller = og.Controller(undoable=False)
309302
_, (node,), _, _ = controller.edit(
310303
"/World/LogicGraph",
@@ -315,13 +308,11 @@ async def test_ui_set_target_and_verify_persistence(self):
315308
},
316309
)
317310
await controller.evaluate()
318-
319311
window = ui.Window("TestUI", height=600, width=400)
320312
with window.frame:
321313
with ui.Frame(width=400, height=600):
322314
widget = LogicPropertyWidget("")
323315
widget.show(True)
324-
325316
node_prim = stage.GetPrimAtPath(node.get_prim_path())
326317
widget.refresh([node_prim])
327318
await omni.kit.app.get_app().next_update_async()

source/extensions/lightspeed.trex.properties_pane.widget/config/extension.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
version = "1.14.2"
2+
version = "1.14.3"
33
authors =["Damien Bataille <[email protected]>"]
44
title = "NVIDIA RTX Remix Properties Pane Asset Replacements widget for the StageCraft"
55
description = "Asset Replacements Properties Pane widget for NVIDIA RTX Remix StageCraft App"

source/extensions/lightspeed.trex.properties_pane.widget/docs/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
33

44

5+
## [1.14.3]
6+
### Changed
7+
- Enabled horizontal scrollbar in the Properties pane
8+
59
## [1.14.2]
610
### Changed
711
- Integrated LogicGraphCore for consistent graph root prim detection

source/extensions/lightspeed.trex.properties_pane.widget/lightspeed/trex/properties_pane/widget/setup_ui.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ def __create_ui(self):
143143
with self.root_widget:
144144
with ui.ScrollingFrame(
145145
name="WorkspaceBackground",
146-
horizontal_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_OFF,
147146
):
148147
with ui.VStack():
149148
ui.Spacer(height=ui.Pixel(5))

source/extensions/omni.flux.info_icon.widget/config/extension.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
# Semantic Versionning is used: https://semver.org/
3-
version = "1.3.2"
3+
version = "1.4.0"
44

55
# Lists people or organizations that are considered the "authors" of the package.
66
authors = ["Alex Dunn <[email protected]>"]

source/extensions/omni.flux.info_icon.widget/docs/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
44

5+
## [1.4.0]
6+
### Added
7+
- Added optional `max_width` parameter for tooltip width constraint with word wrap
8+
59
## [1.3.2]
610
### Changed
711
- Updated tooltip window styling with explicit padding values

0 commit comments

Comments
 (0)