]> git.tdb.fi Git - r2c2.git/blob - source/remote/remote.cpp
Add a new remote control program with GLtk-based UI
[r2c2.git] / source / remote / remote.cpp
1 #include <msp/gl/framebuffer.h>
2 #include <msp/gltk/layout.h>
3 #include <msp/time/utils.h>
4 #include "connectdialog.h"
5 #include "remote.h"
6
7 using namespace std;
8 using namespace Msp;
9 using namespace R2C2;
10
11 Remote::Remote(int, char **):
12         window(1024, 768),
13         client(catalogue),
14         ui_resources("data/r2c2.res"),
15         root(ui_resources, window),
16         root_layout(new GLtk::Layout),
17         status_bar(client)
18 {
19         window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Remote::exit), 0));
20
21         root.set_size(window.get_width()/2, window.get_height()/2);
22         root.set_layout(root_layout);
23         root_layout->set_margin(GLtk::Sides());
24         root_layout->set_spacing(0);
25
26         for(unsigned i=0; i<2; ++i)
27         {
28                 selectors[i] = new TrainSelector(client);
29                 root.add(*selectors[i]);
30                 root_layout->set_gravity(*selectors[i], i*2-1, 1);
31                 root_layout->set_expand(*selectors[i], true, false);
32                 selectors[i]->signal_train_selected.connect(sigc::bind(sigc::mem_fun(this, &Remote::train_selected), i));
33
34                 if(i>0)
35                 {
36                         root_layout->add_constraint(*selectors[i], GLtk::Layout::RIGHT_OF, *selectors[i-1]);
37                         root_layout->add_constraint(*selectors[i], GLtk::Layout::COPY_WIDTH, *selectors[i-1]);
38                 }
39
40                 panels[i] = 0;
41         }
42
43         root.add(status_bar);
44         root_layout->set_gravity(status_bar, -1, -1);
45         root_layout->set_expand(status_bar, true, false);
46
47         catalogue.add_source("data/Märklin/H0");
48
49         client.use_event_dispatcher(ev_disp);
50 }
51
52 int Remote::main()
53 {
54         ConnectDialog *dlg = new ConnectDialog(client);
55         root.add(*dlg);
56         root_layout->set_gravity(*dlg, 0, 0);
57
58         window.show();
59
60         return Application::main();
61 }
62
63 void Remote::tick()
64 {
65         for(unsigned i=0;; ++i)
66         {
67                 Time::TimeStamp t = Time::now();
68                 if(i>0 && t>=next_frame)
69                 {
70                         next_frame = t+Time::sec/30;
71                         break;
72                 }
73                 ev_disp.tick(max(next_frame-t, Time::zero));
74         }
75
76         window.tick();
77
78         GL::Framebuffer::system().clear(GL::COLOR_BUFFER_BIT);
79         root.render();
80         window.swap_buffers();
81 }
82
83 void Remote::train_selected(NetTrain *train, unsigned index)
84 {
85         delete panels[index];
86         panels[index] = 0;
87
88         if(train)
89         {
90                 panels[index] = new TrainPanel(*train);
91                 root.add(*panels[index]);
92                 root_layout->set_expand(*panels[index], true, true);
93                 root_layout->add_constraint(*panels[index], GLtk::Layout::BELOW, *selectors[index]);
94                 root_layout->add_constraint(*panels[index], GLtk::Layout::ALIGN_LEFT, *selectors[index]);
95                 root_layout->add_constraint(*panels[index], GLtk::Layout::ALIGN_RIGHT, *selectors[index]);
96                 root_layout->add_constraint(*panels[index], GLtk::Layout::ABOVE, status_bar);
97         }
98 }