TrackManiaControl/libs/FML/Script/Features/Paging.php

349 lines
9.7 KiB
PHP
Raw Normal View History

2014-04-27 14:44:40 +02:00
<?php
namespace FML\Script\Features;
use FML\Controls\Control;
use FML\Controls\Label;
2014-05-14 23:24:00 +02:00
use FML\Script\Builder;
use FML\Script\Script;
2014-04-27 14:44:40 +02:00
use FML\Script\ScriptInclude;
2014-05-14 23:24:00 +02:00
use FML\Script\ScriptLabel;
2014-04-27 14:44:40 +02:00
/**
2014-06-21 03:18:21 +02:00
* Script Feature realising a mechanism for browsing through Pages
2014-05-14 23:24:00 +02:00
*
2014-05-20 15:44:45 +02:00
* @author steeffeen <mail@steeffeen.com>
2014-04-27 14:44: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-04-27 14:44:40 +02:00
*/
class Paging extends ScriptFeature {
/*
* Constants
*/
2014-05-14 23:24:00 +02:00
const VAR_CURRENT_PAGE = 'FML_Paging_CurrentPage';
2014-04-27 14:44:40 +02:00
const FUNCTION_UPDATE_CURRENT_PAGE = 'FML_UpdateCurrentPage';
2014-05-14 23:24:00 +02:00
2014-04-27 14:44:40 +02:00
/*
2014-06-21 03:18:21 +02:00
* Protected properties
2014-04-27 14:44:40 +02:00
*/
2014-06-21 03:18:21 +02:00
/** @var PagingPage[] $pages */
2014-04-27 14:44:40 +02:00
protected $pages = array();
2014-06-21 03:18:21 +02:00
/** @var PagingButton[] $buttons */
2014-04-27 14:44:40 +02:00
protected $buttons = array();
2014-05-14 23:24:00 +02:00
/** @var Label $label */
2014-04-27 14:44:40 +02:00
protected $label = null;
2014-04-28 16:59:55 +02:00
protected $startPageNumber = null;
2014-04-27 14:44:40 +02:00
protected $customMaxPageNumber = null;
protected $previousChunkAction = null;
protected $nextChunkAction = null;
protected $chunkActionAppendsPageNumber = null;
/**
* Construct a new Paging Script Feature
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param Label $label (optional) Page number Label
2014-04-27 14:44:40 +02:00
*/
public function __construct(Label $label = null) {
2014-08-11 23:15:53 +02:00
if ($label !== null) {
2014-04-27 14:44:40 +02:00
$this->setLabel($label);
}
}
/**
* Add a new Page Control
2014-05-14 23:24:00 +02:00
*
2014-04-27 14:44:40 +02:00
* @param Control $pageControl Page Control
2014-06-21 03:18:21 +02:00
* @param string $pageNumber (optional) Page number
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function addPage(Control $pageControl, $pageNumber = null) {
2014-08-11 23:15:53 +02:00
if ($pageNumber === null) {
2014-04-27 14:44:40 +02:00
$pageNumber = count($this->pages) + 1;
}
$page = new PagingPage($pageControl, $pageNumber);
$this->appendPage($page);
return $this;
}
/**
* Append a Page
2014-05-14 23:24:00 +02:00
*
2014-04-27 14:44:40 +02:00
* @param PagingPage $page Paging Page
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function appendPage(PagingPage $page) {
2014-06-21 03:18:21 +02:00
if (!in_array($page, $this->pages, true)) {
array_push($this->pages, $page);
}
2014-04-27 14:44:40 +02:00
return $this;
}
/**
* Add a new Button to browse through the Pages
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param Control $buttonControl Button used for browsing
* @param int $browseAction (optional) Number of browsed Pages per click
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function addButton(Control $buttonControl, $browseAction = null) {
2014-08-11 23:15:53 +02:00
if ($browseAction === null) {
2014-04-27 14:44:40 +02:00
$buttonCount = count($this->buttons);
if ($buttonCount % 2 === 0) {
$browseAction = $buttonCount / 2 + 1;
2014-05-14 23:24:00 +02:00
} else {
2014-04-27 14:44:40 +02:00
$browseAction = $buttonCount / -2 - 1;
}
}
$button = new PagingButton($buttonControl, $browseAction);
$this->appendButton($button);
return $this;
}
/**
* Append a Button to browse through Pages
2014-05-14 23:24:00 +02:00
*
2014-04-27 14:44:40 +02:00
* @param PagingButton $button Paging Button
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function appendButton(PagingButton $button) {
2014-06-21 03:18:21 +02:00
if (!in_array($button, $this->buttons, true)) {
array_push($this->buttons, $button);
}
2014-04-27 14:44:40 +02:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set the Label showing the Page number
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param Label $label Page number Label
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function setLabel(Label $label) {
2014-06-21 03:18:21 +02:00
$this->label = $label->checkId();
2014-04-27 14:44:40 +02:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set the Start Page number
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param int $startPageNumber Page number to start with
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
2014-04-28 16:59:55 +02:00
public function setStartPageNumber($startPageNumber) {
2014-05-14 23:24:00 +02:00
$this->startPageNumber = (int)$startPageNumber;
2014-04-27 14:44:40 +02:00
}
/**
2014-06-21 03:18:21 +02:00
* Set a custom maximum Page number for using chunks
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param int $maxPageNumber Custom maximum Page number
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function setCustomMaxPageNumber($maxPageNumber) {
2014-05-14 23:24:00 +02:00
$this->customMaxPageNumber = (int)$maxPageNumber;
2014-04-27 14:44:40 +02:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set the action triggered when the previous chunk is needed
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param string $previousChunkAction Triggered action
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function setPreviousChunkAction($previousChunkAction) {
2014-05-14 23:24:00 +02:00
$this->previousChunkAction = (string)$previousChunkAction;
2014-04-27 14:44:40 +02:00
return $this;
}
/**
2014-06-21 03:18:21 +02:00
* Set the action triggered when the next chunk is needed
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param string $nextChunkAction Triggered action
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function setNextChunkAction($nextChunkAction) {
2014-05-14 23:24:00 +02:00
$this->nextChunkAction = (string)$nextChunkAction;
2014-04-27 14:44:40 +02:00
return $this;
}
2014-04-28 16:59:55 +02:00
/**
2014-06-21 03:18:21 +02:00
* Set the actions triggered when another chunk is needed
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param string $chunkAction Triggered action
2014-07-03 22:34:47 +02:00
* @return static
2014-04-28 16:59:55 +02:00
*/
public function setChunkActions($chunkAction) {
$this->setNextChunkAction($chunkAction);
$this->setPreviousChunkAction($chunkAction);
return $this;
}
2014-04-27 14:44:40 +02:00
/**
2014-06-21 03:18:21 +02:00
* Set if the chunk action should get the needed Page number appended
2014-05-14 23:24:00 +02:00
*
2014-06-21 03:18:21 +02:00
* @param bool $appendPageNumber Whether to append the needed Page number
2014-07-03 22:34:47 +02:00
* @return static
2014-04-27 14:44:40 +02:00
*/
public function setChunkActionAppendsPageNumber($appendPageNumber) {
2014-05-14 23:24:00 +02:00
$this->chunkActionAppendsPageNumber = (bool)$appendPageNumber;
2014-04-27 14:44:40 +02:00
return $this;
}
/**
* @see \FML\Script\Features\ScriptFeature::prepare()
*/
public function prepare(Script $script) {
2014-06-21 03:18:21 +02:00
if (empty($this->pages)) {
2014-04-27 16:31:46 +02:00
return $this;
}
2014-04-27 14:44:40 +02:00
$script->setScriptInclude(ScriptInclude::TEXTLIB);
2014-05-14 23:24:00 +02:00
2014-04-27 14:44:40 +02:00
$currentPageVariable = self::VAR_CURRENT_PAGE;
2014-05-14 23:24:00 +02:00
$updatePageFunction = self::FUNCTION_UPDATE_CURRENT_PAGE;
$minPageNumber = 1;
2014-04-28 16:59:55 +02:00
$startPageNumber = (is_int($this->startPageNumber) ? $this->startPageNumber : $minPageNumber);
2014-05-14 23:24:00 +02:00
$maxPage = $this->getMaxPage();
$maxPageNumber = $this->customMaxPageNumber;
2014-04-28 16:59:55 +02:00
if (!is_int($maxPageNumber)) {
$maxPageNumber = $maxPage->getPageNumber();
2014-04-27 14:44:40 +02:00
}
2014-05-14 23:24:00 +02:00
2014-06-21 03:18:21 +02:00
$pagingId = $maxPage->getControl()->getId(true, true);
$pageLabelId = '""';
2014-04-27 17:21:38 +02:00
if ($this->label) {
2014-06-21 03:18:21 +02:00
$pageLabelId = $this->label->getId(true, true);
2014-04-27 17:21:38 +02:00
}
2014-05-14 23:24:00 +02:00
$pagesArrayText = $this->getPagesArrayText();
2014-04-27 14:44:40 +02:00
$pageButtonsArrayText = $this->getPageButtonsArrayText();
2014-05-14 23:24:00 +02:00
2014-06-21 03:18:21 +02:00
$previousChunkAction = Builder::escapeText($this->previousChunkAction, true);
$nextChunkAction = Builder::escapeText($this->nextChunkAction, true);
2014-04-27 14:44:40 +02:00
$chunkActionAppendsPageNumber = Builder::getBoolean($this->chunkActionAppendsPageNumber);
2014-05-14 23:24:00 +02:00
2014-04-27 14:44:40 +02:00
// Init
$initScriptText = "
declare {$currentPageVariable} for This = Integer[Text];
2014-06-21 03:18:21 +02:00
{$currentPageVariable}[{$pagingId}] = {$startPageNumber};
{$updatePageFunction}({$pagingId}, {$pageLabelId}, 0, {$minPageNumber}, {$maxPageNumber}, {$pagesArrayText}, {$previousChunkAction}, {$nextChunkAction}, {$chunkActionAppendsPageNumber});";
2014-04-27 14:44:40 +02:00
$script->appendGenericScriptLabel(ScriptLabel::ONINIT, $initScriptText, true);
2014-05-14 23:24:00 +02:00
2014-04-27 14:44:40 +02:00
// MouseClick
$clickScriptText = "
declare PageButtons = {$pageButtonsArrayText};
if (PageButtons.existskey(Event.Control.ControlId)) {
declare BrowseAction = PageButtons[Event.Control.ControlId];
2014-06-21 03:18:21 +02:00
{$updatePageFunction}({$pagingId}, {$pageLabelId}, BrowseAction, {$minPageNumber}, {$maxPageNumber}, {$pagesArrayText}, {$previousChunkAction}, {$nextChunkAction}, {$chunkActionAppendsPageNumber});
2014-04-27 14:44:40 +02:00
}";
$script->appendGenericScriptLabel(ScriptLabel::MOUSECLICK, $clickScriptText, true);
2014-05-14 23:24:00 +02:00
2014-04-27 14:44:40 +02:00
// Update function
$functionText = "
Void {$updatePageFunction}(Text _PagingId, Text _PageLabelId, Integer _BrowseAction, Integer _MinPageNumber, Integer _MaxPageNumber, Text[Integer] _Pages, Text _PreviousChunkAction, Text _NextChunkAction, Boolean _ChunkActionAppendPageNumber) {
declare {$currentPageVariable} for This = Integer[Text];
if (!{$currentPageVariable}.existskey(_PagingId)) return;
declare CurrentPage = {$currentPageVariable}[_PagingId] + _BrowseAction;
if (CurrentPage < _MinPageNumber) {
CurrentPage = _MinPageNumber;
} else if (CurrentPage > _MaxPageNumber) {
CurrentPage = _MaxPageNumber;
}
{$currentPageVariable}[_PagingId] = CurrentPage;
declare PageFound = False;
foreach (PageNumber => PageId in _Pages) {
declare PageControl <=> Page.GetFirstChild(PageId);
PageControl.Visible = (CurrentPage == PageNumber);
if (PageControl.Visible) {
PageFound = True;
}
}
if (!PageFound && _BrowseAction != 0) {
declare Text ChunkAction;
if (_BrowseAction < 0) {
ChunkAction = _PreviousChunkAction;
} else {
ChunkAction = _NextChunkAction;
}
if (_ChunkActionAppendPageNumber) {
ChunkAction ^= CurrentPage;
}
TriggerPageAction(ChunkAction);
}
2014-06-21 03:18:21 +02:00
if (_PageLabelId == " . Builder::EMPTY_STRING . ") return;
2014-04-27 14:44:40 +02:00
declare PageLabel <=> (Page.GetFirstChild(_PageLabelId) as CMlLabel);
if (PageLabel == Null) return;
PageLabel.Value = CurrentPage^\"/\"^_MaxPageNumber;
}";
$script->addScriptFunction($updatePageFunction, $functionText);
return $this;
}
2014-04-28 16:59:55 +02:00
2014-04-27 14:44:40 +02:00
/**
* Get the minimum Page
2014-05-14 23:24:00 +02:00
*
2014-04-27 14:44:40 +02:00
* @return \FML\Script\Features\PagingPage
*/
protected function getMinPage() {
$minPageNumber = null;
2014-05-14 23:24:00 +02:00
$minPage = null;
2014-04-27 14:44:40 +02:00
foreach ($this->pages as $page) {
$pageNumber = $page->getPageNumber();
2014-08-11 23:15:53 +02:00
if ($minPageNumber === null || $pageNumber < $minPageNumber) {
2014-04-27 14:44:40 +02:00
$minPageNumber = $pageNumber;
2014-05-14 23:24:00 +02:00
$minPage = $page;
2014-04-27 14:44:40 +02:00
}
}
return $minPage;
}
/**
* Get the maximum Page
2014-05-14 23:24:00 +02:00
*
2014-04-27 14:44:40 +02:00
* @return \FML\Script\Features\PagingPage
*/
protected function getMaxPage() {
$maxPageNumber = null;
2014-05-14 23:24:00 +02:00
$maxPage = null;
2014-04-27 14:44:40 +02:00
foreach ($this->pages as $page) {
$pageNumber = $page->getPageNumber();
2014-08-11 23:15:53 +02:00
if ($maxPageNumber === null || $pageNumber > $maxPageNumber) {
2014-04-27 14:44:40 +02:00
$maxPageNumber = $pageNumber;
2014-05-14 23:24:00 +02:00
$maxPage = $page;
2014-04-27 14:44:40 +02:00
}
}
return $maxPage;
}
/**
2014-06-21 03:18:21 +02:00
* Build the array text for the Pages
2014-05-14 23:24:00 +02:00
*
2014-04-27 14:44:40 +02:00
* @return string
*/
protected function getPagesArrayText() {
2014-06-21 03:18:21 +02:00
if (empty($this->pages)) {
return Builder::getArray(array(0 => ''), true);
}
2014-04-27 14:44:40 +02:00
$pages = array();
foreach ($this->pages as $page) {
2014-06-21 03:18:21 +02:00
$pages[$page->getPageNumber()] = $page->getControl()->getId();
2014-04-27 14:44:40 +02:00
}
return Builder::getArray($pages, true);
}
/**
2014-06-21 03:18:21 +02:00
* Build the array text for the Page Buttons
2014-05-14 23:24:00 +02:00
*
2014-04-27 14:44:40 +02:00
* @return string
*/
protected function getPageButtonsArrayText() {
2014-06-21 03:18:21 +02:00
if (empty($this->buttons)) {
return Builder::getArray(array('' => 0), true);
2014-04-27 18:59:21 +02:00
}
2014-04-27 14:44:40 +02:00
$pageButtons = array();
foreach ($this->buttons as $pageButton) {
2014-06-21 03:18:21 +02:00
$pageButtons[$pageButton->getControl()->getId()] = $pageButton->getBrowseAction();
2014-04-27 14:44:40 +02:00
}
return Builder::getArray($pageButtons, true);
}
}