2008-04-20 00:16:27 +02:00
|
|
|
/*
|
Rectify UI top-level -- introduce a global UiManager (#1067)
There seems to be a mismatch in the arrangement of the top-level entities
* we support multiple windows, yet from reading the code, you'd ge the impression we aren't really aware we have multiple top-level windows
* the `WindowManager` is the core UI manager, which feels like a mix-up in concerns
* the `WorkspaceWindow::createUI()` does the global UI initialisation. Again, we have multiple workspace windows.
* `GtkLumiera::main()` creates a `Model` and a `Controller` in local function scope, but stores the `WindowManager` in an object field.
* it seems, for that very reason, `GtlLumiera` needed to be a singleton, to allow by-name access to "the" `WindowManager`
* needless to say, this causes a host of problems when shutting down the UI.
The idea is to introduce a dedicated UiManager, to deal with the central
framework induced concerns solely, and to demote the WindowManager and the
WorkspaceWindows to care only for their local concerns
2017-01-23 00:40:17 +01:00
|
|
|
UiManager - Global UI Manager
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2008-04-20 00:16:27 +02:00
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
|
Rectify UI top-level -- introduce a global UiManager (#1067)
There seems to be a mismatch in the arrangement of the top-level entities
* we support multiple windows, yet from reading the code, you'd ge the impression we aren't really aware we have multiple top-level windows
* the `WindowManager` is the core UI manager, which feels like a mix-up in concerns
* the `WorkspaceWindow::createUI()` does the global UI initialisation. Again, we have multiple workspace windows.
* `GtkLumiera::main()` creates a `Model` and a `Controller` in local function scope, but stores the `WindowManager` in an object field.
* it seems, for that very reason, `GtlLumiera` needed to be a singleton, to allow by-name access to "the" `WindowManager`
* needless to say, this causes a host of problems when shutting down the UI.
The idea is to introduce a dedicated UiManager, to deal with the central
framework induced concerns solely, and to demote the WindowManager and the
WorkspaceWindows to care only for their local concerns
2017-01-23 00:40:17 +01:00
|
|
|
2017, Hermann Vosseler <Ichthyostega@web.de>
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2008-04-20 00:16:27 +02:00
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
2010-12-17 23:28:49 +01:00
|
|
|
published by the Free Software Foundation; either version 2 of
|
|
|
|
|
the License, or (at your option) any later version.
|
|
|
|
|
|
2008-04-20 00:16:27 +02:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2008-04-20 00:16:27 +02:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2008-04-20 00:16:27 +02:00
|
|
|
* *****************************************************/
|
|
|
|
|
|
2011-02-06 21:23:34 +01:00
|
|
|
|
Rectify UI top-level -- introduce a global UiManager (#1067)
There seems to be a mismatch in the arrangement of the top-level entities
* we support multiple windows, yet from reading the code, you'd ge the impression we aren't really aware we have multiple top-level windows
* the `WindowManager` is the core UI manager, which feels like a mix-up in concerns
* the `WorkspaceWindow::createUI()` does the global UI initialisation. Again, we have multiple workspace windows.
* `GtkLumiera::main()` creates a `Model` and a `Controller` in local function scope, but stores the `WindowManager` in an object field.
* it seems, for that very reason, `GtlLumiera` needed to be a singleton, to allow by-name access to "the" `WindowManager`
* needless to say, this causes a host of problems when shutting down the UI.
The idea is to introduce a dedicated UiManager, to deal with the central
framework induced concerns solely, and to demote the WindowManager and the
WorkspaceWindows to care only for their local concerns
2017-01-23 00:40:17 +01:00
|
|
|
/** @file ui-manager.cpp
|
2017-02-10 23:10:17 +01:00
|
|
|
** 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
|
|
|
|
|
** UI toolkit level.
|
|
|
|
|
**
|
Rectify UI top-level -- introduce a global UiManager (#1067)
There seems to be a mismatch in the arrangement of the top-level entities
* we support multiple windows, yet from reading the code, you'd ge the impression we aren't really aware we have multiple top-level windows
* the `WindowManager` is the core UI manager, which feels like a mix-up in concerns
* the `WorkspaceWindow::createUI()` does the global UI initialisation. Again, we have multiple workspace windows.
* `GtkLumiera::main()` creates a `Model` and a `Controller` in local function scope, but stores the `WindowManager` in an object field.
* it seems, for that very reason, `GtlLumiera` needed to be a singleton, to allow by-name access to "the" `WindowManager`
* needless to say, this causes a host of problems when shutting down the UI.
The idea is to introduce a dedicated UiManager, to deal with the central
framework induced concerns solely, and to demote the WindowManager and the
WorkspaceWindows to care only for their local concerns
2017-01-23 00:40:17 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2017-05-03 21:13:17 +02:00
|
|
|
#include "gui/gtk-base.hpp"
|
2017-02-01 02:21:04 +01:00
|
|
|
#include "gui/config-keys.hpp"
|
2017-02-17 21:16:42 +01:00
|
|
|
#include "gui/ctrl/ui-manager.hpp"
|
|
|
|
|
#include "gui/ctrl/global-ctx.hpp"
|
|
|
|
|
#include "gui/ctrl/actions.hpp"
|
2017-02-17 22:12:14 +01:00
|
|
|
#include "gui/workspace/style-manager.hpp"
|
2011-02-07 00:54:16 +01:00
|
|
|
#include "lib/searchpath.hpp"
|
|
|
|
|
#include "lib/util.hpp"
|
|
|
|
|
|
2017-05-03 22:31:03 +02:00
|
|
|
#include <gdlmm.h>
|
|
|
|
|
|
2011-02-07 00:54:16 +01:00
|
|
|
using util::cStr;
|
2017-02-08 04:08:55 +01:00
|
|
|
using util::isnil;
|
2008-04-20 00:16:27 +02:00
|
|
|
|
2011-02-07 00:54:16 +01:00
|
|
|
|
2008-04-20 00:16:27 +02:00
|
|
|
namespace gui {
|
2017-02-17 21:16:42 +01:00
|
|
|
namespace ctrl {
|
2008-10-10 11:56:07 +02:00
|
|
|
|
2017-05-03 22:31:03 +02:00
|
|
|
using Gtk::IconSize;
|
|
|
|
|
using Gtk::IconFactory;
|
|
|
|
|
|
2017-02-17 22:12:14 +01:00
|
|
|
using workspace::StyleManager;
|
2017-01-23 01:13:38 +01:00
|
|
|
|
2017-05-03 22:31:03 +02:00
|
|
|
|
2011-02-07 00:54:16 +01:00
|
|
|
|
2014-10-07 03:13:58 +02:00
|
|
|
|
2017-02-02 20:59:54 +01:00
|
|
|
// dtors via smart-ptr invoked from here...
|
2017-05-19 23:42:55 +02:00
|
|
|
UiManager::~UiManager() { }
|
2017-02-02 20:59:54 +01:00
|
|
|
|
|
|
|
|
|
2017-05-03 23:09:01 +02:00
|
|
|
/**
|
2017-05-19 23:42:55 +02:00
|
|
|
* Initialise the GTK framework libraries.
|
|
|
|
|
* @remark in 5/2017 we abandoned the (deprecated) `Gtk::Main`,
|
|
|
|
|
* but we did not switch to `Gtk::Application`, rather we just
|
|
|
|
|
* incorporated the framework initialisation code directly into
|
|
|
|
|
* our own code base. This allows us to ignore all the shiny new
|
|
|
|
|
* D-Bus and desktop integration stuff.
|
2017-05-03 23:09:01 +02:00
|
|
|
*/
|
|
|
|
|
ApplicationBase::ApplicationBase()
|
|
|
|
|
{
|
|
|
|
|
Glib::thread_init();
|
2017-05-19 23:42:55 +02:00
|
|
|
//---------------------------------------------copied from Gtk::Main
|
|
|
|
|
gtk_init (nullptr, nullptr);
|
|
|
|
|
Gtk::Main::init_gtkmm_internals();
|
|
|
|
|
//---------------------------------------------copied from Gtk::Main
|
2017-05-03 23:09:01 +02:00
|
|
|
Gdl::init();
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-19 23:42:55 +02:00
|
|
|
ApplicationBase::~ApplicationBase()
|
|
|
|
|
{
|
|
|
|
|
//---------------------------------------------copied from Gtk::Main
|
|
|
|
|
// Release the gtkmm type registration tables,
|
|
|
|
|
// allowing Main to be instantiated again:
|
|
|
|
|
Glib::wrap_register_cleanup();
|
|
|
|
|
Glib::Error::register_cleanup();
|
|
|
|
|
//---------------------------------------------copied from Gtk::Main
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-03 23:09:01 +02:00
|
|
|
|
2017-02-17 22:12:14 +01:00
|
|
|
/**
|
2017-05-19 23:42:55 +02:00
|
|
|
* @remark Creating the UiManager initialises the interface globally on application start.
|
|
|
|
|
* It wires the global services and attaches to the UI-Bus, defines the main
|
|
|
|
|
* application menu and binds the corresponding actions. Moreover, the StyleManager
|
|
|
|
|
* register the icon configuration and sizes and loads the icon definitions.
|
2017-02-17 22:12:14 +01:00
|
|
|
*/
|
2017-01-26 20:51:43 +01:00
|
|
|
UiManager::UiManager (UiBus& bus)
|
2017-05-03 23:09:01 +02:00
|
|
|
: ApplicationBase()
|
2017-05-19 23:42:55 +02:00
|
|
|
, Gtk::UIManager()
|
2017-02-14 03:01:19 +01:00
|
|
|
, globals_{new GlobalCtx{bus, *this}}
|
2017-02-14 03:31:12 +01:00
|
|
|
, actions_{new Actions{*globals_}}
|
2017-02-17 22:12:14 +01:00
|
|
|
, styleManager_{new StyleManager{}}
|
2017-02-02 19:41:58 +01:00
|
|
|
{
|
2017-02-17 22:12:14 +01:00
|
|
|
actions_->populateMainActions (*this);
|
2017-02-02 19:41:58 +01:00
|
|
|
}
|
2017-01-26 20:51:43 +01:00
|
|
|
|
2017-02-01 03:55:20 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @remarks this function is invoked once from the main application object,
|
2017-05-19 23:42:55 +02:00
|
|
|
* immediately prior to starting the GTK event loop.
|
|
|
|
|
*/
|
2017-02-01 03:55:20 +01:00
|
|
|
void
|
|
|
|
|
UiManager::createApplicationWindow()
|
|
|
|
|
{
|
2017-02-14 03:31:12 +01:00
|
|
|
if (globals_->windowList_.empty())
|
|
|
|
|
globals_->windowList_.newWindow();
|
2015-05-29 04:44:58 +02:00
|
|
|
}
|
2009-01-31 19:12:04 +01:00
|
|
|
|
2017-05-03 02:37:48 +02:00
|
|
|
|
2017-05-19 23:42:55 +02:00
|
|
|
/**
|
|
|
|
|
* Run the GTK UI.
|
|
|
|
|
* @remarks this function is equivalent to calling Gtk::Main::run()
|
|
|
|
|
* In GTK-3.0.3, the implementation is already based on libGIO;
|
|
|
|
|
* after possibly handling command line arguments (which does not apply
|
|
|
|
|
* in our case), it invokes `g_main_loop_run()`, which in turn ends up
|
|
|
|
|
* polling the main context via `g_main_context_iterate()`, until the
|
|
|
|
|
* use count drops to zero. This is the "event loop".
|
|
|
|
|
*/
|
2017-05-03 02:37:48 +02:00
|
|
|
void
|
|
|
|
|
UiManager::performMainLoop()
|
|
|
|
|
{
|
2017-05-19 23:42:55 +02:00
|
|
|
gtk_main(); // GTK event loop
|
2017-05-03 02:37:48 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-14 03:43:41 +01:00
|
|
|
|
2017-05-19 23:42:55 +02:00
|
|
|
/**
|
|
|
|
|
* @note this function can be invoked from an UI event, since it just
|
|
|
|
|
* signals shutdown to the GTK event loop by invoking `gtk_main_quit()`.
|
|
|
|
|
* The latter will finish processing of the current event and then return
|
|
|
|
|
* from the UiManager::performmainLoop() call, which eventually causes the
|
|
|
|
|
* UI subsystem to signal termination to the Lumiera application as a whole.
|
|
|
|
|
*/
|
2017-02-14 03:43:41 +01:00
|
|
|
void
|
|
|
|
|
UiManager::terminateUI()
|
|
|
|
|
{
|
2017-05-19 23:42:55 +02:00
|
|
|
gtk_main_quit();
|
2017-02-14 03:43:41 +01:00
|
|
|
}
|
|
|
|
|
|
2017-02-01 03:55:20 +01:00
|
|
|
void
|
|
|
|
|
UiManager::updateWindowFocusRelatedActions()
|
|
|
|
|
{
|
2017-05-04 01:24:32 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1076 find out how to handle this properly
|
|
|
|
|
actions_->updateActionState (globals_->windowList_.findActiveWindow());
|
2017-02-01 03:55:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-01-26 21:51:19 +01:00
|
|
|
void
|
|
|
|
|
UiManager::allowCloseWindow (bool yes)
|
|
|
|
|
{
|
|
|
|
|
this->get_action("/MenuBar/WindowMenu/WindowCloseWindow")
|
|
|
|
|
->set_sensitive (yes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-02-17 21:16:42 +01:00
|
|
|
}}// namespace gui::ctrl
|