Skip to content

Commit f34759f

Browse files
committed
Push all
1 parent 0a8e1ea commit f34759f

20 files changed

+955
-1
lines changed

.poggit.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
--- # Poggit-CI Manifest. Open the CI at https://poggit.pmmp.io/ci/Cosmoverse/Forms
2+
branches:
3+
- master
4+
projects:
5+
Forms:
6+
path: ""
7+
model: virion
8+
type: library
9+
...

LICENSE

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
This is free and unencumbered software released into the public domain.
2+
3+
Anyone is free to copy, modify, publish, use, compile, sell, or
4+
distribute this software, either in source code form or as a compiled
5+
binary, for any purpose, commercial or non-commercial, and by any
6+
means.
7+
8+
In jurisdictions that recognize copyright laws, the author or authors
9+
of this software dedicate any and all copyright interest in the
10+
software to the public domain. We make this dedication for the benefit
11+
of the public at large and to the detriment of our heirs and
12+
successors. We intend this dedication to be an overt act of
13+
relinquishment in perpetuity of all present and future rights to this
14+
software under copyright law.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
OTHER DEALINGS IN THE SOFTWARE.
23+
24+
For more information, please refer to <https://unlicense.org>

README.md

+238-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,239 @@
11
# 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+
```

src/cosmicpe/form/CustomForm.php

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace cosmicpe\form;
6+
7+
use Closure;
8+
use cosmicpe\form\entries\custom\CustomFormEntry;
9+
use cosmicpe\form\entries\ModifyableEntry;
10+
use cosmicpe\form\types\Icon;
11+
use Exception;
12+
use pocketmine\form\FormValidationException;
13+
use pocketmine\Player;
14+
15+
abstract class CustomForm implements Form{
16+
17+
/** @var string */
18+
private $title;
19+
20+
/** @var Icon|null */
21+
private $icon;
22+
23+
/** @var CustomFormEntry[] */
24+
private $entries = [];
25+
26+
/** @var Closure[] */
27+
private $entry_listeners = [];
28+
29+
public function __construct(string $title){
30+
$this->title = $title;
31+
}
32+
33+
final public function setIcon(?Icon $icon) : void{
34+
$this->icon = $icon;
35+
}
36+
37+
/**
38+
* @param CustomFormEntry $entry
39+
* @param Closure|null $listener
40+
*
41+
* Listener parameters:
42+
* * Player $player
43+
* * InputEntry $entry
44+
* * mixed $value [NOT NULL]
45+
*/
46+
final public function addEntry(CustomFormEntry $entry, Closure $listener = null) : void{
47+
$this->entries[] = $entry;
48+
if($listener !== null){
49+
$this->entry_listeners[array_key_last($this->entries)] = $listener;
50+
}
51+
}
52+
53+
public function handleResponse(Player $player, $data) : void{
54+
if($data === null){
55+
$this->onClose($player);
56+
}else{
57+
try{
58+
$this->onSubmit($player, $data);
59+
}catch(Exception $e){
60+
throw new FormValidationException($e->getMessage());
61+
}
62+
}
63+
}
64+
65+
public function onSubmit(Player $player, array $data) : void {}
66+
67+
public function onClose(Player $player) : void {}
68+
69+
final public function jsonSerialize() : array{
70+
return [
71+
"type" => "custom_form",
72+
"title" => $this->title,
73+
"icon" => $this->icon,
74+
"content" => $this->entries
75+
];
76+
}
77+
}

src/cosmicpe/form/Form.php

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace cosmicpe\form;
6+
7+
use pocketmine\form\Form as PocketMineForm;
8+
9+
interface Form extends PocketMineForm{
10+
}

0 commit comments

Comments
 (0)