Lumiera  0.pre.03
»edit your freedom«
track-profile.hpp
Go to the documentation of this file.
1 /*
2  TRACK-PROFILE.hpp - building the 3D profile of tracks for timeline presentation
3 
4  Copyright (C)
5  2019, 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 
29 #ifndef STAGE_TIMELINE_TRACK_PROFILE_H
30 #define STAGE_TIMELINE_TRACK_PROFILE_H
31 
32 #include "stage/gtk-base.hpp"
33 #include "lib/verb-visitor.hpp"
34 
35 #include "lib/iter-explorer.hpp"
36 #include "lib/symbol.hpp"
37 #include "lib/util.hpp"
38 
39 //#include <memory>
40 #include <utility>
41 #include <vector>
42 
43 
44 
45 namespace stage {
46 namespace timeline {
47 
48  using lib::Literal;
49  using util::isnil;
50  using std::forward;
51 
53  {
54  public:
55  virtual ~ProfileInterpreter() { }
56 
57  virtual void ruler(uint h) =0;
58  virtual void gap(uint h) =0;
59  virtual void content(uint h) =0;
60  virtual void open() =0;
61  virtual void close(uint n) =0;
62  virtual void prelude() =0;
63  virtual void coda(uint pad) =0;
64 
65  static const size_t MAX_ARG_SIZE = sizeof(size_t);
66  };
67 
79  {
81  using Elements = std::vector<SlopeVerb>;
82 
83  Elements elements;
84  int pinnedPrefixCnt = 0;
85 
86  public:
87  // default constructible, standard copy operations
88 
89  bool
90  empty() const
91  {
92  return elements.empty();
93  }
94 
95  void
96  clear() noexcept
97  {
98  elements.clear();
99  }
100 
101  void
102  performWith (ProfileInterpreter& interpreter)
103  {
104  for (auto& slopeVerb : elements)
105  slopeVerb.applyTo (interpreter);
106  }
107 
108  void performWith (ProfileInterpreter& interpreter, bool isRulerSegment);
109 
110 
111 
112  private:/* ===== Internals: handling tokens ===== */
113 
114  template<typename FUN, typename...ARGS>
115  void
116  append (FUN&& handler, Literal token, ARGS&&... params)
117  {
118  elements.emplace_back (forward<FUN>(handler), token, forward<ARGS>(params)...);
119  }
120 
121 #define TOKEN_BUILDER(_TOK_) \
122  template<typename...ARGS> \
123  void \
124  append_ ## _TOK_ (ARGS&&... params)\
125  { \
126  this->append (&ProfileInterpreter::_TOK_, STRINGIFY(_TOK_), forward<ARGS>(params)...); \
127  }
128 
129  public:
130  TOKEN_BUILDER (ruler)
131  TOKEN_BUILDER (gap)
132  TOKEN_BUILDER (content)
133  TOKEN_BUILDER (open)
134  TOKEN_BUILDER (close)
135  TOKEN_BUILDER (prelude)
136  TOKEN_BUILDER (coda)
137 
138  void
139  addSlopeDown()
140  {
141  this->append_open();
142  }
143 
144  void
145  addSlopeUp()
146  {
147  if (lastEntryIs("close"))
148  incrementLastCloseSlope();
149  else
150  append_close (1);
151  }
152 
153  uint
154  getPrecedingSlopeUp()
155  {
156  if (lastEntryIs("close"))
157  return elements.back().accessArg<uint>();
158  return 0;
159  }
160 
161  void
162  markPrefixEnd()
163  {
164  pinnedPrefixCnt = elements.size();
165  }
166 
167  private:
168  bool
169  lastEntryIs (Literal expectedToken)
170  {
171  return not isnil(elements)
172  and elements.back()->getID() == expectedToken;
173  }
174 
175  void
176  incrementLastCloseSlope()
177  {
178  REQUIRE (lastEntryIs ("close"));
179  uint& slopeDepth = elements.back().accessArg<uint>();
180 
181  ++ slopeDepth;
182  }
183 
184  auto
185  filterSegment(bool selectPrefixPart)
186  {
187  struct CountingFilter
188  {
189  int cnt;
190  bool selectPrefix;
191 
192  bool
193  operator() (...)
194  {
195  bool isPrefixPart = 0 < cnt--;
196  return selectPrefix? isPrefixPart : not isPrefixPart;
197  }
198  };
199 
200 
201  return lib::explore (elements)
202  .filter (CountingFilter{pinnedPrefixCnt, selectPrefixPart});
203  }
204  };
205 
206 
220  inline void
221  TrackProfile::performWith (ProfileInterpreter& interpreter, bool isRulerSegment)
222  {
223  for (auto& slopeVerb : filterSegment(isRulerSegment))
224  slopeVerb.applyTo (interpreter);
225  }
226 
227 
228 
229 }}// namespace stage::timeline
230 #endif /*STAGE_TIMELINE_TRACK_PROFILE_H*/
virtual void open()=0
indicate entering a nested structure, typically as 3D inset
IterQueue< T > elements(T const &elm)
convenience free function to build an iterable sequence
Definition: iter-stack.hpp:292
auto explore(IT &&srcSeq)
start building a IterExplorer by suitably wrapping the given iterable source.
virtual void content(uint h)=0
represent a content area with the given vertical extension
A self-contained token to embody a specific yet abstracted operation, together with a concrete set of...
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:76
virtual void close(uint n)=0
indicate the end of n nested structures, typically by ascending back n levels
virtual ~ProfileInterpreter()
this is an interface
virtual void prelude()=0
start the track presentation at top of the timeline
Marker types to indicate a literal string and a Symbol.
Description of the structure and arrangement of tracks for display in the UI.
A specific double dispatch variation for function invocation.
Lumiera GTK UI implementation root.
Definition: guifacade.cpp:37
virtual void gap(uint h)=0
represent a gap to structure the display
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
virtual void coda(uint pad)=0
closing part of the timeline below track display, with pad additional padding
Building tree expanding and backtracking evaluations within hierarchical scopes.
A set of basic GTK includes for the UI.
virtual void ruler(uint h)=0
represent an overview/ruler track with the given height