From: Mikko Rasa Date: Wed, 4 Jun 2008 23:51:10 +0000 (+0000) Subject: Add locomotive types X-Git-Url: https://git.tdb.fi/?a=commitdiff_plain;h=447d621e93e71b710fed0920b473350122426b97;p=r2c2.git Add locomotive types Buttons for locomotive functions Various enhancements around the code UI graphics for dropdown --- diff --git a/engineer.res b/engineer.res index 7f75ae4..c5650af 100644 --- a/engineer.res +++ b/engineer.res @@ -68,6 +68,19 @@ graphic "entrycursor" slice 54 74 2 12; }; +graphic "dropdownbg" +{ + texture "gui.png"; + slice 58 72 30 16; + border { top 4; right 20; bottom 4; left 2; }; +}; + +graphic "dropdownarrow" +{ + texture "gui.png"; + slice 90 75 10 8; +}; + graphic "yellowlamp" { texture "gui.png"; @@ -291,3 +304,47 @@ style "root" { special "children"; }; + +style "dropdown" +{ + font_color 0.0 0.0 0.0; + + part + { + graphic NORMAL "dropdownbg"; + }; + + part + { + graphic NORMAL "dropdownarrow"; + align 1.0 0.5; + fill 0.0 0.0; + margin { right 2; }; + }; + + special "text" + { + align 0.0 0.5; + fill 0.0 0.0; + margin { left 2; }; + }; + + special "list"; +}; + +style "list" +{ + font_color 0.0 0.0 0.0; + + part + { + graphic NORMAL "entrybg"; + }; + + special "items" + { + margin { top 2; right 2; bottom 2; left 2; }; + }; +}; + +style "vslider"; diff --git a/gui.blend b/gui.blend index f53efda..9407d86 100644 Binary files a/gui.blend and b/gui.blend differ diff --git a/gui.png b/gui.png index cb71fa1..b0fec5b 100644 Binary files a/gui.png and b/gui.png differ diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index ec56103..0d4f729 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -71,6 +71,7 @@ Engineer::Engineer(int argc, char **argv): layout_3d.set_quality(quality); catalogue.load("tracks.dat"); + catalogue.load("locos.dat"); const vector &args=getopt.get_args(); if(args.empty()) @@ -92,37 +93,33 @@ Engineer::~Engineer() delete trfc_mgr; } -Train *Engineer::add_train(unsigned addr) +void Engineer::add_train() { - if(addr==0) - { - train_prop=new TrainProperties(*this, ui_res, 0); - root->add(*train_prop); - train_prop->signal_ok.connect(sigc::mem_fun(this, &Engineer::dismiss_train_prop)); - train_prop_stale=false; - train_prop->set_visible(true); + train_prop=new TrainProperties(*this, ui_res, 0); + root->add(*train_prop); + train_prop->signal_ok.connect(sigc::mem_fun(this, &Engineer::dismiss_train_prop)); + train_prop_stale=false; + train_prop->set_visible(true); +} - return 0; - } - else - { - Locomotive *loco=new Locomotive(control, addr); - Train *train=new Train(*trfc_mgr, *loco); - train->set_name(format("Train %d", trfc_mgr->get_trains().size())); - - TrainPanel *tpanel=new TrainPanel(*this, ui_res, *train); - root->add(*tpanel); - int y=main_panel->get_geometry().y; - for(list::iterator i=train_panels.begin(); i!=train_panels.end(); ++i) - y-=(*i)->get_geometry().h; - tpanel->set_position(0, y-tpanel->get_geometry().h); - train_panels.push_back(tpanel); - tpanel->set_visible(true); - - place_train(*train); - - return train; - } +Train *Engineer::add_train(const LocoType &type, unsigned addr) +{ + Locomotive *loco=new Locomotive(type, control, addr); + Train *train=new Train(*trfc_mgr, *loco); + train->set_name(format("Train %d", trfc_mgr->get_trains().size())); + + TrainPanel *tpanel=new TrainPanel(*this, ui_res, *train); + root->add(*tpanel); + int y=main_panel->get_geometry().y; + for(list::iterator i=train_panels.begin(); i!=train_panels.end(); ++i) + y-=(*i)->get_geometry().h; + tpanel->set_position(0, y-tpanel->get_geometry().h); + train_panels.push_back(tpanel); + tpanel->set_visible(true); + + place_train(*train); + + return train; } void Engineer::place_train(Train &train) diff --git a/source/engineer/engineer.h b/source/engineer/engineer.h index 3552bad..f6e23bc 100644 --- a/source/engineer/engineer.h +++ b/source/engineer/engineer.h @@ -8,6 +8,7 @@ #include #include "libmarklin/catalogue.h" #include "libmarklin/control.h" +#include "libmarklin/locotype.h" #include "libmarklin/trafficmanager.h" #include "libmarklin/train.h" #include "3d/layout.h" @@ -48,8 +49,10 @@ public: Engineer(int argc, char **argv); ~Engineer(); + const Marklin::Catalogue &get_catalogue() const { return catalogue; } Marklin::Control &get_control() { return control; } - Marklin::Train *add_train(unsigned); + void add_train(); + Marklin::Train *add_train(const Marklin::LocoType &, unsigned); void place_train(Marklin::Train &); int main(); void quit() { exit(0); } diff --git a/source/engineer/mainpanel.cpp b/source/engineer/mainpanel.cpp index c89060a..7866a1c 100644 --- a/source/engineer/mainpanel.cpp +++ b/source/engineer/mainpanel.cpp @@ -71,7 +71,7 @@ void MainPanel::power_off() void MainPanel::new_loc() { - engineer.add_train(0); + engineer.add_train(); } void MainPanel::quit() diff --git a/source/engineer/trainpanel.cpp b/source/engineer/trainpanel.cpp index cd41c23..8c23f26 100644 --- a/source/engineer/trainpanel.cpp +++ b/source/engineer/trainpanel.cpp @@ -13,7 +13,7 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t): engineer(e), train(t) { - set_size(200, 131); + set_size(200, 172); add(*(lbl_addr=new GLtk::Label(res, format("%2d", train.get_locomotive().get_address())))); lbl_addr->set_style("digital"); @@ -35,13 +35,31 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t): lbl_speed->set_geometry(GLtk::Geometry(10, geom.h-63, 35, 24)); train.get_locomotive().signal_speed_changed.connect(sigc::mem_fun(this, &TrainPanel::loco_speed_changed)); + GLtk::Button *btn; + + const map &funcs=train.get_locomotive().get_type().get_functions(); + unsigned x=10; + for(map::const_iterator i=funcs.begin(); i!=funcs.end(); ++i, x+=40) + { + string fname=i->second; + fname[0]=toupper(fname[0]); + add(*(btn=new GLtk::Button(res, fname))); + btn->set_geometry(GLtk::Geometry(x, 68, 40, 24)); + btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(this, &TrainPanel::func_clicked), i->first)); + + GLtk::Indicator *ind=new GLtk::Indicator(res); + add(*ind); + ind->set_geometry(GLtk::Geometry(x, 92, 40, 12)); + ind->set_active(train.get_locomotive().get_function(i->first)); + ind_funcs[i->first]=ind; + } + train.get_locomotive().signal_function_changed.connect(sigc::mem_fun(this, &TrainPanel::loco_function_changed)); + add(*(lbl_status=new GLtk::Label(res, train.get_status()))); lbl_status->set_style("digital"); - lbl_status->set_geometry(GLtk::Geometry(10, geom.h-92, geom.w-20, 24)); + lbl_status->set_geometry(GLtk::Geometry(10, 39, geom.w-20, 24)); train.signal_status_changed.connect(sigc::mem_fun(this, &TrainPanel::train_status_changed)); - GLtk::Button *btn; - add(*(btn=new GLtk::Button(res, "Edit"))); btn->set_geometry(GLtk::Geometry(geom.w-50, 10, 40, 24)); @@ -60,6 +78,13 @@ void TrainPanel::loco_speed_changed(unsigned speed) lbl_speed->set_text(format("%2d", speed)); } +void TrainPanel::loco_function_changed(unsigned func, bool value) +{ + map::iterator i=ind_funcs.find(func); + if(i!=ind_funcs.end()) + i->second->set_active(value); +} + void TrainPanel::train_status_changed(const string &s) { lbl_status->set_text(s); @@ -69,3 +94,8 @@ void TrainPanel::place_clicked() { engineer.place_train(train); } + +void TrainPanel::func_clicked(unsigned func) +{ + train.get_locomotive().set_function(func, !train.get_locomotive().get_function(func)); +} diff --git a/source/engineer/trainpanel.h b/source/engineer/trainpanel.h index 87e17c9..63e6e73 100644 --- a/source/engineer/trainpanel.h +++ b/source/engineer/trainpanel.h @@ -2,6 +2,7 @@ #define TRAINPANEL_H_ #include +#include #include #include #include "libmarklin/train.h" @@ -16,17 +17,19 @@ private: Msp::GLtk::Label *lbl_addr; Msp::GLtk::Label *lbl_name; Msp::GLtk::HSlider *sld_speed; - Marklin::Locomotive *loco; Msp::GLtk::Label *lbl_speed; Msp::GLtk::Label *lbl_status; + std::map ind_funcs; public: TrainPanel(Engineer &, const Msp::GLtk::Resources &, Marklin::Train &); private: void speed_slider_changed(double); void loco_speed_changed(unsigned); + void loco_function_changed(unsigned, bool); void train_status_changed(const std::string &); void place_clicked(); + void func_clicked(unsigned); }; #endif diff --git a/source/engineer/trainproperties.cpp b/source/engineer/trainproperties.cpp index 1a918ad..36f9325 100644 --- a/source/engineer/trainproperties.cpp +++ b/source/engineer/trainproperties.cpp @@ -1,8 +1,10 @@ #include +#include #include #include "engineer.h" #include "trainproperties.h" +using namespace std; using namespace Msp; using namespace Marklin; @@ -16,6 +18,13 @@ TrainProperties::TrainProperties(Engineer &e, GLtk::Resources &r, Train *t): add(*(ent_addr=new GLtk::Entry(res))); ent_addr->set_geometry(GLtk::Geometry(10, geom.h-30, 40, 20)); + add(*(drp_type=new GLtk::Dropdown(res))); + drp_type->set_geometry(GLtk::Geometry(60, geom.h-30, geom.w-70, 20)); + + const map &locos=engineer.get_catalogue().get_locomotives(); + for(map::const_iterator i=locos.begin(); i!=locos.end(); ++i) + drp_type->append(format("%d %s", i->second->get_article_number(), i->second->get_name())); + add(*(ent_name=new GLtk::Entry(res, "Train"))); ent_name->set_geometry(GLtk::Geometry(10, geom.h-55, geom.w-20, 20)); @@ -29,17 +38,23 @@ TrainProperties::TrainProperties(Engineer &e, GLtk::Resources &r, Train *t): add(*(btn=new GLtk::Button(res, "Cncl"))); btn->set_style("red"); btn->set_geometry(GLtk::Geometry(geom.w-80, 10, 30, 25)); + btn->signal_clicked.connect(sigc::mem_fun(this, &TrainProperties::cancel_clicked)); } void TrainProperties::ok_clicked() { - if(train) - { - } - else + if(!train) { - train=engineer.add_train(lexical_cast(ent_addr->get_text())); - train->set_name(ent_name->get_text()); + const map &locos=engineer.get_catalogue().get_locomotives(); + map::const_iterator i=locos.begin(); + advance(i, drp_type->get_selected_index()); + train=engineer.add_train(*i->second, lexical_cast(ent_addr->get_text())); } + + train->set_name(ent_name->get_text()); signal_ok.emit(); } + +void TrainProperties::cancel_clicked() +{ +} diff --git a/source/engineer/trainproperties.h b/source/engineer/trainproperties.h index 5d24613..20ab334 100644 --- a/source/engineer/trainproperties.h +++ b/source/engineer/trainproperties.h @@ -1,6 +1,7 @@ #ifndef TRAINPROPERTIES_H_ #define TRAINPROPERTIES_H_ +#include #include #include #include @@ -13,6 +14,7 @@ private: Engineer &engineer; Marklin::Train *train; Msp::GLtk::Entry *ent_addr; + Msp::GLtk::Dropdown *drp_type; Msp::GLtk::Entry *ent_name; public: @@ -21,6 +23,7 @@ public: TrainProperties(Engineer &, Msp::GLtk::Resources &, Marklin::Train *); private: void ok_clicked(); + void cancel_clicked(); }; #endif diff --git a/source/libmarklin/catalogue.cpp b/source/libmarklin/catalogue.cpp index 00c2773..3ab96a9 100644 --- a/source/libmarklin/catalogue.cpp +++ b/source/libmarklin/catalogue.cpp @@ -1,6 +1,7 @@ #include #include #include "catalogue.h" +#include "locotype.h" #include "tracktype.h" using namespace std; @@ -14,7 +15,7 @@ Catalogue::~Catalogue() delete i->second; } -TrackType &Catalogue::get_track(unsigned art_nr) +TrackType &Catalogue::get_track(unsigned art_nr) const { map::const_iterator i=tracks.find(art_nr); if(i==tracks.end()) @@ -23,6 +24,15 @@ TrackType &Catalogue::get_track(unsigned art_nr) return *i->second; } +LocoType &Catalogue::get_locomotive(unsigned art_nr) const +{ + map::const_iterator i=locos.find(art_nr); + if(i==locos.end()) + throw KeyError("Unknown locomotive type"); + + return *i->second; +} + void Catalogue::load(const string &fn) { IO::File in(fn.c_str()); @@ -36,9 +46,22 @@ void Catalogue::load(const string &fn) Catalogue::Loader::Loader(Catalogue &c): cat(c) { + add("locomotive", &Loader::locomotive); add("track", &Loader::track); } +void Catalogue::Loader::locomotive(unsigned art_no) +{ + map::iterator i=cat.locos.find(art_no); + if(i!=cat.locos.end()) + throw Exception("Duplicate locomotive number"); + + RefPtr loco=new LocoType(art_no); + load_sub(*loco); + unsigned art_nr=loco->get_article_number(); + cat.locos[art_nr]=loco.release(); +} + void Catalogue::Loader::track(unsigned art_no) { map::iterator i=cat.tracks.find(art_no); @@ -48,7 +71,7 @@ void Catalogue::Loader::track(unsigned art_no) RefPtr trk=new TrackType(art_no); load_sub(*trk); unsigned art_nr=trk->get_article_number(); - cat.tracks.insert(map::value_type(art_nr, trk.release())); + cat.tracks[art_nr]=trk.release(); } } // namespace Marklin diff --git a/source/libmarklin/catalogue.h b/source/libmarklin/catalogue.h index 66e3466..4179ea7 100644 --- a/source/libmarklin/catalogue.h +++ b/source/libmarklin/catalogue.h @@ -6,6 +6,7 @@ namespace Marklin { +class LocoType; class TrackType; class Catalogue @@ -18,17 +19,21 @@ public: private: Catalogue &cat; + void locomotive(unsigned); void track(unsigned); }; private: std::map tracks; + std::map locos; public: ~Catalogue(); - TrackType &get_track(unsigned); + TrackType &get_track(unsigned) const; const std::map &get_tracks() const { return tracks; } + LocoType &get_locomotive(unsigned) const; + const std::map &get_locomotives() const { return locos; } void load(const std::string &); }; diff --git a/source/libmarklin/locomotive.cpp b/source/libmarklin/locomotive.cpp index 0de0110..530a111 100644 --- a/source/libmarklin/locomotive.cpp +++ b/source/libmarklin/locomotive.cpp @@ -10,7 +10,8 @@ using namespace Msp; namespace Marklin { -Locomotive::Locomotive(Control &c, unsigned a): +Locomotive::Locomotive(const LocoType &t, Control &c, unsigned a): + type(t), control(c), addr(a), speed(0), @@ -56,6 +57,8 @@ void Locomotive::set_function(unsigned func, bool state) funcs&=~(1<>i)&1); } } diff --git a/source/libmarklin/locomotive.h b/source/libmarklin/locomotive.h index eae99f5..a127a17 100644 --- a/source/libmarklin/locomotive.h +++ b/source/libmarklin/locomotive.h @@ -9,10 +9,12 @@ namespace Marklin { class Control; +class LocoType; class Locomotive { private: + const LocoType &type; Control &control; unsigned addr; unsigned speed; @@ -21,9 +23,11 @@ private: public: sigc::signal signal_speed_changed; + sigc::signal signal_function_changed; - Locomotive(Control &, unsigned); + Locomotive(const LocoType &, Control &, unsigned); + const LocoType &get_type() const { return type; } void set_speed(unsigned); void set_reverse(bool); void set_function(unsigned, bool); diff --git a/source/libmarklin/locotype.cpp b/source/libmarklin/locotype.cpp new file mode 100644 index 0000000..31a995a --- /dev/null +++ b/source/libmarklin/locotype.cpp @@ -0,0 +1,24 @@ +#include "locotype.h" + +using namespace std; + +namespace Marklin { + +LocoType::LocoType(unsigned an): + art_nr(an) +{ } + + +LocoType::Loader::Loader(LocoType <): + ltype(lt) +{ + add("function", &Loader::function); + add("name", &LocoType::name); +} + +void LocoType::Loader::function(unsigned i, const string &f) +{ + ltype.funcs[i]=f; +} + +} // namespace Marklin diff --git a/source/libmarklin/locotype.h b/source/libmarklin/locotype.h new file mode 100644 index 0000000..bce5c57 --- /dev/null +++ b/source/libmarklin/locotype.h @@ -0,0 +1,37 @@ +#ifndef LIBMARKLIN_LOCOTYPE_H_ +#define LIBMARKLIN_LOCOTYPE_H_ + +#include + +namespace Marklin { + +class LocoType +{ +public: + class Loader: public Msp::DataFile::Loader + { + private: + LocoType <ype; + + public: + Loader(LocoType &); + LocoType &get_object() const { return ltype; } + private: + void function(unsigned, const std::string &); + }; + +private: + unsigned art_nr; + std::string name; + std::map funcs; + +public: + LocoType(unsigned); + unsigned get_article_number() const { return art_nr; } + const std::string &get_name() const { return name; } + const std::map &get_functions() const { return funcs; } +}; + +} // namespace Marklin + +#endif