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) Lumiera.org
5  2019, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
38 #ifndef STAGE_TIMELINE_TRACK_PROFILE_H
39 #define STAGE_TIMELINE_TRACK_PROFILE_H
40 
41 #include "stage/gtk-base.hpp"
42 #include "lib/verb-visitor.hpp"
43 
44 #include "lib/iter-explorer.hpp"
45 #include "lib/symbol.hpp"
46 #include "lib/util.hpp"
47 
48 //#include <memory>
49 #include <utility>
50 #include <vector>
51 
52 
53 
54 namespace stage {
55 namespace timeline {
56 
57  using lib::Literal;
58  using util::isnil;
59  using std::forward;
60 
62  {
63  public:
64  virtual ~ProfileInterpreter() { }
65 
66  virtual void ruler(uint h) =0;
67  virtual void gap(uint h) =0;
68  virtual void content(uint h) =0;
69  virtual void open() =0;
70  virtual void close(uint n) =0;
71  virtual void prelude() =0;
72  virtual void coda(uint pad) =0;
73 
74  static const size_t MAX_ARG_SIZE = sizeof(size_t);
75  };
76 
88  {
90  using Elements = std::vector<SlopeVerb>;
91 
92  Elements elements;
93  int pinnedPrefixCnt = 0;
94 
95  public:
96  // default constructible, standard copy operations
97 
98  bool
99  empty() const
100  {
101  return elements.empty();
102  }
103 
104  void
105  clear() noexcept
106  {
107  elements.clear();
108  }
109 
110  void
111  performWith (ProfileInterpreter& interpreter)
112  {
113  for (auto& slopeVerb : elements)
114  slopeVerb.applyTo (interpreter);
115  }
116 
117  void performWith (ProfileInterpreter& interpreter, bool isRulerSegment);
118 
119 
120 
121  private:/* ===== Internals: handling tokens ===== */
122 
123  template<typename FUN, typename...ARGS>
124  void
125  append (FUN&& handler, Literal token, ARGS&&... params)
126  {
127  elements.emplace_back (forward<FUN>(handler), token, forward<ARGS>(params)...);
128  }
129 
130 #define TOKEN_BUILDER(_TOK_) \
131  template<typename...ARGS> \
132  void \
133  append_ ## _TOK_ (ARGS&&... params)\
134  { \
135  this->append (&ProfileInterpreter::_TOK_, STRINGIFY(_TOK_), forward<ARGS>(params)...); \
136  }
137 
138  public:
139  TOKEN_BUILDER (ruler)
140  TOKEN_BUILDER (gap)
141  TOKEN_BUILDER (content)
142  TOKEN_BUILDER (open)
143  TOKEN_BUILDER (close)
144  TOKEN_BUILDER (prelude)
145  TOKEN_BUILDER (coda)
146 
147  void
148  addSlopeDown()
149  {
150  this->append_open();
151  }
152 
153  void
154  addSlopeUp()
155  {
156  if (lastEntryIs("close"))
157  incrementLastCloseSlope();
158  else
159  append_close (1);
160  }
161 
162  uint
163  getPrecedingSlopeUp()
164  {
165  if (lastEntryIs("close"))
166  return elements.back().accessArg<uint>();
167  return 0;
168  }
169 
170  void
171  markPrefixEnd()
172  {
173  pinnedPrefixCnt = elements.size();
174  }
175 
176  private:
177  bool
178  lastEntryIs (Literal expectedToken)
179  {
180  return not isnil(elements)
181  and elements.back()->getID() == expectedToken;
182  }
183 
184  void
185  incrementLastCloseSlope()
186  {
187  REQUIRE (lastEntryIs ("close"));
188  uint& slopeDepth = elements.back().accessArg<uint>();
189 
190  ++ slopeDepth;
191  }
192 
193  auto
194  filterSegment(bool selectPrefixPart)
195  {
196  struct CountingFilter
197  {
198  int cnt;
199  bool selectPrefix;
200 
201  bool
202  operator() (...)
203  {
204  bool isPrefixPart = 0 < cnt--;
205  return selectPrefix? isPrefixPart : not isPrefixPart;
206  }
207  };
208 
209 
210  return lib::explore (elements)
211  .filter (CountingFilter{pinnedPrefixCnt, selectPrefixPart});
212  }
213  };
214 
215 
229  inline void
230  TrackProfile::performWith (ProfileInterpreter& interpreter, bool isRulerSegment)
231  {
232  for (auto& slopeVerb : filterSegment(isRulerSegment))
233  slopeVerb.applyTo (interpreter);
234  }
235 
236 
237 
238 }}// namespace stage::timeline
239 #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:301
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:85
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:46
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