Added panel splitting

This commit is contained in:
Joel Holdsworth 2009-04-15 12:24:34 +01:00
parent 592d94fadb
commit a4fbcfec49
4 changed files with 160 additions and 32 deletions

View file

@ -81,6 +81,13 @@ PanelBar::setup_panel_button()
lockItem = dynamic_cast<CheckMenuItem*>(&list.back());
ENSURE(lockItem);
lockItem->set_active(panel.is_locked());
list.push_back( Menu_Helpers::MenuElem(_("Split _Horizontal"),
bind(mem_fun(*this, &PanelBar::on_split_panel),
ORIENTATION_HORIZONTAL) ) );
list.push_back( Menu_Helpers::MenuElem(_("Split _Vertical"),
bind(mem_fun(*this, &PanelBar::on_split_panel),
ORIENTATION_VERTICAL) ) );
}
void
@ -166,5 +173,11 @@ PanelBar::on_lock()
}
}
void
PanelBar::on_split_panel(Gtk::Orientation split_direction)
{
panel.get_panel_manager().split_panel(panel, split_direction);
}
} // widgets
} // gui

View file

@ -89,6 +89,12 @@ private:
* Event handler for when the "Lock" menu item is clicked
**/
void on_lock();
/**
* Event handler for when the split panel menu item is clicked
* @param split_direction The direction to split in.
**/
void on_split_panel(Gtk::Orientation split_direction);
private:

View file

@ -30,6 +30,7 @@
using namespace boost;
using namespace std;
using namespace Gtk;
namespace gui {
namespace workspace {
@ -146,11 +147,40 @@ void PanelManager::switch_panel(panels::Panel &old_panel,
*this, dock_item));
g_object_unref(dock_item);
new_panel->show_all();
panels.push_back(new_panel);
}
void
PanelManager::split_panel(panels::Panel &panel,
Gtk::Orientation split_direction)
{
// Create the new panel
const int index = get_panel_type(&panel);
shared_ptr<panels::Panel> new_panel = create_panel_by_index(index);
// Add it to the list
panels.push_back(new_panel);
// Dock the panel
GdlDockPlacement 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, "Unrecognisized split_direction: %d", split_direction);
return;
break;
}
gdl_dock_object_dock(GDL_DOCK_OBJECT(panel.get_dock_item()),
GDL_DOCK_OBJECT(new_panel->get_dock_item()), placement, NULL);
}
int
PanelManager::get_panel_description_count()
{
@ -186,30 +216,68 @@ PanelManager::create_panels()
panels.push_back(resourcesPanel);
}
shared_ptr<panels::Panel>
PanelManager::create_panel_by_name(const char* class_name)
{
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))
{
// Make a unique name for the panel
char name[5];
snprintf(name, sizeof(name), "%X", panelID++);
// Create a dock item
GdlDockItem *dock_item = GDL_DOCK_ITEM(
gdl_dock_item_new(name, "", GDL_DOCK_ITEM_BEH_NORMAL));
// Create the panel object
return shared_ptr<panels::Panel>(
panelDescriptionList[i].create(*this, dock_item));
}
return i;
}
ERROR(gui, "Unable to create a panel with class name %s", class_name);
return shared_ptr<panels::Panel>();
ERROR(gui, "Unable to find a description with class name %s",
class_name);
return -1;
}
shared_ptr<panels::Panel>
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
GdlDockItem *dock_item = GDL_DOCK_ITEM(
gdl_dock_item_new(name, "", GDL_DOCK_ITEM_BEH_NORMAL));
// Create the panel object
shared_ptr<panels::Panel> panel(
panelDescriptionList[index].create(*this, dock_item));
ENSURE(panel);
panel->show_all();
return panel;
}
shared_ptr<panels::Panel>
PanelManager::create_panel_by_name(const char* class_name)
{
REQUIRE(class_name);
const int index = find_panel_description(class_name);
return create_panel_by_index(index);
}
int
PanelManager::get_panel_type(panels::Panel *panel) const
{
REQUIRE(panel);
const type_info &info = typeid(*panel);
const int count = get_panel_description_count();
for(int i = 0; i < count; i++)
{
if(info == panelDescriptionList[i].get_class_info())
return i;
}
ERROR(gui, "Unable to find a description with with this class type");
return -1;
}
} // namespace workspace

View file

@ -29,6 +29,7 @@
#define PANEL_MANAGER_HPP
#include <libgdl-1.0/gdl/gdl.h>
#include <typeinfo>
#include "../panels/panel.hpp"
@ -90,6 +91,14 @@ public:
**/
void switch_panel(panels::Panel &old_panel,
int new_panel_description_index);
/**
* Splits a panel into two panels of the same type.
* @param panel The panel to split.
* @param split_direction The direction to split the panel in.
**/
void split_panel(panels::Panel &panel,
Gtk::Orientation split_direction);
public:
@ -111,14 +120,39 @@ private:
* Creates the standard panel layout.
**/
void create_panels();
/**
* Find the index of a panel description given the class name.
* @param class_name The name of the object class to search for.
* @return Returns the index of the panel description found, or -1
* if no description was found for this type.
**/
int find_panel_description(const char* class_name) const;
/**
* Creates a panel by description index.
* @param index The index of the description to instantiate.
* @return Returns a pointer to the new instantiated panel object.
**/
boost::shared_ptr<panels::Panel> create_panel_by_index(
const int index);
/**
* Creates a panel by class name.
* @param class_name The name of the object class to create.
* @return Returns a pointer to the new instantiated panel object.
**/
boost::shared_ptr<panels::Panel> create_panel_by_name(
const char* class_name);
/**
* Gets the type of a given panel.
* @param panel The Panel to get the type of
* @return Returns the index of the panel description found, or -1
* if no description was found for this type.
**/
int get_panel_type(panels::Panel *panel) const;
private:
/**
@ -175,32 +209,39 @@ private:
protected:
/**
* Constructor
* @param class_name The name of the Panel class
* @param classInfo The typeid of the Panel class
* @param title The localized title that will be shown on the
* panel.
* @param stock_id The Stock ID for this type of panel.
* @param create_panel_proc A pointer to a function that will
* instantiate the panel object.
**/
PanelDescription(const char* class_name, const char *title,
const gchar *stock_id, CreatePanelProc create_panel_proc) :
className(class_name),
PanelDescription(const std::type_info &class_info,
const char *title, const gchar *stock_id,
CreatePanelProc create_panel_proc) :
classInfo(class_info),
titleName(title),
stockID(stock_id),
createPanelProc(create_panel_proc)
{
REQUIRE(className);
REQUIRE(titleName);
}
public:
/**
* Returns a pointer to the string name of class.
* Returns a reference to the typeid of the class.
**/
const std::type_info& get_class_info() const
{
return classInfo;
}
/**
* Returns a pointer to the string name of the class.
**/
const char* get_class_name() const
{
ENSURE(className);
return className;
return classInfo.name();
}
/**
@ -236,9 +277,9 @@ private:
private:
/**
* A pointer to the string name of class.
**/
const char* const className;
* A reference to the typeid of this class
**/
const std::type_info &classInfo;
/**
* The localized title that will be shown on the panel.
@ -268,7 +309,7 @@ private:
* Constructor
**/
Panel() :
PanelDescription(typeid(P).name(), P::get_title(),
PanelDescription(typeid(P), P::get_title(),
P::get_stock_id(), Panel::create_panel)
{}