1 #include "elevatorgui.hpp"
3 ElevatorGUI::ElevatorGUI (int floors, int elevators)
5 , number_of_floors_(floors)
6 , number_of_elevators_(elevators)
7 , simulation_status_(STOPPED)
9 /* The ElevatorController */
10 , ec_(floors, elevators)
16 , table_(floors+3, elevators+1)
17 , button_playpause_(Gtk::Stock::MEDIA_PLAY)
18 , button_stop_(Gtk::Stock::STOP)
19 , button_quit_(Gtk::Stock::QUIT)
21 /* Storage for GUI elements for later lookup */
27 int i, j, e, f, e_num, f_num, f_attach;
28 std::ostringstream str;
30 /* Set Table Spacing / Window Border Size */
31 table_.set_col_spacings (8);
32 table_.set_row_spacings (8);
33 set_border_width (10);
35 /* Fill in all of the ElevatorDoors and CallButtons */
36 for (f_attach=0, f=floors-1; f>=0; --f, ++f_attach)
38 /* Create and attach the VBox */
39 Gtk::VBox *box = new Gtk::VBox ();
40 table_.attach (*box, 0, 1, f_attach, f_attach+1);
42 /* Only create UP CallButton if we are not on the top floor */
45 CallButton *callbutton = new CallButton (f, UP);
46 callbutton->set_label ("Up");
48 // Connect to the on_call_button_toggled() signal
49 callbutton->signal_toggled().connect (
50 sigc::bind <CallButton*> (
51 sigc::mem_fun (*this, &ElevatorGUI::on_call_button_toggled),
56 call_buttons_.push_back (callbutton);
57 box->pack_start (*callbutton);
59 else // we are on the top floor, create a dummy label
61 Gtk::Label *label = new Gtk::Label ("");
62 box->pack_start (*label);
65 /* Only create the DOWN CallButton if we are not on the bottom floor */
68 CallButton *callbutton = new CallButton (f, DOWN);
69 callbutton->set_label ("Down");
71 // Connect to the on_call_button_toggled() signal
72 callbutton->signal_toggled().connect (
73 sigc::bind <CallButton*> (
74 sigc::mem_fun (*this, &ElevatorGUI::on_call_button_toggled),
79 call_buttons_.push_back (callbutton);
80 box->pack_end (*callbutton);
82 else // we are on the bottom floor, create a dummy label
84 Gtk::Label *label = new Gtk::Label ("");
85 box->pack_end (*label);
88 for (e=0; e<elevators; ++e) // run left-to-right
90 ElevatorDoor *door = new ElevatorDoor (e, f);
91 elevator_doors_.push_back (door);
92 table_.attach (*door, e+1, e+2, f_attach, f_attach+1);
98 /* Fill in all of the Elevator Request Panels */
99 for (e=0; e<elevators; ++e)
101 // Create a 2-column table with enough slots for each Floor
102 Gtk::Table *panel = new Gtk::Table ((floors+1)/2, 2);
104 for (f=0; f<floors; ++f)
112 RequestButton *button = new RequestButton (e, f);
113 button->set_label (str.str());
115 // Connect the on_request_button_toggled() signal
116 button->signal_toggled().connect (
117 sigc::bind <RequestButton*> (
118 sigc::mem_fun (*this, &ElevatorGUI::on_request_button_toggled),
124 request_buttons_.push_back (button);
126 // If floor is odd, attach in the left col
127 // Otherwise, attach in the right col
129 panel->attach (*button, 0, 1, f_attach, f_attach+1);
131 panel->attach (*button, 1, 2, f_attach, f_attach+1);
135 table_.attach (*panel, e+1, e+2, floors, floors+1);
140 /* Fill in all of the PositionLabels */
141 for (e=0; e<elevators; ++e)
143 PositionLabel *label = new PositionLabel (e);
144 position_labels_.push_back (label);
145 table_.attach (*label, e+1, e+2, floors+1, floors+2);
149 /* Fill in the control buttons */
150 Gtk::HBox *box = new Gtk::HBox ();
152 button_quit_.signal_clicked().connect (
153 sigc::mem_fun (*this, &ElevatorGUI::on_quit_button_clicked));
154 button_stop_.signal_clicked().connect (
155 sigc::mem_fun (*this, &ElevatorGUI::on_stop_button_clicked));
156 button_playpause_.signal_clicked().connect (
157 sigc::mem_fun (*this, &ElevatorGUI::on_playpause_button_clicked));
159 box->pack_start (button_playpause_);
160 box->pack_start (button_stop_);
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[] = { "STOPPED", "RUNNING", "PAUSED" };
182 std::cout << "Play/Pause pressed with status=" << names[simulation_status_] << std::endl;
184 switch (simulation_status_)
187 simulation_status_ = RUNNING;
189 // add and start timer
190 timer_ = Glib::signal_timeout().connect (
191 sigc::mem_fun (*this, &ElevatorGUI::on_timer_tick),
196 simulation_status_= PAUSED;
198 // stop and remove timer
199 timer_.disconnect ();
203 simulation_status_ = RUNNING;
205 // add and start timer
206 timer_ = Glib::signal_timeout().connect (
207 sigc::mem_fun (*this, &ElevatorGUI::on_timer_tick),
212 std::cout << "Bad Simulation Status in Play/Pause" << std::endl;
217 void ElevatorGUI::on_stop_button_clicked ()
219 // FIXME: implement this
220 std::cout << "STOP Button Clicked" << std::endl;
222 simulation_status_ = STOPPED;
225 void ElevatorGUI::on_request_button_toggled (RequestButton *button)
227 // Only send an elevator if we are toggled to on
228 if (button->get_active())
230 std::cout << "Request elevator=" << button->getElevatorNumber()
231 << " to floor=" << button->getFloorNumber() << std::endl;
232 ec_.elevator_request (button->getElevatorNumber(), button->getFloorNumber());
236 void ElevatorGUI::on_call_button_toggled (CallButton *button)
238 // Only send an elevator if we are toggled to on
239 if (button->get_active())
241 std::cout << "Elevator Called on floor=" << button->getFloorNumber()
242 << " in direction=" << button->getDirection() << std::endl;
243 ec_.call_elevator_to (button->getFloorNumber(), button->getDirection());
247 void ElevatorGUI::gui_update_position_label (int elevator, float new_position, Direction direction)
249 // Find the correct label and set it
250 PositionLabelVector::iterator it;
252 for (it=position_labels_.begin(); it!=position_labels_.end(); it++)
253 if ((*it)->getElevatorNumber() == elevator)
254 (*it)->update_position (new_position, direction);
257 void ElevatorGUI::gui_unpress_call_button (int floor, Direction direction)
259 CallButtonVector::iterator it;
261 for (it=call_buttons_.begin(); it!=call_buttons_.end(); it++)
262 if ((*it)->getFloorNumber() == floor && (*it)->getDirection() == direction)
263 (*it)->set_active (false);
266 void ElevatorGUI::gui_unpress_request_button (int elevator, int floor)
268 RequestButtonVector::iterator it;
270 for (it=request_buttons_.begin(); it!=request_buttons_.end(); it++)
271 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
272 (*it)->set_active (false);
275 void ElevatorGUI::gui_open_door (int elevator, int floor)
277 ElevatorDoorVector::iterator it;
279 for (it=elevator_doors_.begin(); it!=elevator_doors_.end(); it++)
280 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
284 void ElevatorGUI::gui_close_door (int elevator, int floor)
286 ElevatorDoorVector::iterator it;
288 for (it=elevator_doors_.begin(); it!=elevator_doors_.end(); it++)
289 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
293 bool ElevatorGUI::on_timer_tick ()
295 ec_.move_elevators ();
297 // Keep going (do NOT disconnect yet)
301 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */