|
1 | 1 | # Forms
|
2 |
| -A modified version of CosmicPE forms library that use array instead of Sets. |
| 2 | +A library for PocketMine-MP providing an API to create forms. |
| 3 | + |
| 4 | +## Developer Docs |
| 5 | +### Modal Form |
| 6 | +These forms can serve as a prompt window. They require a title field, a body and either one or two buttons. |
| 7 | +The second button is pretty unnecessary as it does the same action as of closing the window. The bedrock client doesn't let servers |
| 8 | +distinguish between a "prompt window close action" and a "second button click action". |
| 9 | +```php |
| 10 | +class MyModalForm extends ModalForm{ |
| 11 | + |
| 12 | + public function __construct(){ |
| 13 | + parent::__construct("/suicide prevention", // <- title |
| 14 | + "Are you sure you'd like to commit /suicide?" . TextFormat::EOL . // <- body |
| 15 | + "You will lose all your inventory contents if you proceed." |
| 16 | + ); |
| 17 | + $this->setFirstButton("YES"); |
| 18 | + $this->setSecondButton("I'll need time to make up my mind."); // optional second button |
| 19 | + } |
| 20 | + |
| 21 | + protected function onAccept(Player $player) : void{ |
| 22 | + // Called when first button is clicked |
| 23 | + $player->getServer()->dispatchCommand($player, "kill"); |
| 24 | + } |
| 25 | + |
| 26 | + protected function onClose(Player $player) : void{ |
| 27 | + // Called when second button is clicked OR player closes the form |
| 28 | + $player->sendMessage("You can access this form again, anytime, using /suicide"); |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +$player->sendForm(new MyModalForm()); |
| 33 | +``` |
| 34 | + |
| 35 | +### Simple Form |
| 36 | +A bunch of buttons, that's all this form provides. Some servers like using this as a method of sending client text in a form window. |
| 37 | +You can add as many buttons as you like, or no buttons. |
| 38 | +```php |
| 39 | +class MySimpleForm extends SimpleForm{ |
| 40 | + |
| 41 | + public function __construct(){ |
| 42 | + parent::__construct("/suicide prevention", // <- title |
| 43 | + "There's more to life than our shithole education system!" . TextFormat::EOL . // <- body |
| 44 | + "Do you really think it's worth losing all your diamonds?" |
| 45 | + ); |
| 46 | + |
| 47 | + $this->addButton( |
| 48 | + new Button("Ugh..?", new Icon(Icon::TYPE_URL, "http://meme.images/three-qn-marks.png")), // <- button params: body, icon (optional) |
| 49 | + function(Player $player, int $button_index) : void{ // <- (optional) callback when this button is clicked |
| 50 | + $player->getServer()->dispatchCommand($player, "kill"); |
| 51 | + } |
| 52 | + ); |
| 53 | + |
| 54 | + $this->addButton(new Button("I guess you have a point")); |
| 55 | + |
| 56 | + $this->addButton(new Button( |
| 57 | + "Emergency Call" . TextFormat::EOL . |
| 58 | + "There are people out there" . TextFormat::EOL . |
| 59 | + "who genuinely care for you!" |
| 60 | + )); |
| 61 | + } |
| 62 | + |
| 63 | + public function onClickButton(Player $player, Button $button, int $button_index) : void{ |
| 64 | + // optional override |
| 65 | + // for buttons that dont have a callback |
| 66 | + } |
| 67 | + |
| 68 | + public function onClose(Player $player) : void{ |
| 69 | + // when player closes this form |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +$player->sendForm(new MySimpleForm()); |
| 74 | +``` |
| 75 | + |
| 76 | +### Paginated Form |
| 77 | +These are simple forms that provide an interface for creating simple forms with pages. |
| 78 | +```php |
| 79 | +class MyPaginatedForm extends PaginatedForm{ |
| 80 | + |
| 81 | + private const ENTRIES_PER_PAGE = 10; |
| 82 | + |
| 83 | + /** @var int */ |
| 84 | + private $total_players; |
| 85 | + |
| 86 | + /** @var string[] */ |
| 87 | + private $people_to_avoid = []; |
| 88 | + |
| 89 | + public function __construct(int $current_page = 1){ |
| 90 | + $players = Server::getInstance()->getOnlinePlayers(); |
| 91 | + $this->total_players = count($players); |
| 92 | + |
| 93 | + foreach(array_slice( |
| 94 | + $players, |
| 95 | + ($current_page - 1) * self::ENTRIES_PER_PAGE, |
| 96 | + self::ENTRIES_PER_PAGE |
| 97 | + ) as $player){ |
| 98 | + $this->people_to_avoid[] = $player->getName(); |
| 99 | + } |
| 100 | + |
| 101 | + // Call parent::__construct() at the end. |
| 102 | + parent::__construct( |
| 103 | + "List of people to avoid" // <- title |
| 104 | + "Avoid talking with or being in the vicinity of these people." // <- content |
| 105 | + $current_page // <- current page, defaults to 1 (pages start at 1, not 0) |
| 106 | + ); |
| 107 | + } |
| 108 | + |
| 109 | + protected function getPreviousButton() : Button{ |
| 110 | + return new Button("<- Go back"); |
| 111 | + } |
| 112 | + |
| 113 | + protected function getNextButton() : Button{ |
| 114 | + return new Button("Next Page ->"); |
| 115 | + } |
| 116 | + |
| 117 | + protected function getPages() : int{ |
| 118 | + // Returns the maximum number of pages. |
| 119 | + // This will alter the visibility of previous and next buttons. |
| 120 | + // For example: |
| 121 | + // * If we are on page 7 of 7, the "next" button wont be visible |
| 122 | + // * If we are on page 6 of 7, the "next" and "previous" button WILL be visible |
| 123 | + // * If we are on page 1 of 7, the "previous" button won't be visible |
| 124 | + return (int) ceil(count($this->total_players) / self::ENTRIES_PER_PAGE); |
| 125 | + } |
| 126 | + |
| 127 | + protected function populatePage() : void{ |
| 128 | + // populate this page with buttons |
| 129 | + foreach($this->people_to_avoid as $people){ |
| 130 | + $this->addButton(new Button($people, "- Responsible for limiting PhotoTransferPacket to edu only")); |
| 131 | + } |
| 132 | + } |
| 133 | + |
| 134 | + protected function sendPreviousPage(Player $player) : void{ |
| 135 | + $player->sendForm(new self($this->current_page - 1)); |
| 136 | + } |
| 137 | + |
| 138 | + protected function sendNextPage(Player $player) : void{ |
| 139 | + $player->sendForm(new self($this->current_page + 1)); |
| 140 | + } |
| 141 | +} |
| 142 | +
|
| 143 | +$player->sendForm(new MyPaginatedForm()); |
| 144 | +``` |
| 145 | +
|
| 146 | +
|
| 147 | +### Custom Form |
| 148 | +Unlike the other two forms, this form lets players enter a custom input. At the bottom of this form is a "Submit" button. No, you |
| 149 | +cannot modify that button's text. |
| 150 | +These forms don't contain buttons. As of now, there are 6 types of entries you can add to this form. |
| 151 | +
|
| 152 | +#### 1. Dropdown |
| 153 | +The closest alternative to buttons. Dropdowns let players select an option from a list of options. |
| 154 | +```php |
| 155 | +$entry = new DropdownEntry( |
| 156 | + "What's your gender?", // the first parameter is the name of the dropdown |
| 157 | + "Male", // the next parameters are the dropdown options |
| 158 | + "Female", |
| 159 | + "Prefer not to answer" |
| 160 | +); |
| 161 | +$entry->setDefault("Prefer not to answer"); |
| 162 | +``` |
| 163 | +
|
| 164 | +#### 2. Input |
| 165 | +Lets players input a string. Also can be useful in making shit confirmatory prompts. |
| 166 | +```php |
| 167 | +// Parameters: |
| 168 | +// * Name of the input option |
| 169 | +// * Placeholder (displayed in grey) [optional] |
| 170 | +// * Default (fallback value if nothing entered) [optional] |
| 171 | +$entry = new InputEntry("Enter your name", "Sbeve"); |
| 172 | +``` |
| 173 | +
|
| 174 | +#### 3. Label |
| 175 | +Remember when I said these forms let players enter a custom input? This entry is an exception. Labels only display text[citation needed]. |
| 176 | +```php |
| 177 | +$entry = new LabelEntry("Probably can fit a huge wall of text here?"); |
| 178 | +``` |
| 179 | +
|
| 180 | +#### 4. Slider |
| 181 | +Lets players choose a value between two numbers using a slider to select. |
| 182 | +```php |
| 183 | +$entry = new Slider( |
| 184 | + "How would you rate our suicide prevention?", // <- title |
| 185 | + 0.0, // <- minimum value |
| 186 | + 10.0, // <- maximum value |
| 187 | + 0.5, // <- step size, |
| 188 | + 10.0 // <- default value |
| 189 | +); |
| 190 | +``` |
| 191 | +
|
| 192 | +#### 5. Step Slider |
| 193 | +Resemble sliders, but their value is a string. |
| 194 | +```php |
| 195 | +$entry = new StepSlider( |
| 196 | + "Brain size", // <- title |
| 197 | + "Small", // <- the next parameters are steps in order |
| 198 | + "Medium", |
| 199 | + "Large" |
| 200 | +); |
| 201 | +$entry->setDefault("Medium"); |
| 202 | +``` |
| 203 | +
|
| 204 | +#### 6. Toggle |
| 205 | +A simple switch. |
| 206 | +```php |
| 207 | +$entry = new Toggle("Enable suicide prevention", true); // <- parameters: title, bool (true: turned on, false: turned off) |
| 208 | +``` |
| 209 | +
|
| 210 | +#### Creating the custom form |
| 211 | +```php |
| 212 | +class MyCustomForm extends CustomForm{ |
| 213 | +
|
| 214 | + public function __construct(){ |
| 215 | + parent::__construct("Suicide prevention confirmation"); |
| 216 | + |
| 217 | + $this->addEntry(new LabelEntry("Are you sure you'd like to commit /suicide? You will lose all your inventory contents.")); |
| 218 | + $this->addEntry(new LabelEntry("Type " . TextFormat::BOLD . "YES" . TextFormat::RESET . "below to confirm!"); |
| 219 | + |
| 220 | + |
| 221 | + $this->addEntry( |
| 222 | + new InputEntry("", "Type YES here"), |
| 223 | + function(Player $player, InputEntry $entry, string $value) : void{ |
| 224 | + if($value === "YES"){ |
| 225 | + $player->getServer()->dispatchCommand($player, "kill"); |
| 226 | + }else{ |
| 227 | + $player->sendMessage("Suicide aborted."); |
| 228 | + } |
| 229 | + } |
| 230 | + ); |
| 231 | + } |
| 232 | + |
| 233 | + public function onClose(Player $player) : void{ |
| 234 | + // when player closes this form |
| 235 | + } |
| 236 | +} |
| 237 | +
|
| 238 | +$player->sendForm(new MyCustomForm()); |
| 239 | +``` |
0 commit comments