Kiosk Application Template #3

This is the third template of the kiosk application template series.

This produces exactly the same output as the second template. The only difference it's re-written using classes, or object-oriented programming.

As you can see from the codes below, the login and the main application are now neatly encapsulated into each of its own class. This makes it much easier and better for maintenance and debugging.

 

The Code

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
40   
41   
42   
43   
44   
45   
46   
47   
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   
79   
81   
82   
83   
85   
87   
88   
89   
90   
92   
93   
95   
96   
97   
98   
99   
100   
101   
103   
106   
107   
108   
111   
112   
113   
114   
116   
117   
119   
120   
121   
122   
125   
126   
127   
128   
129   
131   
133   
134   
135   
136   
138   
140   
141   
142   
143   
146   
148   
150   
151   
152   
153   
155   
156   
157   
158   
159   
160   
161   
162   
163   
164   
165   
166   
167   
168   
169   
170   
171   
172   
173   
174   
175   
176   
178   
179   
180   
181   
182   
183   
184   
185   
186   
187   
188   
189   
193   
194   
195   
196   
197   
198   
199   
200   
201   
203   
204   
206   
207   
208   
209   
210   
211   
212   
213   
214   
215   
216   
217   
219   
220   
221   
222   
223   
224   
225   
226   
227   
228   
229   
230   
234   
235   
236   
237   
238   
242   
243   
244   
245   
246   
248   
249   
250   
251   
252   
253   
254   
255   
256   
257   
259   
262   
263   
264   
266   
267   
268   
269   
270   
271   
272   
274   
275   
276   
277   
278   
279   
280   
283   
284   
285   
286   
287   
288   
289   
290   
291   
292   
293   
294   
<?php

define('MAX_USAGE', 30);  // max usage time = 30 min
define('INACTIVITY', 10); // auto logout after 10 min of inactivity

$app = new KioskApp();

class KioskApp {

    public function __construct() {
        while(1) {
            $login = new Login();
            $login->login_success = 0;
            while($login->login_success!=1) {
                $login->go();
            }

            // starts the main program only if login successful
            $main = new MainApp();
        }


    }
}

class MainApp {

    protected $start_time; // start time
    protected $last_activity; // time of last activity
    protected $timeout_maxtime; // timeout_id for maxtime
    protected $timeout_inactivity; // timeout_id for inactivity
    protected $main_win; // main application window

    public function __construct() {
        $this->go();
    }

    public function go() {
        $this->setup();
        $this->main_win->run();
        $this->main_win->destroy();
    }

    protected function setup() {
        $dialog = new GtkDialog();
        $dialog->fullscreen();
        $eventbox = new GtkEventBox(); // note 1
        $dialog->vbox->pack_start($eventbox); // note 1
        $vbox = new GtkVBox();
        $eventbox->add($vbox);
        $vbox->pack_start(new GtkLabel());

        // display title
        $title = new GtkLabel("This is the main program");
        $title->modify_font(new PangoFontDescription(
            "Times New Roman Italic 10"));
        $title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff"));
        $title->set_size_request(-1, 40);
        $vbox->pack_start($title, 0);

        $vbox->pack_start(new GtkLabel("User verified"), 0);
        $vbox->pack_start(new GtkLabel("Main application starts..."), 0);
        $vbox->pack_start(new GtkLabel(
        "Note: application will auto-logout after 30 min of usage"), 0);
        $vbox->pack_start(new GtkLabel(
        "or after 10 min of inactivity (i.e. no mouse or keyboard movement)"), 0);
        $vbox->pack_start(new GtkLabel());

        // sets up a logout button
        $vbox->pack_start($hbox = new GtkHBox(), 0);
        $hbox->pack_start(new GtkLabel());
        $button = new GtkButton('Logout');
        $hbox->pack_start($button, 0);
        $button->connect('clicked', array(&$this, 'on_logout_button'));

        // auto-logout after 30 minutes of usage
        $this->start_time = time();
        $this->timeout_maxtime =
            Gtk::timeout_add(MAX_USAGE * 60 * 1000, array(&$this, 'logout'));

        // check for inactivity
        $this->last_activity = time();
        $dialog->connect('key-press-event', array(&$this, 'on_keypress'));
        $dialog->connect('button-press-event', array(&$this, 'on_buttonpress'));
        $dialog->connect('motion-notify-event', array(&$this, 'on_motion'));
        $this->timeout_inactivity = Gtk::timeout_add(1000,
            array(&$this, 'check_inactivity'));

        $dialog->set_has_separator(false);
        $dialog->show_all();
        $this->main_win = $dialog;
    }

