Skip to content

Commit 92ab718

Browse files
authored
Adsk Contrib - Enhance active display/view list API (#2186)
* Enhance active display/view list API Signed-off-by: Doug Walker <[email protected]> * Update ocioview to use new API Signed-off-by: Doug Walker <[email protected]> * Fix python arg name Signed-off-by: Doug Walker <[email protected]> --------- Signed-off-by: Doug Walker <[email protected]>
1 parent 1cec2ab commit 92ab718

File tree

9 files changed

+707
-54
lines changed

9 files changed

+707
-54
lines changed

include/OpenColorIO/OpenColorIO.h

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,37 +1096,78 @@ class OCIOEXPORT Config
10961096
/**
10971097
* \brief
10981098
*
1099-
* $OCIO_ACTIVE_DISPLAYS envvar can, at runtime, optionally override the
1100-
* allowed displays. It is a comma or colon delimited list. Active displays
1101-
* that are not in the specified profile will be ignored, and the
1102-
* left-most defined display will be the default.
1103-
*
1104-
* Comma-delimited list of names to filter and order the active displays.
1099+
* The Active Displays list allows end users, config authors, and client apps to filter and
1100+
* reorder of the list of displays available in a user-interface. The list may be left empty
1101+
* to indicate all displays are active.
1102+
*
1103+
* The first active display is the config's Default Display.
1104+
*
1105+
* If the active list would remove all displays from a config, it is ignored (though the
1106+
* config won't validate).
1107+
*
1108+
* When serialized in the config, commas are used as separators. However, if a display name
1109+
* contains a comma, the name will be enclosed in quotes so its comma is not a separator.
11051110
*
1106-
* \note
1107-
* The setter does not override the envvar. The getter does not take into
1108-
* account the envvar value and thus may not represent what the user is seeing.
1111+
* The OCIO_ACTIVE_DISPLAYS environment variable will override the active list specified in
1112+
* the config file as well as any modifications made by the client app. These functions
1113+
* only get and set what is in the config object and do not take into account the override
1114+
* and thus may not represent the actual user experience.
11091115
*/
1116+
/// Set all active displays at once as a comma or colon delimited string. This replaces any
1117+
/// previous contents of the list.
11101118
void setActiveDisplays(const char * displays);
1119+
/// Get a string with all active displays (as it would appear in a config file).
1120+
/// Commas are always used as the separator.
11111121
const char * getActiveDisplays() const;
1122+
/// Get the number of active displays.
1123+
int getNumActiveDisplays() const;
1124+
/// Get a single active display, by index. Returns nullptr if the index is out of range.
1125+
const char * getActiveDisplay(int index) const;
1126+
/// Add a single active display to the end of the list. If the display is already present,
1127+
/// no action is taken.
1128+
void addActiveDisplay(const char * display);
1129+
/// Remove a single display. Will throw if the display is not present.
1130+
void removeActiveDisplay(const char * display);
1131+
/// Clear the active displays list.
1132+
void clearActiveDisplays();
11121133

11131134
/**
11141135
* \brief
11151136
*
1116-
* $OCIO_ACTIVE_VIEWS envvar can, at runtime, optionally override the allowed views.
1117-
* It is a comma or colon delimited list.
1118-
* Active views that are not in the specified profile will be ignored, and the
1119-
* left-most defined view will be the default.
1120-
*
1121-
* Comma-delimited list of names to filter and order the active views.
1137+
* The Active Views list allows end users, config authors, and client apps to filter and
1138+
* reorder of the list of views available in a user-interface. The list may be left empty
1139+
* to indicate all views are active.
1140+
*
1141+
* The first active view for a display is its Default View.
1142+
*
1143+
* If the active list would remove all views from a display, the list is ignored for that
1144+
* display and all views are shown for it.
1145+
*
1146+
* When serialized in the config, commas are used as separators. However, if a view name
1147+
* contains a comma, the name will be enclosed in quotes so its comma is not a separator.
11221148
*
1123-
* \note
1124-
* The setter does not override the envvar. The getter does not take
1125-
* into account the envvar value and thus may not represent what the
1126-
* user is seeing.
1149+
* The OCIO_ACTIVE_VIEWS environment variable will override the active list specified in
1150+
* the config file as well as any modifications made by the client app. These functions
1151+
* only get and set what is in the config object and do not take into account the override
1152+
* and thus may not represent the actual user experience.
11271153
*/
1154+
/// Set all active views at once as a comma or colon delimited string. This replaces any
1155+
/// previous contents of the list.
11281156
void setActiveViews(const char * views);
1157+
/// Get a string with all active views (as it would appear in a config file).
1158+
/// Commas are always used as the separator.
11291159
const char * getActiveViews() const;
1160+
/// Get the number of active views.
1161+
int getNumActiveViews() const;
1162+
/// Get a single active view, by index. Returns nullptr if the index is out of range.
1163+
const char * getActiveView(int index) const;
1164+
/// Add a single active view to the end of the list. If the view is already present,
1165+
/// no action is taken.
1166+
void addActiveView(const char * view);
1167+
/// Remove a single view. Will throw if the view is not present.
1168+
void removeActiveView(const char * view);
1169+
/// Clear the active views list.
1170+
void clearActiveViews();
11301171

11311172
/// Get all displays in the config, ignoring the active_displays list.
11321173
int getNumDisplaysAll() const noexcept;

src/OpenColorIO/Config.cpp

Lines changed: 168 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,7 @@ class Config::Impl
10291029
oss << "Profile description: " << monitorDescription;
10301030
cs->setDescription(oss.str().c_str());
10311031
cs->setTransform(file, COLORSPACE_DIR_FROM_REFERENCE);
1032+
cs->setEncoding("sdr-video");
10321033

10331034
// Note that it adds it or updates the existing one.
10341035
m_allColorSpaces->addColorSpace(cs);
@@ -3386,7 +3387,7 @@ void Config::removeSharedView(const char * view)
33863387
{
33873388
std::ostringstream os;
33883389
os << "Shared view could not be removed from config. A shared view named '"
3389-
<< view << "' could be be found.";
3390+
<< view << "' could not be found.";
33903391
throw Exception(os.str().c_str());
33913392
}
33923393
}
@@ -4115,6 +4116,14 @@ void Config::setActiveDisplays(const char * displays)
41154116
getImpl()->m_activeDisplays.clear();
41164117
getImpl()->m_activeDisplays = SplitStringEnvStyle(displays);
41174118

