ViewSpec: decide how to cast the types for building the DSL
we'll use a typedef to represent the default case and provide the level within the UI-Tree as template parameter for the generic case This avoids wrapping each definition into a builder function, which will be the same function for 99% of the cases, and it looks rather compact and natural for the default case, while still retaining genericity. Another alternative would have been to inject the Tree-level at the invocation; but doing so feels more like magic for me.
This commit is contained in:
parent
41b8d12b66
commit
69f87e994c
3 changed files with 224 additions and 22 deletions
|
|
@ -121,7 +121,7 @@ namespace interact {
|
|||
* It takes a _viewID_ as argument, which actually is more of a typeID to designate
|
||||
* the kind of view or UI widget, which shall be attached at or retrieved from the
|
||||
* location resolved through the LocationRule. The latter is essentially what is
|
||||
* embedded within the Locator functor
|
||||
* embedded within the Locator functor.
|
||||
*/
|
||||
using Locator = std::function<UICoord(Literal)>;
|
||||
|
||||
|
|
@ -130,32 +130,41 @@ namespace interact {
|
|||
* A specification to describe the desired location of a component view within the Lumiera UI.
|
||||
* ViewSpec is basically a set of [UI coordinates](\ref UICoord), with the additional possibility
|
||||
* of specifying several alternatives, with the intention to pick the first applicable one.
|
||||
*
|
||||
* @todo initial draft as of 9/2017
|
||||
* @tparam depth the level in the tree addressed by this locator
|
||||
* @remarks Locator is build from a DSL expression, which is basically a UICoord::Builder.
|
||||
* This coordinate spec describes a sequence of several places where to locate
|
||||
* the UI-Element in question. The template parameter clarifies if we're talking
|
||||
* about windows here, or panels or views. The latter is the [default case](\ref ViewSpec).
|
||||
*/
|
||||
class ViewSpec
|
||||
template<size_t depth>
|
||||
class LocatorSpec
|
||||
: public Locator
|
||||
{
|
||||
|
||||
public:
|
||||
ViewSpec(UICoord coordinates)
|
||||
LocatorSpec(UICoord coordinates)
|
||||
: Locator([](Literal componentID) -> UICoord
|
||||
{
|
||||
UNIMPLEMENTED ("resolve a view spec to yield explicit UI coordinates");
|
||||
})
|
||||
{
|
||||
UNIMPLEMENTED ("build a view spec from explicitly given UI coordinates");
|
||||
}
|
||||
|
||||
/** shortcut to allow initialisation from UI-Coordinate builder expression */
|
||||
ViewSpec(UICoord::Builder&& coordinates)
|
||||
: ViewSpec{UICoord(std::move (coordinates))}
|
||||
LocatorSpec(UICoord::Builder&& coordinates)
|
||||
: LocatorSpec{UICoord(std::move (coordinates))}
|
||||
{ }
|
||||
|
||||
UICoord
|
||||
operator() (Literal componentID)
|
||||
{
|
||||
UNIMPLEMENTED ("resolve a view spec to yield explicit UI coordinates");
|
||||
}
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A specification to describe the desired location of a component view within the Lumiera UI.
|
||||
* ViewSpec is basically a set of [UI coordinates](\ref UICoord), with the additional possibility
|
||||
* of specifying several alternatives, with the intention to pick the first applicable one.
|
||||
*/
|
||||
using ViewSpec = LocatorSpec<UIC_VIEW>;
|
||||
|
||||
|
||||
/**
|
||||
* Allocator is a functor to resolve a given, desired location of a view within the UI, resulting
|
||||
|
|
|
|||
|
|
@ -2838,7 +2838,7 @@ Command instances are like prototypes -- thus each additional level of different
|
|||
see the description in &rarr; CommandSetup
|
||||
</pre>
|
||||
</div>
|
||||
<div title="GuiComponentView" creator="Ichthyostega" modifier="Ichthyostega" created="201709021521" modified="201802160224" tags="def GuiPattern design" changecount="50">
|
||||
<div title="GuiComponentView" creator="Ichthyostega" modifier="Ichthyostega" created="201709021521" modified="201802240154" tags="def GuiPattern design" changecount="51">
|
||||
<pre>//A view within the UI, featuring some component of relevance to »the model«.//
|
||||
While any UI is comprised of numerous widgets acting as //view of something,// only some of those views play the prominent role to act as //building block component// of the user interface.
|
||||
Such UI component views exhibit some substantial traits
|
||||
|
|
@ -2858,7 +2858,7 @@ Here, //Allocation// means
|
|||
The classical example to verify this definition is the //allocation of viewers:// when starting playback of a new media item, we "need a viewer" to show it. But we can not just create yet another viewer window -- rather we're bound to allocate one of the possible "viewer slots". In fact this is a configurable property of the UI layout employed; sometimes some people need the limitation to one single viewer entity (which might even be external, routed to a beamer or monitor), while other ones request the classical editor layout with two viewer windows side by side, while yet different working styles might exploit a limited set of viewers allocated in stack- or round-robin style.
|
||||
|
||||
!View access
|
||||
The global access point to component views is the {{{ViewLocator}}} within InteractionDirector, which exposes a generic access- and management API to
|
||||
The global access point to component views is the ViewLocator within InteractionDirector, which exposes a generic access- and management API to
|
||||
* get (possibly create) some view of given type
|
||||
* get (possibly create) a view with specific identity
|
||||
* destroy a specific view
|
||||
|
|
@ -3730,7 +3730,7 @@ Especially the focus navigation entails the use of some kind of ubiquitous [[coo
|
|||
|
||||
</pre>
|
||||
</div>
|
||||
<div title="InteractionDirector" creator="Ichthyostega" modifier="Ichthyostega" created="201702102146" modified="201801132336" tags="def design GuiPattern" changecount="27">
|
||||
<div title="InteractionDirector" creator="Ichthyostega" modifier="Ichthyostega" created="201702102146" modified="201802240129" tags="def design GuiPattern" changecount="28">
|
||||
<pre>//the top-level controller within the UI.//
|
||||
In Lumiera, the structures of the model within the [[Session]] (the so called HighLevelModel) are mapped onto corresponding [[tangible UI entities|UI-Element]], which serve as a front-end to represent those entities towards the user. Within this model, there is a //conceptual root node// -- which logically corresponds to the session itself. This [[root element in model|ModelRootMO]] links together the actual top-level entities, which are the (multiple) timelines, together with the asset management and defaults and rules configuration within the session.
|
||||
|
||||
|
|
@ -3752,6 +3752,7 @@ The InteractionDirector is part of the model, and thus we have to distinguish be
|
|||
:* the SpotLocator is what is "moved" when the [[Spot]] of current activity moves
|
||||
:* the FocusTracker is responsible for //detecting changes in current selection and focus.//
|
||||
:* the [[Navigator]] is a special controller to handle moving the SpotLocator within the UI tree topology
|
||||
:* the ViewLocator serves for any kind of high-level, abstracted access to [[component views|GuiComponentView]] and location resolution.
|
||||
|
||||
!Collaborations
|
||||
* several global actions are exposed here, like opening the session and creating a new timeline.<br/>Such operations are typically bound into menu and action buttons, and in turn invoke [[commands|CommandHandling]] into the Session
|
||||
|
|
@ -4288,7 +4289,7 @@ The UI-Bus offers a dedicated API to direct ~MutationMessages towards {{{Tangibl
|
|||
|
||||
In the case at hand, the basic building block of the Lumiera UI, the {{{Tangible}}} offers this interface and thus the ability to construct a concrete TreeMutator, which in turn is bound to the internals of the actual UI-Element in question. Together this allows for a generic implementation of MutationMessage handling, where the designated UI-Element is reshaped by applying a concrete diff sequence embedded in the message with the help of a {{{DiffApplicator<DiffMutable>}}}, based on the TreeMutator exposed.</pre>
|
||||
</div>
|
||||
<div title="Navigator" creator="Ichthyostega" modifier="Ichthyostega" created="201710132354" modified="201712170155" tags="spec decision draft GuiPattern" changecount="21">
|
||||
<div title="Navigator" creator="Ichthyostega" modifier="Ichthyostega" created="201710132354" modified="201802240130" tags="spec decision draft GuiPattern" changecount="23">
|
||||
<pre>//Service to navigate through the UI as generic structure.//
|
||||
The Navigator is a component maintained by the InteractionDirector, and the actual implementation is backed by several facilities of the GuiTopLevel. It serves as foundation to treat the UI as a topological network of abstracted locations, represented as [[UI-Coordinates|UICoord]]. This design, together with the UI-Bus helps to reduce coupling within the UI implementation, since it enables to //get somewhere// and reach //some place// -- without the necessity to rely on concrete widget implementation structure.
|
||||
|
||||
|
|
@ -4312,6 +4313,10 @@ In the current situation ({{red{10/2017}}}), before engaging into the actual imp
|
|||
:* or to get //just some instance// of a view identified by type
|
||||
;WorkSite navication
|
||||
:move the Spot to some other place in the UI known by its [[UI-Coordinates|UICoord]]
|
||||
!!!{{red{Update 2/2018:}}} changed responsibilities
|
||||
Elaboration on the topic of »View Allocation« caused some minor architectural rearrangements.
|
||||
* Navigator became a pure information service (read-only), working on an abstracted view of the UI through [[UI coordinates|UICoord]]
|
||||
* the ViewLocator became service point for any high-level access to GuiComponentView elements
|
||||
|
||||
!!!Requirements clarified
|
||||
From these use cases we conclude that the actual requirements for a Navigator component are less than one might expect.
|
||||
|
|
@ -9846,6 +9851,14 @@ Establishing a ~ViewConnection is prerequisite for creating or attaching an Play
|
|||
View connections are part of the model and thus persistent. They can be created explicitly, or just derived by //allocating a viewer.// And a new view connection can push aside (and thus "break") an existing one from another timeline or model element. When a view connection is //broken,// any associated PlayProcess needs to be terminated (this is a blocking operation). Thus, at any time, there can be only one active view connection to a given viewer or output sink; here "active" means, that a PlayController has been hooked up, and the connection is ready for playback or rendering. But on the other hand, nothing prevents a timeline (or similar model object) to maintain multiple view connections -- consequently the actual playback position behaves as if associated with the view connection; it has only meaning with respect to this specific connection. An obvious example is that you may play back, without interfering with an ongoing render.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="ViewLocator" creator="Ichthyostega" modifier="Ichthyostega" created="201802240138" modified="201802240150" tags="spec decision draft GuiPattern" changecount="6">
|
||||
<pre>//access and location of [[component views|GuiComponentView]] as abstracted from actual UI widgets.//
|
||||
The ViewLocator is a close sibling and mutually interdependent with the [[Navigator]] -- the primary difference being the uniform, completely symbolic representation by [[UI-tree topology|UICoord]], as exposed through the latter, which precludes //immediate manipulation.// The ViewLocator likewise presents an abstracted view, but oriented towards individual components, which it allows to locate, allocate and expose by direct reference as UI-Element.
|
||||
|
||||
!Rules based handling by kind-of-view
|
||||
A small selection of //relevant UI elements// can in fact be located "by-type", relying on a configuration in the form of //locating rules...// &rarr; elaborated in more detail [[here|GuiComponentView]].
|
||||
This access mechanism allows to act on "the primary one of that kind", possibly creating a new instance on demand -- such UI elements are not to be confused with the model entities they expose for user interaction; typically they can either be re-linked or re-bound to a specific entity, or they are able to handle multiple model connections in separate tabs within the view (e.g. several [[Timelines|GuiTimelineView]]).</pre>
|
||||
</div>
|
||||
<div title="ViewerAsset" modifier="Ichthyostega" created="201105230116" modified="201105232228" tags="Model spec">
|
||||
<pre>A [[structural Asset|StructAsset]] corresponding to a Viewer element in the GUI.
|
||||
|
||||
|
|
|
|||
|
|
@ -10223,13 +10223,193 @@
|
|||
<node CREATED="1519358000671" ID="ID_49826255" MODIFIED="1519358015345" TEXT="Aufruf mit Typ-ID-Argument"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1519358138988" ID="ID_1481930885" MODIFIED="1519358147156" TEXT="Problem: DSL-Mechanik">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1519358138988" ID="ID_1481930885" MODIFIED="1519442424308" TEXT="DSL-Mechanik">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1519358154386" ID="ID_1810798001" MODIFIED="1519358201550" TEXT="Allocator wird durch Zuweisen der AlocSpec generiert">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1519358178623" ID="ID_517547970" MODIFIED="1519358197549" TEXT="beim Locator fehlt ein entsprechendes Gegenstück">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node CREATED="1519358178623" ID="ID_517547970" MODIFIED="1519442398323" TEXT="beim Locator fehlt ein entsprechendes Gegenstück">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1519359156410" ID="ID_1786241256" MODIFIED="1519359162713" TEXT="Idee">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1519359176855" ID="ID_853060191" MODIFIED="1519359192777">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
der <i>Level</i> im UI ist noch offen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1519359193821" ID="ID_588596170" MODIFIED="1519359234665" STYLE="fork" TEXT="das könnte Argument eines Builders sein"/>
|
||||
<node CREATED="1519359239735" ID="ID_988890391" MODIFIED="1519442391464" TEXT="konkret......">
|
||||
<node CREATED="1519438604809" ID="ID_313142617" MODIFIED="1519438615852" TEXT="Lösevorgang muß den Ziel-Level kennen"/>
|
||||
<node CREATED="1519438617271" ID="ID_1310079168" MODIFIED="1519438673926">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<i>fast immer</i> ist das aber UIC_VIEW
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
im Moment fällt mir überhaupt keine Ausnahme ein
|
||||
</p>
|
||||
<p>
|
||||
aber man soll niemals nie sagen;
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
jedenfalls ist der LocationSolver komplett generisch geschrieben,
|
||||
</p>
|
||||
<p>
|
||||
wäre ja auch dämlich, den auf einen Level festzunageln
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1519439848624" ID="ID_1356890401" MODIFIED="1519440019400">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
kann man den Level <i>erschließen?</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1519439872572" ID="ID_1387780581" MODIFIED="1519439914138" TEXT="fast, aber leider nein">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
<node CREATED="1519439893089" ID="ID_350245814" MODIFIED="1519440011427" TEXT="nicht wenn alle Pattern gleich lang sind">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
es ist nicht klar, ob die pattern bereits das fragliche View-Element mit einschließen,
|
||||
</p>
|
||||
<p>
|
||||
oder ob das View-Element noch angehängt werden soll. Diese Variation ist essentiell,
|
||||
</p>
|
||||
<p>
|
||||
um Regeln auszudrücken, die explizit nur eine schon existierende UI-Komponente greifen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1519440039302" ID="ID_779685706" MODIFIED="1519442729591" TEXT="folglich...">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1519440044629" ID="ID_433141744" MODIFIED="1519442714991" TEXT="muß der Level entweder aus der DSL kommen">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
<node CREATED="1519440054651" ID="ID_1512334426" MODIFIED="1519442712213" TEXT="oder er muß über den Typ gecodet sein">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1519442682549" ID="ID_1285145089" MODIFIED="1519442708878" TEXT="oder explizit beim Aufruf mitgegeben">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1519437341366" ID="ID_1400629217" MODIFIED="1519437344737" TEXT="Alternativen">
|
||||
<node CREATED="1519437362523" ID="ID_1967120024" MODIFIED="1519440122737" STYLE="bubble">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
auto locate = matchView(
|
||||
</p>
|
||||
<p>
|
||||
                          panel("blah")
|
||||
</p>
|
||||
<p>
|
||||
                          or currentWindow().panel("blubb").create() )
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
<node CREATED="1519437509655" ID="ID_241024117" MODIFIED="1519442360056" STYLE="bubble">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
LocatorSpec<UIC_VIEW> locate = panel("blah")
|
||||
</p>
|
||||
<p>
|
||||
                                                     or currentWindow().panel("blubb").create()
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1519437756333" ID="ID_565391583" MODIFIED="1519440134474" STYLE="bubble">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
ViewSpec locate = panel("blah")
|
||||
</p>
|
||||
<p>
|
||||
                                or currentWindow().panel("blubb").create()
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1519440138712" ID="ID_861550710" MODIFIED="1519440299158" TEXT="Entscheidung">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1519440157310" ID="ID_1912054433" MODIFIED="1519440166344" TEXT="ziehe die letzte Variante als Standard-Fall vor">
|
||||
<node CREATED="1519440168660" ID="ID_1954754744" MODIFIED="1519440288338" TEXT="weil sie am unscheinbarsten ist">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node CREATED="1519440271318" ID="ID_436275698" MODIFIED="1519440283871" TEXT="auch wenn dadurch die Definitionen etwas schief werden">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1519440180978" ID="ID_42017722" MODIFIED="1519440194012" TEXT="die vorletzte Variante ist die eigentliche Definition">
|
||||
<node CREATED="1519440198016" ID="ID_650838793" MODIFIED="1519440207306" TEXT="und ViewSpec ein Typ-Alias"/>
|
||||
<node CREATED="1519440208487" ID="ID_1465224504" MODIFIED="1519440222184" TEXT="analog für PanelSpec, WindowSpec"/>
|
||||
</node>
|
||||
<node CREATED="1519440250849" ID="ID_800018525" MODIFIED="1519440267084" TEXT="die Asymetrie in der DSL-Definition nehme ich in Kauf">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1519355735012" ID="ID_241646491" MODIFIED="1519355793090" TEXT="wo entsteht die LocationRule?">
|
||||
|
|
|
|||
Loading…
Reference in a new issue