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+1, elevators+3)
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 /* Fill in all of the ElevatorDoors and CallButtons */
31 for (f_attach=0, f=floors-1; f>=0; --f, ++f_attach)
33 /* Create and attach the VBox */
34 Gtk::VBox *box = new Gtk::VBox ();
35 table_.attach (*box, 0, 1, f_attach, f_attach+1);
37 /* Only create UP CallButton if we are not on the top floor */
40 CallButton *callbutton = new CallButton (f, UP);
41 callbutton->set_label ("Up");
43 // Connect to the on_call_button_toggled() signal
44 callbutton->signal_toggled().connect (
45 sigc::bind <CallButton*> (
46 sigc::mem_fun (*this, &ElevatorGUI::on_call_button_toggled),
51 call_buttons_.push_back (callbutton);
52 box->pack_start (*callbutton);
55 /* Only create the DOWN CallButton if we are not on the bottom floor */
58 CallButton *callbutton = new CallButton (f, DOWN);
59 callbutton->set_label ("Down");
61 // Connect to the on_call_button_toggled() signal
62 callbutton->signal_toggled().connect (
63 sigc::bind <CallButton*> (
64 sigc::mem_fun (*this, &ElevatorGUI::on_call_button_toggled),
69 call_buttons_.push_back (callbutton);
70 box->pack_end (*callbutton);
73 for (e=0; e<elevators; ++e) // run left-to-right
75 ElevatorDoor *door = new ElevatorDoor (e, f);
76 elevator_doors_.push_back (door);
77 table_.attach (*door, e+1, e+2, f_attach, f_attach+1);
83 /* Fill in all of the Elevator Request Panels */
84 for (e=0; e<elevators; ++e)
86 // Create a 2-column table with enough slots for each Floor
87 Gtk::Table *panel = new Gtk::Table ((floors+1)/2, 2);
89 for (f=0; f<floors; ++f)
97 RequestButton *button = new RequestButton (e, f);
98 button->set_label (str.str());
100 // Connect the on_request_button_toggled() signal
101 button->signal_toggled().connect (
102 sigc::bind <RequestButton*> (
103 sigc::mem_fun (*this, &ElevatorGUI::on_request_button_toggled),
109 request_buttons_.push_back (button);
111 // If floor is odd, attach in the left col
112 // Otherwise, attach in the right col
114 panel->attach (*button, 0, 1, f_attach, f_attach+1);
116 panel->attach (*button, 1, 2, f_attach, f_attach+1);
120 table_.attach (*panel, e+1, e+2, floors, floors+1);
125 /* Fill in all of the PositionLabels */
126 for (e=0; e<elevators; ++e)
128 PositionLabel *label = new PositionLabel (e);
129 position_labels_.push_back (label);
130 table_.attach (*label, e+1, e+2, floors+1, floors+2);
134 /* Fill in the control buttons */
135 Gtk::HBox *box = new Gtk::HBox ();
137 button_quit_.signal_clicked().connect (
138 sigc::mem_fun (*this, &ElevatorGUI::on_quit_button_clicked));
139 button_stop_.signal_clicked().connect (
140 sigc::mem_fun (*this, &ElevatorGUI::on_stop_button_clicked));
141 button_playpause_.signal_clicked().connect (
142 sigc::mem_fun (*this, &ElevatorGUI::on_playpause_button_clicked));
144 box->pack_start (button_playpause_);
145 box->pack_start (button_stop_);
146 box->pack_start (button_quit_);
148 /* Attach the box to the bottom of the GUI */
149 table_.attach (*box, 0, elevators+1, floors+2, floors+3);
151 /* Add the table to the window */
154 /* Show everything, we're up and running! */
155 show_all_children ();
159 void ElevatorGUI::on_quit_button_clicked ()
164 void ElevatorGUI::on_playpause_button_clicked ()
166 std::string names[] = { "STOPPED", "RUNNING", "PAUSED" };
167 std::cout << "Play/Pause pressed with status=" << names[simulation_status_] << std::endl;
169 switch (simulation_status_)
172 simulation_status_ = RUNNING;
174 // add and start timer
175 timer_ = Glib::signal_timeout().connect (
176 sigc::mem_fun (*this, &ElevatorGUI::on_timer_tick),
181 simulation_status_= PAUSED;
183 // stop and remove timer
184 timer_.disconnect ();
188 simulation_status_ = RUNNING;
190 // add and start timer
191 timer_ = Glib::signal_timeout().connect (
192 sigc::mem_fun (*this, &ElevatorGUI::on_timer_tick),
197 std::cout << "Bad Simulation Status in Play/Pause" << std::endl;
202 void ElevatorGUI::on_stop_button_clicked ()
204 // FIXME: implement this
205 std::cout << "STOP Button Clicked" << std::endl;
207 simulation_status_ = STOPPED;
210 void ElevatorGUI::on_request_button_toggled (RequestButton *button)
212 // Only send an elevator if we are toggled to on
213 if (button->get_active())
215 std::cout << "Request elevator=" << button->getElevatorNumber()
216 << " to floor=" << button->getFloorNumber() << std::endl;
217 ec_.elevator_request (button->getElevatorNumber(), button->getFloorNumber());
221 void ElevatorGUI::on_call_button_toggled (CallButton *button)
223 // Only send an elevator if we are toggled to on
224 if (button->get_active())
226 std::cout << "Elevator Called on floor=" << button->getFloorNumber()
227 << " in direction=" << button->getDirection() << std::endl;
228 ec_.call_elevator_to (button->getFloorNumber(), button->getDirection());
232 void ElevatorGUI::gui_update_position_label (int elevator, float new_position, Direction direction)
234 // Find the correct label and set it
235 PositionLabelVector::iterator it;
237 for (it=position_labels_.begin(); it!=position_labels_.end(); it++)
238 if ((*it)->getElevatorNumber() == elevator)
239 (*it)->update_position (new_position, direction);
242 void ElevatorGUI::gui_unpress_call_button (int floor, Direction direction)
244 CallButtonVector::iterator it;
246 for (it=call_buttons_.begin(); it!=call_buttons_.end(); it++)
247 if ((*it)->getFloorNumber() == floor && (*it)->getDirection() == direction)
248 (*it)->set_active (false);
251 void ElevatorGUI::gui_unpress_request_button (int elevator, int floor)
253 RequestButtonVector::iterator it;
255 for (it=request_buttons_.begin(); it!=request_buttons_.end(); it++)
256 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
257 (*it)->set_active (false);
260 void ElevatorGUI::gui_open_door (int elevator, int floor)
262 ElevatorDoorVector::iterator it;
264 for (it=elevator_doors_.begin(); it!=elevator_doors_.end(); it++)
265 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
269 void ElevatorGUI::gui_close_door (int elevator, int floor)
271 ElevatorDoorVector::iterator it;
273 for (it=elevator_doors_.begin(); it!=elevator_doors_.end(); it++)
274 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
278 bool ElevatorGUI::on_timer_tick ()
280 ec_.move_elevators ();
282 // Keep going (do NOT disconnect yet)
286 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */