1 #include "elevatorgui.hpp"
3 ElevatorGUI::ElevatorGUI (int floors, int elevators)
5 , number_of_floors_(floors)
6 , number_of_elevators_(elevators)
7 , simulation_status_(PAUSED)
9 /* The ElevatorController */
10 , ec_(floors, elevators)
16 , table_(floors+3, elevators+1)
17 , button_playpause_(Gtk::Stock::MEDIA_PLAY)
18 , button_quit_(Gtk::Stock::QUIT)
20 /* Storage for GUI elements for later lookup */
26 int i, j, e, f, e_num, f_num, f_attach;
27 std::ostringstream str;
29 /* Set Table Spacing / Window Border Size */
30 table_.set_col_spacings (8);
31 table_.set_row_spacings (8);
32 set_border_width (10);
34 /* Fill in all of the ElevatorDoors and CallButtons */
35 for (f_attach=0, f=floors-1; f>=0; --f, ++f_attach)
37 /* Create and attach the VBox */
38 Gtk::VBox *box = new Gtk::VBox ();
39 table_.attach (*box, 0, 1, f_attach, f_attach+1);
41 /* Only create UP CallButton if we are not on the top floor */
44 CallButton *callbutton = new CallButton (f, UP);
45 callbutton->set_label ("Up");
47 // Connect to the on_call_button_toggled() signal
48 callbutton->signal_toggled().connect (
49 sigc::bind <CallButton*> (
50 sigc::mem_fun (*this, &ElevatorGUI::on_call_button_toggled),
55 call_buttons_.push_back (callbutton);
56 box->pack_start (*callbutton);
58 else // we are on the top floor, create a dummy label
60 Gtk::Label *label = new Gtk::Label ("");
61 box->pack_start (*label);
64 /* Only create the DOWN CallButton if we are not on the bottom floor */
67 CallButton *callbutton = new CallButton (f, DOWN);
68 callbutton->set_label ("Down");
70 // Connect to the on_call_button_toggled() signal
71 callbutton->signal_toggled().connect (
72 sigc::bind <CallButton*> (
73 sigc::mem_fun (*this, &ElevatorGUI::on_call_button_toggled),
78 call_buttons_.push_back (callbutton);
79 box->pack_end (*callbutton);
81 else // we are on the bottom floor, create a dummy label
83 Gtk::Label *label = new Gtk::Label ("");
84 box->pack_end (*label);
87 for (e=0; e<elevators; ++e) // run left-to-right
89 ElevatorDoor *door = new ElevatorDoor (e, f);
90 elevator_doors_.push_back (door);
91 table_.attach (*door, e+1, e+2, f_attach, f_attach+1);
97 /* Fill in all of the Elevator Request Panels */
98 for (e=0; e<elevators; ++e)
100 // Create a 2-column table with enough slots for each Floor
101 Gtk::Table *panel = new Gtk::Table ((floors+1)/2, 2);
103 for (f=0; f<floors; ++f)
111 RequestButton *button = new RequestButton (e, f);
112 button->set_label (str.str());
114 // Connect the on_request_button_toggled() signal
115 button->signal_toggled().connect (
116 sigc::bind <RequestButton*> (
117 sigc::mem_fun (*this, &ElevatorGUI::on_request_button_toggled),
123 request_buttons_.push_back (button);
125 // If floor is odd, attach in the left col
126 // Otherwise, attach in the right col
128 panel->attach (*button, 0, 1, f_attach, f_attach+1);
130 panel->attach (*button, 1, 2, f_attach, f_attach+1);
134 table_.attach (*panel, e+1, e+2, floors, floors+1);
139 /* Fill in all of the PositionLabels */
140 for (e=0; e<elevators; ++e)
142 PositionLabel *label = new PositionLabel (e);
143 position_labels_.push_back (label);
144 table_.attach (*label, e+1, e+2, floors+1, floors+2);
148 /* Fill in the control buttons */
149 Gtk::HBox *box = new Gtk::HBox ();
151 /* Tell the Play/Pause button to use the StockID so we can change it's image */
152 button_playpause_.set_use_stock (true);
154 /* Signals for control buttons */
155 button_quit_.signal_clicked().connect (
156 sigc::mem_fun (*this, &ElevatorGUI::on_quit_button_clicked));
157 button_playpause_.signal_clicked().connect (
158 sigc::mem_fun (*this, &ElevatorGUI::on_playpause_button_clicked));
160 box->pack_start (button_playpause_);
161 box->pack_start (button_quit_);
163 /* Attach the box to the bottom of the GUI */
164 table_.attach (*box, 0, elevators+1, floors+2, floors+3);
166 /* Add the table to the window */
169 /* Show everything, we're up and running! */
170 show_all_children ();
174 void ElevatorGUI::on_quit_button_clicked ()
179 void ElevatorGUI::on_playpause_button_clicked ()
181 std::string names[] = { "RUNNING", "PAUSED" };
182 std::cout << "Play/Pause pressed with status=" << names[simulation_status_] << std::endl;
184 switch (simulation_status_)
187 simulation_status_= PAUSED;
189 // stop and remove timer
190 timer_.disconnect ();
192 // Set the StockID of the button
193 button_playpause_.set_label ("gtk-media-play");
197 simulation_status_ = RUNNING;
199 // add and start timer
200 timer_ = Glib::signal_timeout().connect (
201 sigc::mem_fun (*this, &ElevatorGUI::on_timer_tick),
204 // Set the StockID of the button
205 button_playpause_.set_label ("gtk-media-pause");
209 std::cout << "Bad Simulation Status in Play/Pause" << std::endl;
214 void ElevatorGUI::on_request_button_toggled (RequestButton *button)
216 // Only send an elevator if we are toggled to on
217 if (button->get_active())
219 std::cout << "Request elevator=" << button->getElevatorNumber()
220 << " to floor=" << button->getFloorNumber() << std::endl;
221 ec_.elevator_request (button->getElevatorNumber(), button->getFloorNumber());
225 void ElevatorGUI::on_call_button_toggled (CallButton *button)
227 // Only send an elevator if we are toggled to on
228 if (button->get_active())
230 std::cout << "Elevator Called on floor=" << button->getFloorNumber()
231 << " in direction=" << button->getDirection() << std::endl;
232 ec_.call_elevator_to (button->getFloorNumber(), button->getDirection());
236 void ElevatorGUI::gui_update_position_label (int elevator, float new_position, Direction direction)
238 // Find the correct label and set it
239 PositionLabelVector::iterator it;
241 for (it=position_labels_.begin(); it!=position_labels_.end(); it++)
242 if ((*it)->getElevatorNumber() == elevator)
243 (*it)->update_position (new_position, direction);
246 void ElevatorGUI::gui_unpress_call_button (int floor, Direction direction)
248 CallButtonVector::iterator it;
250 for (it=call_buttons_.begin(); it!=call_buttons_.end(); it++)
251 if ((*it)->getFloorNumber() == floor && (*it)->getDirection() == direction)
252 (*it)->set_active (false);
255 void ElevatorGUI::gui_unpress_request_button (int elevator, int floor)
257 RequestButtonVector::iterator it;
259 for (it=request_buttons_.begin(); it!=request_buttons_.end(); it++)
260 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
261 (*it)->set_active (false);
264 void ElevatorGUI::gui_open_door (int elevator, int floor)
266 ElevatorDoorVector::iterator it;
268 for (it=elevator_doors_.begin(); it!=elevator_doors_.end(); it++)
269 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
273 void ElevatorGUI::gui_close_door (int elevator, int floor)
275 ElevatorDoorVector::iterator it;
277 for (it=elevator_doors_.begin(); it!=elevator_doors_.end(); it++)
278 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
282 bool ElevatorGUI::on_timer_tick ()
284 ec_.move_elevators ();
286 // Keep going (do NOT disconnect yet)
290 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */