Skip to content

Commit 687aa82

Browse files
agb63meshula
authored andcommitted
usdUI: Add UI hints metadata and API
usdUI now creates a dictionary-valued plugin metadata field called `uiHints` for holding presentation metadata. "Schema-like" access classes are provided to read and write dictionary entries for the hints that are relevant to the repsective core object type: UsdUIObjectHints, UsdUIPrimHints, UsdUIPropertyHints, and UsdUIAttributeHints. There are no relationship-specific UI hints, thus no UsdUIRelationshipHints. (Internal change: 2373053) (Internal change: 2373124)
1 parent b9ce8db commit 687aa82

17 files changed

+1567
-1
lines changed

pxr/usd/usdUI/CMakeLists.txt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,21 @@ pxr_library(usdUI
1010
sdf
1111
usd
1212

13+
PUBLIC_CLASSES
14+
attributeHints
15+
objectHints
16+
primHints
17+
propertyHints
18+
1319
PUBLIC_HEADERS
1420
api.h
15-
21+
22+
PYMODULE_CPPFILES
23+
wrapAttributeHints.cpp
24+
wrapObjectHints.cpp
25+
wrapPrimHints.cpp
26+
wrapPropertyHints.cpp
27+
1628
PYMODULE_FILES
1729
__init__.py
1830

@@ -21,10 +33,16 @@ pxr_library(usdUI
2133
)
2234

2335
pxr_test_scripts(
36+
testenv/testUsdUIHints.py
2437
testenv/testUsdUINodeGraphNode.py
2538
testenv/testUsdUISceneGraphPrim.py
2639
)
2740

41+
pxr_install_test_dir(
42+
SRC testenv/testUsdUIHints
43+
DEST testUsdUIHints
44+
)
45+
2846
pxr_install_test_dir(
2947
SRC testenv/testUsdUINodeGraphNode
3048
DEST testUsdUINodeGraphNode
@@ -34,6 +52,10 @@ pxr_install_test_dir(
3452
DEST testUsdUISceneGraphPrim
3553
)
3654

55+
pxr_register_test(testUsdUIHints
56+
PYTHON
57+
COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testUsdUIHints"
58+
)
3759
pxr_register_test(testUsdUINodeGraphNode
3860
PYTHON
3961
COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testUsdUINodeGraphNode"

pxr/usd/usdUI/attributeHints.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//
2+
// Copyright 2025 Pixar
3+
//
4+
// Licensed under the terms set forth in the LICENSE.txt file available at
5+
// https://openusd.org/license.
6+
//
7+
8+
#include "pxr/usd/usdUI/attributeHints.h"
9+
#include "pxr/base/tf/diagnostic.h"
10+
11+
PXR_NAMESPACE_OPEN_SCOPE
12+
13+
UsdUIAttributeHints::UsdUIAttributeHints() = default;
14+
15+
UsdUIAttributeHints::UsdUIAttributeHints(const UsdAttribute& attr)
16+
: UsdUIPropertyHints(attr),
17+
_attr(attr)
18+
{
19+
}
20+
21+
VtDictionary
22+
UsdUIAttributeHints::GetValueLabels() const
23+
{
24+
if (!_attr) {
25+
return {};
26+
}
27+
28+
VtDictionary labels;
29+
if (_attr.GetMetadataByDictKey(
30+
UsdUIHintKeys->UIHints,
31+
UsdUIHintKeys->ValueLabels,
32+
&labels)) {
33+
return labels;
34+
}
35+
36+
return {};
37+
}
38+
39+
bool
40+
UsdUIAttributeHints::SetValueLabels(const VtDictionary& labels)
41+
{
42+
if (!_attr) {
43+
TF_CODING_ERROR("Invalid attribute");
44+
return false;
45+
}
46+
47+
return _attr.SetMetadataByDictKey(
48+
UsdUIHintKeys->UIHints,
49+
UsdUIHintKeys->ValueLabels,
50+
labels);
51+
}
52+
53+
VtTokenArray
54+
UsdUIAttributeHints::GetValueLabelsOrder() const
55+
{
56+
if (!_attr) {
57+
return {};
58+
}
59+
60+
VtTokenArray order;
61+
if (_attr.GetMetadataByDictKey(
62+
UsdUIHintKeys->UIHints,
63+
UsdUIHintKeys->ValueLabelsOrder,
64+
&order)) {
65+
return order;
66+
}
67+
68+
return {};
69+
}
70+
71+
bool
72+
UsdUIAttributeHints::SetValueLabelsOrder(const VtTokenArray& order)
73+
{
74+
if (!_attr) {
75+
TF_CODING_ERROR("Invalid attribute");
76+
return false;
77+
}
78+
79+
return _attr.SetMetadataByDictKey(
80+
UsdUIHintKeys->UIHints,
81+
UsdUIHintKeys->ValueLabelsOrder,
82+
order);
83+
}
84+
85+
bool
86+
UsdUIAttributeHints::ApplyValueLabel(const std::string& label)
87+
{
88+
if (!_attr) {
89+
TF_CODING_ERROR("Invalid attribute");
90+
return false;
91+
}
92+
93+
const TfToken keyPath =
94+
_MakeKeyPath(UsdUIHintKeys->ValueLabels, TfToken(label));
95+
VtValue value;
96+
97+
if (_attr.GetMetadataByDictKey(
98+
UsdUIHintKeys->UIHints, keyPath, &value)) {
99+
return _attr.Set(value);
100+
}
101+
102+
return false;
103+
}
104+
105+
PXR_NAMESPACE_CLOSE_SCOPE

pxr/usd/usdUI/attributeHints.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//
2+
// Copyright 2025 Pixar
3+
//
4+
// Licensed under the terms set forth in the LICENSE.txt file available at
5+
// https://openusd.org/license.
6+
//
7+
8+
#ifndef PXR_USD_USDUI_ATTRIBUTE_HINTS_H
9+
#define PXR_USD_USDUI_ATTRIBUTE_HINTS_H
10+
11+
#include "pxr/usd/usdUI/propertyHints.h"
12+
#include "pxr/usd/usd/attribute.h"
13+
14+
#include "pxr/base/vt/dictionary.h"
15+
#include "pxr/base/vt/value.h"
16+
17+
#include <string>
18+
19+
PXR_NAMESPACE_OPEN_SCOPE
20+
21+
/// \class UsdUIAttributeHints
22+
///
23+
/// A "schema-like" wrapper that provides API for retrieving and authoring UI
24+
/// hint values within the \c uiHints dictionary field on a UsdAttribute
25+
/// instance.
26+
///
27+
/// UsdUIAttributeHints is "schema-like" in that it interprets fields belonging
28+
/// to a core object type (in this case UsdAttribute, but see also
29+
/// UsdUIObjectHints, UsdUIPrimHints, and UsdUIPropertyHints), and provides
30+
/// convenient API for using those fields. However, it is not formally a schema
31+
/// and does not derive from UsdSchemaBase.
32+
class UsdUIAttributeHints : public UsdUIPropertyHints
33+
{
34+
public:
35+
/// Default constructor that creates an invalid hints object.
36+
///
37+
/// Calling "set" operations on this object will post errors. "Get"
38+
/// operations will return fallback values.
39+
USDUI_API
40+
UsdUIAttributeHints();
41+
42+
/// Construct a hints object for the given UsdAttribute \p attr.
43+
USDUI_API
44+
explicit UsdUIAttributeHints(const UsdAttribute& attr);
45+
46+
/// Return the attribute that this hints instance is interpreting.
47+
UsdAttribute GetAttribute() const { return _attr; }
48+
49+
/// Return the attribute's value labels dictionary.
50+
///
51+
/// This dictionary associates user-facing labels for display in the UI with
52+
/// underlying values to be authored to the attribute when selected.
53+
USDUI_API
54+
VtDictionary GetValueLabels() const;
55+
56+
/// Set the attribute's value labels dictionary. Return \c true if
57+
/// successful.
58+
///
59+
/// Note that since this field is dictionary-valued, its composed value will
60+
/// be the combination of all its entries as specified across all relevant
61+
/// edit targets. Overrides occur per-entry rather than the dictionary as a
62+
/// whole.
63+
USDUI_API
64+
bool SetValueLabels(const VtDictionary& labels);
65+
66+
/// Return the value labels order, indicating the order in which value
67+
/// labels should appear.
68+
USDUI_API
69+
VtTokenArray GetValueLabelsOrder() const;
70+
71+
/// Set the attribute's value labels order. Return \c true if successful.
72+
USDUI_API
73+
bool SetValueLabelsOrder(const VtTokenArray& order);
74+
75+
/// Author the value associated with the given \p label to the attribute.
76+
/// If \p label is not a key in the attribute's value labels dictionary,
77+
/// return \c false. Otherwise return \c true if \p label was successfully
78+
/// applied.
79+
USDUI_API
80+
bool ApplyValueLabel(const std::string& label);
81+
82+
private:
83+
UsdAttribute _attr;
84+
};
85+
86+
PXR_NAMESPACE_CLOSE_SCOPE
87+
88+
#endif

pxr/usd/usdUI/module.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ PXR_NAMESPACE_USING_DIRECTIVE
1111

1212
TF_WRAP_MODULE
1313
{
14+
TF_WRAP(UsdUIObjectHints);
15+
TF_WRAP(UsdUIPrimHints);
16+
TF_WRAP(UsdUIPropertyHints);
17+
TF_WRAP(UsdUIAttributeHints);
18+
1419
// Generated Schema classes. Do not remove or edit the following line.
1520
#include "generatedSchema.module.h"
1621
}

pxr/usd/usdUI/objectHints.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//
2+
// Copyright 2025 Pixar
3+
//
4+
// Licensed under the terms set forth in the LICENSE.txt file available at
5+
// https://openusd.org/license.
6+
//
7+
8+
#include "pxr/usd/usdUI/objectHints.h"
9+
#include "pxr/base/tf/stringUtils.h"
10+
11+
PXR_NAMESPACE_OPEN_SCOPE
12+
13+
TF_DEFINE_PUBLIC_TOKENS(UsdUIHintKeys, USDUI_HINT_KEYS);
14+
15+
UsdUIObjectHints::UsdUIObjectHints() = default;
16+
17+
UsdUIObjectHints::UsdUIObjectHints(const UsdObject& obj)
18+
: _obj(obj)
19+
{
20+
}
21+
22+
std::string
23+
UsdUIObjectHints::GetDisplayName() const
24+
{
25+
if (!_obj) {
26+
return {};
27+
}
28+
29+
std::string name;
30+
if (_obj.GetMetadataByDictKey(
31+
UsdUIHintKeys->UIHints,
32+
UsdUIHintKeys->DisplayName,
33+
&name)) {
34+
return name;
35+
}
36+
37+
// XXX: Fall back to legacy field
38+
return _obj.GetDisplayName();
39+
}
40+
41+
bool
42+
UsdUIObjectHints::SetDisplayName(const std::string& name)
43+
{
44+
if (!_obj) {
45+
TF_CODING_ERROR("Invalid object");
46+
return false;
47+
}
48+
49+
return _obj.SetMetadataByDictKey(
50+
UsdUIHintKeys->UIHints,
51+
UsdUIHintKeys->DisplayName,
52+
name);
53+
}
54+
55+
bool
56+
UsdUIObjectHints::GetHidden() const
57+
{
58+
if (!_obj) {
59+
return false;
60+
}
61+
62+
bool hidden = false;
63+
if (_obj.GetMetadataByDictKey(
64+
UsdUIHintKeys->UIHints,
65+
UsdUIHintKeys->Hidden,
66+
&hidden)) {
67+
return hidden;
68+
}
69+
70+
// XXX: Fall back to legacy field
71+
return _obj.IsHidden();
72+
}
73+
74+
bool
75+
UsdUIObjectHints::SetHidden(bool hidden)
76+
{
77+
if (!_obj) {
78+
TF_CODING_ERROR("Invalid object");
79+
return false;
80+
}
81+
82+
return _obj.SetMetadataByDictKey(
83+
UsdUIHintKeys->UIHints,
84+
UsdUIHintKeys->Hidden,
85+
hidden);
86+
}
87+
88+
/* static */
89+
TfToken
90+
UsdUIObjectHints::_MakeKeyPath(
91+
const TfToken& key1,
92+
const TfToken& key2)
93+
{
94+
return TfToken(
95+
TfStringPrintf("%s%c%s",
96+
key1.GetText(),
97+
UsdObject::GetNamespaceDelimiter(),
98+
key2.GetText()));
99+
}
100+
101+
PXR_NAMESPACE_CLOSE_SCOPE

0 commit comments

Comments
 (0)