UI-Lifecycle: verify and rectify start-up sequence (#1147)
...still not entirely decided yet where to plant the mechanism for UI content retrieval (#1150)
This commit is contained in:
parent
c24778132e
commit
0c5a0fed6a
10 changed files with 476 additions and 402 deletions
|
|
@ -37,7 +37,7 @@
|
|||
#include "gui/ctrl/global-ctx.hpp"
|
||||
#include "gui/ctrl/actions.hpp"
|
||||
#include "gui/ctrl/facade.hpp"
|
||||
#include "gui/workspace/style-manager.hpp"
|
||||
#include "gui/workspace/ui-style.hpp"
|
||||
#include "lib/searchpath.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ namespace ctrl {
|
|||
using Gtk::IconSize;
|
||||
using Gtk::IconFactory;
|
||||
|
||||
using workspace::StyleManager;
|
||||
using workspace::UIStyle;
|
||||
|
||||
|
||||
|
||||
|
|
@ -101,9 +101,9 @@ namespace ctrl {
|
|||
: ApplicationBase()
|
||||
, Gtk::UIManager()
|
||||
, globals_{new GlobalCtx{bus, *this}}
|
||||
, uiStyle_{new UIStyle{}}
|
||||
, actions_{new Actions{*globals_}}
|
||||
, facade_{} // note: not activated yet
|
||||
, styleManager_{new StyleManager{}}
|
||||
{
|
||||
actions_->populateMainActions (*this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ namespace gui {
|
|||
|
||||
class UiBus;
|
||||
|
||||
namespace workspace { class StyleManager; }
|
||||
namespace workspace { class UIStyle; }
|
||||
namespace ctrl {
|
||||
|
||||
using std::unique_ptr;
|
||||
|
|
@ -95,11 +95,13 @@ namespace ctrl {
|
|||
: public ApplicationBase
|
||||
, public Gtk::UIManager
|
||||
{
|
||||
using UIStyle = workspace::UIStyle;
|
||||
|
||||
unique_ptr<GlobalCtx> globals_;
|
||||
unique_ptr<UIStyle> uiStyle_;
|
||||
unique_ptr<Actions> actions_;
|
||||
unique_ptr<Facade> facade_;
|
||||
|
||||
unique_ptr<workspace::StyleManager> styleManager_;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -90,8 +90,8 @@ namespace gui {
|
|||
void
|
||||
NotificationService::displayInfo (NotifyLevel severity, string const& text)
|
||||
{
|
||||
INFO (gui, "@GUI: display '%s' as notification message.", cStr(text)); ///////////////////////////////////TICKET #1102 : build a message display box in the UI
|
||||
////////////////////////TODO actually push the information to the GUI ///////////////////////////////////TICKET #1098 : use a suitable Dispatcher
|
||||
INFO (gui, "@GUI: display '%s' as notification message.", cStr(text));
|
||||
////////////////////////TODO actually push the information to the GUI ///////////////////////////////////TICKET #1102 : build a message display box in the UI
|
||||
////////////////////////////////////////////////TICKET #1047 : as a temporary solution, use the InfoBox panel...
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "gui/widget/timeline/timeline-body.hpp"
|
||||
#include "gui/widget/timeline-widget.hpp"
|
||||
#include "gui/workspace/style-manager.hpp"
|
||||
#include "gui/workspace/ui-style.hpp"
|
||||
#include "gui/draw/cairo-util.hpp"
|
||||
|
||||
#include "timeline-arrow-tool.hpp"
|
||||
|
|
@ -531,14 +531,14 @@ TimelineBody::register_styles() const
|
|||
void
|
||||
TimelineBody::read_styles()
|
||||
{
|
||||
backgroundColour = workspace::StyleManager::readStyleColourProperty(
|
||||
backgroundColour = workspace::UIStyle::readStyleColourProperty(
|
||||
*this, "background", 0, 0, 0);
|
||||
|
||||
selectionColour = workspace::StyleManager::readStyleColourProperty(
|
||||
selectionColour = workspace::UIStyle::readStyleColourProperty(
|
||||
*this, "selection", 0, 0, 0);
|
||||
get_style_property("selection_alpha", selectionAlpha);
|
||||
|
||||
playbackPointColour = workspace::StyleManager::readStyleColourProperty(
|
||||
playbackPointColour = workspace::UIStyle::readStyleColourProperty(
|
||||
*this, "playback_point", 0, 0, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "gui/widget/timeline/timeline-ruler.hpp"
|
||||
#include "gui/widget/timeline-widget.hpp"
|
||||
#include "gui/workspace/style-manager.hpp"
|
||||
#include "gui/workspace/ui-style.hpp"
|
||||
#include "gui/draw/cairo-util.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/time.h"
|
||||
|
|
@ -691,12 +691,12 @@ namespace timeline {
|
|||
get_style_property("mouse_chevron_size", mouseChevronSize);
|
||||
get_style_property("selection_chevron_size", selectionChevronSize);
|
||||
|
||||
playbackPointColour = workspace::StyleManager::readStyleColourProperty(
|
||||
playbackPointColour = workspace::UIStyle::readStyleColourProperty(
|
||||
*this, "playback_point_colour", 0, 0, 0);
|
||||
get_style_property("playback_point_alpha", playbackPointAlpha);
|
||||
get_style_property("playback_point_size", playbackPointSize);
|
||||
|
||||
playbackPeriodArrowColour =workspace::StyleManager::readStyleColourProperty(
|
||||
playbackPeriodArrowColour =workspace::UIStyle::readStyleColourProperty(
|
||||
*this, "playback_period_arrow_colour", 0, 0, 0);
|
||||
get_style_property("playback_period_arrow_alpha",
|
||||
playbackPeriodArrowAlpha);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include "gui/widget/timeline/timeline-track.hpp"
|
||||
#include "gui/widget/timeline-widget.hpp"
|
||||
#include "gui/workspace/style-manager.hpp"
|
||||
#include "gui/workspace/ui-style.hpp"
|
||||
#include "gui/dialog/name-chooser.hpp"
|
||||
#include "include/logging.h"
|
||||
|
||||
|
|
@ -54,8 +54,8 @@ namespace timeline {
|
|||
, expanded(true)
|
||||
, expandDirection(None)
|
||||
, headerWidget(*this)
|
||||
, enableButton(Gtk::StockID("track_enabled"), workspace::StyleManager::MenuIconSize)
|
||||
, lockButton(Gtk::StockID("track_unlocked"), workspace::StyleManager::MenuIconSize)
|
||||
, enableButton(Gtk::StockID("track_enabled"), workspace::UIStyle::MenuIconSize)
|
||||
, lockButton(Gtk::StockID("track_unlocked"), workspace::UIStyle::MenuIconSize)
|
||||
{
|
||||
REQUIRE(modelTrack);
|
||||
|
||||
|
|
@ -327,12 +327,12 @@ namespace timeline {
|
|||
|
||||
if (modelTrack->getEnabled())
|
||||
{
|
||||
enableButton.setStockID (Gtk::StockID("track_enabled"), workspace::StyleManager::MenuIconSize);
|
||||
enableButton.setStockID (Gtk::StockID("track_enabled"), workspace::UIStyle::MenuIconSize);
|
||||
enableButton.set_tooltip_text(_("Disable track"));
|
||||
}
|
||||
else
|
||||
{
|
||||
enableButton.setStockID (Gtk::StockID("track_disabled"), workspace::StyleManager::MenuIconSize);
|
||||
enableButton.setStockID (Gtk::StockID("track_disabled"), workspace::UIStyle::MenuIconSize);
|
||||
enableButton.set_tooltip_text(_("Enable track"));
|
||||
}
|
||||
}
|
||||
|
|
@ -345,12 +345,12 @@ namespace timeline {
|
|||
|
||||
if (modelTrack->getLocked())
|
||||
{
|
||||
lockButton.setStockID (Gtk::StockID("track_locked"), workspace::StyleManager::MenuIconSize);
|
||||
lockButton.setStockID (Gtk::StockID("track_locked"), workspace::UIStyle::MenuIconSize);
|
||||
lockButton.set_tooltip_text(_("Unlock track"));
|
||||
}
|
||||
else
|
||||
{
|
||||
lockButton.setStockID (Gtk::StockID("track_unlocked"), workspace::StyleManager::MenuIconSize);
|
||||
lockButton.setStockID (Gtk::StockID("track_unlocked"), workspace::UIStyle::MenuIconSize);
|
||||
lockButton.set_tooltip_text(_("Lock track"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
StyleManager - Global UI Manager
|
||||
UiStyle - manage coherent UI styling
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
/** @file style-manager.cpp
|
||||
/** @file ui-style.cpp
|
||||
** Implementation of global concerns regarding a coherent UI and global state.
|
||||
** Especially, the wiring of top-level components is done here, as is the
|
||||
** basic initialisation of the interface and global configuration on
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "gui/workspace/style-manager.hpp"
|
||||
#include "gui/workspace/ui-style.hpp"
|
||||
#include "gui/config-keys.hpp"
|
||||
#include "lib/searchpath.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
|
@ -50,21 +50,21 @@ namespace workspace {
|
|||
|
||||
namespace fsys = boost::filesystem;
|
||||
|
||||
IconSize StyleManager::GiantIconSize = Gtk::ICON_SIZE_INVALID;
|
||||
IconSize StyleManager::MenuIconSize = Gtk::ICON_SIZE_INVALID;
|
||||
IconSize UIStyle::GiantIconSize = Gtk::ICON_SIZE_INVALID;
|
||||
IconSize UIStyle::MenuIconSize = Gtk::ICON_SIZE_INVALID;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the theme and style related global properties of the UI.
|
||||
* @internal Initialise the theme and style related global properties of the UI.
|
||||
* Register the icon configuration and sizes and lookup all standard icons --
|
||||
* either from the default theme of via the given Lumiera icon search paths,
|
||||
* typically from `setup.ini`.
|
||||
*
|
||||
* @see lumiera::Config
|
||||
*/
|
||||
StyleManager::StyleManager()
|
||||
UIStyle::UIStyle()
|
||||
: Gtk::UIManager()
|
||||
, iconSearchPath_{Config::get (KEY_ICON_PATH)}
|
||||
, resourceSerachPath_{Config::get (KEY_UIRES_PATH)}
|
||||
|
|
@ -80,7 +80,7 @@ namespace workspace {
|
|||
|
||||
|
||||
void
|
||||
StyleManager::setTheme (string const& stylesheetName)
|
||||
UIStyle::setTheme (string const& stylesheetName)
|
||||
{
|
||||
auto screen = Gdk::Screen::get_default();
|
||||
auto css_provider = Gtk::CssProvider::create();
|
||||
|
|
@ -102,9 +102,9 @@ namespace workspace {
|
|||
|
||||
|
||||
Cairo::RefPtr<Cairo::SolidPattern>
|
||||
StyleManager::readStyleColourProperty (Gtk::Widget& widget
|
||||
,const gchar * property_name
|
||||
,guint16 red, guint16 green, guint16 blue)
|
||||
UIStyle::readStyleColourProperty (Gtk::Widget& widget
|
||||
,const gchar * property_name
|
||||
,guint16 red, guint16 green, guint16 blue)
|
||||
{
|
||||
REQUIRE (property_name);
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ namespace workspace {
|
|||
gtk_widget_style_get(widget.gobj(), property_name, &color, NULL);
|
||||
|
||||
Cairo::RefPtr<Cairo::SolidPattern> pattern;
|
||||
// Did the color load successfully?
|
||||
// Did the colour load successfully?
|
||||
if (color != NULL)
|
||||
{
|
||||
pattern = Cairo::SolidPattern::create_rgb ( (double)color->red / 0xFFFF,
|
||||
|
|
@ -132,7 +132,7 @@ namespace workspace {
|
|||
|
||||
|
||||
void
|
||||
StyleManager::registerAppIconSizes()
|
||||
UIStyle::registerAppIconSizes()
|
||||
{
|
||||
if(GiantIconSize == Gtk::ICON_SIZE_INVALID)
|
||||
GiantIconSize = IconSize::register_new ("giant", 48, 48);
|
||||
|
|
@ -146,7 +146,7 @@ namespace workspace {
|
|||
* icons and labels associated with IDs
|
||||
*/
|
||||
void
|
||||
StyleManager::registerStockItems()
|
||||
UIStyle::registerStockItems()
|
||||
{
|
||||
Glib::RefPtr<IconFactory> factory = Gtk::IconFactory::create();
|
||||
|
||||
|
|
@ -171,10 +171,10 @@ namespace workspace {
|
|||
|
||||
|
||||
bool
|
||||
StyleManager::addStockIconSet (Glib::RefPtr<IconFactory> const& factory
|
||||
,cuString& icon_name
|
||||
,cuString& id
|
||||
,cuString& label)
|
||||
UIStyle::addStockIconSet (Glib::RefPtr<IconFactory> const& factory
|
||||
,cuString& icon_name
|
||||
,cuString& id
|
||||
,cuString& label)
|
||||
{
|
||||
Glib::RefPtr<Gtk::IconSet> icon_set = Gtk::IconSet::create();
|
||||
|
||||
|
|
@ -207,10 +207,10 @@ namespace workspace {
|
|||
|
||||
|
||||
bool
|
||||
StyleManager::addStockIcon (Glib::RefPtr<Gtk::IconSet> const& icon_set
|
||||
,cuString& icon_name
|
||||
,Gtk::IconSize size
|
||||
,bool wildcard)
|
||||
UIStyle::addStockIcon (Glib::RefPtr<Gtk::IconSet> const& icon_set
|
||||
,cuString& icon_name
|
||||
,Gtk::IconSize size
|
||||
,bool wildcard)
|
||||
{
|
||||
// Try the icon theme
|
||||
if (addThemeIconSource(icon_set, icon_name, size, wildcard))
|
||||
|
|
@ -231,10 +231,10 @@ namespace workspace {
|
|||
|
||||
|
||||
bool
|
||||
StyleManager::addThemeIconSource (Glib::RefPtr<Gtk::IconSet> const& icon_set
|
||||
,cuString& icon_name
|
||||
,Gtk::IconSize size
|
||||
,bool wildcard)
|
||||
UIStyle::addThemeIconSource (Glib::RefPtr<Gtk::IconSet> const& icon_set
|
||||
,cuString& icon_name
|
||||
,Gtk::IconSize size
|
||||
,bool wildcard)
|
||||
{
|
||||
// Get the size
|
||||
int width = 0, height = 0;
|
||||
|
|
@ -257,11 +257,11 @@ namespace workspace {
|
|||
|
||||
|
||||
bool
|
||||
StyleManager::addNonThemeIconSource (Glib::RefPtr<Gtk::IconSet> const& icon_set
|
||||
,cuString& base_dir
|
||||
,cuString& icon_name
|
||||
,Gtk::IconSize size
|
||||
,bool wildcard)
|
||||
UIStyle::addNonThemeIconSource (Glib::RefPtr<Gtk::IconSet> const& icon_set
|
||||
,cuString& base_dir
|
||||
,cuString& icon_name
|
||||
,Gtk::IconSize size
|
||||
,bool wildcard)
|
||||
{
|
||||
// Get the size
|
||||
int width = 0, height = 0;
|
||||
|
|
@ -277,10 +277,10 @@ namespace workspace {
|
|||
|
||||
|
||||
bool
|
||||
StyleManager::addStockIconFromPath (string path
|
||||
,Glib::RefPtr<Gtk::IconSet> const& icon_set
|
||||
,Gtk::IconSize size
|
||||
,bool wildcard)
|
||||
UIStyle::addStockIconFromPath (string path
|
||||
,Glib::RefPtr<Gtk::IconSet> const& icon_set
|
||||
,Gtk::IconSize size
|
||||
,bool wildcard)
|
||||
{
|
||||
if (!fsys::exists (path)) return false;
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
STYLE-MANAGER.hpp - Global UI Manager
|
||||
UI-STYLE.hpp - manage coherent UI styling
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
*/
|
||||
|
||||
|
||||
/** @file style-manager.hpp
|
||||
/** @file ui-style.hpp
|
||||
** Service for global theming and style related concerns.
|
||||
** The central UiManager operates an instance of this service to set up and configure the UI
|
||||
** globally. Widgets and similar parts of the interface may use it, when taking decisions
|
||||
|
|
@ -33,8 +33,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef GUI_WORKSPACE_STYLE_MANAGER_H
|
||||
#define GUI_WORKSPACE_STYLE_MANAGER_H
|
||||
#ifndef GUI_WORKSPACE_UI_STYLE_H
|
||||
#define GUI_WORKSPACE_UI_STYLE_H
|
||||
|
||||
#include "gui/gtk-base.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
|
|
@ -62,7 +62,7 @@ namespace workspace {
|
|||
* further global services to create workspace windows, to bind
|
||||
* menu / command actions and to enter the top-level model parts.
|
||||
*/
|
||||
class StyleManager
|
||||
class UIStyle
|
||||
: public Gtk::UIManager
|
||||
, util::NonCopyable
|
||||
{
|
||||
|
|
@ -87,13 +87,12 @@ namespace workspace {
|
|||
|
||||
public:
|
||||
/**
|
||||
* There is one global UiManager instance,
|
||||
* which is created by [the Application](\ref GtkLumiera)
|
||||
* and allows access to the UI-Bus backbone. The UiManager itself
|
||||
* is _not a ctrl::Controller,_ and thus not directly connected to the Bus.
|
||||
* Rather, supports the top-level windows for creating a consistent interface.
|
||||
* Set up a coherent theming and styling for the application.
|
||||
* Based on the Gtk::UIManager, the UIStyle service allows to access some
|
||||
* style related resources, but mostly its task is to configure the GTK toolkit
|
||||
* appropriately during startup.
|
||||
*/
|
||||
StyleManager ();
|
||||
UIStyle();
|
||||
|
||||
/**
|
||||
* Sets the theme to use for the Lumiera GUI.
|
||||
|
|
@ -200,4 +199,4 @@ namespace workspace {
|
|||
|
||||
|
||||
}}// namespace gui::workspace
|
||||
#endif /*GUI_WORKSPACE_STYLE_MANAGER_H*/
|
||||
#endif /*GUI_WORKSPACE_UI_STYLE_H*/
|
||||
|
|
@ -3335,7 +3335,7 @@ The most fundamental principle is that of ''subsidiarity'': we understand both &
|
|||
Based on these foundations, we shape and form the core part of the interface, which is the [[timeline display|GuiTimelineView]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="GuiStart" modifier="Ichthyostega" created="200812050525" modified="201807121900" tags="GuiIntegration GuiPattern" changecount="7">
|
||||
<div title="GuiStart" modifier="Ichthyostega" created="200812050525" modified="201807141734" tags="GuiIntegration GuiPattern" changecount="8">
|
||||
<pre>Starting up the GUI is optional and is considered part of the Application start/stop and lifecycle.
|
||||
* main and AppState activate the lifecyle methods on the ~GuiSubsysDescriptor, accessible via the GuiFacade
|
||||
* loading a GuiStarterPlugin actually
|
||||
|
|
@ -3362,6 +3362,9 @@ Now, when invoking an operation on some public interface, the code in the lower
|
|||
Regarding the internal organisation of Lumiera's ~UI-Layer, there is a [[top level structure|GuiTopLevel]] to manage application lifecycle.
|
||||
This top-level circle is established starting from the UI-Bus (''Nexus'') and the ''UI Manager'', which in turn creates the other dedicated control entities, especially the InteractionDirector. All these build-up steps are triggered right from the UI main() function, right before starting the ''UI event loop''. The remainder of the start-up process is driven by //contextual state,// as discovered by the top-level entities, delegating to the controllers and widgets.
|
||||
|
||||
!!!reaching the operative state
|
||||
The UI is basically in operative state when the GTK event loop is running. Before this happens, the initial //workspace window// is explicitly created and made visible -- showing an empty workspace frame without content and detail views. However, from that point on, any user interaction with and UI control currently available is guaranteed to yield the desired effect, which is typically to issue and enqueue a command into the ProcDispatcher, or to show/hide some other UI element. Which also means that all backbone components of the UI have to be created and wired prior to entering operative state. This is ensured through the construction of the {{{UIManager}}}, which holds all the relevant core components either as directly managed "~PImpl" members, or as references. The GTK UI event loop is activated through a blocking call of {{{UIManager::performMainLoop()}}}, which also happens to open all external façade interfaces of the UI-Layer. In a similar vein, the //shutdown of the UI// can be effected through the call {{{UIManager::terminateUI()}}}, causing the GTK loop to terminate, and so the UI thread will leave the aforementioned {{{performMainLoop()}}} and commence to destroy the {{{UIManager}}}, which causes disposal of all core UI components.
|
||||
|
||||
!content population
|
||||
In accordance with the Lumiera application architecture in general, the UI is not allowed to open and build its visible parts on its own behalf. Content and structure is defined by the [[Session]] while the UI takes on a passive role to receive and reflect the session's content. This is accomplished by issuing a //content request,// which in turn installs a listener within the session. This listener in turn causes a //population diff// to be sent upwards into the UI-Layer. Only in response to these content messages the UI will build and activate the visible structures for user interaction.
|
||||
&rarr; GuiContentPopulation
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue