j1b1x / forms
Requires
- pocketmine/pocketmine-mp: ^5.0
README
This is a PocketMine-MP 5.0 form library with PHP 8.0 support and high quality code
Credits
This API is a spoon of Frago's forms library and also includes a ServerSettingsForm which is inspired of skymin's ServerSettingsForm virion and a Image loading fix which is inspired by Muqsit's FormImagesFix plugin.
Code samples
Registration
In order to use the ServerSettingsForms, ImageFix and the auto-back feature you first need to register the packet handler by doing
protected function onEnable(): void{ \Jibix\Forms\Forms::register($this); }
Note: You only need to do this if you use this plugin as a virion, otherwise it's handled by the Main class
Auto-back
Auto-back is a feature that sends the previous opened form to the player once they close a form or click on a back button. It also overwrites back buttons in a MenuForm with close buttons if there's no form to go back to If you want to use the auto-back feature, you just need to do
\Jibix\Forms\Forms::setAutoBack(true);
Image fix
Image fix is a workaround for a MCPE MenuForm bug, where url button images take ages to load To make this work you only need to do the registration
ServerSettingsForm
The ServerSettingsForm is similar to a CustomForm and has the same elements, but will be displayed in the player's game-settings ui Once you have registered the packet handler, you can just use the ServerSettingsFormEvent
public function onServerSettingsForm(ServerSettingsFormEvent $event): void{ $player = $event->getPlayer(); if (!$player->hasPermission(DefaultPermissions::ROOT_OPERATOR)) return; //Not an operator (new ServerSettingsForm( "§bServer settings", [ new Label("Want to adjust some server settings? Just do it!"), new Input("Motd", "§cBest Server!", Server::getInstance()->getNetwork()->getName(), function (Player $player, Input $input): void{ Server::getInstance()->getNetwork()->setName($input->getName()); }), ], function (Player $player, CustomFormResponse $response): void{ $player->sendMessage("Done! You successfully adjusted the server settings."); }, Image::path("textures/items/diamond") //Set the icon of the form ))->send($player); }
ModalForm
Using ModalForm to represent "yes" / "no" button clicks as bool
in closure
$player->sendForm(new ModalForm("A small question", "Is our server cool?", //result of pressing the "yes" / "no" button is written to a variable $choice function (Player $player, bool $choice): void{ $player->sendMessage($choice ? "Thank you" : "We will try to become better"); } ));
Short version of ModalForm to confirm any action
$player->sendForm(ModalForm::confirm("Teleport request", "Do you want to accept it?", //called only when the player selects the "yes" button function (Player $player): void{ $player->sendMessage("*teleporting*"); } ));
MenuForm
Using MenuForm to display buttons with icons from URL and path
$player->sendForm(new MenuForm("Select server", "Choose server", [ //buttons without icon new Button("SkyWars #1"), //URL and path are supported for image new Button("SkyWars #2", null, Image::url("https://static.wikia.nocookie.net/minecraft_gamepedia/images/f/f0/Melon_JE2_BE2.png")), new Button("SkyWars #3", null, Image::path("textures/items/apple.png")), //If you have some dynamic images you can use Image::detect new Button("SkyWars #4", null, Image::detect($image)), new BackButton(), //Dynamic back button ], function (Player $player, Button $selected): void{ $player->sendMessage("You selected: " . $selected->getText()); $player->sendMessage("Index of button: " . $selected->getValue()); }, function (Player $player): void{ $player->sendMessage("You closed the server selector!"); }));
Shorther/simpler MenuForm, you can directly set the button's onSubmit callback, which can be useful if you have object foreaches
foreach ($objectArray as $key => $object) { $buttons[] = new Button("Key #$key", function (Player $player, Button $selected) use ($key, $object): void{ $player->sendMessage("You have selected the key #$key"); //Do something with $object }) } $buttons[] = new BackButton(); //Dynamic back button $player->sendForm(new MenuForm("Select key", "Choose key", $buttons));
CustomForm
Using CustomForm with strict-typed API
$player->sendForm(new CustomForm("Enter data", [ new Dropdown("Select product", ["beer", "cheese", "cola"]), new Input("Enter your name", "Bob"), new Label("I am label!"), //Note: get<BaseElement>() does not work with label new Slider("Select count", 0.0, 100.0, 1.0, 50.0), new StepSlider("Select product", ["beer", "cheese", "cola"]), new Toggle("Creative", $player->isCreative()), ], function (Player $player, CustomFormResponse $response): void{ $dropdown = $response->getDropdown(); $player->sendMessage("You selected: " . $dropdown->getSelectedOption()); $input = $response->getInput(); $player->sendMessage("Your name is " . $input->getValue()); $slider = $response->getSlider(); $player->sendMessage("Count: " . $slider->getValue()); $stepSlider = $response->getStepSlider(); $player->sendMessage("You selected: " . $stepSlider->getSelectedOption()); $toggle = $response->getToggle(); $player->setGamemode($toggle->getValue() ? GameMode::CREATIVE() : GameMode::SURVIVAL()); }));
Using CustomForm with less strict-typed API
$player->sendForm(new CustomForm("Enter data", [ new Dropdown("Select product", ["beer", "cheese", "cola"]), new Input("Enter your name", "Bob"), new Label("I am label!"), //Note: get<BaseElement>() does not work with label new Slider("Select count", 0.0, 100.0, 1.0, 50.0), new StepSlider("Select product", ["beer", "cheese", "cola"]), new Toggle("Creative", $player->isCreative()), ], function (Player $player, CustomFormResponse $response): void{ [$product1, $username, $count, $product2, $enableCreative] = $response->getValues(); $player->sendMessage("You selected: $product1"); $player->sendMessage("Your name is $username"); $player->sendMessage("Count: $count"); $player->sendMessage("You selected: $product2"); $player->setGamemode($enableCreative ? GameMode::CREATIVE() : GameMode::SURVIVAL()); }));
Using CustomForms elements with directly setting their onSubmit callback
$player->sendForm(new CustomForm("Enter data", [ new Dropdown("Select product #1", ["beer", "cheese", "cola"], "", function (Player $player, Dropdown $dropdown): void{ $player->sendMessage("Your first product is {$dropdown->getSelectedOption()}"); }), new Input("Enter your name", "Bob", "", function (Player $player, Input $input): void{ $player->sendMessage("You entered the name: {$input->getValue()}!"); }), new Label("I am label!"), new Slider("Select count", 0.0, 100.0, 1.0, 50.0, function (Player $player, Slider $slider): void{ $player->sendMessgae("You selected a count of {$slider->getValue()}"); }), new StepSlider("Select product #2", ["beef", "fanta", "chips"], "", function (Player $player, StepSlider $slider): void{ $player->sendMessage("Your second product is {$slider->getSelectedOption()}"); }), new Toggle("Creative", $player->isCreative(), function (Player $player, Toggle $toggle): void{ $player->setGamemode($toggle->getValue() ? GameMode::CREATIVE() : GameMode::SURVIVAL()); }), ]));
From/to Data CustomForm. This can be useful if you want to send the same ui again, but with some changes, such as an error message label
public function sendCustomForm(Player $player, array $data = [], ?string $message = null){ $player->sendForm(new CustomForm( "Enter rank data", CustomForm::fromData([ new Label($message ?? "Enter the ranks data!") new Input("Name", "Owner"), new Slider("Price", 0, 100, 1) ], $data), function (Player $player, CustomFormResponse $response): void{ $data = $response->__toData(); [$name, $price] = $response->getElements(); $error = match (true) { strlen($name) < 4 => "§cThe name must be at least 4 chars!", strlen($name) > 20 => "§cThe name must be shorter than 20 chars!", //other checks default => null }; if ($error !== null) { $this->sendCustomForm($player, $data, $error); return; } //Do something with the rank data } )); }
Uncloseable form
An uncloseable form can be useful if you permanently want to display something to the player
$player->sendForm(new MenuForm( "§cMaintenance", "Hello {$player->getName()}! Unfortunately we are currently in maintenance to update some server features!\nPlease come back once we announce that we're done with the update.", [], null, Form::uncloseable() ));