Subversion Repositories programming

Rev

Rev 350 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*******************************************************************************
 * elevator_window.cc
 *
 * Implementation for the Elevator_Window class.
 *
 * Copyright 2006, Ira W. Snyder (devel@irasnyder.com)
 ******************************************************************************/

#include "elevator_window.h"

Elevator_Window::Elevator_Window (int numFloors, int numElevators)
    : numFloors (numFloors),
      numElevators (numElevators),
      m_table (numFloors+1, numElevators+3, true)
{
    int i, j;
    std::ostringstream strstrm;
    Gtk::ToggleButton *pToggleButton;
    Gtk::Label *pLabel;
    Gtk::Image *pImage;
    Button_Data bData;

    // Set up all of the buttons
    upbuttons.reserve (numFloors-1);
    downbuttons.reserve (numFloors-1);

    for (i=0; i<numFloors-1; i++)
    {
        // Create an "up" button
        strstrm.str ("");
        strstrm << "Up";
        pToggleButton = new Gtk::ToggleButton (strstrm.str());

        bData.str = strstrm.str();
        bData.button_num = i;
        bData.direction = MOVE_UP;
        bData.theButton = pToggleButton;

        pToggleButton->signal_clicked ().connect (
                sigc::bind<Button_Data> (sigc::mem_fun (*this, &Elevator_Window::on_toggle_button_pressed), bData));
        upbuttons.push_back (pToggleButton);

        // Put it in the table
        m_table.attach (*pToggleButton, 1, 2, numFloors-(i+1), numFloors-i);

        // Create a "down" button
        strstrm.str ("");
        strstrm << "Down";
        pToggleButton = new Gtk::ToggleButton (strstrm.str());

        bData.str = strstrm.str();
        bData.button_num = i;
        bData.direction = MOVE_DOWN;
        bData.theButton = pToggleButton;

        pToggleButton->signal_clicked ().connect (
                sigc::bind<Button_Data> (sigc::mem_fun (*this, &Elevator_Window::on_toggle_button_pressed), bData));
        downbuttons.push_back (pToggleButton);

        // Put it in the table
        m_table.attach (*pToggleButton, 2, 3, numFloors-(i+2), numFloors-(i+1));
    }

    // Labels
    for (i=0; i<numFloors; i++)
    {
        strstrm.str ("");
        strstrm << "Floor " << i;
        pLabel = new Gtk::Label (strstrm.str ());

        m_table.attach (*pLabel, 0, 1, numFloors-(i+1), numFloors-i);
    }

    images.reserve (numFloors*numElevators);

    // Images
    for (i=0; i<numFloors; i++)
    {
        for (j=3; j<numElevators+3; j++)
        {
            pImage = new Gtk::Image ("eclose.png");

            images.push_back (pImage);

            m_table.attach (*pImage, j, j+1, i, i+1);
        }
    }

    // Bottom Row of Labels
    pLabel = new Gtk::Label ("Position:");
    m_table.attach (*pLabel, 2, 3, numFloors, numFloors+1);

    labels.reserve (numElevators);

    for (i=3; i<numElevators+3; i++)
    {
        pLabel = new Gtk::Label ("0");
        labels.push_back (pLabel);
        m_table.attach (*pLabel, i, i+1, numFloors, numFloors+1);
    }

    set_title ("GTK Elevator Simulator");

    // Set the border width of the window
    set_border_width (10);

    m_table.set_row_spacings (10);
    m_table.set_col_spacings (10);

    add (m_table);

    show_all_children ();
}

Elevator_Window::~Elevator_Window ()
{

}

void Elevator_Window::on_toggle_button_pressed (Button_Data data)
{
    std::string s;
    bool active = false;

    if (data.direction == MOVE_UP)
    {
        s = "MOVE_UP";
        active = data.theButton->get_active ();

        if (active)
            controller->request_elevator (data.button_num, MOVE_UP);
    }
    else if (data.direction == MOVE_DOWN)
    {
        s = "MOVE_DOWN";
        active = data.theButton->get_active ();

        if (active)
            controller->request_elevator (data.button_num+1, MOVE_DOWN);
    }
    else
        s = "NOT VALID";
}

void Elevator_Window::open_elevator_at (int row, int col)
{
    assert (row >= 0);
    assert (row < numFloors);
    assert (col >= 0);
    assert (col < numElevators);

    images.at (row*numElevators+col)->set ("eopen2.png");
}

void Elevator_Window::close_elevator_at (int row, int col)
{
    assert (row >= 0);
    assert (row < numFloors);
    assert (col >= 0);
    assert (col < numElevators);

    images.at (row*numElevators+col)->clear ();
    images.at (row*numElevators+col)->set ("eclose.png");
}

void Elevator_Window::unset_up_button (int button_num)
{
    assert (button_num >= 0);
    assert (button_num < numFloors);

    upbuttons.at (button_num)->set_active (false);
}

void Elevator_Window::unset_down_button (int button_num)
{
    assert (button_num >= 0);
    assert (button_num < numFloors);

    downbuttons.at (button_num)->set_active (false);
}

void Elevator_Window::set_label (int label_num, std::string new_text)
{
    assert (label_num >= 0);
    assert (label_num < numElevators);

    labels.at (label_num)->set_text (new_text);
}

void Elevator_Window::set_controller (Controller *controller)
{
    this->controller = controller;
}

void Elevator_Window::get_floors_from_user (int elevator_num, int floor)
{
    int res;
    std::ostringstream strstrm;

    strstrm << "Elevator Number: " << elevator_num << " at Floor: " << floor;

    Gtk::Dialog d ("Floor Dialog", true, true);
    Gtk::Entry entry;
    Gtk::Label label1 ("Enter floors to stop at (space seperated): ");
    Gtk::Label label2 ("Just push ok for none");
    Gtk::Label label3 (strstrm.str());

    Gtk::Box *pBox = d.get_vbox();

    pBox->set_spacing (10);

    pBox->pack_start (label1);
    pBox->pack_start (label2);
    pBox->pack_start (label3);
    pBox->pack_start (entry);

    label1.show ();
    label2.show ();
    label3.show ();
    entry.show ();

    d.add_button ("gtk-ok", 7);

    // Run the Dialog
    res = d.run ();

    // Parse the entry
    std::string s = entry.get_text();
    std::vector<std::string> SplitVec;
    boost::split (SplitVec, s, boost::is_any_of(" "));

    int i, val;
    for (i=0; i<SplitVec.size(); i++)
    {
        if (SplitVec[i] == "" || SplitVec[i] == " ")
            val = -1;
        else
            val = atoi (SplitVec[i].c_str());

        // Ignore values that are outside of range
        if (val >= 0 && val < numFloors)
            controller->push_button_in_elevator (elevator_num, val);
    }
}