]> git.tdb.fi Git - r2c2.git/blobdiff - source/designer/designer.cpp
Add an internal layout to Catalogue for selecting tracks
[r2c2.git] / source / designer / designer.cpp
index a28811f74fb254f3fa10446b8be5e7213a01ecf4..02563f808edef83585cb8c2055ac3717cebdaf97 100644 (file)
@@ -8,6 +8,7 @@ Distributed under the GPL
 #include <signal.h>
 #include <cmath>
 #include <GL/gl.h>
+#include <msp/gl/blend.h>
 #include <msp/gl/matrix.h>
 #include <msp/gl/misc.h>
 #include <msp/gl/projection.h>
@@ -38,11 +39,12 @@ using namespace Msp;
 Application::RegApp<Designer> Designer::reg;
 
 Designer::Designer(int argc, char **argv):
-       screen_w(1280),
-       screen_h(960),
+       window(1280, 960),
        base_object(0),
        cur_route(0),
        mode(SELECT),
+       manipulator(*this, selection),
+       measure(*this),
        input(0),
        cam_yaw(M_PI/2),
        cam_pitch(-M_PI/4),
@@ -54,24 +56,22 @@ Designer::Designer(int argc, char **argv):
        rotate(0),
        pitch(0)
 {
+       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));
+       measure.signal_changed.connect(sigc::mem_fun(this, &Designer::measure_changed));
+       measure.signal_done.connect(sigc::mem_fun(this, &Designer::measure_done));
+
+       // Setup catalogue and layout
        DataFile::load(catalogue, "tracks.dat");
 
-       cat_layout = new Layout(catalogue);
-       cat_layout_3d = new Layout3D(*cat_layout);
-
-       const map<unsigned, TrackType *> &ctracks = catalogue.get_tracks();
-       unsigned n = 0;
-       for(map<unsigned, TrackType *>::const_iterator i=ctracks.begin(); i!=ctracks.end(); ++i, ++n)
-       {
-               Track *track = new Track(*i->second);
-               track->set_position(Point((n%11)*0.1-0.5, 0.2-n/11*0.3, 0));
-               track->set_rotation(M_PI/2);
-               cat_layout->add_track(*track);
-       }
-
-       manipulator = new Manipulator(*this);
-       manipulator->signal_status.connect(sigc::mem_fun(this, &Designer::manipulation_status));
-       manipulator->signal_done.connect(sigc::mem_fun(this, &Designer::manipulation_done));
+       cat_layout_3d = new Layout3D(catalogue.get_layout());
 
        layout = new Layout(catalogue);
        layout_3d = new Layout3D(*layout);
@@ -91,42 +91,13 @@ Designer::Designer(int argc, char **argv):
                }
        }
 
-       selection = new Selection;
-       manipulator->set_selection(selection);
-
-       measure = new Measure(*this);
-       measure->signal_changed.connect(sigc::mem_fun(this, &Designer::measure_changed));
-       measure->signal_done.connect(sigc::mem_fun(this, &Designer::measure_done));
-}
-
-Designer::~Designer()
-{
-       delete manipulator;
-       delete selection;
-       delete layout;
-       delete layout_3d;
-       delete cat_layout;
-       delete cat_layout_3d;
-       delete measure;
-}
-
-int Designer::main()
-{
-       dpy = new Graphics::Display;
-       wnd = new Graphics::Window(*dpy, screen_w, screen_h);
-       glc = new Graphics::GLContext(*wnd);
-       wnd->set_title("Railway Designer");
-
-       wnd->signal_close.connect(sigc::bind(sigc::mem_fun(this, &Designer::exit), 0));
-       wnd->show();
-
-       glEnableClientState(GL_VERTEX_ARRAY);
-       glEnable(GL_DEPTH_TEST);
-       glEnable(GL_BLEND);
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glEnable(GL_CULL_FACE);
+       // Setup OpenGL
+       GL::enable(GL::DEPTH_TEST);
+       GL::enable(GL::BLEND);
+       GL::blend_func(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA);
+       GL::enable(GL_CULL_FACE);
 
-       pipeline = new GL::Pipeline(screen_w, screen_h, false);
+       pipeline = new GL::Pipeline(window.get_width(), window.get_height(), false);
        pipeline->add_renderable(layout_3d->get_scene());
        if(base_object)
                pipeline->add_renderable(*base_object);
@@ -137,8 +108,9 @@ int Designer::main()
        GL::PipelinePass *pass = &pipeline->add_pass(GL::Tag());
        pass->lighting = &lighting;
 
+       // Setup UI
        DataFile::load(ui_res, "marklin.res");
-       root = new GLtk::Root(ui_res, *wnd);
+       root = new GLtk::Root(ui_res, window);
 
        lbl_tooltip = new GLtk::Label(ui_res);
        lbl_tooltip->set_style("tooltip");
@@ -147,26 +119,25 @@ int Designer::main()
 
        toolbar = new Toolbar(*this);
        root->add(*toolbar);
-       toolbar->set_position(0, screen_h-toolbar->get_geometry().h);
+       toolbar->set_position(0, window.get_height()-toolbar->get_geometry().h);
        toolbar->set_visible(true);
+}
 
