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 std::cout << "at floor: " << f << std::endl;
35 /* Create and attach the VBox */
36 Gtk::VBox *box = new Gtk::VBox ();
37 table_.attach (*box, 0, 1, f_attach, f_attach+1);
39 /* Only create UP CallButton if we are not on the top floor */
42 CallButton *callbutton = new CallButton (f, UP);
43 callbutton->set_label ("Up");
45 // Connect to the on_call_button_toggled() signal
46 callbutton->signal_toggled().connect (
47 sigc::bind <CallButton*> (
48 sigc::mem_fun (*this, &ElevatorGUI::on_call_button_toggled),
53 call_buttons_.push_back (callbutton);
54 box->pack_start (*callbutton);
57 /* Only create the DOWN CallButton if we are not on the bottom floor */
60 CallButton *callbutton = new CallButton (f, DOWN);
61 callbutton->set_label ("Down");
63 // Connect to the on_call_button_toggled() signal
64 callbutton->signal_toggled().connect (
65 sigc::bind <CallButton*> (
66 sigc::mem_fun (*this, &ElevatorGUI::on_call_button_toggled),
71 call_buttons_.push_back (callbutton);
72 box->pack_end (*callbutton);
75 for (e=0; e<elevators; ++e) // run left-to-right
77 std::cout << "Attaching ElevatorDoor (e=" << e << ", f=" << f << ")" << std::endl;
78 ElevatorDoor *door = new ElevatorDoor (e, f);
79 elevator_doors_.push_back (door);
80 table_.attach (*door, e+1, e+2, f_attach, f_attach+1);
86 /* Fill in all of the Elevator Request Panels */
87 for (e=0; e<elevators; ++e)
89 // Create a 2-column table with enough slots for each Floor
90 Gtk::Table *panel = new Gtk::Table ((floors+1)/2, 2);
92 for (f=0; f<floors; ++f)
100 RequestButton *button = new RequestButton (e, f);
101 button->set_label (str.str());
103 // Connect the on_request_button_toggled() signal
104 button->signal_toggled().connect (
105 sigc::bind <RequestButton*> (
106 sigc::mem_fun (*this, &ElevatorGUI::on_request_button_toggled),
112 request_buttons_.push_back (button);
114 // If floor is odd, attach in the left col
115 // Otherwise, attach in the right col
117 panel->attach (*button, 0, 1, f_attach, f_attach+1);
119 panel->attach (*button, 1, 2, f_attach, f_attach+1);
123 table_.attach (*panel, e+1, e+2, floors, floors+1);
128 /* Fill in all of the PositionLabels */
129 for (e=0; e<elevators; ++e)
131 PositionLabel *label = new PositionLabel (e);
132 position_labels_.push_back (label);
133 table_.attach (*label, e+1, e+2, floors+1, floors+2);
137 /* Fill in the control buttons */
138 Gtk::HBox *box = new Gtk::HBox ();
140 button_quit_.signal_clicked().connect (
141 sigc::mem_fun (*this, &ElevatorGUI::on_quit_button_clicked));
142 button_stop_.signal_clicked().connect (
143 sigc::mem_fun (*this, &ElevatorGUI::on_stop_button_clicked));
144 button_playpause_.signal_clicked().connect (
145 sigc::mem_fun (*this, &ElevatorGUI::on_playpause_button_clicked));
147 box->pack_start (button_playpause_);
148 box->pack_start (button_stop_);
149 box->pack_start (button_quit_);
151 /* Attach the box to the bottom of the GUI */
152 table_.attach (*box, 0, elevators+1, floors+2, floors+3);
154 /* Add the table to the window */
157 /* Show everything, we're up and running! */
158 show_all_children ();
162 void ElevatorGUI::on_quit_button_clicked ()
167 void ElevatorGUI::on_playpause_button_clicked ()
169 std::string names[] = { "STOPPED", "RUNNING", "PAUSED" };
170 std::cout << "Play/Pause pressed with status=" << names[simulation_status_] << std::endl;
172 switch (simulation_status_)
175 simulation_status_ = RUNNING;
177 // add and start timer
178 timer_ = Glib::signal_timeout().connect (
179 sigc::mem_fun (*this, &ElevatorGUI::on_timer_tick),
184 simulation_status_= PAUSED;
186 // stop and remove timer
187 timer_.disconnect ();
191 simulation_status_ = RUNNING;
193 // add and start timer
194 timer_ = Glib::signal_timeout().connect (
195 sigc::mem_fun (*this, &ElevatorGUI::on_timer_tick),
200 std::cout << "Bad Simulation Status in Play/Pause" << std::endl;
205 void ElevatorGUI::on_stop_button_clicked ()
207 // FIXME: implement this
208 std::cout << "STOP Button Clicked" << std::endl;
210 simulation_status_ = STOPPED;
213 void ElevatorGUI::on_request_button_toggled (RequestButton *button)
215 // Only send an elevator if we are toggled to on
216 if (button->get_active())
218 std::cout << "Request elevator=" << button->getElevatorNumber()
219 << " to floor=" << button->getFloorNumber() << std::endl;
220 ec_.elevator_request (button->getElevatorNumber(), button->getFloorNumber());
224 void ElevatorGUI::on_call_button_toggled (CallButton *button)
226 // Only send an elevator if we are toggled to on
227 if (button->get_active())
229 std::cout << "Elevator Called on floor=" << button->getFloorNumber()
230 << " in direction=" << button->getDirection() << std::endl;
231 ec_.call_elevator_to (button->getFloorNumber(), button->getDirection());
235 void ElevatorGUI::gui_update_position_label (int elevator, float new_position)
237 std::ostringstream str;
240 str << std::setiosflags (std::ios_base::showpoint | std::ios_base::fixed)
241 << std::setprecision(1) << new_position;
243 // Find the correct label and set it
244 PositionLabelVector::iterator it;
246 for (it=position_labels_.begin(); it!=position_labels_.end(); it++)
247 if ((*it)->getElevatorNumber() == elevator)
248 (*it)->set_text (str.str());
251 void ElevatorGUI::gui_unpress_call_button (int floor, Direction direction)
253 CallButtonVector::iterator it;
255 for (it=call_buttons_.begin(); it!=call_buttons_.end(); it++)
256 if ((*it)->getFloorNumber() == floor && (*it)->getDirection() == direction)
257 (*it)->set_active (false);
260 void ElevatorGUI::gui_unpress_request_button (int elevator, int floor)
262 RequestButtonVector::iterator it;
264 for (it=request_buttons_.begin(); it!=request_buttons_.end(); it++)
265 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
266 (*it)->set_active (false);
269 void ElevatorGUI::gui_open_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 void ElevatorGUI::gui_close_door (int elevator, int floor)
280 ElevatorDoorVector::iterator it;
282 for (it=elevator_doors_.begin(); it!=elevator_doors_.end(); it++)
283 if ((*it)->getElevatorNumber() == elevator && (*it)->getFloorNumber() == floor)
287 bool ElevatorGUI::on_timer_tick ()
289 ec_.move_elevators ();
291 // Keep going (do NOT disconnect yet)
295 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */