//
// gui.cc
//
#include "wx/bitmap.h"
#include "wx/frame.h"
#include "wx/gauge.h"
#include "wx/icon.h"
#include "wx/menu.h"
#include "wx/msgdlg.h"
#include "wx/statusbr.h"
#include "wx/string.h"
#include "wx/toolbar.h"
#include <math.h>
#include "canvas.h"
#include "config.h"
#include "edge.h"
#include "factory.h"
#include "graph.h"
#include "gui.h"
#include "lang.h"
#include "undo.h"
#include "vertex.h"
// Toolbar pixmaps
#include "edge_mode.xpm"
#include "vertex_mode.xpm"
#include "logo.xpm"
BEGIN_EVENT_TABLE(GTFrame, wxFrame)
EVT_SIZE (GTFrame::OnSize)
EVT_MENU (ID_FILE_LOAD, GTFrame::cb_File_Load)
EVT_MENU (ID_FILE_SAVE, GTFrame::cb_File_Save)
EVT_MENU (ID_FILE_EXIT, GTFrame::cb_File_Exit)
EVT_MENU (ID_EDIT_UNDO, GTFrame::cb_Edit_Undo)
EVT_MENU (ID_EDIT_SELECTALL, GTFrame::cb_Edit_SelectAll)
EVT_MENU (ID_EDIT_SELECTNONE, GTFrame::cb_Edit_SelectNone)
EVT_MENU (ID_EDIT_INVERTSELV, GTFrame::cb_Edit_InvertSelectionVertices)
EVT_MENU (ID_EDIT_INVERTSELE, GTFrame::cb_Edit_InvertSelectionEdges)
EVT_MENU (ID_EDIT_INVERTSELA, GTFrame::cb_Edit_InvertSelectionAll)
EVT_MENU (ID_VIEW_LABELS, GTFrame::cb_View)
EVT_MENU (ID_VIEW_WEIGHTS, GTFrame::cb_View)
EVT_MENU (ID_VIEW_FLOWS, GTFrame::cb_View)
EVT_MENU (ID_GRAPH_CLEAR, GTFrame::cb_Graph_Clear)
EVT_MENU (ID_GRAPH_COMPLEMENT, GTFrame::cb_Graph_Complement)
EVT_MENU (ID_GRAPH_LINEGRAPH, GTFrame::cb_Graph_LineGraph)
EVT_MENU (ID_GRAPH_SUBGRAPH, GTFrame::cb_Graph_Subgraph)
EVT_MENU (ID_GRAPH_FIND_SHORTESTPATH, GTFrame::cb_Graph_Find_ShortestPath)
EVT_MENU (ID_GRAPH_FIND_BFS, GTFrame::cb_Graph_Find_BFS)
EVT_MENU (ID_GRAPH_FIND_DFS, GTFrame::cb_Graph_Find_DFS)
EVT_MENU (ID_GRAPH_FIND_MST, GTFrame::cb_Graph_Find_MST)
EVT_MENU (ID_GRAPH_FIND_MAXFLOW, GTFrame::cb_Graph_Find_MaxFlow)
EVT_MENU (ID_GRAPH_PROPERTIES_CONNECTIVITY, GTFrame::cb_Graph_Properties_Connectivity)
EVT_MENU (ID_GRAPH_PROPERTIES_EULERICITY, GTFrame::cb_Graph_Properties_Eulericity)
EVT_MENU (ID_GRAPH_PROPERTIES_HAMILTONICITY, GTFrame::OnMenu)
EVT_MENU (ID_GRAPH_PROPERTIES_PLANARITY, GTFrame::OnMenu)
EVT_MENU (ID_GRAPH_STATISTICS_ADJMATRIX, GTFrame::cb_Graph_Statistics_AdjacencyMatrix)
EVT_MENU (ID_GRAPH_STATISTICS_DEGSEQ, GTFrame::cb_Graph_Statistics_DegreeSequence)
EVT_MENU (ID_GRAPH_STATISTICS_DIAMETER, GTFrame::cb_Graph_Statistics_Diameter)
EVT_MENU (ID_GRAPH_STATISTICS_GIRTH, GTFrame::OnMenu)
EVT_MENU (ID_GRAPH_STATISTICS_RADIUS, GTFrame::cb_Graph_Statistics_Radius)
EVT_MENU (ID_GRAPH_STATISTICS_CHROMNUM, GTFrame::cb_Graph_Statistics_ChromaticNumber)
EVT_MENU (ID_GRAPH_STATISTICS_CHROMINDEX, GTFrame::cb_Graph_Statistics_ChromaticIndex)
EVT_MENU (ID_GRAPH_STATISTICS_CHROMPOLY, GTFrame::cb_Graph_Statistics_ChromaticPolynomial)
EVT_MENU (ID_PREFAB_COMPLETE, GTFrame::cb_Prefab_Complete)
EVT_MENU (ID_PREFAB_COMPLETEBIPARTITE, GTFrame::cb_Prefab_CompleteBipartite)
EVT_MENU (ID_PREFAB_CYCLE, GTFrame::cb_Prefab_Cycle)
EVT_MENU (ID_PREFAB_GEAR, GTFrame::cb_Prefab_Gear)
EVT_MENU (ID_PREFAB_HANOI, GTFrame::cb_Prefab_Hanoi)
EVT_MENU (ID_PREFAB_LADDER, GTFrame::cb_Prefab_Ladder)
EVT_MENU (ID_PREFAB_LATTICE, GTFrame::cb_Prefab_Lattice)
EVT_MENU (ID_PREFAB_NULL, GTFrame::cb_Prefab_Null)
EVT_MENU (ID_PREFAB_STAR, GTFrame::cb_Prefab_Star)
EVT_MENU (ID_PREFAB_TREE, GTFrame::OnMenu)
EVT_MENU (ID_PREFAB_WHEEL, GTFrame::cb_Prefab_Wheel)
EVT_MENU (ID_PREFAB_PETERSEN, GTFrame::cb_Prefab_Petersen)
EVT_MENU (ID_PREFAB_PLATONIC_TETRAHEDRAL, GTFrame::cb_Prefab_Platonic_Tetrahedral)
EVT_MENU (ID_PREFAB_PLATONIC_CUBICAL, GTFrame::cb_Prefab_Platonic_Cubical)
EVT_MENU (ID_PREFAB_PLATONIC_OCTAHEDRAL, GTFrame::cb_Prefab_Platonic_Octahedral)
EVT_MENU (ID_PREFAB_PLATONIC_DODECAHEDRAL, GTFrame::cb_Prefab_Platonic_Dodecahedral)
EVT_MENU (ID_PREFAB_PLATONIC_ICOSAHEDRAL, GTFrame::cb_Prefab_Platonic_Icosahedral)
EVT_MENU (ID_HELP_ABOUT, GTFrame::cb_Help_About)
EVT_TOOL (ID_TOOL_VERTEXMODE, GTFrame::cb_Change_Mode)
EVT_TOOL (ID_TOOL_EDGEMODE, GTFrame::cb_Change_Mode)
END_EVENT_TABLE()
wxMenuBar *GTFrame::genMenuBar ()
{
// File Menu
wxMenu *menu_file = new wxMenu ();
menu_file->Append (ID_FILE_LOAD, _("&Load\tCtrl-O"));
menu_file->Append (ID_FILE_SAVE, _("&Save\tCtrl-S"));
menu_file->AppendSeparator ();
menu_file->Append (ID_FILE_EXIT, _("E&xit\tCtrl-Q"));
// Edit Menu
wxMenu *menu_edit = new wxMenu ();
menu_edit->Append (ID_EDIT_UNDO, _("&Undo\tCtrl-Z"));
menu_edit->FindItem (ID_EDIT_UNDO)->Enable (false);
menu_edit->AppendSeparator ();
menu_edit->Append (ID_EDIT_SELECTALL, _("Select &All\tCtrl-A"));
menu_edit->Append (ID_EDIT_SELECTNONE, _("Select &None"));
menu_edit->Append (ID_EDIT_INVERTSELV, _("Invert Selection (&Vertices)"));
menu_edit->Append (ID_EDIT_INVERTSELE, _("Invert Selection (&Edges)"));
menu_edit->Append (ID_EDIT_INVERTSELA, _("&Invert Selection (All)"));
// View Menu
wxMenu *menu_view = new wxMenu ();
menu_view->AppendCheckItem (ID_VIEW_LABELS, _("&Labels"));
menu_view->AppendSeparator ();
menu_view->AppendCheckItem (ID_VIEW_WEIGHTS, _("&Weights"));
menu_view->AppendCheckItem (ID_VIEW_FLOWS, _("&Flows"));
// Graph Menu
wxMenu *menu_graph = new wxMenu ();
menu_graph->Append (ID_GRAPH_CLEAR, _("&Clear\tCtrl-W"));
menu_graph->Append (ID_GRAPH_COMPLEMENT, _("C&omplement"));
menu_graph->Append (ID_GRAPH_LINEGRAPH, _("&Line Graph"));
menu_graph->Append (ID_GRAPH_SUBGRAPH, _("S&ubgraph"));
menu_graph->AppendSeparator ();
// Graph/Find submenu
wxMenu *menu_graph_find = new wxMenu ();
menu_graph_find->Append (ID_GRAPH_FIND_SHORTESTPATH,
_("&Shortest Path"));
menu_graph_find->Append (ID_GRAPH_FIND_BFS,
_("&Breadth-First Search"));
menu_graph_find->Append (ID_GRAPH_FIND_DFS,
_("&Depth-First Search"));
menu_graph_find->Append (ID_GRAPH_FIND_MST,
_("&Minimum Spanning Tree"));
menu_graph_find->Append (ID_GRAPH_FIND_MAXFLOW,
_("Maximum &Flow"));
menu_graph->Append (ID_GRAPH_FIND, _("&Find"), menu_graph_find);
// Graph/Properties submenu
wxMenu *menu_graph_prop = new wxMenu ();
menu_graph_prop->Append (ID_GRAPH_PROPERTIES_CONNECTIVITY,
_("&Connectivity"));
menu_graph_prop->Append (ID_GRAPH_PROPERTIES_EULERICITY,
_("&Eulericity"));
menu_graph_prop->Append (ID_GRAPH_PROPERTIES_HAMILTONICITY,
_("&Hamiltonicity"));
menu_graph_prop->FindItem (ID_GRAPH_PROPERTIES_HAMILTONICITY)->Enable (false);
menu_graph_prop->Append (ID_GRAPH_PROPERTIES_PLANARITY,
_("&Planarity"));
menu_graph_prop->FindItem (ID_GRAPH_PROPERTIES_PLANARITY)->Enable (false);
menu_graph->Append (ID_GRAPH_PROPERTIES, _("&Properties"), menu_graph_prop);
// Graph/Statistics submenu
wxMenu *menu_graph_stat = new wxMenu ();
menu_graph_stat->Append (ID_GRAPH_STATISTICS_ADJMATRIX,
_("&Adjacency Matrix"));
menu_graph_stat->Append (ID_GRAPH_STATISTICS_DEGSEQ,
_("&Degree Sequence"));
menu_graph_stat->Append (ID_GRAPH_STATISTICS_DIAMETER,
_("D&iameter"));
menu_graph_stat->Append (ID_GRAPH_STATISTICS_GIRTH,
_("&Girth"));
menu_graph_stat->FindItem (ID_GRAPH_STATISTICS_GIRTH)->Enable (false);
menu_graph_stat->Append (ID_GRAPH_STATISTICS_RADIUS,
_("&Radius"));
menu_graph_stat->AppendSeparator ();
menu_graph_stat->Append (ID_GRAPH_STATISTICS_CHROMNUM,
_("&Chromatic Number"));
menu_graph_stat->Append (ID_GRAPH_STATISTICS_CHROMINDEX,
_("C&hromatic Index"));
menu_graph_stat->Append (ID_GRAPH_STATISTICS_CHROMPOLY,
_("Chromatic &Polynomial"));
menu_graph->Append (ID_GRAPH_STATISTICS, _("&Statistics"), menu_graph_stat);
// Prefab Menu
wxMenu *menu_prefab = new wxMenu ();
menu_prefab->Append (ID_PREFAB_COMPLETE, _("Complete (&Kn)"));
menu_prefab->Append (ID_PREFAB_COMPLETEBIPARTITE,
_("Complete &Bipartite (Kn,m)"));
menu_prefab->Append (ID_PREFAB_CYCLE, _("Cycle (&Cn)"));
menu_prefab->Append (ID_PREFAB_GEAR, _("Gear (&Gn)"));
menu_prefab->Append (ID_PREFAB_HANOI, _("Hanoi (&Hn)"));
menu_prefab->Append (ID_PREFAB_LADDER, _("Ladder (&Ln)"));
menu_prefab->Append (ID_PREFAB_LATTICE, _("Lattice (Ln,m)"));
menu_prefab->Append (ID_PREFAB_NULL, _("Null (&Nn)"));
menu_prefab->Append (ID_PREFAB_STAR, _("Star (&Sn)"));
menu_prefab->Append (ID_PREFAB_TREE, _("Tree (&Tn)"));
menu_prefab->FindItem (ID_PREFAB_TREE)->Enable (false);
menu_prefab->Append (ID_PREFAB_WHEEL, _("Wheel (&Wn)"));
menu_prefab->AppendSeparator ();
menu_prefab->Append (ID_PREFAB_PETERSEN, _("Petersen"));
// Prefab/Platonic submenu
wxMenu *menu_prefab_platonic = new wxMenu ();
menu_prefab_platonic->Append (ID_PREFAB_PLATONIC_TETRAHEDRAL,
_("&Tetrahedral"));
menu_prefab_platonic->Append (ID_PREFAB_PLATONIC_CUBICAL,
_("&Cubical"));
menu_prefab_platonic->Append (ID_PREFAB_PLATONIC_OCTAHEDRAL,
_("&Octahedral"));
menu_prefab_platonic->Append (ID_PREFAB_PLATONIC_DODECAHEDRAL,
_("&Dodecahedral"));
menu_prefab_platonic->Append (ID_PREFAB_PLATONIC_ICOSAHEDRAL,
_("&Icosahedral"));
menu_prefab->Append (ID_PREFAB_PLATONIC, _("&Platonic"), menu_prefab_platonic);
// Help Menu
wxMenu *menu_help = new wxMenu ();
menu_help->Append (ID_HELP_ABOUT, _("&About\tF1"));
// Menubar
wxMenuBar *mb = new wxMenuBar ();
mb->Append (menu_file, _("&File"));
mb->Append (menu_edit, _("&Edit"));
mb->Append (menu_view, _("&View"));
mb->Append (menu_graph, _("&Graph"));
mb->Append (menu_prefab, _("&Prefab"));
mb->Append (menu_help, _("&Help"));
// TODO: right-align help menu
return mb;
}
void GTFrame::OnMenu (wxCommandEvent &event)
{
// TODO
wxMessageDialog dlg (this, wxT("This isn't implemented yet!"), wxT("NYI."),
wxOK | wxICON_ERROR);
dlg.ShowModal ();
}
#include "wx/settings.h"
void GTFrame::OnSize (wxSizeEvent &event)
{
wxRect rect;
// Fix up progress bar
if (!statusBar)
return;
statusBar->GetFieldRect (2, rect);
progressBar->SetSize (rect.x + 2, rect.y + 2, rect.width - 4, rect.height - 4);
wxSize sz = progressBar->GetSize ();
progressBar->Move (rect.x + (rect.width - sz.x) / 2,
rect.y + (rect.height - sz.y) / 2);
// Fix up canvas
sz = GetClientSize ();
int nudge_horiz = wxSystemSettings::GetMetric (wxSYS_VSCROLL_X);
int nudge_vert = wxSystemSettings::GetMetric (wxSYS_HSCROLL_Y);
sz.SetWidth (sz.GetWidth () - nudge_horiz);
sz.SetHeight (sz.GetHeight () - nudge_vert);
canvas->SetClientSize (sz.GetWidth (), sz.GetHeight ());
Factory::width = sz.GetWidth ();
Factory::height = sz.GetHeight ();
}
void GTFrame::setUndoText (wxString description)
{
wxString s_txt (_("&Undo"));
if (description != wxT(""))
s_txt += wxT(" (") + description + wxT(")");
s_txt += wxT("\tCtrl-Z");
edit_Undo->SetText (s_txt);
}
GTFrame::GTFrame ()
: wxFrame ((wxFrame *) NULL, -1, wxT("GraphThing " GT_VERSION),
wxDefaultPosition, wxSize (600, 500)), statusBar (0)
{
SetIcon (wxIcon (logo_xpm));
graph = new Graph ();
SetMenuBar (genMenuBar ());
edit_Undo = GetMenuBar ()->FindItem (ID_EDIT_UNDO);
view_Labels = GetMenuBar ()->FindItem (ID_VIEW_LABELS);
view_Weights = GetMenuBar ()->FindItem (ID_VIEW_WEIGHTS);
view_Flows = GetMenuBar ()->FindItem (ID_VIEW_FLOWS);
view_Labels->Check ();
wxToolBar *tb = CreateToolBar (wxTB_HORIZONTAL | wxTB_TEXT);
statusBar = CreateStatusBar (3);
int widths[] = { 0, -1, -1 };
statusBar->SetStatusWidths (3, widths);
progressBar = new wxGauge (statusBar, -1, 100);
progressBar->SetValue (0);
wxBitmap *vPix = new wxBitmap (vertex_mode_xpm);
wxBitmap *ePix = new wxBitmap (edge_mode_xpm);
tb->AddRadioTool (ID_TOOL_VERTEXMODE, _("Vertex Mode"), *vPix, *vPix,
_("Change to Vertex Mode"));
tb->AddRadioTool (ID_TOOL_EDGEMODE, _("Edge Mode"), *ePix, *ePix,
_("Change to Edge Mode"));
tb->Realize ();
canvas = new Canvas (this, &graph);
pushStatus (_("Ready."));
wxCommandEvent ev (0, ID_TOOL_VERTEXMODE);
cb_Change_Mode (ev);
cb_View (ev);
}
GTFrame::~GTFrame ()
{
delete graph;
}
void GTFrame::undoableAction (wxString description)
{
UndoStep step (new Graph (*graph), description);
undoStack.push (step);
edit_Undo->Enable ();
setUndoText (description);
}
void GTFrame::loadGraph (const wxString fname)
{
bool res;
Graph *g = graph->load (fname, res);
if (g) {
// TODO: Make this undoable?
delete graph;
graph = g;
}
canvas->redraw ();
}
void GTFrame::msg (const wxString &title, const wxString &s)
{
// TODO: pass through more flags
wxMessageDialog dlg (this, s, title, wxOK);
dlg.CentreOnParent ();
dlg.ShowModal ();
}
void GTFrame::msg (const wxString &title, const char *s)
{
msg (title, wxString (s, wxConvUTF8));
}
void GTFrame::toggleMode ()
{
// TODO: toggle the toolbar buttons!
}
void GTFrame::pushStatus (const wxString &str)
{
statusBar->PushStatusText (str, 1);
}
void GTFrame::popStatus ()
{
statusBar->PopStatusText (1);
}
void GTFrame::setProgress (double frac)
{
static double last_frac = -1.0;
// TODO: implement progress percentage text somehow
if (frac < 0.0) {
// hide progress bar
//progressBar->set_show_text (false);
progressBar->Hide ();
last_frac = frac - 1;
} else if (frac <= 1.0) {
progressBar->SetValue (int (frac * 100));
//progressBar->set_format_string ("%p%% complete");
//progressBar->set_show_text (true);
progressBar->Show ();
}
//progressBar->Refresh ();
//progressBar->Update ();
}
syntax highlighted by Code2HTML, v. 0.9.1