+Designer::~Designer()
+{
+       delete root;
+       delete layout;
+       delete layout_3d;
+       delete cat_layout_3d;
+}
 
-       wnd->signal_key_press.connect(sigc::mem_fun(this, &Designer::key_press));
-       wnd->signal_key_release.connect(sigc::mem_fun(this, &Designer::key_release));
-       wnd->signal_button_press.connect(sigc::mem_fun(this, &Designer::button_press));
-       wnd->signal_pointer_motion.connect(sigc::mem_fun(this, &Designer::pointer_motion));
+int Designer::main()
+{
+       window.show();
 
        mode = SELECT;
 
-       Application::main();
-
-       delete root;
-
-       delete glc;
-       delete wnd;
-       delete dpy;
-
-       return exit_code;
+       return Application::main();
 }
 
 void Designer::save()
@@ -194,7 +165,7 @@ void Designer::add_selection_to_route()
 
        try
        {
-               const set<Track *> &stracks = selection->get_tracks();
+               const set<Track *> &stracks = selection.get_tracks();
                set<const Track *> tracks(stracks.begin(), stracks.end());
                cur_route->add_tracks(tracks);
        }
@@ -218,8 +189,8 @@ void Designer::map_pointer_coords(int x, int y, float &gx, float &gy)
        float uy = sin_yaw*-sin_pitch*0.41421;
        float uz = cos_pitch*0.41421;
 
-       float xf = static_cast<float>(x)*2/screen_w-1;
-       float yf = static_cast<float>(y)*2/screen_h-1;
+       float xf = static_cast<float>(x)*2/window.get_width()-1;
+       float yf = static_cast<float>(y)*2/window.get_height()-1;
 
        float vx = cos_yaw*cos_pitch + xf*rx + yf*ux;
        float vy = sin_yaw*cos_pitch + xf*ry + yf*uy;
@@ -235,7 +206,7 @@ void Designer::tick()
        float dt = (t-last_tick)/Msp::Time::sec;
        last_tick = t;
 
-       dpy->tick();
+       window.get_display().tick();
 
        if(move_y)
        {
@@ -312,7 +283,7 @@ void Designer::tick()
 
        render();
 
-       glc->swap_buffers();
+       window.swap_buffers();
 }
 
 void Designer::key_press(unsigned code, unsigned mod, wchar_t)
@@ -329,24 +300,24 @@ void Designer::key_press(unsigned code, unsigned mod, wchar_t)
                mode = CATALOGUE;
        else if(key==Msp::Input::KEY_G)
        {
-               manipulator->start_move();
+               manipulator.start_move();
                mode = MANIPULATE;
        }
        else if(key==Msp::Input::KEY_R)
        {
-               manipulator->start_rotate();
+               manipulator.start_rotate();
                mode = MANIPULATE;
        }
        else if(key==Msp::Input::KEY_D)
        {
-               manipulator->duplicate();
-               manipulator->start_move();
+               manipulator.duplicate();
+               manipulator.start_move();
                mode = MANIPULATE;
        }
        else if(key==Msp::Input::KEY_W)
                save();
        else if(key==Msp::Input::KEY_PLUS)