4119+
// SplitStringEnvStyle needs to always return a result, even if empty, for look parsing.
4120+
// However, this does not count as an active display, so delete it.
4121+
if( getImpl()->m_activeDisplays.size() == 1 &&
4122+
getImpl()->m_activeDisplays[0].empty() )
4123+
{
4124+
getImpl()->m_activeDisplays.clear();
4125+
}
4126+
41184127
getImpl()->m_displayCache.clear();
41194128

41204129
AutoMutex lock(getImpl()->m_cacheidMutex);
@@ -4127,11 +4136,94 @@ const char * Config::getActiveDisplays() const
41274136
return getImpl()->m_activeDisplaysStr.c_str();
41284137
}
41294138

4139+
void Config::addActiveDisplay(const char * display)
4140+
{
4141+
if( !display || !display[0] )
4142+
{
4143+
throw Exception("Active display could not be added to config, display name was empty");
4144+
}
4145+
4146+
auto it = std::find(getImpl()->m_activeDisplays.begin(),
4147+
getImpl()->m_activeDisplays.end(), display);
4148+
4149+
if( it != getImpl()->m_activeDisplays.end() )
4150+
{
4151+
// Display is already present.
4152+
return;
4153+
}
4154+
4155+
getImpl()->m_activeDisplays.push_back(display);
4156+
4157+
getImpl()->m_displayCache.clear();
4158+
AutoMutex lock(getImpl()->m_cacheidMutex);
4159+
getImpl()->resetCacheIDs();
4160+
}
4161+
4162+
void Config::removeActiveDisplay(const char * display)
4163+
{
4164+
if( !display || !display[0] )
4165+
{
4166+
throw Exception("Active display could not be removed from config, display name was empty.");
4167+
}
4168+
4169+
auto it = std::find( getImpl()->m_activeDisplays.begin(),
4170+
getImpl()->m_activeDisplays.end(), display );
4171+
4172+
if( it != getImpl()->m_activeDisplays.end() )
4173+
{
4174+
getImpl()->m_activeDisplays.erase(it);
4175+
}
4176+
else
4177+
{
4178+
std::ostringstream os;
4179+
os << "Active display could not be removed from config, display '"
4180+
<< display << "' was not found.";
4181+
throw Exception(os.str().c_str());
4182+
}
4183+
4184+
getImpl()->m_displayCache.clear();
4185+
AutoMutex lock(getImpl()->m_cacheidMutex);
4186+
getImpl()->resetCacheIDs();
4187+
}
4188+
4189+
void Config::clearActiveDisplays()
4190+
{
4191+
getImpl()->m_activeDisplays.clear();
4192+
4193+
getImpl()->m_displayCache.clear();
4194+
AutoMutex lock(getImpl()->m_cacheidMutex);
4195+
getImpl()->resetCacheIDs();
4196+
}
4197+
4198+
const char * Config::getActiveDisplay( int index ) const
4199+
{
4200+
if( index<0 ||
4201+
index >= static_cast<int>(getImpl()->m_activeDisplays.size()))
4202+
{
4203+
return nullptr;
4204+
}
4205+
4206+
return getImpl()->m_activeDisplays[index].c_str();
4207+
}
4208+
4209+
int Config::getNumActiveDisplays() const
4210+
{
4211+
return static_cast<int>(getImpl()->m_activeDisplays.size());
4212+
}
4213+
41304214
void Config::setActiveViews(const char * views)
41314215
{
41324216
getImpl()->m_activeViews.clear();
41334217
getImpl()->m_activeViews = SplitStringEnvStyle(views);
41344218

4219+
// SplitStringEnvStyle needs to always return a result, even if empty, for look parsing.
4220+
// However, this does not count as an active view, so delete it.
4221+
if( getImpl()->m_activeViews.size() == 1 &&
4222+
getImpl()->m_activeViews[0].empty() )
4223+
{
4224+
getImpl()->m_activeViews.clear();
4225+
}
4226+
41354227
getImpl()->m_displayCache.clear();
41364228

41374229
AutoMutex lock(getImpl()->m_cacheidMutex);
@@ -4144,6 +4236,81 @@ const char * Config::getActiveViews() const
41444236
return getImpl()->m_activeViewsStr.c_str();
41454237
}
41464238

