TrackManiaControl/libs/FML/Controls/Control.php

506 lines
12 KiB
PHP
Raw Normal View History

2014-01-03 17:18:14 +01:00
<?php
namespace FML\Controls;
2014-05-14 23:24:00 +02:00
use FML\Script\Builder;
2014-04-27 14:44:40 +02:00
use FML\Script\Features\ActionTrigger;
2014-05-14 23:24:00 +02:00
use FML\Script\Features\ControlScript;
2014-04-27 14:44:40 +02:00
use FML\Script\Features\MapInfo;
use FML\Script\Features\PlayerProfile;
2014-05-14 23:24:00 +02:00
use FML\Script\Features\ScriptFeature;
2014-04-27 14:44:40 +02:00
use FML\Script\Features\Toggle;
use FML\Script\Features\Tooltip;
2014-05-14 23:24:00 +02:00
use FML\Script\Features\UISound;
use FML\Script\ScriptLabel;
use FML\Types\Renderable;
use FML\Types\ScriptFeatureable;
2014-06-21 03:18:21 +02:00
use FML\UniqueID;
2014-01-03 17:18:14 +01:00
/**
2014-01-19 19:30:21 +01:00
* Base Control
2014-01-12 00:51:46 +01:00
* (CMlControl)
2014-01-03 17:18:14 +01:00
*
2014-05-20 15:44:45 +02:00
* @author steeffeen <mail@steeffeen.com>
2014-04-13 18:21:40 +02:00
* @copyright FancyManiaLinks Copyright © 2014 Steffen Schröder
2014-05-14 23:24:00 +02:00
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
2014-01-03 17:18:14 +01:00
*/
2014-04-27 14:44:40 +02:00
abstract class Control implements Renderable, ScriptFeatureable {
2014-01-21 20:30:40 +01:00
/*
2014-01-03 17:18:14 +01:00
* Constants
*/
2014-05-14 23:24:00 +02:00
const CENTER = 'center';
2014-01-03 17:18:14 +01:00
const CENTER2 = 'center2';
2014-05-14 23:24:00 +02:00
const TOP = 'top';
const RIGHT = 'right';
const BOTTOM = 'bottom';
const LEFT = 'left';
2014-04-13 18:21:40 +02:00
/*
2014-06-21 03:18:21 +02:00
* Protected properties
2014-01-03 17:18:14 +01:00
*/
protected $tagName = 'control';
2014-06-21 03:18:21 +02:00
protected $controlId = null;
protected $posX = 0.;
protected $posY = 0.;
protected $posZ = 0.;
2014-01-03 17:18:14 +01:00
protected $width = -1.;
protected $height = -1.;
protected $hAlign = self::CENTER;
protected $vAlign = self::CENTER2;
protected $scale = 1.;
2014-06-21 03:18:21 +02:00
protected $hidden = null;
protected $rotation = 0.;
/** @var string[] $classes */
2014-01-03 17:18:14 +01:00
protected $classes = array();
2014-06-21 03:18:21 +02:00
/** @var ScriptFeature[] $scriptFeatures */
2014-04-27 14:44:40 +02:00
protected $scriptFeatures = array();
2014-01-03 17:18:14 +01:00
/**
2014-06-21 03:18:21 +02:00
* Create a new Control object
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param string $controlId (optional) Control id
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
2014-06-21 03:18:21 +02:00
public static function create($controlId = null) {
return new static($controlId);
}
/**
* Construct a new Control object
*
* @param string $controlId (optional) Control id
*/
public function __construct($controlId = null) {
2014-08-11 23:15:53 +02:00
if ($controlId !== null) {
2014-06-21 03:18:21 +02:00
$this->setId($controlId);
2014-01-19 19:30:21 +01:00
}
2014-01-03 17:18:14 +01:00
}
2014-05-16 22:44:22 +02:00
/**
2014-06-21 03:18:21 +02:00
* Check Id for dangerous characters and assign a new unique id if necessary
2014-05-16 22:44:22 +02:00
*
2014-06-21 03:18:21 +02:00
* @param bool $forceNewId (optional) Whether to force setting a newly generated id
2014-07-03 22:34:47 +02:00
* @return static
2014-05-16 22:44:22 +02:00
*/
public function checkId($forceNewId = false) {
if ($forceNewId || !$this->getId()) {
2014-06-21 03:18:21 +02:00
$this->setId(new UniqueID());
2014-05-16 22:44:22 +02:00
return $this;
}
$dangerousCharacters = array(' ', ' ', '.', '|', '-', PHP_EOL);
$idCharacters = str_split($this->getId());
$danger = false;
foreach ($idCharacters as $character) {
if (!in_array($character, $dangerousCharacters)) {
continue;
}
$danger = true;
break;
}
if ($danger) {
2014-06-21 03:18:21 +02:00
trigger_error("Please don't use special characters in ids, they might cause problems! (I stripped them for you.)");
$controlId = str_ireplace($dangerousCharacters, '', $this->getId());
$this->setId($controlId);
2014-05-16 22:44:22 +02:00
}
return $this;
}
2014-01-03 17:18:14 +01:00
/**
2014-06-21 03:18:21 +02:00
* Get the Control id
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param bool $escaped (optional) Whether the id should be escaped for ManiaScript
* @param bool $addApostrophes (optional) Whether to add apostrophes before and after the text
2014-01-03 17:18:14 +01:00
* @return string
*/
2014-06-21 03:18:21 +02:00
public function getId($escaped = false, $addApostrophes = false) {
2014-04-27 14:44:40 +02:00
if ($escaped) {
2014-06-21 03:18:21 +02:00
return Builder::escapeText($this->controlId, $addApostrophes);
2014-04-27 14:44:40 +02:00
}
2014-06-21 03:18:21 +02:00
return $this->controlId;
2014-01-03 17:18:14 +01:00
}
/**
2014-06-21 03:18:21 +02:00
* Set Control id
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param string $controlId Control id
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
2014-06-21 03:18:21 +02:00
public function setId($controlId) {
$this->controlId = (string)$controlId;
2014-01-03 17:18:14 +01:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set Control position
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param float $posX Horizontal position
* @param float $posY Vertical position
* @param float $posZ (optional) Depth
2014-07-03 22:34:47 +02:00
* @return static
2014-06-21 03:18:21 +02:00
*/
public function setPosition($posX, $posY, $posZ = null) {
$this->setX($posX);
$this->setY($posY);
2014-08-11 23:15:53 +02:00
if ($posZ !== null) {
2014-06-21 03:18:21 +02:00
$this->setZ($posZ);
2014-01-03 17:18:14 +01:00
}
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set X position
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param float $posX Horizontal position
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
2014-06-21 03:18:21 +02:00
public function setX($posX) {
$this->posX = (float)$posX;
2014-01-03 17:18:14 +01:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set Y position
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param float $posY Vertical position
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
2014-06-21 03:18:21 +02:00
public function setY($posY) {
$this->posY = (float)$posY;
2014-01-03 17:18:14 +01:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set Z position
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param float $posZ Depth
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
2014-06-21 03:18:21 +02:00
public function setZ($posZ) {
$this->posZ = (float)$posZ;
2014-01-03 17:18:14 +01:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set Control size
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param float $width Control width
* @param float $height Control height
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
2014-05-16 22:44:22 +02:00
public function setSize($width, $height) {
$this->setWidth($width);
$this->setHeight($height);
2014-01-03 17:18:14 +01:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set Control width
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param float $width Control width
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
public function setWidth($width) {
2014-05-14 23:24:00 +02:00
$this->width = (float)$width;
2014-01-03 17:18:14 +01:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set Control height
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param float $height Control height
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
public function setHeight($height) {
2014-05-14 23:24:00 +02:00
$this->height = (float)$height;
2014-01-03 17:18:14 +01:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Center alignment
2014-01-03 17:18:14 +01:00
*
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
2014-05-16 22:44:22 +02:00
public function centerAlign() {
$this->setAlign(self::CENTER, self::CENTER2);
2014-01-03 17:18:14 +01:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set horizontal and vertical alignment
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param string $hAlign Horizontal alignment
* @param string $vAlign Vertical alignment
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
2014-05-16 22:44:22 +02:00
public function setAlign($hAlign, $vAlign) {
$this->setHAlign($hAlign);
$this->setVAlign($vAlign);
2014-01-03 17:18:14 +01:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set horizontal alignment
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param string $hAlign Horizontal alignment
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
2014-05-16 22:44:22 +02:00
public function setHAlign($hAlign) {
$this->hAlign = (string)$hAlign;
2014-01-03 17:18:14 +01:00
return $this;
}
2014-05-14 23:24:00 +02:00
/**
2014-06-21 03:18:21 +02:00
* Set vertical alignment
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param string $vAlign Vertical alignment
2014-07-03 22:34:47 +02:00
* @return static
2014-05-14 23:24:00 +02:00
*/
2014-05-16 22:44:22 +02:00
public function setVAlign($vAlign) {
$this->vAlign = (string)$vAlign;
2014-05-14 23:24:00 +02:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Reset alignment
2014-05-14 23:24:00 +02:00
*
2014-07-03 22:34:47 +02:00
* @return static
2014-05-14 23:24:00 +02:00
*/
public function resetAlign() {
$this->setAlign(null, null);
return $this;
}
2014-01-03 17:18:14 +01:00
/**
2014-06-21 03:18:21 +02:00
* Set Control scale
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param float $scale Control scale
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
public function setScale($scale) {
2014-05-14 23:24:00 +02:00
$this->scale = (float)$scale;
2014-01-03 17:18:14 +01:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set visibility
2014-01-03 17:18:14 +01:00
*
2014-06-21 03:18:21 +02:00
* @param bool $visible Whether the Control should be visible
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
2014-05-14 23:24:00 +02:00
public function setVisible($visible = true) {
2014-01-03 17:18:14 +01:00
$this->hidden = ($visible ? 0 : 1);
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set Control rotation
2014-01-03 17:18:14 +01:00
*
2014-07-03 22:34:47 +02:00
* @param float $rotation Control rotation
* @return static
2014-06-21 03:18:21 +02:00
*/
public function setRotation($rotation) {
$this->rotation = (float)$rotation;
return $this;
}
/**
* Add a new class name
*
* @param string $class Class name
2014-07-03 22:34:47 +02:00
* @return static
2014-01-03 17:18:14 +01:00
*/
public function addClass($class) {
2014-05-14 23:24:00 +02:00
$class = (string)$class;
2014-01-03 17:18:14 +01:00
if (!in_array($class, $this->classes)) {
array_push($this->classes, $class);
}
return $this;
}
2014-04-27 14:44:40 +02:00
/**
* Add a dynamic Action Trigger
*
* @param string $actionName Action to trigger
2014-06-21 03:18:21 +02:00
* @param string $eventLabel (optional) Event on which the action is triggered
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function addActionTriggerFeature($actionName, $eventLabel = ScriptLabel::MOUSECLICK) {
2014-08-11 23:15:53 +02:00
if ($actionName instanceof ActionTrigger) {
2014-06-21 03:18:21 +02:00
$this->addScriptFeature($actionName);
} else {
$actionTrigger = new ActionTrigger($actionName, $this, $eventLabel);
$this->addScriptFeature($actionTrigger);
}
2014-04-27 14:44:40 +02:00
return $this;
}
2014-05-16 22:44:22 +02:00
/**
2014-06-21 03:18:21 +02:00
* Add a new Script Feature
2014-05-16 22:44:22 +02:00
*
* @param ScriptFeature $scriptFeature Script Feature
2014-07-03 22:34:47 +02:00
* @return static
2014-05-16 22:44:22 +02:00
*/
public function addScriptFeature(ScriptFeature $scriptFeature) {
2014-06-21 03:18:21 +02:00
if (!in_array($scriptFeature, $this->scriptFeatures, true)) {
array_push($this->scriptFeatures, $scriptFeature);
}
2014-05-16 22:44:22 +02:00
return $this;
}
2014-04-27 14:44:40 +02:00
/**
2014-06-21 03:18:21 +02:00
* Add a dynamic Feature opening the current map info
2014-04-27 14:44:40 +02:00
*
2014-06-21 03:18:21 +02:00
* @param string $eventLabel (optional) Event on which the map info will be opened
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function addMapInfoFeature($eventLabel = ScriptLabel::MOUSECLICK) {
$mapInfo = new MapInfo($this, $eventLabel);
2014-05-14 23:24:00 +02:00
$this->addScriptFeature($mapInfo);
2014-04-27 14:44:40 +02:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Add a dynamic Feature to open a specific player profile
2014-04-27 14:44:40 +02:00
*
2014-06-21 03:18:21 +02:00
* @param string $login Login of the player
* @param string $eventLabel (optional) Event on which the player profile will be opened
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function addPlayerProfileFeature($login, $eventLabel = ScriptLabel::MOUSECLICK) {
$playerProfile = new PlayerProfile($login, $this, $eventLabel);
2014-05-14 23:24:00 +02:00
$this->addScriptFeature($playerProfile);
2014-04-27 14:44:40 +02:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Add a dynamic Feature playing a UISound
2014-04-27 14:44:40 +02:00
*
2014-06-21 03:18:21 +02:00
* @param string $soundName UISound name
* @param int $variant (optional) Sound variant
* @param string $eventLabel (optional) Event on which the sound will be played
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function addUISoundFeature($soundName, $variant = 0, $eventLabel = ScriptLabel::MOUSECLICK) {
$uiSound = new UISound($soundName, $this, $variant, $eventLabel);
2014-05-14 23:24:00 +02:00
$this->addScriptFeature($uiSound);
2014-04-27 14:44:40 +02:00
return $this;
}
/**
* Add a dynamic Feature toggling another Control
*
* @param Control $toggledControl Toggled Control
2014-06-21 03:18:21 +02:00
* @param string $labelName (optional) Script label name
* @param bool $onlyShow (optional) Whether it should only show the Control but not toggle
* @param bool $onlyHide (optional) Whether it should only hide the Control but not toggle
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function addToggleFeature(Control $toggledControl, $labelName = Scriptlabel::MOUSECLICK, $onlyShow = false, $onlyHide = false) {
$toggle = new Toggle($this, $toggledControl, $labelName, $onlyShow, $onlyHide);
2014-05-14 23:24:00 +02:00
$this->addScriptFeature($toggle);
2014-04-27 14:44:40 +02:00
return $this;
}
/**
* Add a dynamic Feature showing a Tooltip on hovering
*
* @param Control $tooltipControl Tooltip Control
2014-06-21 03:18:21 +02:00
* @param bool $stayOnClick (optional) Whether the Tooltip should stay on click
* @param bool $invert (optional) Whether the visibility toggling should be inverted
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function addTooltipFeature(Control $tooltipControl, $stayOnClick = false, $invert = false) {
$tooltip = new Tooltip($this, $tooltipControl, $stayOnClick, $invert);
2014-05-14 23:24:00 +02:00
$this->addScriptFeature($tooltip);
2014-04-27 14:44:40 +02:00
return $this;
}
/**
* Add a dynamic Feature showing a Tooltip on hovering
*
2014-05-14 23:24:00 +02:00
* @param Label $tooltipControl Tooltip Control
2014-06-21 03:18:21 +02:00
* @param string $text Text to display on the Tooltip Label
* @param bool $stayOnClick (optional) Whether the Tooltip should stay on click
* @param bool $invert (optional) Whether the visibility toggling should be inverted
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function addTooltipLabelFeature(Label $tooltipControl, $text, $stayOnClick = false, $invert = false) {
$tooltip = new Tooltip($this, $tooltipControl, $stayOnClick, $invert, $text);
2014-05-14 23:24:00 +02:00
$this->addScriptFeature($tooltip);
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Add a custom Control Script text part
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param string $scriptText Script text
* @param string $label (optional) Script label name
2014-07-03 22:34:47 +02:00
* @return static
2014-05-14 23:24:00 +02:00
*/
2014-05-16 22:44:22 +02:00
public function addScriptText($scriptText, $label = ScriptLabel::MOUSECLICK) {
$customText = new ControlScript($this, $scriptText, $label);
2014-05-14 23:24:00 +02:00
$this->addScriptFeature($customText);
return $this;
}
2014-04-27 19:22:20 +02:00
/**
* Remove all Script Features
2014-05-14 23:24:00 +02:00
*
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 19:22:20 +02:00
*/
public function removeScriptFeatures() {
$this->scriptFeatures = array();
return $this;
}
2014-05-14 23:24:00 +02:00
2014-04-27 14:44:40 +02:00
/**
* @see \FML\Types\ScriptFeatureable::getScriptFeatures()
*/
public function getScriptFeatures() {
return $this->scriptFeatures;
}
2014-01-03 17:18:14 +01:00
/**
* @see \FML\Types\Renderable::render()
*/
public function render(\DOMDocument $domDocument) {
2014-01-12 00:51:46 +01:00
$xmlElement = $domDocument->createElement($this->tagName);
2014-06-21 03:18:21 +02:00
if ($this->controlId) {
$xmlElement->setAttribute('id', $this->controlId);
2014-01-03 17:18:14 +01:00
}
2014-06-21 03:18:21 +02:00
if ($this->posX || $this->posY || $this->posZ) {
$xmlElement->setAttribute('posn', "{$this->posX} {$this->posY} {$this->posZ}");
2014-01-03 17:18:14 +01:00
}
if ($this->width >= 0. || $this->height >= 0.) {
2014-01-12 00:51:46 +01:00
$xmlElement->setAttribute('sizen', "{$this->width} {$this->height}");
2014-01-03 17:18:14 +01:00
}
2014-06-21 03:18:21 +02:00
if ($this->hAlign !== self::LEFT) {
2014-01-12 00:51:46 +01:00
$xmlElement->setAttribute('halign', $this->hAlign);
2014-01-03 17:18:14 +01:00
}
2014-06-21 03:18:21 +02:00
if ($this->vAlign !== self::TOP) {
2014-01-12 00:51:46 +01:00
$xmlElement->setAttribute('valign', $this->vAlign);
2014-01-03 17:18:14 +01:00
}
2014-01-12 00:51:46 +01:00
if ($this->scale != 1.) {
$xmlElement->setAttribute('scale', $this->scale);
2014-01-03 17:18:14 +01:00
}
if ($this->hidden) {
2014-01-12 00:51:46 +01:00
$xmlElement->setAttribute('hidden', $this->hidden);
2014-01-03 17:18:14 +01:00
}
2014-06-21 03:18:21 +02:00
if ($this->rotation) {
$xmlElement->setAttribute('rot', $this->rotation);
}
2014-01-12 00:51:46 +01:00
if (!empty($this->classes)) {
2014-04-27 14:44:40 +02:00
$classes = implode(' ', $this->classes);
2014-01-12 00:51:46 +01:00
$xmlElement->setAttribute('class', $classes);
2014-01-03 17:18:14 +01:00
}
2014-01-12 00:51:46 +01:00
return $xmlElement;
2014-01-03 17:18:14 +01:00
}
2014-05-16 22:44:22 +02:00
/**
2014-06-21 03:18:21 +02:00
* Get the ManiaScript class of the Control
2014-05-16 22:44:22 +02:00
*
* @return string
*/
public abstract function getManiaScriptClass();
2014-01-03 17:18:14 +01:00
}