-               selection->select_more();
+               selection.select_more();
        else if(key==Msp::Input::KEY_L && (mod&1))
        {
                const set<Track *> &tracks = layout->get_tracks();
@@ -356,30 +327,30 @@ void Designer::key_press(unsigned code, unsigned mod, wchar_t)
                IO::print("Total length: %.1fm\n", len);
        }
        else if(key==Msp::Input::KEY_L)
-               selection->select_linked();
+               selection.select_linked();
        else if(key==Msp::Input::KEY_M)
        {
-               measure->start();
+               measure.start();
                mode = MEASURE;
        }
        else if(key==Msp::Input::KEY_Z)
        {
-               manipulator->start_elevate();
+               manipulator.start_elevate();
                mode = MANIPULATE;
        }
        else if(key==Msp::Input::KEY_ESC)
        {
                if(mode==MANIPULATE)
-                       manipulator->cancel();
+                       manipulator.cancel();
                else if(mode==CATALOGUE)
                        mode = SELECT;
                else
-                       selection->clear();
+                       selection.clear();
        }
        else if(key==Msp::Input::KEY_X)
        {
-               set<Track *> tracks = selection->get_tracks();
-               selection->clear();
+               set<Track *> tracks = selection.get_tracks();
+               selection.clear();
                for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                {
                        layout->remove_track(**i);
@@ -388,7 +359,7 @@ void Designer::key_press(unsigned code, unsigned mod, wchar_t)
        }
        else if(key==Msp::Input::KEY_F && (mod&1))
        {
-               const set<Track *> &tracks = selection->get_tracks();
+               const set<Track *> &tracks = selection.get_tracks();
                const set<Track *> &ltracks = layout->get_tracks();
                for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
                {
@@ -402,15 +373,15 @@ void Designer::key_press(unsigned code, unsigned mod, wchar_t)
                }
        }
        else if(key==Msp::Input::KEY_F)
-               manipulator->flatten();
+               manipulator.flatten();
        else if(key==Msp::Input::KEY_E && (mod&1))
-               manipulator->even_slope(true);
+               manipulator.even_slope(true);
        else if(key==Msp::Input::KEY_E)
-               manipulator->even_slope();
+               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)
+               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));
@@ -420,7 +391,7 @@ void Designer::key_press(unsigned code, unsigned mod, wchar_t)
        }
        else if(key==Msp::Input::KEY_S)
        {
-               const set<Track *> &tracks = selection->get_tracks();
+               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)
@@ -490,7 +461,7 @@ void Designer::key_release(unsigned code, unsigned)
 
 void Designer::button_press(int x, int y, unsigned btn, unsigned)
 {
-       y = screen_h-y-1;
+       y = window.get_height()-y-1;
 
        float gx, gy;
        map_pointer_coords(x, y, gx, gy);
@@ -506,8 +477,8 @@ void Designer::button_press(int x, int y, unsigned btn, unsigned)
                                track->set_position(Point(gx, gy, 0));
                                layout->add_track(*track);
 
-                               selection->clear();
-                               selection->add_track(track);
+                               selection.clear();
+                               selection.add_track(track);
 
                                mode = SELECT;
                        }
@@ -523,20 +494,20 @@ void Designer::button_press(int x, int y, unsigned btn, unsigned)
                        if(track)
                        {
                                if(!shift)
-                                       selection->clear();
-                               selection->toggle_track(&track->get_track());
+                                       selection.clear();
+                               selection.toggle_track(&track->get_track());
                        }
                }
        }
        else if(mode==MANIPULATE)
-               manipulator->button_press(x, y, gx, gy, btn);
+               manipulator.button_press(x, y, gx, gy, btn);
        else if(mode==MEASURE)
