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