Add themes to form loading (Issue #325)#348
Conversation
Implement Container::loadWidgetsImpl with clear/restore of Theme::getDefault() for both loadWidgetsFromFile and loadWidgetsFromStream. Tests: default theme restored; file vs stream parity for widget colors. Changelog: document stream behavior alignment.
|
I haven't had the time to look at all the changes in detail yet, but it looked fine on first sight except for one big thing. Changes to the Widget::load function signature break the backwards-compatibility of the API, as anyone with a custom widget will need to make this change. Code that was written to use an earlier TGUI 1.x version should ideally continue to work without changes. Annoyingly, this means you also can't simply add another load overload and call that one, because then the old function would no longer be called. The old overload must continue to function correctly. One way to do it might be something like this: void Widget::load(const std::unique_ptr<DataIO::Node>& node, const LoadingRenderersMap& renderers)
{
// Implementation here. Does same as before if m_loadRuntimeThemesByAlias and m_loadThemeFallbacks are nullptr.
// Would contains something like this:
// WidgetLoadResources widgetResources;
// widgetResources.renderers = availableRenderers;
// widgetResources.runtimeThemesByAlias = m_loadRuntimeThemesByAlias;
// widgetResources.themeFallbacks = m_loadThemeFallbacks;
// loadRendererFromFormValue(this, node->propertyValuePairs[U"Renderer"]->value, widgetResources);
// Implementation of Container::load has to be careful with how it calls the Widget::load function on itself.
}
// This function overload would NOT be virtual
void Widget::load(const std::unique_ptr<DataIO::Node>& node, const WidgetLoadResources& resources)
{
m_loadRuntimeThemesByAlias = resources.runtimeThemesByAlias;
m_loadThemeFallbacks = resources.themeFallbacks;
load(renderers);
m_loadRuntimeThemesByAlias = nullptr;
m_loadThemeFallbacks = nullptr;
}If I ever make breaking changes in the future then I will replace the code to implement it like you did right now. |
|
Ah, I see what you mean, I kept backwards compatibility of the loadWidgetsFrom... functions and forgot the existence of client subclasses. I got too focused on my feature and didn't respect the API on a minor version bump. We can't have an overload because if we call I'll have a look at it and update the PR to maintain backwards compatibility of the Widget API. |
8587b97 to
aa6c75d
Compare
b06be9b to
ee4b8b0
Compare
Introduce FormLoadOptions with applyDefaultTheme and overloads of loadWidgetsFromFile / loadWidgetsFromStream on Container and BackendGui. When applyDefaultTheme is false (default), behavior matches the unified loader: clear the global default theme for the duration of the load. When true, the default theme stays active so widgets without an explicit Renderer match programmatic construction.
6b10806 to
13512f0
Compare
Extend FormLoadOptions with themesByAlias. Forms may use Renderer = @alias or @Alias.Section, resolved from the runtime map or Theme.<Alias> fallback sections. Add WidgetLoadResources, Widget::load(node, WidgetLoadResources) dispatching to virtual load(node, LoadingRenderersMap), and FormThemeLoad tests. Updates changelog.
13512f0 to
d6dbe59
Compare
|
@texus updated the PR to avoid breaking the API, following your suggested approach. Added various tests to confirm containers and pre-existing subclasses continue to work as expected. Rebased the changes to avoid having the API break in the history. |
This PR has been broken into individual commits that can be built and tested separately for ease of review. Some commits only add interface changes and delay implementation to a later commit.
Summary
This change implements theme-aware form loading so
.txtforms can bind renderers to named themes and optional in-form fallbacks, with explicit load options onContainer/BackendGui. It closes the gap between file and stream loading for default-theme handling and adds tests around the new behavior.Proposed in Issue #325.
Theme / form loading
FormLoadOptions(themesByAlias,applyDefaultTheme) is accepted by overloads ofloadWidgetsFromFileandloadWidgetsFromStream(lvalue and rvalue stream).loadWidgetsFromStreamnow follows the same default-theme clear/restore pattern asloadWidgetsFromFile, unlessapplyDefaultThemeis used to keep the global default theme during load (so widgets without aRendererline match programmatic construction when desired).Theme.<Alias>sections with per-widget renderer fallbacks (e.g.Button = &1;).Renderervalues may use@Alias/@Alias.Section, resolved fromFormLoadOptions::themesByAliasat runtime and/or form-defined fallbacks.WidgetLoadResources(extends the previous renderers map with theme alias resolution), withContainer::loadWidgetsFromNodeTreeavailable where a parsed node tree is loaded with options.Tests
tests/Loading/FormThemeLoad.cpp) covering alias binding,applyDefaultTheme, and parity with the two-argument stream API when using defaultFormLoadOptions.Backward compatibility
Existing two-argument
loadWidgetsFromFile/loadWidgetsFromStreamcall sites keep prior behavior by routing through default-constructedFormLoadOptions.