4239+
void Config::addActiveView(const char * view)
4240+
{
4241+
if( !view || !view[0] )
4242+
{
4243+
throw Exception("Active view could not be added to config, view name was empty.");
4244+
}
4245+
4246+
auto it = std::find(getImpl()->m_activeViews.begin(),
4247+
getImpl()->m_activeViews.end(), view);
4248+
4249+
if( it != getImpl()->m_activeViews.end() )
4250+
{
4251+
// View is already present.
4252+
return;
4253+
}
4254+
4255+
getImpl()->m_activeViews.push_back(view);
4256+
4257+
getImpl()->m_displayCache.clear();
4258+
AutoMutex lock(getImpl()->m_cacheidMutex);
4259+
getImpl()->resetCacheIDs();
4260+
}
4261+
4262+
void Config::removeActiveView(const char * view)
4263+
{
4264+
if( !view || !view[0] )
4265+
{
4266+
throw Exception("Active view could not be removed from config, view name was empty.");
4267+
}
4268+
4269+
auto it = std::find( getImpl()->m_activeViews.begin(),
4270+
getImpl()->m_activeViews.end(), view );
4271+
4272+
if(it!=getImpl()->m_activeViews.end())
4273+
{
4274+
getImpl()->m_activeViews.erase(it);
4275+
}
4276+
else
4277+
{
4278+
std::ostringstream os;
4279+
os << "Active view could not be removed from config, view '"
4280+
<< view << "' was not found.";
4281+
throw Exception(os.str().c_str());
4282+
}
4283+
4284+
getImpl()->m_displayCache.clear();
4285+
AutoMutex lock(getImpl()->m_cacheidMutex);
4286+
getImpl()->resetCacheIDs();
4287+
}
4288+
4289+
void Config::clearActiveViews()
4290+
{
4291+
getImpl()->m_activeViews.clear();
4292+
4293+
getImpl()->m_displayCache.clear();
4294+
AutoMutex lock(getImpl()->m_cacheidMutex);
4295+
getImpl()->resetCacheIDs();
4296+
}
4297+
4298+
const char * Config::getActiveView( int index ) const
4299+
{
4300+
if( index<0 ||
4301+
index >= static_cast<int>(getImpl()->m_activeViews.size()))
4302+
{
4303+
return nullptr;
4304+
}
4305+
4306+
return getImpl()->m_activeViews[index].c_str();
4307+
}
4308+
4309+
int Config::getNumActiveViews() const
4310+
{
4311+
return static_cast<int>(getImpl()->m_activeViews.size());
4312+
}
4313+
41474314
int Config::getNumDisplaysAll() const noexcept
41484315
{
41494316
return static_cast<int>(getImpl()->m_displays.size());

src/OpenColorIO/OCIOYaml.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5061,13 +5061,26 @@ inline void save(YAML::Emitter & out, const Config & config)
50615061
out << YAML::Newline;
50625062
out << YAML::Key << "active_displays";
50635063
StringUtils::StringVec active_displays;
5064-
if(config.getActiveDisplays() != NULL && strlen(config.getActiveDisplays()) > 0)
5065-
active_displays = SplitStringEnvStyle(config.getActiveDisplays());
5064+
int nDisplays = config.getNumActiveDisplays();
5065+
active_displays.reserve( nDisplays );
5066+
for (int i = 0; i < nDisplays; i++)
5067+
{
5068+
active_displays.push_back(config.getActiveDisplay(i));
5069+
}
5070+
5071+
// The YAML library will wrap names that use a comma in quotes.
50665072
out << YAML::Value << YAML::Flow << active_displays;
5073+
50675074
out << YAML::Key << "active_views";
50685075
StringUtils::StringVec active_views;
5069-
if(config.getActiveViews() != NULL && strlen(config.getActiveViews()) > 0)
5070-
active_views = SplitStringEnvStyle(config.getActiveViews());
5076+
int nViews = config.getNumActiveViews();
5077+
active_views.reserve( nViews );
5078+
for (int i = 0; i < nViews; i++)
5079+
{
5080+
active_views.push_back(config.getActiveView(i));
5081+
}
5082+
5083+
// The YAML library will wrap names that use a comma in quotes.
50715084
out << YAML::Value << YAML::Flow << active_views;
50725085

50735086
const std::string inactiveCSs = config.getInactiveColorSpaces();

0 commit comments

Comments
 (0)