From 9afe42fc94eed6754da8401082e76121f8c66783 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 16 Nov 2013 01:01:39 +0200 Subject: [PATCH] Implement an UI for importing locomotives from the driver --- data/trainlistdialog.ui | 33 ++++++++++++++++-- source/engineer/engineer.cpp | 21 ++++++++++++ source/engineer/engineer.h | 4 +++ source/engineer/trainlistdialog.cpp | 52 +++++++++++++++++++++++++++++ source/engineer/trainlistdialog.h | 5 +++ 5 files changed, 113 insertions(+), 2 deletions(-) diff --git a/data/trainlistdialog.ui b/data/trainlistdialog.ui index a1ebf79..0582066 100644 --- a/data/trainlistdialog.ui +++ b/data/trainlistdialog.ui @@ -25,9 +25,38 @@ column }; }; - list "lst_trains" + row { - view_size 10; + column + { + toggle "tgl_trains" + { + text "Trains"; + style "pointer_left"; + exclusive true; + value true; + }; + toggle "tgl_import" + { + text "Import"; + style "pointer_left"; + exclusive true; + }; + }; + + stack + { + list "lst_trains" + { + view_size 10; + }; + + list "lst_imported" + { + view_size 10; + visible false; + }; + }; }; row diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index 87e3dda..d0c879c 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -27,6 +27,7 @@ #include "3d/vehicle.h" #include "engineer.h" #include "mainwindow.h" +#include "newtraindialog.h" #include "traindialog.h" #include "trainview.h" @@ -40,6 +41,7 @@ Engineer::Engineer(int argc, char **argv): keyboard(window), mouse(window), ui_res("r2c2.res"), + import_active(false), layout(catalogue, (options.driver.empty() ? 0 : Driver::create(options.driver))), layout_3d(layout), server(0), @@ -71,6 +73,8 @@ Engineer::Engineer(int argc, char **argv): DataFile::load(catalogue, "wagons.dat"); DataFile::load(layout, options.layout_fn); + if(layout.has_driver()) + layout.get_driver().signal_locomotive_detected.connect(sigc::mem_fun(this, &Engineer::locomotive_detected)); layout.signal_train_added.connect(sigc::mem_fun(this, &Engineer::train_added)); layout.signal_emergency.connect(sigc::mem_fun(this, &Engineer::set_status)); const set &blocks = layout.get_all(); @@ -296,6 +300,23 @@ Object *Engineer::pick_object(const Vector &p) return layout.pick(Ray(start, Vector(ray))); } +void Engineer::locomotive_detected(const Driver::DetectedLocomotive &loco) +{ + if(!import_active) + { + NewTrainDialog *dlg = new NewTrainDialog(*this); + dlg->prefill(loco); + dlg->signal_response.connect(sigc::mem_fun(this, &Engineer::import_finished)); + root->add(*dlg); + import_active = true; + } +} + +void Engineer::import_finished(int) +{ + import_active = false; +} + void Engineer::process_new_train(Train &train) { Vehicle3D &loco3d = layout_3d.get_3d(train.get_vehicle(0)); diff --git a/source/engineer/engineer.h b/source/engineer/engineer.h index 418c0cd..d821e05 100644 --- a/source/engineer/engineer.h +++ b/source/engineer/engineer.h @@ -10,6 +10,7 @@ #include #include #include "libr2c2/catalogue.h" +#include "libr2c2/driver.h" #include "libr2c2/train.h" #include "3d/layout.h" #include "3d/overlay.h" @@ -32,6 +33,7 @@ private: Msp::GLtk::Resources ui_res; Msp::GLtk::Root *root; Msp::GLtk::Arrangement *root_arrangement; + bool import_active; R2C2::Catalogue catalogue; R2C2::Layout layout; @@ -72,6 +74,8 @@ private: void sensor_event(unsigned, bool); void block_reserved(const R2C2::Block &, const R2C2::Train *); R2C2::Object *pick_object(const R2C2::Vector &); + void locomotive_detected(const R2C2::Driver::DetectedLocomotive &); + void import_finished(int); void train_added(R2C2::Train &); void process_new_train(R2C2::Train &); virtual void sighandler(int); diff --git a/source/engineer/trainlistdialog.cpp b/source/engineer/trainlistdialog.cpp index f4fbb10..e84fc88 100644 --- a/source/engineer/trainlistdialog.cpp +++ b/source/engineer/trainlistdialog.cpp @@ -20,6 +20,15 @@ public: }; +class DetectedLocoItem: public GLtk::List::MultiColumnItem +{ +public: + typedef const Driver::DetectedLocomotive *ValueType; + + DetectedLocoItem(ValueType); +}; + + TrainListDialog::TrainListDialog(Engineer &e): engineer(e), layout(engineer.get_layout()) @@ -31,6 +40,13 @@ TrainListDialog::TrainListDialog(Engineer &e): lst_trains->set_data(trains); lst_trains->set_item_type(); + lst_imported = dynamic_cast(get_item(widgets, "lst_imported")); + lst_imported->set_data(detected_locos); + lst_imported->set_item_type(); + + dynamic_cast(get_item(widgets, "tgl_trains"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainListDialog::tab_toggled), lst_trains)); + dynamic_cast(get_item(widgets, "tgl_import"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainListDialog::tab_toggled), lst_imported)); + dynamic_cast(get_item(widgets, "btn_new"))->signal_clicked.connect(sigc::mem_fun(this, &TrainListDialog::new_clicked)); dynamic_cast(get_item(widgets, "btn_show"))->signal_clicked.connect(sigc::mem_fun(this, &TrainListDialog::show_clicked)); @@ -41,6 +57,12 @@ TrainListDialog::TrainListDialog(Engineer &e): i->second->signal_name_changed.connect(sigc::hide(sigc::bind(sigc::mem_fun(this, &TrainListDialog::train_name_changed), sigc::ref(*i->second)))); } + if(layout.has_driver()) + { + Driver &driver = layout.get_driver(); + driver.signal_locomotive_detected.connect(sigc::mem_fun(this, &TrainListDialog::locomotive_detected)); + driver.signal_locomotive_gone.connect(sigc::mem_fun(this, &TrainListDialog::locomotive_gone)); + } layout.signal_train_added.connect(sigc::mem_fun(this, &TrainListDialog::train_added)); layout.signal_train_removed.connect(sigc::mem_fun(this, &TrainListDialog::train_removed)); } @@ -48,6 +70,12 @@ TrainListDialog::TrainListDialog(Engineer &e): void TrainListDialog::new_clicked() { NewTrainDialog *dlg = new NewTrainDialog(engineer); + if(lst_imported->is_visible()) + { + int selected = lst_imported->get_selected_index(); + if(selected>=0) + dlg->prefill(*detected_locos.get(selected)); + } find_ancestor()->add(*dlg); dlg->autosize(); } @@ -62,6 +90,23 @@ void TrainListDialog::show_clicked() } } +void TrainListDialog::tab_toggled(bool value, GLtk::Widget *wdg) +{ + wdg->set_visible(value); +} + +void TrainListDialog::locomotive_detected(const Driver::DetectedLocomotive &loco) +{ + detected_locos.append(&loco); +} + +void TrainListDialog::locomotive_gone(const Driver::DetectedLocomotive &loco) +{ + int index = detected_locos.find(&loco); + if(index>=0) + detected_locos.remove(index); +} + void TrainListDialog::train_added(Train &train) { unsigned n_items = trains.size(); @@ -94,3 +139,10 @@ TrainItem::TrainItem(ValueType train) add(*new GLtk::Label(train->get_name())); } + +DetectedLocoItem::DetectedLocoItem(ValueType loco) +{ + add(*new GLtk::Label(loco->protocol)); + add(*new GLtk::Label(lexical_cast(loco->address))); + add(*new GLtk::Label(loco->name)); +} diff --git a/source/engineer/trainlistdialog.h b/source/engineer/trainlistdialog.h index 5757c73..9403d2f 100644 --- a/source/engineer/trainlistdialog.h +++ b/source/engineer/trainlistdialog.h @@ -16,6 +16,8 @@ private: R2C2::Layout &layout; Msp::GLtk::BasicListData trains; Msp::GLtk::List *lst_trains; + Msp::GLtk::BasicListData detected_locos; + Msp::GLtk::List *lst_imported; public: TrainListDialog(Engineer &); @@ -23,6 +25,9 @@ public: private: void new_clicked(); void show_clicked(); + void tab_toggled(bool, Msp::GLtk::Widget *); + void locomotive_detected(const R2C2::Driver::DetectedLocomotive &); + void locomotive_gone(const R2C2::Driver::DetectedLocomotive &); void train_added(R2C2::Train &); void train_removed(R2C2::Train &); void train_name_changed(R2C2::Train &); -- 2.43.0