UI-top-level: draft a concept how to attach actions to the current window (#1069)

This is a very pervasive change and basically turns the whole top-level
of the GTK-UI bottom-up. If this change turns out right, it would likely
solve #1048

WARNING: in parts not implemented, breaks UI
This commit is contained in:
Fischlurch 2017-02-01 03:55:20 +01:00
parent 865ee11621
commit 0f5280a4f0
12 changed files with 143 additions and 77 deletions

View file

@ -23,12 +23,13 @@
#include "gui/gtk-lumiera.hpp"
#include "gui/workspace/ui-manager.hpp"
#include "gui/workspace/workspace-window.hpp"
#include "gui/ui-bus.hpp"
#include "lib/depend.hpp"
#include "include/config-facade.h"
#include <gdlmm.h>
namespace gui {
@ -75,15 +76,4 @@ namespace gui {
}
workspace::WindowList&
GtkLumiera::windowManager() /////////////////////////////////////////TICKET #1048 : last Blocker is Actions::onMenu_window_new_window()
{
if (not windowManagerInstance_)
throw error::Logic ("GTK UI is not in running state"
, error::LUMIERA_ERROR_LIFECYCLE);
return *windowManagerInstance_;
}
}// namespace gui

View file

@ -32,7 +32,8 @@
namespace gui {
namespace workspace {
class PanelManager;
class PanelManager;
class WorkspaceWindow;
}
namespace panel {

View file

@ -55,11 +55,10 @@ using std::vector;
namespace gui {
namespace workspace {
Actions::Actions (WorkspaceWindow& owner)
: workspaceWindow_(owner)
Actions::Actions (GetWindow how_to_access_current_window)
: getWorkspaceWindow(how_to_access_current_window)
, is_updating_action_state(false)
{
owner.signal_show ().connect_notify(mem_fun(this, &Actions::updateActionState));
}
@ -251,18 +250,20 @@ namespace workspace {
void
Actions::updateActionState()
{
/*REQUIRE(workspaceWindow.assetsPanel != NULL);
REQUIRE(workspaceWindow.timelinePanel != NULL);
REQUIRE(workspaceWindow.viewerPanel != NULL);
///////////////////////////////////////////////////////////////////////////////////////TICKET #1076 find out how to handle this properly
/*
WorkspaceWindow& currentWindow = getWorkspaceWindow();
REQUIRE(currentWindow.assetsPanel != NULL);
REQUIRE(currentWindow.timelinePanel != NULL);
REQUIRE(currentWindow.viewerPanel != NULL);
is_updating_action_state = true;
assetsPanelAction->set_active(
workspaceWindow.assetsPanel->is_shown());
timelinePanelAction->set_active(
workspaceWindow.timelinePanel->is_shown());
viewerPanelAction->set_active(
workspaceWindow.viewerPanel->is_shown());
is_updating_action_state = false;*/
assetsPanelAction->set_active (currentWindow.assetsPanel->is_shown());
timelinePanelAction->set_active(currentWindow.timelinePanel->is_shown());
viewerPanelAction->set_active (currentWindow.viewerPanel->is_shown());
is_updating_action_state = false;
*/
}
@ -285,7 +286,7 @@ namespace workspace {
void
Actions::onMenu_file_render()
{
dialog::Render dialog(workspaceWindow_); ////////////////////////////////////TICKET #1069 how to refer to the _current window_
dialog::Render dialog(getWorkspaceWindow());
dialog.run();
}
@ -304,7 +305,7 @@ namespace workspace {
void
Actions::onMenu_edit_preferences()
{
dialog::PreferencesDialog dialog(workspaceWindow_); ////////////////////////////////TICKET #1069 how to refer to the _current window_
dialog::PreferencesDialog dialog(getWorkspaceWindow());
dialog.run();
}
@ -326,7 +327,7 @@ namespace workspace {
{
/////////////////////////////////////////////////////////////////////////////////////TODO defunct since GTK-3 transition
//if(!is_updating_action_state)
// workspaceWindow.timelinePanel->show(timelinePanelAction->get_active());
// workspaceWindow.timelinePanel->show(timelinePanActionselAction->get_active());
}
@ -344,11 +345,11 @@ namespace workspace {
void
Actions::onMenu_sequence_add()
{
dialog::NameChooser dialog(workspaceWindow_, ////////////////////////////////////TICKET #1069 how to refer to the _current window_
dialog::NameChooser dialog(getWorkspaceWindow(),
_("Add Sequence"), _("New Sequence"));
/////////////////////////////////////////////////////////////////////////////////////////TICKET #1070 need a way how to issue session commands
// if(dialog.run() == RESPONSE_OK)
// workspaceWindow_.getProject().add_new_sequence(dialog.getName());
// workspaceWindow().getProject().add_new_sequence(dialog.getName());
}
@ -366,14 +367,14 @@ namespace workspace {
void
Actions::onMenu_window_new_window()
{
GtkLumiera::application().windowManager().newWindow();
// windowList_.newWindow(); //////////////////////////////////TODO move into UiManager
}
void
Actions::onMenu_window_close_window()
{
workspaceWindow_.hide();
getWorkspaceWindow().hide();
// delete &workspaceWindow;
}
@ -381,7 +382,7 @@ namespace workspace {
void
Actions::onMenu_show_panel(int panel_index)
{
workspaceWindow_.getPanelManager().showPanel(panel_index); /////////////////////////TICKET #1069 how to refer to the _current window_
getWorkspaceWindow().getPanelManager().showPanel(panel_index);
}
@ -409,7 +410,7 @@ namespace workspace {
dialog.set_website(Config::get (KEY_WEBSITE));
dialog.set_authors(authorsList);
dialog.set_transient_for(workspaceWindow_);
dialog.set_transient_for(getWorkspaceWindow());
// Show the about dialog
dialog.run();

View file

@ -34,9 +34,13 @@
#include "gui/gtk-lumiera.hpp"
#include <functional>
namespace gui {
namespace workspace {
using std::function;
class WorkspaceWindow;
/**
@ -46,10 +50,12 @@ namespace workspace {
class Actions
{
/**reference to the MainWindow which owns this helper */
WorkspaceWindow& workspaceWindow_;
using GetWindow = function<WorkspaceWindow&()>;
GetWindow getWorkspaceWindow;
public:
Actions (WorkspaceWindow& owner);
Actions (GetWindow how_to_access_current_window);
/**
* Populates a uiManager with the main set of actions.

View file

@ -31,6 +31,7 @@
#include "gui/config-keys.hpp"
#include "gui/ui-bus.hpp"
#include "gui/workspace/ui-manager.hpp"
#include "gui/workspace/workspace-window.hpp"
#include "lib/searchpath.hpp"
#include "lib/util.hpp"
@ -59,12 +60,22 @@ namespace workspace {
UiManager::UiManager (UiBus& bus)
: Gtk::UIManager()
, uiBus_(bus)
, windowList_{*this}
, actions_{[this]() ->WorkspaceWindow& { return windowList_.findActiveWindow();}}
, iconSearchPath_{Config::get (KEY_ICON_PATH)}
, resourceSerachPath_{Config::get (KEY_UIRES_PATH)}
{ }
/**
* Initialise the window manager on application start.
* Register the icon configuration and sizes and lookup
* all the icons -- either from the default theme of via
* the given Lumiera icon search paths (see \c setup.ini ).
* @see lumiera::Config
*/
void
UiManager::init ()
UiManager::initGlobalUI ()
{
Glib::set_application_name (Config::get (KEY_TITLE));
@ -72,9 +83,30 @@ namespace workspace {
registerStockItems();
setTheme (Config::get (KEY_STYLESHEET));
actions_.populateMainActions (*this);
}
/**
* @remarks this function is invoked once from the main application object,
* immediately prior to starting the GTK event loop. */
void
UiManager::createApplicationWindow()
{
UNIMPLEMENTED ("create the first top-level window");
}
void
UiManager::updateWindowFocusRelatedActions()
{
UNIMPLEMENTED ("how to handle activation of menu entries depending on window focus"); ////////TICKET #1076 find out how to handle this properly
//////see Actions::updateActionState()
}
void
UiManager::setTheme (string const& stylesheetName)
{
@ -137,6 +169,10 @@ namespace workspace {
}
/**
* Registers application stock items:
* icons and labels associated with IDs
*/
void
UiManager::registerStockItems()
{

View file

@ -36,6 +36,8 @@
#define GUI_WORKSPACE_UI_MANAGER_H
#include "gui/gtk-base.hpp"
#include "gui/workspace/actions.hpp"
#include "gui/workspace/window-list.hpp"
#include <boost/noncopyable.hpp>
#include <cairomm/cairomm.h>
@ -65,11 +67,13 @@ namespace workspace {
: public Gtk::UIManager
, boost::noncopyable
{
string iconSearchPath_;
string resourceSerachPath_;
UiBus& uiBus_;
WindowList windowList_;
Actions actions_;
string iconSearchPath_;
string resourceSerachPath_;
public:
@ -97,14 +101,15 @@ namespace workspace {
UiManager (UiBus& bus);
/**
* Initialise the window manager on application start.
* Register the icon configuration and sizes and lookup
* all the icons -- either from the default theme of via
* the given Lumiera icon search paths (see \c setup.ini ).
* @see lumiera::Config
* Set up the first top-level application window.
* This triggers the build-up of the user interface widgets.
*/
void init ();
void createApplicationWindow();
/** @todo find a solution how to enable/disable menu entries according to focus
* /////////////////////////////////////////////////TICKET #1076 find out how to handle this properly
*/
void updateWindowFocusRelatedActions();
/**
* Sets the theme to use for the Lumiera GUI.
@ -131,15 +136,9 @@ namespace workspace {
void allowCloseWindow (bool yes);
private:
void initGlobalUI ();
/** Registers the custom icon sizes. */
void registerAppIconSizes();
/**
* Registers application stock items:
* icons and labels associated with IDs
*/
void registerStockItems();
/**

View file

@ -66,6 +66,13 @@ namespace workspace {
}
WorkspaceWindow&
WindowList::findActiveWindow()
{
UNIMPLEMENTED ("search the window list and return the currently active window");
}
bool
WindowList::on_window_closed (GdkEventAny* event)
{

View file

@ -73,6 +73,7 @@ namespace workspace {
void newWindow ();
WorkspaceWindow& findActiveWindow();
private:

View file

@ -44,7 +44,6 @@ namespace workspace {
WorkspaceWindow::WorkspaceWindow (UiManager& uiManager)
: panelManager_(*this)
, actions_(*this)
{
createUI (uiManager);
}
@ -67,6 +66,9 @@ namespace workspace {
void
WorkspaceWindow::createUI (UiManager& uiManager)
{
signal_show ().connect_notify(mem_fun(uiManager, &UiManager::updateWindowFocusRelatedActions)); ///////////////TICKET #1076 find out how to handle this properly
add_accel_group (uiManager.get_accel_group());
// RTL Test Code
//set_default_direction (TEXT_DIR_RTL);
@ -77,10 +79,7 @@ namespace workspace {
//----- Set up the UI Manager -----//
// The UI will be nested within a VBox
add (baseContainer_);
actions_.populateMainActions (uiManager);
add_accel_group (uiManager.get_accel_group());
//----- Set up the Menu Bar -----//
Gtk::Widget* menu_bar = uiManager.get_widget ("/MenuBar");
REQUIRE (menu_bar != NULL);

View file

@ -49,6 +49,7 @@ namespace gui {
namespace workspace {
class UiManager;
/**
@ -58,7 +59,7 @@ namespace gui {
: public Gtk::Window
{
public:
WorkspaceWindow(gui::workspace::UiManager&);
WorkspaceWindow (UiManager&);
~WorkspaceWindow();
PanelManager& getPanelManager();
@ -77,12 +78,6 @@ namespace gui {
//----- Status Bar -----//
Gtk::Statusbar statusBar_;
/**
* Helper to build the menu and for
* registering and handling of user action events
*/
Actions actions_;
};

View file

@ -2780,9 +2780,14 @@ This treatment ensures each nested diff is consumed within a properly typed cont
&amp;rarr; this is the purpose of the {{{DataCap}}} within our [[generic node element|GenNode]]
</pre>
</div>
<div title="GuiNotificationFacade" modifier="Ichthyostega" created="200902080659" tags="spec">
<div title="GuiNotificationFacade" modifier="Ichthyostega" created="200902080659" modified="201701280025" tags="spec" changecount="1">
<pre>LayerSeparationInterface provided by the GUI.
Access point for the lower layers to push information and state changes (aynchronously) to the GUI. Actually, most operations within Lumiera are initiated by the user through the GUI. In the course of such actions, the GUI uses the services of the lower layer and typically recieves an synchronous response. In some exceptional cases, these operations may cause additional changes to happen asynchronously from the GUI's perspective. For example, an edit operation might trigger a re-build of the low-level model, which then detects an error.
Access point for the lower layers to push information and state changes (asynchronously) to the GUI. Most operations within Lumiera are in fact initiated by the user through the GUI. In the course of such actions, the GUI uses the services of the lower layer and typically receives an immediate synchronous response to indicate the change was noted. Yet often, these operations may cause additional changes to happen asynchronously from the GUI's perspective. For example, an edit operation might trigger a re-build of the low-level model, which then detects an error. Any such consequences and notifications can be &quot;cast&quot; up into the UI, using this service here.
Beyond that, a call to trigger shutdown of the UI layer is also exposed here.
!Addressing of UI elements
Most calls in this interface require to specify a receiver or target, in the form of an element ID. It is assumed the caller effectively just knows these IDs, typically because the same IDs are also used as element IDs for the corresponding session entities. And, to start with, the whole UI representation of the session was at some point generated by //population diff messages,// which used the same IDs to indicate the creation of the corresponding UI representation elements.
</pre>
</div>
<div title="GuiPattern" creator="Ichthyostega" modifier="Ichthyostega" created="201410160054" modified="201612021723" tags="overview" changecount="4">

View file

@ -1664,18 +1664,25 @@
<icon BUILTIN="flag-yellow"/>
<node CREATED="1485550968230" ID="ID_164246989" MODIFIED="1485550989113" TEXT="GtkLumiera darf kein Singleton mehr sein">
<linktarget COLOR="#80b3ef" DESTINATION="ID_164246989" ENDARROW="Default" ENDINCLINATION="-42;-74;" ID="Arrow_ID_401425747" SOURCE="ID_1145950660" STARTARROW="None" STARTINCLINATION="348;19;"/>
<node CREATED="1485561982971" ID="ID_287757293" MODIFIED="1485561988374" TEXT="Blocker entfernen"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1485561988922" ID="ID_1690912259" MODIFIED="1485562014648" TEXT="letzter Blocker: Actions::onMenu_window_new_window()">
<icon BUILTIN="flag-pink"/>
<node COLOR="#338800" CREATED="1485561982971" ID="ID_287757293" MODIFIED="1485917472736" TEXT="Blocker entfernen">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1485562029644" ID="ID_1022779645" MODIFIED="1485562063560" TEXT="wieder das Problem mit dem BInden der Actions">
<arrowlink DESTINATION="ID_530209145" ENDARROW="Default" ENDINCLINATION="-17;-195;" ID="Arrow_ID_626063593" STARTARROW="None" STARTINCLINATION="9;270;"/>
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1485917478469" ID="ID_1209137422" MODIFIED="1485917483206" TEXT="WIP">
<icon BUILTIN="flag-pink"/>
</node>
</node>
<node CREATED="1485550992299" ID="ID_1685125156" MODIFIED="1485550997398" TEXT="es blocken">
<node CREATED="1485550999762" ID="ID_249139218" MODIFIED="1485551006493" TEXT="WindowList"/>
<node CREATED="1485551007297" ID="ID_1398242341" MODIFIED="1485551011676" TEXT="Project &amp; Controller"/>
</node>
<node CREATED="1485550992299" ID="ID_1685125156" MODIFIED="1485917505214" TEXT="es blocken">
<icon BUILTIN="button_ok"/>
<node CREATED="1485550999762" ID="ID_249139218" MODIFIED="1485917500008" TEXT="WindowList">
<icon BUILTIN="button_cancel"/>
</node>
<node CREATED="1485551007297" ID="ID_1398242341" MODIFIED="1485917502909" TEXT="Project &amp; Controller">
<icon BUILTIN="button_cancel"/>
</node>
</node>
</node>
<node CREATED="1485551018975" ID="ID_1865473127" MODIFIED="1485551025682" TEXT="obsoletes Project &amp; Controller">
@ -1711,6 +1718,9 @@
<node CREATED="1485463515929" ID="ID_785456397" MODIFIED="1485463523940" TEXT="f&#xfc;r die Verdrahtung zust&#xe4;ndig"/>
<node CREATED="1485463525736" ID="ID_1608786246" MODIFIED="1485463536587" TEXT="h&#xe4;lt alle zentralen Komponenten"/>
<node CREATED="1485463537111" ID="ID_929585985" MODIFIED="1485463543226" TEXT="wird nie selber direkt angesprochen"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1485917690936" HGAP="93" ID="ID_939419460" MODIFIED="1485917706156" TEXT="im Moment komplett kaputt" VSHIFT="57">
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
<node CREATED="1485126457025" ID="ID_1698853761" MODIFIED="1485902874186" TEXT="workspace::UiManger">
<linktarget COLOR="#667b93" DESTINATION="ID_1698853761" ENDARROW="Default" ENDINCLINATION="19;-86;" ID="Arrow_ID_1952755524" SOURCE="ID_40172420" STARTARROW="None" STARTINCLINATION="-290;0;"/>
@ -1744,7 +1754,7 @@
<node CREATED="1485549075929" ID="ID_1887127861" MODIFIED="1485549081236" TEXT="spezifische Aktionen">
<node CREATED="1485549803366" ID="ID_1969698948" MODIFIED="1485549809977" TEXT="Fenster-Bindung">
<node CREATED="1485549810780" ID="ID_71301392" MODIFIED="1485549822342" TEXT="Pop-Ups brauchen ein Vater-Fenster"/>
<node CREATED="1485549828450" ID="ID_1089795419" MODIFIED="1485549841655">
<node CREATED="1485549828450" ID="ID_1089795419" MODIFIED="1485917553222">
<richcontent TYPE="NODE"><html>
<head>
@ -1755,6 +1765,7 @@
</p>
</body>
</html></richcontent>
<arrowlink COLOR="#375a84" DESTINATION="ID_1041890737" ENDARROW="Default" ENDINCLINATION="177;-181;" ID="Arrow_ID_373431525" STARTARROW="None" STARTINCLINATION="245;-68;"/>
</node>
</node>
</node>
@ -1826,7 +1837,8 @@
</html>
</richcontent>
<node CREATED="1485903041262" ID="ID_997327941" MODIFIED="1485903044082" TEXT="Fokus"/>
<node CREATED="1485903046613" ID="ID_1041890737" MODIFIED="1485903050080" TEXT="aktuelles Fenster">
<node CREATED="1485903046613" ID="ID_1041890737" MODIFIED="1485917548794" TEXT="aktuelles Fenster">
<linktarget COLOR="#375a84" DESTINATION="ID_1041890737" ENDARROW="Default" ENDINCLINATION="177;-181;" ID="Arrow_ID_373431525" SOURCE="ID_1089795419" STARTARROW="None" STARTINCLINATION="245;-68;"/>
<node CREATED="1485903652236" ID="ID_1692258488" MODIFIED="1485903657033" TEXT="WindowList">
<icon BUILTIN="idea"/>
</node>
@ -1838,9 +1850,21 @@
<node CREATED="1485904072812" ID="ID_829657223" MODIFIED="1485904083263" TEXT="property_is_active">
<icon BUILTIN="help"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1485917438428" HGAP="23" ID="ID_596101447" MODIFIED="1485917450180" TEXT="L&#xf6;sung ausarbeiten" VSHIFT="26">
<icon BUILTIN="flag-pink"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1485917582383" HGAP="163" ID="ID_394170572" MODIFIED="1485917632918" TEXT="TODO" VSHIFT="-30">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485917587927" ID="ID_891876702" MODIFIED="1485917622265" TEXT="wohin kommen jetzt die Funktionen, die gebunden werden">
<icon BUILTIN="help"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485917597429" ID="ID_713875638" MODIFIED="1485917626785" TEXT="auf welche Sub-Komponenten wird referenziert">
<icon BUILTIN="help"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485898796393" ID="ID_1217726538" MODIFIED="1485898814419" TEXT="#1069 how to refer to the current window">
<icon BUILTIN="flag-yellow"/>
</node>
@ -1909,7 +1933,9 @@
<node CREATED="1485546425452" ID="ID_1088557274" MODIFIED="1485546450588" TEXT="wird von GtkLumiera gehalten und verdrahtet"/>
<node CREATED="1485548669665" ID="ID_285796853" MODIFIED="1485548744609" TEXT="Problem: wie erreichbar?">
<icon BUILTIN="pencil"/>
<node CREATED="1485548702476" ID="ID_1295550090" MODIFIED="1485548707407" TEXT="Aufgabe: new_window"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485548702476" ID="ID_1295550090" MODIFIED="1485917665638" TEXT="Aufgabe: new_window">
<icon BUILTIN="flag-yellow"/>
</node>
<node CREATED="1485548713610" ID="ID_1984416789" MODIFIED="1485548737760" TEXT="wird als Action verdrahtet">
<icon BUILTIN="idea"/>
</node>