2009-04-04 17:57:06 +02:00
/*
panel - manager . cpp - Definition of the panel manager object
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-08-17 07:02:48 +02:00
# include "gui/workspace/panel-manager.hpp"
2009-04-04 17:57:06 +02:00
2010-12-27 05:50:40 +01:00
# include "gui/panels/assets-panel.hpp"
# include "gui/panels/viewer-panel.hpp"
# include "gui/panels/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 {
const PanelManager : : PanelDescription
PanelManager : : panelDescriptionList [ ] = {
PanelManager : : Panel < TimelinePanel > ( ) ,
PanelManager : : Panel < ViewerPanel > ( ) ,
2010-12-06 14:18:53 +01:00
PanelManager : : Panel < AssetsPanel > ( )
2009-04-04 17:57:06 +02:00
} ;
2009-04-13 17:11:50 +02:00
unsigned short PanelManager : : panelID = 0 ;
2009-04-04 17:57:06 +02:00
PanelManager : : PanelManager ( WorkspaceWindow & workspace_window ) :
workspaceWindow ( workspace_window ) ,
2011-10-16 08:43:03 +02:00
dock ( ) ,
dockBar ( dock ) ,
dockLayout ( )
2009-04-04 17:57:06 +02:00
{
2011-10-17 04:28:55 +02:00
/* Create the DockLayout */
2011-10-16 08:43:03 +02:00
dockLayout = Gdl : : DockLayout : : create ( dock ) ;
2011-10-17 04:28:55 +02:00
/* Setup the Switcher Style */
Glib : : RefPtr < Gdl : : DockMaster > dock_master = dock . property_master ( ) ;
dock_master - > property_switcher_style ( ) = Gdl : : SWITCHER_STYLE_ICON ;
2009-04-04 17:57:06 +02:00
memset ( & dockPlaceholders , 0 , sizeof ( dockPlaceholders ) ) ;
}
PanelManager : : ~ PanelManager ( )
{
2014-10-14 04:17:56 +02:00
///////////////////////////////////////////////////////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-04 17:57:06 +02:00
2014-10-14 04:17:56 +02:00
# if false /////////////////////////////////////////////////TICKET #937 : disabled for GTK-3 transition. TODO investigate why this logic existed...
2009-04-04 17:57:06 +02:00
for ( int i = 0 ; i < 4 ; i + + )
if ( dockPlaceholders [ i ] )
g_object_unref ( dockPlaceholders [ i ] ) ;
2009-04-16 11:02:53 +02:00
clear_panels ( ) ;
2014-10-14 04:17:56 +02:00
# endif /////////////////////////////////////////////////TICKET #937 : (End)disabled for GTK-3 transition.
2009-04-04 17:57:06 +02:00
}
void
PanelManager : : setup_dock ( )
{
REQUIRE ( dockPlaceholders [ 0 ] = = NULL & & dockPlaceholders [ 1 ] = = NULL & &
dockPlaceholders [ 2 ] = = NULL & & dockPlaceholders [ 3 ] = = NULL ) ;
dockPlaceholders [ 0 ] = GDL_DOCK_PLACEHOLDER ( gdl_dock_placeholder_new (
2011-10-16 08:43:03 +02:00
" ph1 " , GDL_DOCK_OBJECT ( dock . gobj ( ) ) , GDL_DOCK_TOP , FALSE ) ) ;
2009-04-04 17:57:06 +02:00
dockPlaceholders [ 1 ] = GDL_DOCK_PLACEHOLDER ( gdl_dock_placeholder_new (
2011-10-16 08:43:03 +02:00
" ph2 " , GDL_DOCK_OBJECT ( dock . gobj ( ) ) , GDL_DOCK_BOTTOM , FALSE ) ) ;
2009-04-04 17:57:06 +02:00
dockPlaceholders [ 2 ] = GDL_DOCK_PLACEHOLDER ( gdl_dock_placeholder_new (
2011-10-16 08:43:03 +02:00
" ph3 " , GDL_DOCK_OBJECT ( dock . gobj ( ) ) , GDL_DOCK_LEFT , FALSE ) ) ;
2009-04-04 17:57:06 +02:00
dockPlaceholders [ 3 ] = GDL_DOCK_PLACEHOLDER ( gdl_dock_placeholder_new (
2011-10-16 08:43:03 +02:00
" ph4 " , GDL_DOCK_OBJECT ( dock . gobj ( ) ) , GDL_DOCK_RIGHT , FALSE ) ) ;
2009-04-04 17:57:06 +02:00
ENSURE ( dockPlaceholders [ 0 ] & & dockPlaceholders [ 1 ] & &
dockPlaceholders [ 2 ] & & dockPlaceholders [ 3 ] ) ;
create_panels ( ) ;
}
2011-10-16 16:43:59 +02:00
Gdl : : Dock &
2011-10-16 08:43:03 +02:00
PanelManager : : get_dock ( )
2009-04-04 17:57:06 +02:00
{
2011-10-16 16:43:59 +02:00
return dock ;
2009-04-04 17:57:06 +02:00
}
2011-10-16 16:43:59 +02:00
Gdl : : DockBar &
2011-10-16 08:43:03 +02:00
PanelManager : : get_dock_bar ( )
2009-04-04 17:57:06 +02:00
{
2011-10-16 16:43:59 +02:00
return dockBar ;
2009-04-04 17:57:06 +02:00
}
2009-04-13 17:11:50 +02:00
WorkspaceWindow &
PanelManager : : get_workspace_window ( )
{
return workspaceWindow ;
}
2009-04-15 19:14:16 +02:00
void
PanelManager : : show_panel ( const int description_index )
{
2009-04-15 19:27:07 +02:00
// Try and find the panel and present it if possible
2009-04-16 11:02:53 +02:00
list < panels : : Panel * > : : iterator i ;
2009-04-15 19:27:07 +02:00
for ( i = panels . begin ( ) ; i ! = panels . end ( ) ; i + + )
{
2009-04-16 11:02:53 +02:00
panels : : Panel * const panel = * i ;
if ( get_panel_type ( panel ) = = description_index )
2009-04-15 19:27:07 +02:00
{
2009-04-16 11:08:35 +02:00
if ( ! panel - > is_shown ( ) )
panel - > show ( ) ;
2009-04-15 21:12:06 +02:00
2011-10-16 16:43:59 +02:00
Gdl : : DockItem & dock_item = panel - > get_dock_item ( ) ;
// ENSURE(dock_item);
dock_item . present ( dock ) ;
2009-04-15 19:27:07 +02:00
return ;
}
}
2009-04-15 19:14:16 +02:00
// Create the new panel
2009-04-16 11:02:53 +02:00
panels : : Panel * new_panel = create_panel_by_index ( description_index ) ;
2009-04-15 19:14:16 +02:00
// Dock the item
2011-10-16 16:43:59 +02:00
dock . add_item ( new_panel - > get_dock_item ( ) , Gdl : : DOCK_FLOATING ) ;
2009-04-15 19:14:16 +02:00
}
2009-04-05 00:01:50 +02:00
void PanelManager : : switch_panel ( panels : : Panel & old_panel ,
2009-04-15 19:05:45 +02:00
const int description_index )
2009-04-05 00:01:50 +02:00
{
2009-04-15 19:05:45 +02:00
REQUIRE ( description_index > = 0 & &
description_index < get_panel_description_count ( ) ) ;
2009-04-05 00:01:50 +02:00
2009-04-13 17:11:50 +02:00
// Get the dock item
2011-10-16 16:43:59 +02:00
Gdl : : DockItem & dock_item = old_panel . get_dock_item ( ) ;
2009-04-16 11:02:53 +02:00
2009-04-13 17:11:50 +02:00
// Release the old panel
2009-04-16 11:02:53 +02:00
remove_panel ( & old_panel ) ;
2009-04-13 17:11:50 +02:00
// Create the new panel
2009-04-16 11:02:53 +02:00
create_panel_by_index ( description_index , dock_item ) ;
2009-04-05 00:01:50 +02:00
}
2009-04-15 13:24:34 +02:00
void
PanelManager : : split_panel ( panels : : Panel & panel ,
Gtk : : Orientation split_direction )
{
2011-10-17 04:28:55 +02:00
2009-04-15 13:24:34 +02:00
// Create the new panel
const int index = get_panel_type ( & panel ) ;
2009-04-16 11:02:53 +02:00
panels : : Panel * new_panel = create_panel_by_index ( index ) ;
2009-04-15 13:24:34 +02:00
// Dock the panel
2011-10-17 04:28:55 +02:00
Gdl : : DockPlacement placement = Gdl : : DOCK_NONE ;
2009-04-15 13:24:34 +02:00
switch ( split_direction )
{
case ORIENTATION_HORIZONTAL :
2011-10-17 04:28:55 +02:00
placement = Gdl : : DOCK_RIGHT ;
2009-04-15 13:24:34 +02:00
break ;
case ORIENTATION_VERTICAL :
2011-10-17 04:28:55 +02:00
placement = Gdl : : DOCK_BOTTOM ;
2009-04-15 13:24:34 +02:00
break ;
default :
2011-10-17 04:28:55 +02:00
ERROR ( gui , " Unrecognisized split_direction: %d " ,
split_direction ) ;
2009-04-15 13:24:34 +02:00
return ;
break ;
}
2011-10-16 16:43:59 +02:00
2011-10-17 04:28:55 +02:00
panel . get_dock_item ( ) . dock (
new_panel - > get_dock_item ( ) , placement ) ;
2009-04-15 13:24:34 +02:00
}
2009-04-04 19:53:09 +02:00
int
PanelManager : : get_panel_description_count ( )
{
return sizeof ( panelDescriptionList ) / sizeof ( PanelDescription ) ;
}
const gchar *
PanelManager : : get_panel_stock_id ( int index )
{
REQUIRE ( index > = 0 & & index < get_panel_description_count ( ) ) ;
return panelDescriptionList [ index ] . get_stock_id ( ) ;
}
2009-04-15 19:14:16 +02:00
const char *
PanelManager : : get_panel_title ( int index )
{
REQUIRE ( index > = 0 & & index < get_panel_description_count ( ) ) ;
return panelDescriptionList [ index ] . get_title ( ) ;
}
2009-04-04 17:57:06 +02:00
void
PanelManager : : create_panels ( )
{
2010-12-06 14:18:53 +01:00
panels : : Panel * assetsPanel =
create_panel_by_name ( " AssetsPanel " ) ;
2009-04-16 11:02:53 +02:00
panels : : Panel * viewerPanel =
create_panel_by_name ( " ViewerPanel " ) ;
panels : : Panel * timelinePanel =
create_panel_by_name ( " TimelinePanel " ) ;
2011-10-16 16:43:59 +02:00
dock . add_item ( assetsPanel - > get_dock_item ( ) , Gdl : : DOCK_LEFT ) ;
dock . add_item ( timelinePanel - > get_dock_item ( ) , Gdl : : DOCK_BOTTOM ) ;
dock . add_item ( viewerPanel - > get_dock_item ( ) , Gdl : : DOCK_RIGHT ) ;
2009-04-04 17:57:06 +02:00
}
2009-04-15 13:24:34 +02:00
int
PanelManager : : find_panel_description ( const char * class_name ) const
{
REQUIRE ( class_name ) ;
const int count = get_panel_description_count ( ) ;
for ( int i = 0 ; i < count ; i + + )
{
if ( strstr ( panelDescriptionList [ i ] . get_class_name ( ) , class_name ) )
return i ;
}
ERROR ( gui , " Unable to find a description with class name %s " ,
class_name ) ;
return - 1 ;
}
2009-04-16 11:02:53 +02:00
panels : : Panel *
2009-04-15 13:24:34 +02:00
PanelManager : : create_panel_by_index ( const int index )
{
REQUIRE ( index > = 0 & & index < get_panel_description_count ( ) ) ;
// Make a unique name for the panel
char name [ 5 ] ;
snprintf ( name , sizeof ( name ) , " %X " , panelID + + ) ;
// Create a dock item
2011-10-16 16:43:59 +02:00
return create_panel_by_index ( index , * new Gdl : : DockItem ( name , " " , Gdl : : DOCK_ITEM_BEH_NORMAL ) ) ;
2009-04-16 11:02:53 +02:00
}
2009-04-15 13:24:34 +02:00
2009-04-16 11:02:53 +02:00
panels : : Panel *
PanelManager : : create_panel_by_index (
2011-10-16 16:43:59 +02:00
const int index , Gdl : : DockItem & dock_item )
2009-04-16 11:02:53 +02:00
{
2009-04-15 13:24:34 +02:00
// Create the panel object
2009-04-16 11:02:53 +02:00
panels : : Panel * panel =
panelDescriptionList [ index ] . create ( * this , dock_item ) ;
2009-04-15 13:24:34 +02:00
ENSURE ( panel ) ;
panel - > show_all ( ) ;
2009-04-15 21:12:06 +02:00
// Connect event handlers
2011-10-17 05:07:26 +02:00
panel - > signal_hide_panel ( ) . connect ( sigc : : bind (
sigc : : mem_fun ( * this , & PanelManager : : on_panel_shown ) , panel ) ) ;
2009-04-15 21:12:06 +02:00
// Add the panel to the list
panels . push_back ( panel ) ;
2009-04-15 13:24:34 +02:00
return panel ;
}
2009-04-16 11:02:53 +02:00
panels : : Panel *
2009-04-04 17:57:06 +02:00
PanelManager : : create_panel_by_name ( const char * class_name )
2009-04-13 17:11:50 +02:00
{
2009-04-15 13:24:34 +02:00
REQUIRE ( class_name ) ;
const int index = find_panel_description ( class_name ) ;
return create_panel_by_index ( index ) ;
}
int
2009-04-16 11:02:53 +02:00
PanelManager : : get_panel_type ( panels : : Panel * const panel ) const
2009-04-15 13:24:34 +02:00
{
REQUIRE ( panel ) ;
const type_info & info = typeid ( * panel ) ;
2009-04-04 19:53:09 +02:00
const int count = get_panel_description_count ( ) ;
for ( int i = 0 ; i < count ; i + + )
2009-04-04 17:57:06 +02:00
{
2009-04-15 13:24:34 +02:00
if ( info = = panelDescriptionList [ i ] . get_class_info ( ) )
return i ;
2009-04-04 17:57:06 +02:00
}
2009-04-15 13:24:34 +02:00
ERROR ( gui , " Unable to find a description with with this class type " ) ;
return - 1 ;
2009-04-04 17:57:06 +02:00
}
2009-04-15 21:12:06 +02:00
void
2009-04-16 11:02:53 +02:00
PanelManager : : remove_panel ( panels : : Panel * const panel )
{
2009-04-15 21:12:06 +02:00
REQUIRE ( panel ) ;
2009-04-16 11:02:53 +02:00
list < panels : : Panel * > : : iterator i ;
2009-04-15 21:12:06 +02:00
for ( i = panels . begin ( ) ; i ! = panels . end ( ) ; i + + )
{
2009-04-16 11:02:53 +02:00
if ( * i = = panel )
2009-04-15 21:12:06 +02:00
{
2009-04-16 11:02:53 +02:00
delete panel ;
2009-04-15 21:12:06 +02:00
panels . erase ( i ) ;
break ;
}
}
}
2009-04-16 11:02:53 +02:00
void
PanelManager : : clear_panels ( )
{
2014-10-14 04:17:56 +02:00
///////////////////////////////////////////////////////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
2009-04-16 11:02:53 +02:00
list < panels : : Panel * > : : iterator i ;
for ( i = panels . begin ( ) ; i ! = panels . end ( ) ; i + + )
delete * i ;
panels . clear ( ) ;
}
void
PanelManager : : on_panel_shown ( panels : : Panel * panel )
{
REQUIRE ( panel ) ;
if ( panel - > is_shown ( ) | | panel - > is_iconified ( ) )
return ;
remove_panel ( panel ) ;
}
2009-04-04 17:57:06 +02:00
} // namespace workspace
} // namespace gui