Lumiera  0.pre.03
»edit your freedom«
interaction-director.cpp
Go to the documentation of this file.
1 /*
2  interactionDirector - Global UI Manager
3 
4  Copyright (C)
5  2017, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
14 
20 #include "stage/gtk-base.hpp"
21 #include "stage/ui-bus.hpp"
22 #include "stage/ctrl/bus-term.hpp"
32 #include "stage/dialog/render.hpp"
34 #include "stage/ctrl/ui-state.hpp"
37 //#include "stage/timeline/timeline-widget.hpp"
38 //#include "stage/timeline/timeline-controller.hpp" /////////////////TODO still required?
39 #include "include/ui-protocol.hpp"
41 #include "steam/asset/sequence.hpp"
43 #include "steam/cmd.hpp"
44 #include "vault/real-clock.hpp"
46 #include "lib/format-string.hpp"
47 #include "lib/format-obj.hpp"
48 //#include "stage/ui-bus.hpp"
49 //#include "lib/util.hpp"
50 
51 //#include <memory>
52 //#include <list>
53 
54 //using util::isnil;
55 using util::_Fmt;
56 //using std::list;
57 //using std::shared_ptr;
58 using lib::idi::EntryID;
59 using lib::hash::LuidH;
60 using lib::diff::Rec;
63 using LERR_(DIFF_STRUCTURE);
64 using std::make_unique;
65 using util::toString;
66 
67 
68 namespace stage {
69 namespace interact {
70 
71  namespace session = steam::mobject::session;
72  namespace cmd = steam::cmd;
73 
74  using ctrl::GlobalCtx;
75  using ctrl::UiState;
76  using setting::AssetController;
77  using timeline::TimelineController;
78 
79 
80  // emit dtors of children here...
81  InteractionDirector::~InteractionDirector()
82  { }
83 
84 
93  : model::Controller(session::Root::getID(), globals.uiBus_.getAccessPoint())
94  , globalCtx_(globals)
95  , gestureState_{}
96  , viewLocator_{new ViewLocator}
97  , spotLocator_{new SpotLocator}
98  , navigator_{*spotLocator_, *viewLocator_} // Service exposed as Depend<LocationQuery>
99  , tracker_{new FocusTracker{*navigator_}}
100  , uiState_{new UiState{globals.uiBus_.getStateManager(), *tracker_}}
101  , assets_{new AssetController{session::Root::getAssetID(), this->uiBus_}}
102  , timelines_{}
103  {
104  Glib::signal_timeout()
105  .connect_once (sigc::mem_fun(*this, &InteractionDirector::populateContent_afterStart)
106  ,DELAY_AFTER_GUI_START_in_ms
107  ,Glib::PRIORITY_LOW); // after all initial drawing tasks
108  }
109 
110 
111  void
113  {
114  invoke (cmd::test_meta_activateContentDiff);
115  }
116 
117 
118  namespace { // Temporary Junk
119  inline void
120  unimplemented (const char* todo)
121  {
122  WARN (stage, "%s is not yet implemented. So sorry.", todo);
123  }
124  }
125 
126 
127 
128  void
129  InteractionDirector::buildMutator (TreeMutator::Handle buffer)
130  {
131  buffer.emplace(
132  TreeMutator::build()
133  .attach (collection(timelines_)
134  .isApplicableIf ([&](GenNode const& spec) -> bool
135  { // »Selector« : require object-like sub scope
136  return spec.data.isNested();
137  })
138  .constructFrom ([&](GenNode const& spec) -> TimelineGui
139  { // »Constructor« : what to do when the diff mentions a new entity
140  return injectTimeline (spec);
141  }))
142  .mutateAttrib(ATTR_fork, [&](TreeMutator::Handle buff)
143  { // »Attribute Mutator« : how enter an object field as nested scope
144  REQUIRE (assets_);
145  assets_->buildMutator(buff);
146  }));
147  }
148 
149 
158  void
160  {
161  unimplemented ("launch project setup UI");
162  }
163 
164 
171  void
173  {
174  string snapshotID{"snap-" + toString(vault::RealClock::now())};
175  invoke (cmd::session_saveSnapshot, snapshotID);
176  }
177 
178 
191  void
193  {
194  unimplemented ("launch project setup UI to create a fork of the project under new name");
195  }
196 
197 
207  void
209  {
210  dialog::PreferencesDialog dialog(getWorkspaceWindow());
211  dialog.run();
212 
213  unimplemented ("edit global configuration");
214  }
215 
216 
224  void
226  {
227  unimplemented ("open file");
228  }
229 
230 
239  void
241  {
242  dialog::Render dialog{getWorkspaceWindow()};
243  dialog.run();
244 
245  unimplemented ("start render");
246  }
247 
248 
259  void
261  {
262  LuidH anchor{*this};
263  LuidH newSeqID{EntryID<steam::asset::Sequence>().getHash()};
264  invoke (cmd::session_newSequence, anchor, newSeqID);
265  }
266 
267 
283  void
285  {
286  LuidH anchor{*this};
287  LuidH newTrackID{EntryID<steam::mobject::session::Fork>().getHash()};
288  invoke (cmd::sequence_newTrack, anchor, newTrackID);
289  }
290 
291 
293  InteractionDirector::getWorkspaceWindow()
294  {
295  return globalCtx_.windowLoc_.findActiveWindow();
296  }
297 
298 
299  namespace {
315  ID
317  {
318  if (not (spec.data.isNested()
319  and spec.data.get<Rec>().hasAttribute(string{ATTR_fork})
320  and TYPE_Fork == spec.data.get<Rec>().get(string{ATTR_fork}).data.recordType()
321  ) )
322  throw error::State (_Fmt{"When populating a new Timeline, a root track must be given immediately"
323  "nested into INS message. We got the following initialisation payload: %s"}
324  % spec
325  , LERR_(DIFF_STRUCTURE));
326 
327  return spec.data.get<Rec>().get(string{ATTR_fork}).idi;
328  }
329  }
330 
340  {
341  ID rootTrack = verifyDiffStructure_and_extract_RootTrack (spec);
342  TimelineGui anchorProxy{spec.idi, rootTrack};
343 
344  globalCtx_.windowLoc_
345  .locatePanel()
346  .find_or_create<panel::TimelinePanel>()
347  .addTimeline (
348  anchorProxy.buildTimelineWidget (this->uiBus_));
349 
350  globalCtx_.uiManager_.configureStyle (*anchorProxy);
351  return anchorProxy;
352  }
353 
354 
355 
356 
357 }}// namespace stage::interact
void saveSnapshot()
Save a snapshot of the current project&#39;s contents and the UI state.
Access or allocate a UI component view.
smart-Handle as anchor point for "the UI representation" of a timeline.
ID verifyDiffStructure_and_extract_RootTrack(GenNode const &spec)
The timeline is actually a front-end for a binding to some root track.
Helper to pick up typical focus/activity changes, for the purpose of keeping a coherent system of Wor...
TimelineGui injectTimeline(GenNode const &)
Hard wired key constants and basic definitions for communication with the GUI.
void newSequence()
Establish a pristine new sequence within the session.
Access and allocation of UI component views.
bool isNested() const
determine if payload constitutes a nested scope ("object")
Definition: gen-node.hpp:768
Navigating a centre of user activity globally.
Dockable panel to hold timeline widget(s).
Dependency context to hold all the global UI top-level entities.
Under construction: the top level UI controller.
void newTrack()
Establish a empty new track close to the current scope.
void newProject()
setup a new editing project, possibly close the current one.
Sub-Service of the InteractionDirector: Hold and maintain InteractionState.
Front-end for printf-style string template interpolation.
Top level controller for the asset management section in the UI.
typed symbolic and hash ID for asset-like position accounting.
Definition: entry-id.hpp:126
Store and manage persistent interface state.
Definition: ui-state.hpp:75
void buildMutator(lib::diff::TreeMutator::Handle) override
set up a binding to allow some top-level UI state to be treated as part of the session model ...
Common ID definitions for Steam-Layer commands.
Dialog to manage application preferences.
Organisational grouping device within the Session model ("Track" / "Media Bin").
A front-end for using printf-style formatting.
void forkProject()
Continue evolution of the currently active project under a new identity.
MObject within the session to represent "the session itself".
Namespace of Session and user visible high-level objects.
Definition: sequence.hpp:65
void populateContent_afterStart()
ask Session to push up structures for presentation
Attachment point to the UI-Bus.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Structural building block of the session: a sequence of clips.
Dialog to set up a renter process and define output name and format.
The top-level controller to connect model and user interaction state.
Establish and handle persistent interface state.
void editSetup()
Edit global configuration and setup.
Helper to track focus/activation changes to move the activity "Spot" automatically.
Lumiera GTK UI implementation root.
Definition: guifacade.cpp:37
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
Definition: format-obj.hpp:191
Control and navigate the global centre of activity.
void render()
Start a render process.
The main Lumiera workspace window.
Hash implementation based on a lumiera unique object id (LUID) When invoking the default ctor...
Simple functions to represent objects, for debugging and diagnostics.
InteractionDirector(ctrl::GlobalCtx &)
Setup and initialise all representations of "global-ness".
Customisable intermediary to abstract generic tree mutation operations.
Evaluation of UI coordinates against a concrete window topology.
A dialog to choose render output format and name.
Definition: render.hpp:36
A global circle of top-level UI management facilities.
Definition: global-ctx.hpp:70
This file contains the definition of the main workspace window parent, which is the toplevel parent o...
auto collection(COLL &coll)
Entry point to a nested DSL for setup and configuration of a collection binding.
Front-end for simplified access to the current wall clock time.
object-like record of data.
Definition: record.hpp:141
User interface for asset management.
A set of basic GTK includes for the UI.
generic data element node within a tree
Definition: gen-node.hpp:222
void openFile()
Select and open a file to perform a suitable operation.
A dockable container to hold a notebook of timeline displays.
Customisable intermediary to abstract mutating operations on arbitrary, hierarchical object-like data...