File source

<?php
/** Home screen
 - shows date, time
 - weather
 - upcoming calendar events
 - garage door status
*/
class HomeScreen extends Screen{

  protected $id = "home";
  protected $weatherSource;
  protected $calendarSource;
  protected $garageSource;
  protected $lastGarageClosed = true;

  function __construct($weatherSource, $calendarSource, $garageSource){
    $this->weatherSource = $weatherSource;
    $this->calendarSource = $calendarSource;
    $this->garageSource = $garageSource;
    $this->touchPush("weather_btn", 0,40,160,50);
  }

  function renderAppointment($img, $top, $day, $text){
    $black = imagecolorallocate($img, 0, 0, 0);
    $white = imagecolorallocate($img, 255, 255, 255);
    imagefilledrectangle($img, 0, $top, 40, $top+28, $black);
    imagettftext($img, 8, 0, 2, $top+10, $white, "./arial.ttf", $day);
    imagettftext($img, 10,0, 45, $top+20, $black, "./arialbd.ttf", $text);
  }

  function render(){
    if($this->touched("weather_btn")){
      return $this->screen("weather", Array("return"=>"home"));
    }
    $garage = false;

    if($this->garageSource){
      $garage = $this->garageSource->getData();
      if(! $garage["closed"] && $this->lastGarageClosed){
        $this->lastGarageClosed = false;
        return $this->screen("garage", Array("return" => "home"));
      }else{
        $this->lastGarageClosed = $garage["closed"];
      }
    }

    $img = screen();
    $black = imagecolorallocate($img, 0, 0, 0);
    $white = imagecolorallocate($img, 255, 255, 255);
    // time
    imagettfcenter($img, 20, 0, 160/2, 25, $black, "./arialbd.ttf", Date("H:i"));
    // date
    imagettfcenter($img, 8, 0, 160/2, 35, $black, "./arial.ttf", Date("d.m.Y"));
    
    //weather
    $w  = $this->weatherSource->getData();
    imageline($img, 0, 40, 160, 40, $black);
    $icon = imagecreatefrompng("icons/".$w["icon"].".png");
    pasteCenter($img, $icon, 25, 64);
    imagedestroy($icon);
    imagettftext($img, 25, 0, 60, 70, $black, "./arialbd.ttf", number_format($w["temp"],1)."°C");
    imagettftext($img, 8, 0, 60, 85, $black, "./arial.ttf", $w["text"]);
    
    //appointments
    imageline($img, 0, 90, 160, 90, $black);
    $data = $this->calendarSource->getData(2);
    $top = 90;
    foreach($data as $app){
      $this->renderAppointment($img, $top, $this->calendarSource->getRelativeDate($app["date"]), $app["text"]);  
      $top+=30;
    }    

    //garage door
    if($this->garageSource){
      if($garage["closed"]){
        $icon = imagecreatefrompng("icons/closed-small.png");
        paste($img, $icon, 135,140);
        imagedestroy($icon);
      }else{
        $icon = imagecreatefrompng("icons/open-small.png");
        paste($img, $icon, 135,140);
        imagedestroy($icon);
      }
    }
    return $this->image($img);
  }
}