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:
Fischlurch 2018-07-14 19:36:24 +02:00
parent c24778132e
commit 0c5a0fed6a
10 changed files with 476 additions and 402 deletions

View file

@ -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);
}

View file

@ -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:
/**

View file

@ -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...
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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"));
}
}

View file

@ -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;

View file

@ -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*/

View file

@ -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 &quot;~PImpl&quot; 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.
&amp;rarr; GuiContentPopulation

File diff suppressed because it is too large Load diff