From: Mikko Rasa Date: Sat, 24 Aug 2013 13:59:47 +0000 (+0300) Subject: Turn object selection into a tool X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=a882f35842c819e011c5fdf6104852c2b6ab3eef;p=r2c2.git Turn object selection into a tool --- diff --git a/source/designer/designer.cpp b/source/designer/designer.cpp index 7c100db..1df759b 100644 --- a/source/designer/designer.cpp +++ b/source/designer/designer.cpp @@ -28,6 +28,7 @@ #include "manipulator.h" #include "measure.h" #include "movetool.h" +#include "objectselecttool.h" #include "rotatetool.h" #include "routebar.h" #include "selection.h" @@ -51,15 +52,13 @@ Designer::Designer(int argc, char **argv): base_object(0), cur_route(0), cur_zone(0), - mode(SELECT), + mode(TOOL), sel_wrap(selection), cur_tool(0) { window.set_title("Railway Designer"); window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Designer::exit), 0)); - selection.signal_changed.connect(sigc::mem_fun(this, &Designer::selection_changed)); - // Setup catalogue and layout DataFile::load(catalogue, "tracks.dat"); @@ -172,7 +171,7 @@ int Designer::main() { window.show(); - mode = SELECT; + use_select_tool(); return Application::main(); } @@ -192,8 +191,7 @@ void Designer::quit() void Designer::new_track() { - if(mode!=SELECT) - return; + use_select_tool(); mode = CATALOGUE; lbl_status->set_text("Select new track or press Esc to cancel"); @@ -201,8 +199,7 @@ void Designer::new_track() void Designer::erase_tracks() { - if(mode!=SELECT) - return; + use_select_tool(); set tracks = selection.get_objects(); selection.clear(); @@ -215,7 +212,8 @@ void Designer::erase_tracks() void Designer::track_properties() { - if(mode!=SELECT || selection.empty()) + use_select_tool(); + if(selection.empty()) return; TrackProperties *track_prop = new TrackProperties(selection); @@ -260,7 +258,8 @@ void Designer::edit_route(Route *r) void Designer::rename_route() { - if(mode!=SELECT || !cur_route) + use_select_tool(); + if(!cur_route) return; InputDialog *input = new InputDialog(*this, "Route name", cur_route->get_name()); @@ -342,9 +341,7 @@ void Designer::tick() if(cur_tool && cur_tool->is_done()) { cur_tool->update_selection(selection); - delete cur_tool; - cur_tool = 0; - mode = SELECT; + use_select_tool(); } window.tick(); @@ -386,12 +383,6 @@ void Designer::key_press(unsigned key) } else if(key==Msp::Input::KEY_W) save(); - else if(key==Msp::Input::KEY_PLUS) - selection.select_more(); - else if(key==Msp::Input::KEY_L && shift) - selection.select_blocks(); - else if(key==Msp::Input::KEY_L) - selection.select_linked(); else if(key==Msp::Input::KEY_M) use_tool(); else if(key==Msp::Input::KEY_Z) @@ -399,9 +390,7 @@ void Designer::key_press(unsigned key) else if(key==Msp::Input::KEY_ESC) { if(mode==CATALOGUE) - mode = SELECT; - else if(mode==SELECT) - selection.clear(); + use_select_tool(); } else if(key==Msp::Input::KEY_X) erase_tracks(); @@ -471,44 +460,33 @@ void Designer::use_tool(Tool *tool) mode = TOOL; } -void Designer::button_press(unsigned btn) +void Designer::use_select_tool() { - bool shift = keyboard.get_button_state(Input::KEY_SHIFT_L) || keyboard.get_button_state(Input::KEY_SHIFT_R); + use_tool(new ObjectSelectTool(*this, keyboard, mouse, selection)); +} +void Designer::button_press(unsigned btn) +{ Vector pointer(mouse.get_axis_value(0), mouse.get_axis_value(1), 0); Vector ground = map_pointer_to_ground(pointer); if(mode==CATALOGUE) { + Object *obj; if(btn==1) - { - Object *cobj = pick_object(pointer); - if(cobj) - { - Object *obj = cobj->clone(layout); - obj->set_position(ground); - - selection.clear(); - selection.add_object(obj); + obj = pick_object(pointer); - mode = SELECT; - } - } - else - mode = SELECT; - } - else if(mode==SELECT) - { - if(btn==1) + if(obj) { - Object *obj = pick_object(pointer); - if(obj) - { - if(!shift) - selection.clear(); - selection.toggle_object(obj); - } + obj = obj->clone(layout); + obj->set_position(ground); + + selection.clear(); + selection.add_object(obj); } + + if(obj || btn==3) + use_select_tool(); } } @@ -553,20 +531,6 @@ void Designer::update_track_icon(Track3D &track) } } -void Designer::selection_changed() -{ - const set &tracks = selection.get_objects(); - if(tracks.empty()) - lbl_status->set_text(string()); - else - { - float len = 0; - for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) - len += (*i)->get_type().get_total_length(); - lbl_status->set_text(format("%.2fm of track selected\n", len)); - } -} - void Designer::tool_status(const string &status) { lbl_status->set_text(status); diff --git a/source/designer/designer.h b/source/designer/designer.h index f89355c..dcaa146 100644 --- a/source/designer/designer.h +++ b/source/designer/designer.h @@ -34,7 +34,6 @@ class Designer: public Msp::RegisteredApplication private: enum Mode { - SELECT, CATALOGUE, TOOL }; @@ -82,6 +81,7 @@ public: const R2C2::Catalogue &get_catalogue() const { return catalogue; } R2C2::Layout &get_layout() { return *layout; } R2C2::Layout3D &get_layout_3d() { return *layout_3d; } + const R2C2::View3D &get_view() const { return *main_view; } const CameraController &get_camera_controller() const { return *camera_ctl; } void new_track(); @@ -111,12 +111,12 @@ private: template T *use_tool(); void use_tool(Tool *); + void use_select_tool(); void button_press(unsigned); void apply_camera(); void render(); R2C2::Object *pick_object(const R2C2::Vector &); void update_track_icon(R2C2::Track3D &); - void selection_changed(); void tool_status(const std::string &); void track_properties_response(int); void route_name_accept(const std::string &); diff --git a/source/designer/objectselecttool.cpp b/source/designer/objectselecttool.cpp new file mode 100644 index 0000000..b967c88 --- /dev/null +++ b/source/designer/objectselecttool.cpp @@ -0,0 +1,86 @@ +#include +#include +#include "designer.h" +#include "objectselecttool.h" + +using namespace std; +using namespace Msp; +using namespace R2C2; + +ObjectSelectTool::ObjectSelectTool(Designer &d, Input::Keyboard &k, Input::Mouse &m, Selection &s): + Tool(d, k, m), + selection(s) +{ + update_status(); +} + +void ObjectSelectTool::key_press(unsigned key) +{ + if(key==Input::KEY_ESC) + selection.clear(); + else if(key==Msp::Input::KEY_PLUS) + selection.select_more(); + else if(key==Msp::Input::KEY_L && shift_held) + selection.select_blocks(); + else if(key==Msp::Input::KEY_L) + selection.select_linked(); + else + return Tool::key_press(key); + + update_status(); +} + +void ObjectSelectTool::button_press(unsigned btn) +{ + if(btn==1) + { + Ray ray = designer.get_view().create_ray(pointer.x, pointer.y); + Object *obj = designer.get_layout().pick(ray); + if(obj) + { + if(!shift_held) + selection.clear(); + selection.toggle_object(obj); + + update_status(); + } + } +} + +void ObjectSelectTool::update_status() +{ + const set &objects = selection.get_objects(); + float track_length = 0; + unsigned other_count = 0; + for(set::const_iterator i=objects.begin(); i!=objects.end(); ++i) + { + if(Track *track = dynamic_cast(*i)) + track_length += track->get_type().get_total_length(); + else + ++other_count; + } + + if(!track_length && !other_count) + set_status(string()); + else + { + string s; + if(track_length) + { + s += format("%.2fm of track", track_length); + if(other_count) + s += " and "; + } + if(other_count) + { + s += lexical_cast(other_count); + if(track_length) + s += " other"; + s += " object"; + if(other_count>1) + s += 's'; + } + s += " selected"; + set_status(s); + } +} diff --git a/source/designer/objectselecttool.h b/source/designer/objectselecttool.h new file mode 100644 index 0000000..1f40a03 --- /dev/null +++ b/source/designer/objectselecttool.h @@ -0,0 +1,21 @@ +#ifndef OBJECTSELECTTOOL_H_ +#define OBJECTSELECTTOOL_H_ + +#include "tool.h" + +class ObjectSelectTool: public Tool +{ +private: + Selection &selection; + +public: + ObjectSelectTool(Designer &, Msp::Input::Keyboard &, Msp::Input::Mouse &, Selection &); + +private: + virtual void key_press(unsigned); + virtual void button_press(unsigned); + + void update_status(); +}; + +#endif