Mastering Glade for PHP-GTK2
PHP-GTK2 Cookbook Vol.2
PHP-GTK2 Cookbook Vol.1
Intro to Glade for PHP-GTK2
PHP-GTK2 Demystified
PHP-GTK ExplorerYour "secret weapon" for learning, exploring, understanding and mastering PHP-GTK2!
[Free Download Here]
|
|
|
| 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
- 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").
- 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().
- 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.
- 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.
- 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 PHP-GTK2 Manual
Full-text search on php-gtk2 manual
|