Lumiera  0.pre.03
»edit your freedom«
dock-area.cpp
Go to the documentation of this file.
1 /*
2  DockArea - maintain a docking area within the WorkspaceWindow
3 
4  Copyright (C)
5  2008, Joel Holdsworth <joel@airwebreathe.org.uk>
6  2018, Hermann Vosseler <Ichthyostega@web.de>
7 
8   **Lumiera** is free software; you can redistribute it and/or modify it
9   under the terms of the GNU General Public License as published by the
10   Free Software Foundation; either version 2 of the License, or (at your
11   option) any later version. See the file COPYING for further details.
12 
13 * *****************************************************************/
14 
15 
22 
28 
33 
34 #include "include/logging.h"
35 #include "lib/util-foreach.hpp"
36 
37 using namespace boost;
38 using namespace std;
39 using namespace Gtk;
40 
41 namespace stage {
42 namespace workspace {
43 
44  const DockArea::PanelDescription
45  DockArea::panelDescriptionList[] = {
46 #if false
47  DockArea::Panel<TimelinePanel>(),
48  DockArea::Panel<InfoBoxPanel>(),
49  DockArea::Panel<ViewerPanel>(),
50  DockArea::Panel<AssetsPanel>()
51 #endif
52  };
53 
54  unsigned short DockArea::panelID = 0;
55 
56 
57 
58  DockArea::DockArea (WorkspaceWindow& owner)
59  : workspaceWindow_(owner)
60  , dock_()
61  , dockBar_(dock_)
62  , dockLayout_()
63  {
64  /* Create the DockLayout */
65  dockLayout_ = Gdl::DockLayout::create(dock_);
66 
67  /* Setup the Switcher Style */
68  Glib::RefPtr<Gdl::DockMaster> dock_master = dock_.property_master();
69  dock_master->property_switcher_style() = Gdl::SWITCHER_STYLE_ICON;
70 
71  memset(&dockPlaceholders_, 0, sizeof(dockPlaceholders_));
72  }
73 
74 
75 
76  DockArea::~DockArea()
77  {
80 
81 #if false
82  for(int i = 0; i < 4; i++)
84  if(dockPlaceholders_[i])
85  g_object_unref(dockPlaceholders_[i]);
86 
87  clearPanels();
88 #endif
89  }
90 
91 
92 
93  void
94  DockArea::setupDock()
95  {
97 
98  REQUIRE(dockPlaceholders_[0] == NULL && dockPlaceholders_[1] == NULL &&
99  dockPlaceholders_[2] == NULL && dockPlaceholders_[3] == NULL);
100  dockPlaceholders_[0] = GDL_DOCK_PLACEHOLDER(gdl_dock_placeholder_new(
101  "ph1", GDL_DOCK_OBJECT(dock_.gobj()), GDL_DOCK_TOP, FALSE));
102  dockPlaceholders_[1] = GDL_DOCK_PLACEHOLDER(gdl_dock_placeholder_new(
103  "ph2", GDL_DOCK_OBJECT(dock_.gobj()), GDL_DOCK_BOTTOM, FALSE));
104  dockPlaceholders_[2] = GDL_DOCK_PLACEHOLDER(gdl_dock_placeholder_new(
105  "ph3", GDL_DOCK_OBJECT(dock_.gobj()), GDL_DOCK_LEFT, FALSE));
106  dockPlaceholders_[3] = GDL_DOCK_PLACEHOLDER(gdl_dock_placeholder_new(
107  "ph4", GDL_DOCK_OBJECT(dock_.gobj()), GDL_DOCK_RIGHT, FALSE));
108  ENSURE(dockPlaceholders_[0] && dockPlaceholders_[1] &&
109  dockPlaceholders_[2] && dockPlaceholders_[3]);
110 
111  createPanels();
112  }
113 
114 
115  Gdl::Dock&
116  DockArea::getDock()
117  {
118  return dock_;
119  }
120 
121 
122  Gdl::DockBar&
123  DockArea::getDockBar()
124  {
125  return dockBar_;
126  }
127 
128 
130  DockArea::getWorkspaceWindow()
131  {
132  return workspaceWindow_;
133  }
134 
135 
136  bool
137  DockArea::hasPanel (const int description_index)
138  {
139  return util::has_any (panels_, [=](panel::Panel* panel)
140  {
141  return getPanelType(panel) == description_index;
142  });
143  }
144 
145  panel::Panel&
146  DockArea::showPanel (const int description_index)
147  {
148  // Try and find the panel and present it if possible
149  list< panel::Panel* >::iterator i;
150  for(i = panels_.begin(); i != panels_.end(); i++)
151  {
152  panel::Panel* const panel = *i;
153  if (getPanelType(panel) == description_index)
154  {
155  if (!panel->is_shown()) panel->show();
156 
157  Gdl::DockItem &dock_item = panel->getDockItem();
158  // ENSURE(dock_item);
159  dock_item.present(dock_);
160  ENSURE (panel);
161  return *panel;
162  }
163  }
164 
165  // Create the new panel
166  panel::Panel *new_panel = createPanel_by_index (description_index);
167 
168  // Dock the item
169  dock_.add_item(new_panel->getDockItem(), Gdl::DOCK_FLOATING);
170 
171  ENSURE (new_panel);
172  return *new_panel;
173  }
174 
175 
176  void
177  DockArea::switchPanel (panel::Panel& old_panel, const int description_index)
178  {
179  REQUIRE (description_index >= 0 &&
180  description_index < getPanelDescriptionCount());
181 
182  // Get the dock item
183  Gdl::DockItem &dock_item = old_panel.getDockItem();
184 
185  // Release the old panel
186  removePanel (&old_panel);
187 
188  // Create the new panel
189  createPanel_by_index (description_index, dock_item);
190  }
191 
192 
193  void
194  DockArea::splitPanel (panel::Panel& panel, Gtk::Orientation split_direction)
195  {
196 
197  // Create the new panel
198  const int index = getPanelType(&panel);
199  panel::Panel *new_panel = createPanel_by_index(index);
200 
201  // Dock the panel
202  Gdl::DockPlacement placement = Gdl::DOCK_NONE;
203  switch(split_direction)
204  {
205  case ORIENTATION_HORIZONTAL:
206  placement = Gdl::DOCK_RIGHT;
207  break;
208 
209  case ORIENTATION_VERTICAL:
210  placement = Gdl::DOCK_BOTTOM;
211  break;
212 
213  default:
214  ERROR(stage, "Unknown split_direction: %d", split_direction);
215  return;
216  break;
217  }
218 
219  panel.getDockItem().dock(
220  new_panel->getDockItem(),placement);
221  }
222 
223 
224  int
225  DockArea::getPanelDescriptionCount()
226  {
227  return sizeof(panelDescriptionList) / sizeof(PanelDescription);
228  }
229 
230 
231  const gchar*
232  DockArea::getPanelStockID (int index)
233  {
234  REQUIRE (index >= 0 && index < getPanelDescriptionCount());
235  return panelDescriptionList[index].getStockID();
236  }
237 
238 
239  const char*
240  DockArea::getPanelTitle (int index)
241  {
242  REQUIRE (index >= 0 && index < getPanelDescriptionCount());
243  return panelDescriptionList[index].getTitle();
244  }
245 
246 
247  void
248  DockArea::createPanels()
249  {
251  panel::Panel* assetsPanel = createPanel_by_name("AssetsPanel");
252  panel::Panel* viewerPanel = createPanel_by_name("InfoBoxPanel");
253  panel::Panel* timelinePanel = createPanel_by_name("TimelinePanel");
254 
255  dock_.add_item(assetsPanel->getDockItem(),Gdl::DOCK_LEFT);
256  dock_.add_item(timelinePanel->getDockItem(),Gdl::DOCK_BOTTOM);
257  dock_.add_item(viewerPanel->getDockItem(),Gdl::DOCK_RIGHT);
258  }
259 
260 
261  int
262  DockArea::findPanelDescription (const char* class_name)
263  {
264  REQUIRE(class_name);
265 
266  const int count = getPanelDescriptionCount();
267  for(int i = 0; i < count; i++)
268  {
269  if (strstr(panelDescriptionList[i].getClassName(), class_name))
270  return i;
271  }
272 
273  ERROR (stage, "Unable to find a description with class name %s", class_name);
274  return -1;
275  }
276 
277 
278  panel::Panel*
279  DockArea::createPanel_by_index (const int index)
280  {
281  REQUIRE(index >= 0 && index < getPanelDescriptionCount());
282 
283  // Make a unique name for the panel
284  char name[5];
285  snprintf(name, sizeof(name), "%X", panelID++);
286 
287  // Create a dock item
288  return createPanel_by_index(index,
289  *new Gdl::DockItem(name,"",Gdl::DOCK_ITEM_BEH_NORMAL));
290  }
291 
292 
293  panel::Panel*
294  DockArea::createPanel_by_index (const int index, Gdl::DockItem &dock_item)
295  {
296  // Create the panel object
297  panel::Panel *panel = panelDescriptionList[index].create(*this, dock_item);
298  ENSURE(panel);
299  panel->show_all();
300 
301  // Connect event handlers
302  panel->signal_hidePanel().connect(sigc::bind(
303  sigc::mem_fun(*this, &DockArea::on_panel_shown), panel));
304 
305  // Add the panel to the list
306  panels_.push_back(panel);
307 
308  return panel;
309  }
310 
311 
312  panel::Panel*
313  DockArea::createPanel_by_name (const char* class_name)
314  {
315  REQUIRE(class_name);
316  const int index = findPanelDescription(class_name);
317  return createPanel_by_index(index);
318  }
319 
320 
321  int
322  DockArea::getPanelType (panel::Panel* const panel) const
323  {
324  REQUIRE(panel);
325 
326  const type_info &info = typeid(*panel);
327  const int count = getPanelDescriptionCount();
328  for(int i = 0; i < count; i++)
329  {
330  if(info == panelDescriptionList[i].getClassInfo())
331  return i;
332  }
333 
334  ERROR(stage, "Unable to find a description with with this class type");
335  return -1;
336  }
337 
338 
339  void
340  DockArea::removePanel (panel::Panel* const panel)
341  {
342  REQUIRE(panel);
343 
344  list< panel::Panel* >::iterator i;
345  for(i = panels_.begin(); i != panels_.end(); i++)
346  {
347  if(*i == panel)
348  {
349  delete panel;
350  panels_.erase(i);
351  break;
352  }
353  }
354  }
355 
356 
357  void
358  DockArea::clearPanels()
359  {
361 
362  list< panel::Panel* >::iterator i;
363  for(i = panels_.begin(); i != panels_.end(); i++)
364  delete *i;
365  panels_.clear();
366  }
367 
368 
369  void
370  DockArea::on_panel_shown (panel::Panel* panel)
371  {
372  REQUIRE(panel);
373  if(panel->is_shown() || panel->is_iconified()) return;
374 
375  removePanel(panel);
376  }
377 
378 
379 
380 }}// namespace stage::workspace
Management of dockable panels within each top-level WorkspaceWindow.
Definition: trait.hpp:60
STL namespace.
This header is for including and configuring NoBug.
bool is_iconified() const
Definition: panel.cpp:113
void show(bool show=true)
Shows or hides the panel.
Definition: panel.cpp:92
A (dockable) panel to organise the assets of a project.
The base class for all dockable panels.
Definition: panel.hpp:40
Lumiera GTK UI implementation root.
Definition: guifacade.cpp:37
A class to describe and instantiate Panel types.
Definition: dock-area.hpp:232
A (dockable) panel to display and manage information and parameters.
The main Lumiera workspace window.
Definition of a dockable panel to hold the video viewers.
sigc::signal< void > & signal_hidePanel()
fires when the dock item gets hidden.
Definition: panel.cpp:151
Gdl::DockItem & getDockItem()
Definition: panel.cpp:86
Perform operations "for each element" of a collection.
ElementBoxWidget::Config::Qualifier name(string id)
define the name-ID displayed in the caption
A dockable container to hold a notebook of timeline displays.