Added logic

This commit is contained in:
MEFRREEX
2024-01-18 17:07:18 +02:00
parent b3d449c1b3
commit 3db5312678
35 changed files with 1836 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace com\formconstructor;
use com\formconstructor\form\CustomForm;
use com\formconstructor\form\element\custom\Dropdown;
use com\formconstructor\form\element\custom\Input;
use com\formconstructor\form\element\custom\Slider;
use com\formconstructor\form\element\custom\StepSlider;
use com\formconstructor\form\element\custom\Toggle;
use com\formconstructor\form\element\SelectableElement;
use com\formconstructor\form\element\simple\Button;
use com\formconstructor\form\element\simple\ImageType;
use com\formconstructor\form\response\CustomFormResponse;
use com\formconstructor\form\SimpleForm;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\event\Listener;
use pocketmine\player\Player;
use pocketmine\plugin\PluginBase;
class FormConstructor extends PluginBase implements Listener {
private static FormConstructor $instance;
public function onLoad(): void {
self::$instance = $this;
}
public static function getInstance(): self {
return self::$instance;
}
public function onCommand(CommandSender $sender, Command $command, string $label, array $args): bool {
if ($command->getName() === "test") {
$form = new SimpleForm("Sample title");
$form->addContent("New content line");
// Easiest way to add a button
$form->addButton(new Button("Button", function (Player $pl, Button $b) {
$pl->sendMessage("Button clicked: " . $b->getName() . " (" . $b->getIndex() . ")");
}))
// Button with image
->addButton((new Button("Button with image"))
->setImage(ImageType::PATH, "textures/items/diamond"))
// Another way to add a button
->addButton((new Button("Another button"))
->setImage(ImageType::PATH, "textures/blocks/stone")
->onClick(function (Player $pl, Button $b) {
$pl->sendMessage("Another button clicked: " . $b->getName() . " (" . $b->getIndex() . ")");
}));
// Setting the form close handler
$form->setCloseHandler(function (Player $pl) {
$pl->sendMessage("You closed the form!");
});
$form->send($sender);
}
return true;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace com\formconstructor\event;
use com\formconstructor\form\Form;
use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait;
use pocketmine\event\Event;
abstract class FormEvent extends Event implements Cancellable {
use CancellableTrait;
private Form $form;
public function __construct(Form $form) {
$this->form = $form;
}
public function getForm(): Form {
return $this->form;
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace com\formconstructor\event;
use com\formconstructor\form\Form;
use pocketmine\player\Player;
class PlayerFormCloseEvent extends FormEvent {
private Player $player;
public function __construct(Player $player, Form $form) {
parent::__construct($form);
$this->player = $player;
}
public function getPlayer(): Player {
return $this->player;
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace com\formconstructor\event;
use com\formconstructor\form\Form;
use pocketmine\player\Player;
class PlayerFormSendEvent extends FormEvent {
private Player $player;
private bool $async;
public function __construct(Player $player, Form $form, bool $async) {
parent::__construct($form);
$this->player = $player;
$this->async = $async;
}
public function getPlayer(): Player {
return $this->player;
}
public function isAsync(): bool {
return $this->async;
}
public function setAsync(bool $async): void {
$this->async = $async;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace com\formconstructor\form;
use Closure;
abstract class CloseableForm extends Form {
private ?Closure $closeHandler = null;
public function __construct(FormType $type) {
parent::__construct($type);
}
public function getCloseHandler(): ?Closure {
return $this->closeHandler;
}
public function setCloseHandler(Closure $closeHandler): self {
$this->closeHandler = $closeHandler;
return $this;
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace com\formconstructor\form;
use Closure;
use com\formconstructor\form\element\custom\CustomElement;
use com\formconstructor\form\element\custom\Label;
use com\formconstructor\form\element\custom\validator\IValidator;
use com\formconstructor\form\response\CustomFormResponse;
use com\formconstructor\form\response\FormResponse;
use pocketmine\player\Player;
class CustomForm extends CloseableForm {
private string $title;
private array $elements = [];
private bool $validated = true;
private ?Closure $handler;
private ?CustomFormResponse $response = null;
public function __construct(string $title = "", ?Closure $handler = null) {
parent::__construct(FormType::CUSTOM);
$this->title = $title;
$this->handler = $handler;
}
public function getTitle(): string {
return $this->title;
}
public function setTitle(string $title): self {
$this->title = $title;
return $this;
}
public function addContent(string $addition): self {
return $this->addElement(null, new Label($addition));
}
public function addElement(?string $elementId, CustomElement $element): self {
$element->setElementId($elementId);
$this->elements[] = $element;
return $this;
}
public function isValidated(): bool {
return $this->validated;
}
public function setHandler(Closure $handler): self {
$this->handler = $handler;
return $this;
}
public function getResponse(): ?FormResponse {
return $this->response;
}
public function setResponse(mixed $data): void {
if ($data === null) {
return;
}
foreach ($this->elements as $i => $element) {
if (!$element->respond($data[$i])) {
$this->response = new CustomFormResponse(
function (Player $player, CustomFormResponse $response) {
$this->send($player);
},
$this->elements,
$this
);
return;
}
if ($element instanceof IValidator && $this->validated && !$element->isValidated()) {
$this->validated = false;
}
}
foreach ($this->elements as $index => $element) {
$element->setIndex($index);
}
$this->response = new CustomFormResponse($this->handler, $this->elements, $this);
}
public function jsonSerialize() : array{
return [
"type" => $this->getType(),
"title" => $this->title,
"content" => $this->elements
];
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace com\formconstructor\form;
use pocketmine\player\Player;
use pocketmine\Server;
use pocketmine\form\Form as PMForm;
use com\formconstructor\event\PlayerFormSendEvent;
use com\formconstructor\task\FormHandlingTask;
use com\formconstructor\form\response\FormResponse;
use pocketmine\thread\NonThreadSafeValue;
abstract class Form implements PMForm {
private FormType $type;
private bool $async;
public function __construct(FormType $type) {
$this->type = $type;
}
public function send(Player $player, bool $async = false): void {
$event = new PlayerFormSendEvent($player, $this, $async);
$event->call();
if (!$event->isCancelled()) {
$this->async = $event->isAsync();
$player->sendForm($this);
}
}
public function sendAsync(Player $player) {
$this->send($player, true);
}
public function getType(): FormType {
return $this->type;
}
public function isAsync(): bool {
return $this->async;
}
public abstract function setResponse(mixed $data);
public abstract function getResponse(): ?FormResponse;
public final function handleResponse(Player $player, $data): void {
$this->setResponse($data);
$handler = new FormHandlingTask($this->getResponse(), $this, $player);
if ($this->async) {
// TODO async handling
$handler->onRun();
} else {
$handler->onRun();
}
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace com\formconstructor\form;
enum FormType: string implements \JsonSerializable {
case SIMPLE = 'form';
case MODAL = 'modal';
case CUSTOM = 'custom_form';
public function jsonSerialize(): string {
return $this->value;
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace com\formconstructor\form;
use Closure;
use com\formconstructor\form\response\FormResponse;
use com\formconstructor\form\response\ModalFormResponse;
class ModalForm extends CloseableForm {
private string $title;
private string $content;
private string $positiveButton;
private string $negativeButton;
private ?Closure $handler;
private ?ModalFormResponse $response = null;
public function __construct(string $title = "", string $content = "", ?Closure $handler = null) {
parent::__construct(FormType::MODAL);
$this->title = $title;
$this->content = $content;
$this->handler = $handler;
}
public function getTitle(): string {
return $this->title;
}
public function setTitle(string $title): self {
$this->title = $title;
return $this;
}
public function getContent(): string {
return $this->content;
}
public function setContent(string $content): self {
$this->content = $content;
return $this;
}
public function addContent(string $addition): self {
$this->content .= $addition;
return $this;
}
public function getPositiveButton(): string {
return $this->positiveButton;
}
public function setPositiveButton(string $positiveButton): self {
$this->positiveButton = $positiveButton;
return $this;
}
public function getNegativeButton(): string {
return $this->negativeButton;
}
public function setNegativeButton(string $negativeButton): self {
$this->negativeButton = $negativeButton;
return $this;
}
public function setHandler(Closure $handler): self {
$this->handler = $handler;
return $this;
}
public function getResponse(): ?FormResponse {
return $this->response;
}
public function setResponse(mixed $data): void {
if ($data !== null && $this->handler !== null) {
$this->response = new ModalFormResponse($this->handler, $data);
}
}
public function jsonSerialize(): array {
return [
"type" => $this->getType(),
"title" => $this->title,
"content" => $this->content,
"button1" => $this->positiveButton,
"button2" => $this->negativeButton,
];
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace com\formconstructor\form;
use com\formconstructor\form\element\simple\Button;
use com\formconstructor\form\response\SimpleFormResponse;
class SimpleForm extends CloseableForm {
private string $title;
private string $content;
private array $buttons = [];
private ?SimpleFormResponse $response = null;
public function __construct(string $title = "", string $content = "") {
parent::__construct(FormType::SIMPLE);
$this->title = $title;
$this->content = $content;
}
public function getTitle(): string {
return $this->title;
}
public function setTitle(string $title): self {
$this->title = $title;
return $this;
}
public function getContent(): string {
return $this->content;
}
public function setContent(string $content): self {
$this->content = $content;
return $this;
}
public function addContent(string $addition): self {
$this->content .= $addition;
return $this;
}
public function getButtons(): array {
return $this->buttons;
}
public function setButtons(array $buttons): self {
$this->buttons = $buttons;
return $this;
}
public function addButton(Button $button): self {
$this->buttons[] = $button;
return $this;
}
public function getResponse(): ?SimpleFormResponse {
return $this->response;
}
public function setResponse(mixed $data): void {
if ($data === null) {
return;
}
if (!is_int($data)) {
return;
}
if ($data < 0 || $data >= count($this->buttons)) {
$invalidButton = new Button("Invalid", fn($pl, $b) => $this->send($pl));
$this->response = new SimpleFormResponse($invalidButton);
return;
}
foreach ($this->buttons as $index => $button) {
$button->setIndex($index);
}
$this->response = new SimpleFormResponse($this->buttons[$data]);
}
public function jsonSerialize(): array {
return [
"type" => $this->getType(),
"title" => $this->title,
"content" => $this->content,
"buttons" => $this->buttons
];
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace com\formconstructor\form\element;
enum ElementType: string implements \JsonSerializable {
case DROPDOWN = 'dropdown';
case INPUT = 'input';
case LABEL = 'label';
case SLIDER = 'slider';
case STEP_SLIDER = 'step_slider';
case TOGGLE = 'toggle';
public function jsonSerialize(): string {
return $this->value;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace com\formconstructor\form\element;
abstract class FormElement implements \JsonSerializable {
private string $name;
private int $index = -1;
public function __construct(string $name) {
$this->name = $name;
}
public function getName(): string {
return $this->name;
}
public function setName(string $name): self {
$this->name = $name;
return $this;
}
public function getIndex(): int {
return $this->index;
}
public function setIndex(int $index): void {
$this->index = $index;
}
public abstract function jsonSerialize(): array;
}

View File

@@ -0,0 +1,35 @@
<?php
namespace com\formconstructor\form\element;
class SelectableElement {
private string $name;
private mixed $value;
private int $index = -1;
public function __construct(string $name, mixed $value = null) {
$this->name = $name;
$this->value = $value;
}
public function getName(): string {
return $this->name;
}
public function getValue(): mixed {
return $this->value;
}
public function getIndex(): int {
return $this->index;
}
public function setIndex(int $index): void {
$this->index = $index;
}
public function __toString(): string {
return "SelectableElement(name: " . $this->name . ", value: " . $this->value . ", index: " . $this->index . ")";
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace com\formconstructor\form\element\custom;
use com\formconstructor\form\element\ElementType;
use com\formconstructor\form\element\FormElement;
abstract class CustomElement extends FormElement {
private ElementType $type;
private ?string $elementId;
public function __construct(string $name, ElementType $type) {
parent::__construct($name);
$this->type = $type;
}
public abstract function respond(mixed $data): bool;
public function getType(): ElementType {
return $this->type;
}
public function getElementId(): ?string {
return $this->elementId;
}
public function setElementId(?string $elementId): void {
$this->elementId = $elementId;
}
}

View File

@@ -0,0 +1,81 @@
<?php
namespace com\formconstructor\form\element\custom;
use com\formconstructor\form\element\ElementType;
use com\formconstructor\form\element\SelectableElement;
class Dropdown extends CustomElement {
private int $defaultIndex;
private array $options = [];
private array $elements = [];
private int $selectedIndex;
public function __construct(
string $name = "",
array $elements = [],
int $defaultIndex = 0
) {
parent::__construct($name, ElementType::DROPDOWN);
$this->addElements($elements);
$this->defaultIndex = $defaultIndex;
}
public function addElement(SelectableElement $element): Dropdown {
$element->setIndex(count($this->elements));
$this->elements[] = $element;
$this->options[] = $element->getName();
return $this;
}
public function addElements(array $elements): Dropdown {
foreach ($elements as $element) $this->addElement($element);
return $this;
}
public function addText(string $name): Dropdown {
return $this->addElement(new SelectableElement($name, null));
}
public function setDefaultIndex(int $defaultIndex): Dropdown {
$this->defaultIndex = $defaultIndex;
return $this;
}
public function getDefaultIndex(): int {
return $this->defaultIndex;
}
public function getElements(): array {
return $this->elements;
}
public function getSelectedIndex(): int {
return $this->selectedIndex;
}
public function getDefault(): ?SelectableElement {
return empty($this->elements) ? null : $this->elements[$this->defaultIndex];
}
public function getValue(): ?SelectableElement {
return empty($this->elements) ? null : $this->elements[$this->selectedIndex];
}
public function respond(mixed $data): bool {
$this->selectedIndex = (int) $data;
return !empty($this->elements) && $this->selectedIndex >= 0 && $this->selectedIndex < count($this->elements);
}
public function jsonSerialize() : array{
return [
"type" => $this->getType(),
"text" => $this->getName(),
"options" => $this->options,
"default" => $this->defaultIndex
];
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace com\formconstructor\form\element\custom;
use com\formconstructor\form\element\custom\validator\IValidator;
use com\formconstructor\form\element\custom\validator\Validator;
use com\formconstructor\form\element\ElementType;
class Input extends CustomElement implements IValidator {
private string $placeholder;
private string $defaultValue;
private string $value;
private bool $trim = false;
private array $validators = [];
public function __construct(
string $name = "",
string $placeholder = "",
string $defaultValue = ""
) {
parent::__construct($name, ElementType::INPUT);
$this->placeholder = $placeholder;
$this->defaultValue = $defaultValue;
}
public function getPlaceholder(): string {
return $this->placeholder;
}
public function setPlaceholder(string $placeholder): self {
$this->placeholder = $placeholder;
return $this;
}
public function getDefaultValue(): string {
return $this->defaultValue;
}
public function setDefaultValue(string $defaultValue): self {
$this->defaultValue = $defaultValue;
return $this;
}
public function getValue(): string {
return $this->value;
}
public function setValue(string $value): self {
$this->value = $value;
return $this;
}
public function isTrim(): bool {
return $this->trim;
}
public function setTrim(bool $trim): self {
$this->trim = $trim;
return $this;
}
public function validate(): void {
foreach ($this->validators as $validator) {
$validator->validate($this->value);
}
}
public function isValidated(): bool {
return array_reduce(
$this->validators,
fn($carry, $validator) => $carry && $validator->isValidated(),
true
);
}
public function getValidators(): array {
return $this->validators;
}
public function addValidator(Validator $validator): self {
$this->validators[] = $validator;
return $this;
}
public function respond(mixed $data): bool {
$this->value = $this->trim ? trim($data) : $data;
$this->validate();
return true;
}
public function jsonSerialize() : array {
return [
"type" => $this->getType(),
"text" => $this->getName(),
"placeholder" => $this->placeholder,
"default" => $this->defaultValue
];
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace com\formconstructor\form\element\custom;
use com\formconstructor\form\element\ElementType;
class Label extends CustomElement {
public function __construct(string $text = "") {
parent::__construct($text, ElementType::LABEL);
}
public function respond(mixed $data): bool {
return true;
}
public function jsonSerialize(): array {
return [
"type" => $this->getType(),
"text" => $this->getName()
];
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace com\formconstructor\form\element\custom;
use com\formconstructor\form\element\ElementType;
class Slider extends CustomElement {
private float $defaultValue;
private float $min;
private float $max;
private float $step;
private float $value = -1;
public function __construct(
string $name = "",
float $min = 0.0,
float $max = 100.0,
float $step = 1.0,
float $defaultValue = -1.0
) {
parent::__construct($name, ElementType::SLIDER);
$this->min = max($min, 0.0);
$this->max = max($max, $this->min);
$this->defaultValue = $defaultValue;
if ($step > 0) {
$this->step = $step;
}
}
public function getDefaultValue(): float {
return $this->defaultValue;
}
public function setDefaultValue(float $defaultValue): self {
$this->defaultValue = $defaultValue;
return $this;
}
public function getMin(): float {
return $this->min;
}
public function setMin(float $min): self {
$this->min = $min;
return $this;
}
public function getMax(): float {
return $this->max;
}
public function setMax(float $max): self {
$this->max = $max;
return $this;
}
public function getStep(): float {
return $this->step;
}
public function setStep(float $step): self {
$this->step = $step;
return $this;
}
public function getValue(): int {
return $this->value;
}
public function setValue(float $value): self {
$this->value = $value;
return $this;
}
public function respond(mixed $data): bool {
$this->value = (float) $data;
return $this->value >= $this->min && $this->value <= $this->max;
}
public function jsonSerialize() : array{
return [
"type" => $this->getType(),
"text" => $this->getName(),
"min" => $this->min,
"max" => $this->max,
"step" => $this->step,
"default" => $this->defaultValue
];
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace com\formconstructor\form\element\custom;
use com\formconstructor\form\element\ElementType;
use com\formconstructor\form\element\SelectableElement;
class StepSlider extends CustomElement {
private int $defaultIndex;
private array $options = [];
private array $elements = [];
private int $selectedIndex;
public function __construct(
string $name = "",
array $elements = [],
int $defaultIndex = 0
) {
parent::__construct($name, ElementType::STEP_SLIDER);
$this->addSteps($elements);
$this->defaultIndex = $defaultIndex;
}
public function addStep(SelectableElement $element): self {
$element->setIndex(count($this->elements));
$this->elements[] = $element;
$this->options[] = $element->getName();
return $this;
}
public function addSteps(array $elements): self {
foreach ($elements as $element) $this->addStep($element);
return $this;
}
public function addText(string $name): self {
return $this->addStep(new SelectableElement($name, null));
}
public function setDefaultIndex(int $defaultIndex): self {
$this->defaultIndex = $defaultIndex;
return $this;
}
public function getDefaultIndex(): int {
return $this->defaultIndex;
}
public function getElements(): array {
return $this->elements;
}
public function getSelectedIndex(): int {
return $this->selectedIndex;
}
public function getDefault(): ?SelectableElement {
return empty($this->elements) ? null : $this->elements[$this->defaultIndex];
}
public function getValue(): ?SelectableElement {
return empty($this->elements) ? null : $this->elements[$this->selectedIndex];
}
public function respond(mixed $data): bool {
$this->selectedIndex = (int) $data;
if (empty($this->elements) || $this->selectedIndex < 0 || (count($this->elements) == 1 && $this->selectedIndex == 1)) {
return true;
}
return $this->selectedIndex < count($this->elements);
}
public function jsonSerialize() : array{
return [
"type" => $this->getType(),
"text" => $this->getName(),
"steps" => $this->options,
"default" => $this->defaultIndex
];
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace com\formconstructor\form\element\custom;
use pocketmine\form\FormValidationException;
use com\formconstructor\form\element\ElementType;
class Toggle extends CustomElement {
private bool $defaultValue;
private bool $value;
public function __construct(string $name = "", bool $defaultValue = false) {
parent::__construct($name, ElementType::TOGGLE);
$this->defaultValue = $defaultValue;
}
public function getValue(): bool {
return $this->value;
}
public function getDefaultValue(): bool {
return $this->defaultValue;
}
public function setDefaultValue(bool $defaultValue): self {
$this->defaultValue = $defaultValue;
return $this;
}
public function respond(mixed $data): bool {
if (!is_bool($data)) {
throw new FormValidationException();
}
$this->value = $data;
return true;
}
public function jsonSerialize(): array {
return [
"type" => $this->getType(),
"text" => $this->getName(),
"default" => $this->defaultValue
];
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace com\formconstructor\form\element\custom\validator;
interface IValidator {
public function validate(): void;
public function isValidated(): bool;
public function getValidators(): array;
public function addValidator(Validator $validator): IValidator;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace com\formconstructor\form\element\custom\validator;
class LengthValidator extends Validator {
private int $min;
private int $max;
public function __construct(string $name, int $min, int $max) {
parent::__construct($name);
$this->min = $min;
$this->max = $max;
}
public function validate(string $input): void {
$this->setValidated(($this->min === -1 || strlen($input) >= $this->min) && ($this->max === -1 || $this->max >= strlen($input)));
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace com\formconstructor\form\element\custom\validator;
class RegexValidator extends Validator {
private string $regex;
public function __construct(string $name, string $regex) {
parent::__construct($name);
$this->regex = $regex;
}
public function validate(string $input): void {
$this->setValidated(preg_match($this->regex, $input) === 1);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace com\formconstructor\form\element\custom\validator;
abstract class Validator {
private string $name;
private bool $validated;
public function __construct(string $name) {
$this->name = $name;
}
public function getName(): string {
return $this->name;
}
public function isValidated(): bool {
return $this->validated;
}
protected function setValidated(bool $validated): void {
$this->validated = $validated;
}
public abstract function validate(string $input);
}

View File

@@ -0,0 +1,43 @@
<?php
namespace com\formconstructor\form\element\simple;
use Closure;
use com\formconstructor\form\element\FormElement;
class Button extends FormElement implements \JsonSerializable {
private ButtonImage $image;
private ?Closure $handler;
public function __construct(string $name = "", ?Closure $handler = null) {
parent::__construct($name);
$this->handler = $handler;
$this->image = new ButtonImage();
}
public function getImage(): ButtonImage {
return $this->image;
}
public function setImage(ImageType $imageType, string $image): self {
$this->image = new ButtonImage($imageType, $image);
return $this;
}
public function getHandler(): ?Closure {
return $this->handler;
}
public function onClick(callable $handler): self {
$this->handler = $handler;
return $this;
}
public function jsonSerialize(): array {
return [
"text" => $this->getName(),
"image" => $this->image
];
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace com\formconstructor\form\element\simple;
class ButtonImage implements \JsonSerializable {
private ImageType $type;
private string $path;
public function __construct(ImageType $type = ImageType::PATH, string $path = "") {
$this->type = $type;
$this->path = $path;
}
public function getType(): ImageType {
return $this->type;
}
public function setType(ImageType $type): void {
$this->type = $type;
}
public function getPath(): string {
return $this->path;
}
public function setPath(string $path): void {
$this->path = $path;
}
public function jsonSerialize(): array {
return [
"type" => $this->type,
"data" => $this->path,
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace com\formconstructor\form\element\simple;
enum ImageType: string implements \JsonSerializable {
case PATH = 'path';
case URL = 'url';
public function jsonSerialize(): string {
return $this->value;
}
}

View File

@@ -0,0 +1,136 @@
<?php
namespace com\formconstructor\form\response;
use Closure;
use com\formconstructor\form\CustomForm;
use com\formconstructor\form\element\custom\CustomElement;
use com\formconstructor\form\element\custom\Dropdown;
use com\formconstructor\form\element\custom\Input;
use com\formconstructor\form\element\custom\Label;
use com\formconstructor\form\element\custom\Slider;
use com\formconstructor\form\element\custom\StepSlider;
use com\formconstructor\form\element\custom\Toggle;
use com\formconstructor\form\element\custom\validator\IValidator;
use com\formconstructor\form\element\ElementType;
use pocketmine\player\Player;
class CustomFormResponse extends FormResponse {
private array $elements;
private CustomForm $form;
public function __construct(?Closure $handler, array $elements, CustomForm $form) {
parent::__construct($handler, "");
$this->elements = $elements;
$this->form = $form;
}
public function getAllElements(): array {
return $this->elements;
}
public function getForm(): CustomForm {
return $this->form;
}
public function containsId(string $elementId): bool {
foreach ($this->elements as $element) {
if ($element->getElementId() === $elementId) {
return true;
}
}
return false;
}
private function getElementByIndex(int $index): ?CustomElement {
return $this->elements[$index];
}
private function getElement(string $elementId, ElementType $type): mixed {
foreach ($this->elements as $element) {
if ($element->getElementId() === $elementId && $element->getType() === $type) {
return $element;
}
}
return null;
}
private function getElements(ElementType $type): array {
return array_filter($this->elements, fn(CustomElement $element) => $element->getType() === $type);
}
public function getLabel(string $elementId): ?Label {
return $this->getElement($elementId, ElementType::LABEL);
}
public function getLabels(): array {
return $this->getElements(ElementType::LABEL);
}
public function getInput(string $elementId): ?Input {
return $this->getElement($elementId, ElementType::INPUT);
}
public function getInputs(): array {
return $this->getElements(ElementType::INPUT);
}
public function getToggle(string $elementId): ?Toggle {
return $this->getElement($elementId, ElementType::TOGGLE);
}
public function getToggles(): array {
return $this->getElements(ElementType::TOGGLE);
}
public function getSlider(string $elementId): ?Slider {
return $this->getElement($elementId, ElementType::SLIDER);
}
public function getSliders(): array {
return $this->getElements(ElementType::SLIDER);
}
public function getStepSlider(string $elementId): ?StepSlider {
return $this->getElement($elementId, ElementType::STEP_SLIDER);
}
public function getStepSliders(): array {
return $this->getElements(ElementType::STEP_SLIDER);
}
public function getDropdown(string $elementId): ?Dropdown {
return $this->getElement($elementId, ElementType::DROPDOWN);
}
public function getDropdowns(): array {
return $this->getElements(ElementType::DROPDOWN);
}
public function isValidated(): bool {
return $this->form->isValidated();
}
public function getValidatorErrors(): array {
$errors = [];
foreach ($this->elements as $element) {
if ($element instanceof IValidator) {
foreach ($element->getValidators() as $validator) {
if (!$validator->isValidated()) {
$errors[] = $validator->getName();
}
}
}
}
return $errors;
}
public function handle(Player $player): void {
if ($this->getHandler() !== null) {
$this->getHandler()($player, $this);
}
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace com\formconstructor\form\response;
use Closure;
use pocketmine\player\Player;
abstract class FormResponse {
private ?Closure $handler;
private ?string $data;
public function __construct(?Closure $handler, ?string $data) {
$this->handler = $handler;
$this->data = $data;
}
public function getHandler(): ?Closure {
return $this->handler;
}
public function getData(): ?string {
return $this->data;
}
public abstract function handle(Player $player): void;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace com\formconstructor\form\response;
use Closure;
use pocketmine\player\Player;
class ModalFormResponse extends FormResponse {
public function __construct(?Closure $handler, ?string $data) {
parent::__construct($handler, $data);
}
public function handle(Player $player): void {
if ($this->getHandler() !== null) {
$this->getHandler()($player, $this->getData() === "1");
}
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace com\formconstructor\form\response;
use pocketmine\player\Player;
use com\formconstructor\form\element\simple\Button;
class SimpleFormResponse extends FormResponse {
private Button $button;
public function __construct(Button $button) {
parent::__construct($button->getHandler(), "");
$this->button = $button;
}
public function handle(Player $player): void {
if ($this->getHandler() !== null) {
$this->getHandler()($player, $this->button);
}
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace com\formconstructor\task;
use com\formconstructor\event\PlayerFormCloseEvent;
use com\formconstructor\form\CloseableForm;
use com\formconstructor\form\Form;
use com\formconstructor\form\response\CustomFormResponse;
use com\formconstructor\form\response\FormResponse;
use com\formconstructor\form\response\ModalFormResponse;
use com\formconstructor\form\response\SimpleFormResponse;
use pocketmine\player\Player;
// TODO async handing
class FormHandlingTask {
private ?FormResponse $response;
private Form $form;
private Player $player;
public function __construct(?FormResponse $response, Form $form, Player $player) {
$this->response = $response;
$this->form = $form;
$this->player = $player;
}
public function onRun(): void {
if ($this->response === null && $this->form instanceof CloseableForm) {
$closeHandler = $this->form->getCloseHandler();
$event = new PlayerFormCloseEvent($this->player, $this->form);
$event->call();
if ($closeHandler !== null) $closeHandler($this->player);
return;
}
if ($this->response instanceof ModalFormResponse) {
$this->response->handle($this->player);
return;
}
if ($this->response instanceof SimpleFormResponse) {
$this->response->handle($this->player);
return;
}
if ($this->response instanceof CustomFormResponse) {
$this->response->handle($this->player);
}
}
}