using namespace R2C2;
ClockDialog::ClockDialog(Engineer &engineer):
+ DynamicDialog(engineer.get_user_interface()),
clock(engineer.get_layout().get_clock())
{
Loader::WidgetMap widgets;
{
}
}
+
+bool ClockDialog::save_state(DataFile::Statement &st) const
+{
+ st.keyword = "clockdialog";
+ save_position(st.sub);
+
+ return true;
+}
#ifndef CLOCKDIALOG_H_
#define CLOCKDIALOG_H_
-#include <msp/gltk/dialog.h>
#include <msp/gltk/entry.h>
#include <msp/gltk/indicator.h>
#include "libr2c2/clock.h"
+#include "dynamicdialog.h"
class ClockWidget;
class Engineer;
-class ClockDialog: public Msp::GLtk::Dialog, public sigc::trackable
+class ClockDialog: public DynamicDialog, public sigc::trackable
{
private:
R2C2::Clock &clock;
void set_rate();
void stop_clicked();
void set_time();
+
+public:
+ virtual bool save_state(Msp::DataFile::Statement &) const;
};
#endif
#include "libr2c2/train.h"
#include "libr2c2/zone.h"
#include "departuresdialog.h"
+#include "engineer.h"
using namespace std;
using namespace Msp;
using namespace R2C2;
-DeparturesDialog::DeparturesDialog(const Layout &l, const string &group):
- layout(l),
+DeparturesDialog::DeparturesDialog(Engineer &engineer, const string &group):
+ DynamicDialog(engineer.get_user_interface()),
+ layout(engineer.get_layout()),
departures(0)
{
Loader::WidgetMap widgets;
}
}
+bool DeparturesDialog::save_state(DataFile::Statement &st) const
+{
+ st.keyword = "departuresdialog";
+ int sel = drp_groups->get_selected_index();
+ if(sel>=0)
+ st.sub.push_back((DataFile::Statement("group"), groups.get(sel)));
+ save_position(st.sub);
+
+ return true;
+}
+
DeparturesDialog::Row::Row():
departure(0),
lbl_train->set_text(string());
}
}
+
+
+DeparturesDialog::StateLoader::StateLoader(DeparturesDialog &dd):
+ DataFile::DerivedObjectLoader<DeparturesDialog, DynamicDialog::StateLoader>(dd)
+{
+ add("group", &StateLoader::group);
+}
+
+void DeparturesDialog::StateLoader::group(const string &g)
+{
+ obj.set_group(g);
+}
#ifndef DEPARTURESDIALOG_H_
#define DEPARTURESDIALOG_H_
-#include <msp/gltk/dialog.h>
#include <msp/gltk/dropdown.h>
#include <msp/gltk/label.h>
#include "libr2c2/departures.h"
+#include "dynamicdialog.h"
-class DeparturesDialog: public Msp::GLtk::Dialog
+class Engineer;
+
+class DeparturesDialog: public DynamicDialog
{
+public:
+ class StateLoader: public Msp::DataFile::DerivedObjectLoader<DeparturesDialog, DynamicDialog::StateLoader>
+ {
+ public:
+ StateLoader(DeparturesDialog &);
+
+ private:
+ void group(const std::string &);
+ };
+
private:
struct Row
{
std::vector<Row> rows;
public:
- DeparturesDialog(const R2C2::Layout &, const std::string & = std::string());
+ DeparturesDialog(Engineer &, const std::string & = std::string());
void set_group(const std::string &);
private:
void group_selected(unsigned);
void update_rows();
+
+public:
+ virtual bool save_state(Msp::DataFile::Statement &) const;
};
#endif
#include "dynamicdialog.h"
#include "userinterface.h"
+using namespace std;
+using namespace Msp;
+
DynamicDialog::DynamicDialog(UserInterface &u):
ui(u)
{
{
ui.remove_dynamic_dialog(*this);
}
+
+void DynamicDialog::save_position(list<DataFile::Statement> &st) const
+{
+ GLtk::Root *root = find_ancestor<GLtk::Root>();
+ if(root)
+ {
+ const GLtk::Geometry &rgeom = root->get_geometry();
+ float x = static_cast<float>(geom.x)/(rgeom.w-geom.w);
+ float y = static_cast<float>(geom.y)/(rgeom.h-geom.h);
+ st.push_back((DataFile::Statement("position"), x, y));
+ }
+}
+
+
+DynamicDialog::StateLoader::StateLoader(DynamicDialog &dd):
+ DataFile::ObjectLoader<DynamicDialog>(dd)
+{
+ add("position", &StateLoader::position);
+}
+
+void DynamicDialog::StateLoader::position(float x, float y)
+{
+ GLtk::Root *root = obj.find_ancestor<GLtk::Root>();
+ if(root)
+ {
+ const GLtk::Geometry &rgeom = root->get_geometry();
+ obj.set_position(x*(rgeom.w-obj.geom.w), y*(rgeom.h-obj.geom.h));
+ }
+}
class DynamicDialog: public Msp::GLtk::Dialog
{
+public:
+ class StateLoader: public Msp::DataFile::ObjectLoader<DynamicDialog>
+ {
+ public:
+ StateLoader(DynamicDialog &);
+
+ private:
+ void position(float, float);
+ };
+
protected:
UserInterface &ui;
public:
virtual ~DynamicDialog();
- virtual void update() = 0;
+ virtual void update() { };
+ virtual bool save_state(Msp::DataFile::Statement &) const { return false; }
+protected:
+ void save_position(std::list<Msp::DataFile::Statement> &) const;
};
#endif
if(FS::exists(options.state_fn))
DataFile::load(layout, options.state_fn);
+ if(FS::exists(options.uistate_fn))
+ DataFile::load(ui, options.uistate_fn);
+
if(options.network)
{
server = new Server(layout);
FS::rename(options.state_fn+".tmp", options.state_fn);
}
+ ui.save_state(options.uistate_fn);
+
layout.get_driver().halt(true);
layout.get_driver().flush();
getopt.add_option( "sim-speed", sim_speed, GetOpt::REQUIRED_ARG);
getopt.add_option('n', "network", network, GetOpt::NO_ARG);
getopt.add_option( "state", state_fn, GetOpt::REQUIRED_ARG);
+ getopt.add_option( "uistate", uistate_fn, GetOpt::REQUIRED_ARG);
getopt.add_argument("layout", layout_fn, GetOpt::REQUIRED_ARG);
getopt(argc, argv);
if(state_fn.empty())
state_fn = FS::basepart(layout_fn)+".state";
+
+ if(uistate_fn.empty())
+ uistate_fn = FS::basepart(layout_fn)+".uistate";
}
float sim_speed;
std::string layout_fn;
std::string state_fn;
+ std::string uistate_fn;
Options(int, char **);
};
i->label->set_text(text);
}
}
+
+bool TelemetryDialog::save_state(DataFile::Statement &st) const
+{
+ st.keyword = "telemetrydialog";
+ save_position(st.sub);
+
+ return true;
+}
public:
TelemetryDialog(Engineer &);
- void update();
+ virtual void update();
+ virtual bool save_state(Msp::DataFile::Statement &) const;
};
#endif
#include "libr2c2/layout.h"
#include "libr2c2/trainstatus.h"
#include "controlpanel.h"
+#include "engineer.h"
#include "routerpanel.h"
#include "timetablepanel.h"
#include "traindialog.h"
using namespace R2C2;
TrainDialog::TrainDialog(Engineer &e, R2C2::Train &t):
+ DynamicDialog(e.get_user_interface()),
engineer(e),
train(t),
updating(false)
{
panel->set_visible(show);
}
+
+bool TrainDialog::save_state(DataFile::Statement &st) const
+{
+ st.keyword = "traindialog";
+ st.append(train.get_address());
+ st.sub.push_back((DataFile::Statement("expanded"), pnl_expander->is_visible()));
+ save_position(st.sub);
+
+ return true;
+}
+
+
+TrainDialog::StateLoader::StateLoader(TrainDialog &td):
+ DataFile::DerivedObjectLoader<TrainDialog, DynamicDialog::StateLoader>(td)
+{
+ add("expanded", &StateLoader::expanded);
+}
+
+void TrainDialog::StateLoader::expanded(bool e)
+{
+ obj.set_expanded(e);
+}
#define TRAINDIALOG_H_
#include <msp/gltk/button.h>
-#include <msp/gltk/dialog.h>
#include <msp/gltk/hslider.h>
#include <msp/gltk/label.h>
#include <msp/gltk/toggle.h>
#include "libr2c2/train.h"
+#include "dynamicdialog.h"
class Engineer;
-class TrainDialog: public Msp::GLtk::Dialog, public sigc::trackable
+class TrainDialog: public DynamicDialog, public sigc::trackable
{
+public:
+ class StateLoader: public Msp::DataFile::DerivedObjectLoader<TrainDialog, DynamicDialog::StateLoader>
+ {
+ public:
+ StateLoader(TrainDialog &);
+
+ private:
+ void expanded(bool);
+ };
+
private:
Engineer &engineer;
R2C2::Train &train;
void expand_clicked();
void set_expanded(bool);
void toggle_panel(bool, Msp::GLtk::Panel *);
+
+public:
+ virtual bool save_state(Msp::DataFile::Statement &) const;
};
#endif
TrainListDialog::TrainListDialog(Engineer &e):
+ DynamicDialog(e.get_user_interface()),
engineer(e),
layout(engineer.get_layout())
{
trains.refresh(&train);
}
+bool TrainListDialog::save_state(DataFile::Statement &st) const
+{
+ st.keyword = "trainlistdialog";
+ save_position(st.sub);
+
+ return true;
+}
+
TrainItem::TrainItem(ValueType train)
{
#define TRAINLISTDIALOG_H_
#include <sigc++/trackable.h>
-#include <msp/gltk/dialog.h>
#include <msp/gltk/list.h>
#include <msp/gltk/listdata.h>
#include "libr2c2/layout.h"
+#include "dynamicdialog.h"
class Engineer;
-class TrainListDialog: public Msp::GLtk::Dialog, public sigc::trackable
+class TrainListDialog: public DynamicDialog, public sigc::trackable
{
private:
Engineer &engineer;
void train_added(R2C2::Train &);
void train_removed(R2C2::Train &);
void train_name_changed(R2C2::Train &);
+
+public:
+ virtual bool save_state(Msp::DataFile::Statement &) const;
};
#endif
+#include <msp/datafile/writer.h>
#include <msp/gltk/floatingarrangement.h>
#include <msp/time/utils.h>
+#include "clockdialog.h"
#include "departuresdialog.h"
#include "engineer.h"
#include "newtraindialog.h"
+#include "telemetrydialog.h"
#include "traindialog.h"
+#include "trainlistdialog.h"
#include "userinterface.h"
using namespace std;
void UserInterface::show_zone(Zone &zone)
{
- DeparturesDialog *dlg = new DeparturesDialog(engineer.get_layout(), zone.get_group());
+ DeparturesDialog *dlg = new DeparturesDialog(engineer, zone.get_group());
root.add(*dlg);
}
{
root.render();
}
+
+void UserInterface::save_state(const string &fn) const
+{
+ IO::BufferedFile out(fn, IO::M_WRITE);
+ DataFile::Writer writer(out);
+
+ for(set<DynamicDialog *>::const_iterator i=dyn_dialogs.begin(); i!=dyn_dialogs.end(); ++i)
+ {
+ DataFile::Statement st;
+ if((*i)->save_state(st))
+ writer.write(st);
+ }
+}
+
+
+UserInterface::Loader::Loader(UserInterface &ui):
+ DataFile::ObjectLoader<UserInterface>(ui)
+{
+ add("clockdialog", &Loader::basic_dialog<ClockDialog>);
+ add("departuresdialog", &Loader::basic_dialog<DeparturesDialog>);
+ add("telemetrydialog", &Loader::basic_dialog<TelemetryDialog>);
+ add("traindialog", &Loader::traindialog);
+ add("trainlistdialog", &Loader::basic_dialog<TrainListDialog>);
+}
+
+template<typename T>
+void UserInterface::Loader::dialog(T &dlg)
+{
+ obj.root.add(dlg);
+ typename T::StateLoader ldr(dlg);
+ load_sub_with(ldr);
+}
+
+template<typename T>
+void UserInterface::Loader::basic_dialog()
+{
+ dialog(*(new T(obj.engineer)));
+}
+
+void UserInterface::Loader::traindialog(unsigned a)
+{
+ Train &train = obj.engineer.get_layout().get_train(a);
+ dialog(*(new TrainDialog(obj.engineer, train)));
+}
class UserInterface
{
+public:
+ class Loader: public Msp::DataFile::ObjectLoader<UserInterface>
+ {
+ public:
+ Loader(UserInterface &);
+
+ private:
+ template<typename T>
+ void dialog(T &);
+
+ template<typename T>
+ void basic_dialog();
+
+ void traindialog(unsigned);
+ };
+
private:
Engineer &engineer;
Msp::GLtk::Resources resources;
public:
void tick();
void render() const;
+
+ void save_state(const std::string &) const;
};
#endif