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