2009-04-04 17:57:06 +02:00
/*
2015-05-29 04:44:58 +02:00
PanelManager - management of dockable GDL panels
2010-12-17 23:28:49 +01:00
2009-04-04 17:57:06 +02:00
Copyright ( C ) Lumiera . org
2008 , Joel Holdsworth < joel @ airwebreathe . org . uk >
2010-12-17 23:28:49 +01:00
2009-04-04 17:57:06 +02:00
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License as
2010-12-17 23:28:49 +01:00
published by the Free Software Foundation ; either version 2 of
the License , or ( at your option ) any later version .
2009-04-04 17:57:06 +02:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2010-12-17 23:28:49 +01:00
2009-04-04 17:57:06 +02:00
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
2010-12-17 23:28:49 +01:00
2009-04-04 17:57:06 +02:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-05-29 04:44:58 +02:00
2016-11-03 18:20:10 +01:00
/** @file §§§
* * TODO § § §
*/
2014-08-17 07:02:48 +02:00
# include "gui/workspace/panel-manager.hpp"
2009-04-04 17:57:06 +02:00
2015-05-29 04:44:58 +02:00
# include "gui/panel/assets-panel.hpp"
# include "gui/panel/viewer-panel.hpp"
# include "gui/panel/timeline-panel.hpp"
2009-04-04 17:57:06 +02:00
# include "include/logging.h"
using namespace boost ;
using namespace std ;
2009-04-15 13:24:34 +02:00
using namespace Gtk ;
2009-04-04 17:57:06 +02:00
namespace gui {
namespace workspace {
2009-04-15 19:27:07 +02:00
2015-05-29 04:44:58 +02:00
const PanelManager : : PanelDescription
PanelManager : : panelDescriptionList [ ] = {
PanelManager : : Panel < TimelinePanel > ( ) ,
PanelManager : : Panel < ViewerPanel > ( ) ,
PanelManager : : Panel < AssetsPanel > ( )
} ;
2009-04-15 19:14:16 +02:00
2015-05-29 04:44:58 +02:00
unsigned short PanelManager : : panelID = 0 ;
2009-04-15 13:24:34 +02:00
2015-05-29 04:44:58 +02:00
PanelManager : : PanelManager ( WorkspaceWindow & owner )
: workspaceWindow_ ( owner )
, dock_ ( )
, dockBar_ ( dock_ )
, dockLayout_ ( )
2009-04-15 13:24:34 +02:00
{
2015-05-29 04:44:58 +02:00
/* Create the DockLayout */
dockLayout_ = Gdl : : DockLayout : : create ( dock_ ) ;
/* Setup the Switcher Style */
Glib : : RefPtr < Gdl : : DockMaster > dock_master = dock_ . property_master ( ) ;
dock_master - > property_switcher_style ( ) = Gdl : : SWITCHER_STYLE_ICON ;
memset ( & dockPlaceholders_ , 0 , sizeof ( dockPlaceholders_ ) ) ;
2009-04-15 13:24:34 +02:00
}
2015-05-29 04:44:58 +02:00
PanelManager : : ~ PanelManager ( )
{
///////////////////////////////////////////////////////TICKET #195 : violation of policy, dtors must not do any work
///////////////////////////////////////////////////////TICKET #172 : observed as a reason for crashes when closing the GUI. It was invoked after end of main, when the GUI as already gone.
2009-04-15 13:24:34 +02:00
2015-05-29 04:44:58 +02:00
# if false ///////////////////////////////////////////////////TICKET #937 : disabled for GTK-3 transition. TODO investigate why this logic existed...
for ( int i = 0 ; i < 4 ; i + + )
if ( dockPlaceholders_ [ i ] )
g_object_unref ( dockPlaceholders_ [ i ] ) ;
clearPanels ( ) ;
# endif ///////////////////////////////////////////////////TICKET #937 : (End)disabled for GTK-3 transition.
}
2009-04-15 13:24:34 +02:00
2009-04-15 21:12:06 +02:00
2015-05-29 04:44:58 +02:00
void
PanelManager : : setupDock ( )
{
REQUIRE ( dockPlaceholders_ [ 0 ] = = NULL & & dockPlaceholders_ [ 1 ] = = NULL & &
dockPlaceholders_ [ 2 ] = = NULL & & dockPlaceholders_ [ 3 ] = = NULL ) ;
dockPlaceholders_ [ 0 ] = GDL_DOCK_PLACEHOLDER ( gdl_dock_placeholder_new (
" ph1 " , GDL_DOCK_OBJECT ( dock_ . gobj ( ) ) , GDL_DOCK_TOP , FALSE ) ) ;
dockPlaceholders_ [ 1 ] = GDL_DOCK_PLACEHOLDER ( gdl_dock_placeholder_new (
" ph2 " , GDL_DOCK_OBJECT ( dock_ . gobj ( ) ) , GDL_DOCK_BOTTOM , FALSE ) ) ;
dockPlaceholders_ [ 2 ] = GDL_DOCK_PLACEHOLDER ( gdl_dock_placeholder_new (
" ph3 " , GDL_DOCK_OBJECT ( dock_ . gobj ( ) ) , GDL_DOCK_LEFT , FALSE ) ) ;
dockPlaceholders_ [ 3 ] = GDL_DOCK_PLACEHOLDER ( gdl_dock_placeholder_new (
" ph4 " , GDL_DOCK_OBJECT ( dock_ . gobj ( ) ) , GDL_DOCK_RIGHT , FALSE ) ) ;
ENSURE ( dockPlaceholders_ [ 0 ] & & dockPlaceholders_ [ 1 ] & &
dockPlaceholders_ [ 2 ] & & dockPlaceholders_ [ 3 ] ) ;
createPanels ( ) ;
}
2009-04-16 11:02:53 +02:00
2015-05-29 04:44:58 +02:00
Gdl : : Dock &
PanelManager : : getDock ( )
{
return dock_ ;
}
Gdl : : DockBar &
PanelManager : : getDockBar ( )
{
return dockBar_ ;
}
WorkspaceWindow &
PanelManager : : getWorkspaceWindow ( )
{
return workspaceWindow_ ;
}
void
PanelManager : : showPanel ( const int description_index )
{
// Try and find the panel and present it if possible
list < panel : : Panel * > : : iterator i ;
for ( i = panels_ . begin ( ) ; i ! = panels_ . end ( ) ; i + + )
{
panel : : Panel * const panel = * i ;
if ( getPanelType ( panel ) = = description_index )
{
if ( ! panel - > is_shown ( ) ) panel - > show ( ) ;
Gdl : : DockItem & dock_item = panel - > getDockItem ( ) ;
// ENSURE(dock_item);
dock_item . present ( dock_ ) ;
return ;
}
}
// Create the new panel
panel : : Panel * new_panel = createPanel_by_index ( description_index ) ;
// Dock the item
dock_ . add_item ( new_panel - > getDockItem ( ) , Gdl : : DOCK_FLOATING ) ;
}
void
PanelManager : : switchPanel ( panel : : Panel & old_panel , const int description_index )
{
REQUIRE ( description_index > = 0 & &
description_index < getPanelDescriptionCount ( ) ) ;
// Get the dock item
Gdl : : DockItem & dock_item = old_panel . getDockItem ( ) ;
// Release the old panel
removePanel ( & old_panel ) ;
// Create the new panel
createPanel_by_index ( description_index , dock_item ) ;
}
void
PanelManager : : splitPanel ( panel : : Panel & panel , Gtk : : Orientation split_direction )
{
// Create the new panel
const int index = getPanelType ( & panel ) ;
panel : : Panel * new_panel = createPanel_by_index ( index ) ;
// Dock the panel
Gdl : : DockPlacement placement = Gdl : : DOCK_NONE ;
switch ( split_direction )
{
case ORIENTATION_HORIZONTAL :
placement = Gdl : : DOCK_RIGHT ;
break ;
case ORIENTATION_VERTICAL :
placement = Gdl : : DOCK_BOTTOM ;
break ;
default :
ERROR ( gui , " Unknown split_direction: %d " , split_direction ) ;
return ;
break ;
}
panel . getDockItem ( ) . dock (
new_panel - > getDockItem ( ) , placement ) ;
}
int
PanelManager : : getPanelDescriptionCount ( )
{
return sizeof ( panelDescriptionList ) / sizeof ( PanelDescription ) ;
}
const gchar *
PanelManager : : getPanelStockID ( int index )
{
REQUIRE ( index > = 0 & & index < getPanelDescriptionCount ( ) ) ;
return panelDescriptionList [ index ] . getStockID ( ) ;
}
const char *
PanelManager : : getPanelTitle ( int index )
{
REQUIRE ( index > = 0 & & index < getPanelDescriptionCount ( ) ) ;
return panelDescriptionList [ index ] . getTitle ( ) ;
}
void
PanelManager : : createPanels ( )
{
panel : : Panel * assetsPanel = createPanel_by_name ( " AssetsPanel " ) ;
panel : : Panel * viewerPanel = createPanel_by_name ( " ViewerPanel " ) ;
panel : : Panel * timelinePanel = createPanel_by_name ( " TimelinePanel " ) ;
dock_ . add_item ( assetsPanel - > getDockItem ( ) , Gdl : : DOCK_LEFT ) ;
dock_ . add_item ( timelinePanel - > getDockItem ( ) , Gdl : : DOCK_BOTTOM ) ;
dock_ . add_item ( viewerPanel - > getDockItem ( ) , Gdl : : DOCK_RIGHT ) ;
}
int
PanelManager : : findPanelDescription ( const char * class_name ) const
{
REQUIRE ( class_name ) ;
const int count = getPanelDescriptionCount ( ) ;
for ( int i = 0 ; i < count ; i + + )
{
if ( strstr ( panelDescriptionList [ i ] . getClassName ( ) , class_name ) )
return i ;
}
ERROR ( gui , " Unable to find a description with class name %s " , class_name ) ;
return - 1 ;
}
panel : : Panel *
PanelManager : : createPanel_by_index ( const int index )
{
REQUIRE ( index > = 0 & & index < getPanelDescriptionCount ( ) ) ;
// Make a unique name for the panel
char name [ 5 ] ;
snprintf ( name , sizeof ( name ) , " %X " , panelID + + ) ;
// Create a dock item
return createPanel_by_index ( index ,
* new Gdl : : DockItem ( name , " " , Gdl : : DOCK_ITEM_BEH_NORMAL ) ) ;
}
panel : : Panel *
PanelManager : : createPanel_by_index ( const int index , Gdl : : DockItem & dock_item )
{
// Create the panel object
panel : : Panel * panel = panelDescriptionList [ index ] . create ( * this , dock_item ) ;
ENSURE ( panel ) ;
panel - > show_all ( ) ;
// Connect event handlers
panel - > signal_hidePanel ( ) . connect ( sigc : : bind (
sigc : : mem_fun ( * this , & PanelManager : : on_panel_shown ) , panel ) ) ;
// Add the panel to the list
panels_ . push_back ( panel ) ;
return panel ;
}
panel : : Panel *
PanelManager : : createPanel_by_name ( const char * class_name )
{
REQUIRE ( class_name ) ;
const int index = findPanelDescription ( class_name ) ;
return createPanel_by_index ( index ) ;
}
int
PanelManager : : getPanelType ( panel : : Panel * const panel ) const
{
REQUIRE ( panel ) ;
const type_info & info = typeid ( * panel ) ;
const int count = getPanelDescriptionCount ( ) ;
for ( int i = 0 ; i < count ; i + + )
{
if ( info = = panelDescriptionList [ i ] . getClassInfo ( ) )
return i ;
}
ERROR ( gui , " Unable to find a description with with this class type " ) ;
return - 1 ;
}
void
PanelManager : : removePanel ( panel : : Panel * const panel )
{
REQUIRE ( panel ) ;
list < panel : : Panel * > : : iterator i ;
for ( i = panels_ . begin ( ) ; i ! = panels_ . end ( ) ; i + + )
{
if ( * i = = panel )
{
delete panel ;
panels_ . erase ( i ) ;
break ;
}
}
}
void
PanelManager : : clearPanels ( )
{
///////////////////////////////////////////////////////TICKET #195 : this whole approach smells like an obsolete "C-style" approach. We should strive to let the runtime system do such stuff for us whenever possible, eg. by using smart pointers
list < panel : : Panel * > : : iterator i ;
for ( i = panels_ . begin ( ) ; i ! = panels_ . end ( ) ; i + + )
delete * i ;
panels_ . clear ( ) ;
}
void
PanelManager : : on_panel_shown ( panel : : Panel * panel )
{
REQUIRE ( panel ) ;
if ( panel - > is_shown ( ) | | panel - > is_iconified ( ) ) return ;
removePanel ( panel ) ;
}
} } // namespace gui::workspace