    public function on_logout_button($button) {
        $this->logout();
    }

    public function logout() {
        Gtk::timeout_remove($this->timeout_maxtime);
        Gtk::timeout_remove($this->timeout_inactivity);
        $this->main_win->destroy();
    }

    function on_keypress($widget, $event) {
        $this->last_activity = time(); // note 7
        return false;
    }

    function on_motion($widget, $event) {
        $this->last_activity = time(); // note 7
        return false;
    }

    function on_buttonpress($widget, $event) {
        $this->last_activity = time(); // note 7
        return false;
    }

    function check_inactivity() {
        $time_elapsed = time() - $this->last_activity;
        if ($time_elapsed>INACTIVITY * 60 * 1000 ) { // note 8
            echo "no activity. auto-logout...\n";
            $this->logout(); // note 8
            return false;
        } else {
            return true;
        }
    }
}

class Login {

    protected $login_dialog; // the login dialog
    public $login_success = 0; // flag to indicate whether login is successful

    public function __construct() {
    }

    public function go() {
        $this->setup();
        $this->login_dialog->run();
        $this->login_dialog->destroy();
    }

    // setup the login dialog
    function setup() {
        $dialog = new GtkDialog('Login', null, Gtk::DIALOG_MODAL);
        $dialog->fullscreen();
        $vbox = $dialog->vbox;
        $vbox->pack_start(new GtkLabel());

        // display title
        $title = new GtkLabel("Login");
        $title->modify_font(new PangoFontDescription(
            "Times New Roman Italic 10"));
        $title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff"));
        $title->set_size_request(-1, 40);
        $vbox->pack_start($title, 0, 0);


        $field_labels = array("Username:", "Password:");
        $table = new GtkTable();
        $row = 0;
        $input = array();
        foreach ($field_labels as $field_label) {
            $label = new GtkLabel($field_label);
            $label->set_alignment(0,0);
            $table->attach($label, 0, 1, $row, $row+1);
            $input[$row] = new GtkEntry();
            $table->attach($input[$row], 1, 2, $row, $row+1);
            if (eregi("password", $field_label))
            $input[$row]->set_visibility(false);
            ++$row;
        }

        $vbox->pack_start($hbox = new GtkHBox(), 0);
        $vbox->pack_start(new GtkLabel());
        $hbox->pack_start(new GtkLabel());
        $hbox->pack_start($table, 0);
        $hbox->pack_start(new GtkLabel());

        $button_hbox = new GtkHBox();
        $button_ok = GtkButton::new_from_stock(Gtk::STOCK_OK);
        $button_ok->set_size_request(86, -1);
        $button_hbox->pack_start($button_ok, 0);
        $button_hbox->pack_start(new GtkLabel());
        $table->attach($button_hbox, 1, 2, $row, $row+1);
        ++$row;

        $status = new GtkLabel('    ');
        $table->attach($status, 1, 2, $row, $row+1);
        $button_ok->connect('clicked', array(&$this, 'on_button_ok'),
            $input, $status);

        $dialog->connect('key-press-event', array(&$this, 'on_key'),
            $button_ok, $status);
        $dialog->set_has_separator(false);
        $dialog->show_all();
        $this->login_dialog = $dialog;
    }

    public function on_button_ok($button, $input, $status) {
        $username = $input[0]->get_text();
        $passwd = $input[1]->get_text();

        if ($username=='') {
            $input[0]->grab_focus();
            return true;
        }
        if ($passwd=='') {
            $input[1]->grab_focus();
            return true;
        }
        if ($username!='' && $passwd!='') {
            if ($this->validate($username, $passwd)) {
                $this->login_success = 1;
                $this->login_dialog->destroy();
            } else {
                $status->set_text('invalid username/password');
            }
        }
    }

    protected function validate($username, $password) {
        if ($username=='user1' && $password=='phpgtk2') {
            return true;
        } else {
            return false;
        }
    }

    function on_key($widget, $event, $button_ok, $status) {
        $status->set_text('');
        if ($event->keyval==Gdk::KEY_Return) {
            $button_ok->clicked();
            return true;
        } else {
            return false;
        }
    }

}

?>
 

Explanation

Please refer to kiosk template #2.

Related Articles


Responses

  1. kksou:
    March 15, 2010 2:13am

    Is this article useful?

    Found any bugs?

    Improvements for the above article?

    Please enter below...

Leave a Reply

Name:
Country: (optional)
Your Comments:
ANTI-SPAM key:
 

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?