Calculator - Step 2.1 Process the numbers

Objective for this step

In this step, we will process the number input through button clicks first. We will dealt with keyboard inputs in Step 2.6.

The Code

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
20   
21   
22   
24   
26   
27   
28   
29   
30   
31   
32   
33   
37   
38   
39   
45   
49   
50   
51   
52   
53   
54   
55   
56   
57   
58   
59   
60   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
71   
72   
73   
74   
75   
76   
77   
78   
79   
80   
81   
82   
83   
84   
85   
86   
87   
88   
89   
90   
91   
92   
93   
94   
95   
96   
97   
98   
99   
100   
101   
102   
103   
104   
105   
106   
107   
108   
<?php

class Calculator{

    var $operator = '';
    var $stack = array();
    var $is_entering_number = 0;

    // constructor
    function Calculator() {
    }

    function main() {
        $this->setup_window();
        $this->setup_layout();
        $this->window->show_all(); // display the calculator
        Gtk::main(); // and let's go!
    }

    function setup_window() {
        $this->window = new GtkWindow();
        $this->window->set_size_request(200, 240);
        $this->window->connect_simple('destroy', array('Gtk','main_quit'));
    }

    function setup_layout() {
        // setup a vbox to hold display and buttons
        $vbox = new GtkVBox();
        $this->window->add($vbox);

        // setup display
        $this->display = new GtkEntry();
        $this->display->set_alignment(1.0); // right-justified
        $this->display->set_editable(false); // for display only
        $vbox->pack_start($this->display);

        // the button labels
        $button_label = array(
            array('Backspc', 'CE', 'C'),
            array('7', '8', '9', '/', 'sqrt'),
            array('4', '5', '6', '*', '%'),
            array('1', '2', '3', '-', '1/x'),
            array('0', '+/-', '.', '+', '=')
        );

        // setup the buttons
        for ($j=0; $j<5; ++$j) {
            $hbox = new GtkHBox();
            $vbox->pack_start($hbox); // use a hbox to hold each row of buttons
            for ($i=0; $i<5; ++$i) {
                if ($j==0 && $i>2) continue; // first row contains only 3 buttons
                $button = new GtkButton($button_label[$j][$i]);
                $button->set_size_request(40, 32); // set the size
                $button->connect('clicked', array(&$this, "on_button"));  // note 1
                $hbox->pack_start($button);
            }
        }
    }

    // process button click
    function on_button($button) {
        $value = $button->child->get_text(); 
// note 2
        echo "button_click: $value\n";

        if (preg_match("/^[0-9]$/", $value)) { 
// note 3
            $number = array_pop($this->stack); 
// get number from stack
            if (preg_match("/^[0-9]+$/", $number)) { // is it a number?
                $number .= $value; // yes, append the new digit to the end of the number
            } else {
                if ($number!='') array_push($this->stack, $number); 
// no, push it back
                $number = $value; // start a new number
            }
            array_push($this->stack, $number);
            $this->display->set_text($number); 
// note 4
        } else {
            array_push($this->stack, $value); 
// note 5
        }
        $this->show_stack(); 
// just for debugging purpose
    }

    // prints the current stack content
    function show_stack() {
        echo "current stack content:\n";
        for ($i=count($this->stack)-1; $i>=0; --$i) {
            echo "stack[$i] = {$this->stack[$i]}\n";
        }
        echo "\n";
    }


}

$cal = new Calculator(); // cerate a new calculator
$cal->main(); // let's run it!

?>
 

Sample Output

For example, if you press the buttons to input: 1234 + 56, you will get:

 

And the stack content:

 

The Stack

We usually implement a calculator using a stack. A stack is just like a paper tray. The first one that goes in stays at the bottom, and you keep piling documents up. It's a list-in-first-out (LIFO) list. Compare this with a queue - which is a first-in-first-out (FIFO) list.

The function show_stack() is just for debugging purpose. It gives a visual printout of the content of the stack as shown above. Note again that the first one that goes in (1234) stays at the bottom, and the latest that goes in (56) is at the top.

Explanation

  1. Just a reminder again that we are only handling button click. This is done with $button->connect('clicked', array(&$this, "on_button")). Note how event handlers are set up if you are using classes. You need to pass in the pointer to the class as well: array(&$this, "on_button").
  2. Note the use of one event handler to handle all button clicks. We know which button is being pressed because php-gtk2 pass you a pointer to that button as the first argument. You can get the label of the button with $button->child->get_text().
  3. We test for digit input with preg_match("/^[0-9]$/", $value). If it is, we need to then:
    • Check if the item on the top of the stack is a number.
    • If it is, e.g. if it's 123, and the new input is 4, we need to append the 4 to the end of 123 with $number .= $value. The new number becomes 1234, and we shove this number back to the stack.
    • If the top of stack is not a number, e.g. it's a '+', and the new input is 5, we just place the number 5 onto the stack.
  4. We display the number with $this->display->set_text($number). Note that because we have wrapped our functions under one class, we have access to the variable $this->display that allows us to set its text from here. If we didn't use class, we have to declare the pointer to the display as global, or pass in as one of the arguments.
  5. We are focusing on processing numbers here. So we just dump everything else that are not numbers onto the stack.

What's Next

We have processed the numbers. In the next step, we will proceed to process the binary operators (+, -, * and /) and the equal sign.

Links

Search This Site

Google
Web This Site

Search PHP-GTK2 Manual

Full-text search on php-gtk2 manual

Members Login

Username:
Password:
Key:
What is this?
  Forget Password?