-               measure->button_press(x, y, gx, gy, btn);
+               measure.button_press(x, y, gx, gy, btn);
 }
 
 void Designer::pointer_motion(int x, int y)
 {
-       y = screen_h-y-1;
+       y = window.get_height()-y-1;
 
        pointer_x = x;
        pointer_y = y;
@@ -550,8 +521,8 @@ void Designer::pointer_motion(int x, int y)
        {
                float gx, gy;
                map_pointer_coords(x, y, gx, gy);
-               manipulator->pointer_motion(x, y, gx, gy);
-               measure->pointer_motion(x, y, gx, gy);
+               manipulator.pointer_motion(x, y, gx, gy);
+               measure.pointer_motion(x, y, gx, gy);
        }
 }
 
@@ -609,14 +580,14 @@ void Designer::render()
                        }
                }*/
 
-               manipulator->render();
+               manipulator.render();
                if(mode==MEASURE)
-                       measure->render();
+                       measure.render();
        }
 
        GL::matrix_mode(GL::PROJECTION);
        GL::load_identity();
-       GL::ortho_bottomleft(screen_w, screen_h);
+       GL::ortho_bottomleft(window.get_width(), window.get_height());
        GL::matrix_mode(GL::MODELVIEW);
        GL::load_identity();
 
@@ -631,9 +602,9 @@ Track3D *Designer::pick_track(int x, int y)
        if(mode==CATALOGUE)
                l = cat_layout_3d;
 
-       float xx = (static_cast<float>(x-static_cast<int>(screen_w)/2)/screen_h)*0.82843;
-       float yy = (static_cast<float>(y)/screen_h-0.5)*0.82843;
-       float size = 4.0/screen_h*0.82843;
+       float xx = ((float(x)-window.get_width()/2)/window.get_height())*0.82843;
+       float yy = (float(y)/window.get_height()-0.5)*0.82843;
+       float size = 4.0/window.get_height()*0.82843;
 
        project_3d();
        apply_camera();
@@ -670,10 +641,10 @@ void Designer::manipulation_done(bool)
 
 void Designer::measure_changed()
 {
-       float pard = measure->get_parallel_distance()*1000;
-       float perpd = measure->get_perpendicular_distance()*1000;
+       float pard = measure.get_parallel_distance()*1000;
+       float perpd = measure.get_perpendicular_distance()*1000;
        float d = sqrt(pard*pard+perpd*perpd);
-       float adiff = measure->get_angle_difference()*180/M_PI;
+       float adiff = measure.get_angle_difference()*180/M_PI;
        string info = format("Par %.1fmm - Perp %.1fmm - Total %.1fmm - Angle %.1f°", pard, perpd, d, adiff);
        set_tooltip(pointer_x, pointer_y, info);
 }
@@ -688,8 +659,8 @@ void Designer::set_tooltip(int x, int y, const std::string &text)
        int fontsize = ui_res.get_default_font().get_default_size();
        int h = fontsize+6;
        int w = static_cast<int>(ui_res.get_default_font().get_string_width(text)*fontsize)+6;
-       x = max(min(static_cast<int>(screen_w)-w, x), 0);
-       y = max(min(static_cast<int>(screen_h)-h, y), 0);
+       x = max(min(static_cast<int>(window.get_width())-w, x), 0);
+       y = max(min(static_cast<int>(window.get_height())-h, y), 0);
        lbl_tooltip->set_text(text);
        lbl_tooltip->set_geometry(GLtk::Geometry(x, y, w, h));
        lbl_tooltip->set_visible(true);
@@ -709,7 +680,7 @@ void Designer::save_accept()
 
 void Designer::turnout_id_accept()
 {
-       Track *track = selection->get_track();
+       Track *track = selection.get_track();
        unsigned id = lexical_cast<unsigned>(input->get_text());
        track->set_turnout_id(id);
 
@@ -720,7 +691,7 @@ void Designer::turnout_id_accept()
 
 void Designer::sensor_id_accept()
 {
-       const set<Track *> &tracks = selection->get_tracks();
+       const set<Track *> &tracks = selection.get_tracks();
        unsigned id = lexical_cast<unsigned>(input->get_text());
        for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {