File source

<?php
/** Base class for one terminal screen **/
class Screen{
  
// every subclass should provide unique ID
  
protected $id "";
  
// timeout for screen, if no user interaction happens
  // in this timeout, screen is refreshed anyway
  
protected $timeout 5000;
  
// array of touch regions
  
protected $touchStack = Array();

  
/* constructor */
  
function __construct(){

  }

  
/* returns ID of screen */
  
function id(){
    return 
$this->id;
  }

  
/* sets or gets timeout for this screen */
  
function timeout($n false){
    if(
$n === false) return $this->timeout;
    
$this->timeout $n;
    return 
$this;
  }

  
/* gets called from screen manager */
  
function work(){
    
$this->handleTouch();
    
$r $this->render();
    
$this->touchClear();
    return 
$r;
  }

  
/* returns an array with keys:
    action => "nothing" = do nothing
    -- OR --
    action => "image"   = send image to device
    image => GD image to send
    destroy => true to destroy image after use(default)
    -- OR --
    action => "screen"  = switch to other screen
    id => id of screen to switch to
    params => array of parameters to pass to Screen instance
              we are switching to
  */
  
function render(){
    return 
$this->nothing();
  }

  
/* helper */
  
function nothing(){
    return Array(
"action"=>"nothing");
  }

  function 
image($i$destroy true){
    return Array(
"action"=>"image""image"=>$i"destroy"=>$destroy);
  }

  function 
screen($id$params false){
    return Array(
"action"=>"screen""id"=>$id,"params"=>$params);
  }

  
/* gets called when other screen switches to this instance */
  
function activate($params){

  }

  
/* register touch on $x,$y coordinates
   ! rotated by 90 deg -  landscape
   (called from ScreenManager)
  */
  
function touch($x,$y){
    foreach (
$this->touchStack as &$btn) {
      if(
$btn["x"]<= $x && $btn["x"]+$btn["w"]>= $x && $btn["y"]<= $y && $btn["y"]+$btn["h"]>= $y){
        
$btn["touched"] = true;
      }
    }
  }

  
/* unmark all touched regions */
  
function touchClear(){
    foreach (
$this->touchStack as &$btn) {
      
$btn["touched"] = false;
    }
  }

  
/* returns true if region $id was touched */
  
function touched($id){
    return 
$this->touchStack[$id]["touched"];
  }

  
/* push region to stack
    $id = id of refion
    $x,$y,$w,$h = coordinates, width, height
    $action = default action of touch
  */
  
function touchPush($id,$x,$y,$w,$h,$action false){
    
$this->touchStack[$id] = Array(
      
"id" => $id,
      
"x" => $x,
      
"y" => $y,
      
"w" => $w,
      
"h" => $h,
      
"action" => $action,
      
"touched" => false
    
);
  }

  
/* pop from region stack */
  
function touchPop($id){
    unset(
$this->touchStack[$id]);
  }

  
/* handle touches - handle default actions 
     unmark handled regions, leave others
  */
  
function handleTouch(){
    foreach(
$this->touchStack as $id => &$btn){
      if(
$btn["touched"] && $btn["action"]){
        if(
$this->handleAction($btn["action"])){
          
$btn["touched"] = false;
        }
      }
    }
  }

  
/* handle action named $action and return true if action was handled */
  
function handleAction($action){
    return 
false;
  }

}