Lumiera  0.pre.03
»edit your freedom«
track-head-widget.cpp
Go to the documentation of this file.
1 /*
2  TrackHeadWidget - display of track heads within the timeline
3 
4  Copyright (C) Lumiera.org
5  2016, 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 
48 #include "stage/gtk-base.hpp"
49 #include "stage/style-scheme.hpp"
51 
52 #include "lib/util.hpp"
53 
54 using util::max;
55 
56 
57 namespace stage {
58 namespace timeline {
59 
60 
61 
62 
63  TrackHeadWidget::~TrackHeadWidget() { }
64  HeadControlArea::~HeadControlArea() { }
65 
66 
67 
68  TrackHeadWidget::TrackHeadWidget()
69  : Gtk::Grid{}
71  , structure_{}
72  , padding_{}
73  , headCtrl_{}
74  , childCnt_{0}
75  {
76  get_style_context()->add_class (CLASS_fork_head);
77  headCtrl_.set_valign(Gtk::Align::ALIGN_CENTER);
78  headCtrl_.set_halign(Gtk::Align::ALIGN_FILL);
79  this->attach (trackName_, 0,0, 2,1);
80  this->attach (structure_, 0,1, 1,2);
81  this->attach (headCtrl_, 1,1, 1,1); // corresponds to direct content
82  this->attach (padding_, 1,2, 1,1);// used to sync with sub-track display
83  this->property_expand() = false; // do not expand to fill
84  this->set_column_spacing(0);
85  this->set_row_spacing(0);
86  this->show_all();
87  }
88 
89 
90  HeadControlArea::HeadControlArea()
91  : Gtk::Grid{}
92  , ctrlTODO_{"\n 💡"}
93  {
94  get_style_context()->add_class (CLASS_fork_control);
95  ctrlTODO_.set_xalign (0.3);
96  ctrlTODO_.set_yalign (0.5);
97  this->attach (ctrlTODO_, 0,0, 1,1);
98  this->property_expand() = true;
99  this->show_all();
100  }
101 
102 
103  void
104  TrackHeadWidget::setTrackName (cuString& trackName)
105  {
106  trackName_.setName (trackName);
107  }
108 
109  uint
110  TrackHeadWidget::getHeightAt (int left, int top) const
111  {
112  auto* cell = this->get_child_at(left,top);
113  if (cell == nullptr) return 0;
114  int actual = cell->get_height();
115  int minimal=0, natural=0;
116  cell->get_preferred_height(minimal, natural);
117  return max (0, max (actual, natural));
118  }
119 
120  uint
121  TrackHeadWidget::getOverallHeight() const
122  {
123  uint heightSum{0};
124  for (uint line=1; line <= 2u + childCnt_; ++line)
125  heightSum += getHeightAt (1,line);
126  heightSum = max (heightSum, getExpansionHeight());
127  return heightSum + getLabelHeight();
128  }
129 
130  void
131  TrackHeadWidget::enforceHeightAt(int left, int top, uint height)
132  {
133  auto* cell = this->get_child_at(left,top);
134  REQUIRE (cell);
135  cell->set_size_request (-1, height);
136  }
137 
138  void
139  TrackHeadWidget::accommodateContentHeight(uint contentHeight)
140  {
141  uint localHeight = getContentHeight();
142  if (contentHeight > localHeight)
143  enforceContentHeight (contentHeight);
144  }
145 
146  void
147  TrackHeadWidget::accommodateOverallHeight(uint overallHeight)
148  {
149  uint discrepancy{0};
150  uint localHeight = getOverallHeight();
151  if (overallHeight > localHeight)
152  {
153  enforceExpansionHeight (overallHeight - getLabelHeight());
154  discrepancy = overallHeight-localHeight;
155  }
156  linkSubTrackPositions (discrepancy);
157  }
158 
166  void
168  {
169  uint localHeight = getContentHeight() + getLabelHeight();
170  if (directHeight > localHeight)
171  enforceSyncPadHeight (directHeight - localHeight);
172  }
173 
180  void
182  {
183  structure_.clearConnectors();
184  uint offset = getContentHeight()
185  + getSyncPadHeight()
186  + discrepancy
187  + getLabelHeight() // offset by the label in the children
188  ;
189  for (uint child=0; child < childCnt_; ++child)
190  {
191  structure_.addConnector (offset);
192  offset += getHeightAt (1, child+3);
193  }
194  }
195 
196 
212  void
214  {
215  ++childCnt_;
216  uint act = 2 + childCnt_; // left,top
217  Gtk::Grid::attach (subForkHead, 1, act, 1,1);
218  // expand the structure display column....
219  Gtk::Grid::remove (structure_); // width,height
220  Gtk::Grid::attach (structure_, 0,1, 1, act);
221  }
222 
233  void
235  {
236  --childCnt_;
237  uint act = 2 + childCnt_;
238  Gtk::Grid::remove (subForkHead);
239  // reduce the structure display column....
240  Gtk::Grid::remove (structure_);
241  Gtk::Grid::attach (structure_, 0,1, 1,act);
242  }
243 
244 
245  void
247  {
248  if (not childCnt_) return;
249  Gtk::Grid::remove (structure_);
250  while (childCnt_ > 0)
251  {
252  Gtk::Grid::remove_row (childCnt_);
253  --childCnt_;
254  }
255  Gtk::Grid::attach (structure_, 0,1, 1,2);
256  }
257 
258 
259 
260  /* ==== Interface: ViewHook ===== */
261 
262  void
263  TrackHeadWidget::hook (TrackHeadWidget& subHead)
264  {
265  attachSubFork (subHead);
266  }
267 
268  void
269  TrackHeadWidget::remove (TrackHeadWidget& subHead)
270  {
271  detachSubFork (subHead);
272  }
273 
282  void
283  TrackHeadWidget::rehook (TrackHeadWidget& hookedSubHead) noexcept
284  {
285  detachSubFork (hookedSubHead);
286  attachSubFork (hookedSubHead);
287  }
288 
289 
290 
291 }}// namespace stage::timeline
Header pane control area corresponding to a Track with nested child Tracks.
void attachSubFork(TrackHeadWidget &subForkHead)
Integrate the control area for a nested sub track fork.
void clearFork()
Discard all nested sub track display widgets.
Widget represents an entity within a collection (Bin)
void syncSubtrackStartHeight(uint)
The first part of each track&#39;s display relates to the direct content; below that area, the content of sub-tracks may be added.
Widget to represent a track head with placement parameters, within the timeline header pane...
Lumiera GTK UI implementation root.
Definition: guifacade.cpp:46
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
void linkSubTrackPositions(uint)
Coordinate the exact positions of sub-Track start during DisplayEvaluaton.
void rehook(TrackHeadWidget &) noexcept override
uint getHeightAt(int left, int top) const
get the height allocated at cell(x,y)
represents a label or descriptor
Definition of access keys for uniform UI styling.
A set of basic GTK includes for the UI.
void detachSubFork(TrackHeadWidget &subForkHead)