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;
  }

}