From 7587f018794f53974409a2aad76a0a421cea2d24 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 13 Dec 2009 16:27:21 +0000 Subject: [PATCH] Support setting routes for trains Fix Train::find_speed --- source/engineer/engineer.h | 1 + source/engineer/routeselect.cpp | 55 +++++++++++++++++++++++++++++++++ source/engineer/routeselect.h | 30 ++++++++++++++++++ source/engineer/trainpanel.cpp | 28 ++++++++++++++++- source/engineer/trainpanel.h | 4 +++ source/libmarklin/train.cpp | 32 ++++++++++++++++--- source/libmarklin/train.h | 5 +++ 7 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 source/engineer/routeselect.cpp create mode 100644 source/engineer/routeselect.h diff --git a/source/engineer/engineer.h b/source/engineer/engineer.h index df45678..8e8e021 100644 --- a/source/engineer/engineer.h +++ b/source/engineer/engineer.h @@ -64,6 +64,7 @@ public: const Msp::GLtk::Resources &get_ui_resources() const { return ui_res; } Msp::GLtk::Root &get_root() const { return *root; } const Marklin::Catalogue &get_catalogue() const { return catalogue; } + const Marklin::Layout &get_layout() const { return layout; } Marklin::Control &get_control() { return control; } Marklin::TrafficManager &get_traffic_manager() { return *trfc_mgr; } void place_train(Marklin::Train &); diff --git a/source/engineer/routeselect.cpp b/source/engineer/routeselect.cpp new file mode 100644 index 0000000..8b526ae --- /dev/null +++ b/source/engineer/routeselect.cpp @@ -0,0 +1,55 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2009 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#include +#include "engineer.h" +#include "libmarklin/route.h" +#include "routeselect.h" + +using namespace std; +using namespace Msp; +using namespace Marklin; + +RouteSelect::RouteSelect(Engineer &e, const GLtk::Resources &r, Train &t): + GLtk::Widget(r), + Dialog(r), + engineer(e), + train(t) +{ + set_size(200, 95); + + GLtk::Label *label; + add(*(label = new GLtk::Label(res, "Select route"))); + label->set_geometry(GLtk::Geometry(10, geom.h-25, geom.w-20, 20)); + + add(*(drp_route = new GLtk::Dropdown(res))); + drp_route->set_geometry(GLtk::Geometry(10, geom.h-50, geom.w-20, 20)); + drp_route->append("(none)"); + drp_route->set_selected_index(0); + const set &routes = engineer.get_layout().get_routes(); + unsigned n = 1; + for(set::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n) + { + drp_route->append((*i)->get_name()); + if(*i==train.get_route()) + drp_route->set_selected_index(n); + } +} + +void RouteSelect::on_ok_clicked() +{ + if(drp_route->get_selected_index()>0) + { + const set &routes = engineer.get_layout().get_routes(); + set::const_iterator i = routes.begin(); + advance(i, drp_route->get_selected_index()-1); + + train.set_route(*i); + } + else + train.set_route(0); +} diff --git a/source/engineer/routeselect.h b/source/engineer/routeselect.h new file mode 100644 index 0000000..53bf2fb --- /dev/null +++ b/source/engineer/routeselect.h @@ -0,0 +1,30 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2009 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#ifndef ROUTESELECT_H_ +#define ROUTESELECT_H_ + +#include +#include "libmarklin/train.h" +#include "dialog.h" + +class Engineer; + +class RouteSelect: public Dialog +{ +private: + Engineer &engineer; + Marklin::Train &train; + Msp::GLtk::Dropdown *drp_route; + +public: + RouteSelect(Engineer &, const Msp::GLtk::Resources &, Marklin::Train &); +private: + virtual void on_ok_clicked(); +}; + +#endif diff --git a/source/engineer/trainpanel.cpp b/source/engineer/trainpanel.cpp index be675d6..d462b51 100644 --- a/source/engineer/trainpanel.cpp +++ b/source/engineer/trainpanel.cpp @@ -9,6 +9,7 @@ Distributed under the GPL #include #include "libmarklin/locomotive.h" #include "engineer.h" +#include "routeselect.h" #include "trainpanel.h" #include "trainproperties.h" @@ -22,7 +23,7 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t): engineer(e), train(t) { - set_size(200, 145); + set_size(200, 170); add(*(lbl_addr=new GLtk::Label(res, format("%2d", train.get_locomotive().get_address())))); lbl_addr->set_style("digital"); @@ -50,6 +51,11 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t): tgl_forward->set_value(!train.get_locomotive().get_reverse()); tgl_forward->signal_toggled.connect(sigc::mem_fun(this, &TrainPanel::forward_toggled)); + add(*(lbl_route=new GLtk::Label(res, "Free run"))); + lbl_route->set_style("digital"); + lbl_route->set_geometry(GLtk::Geometry(10, 58, geom.w-20, 24)); + train.signal_route_changed.connect(sigc::mem_fun(this, &TrainPanel::train_route_changed)); + add(*(lbl_status=new GLtk::Label(res, train.get_status()))); lbl_status->set_style("digital"); lbl_status->set_geometry(GLtk::Geometry(10, 34, geom.w-20, 24)); @@ -84,6 +90,10 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t): add(*(btn=new GLtk::Button(res, "GoTo"))); btn->set_geometry(GLtk::Geometry(geom.w-130, 10, 40, 24)); + + add(*(btn=new GLtk::Button(res, "Route"))); + btn->set_geometry(GLtk::Geometry(geom.w-170, 10, 40, 24)); + btn->signal_clicked.connect(sigc::mem_fun(this, &TrainPanel::route_clicked)); } void TrainPanel::speed_slider_changed(double v) @@ -104,6 +114,14 @@ void TrainPanel::loco_function_changed(unsigned func, bool value) i->second->set_value(value); } +void TrainPanel::train_route_changed(const Route *r) +{ + if(r) + lbl_route->set_text(r->get_name()); + else + lbl_route->set_text("Free run"); +} + void TrainPanel::train_status_changed(const string &s) { lbl_status->set_text(s); @@ -122,6 +140,14 @@ void TrainPanel::edit_clicked() dialog->set_visible(true); } +void TrainPanel::route_clicked() +{ + RouteSelect *dialog = new RouteSelect(engineer, res, train); + engineer.get_root().add(*dialog); + dialog->set_position(geom.x+geom.w, geom.y+geom.h-dialog->get_geometry().h); + dialog->set_visible(true); +} + void TrainPanel::forward_toggled(bool value) { train.set_reverse(!value); diff --git a/source/engineer/trainpanel.h b/source/engineer/trainpanel.h index 817ba18..aae71f9 100644 --- a/source/engineer/trainpanel.h +++ b/source/engineer/trainpanel.h @@ -12,6 +12,7 @@ Distributed under the GPL #include #include #include +#include "libmarklin/route.h" #include "libmarklin/train.h" class Engineer; @@ -25,6 +26,7 @@ private: Msp::GLtk::Label *lbl_name; Msp::GLtk::HSlider *sld_speed; Msp::GLtk::Label *lbl_speed; + Msp::GLtk::Label *lbl_route; Msp::GLtk::Label *lbl_status; Msp::GLtk::Toggle *tgl_forward; std::map tgl_funcs; @@ -35,9 +37,11 @@ private: void speed_slider_changed(double); void train_speed_changed(unsigned); void loco_function_changed(unsigned, bool); + void train_route_changed(const Marklin::Route *); void train_status_changed(const std::string &); void place_clicked(); void edit_clicked(); + void route_clicked(); void forward_toggled(bool); void func_toggled(bool, unsigned); }; diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index e904ebf..12c4c26 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -11,6 +11,7 @@ Distributed under the GPL #include #include "control.h" #include "except.h" +#include "route.h" #include "tracktype.h" #include "trafficmanager.h" #include "train.h" @@ -80,6 +81,12 @@ void Train::set_reverse(bool rev) loco.set_reverse(rev); } +void Train::set_route(const Route *r) +{ + route = r; + signal_route_changed.emit(route); +} + void Train::place(Block *block, unsigned entry) { for(list::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end();) @@ -321,6 +328,12 @@ unsigned Train::reserve_more() Block *link = last->block->get_link(exit); if(link && link->reserve(this)) { + if(route && link->get_turnout_id()) + { + int path = route->get_turnout(link->get_turnout_id()); + if(path>=0) + trfc_mgr.get_control().get_turnout(link->get_turnout_id()).set_path(path); + } rsv_blocks.push_back(BlockRef(link, link->get_endpoint_by_link(*last->block))); last = &rsv_blocks.back(); if(last->block->get_sensor_id()) @@ -422,14 +435,23 @@ unsigned Train::find_speed(float real) const { if(real<=real_speed[0].speed) return 0; - if(real>=real_speed[14].speed) - return 14; unsigned low = 0; unsigned high = 0; - for(high=0; real_speed[high].speed(low*real/real_speed[low].speed), 14U); + } float f = (real-real_speed[low].speed)/(real_speed[high].speed-real_speed[low].speed); return static_cast(low*(1-f)+high*f+0.5); diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index b891a66..90627ae 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -16,6 +16,7 @@ Distributed under the GPL namespace Marklin { class Locomotive; +class Route; class Sensor; class TrafficManager; class Turnout; @@ -33,6 +34,7 @@ public: sigc::signal signal_name_changed; sigc::signal signal_target_speed_changed; + sigc::signal signal_route_changed; sigc::signal signal_status_changed; private: @@ -59,6 +61,7 @@ private: std::list cur_blocks; std::list rsv_blocks; unsigned target_speed; + const Route *route; Msp::Time::TimeStamp try_reserve; std::string status; @@ -79,9 +82,11 @@ public: void set_name(const std::string &); void set_speed(unsigned); void set_reverse(bool); + void set_route(const Route *); const std::string &get_name() const { return name; } Locomotive &get_locomotive() const { return loco; } unsigned get_target_speed() const { return target_speed; } + const Route *get_route() const { return route; } const std::string &get_status() const { return status; } const Point &get_position() const { return pos; } void place(Block *, unsigned); -- 2.43.0