mode(SELECT),
manipulator(*this, selection),
measure(*this),
- input(0),
- camera_ctl(window, camera),
- shift(false)
+ camera_ctl(window, camera)
{
window.set_title("Railway Designer");
window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Designer::exit), 0));
- window.signal_key_press.connect(sigc::mem_fun(this, &Designer::key_press));
- window.signal_key_release.connect(sigc::mem_fun(this, &Designer::key_release));
- window.signal_button_press.connect(sigc::mem_fun(this, &Designer::button_press));
- window.signal_pointer_motion.connect(sigc::mem_fun(this, &Designer::pointer_motion));
manipulator.signal_status.connect(sigc::mem_fun(this, &Designer::manipulation_status));
manipulator.signal_done.connect(sigc::mem_fun(this, &Designer::manipulation_done));
// Setup UI
DataFile::load(ui_res, "marklin.res");
root = new GLtk::Root(ui_res, window);
+ root->signal_key_press.connect(sigc::mem_fun(this, &Designer::key_press));
+ root->signal_button_press.connect(sigc::mem_fun(this, &Designer::button_press));
+ root->signal_pointer_motion.connect(sigc::mem_fun(this, &Designer::pointer_motion));
root->signal_tooltip.connect(sigc::mem_fun(this, &Designer::tooltip));
toolbar = new Toolbar(*this);
root->add(*toolbar);
toolbar->set_position(0, window.get_height()-toolbar->get_geometry().h);
- toolbar->set_visible(true);
+ toolbar->set_focusable(false);
GLtk::Panel *statusbar = new GLtk::Panel(ui_res);
root->add(*statusbar);
statusbar->set_size(window.get_width(), 20);
- statusbar->set_visible(true);
+ statusbar->set_focusable(false);
lbl_status = new GLtk::Label(ui_res);
statusbar->add(*lbl_status);
void Designer::save()
{
- input = new ::Input(*this, "Save layout", filename);
- input->signal_cancel.connect(sigc::mem_fun(this, &Designer::input_dismiss));
- input->signal_accept.connect(sigc::mem_fun(this, &Designer::save_accept));
- mode = INPUT;
+ InputDialog *input = new InputDialog(*this, "Save layout", filename);
+ input->signal_accept.connect(sigc::mem_fun(layout, &Layout::save));
}
void Designer::quit()
exit(0);
}
+void Designer::new_track()
+{
+ mode = CATALOGUE;
+}
+
+void Designer::set_turnout_id()
+{
+ Track *track = selection.get_track();
+ if(selection.size()==1 && track->get_type().get_n_paths()>1)
+ {
+ InputDialog *input = new InputDialog(*this, "Turnout ID", lexical_cast(track->get_turnout_id()));
+ input->signal_accept.connect(sigc::mem_fun(this, &Designer::turnout_id_accept));
+ }
+}
+
+void Designer::set_sensor_id()
+{
+ const set<Track *> &tracks = selection.get_tracks();
+ bool ok = false;
+ int id = -1;
+ for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ {
+ if((*i)->get_type().get_n_paths()==1)
+ ok = true;
+ if(static_cast<int>((*i)->get_sensor_id())!=id)
+ {
+ if(id==-1)
+ id = (*i)->get_sensor_id();
+ else
+ id = -2;
+ }
+ }
+
+ if(ok)
+ {
+ InputDialog *input = new InputDialog(*this, "Sensor ID", (id>=0 ? lexical_cast(id) : string()));
+ input->signal_accept.connect(sigc::mem_fun(this, &Designer::sensor_id_accept));
+ }
+}
+
void Designer::edit_route(Route &r)
{
cur_route = &r;
window.swap_buffers();
}
-void Designer::key_press(unsigned code, unsigned mod, wchar_t)
+void Designer::key_press(unsigned key, unsigned mod, wchar_t)
{
- unsigned key = Msp::Input::key_from_sys(code);
-
- if(mode==INPUT)
- return;
-
- if(key==Msp::Input::KEY_SHIFT_L || key==Msp::Input::KEY_SHIFT_R)
- shift = true;
+ key = Input::key_from_sys(key);
+ mod = Input::mod_from_sys(mod);
if(key==Msp::Input::KEY_N)
- mode = CATALOGUE;
+ new_track();
else if(key==Msp::Input::KEY_G)
{
manipulator.start_move();
save();
else if(key==Msp::Input::KEY_PLUS)
selection.select_more();
- else if(key==Msp::Input::KEY_L && (mod&1))
+ else if(key==Msp::Input::KEY_L && (mod&Input::MOD_SHIFT))
{
const set<Track *> &tracks = layout->get_tracks();
float len = 0;
delete *i;
}
}
- else if(key==Msp::Input::KEY_F && (mod&1))
+ else if(key==Msp::Input::KEY_F && (mod&Input::MOD_SHIFT))
{
const set<Track *> &tracks = selection.get_tracks();
const set<Track *> <racks = layout->get_tracks();
}
else if(key==Msp::Input::KEY_F)
manipulator.flatten();
- else if(key==Msp::Input::KEY_E && (mod&1))
+ else if(key==Msp::Input::KEY_E && (mod&Input::MOD_SHIFT))
manipulator.even_slope(true);
else if(key==Msp::Input::KEY_E)
manipulator.even_slope();
else if(key==Msp::Input::KEY_T)
- {
- Track *track = selection.get_track();
- if(selection.size()==1 && track->get_type().get_n_paths()>1)
- {
- input = new ::Input(*this, "Turnout ID", lexical_cast(track->get_turnout_id()));
- input->signal_cancel.connect(sigc::mem_fun(this, &Designer::input_dismiss));
- input->signal_accept.connect(sigc::mem_fun(this, &Designer::turnout_id_accept));
- mode = INPUT;
- }
- }
+ set_turnout_id();
else if(key==Msp::Input::KEY_S)
- {
- const set<Track *> &tracks = selection.get_tracks();
- bool ok = false;
- int id = -1;
- for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
- {
- if((*i)->get_type().get_n_paths()==1)
- ok = true;
- if(static_cast<int>((*i)->get_sensor_id())!=id)
- {
- if(id==-1)
- id = (*i)->get_sensor_id();
- else
- id = -2;
- }
- }
- if(ok)
- {
- input = new ::Input(*this, "Sensor ID", (id>=0 ? lexical_cast(id) : string()));
- input->signal_cancel.connect(sigc::mem_fun(this, &Designer::input_dismiss));
- input->signal_accept.connect(sigc::mem_fun(this, &Designer::sensor_id_accept));
- mode = INPUT;
- }
- }
+ set_sensor_id();
else if(key==Msp::Input::KEY_A)
add_selection_to_route();
}
-void Designer::key_release(unsigned code, unsigned)
-{
- unsigned key = Msp::Input::key_from_sys(code);
-
- if(mode==INPUT)
- return;
-
- if(key==Msp::Input::KEY_SHIFT_L || key==Msp::Input::KEY_SHIFT_R)
- shift = false;
-}
-
-void Designer::button_press(int x, int y, unsigned btn, unsigned)
+void Designer::button_press(int x, int y, unsigned btn, unsigned mod)
{
y = window.get_height()-y-1;
+ mod = Input::mod_from_sys(mod);
Point ground = map_pointer_coords(x, y);
Track3D *track = pick_track(x, y);
if(track)
{
- if(!shift)
+ if(!(mod&Input::MOD_SHIFT))
selection.clear();
selection.toggle_track(&track->get_track());
}
{
y = window.get_height()-y-1;
- if(mode!=INPUT)
+ if(!root->get_child_at(x, y))
{
Point ground = map_pointer_coords(x, y);
manipulator.pointer_motion(x, y, ground.x, ground.y);
mode = SELECT;
}
-void Designer::save_accept()
-{
- layout->save(input->get_text());
-
- input_dismiss();
-}
-
-void Designer::turnout_id_accept()
+void Designer::turnout_id_accept(const string &text)
{
Track *track = selection.get_track();
- unsigned id = lexical_cast<unsigned>(input->get_text());
+ unsigned id = (text.empty() ? 0 : lexical_cast<unsigned>(text));
track->set_turnout_id(id);
update_track_icon(layout_3d->get_track(*track));
-
- input_dismiss();
}
-void Designer::sensor_id_accept()
+void Designer::sensor_id_accept(const string &text)
{
const set<Track *> &tracks = selection.get_tracks();
- unsigned id = lexical_cast<unsigned>(input->get_text());
+ unsigned id = (text.empty() ? 0 : lexical_cast<unsigned>(text));
for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
{
(*i)->set_sensor_id(id);
update_track_icon(layout_3d->get_track(**i));
}
-
- input_dismiss();
-}
-
-void Designer::input_dismiss()
-{
- delete input;
- input = 0;
- mode = SELECT;
}
void Designer::view_all()
#include "measure.h"
#include "selection.h"
-class Input;
class Toolbar;
class Designer: public Msp::Application
SELECT,
CATALOGUE,
MANIPULATE,
- MEASURE,
- INPUT
+ MEASURE
};
Msp::Graphics::SimpleGLWindow window;
Selection selection;
Manipulator manipulator;
Measure measure;
- Input *input;
CameraController camera_ctl;
- bool shift;
-
Msp::Time::TimeStamp last_tick;
static Msp::Application::RegApp<Designer> reg;
const Msp::GL::Camera &get_camera() const { return camera; }
const Msp::GLtk::Resources &get_ui_resources() const { return ui_res; }
Msp::GLtk::Root &get_root() const { return *root; }
+
+ void new_track();
+ void set_turnout_id();
+ void set_sensor_id();
+
void edit_route(Marklin::Route &);
Marklin::Route *get_current_route() const { return cur_route; }
void add_selection_to_route();
private:
void tick();
void key_press(unsigned, unsigned, wchar_t);
- void key_release(unsigned, unsigned);
void button_press(int, int, unsigned, unsigned);
void pointer_motion(int, int);
void apply_camera();
void manipulation_done(bool);
void measure_changed();
void measure_done();
- void set_tooltip(int, int, const std::string &);
- void clear_tooltip();
- void save_accept();
- void turnout_id_accept();
- void sensor_id_accept();
- void input_dismiss();
+ void turnout_id_accept(const std::string &);
+ void sensor_id_accept(const std::string &);
void view_all();
std::string tooltip(int, int);
};
/* $Id$
This file is part of the MSP Märklin suite
-Copyright © 2006-2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2006-2008, 2010 Mikkosoft Productions, Mikko Rasa
Distributed under the GPL
*/
using namespace std;
using namespace Msp;
-::Input::Input(Designer &d, const string &title, const string &text):
+InputDialog::InputDialog(Designer &d, const string &title, const string &text):
GLtk::Widget(d.get_ui_resources()),
- GLtk::Panel(d.get_ui_resources()),
+ GLtk::Dialog(d.get_ui_resources()),
designer(d)
{
set_size(300, 100);
GLtk::Button *btn;
- add(*(btn=new GLtk::Button(res, "Cncl")));
+ add_button(*(btn=new GLtk::Button(res, "Cncl")), 0);
btn->set_geometry(GLtk::Geometry(geom.w-90, 10, 40, 24));
btn->set_style("red");
- btn->signal_clicked.connect(signal_cancel);
- add(*(btn=new GLtk::Button(res, "OK")));
+ add_button(*(btn=new GLtk::Button(res, "OK")), 1);
btn->set_geometry(GLtk::Geometry(geom.w-50, 10, 40, 24));
btn->set_style("green");
- btn->signal_clicked.connect(signal_accept);
designer.get_root().add(*this);
const GLtk::Geometry &rgeom=designer.get_root().get_geometry();
entry->set_focus();
}
-const string &::Input::get_text() const
-{
- return entry->get_text();
-}
-
-void ::Input::key_press(unsigned key, unsigned mod, wchar_t ch)
+void InputDialog::key_press(unsigned key, unsigned mod, wchar_t ch)
{
if(key==Msp::Input::KEY_ENTER)
- signal_accept.emit();
+ response(1);
else if(key==Msp::Input::KEY_ESC)
- signal_cancel.emit();
+ response(0);
else
- Panel::key_press(key, mod, ch);
+ Dialog::key_press(key, mod, ch);
+}
+
+void InputDialog::on_response(int code)
+{
+ if(code)
+ signal_accept.emit(entry->get_text());
}
/* $Id$
This file is part of the MSP Märklin suite
-Copyright © 2006-2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2006-2008, 2010 Mikkosoft Productions, Mikko Rasa
Distributed under the GPL
*/
#include <string>
#include <sigc++/sigc++.h>
+#include <msp/gltk/dialog.h>
#include <msp/gltk/entry.h>
class Designer;
-class Input: public Msp::GLtk::Panel
+class InputDialog: public Msp::GLtk::Dialog
{
public:
- sigc::signal<void> signal_accept;
- sigc::signal<void> signal_cancel;
+ sigc::signal<void, const std::string &> signal_accept;
private:
Designer &designer;
Msp::GLtk::Entry *entry;
public:
- Input(Designer &, const std::string &, const std::string & =std::string());
- const std::string &get_text() const;
+ InputDialog(Designer &, const std::string &, const std::string & =std::string());
private:
virtual void key_press(unsigned, unsigned, wchar_t);
+ virtual void on_response(int);
};
#endif
GLtk::Panel(d.get_ui_resources()),
designer(d)
{
- set_size(370, 40);
+ set_size(410, 40);
GLtk::Button *btn;
GLtk::Label *lbl;
add(*(btn=new GLtk::Button(res, "Load")));
btn->set_geometry(GLtk::Geometry(5, 10, 40, 24));
+ btn->set_tooltip("Load layout (not implemented)");
add(*(btn=new GLtk::Button(res, "Save")));
btn->set_geometry(GLtk::Geometry(45, 10, 40, 24));
+ btn->set_tooltip("Save current layout");
btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::save));
add(*(btn=new GLtk::Button(res, "Quit")));
btn->set_geometry(GLtk::Geometry(85, 10, 40, 24));
btn->set_style("red");
+ btn->set_tooltip("Exit Designer");
btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::quit));
- add(*(btn=new GLtk::Button(res, "Trnt")));
+ add(*(btn=new GLtk::Button(res, "NewT")));
btn->set_geometry(GLtk::Geometry(135, 10, 40, 24));
+ btn->set_tooltip("Add a track piece");
+ btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::new_track));
- add(*(btn=new GLtk::Button(res, "Sens")));
+ add(*(btn=new GLtk::Button(res, "Trnt")));
btn->set_geometry(GLtk::Geometry(175, 10, 40, 24));
+ btn->set_tooltip("Set turnout ID of selected track");
+ btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::set_turnout_id));
+
+ add(*(btn=new GLtk::Button(res, "Sens")));
+ btn->set_geometry(GLtk::Geometry(215, 10, 40, 24));
+ btn->set_tooltip("Set sensor ID of selected tracks");
+ btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::set_sensor_id));
add(*(lbl=new GLtk::Label(res, "Routes:")));
- lbl->set_geometry(GLtk::Geometry(225, 22, 40, 13));
+ lbl->set_geometry(GLtk::Geometry(265, 22, 40, 13));
add(*(drp_routes=new GLtk::Dropdown(res)));
- drp_routes->set_geometry(GLtk::Geometry(225, 5, 100, 17));
+ drp_routes->set_geometry(GLtk::Geometry(265, 5, 100, 17));
+ drp_routes->set_tooltip("Select route to edit");
drp_routes->append("(new route)");
drp_routes->signal_item_selected.connect(sigc::mem_fun(this, &Toolbar::route_selected));
add(*(btn=new GLtk::Button(res, "AddT")));
- btn->set_geometry(GLtk::Geometry(325, 10, 40, 24));
+ btn->set_geometry(GLtk::Geometry(365, 10, 40, 24));
+ btn->set_tooltip("Add selected tracks to current route");
btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::add_selection_to_route));
designer.get_layout()->signal_route_added.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes)));