mirror of
https://github.com/quizhizhe/LiteLoaderBDS-1.16.40.git
synced 2025-06-01 11:43:41 +00:00
447 lines
15 KiB
C++
447 lines
15 KiB
C++
#pragma once
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Form UI Utility - Help you to build forms and options more easily
|
|
//
|
|
// [Example - Simple Form]
|
|
// - Form that contains several buttons (with optional image)
|
|
// - Let the player choose an option from multiple options
|
|
//
|
|
// SimpleForm form("Welcome to shop", "Choose what you want to do..."); // Initialize the form with title and content
|
|
// form.addButton("Buy", "textures/items/apple", // Add a button "Buy" with texture image
|
|
// [](Player* pl) { pl->sendText("To buy something..."); }) // Buy's callback function
|
|
//
|
|
// .addButton("Sell", "https://xxx.com/xxx.png", // Add a button "Sell" with online image
|
|
// [](Player* pl) { pl->sendText("To sell something..."); }) // Sell's callback function
|
|
//
|
|
// .addButton("Settings", "", // Add a button "Settings" with no image
|
|
// [](Player* pl) { pl->sendText("Get into settings..."); }) // Settings's callback function
|
|
//
|
|
// .addButton("Exit") // Add a single button "Exit"
|
|
// .sendTo(Level::getPlayer("John")); // Send the form to a player called "John"
|
|
//
|
|
//
|
|
// [Example - Modal Form]
|
|
// - Form with Confirm and Cancel buttons
|
|
// - Let the player confirm or cancel an action
|
|
//
|
|
// ModalForm form("Confirm the action", "Do you want that?", "Yes", "Nope"); // Initialize the form with title, content and two buttons ("Yes", "Nope")
|
|
// form.sendTo(Level::getPlayer("S3v3N1ce"), // Send the form to a player called "S3v3N1ce"
|
|
// [](Player* player, bool isConfirm) // Callback function to process the result
|
|
// {
|
|
// if (isConfirm) // Player pressed button "Yes"
|
|
// player->sendText("Okay, let's go");
|
|
// else // Player pressed button "Nope"
|
|
// player->sendText("Hm, suit yourself");
|
|
// });
|
|
//
|
|
//
|
|
// [Example - Custom Form]
|
|
// - Form that contains some kinds of elements (like input line, toggle, dropdown, ....)
|
|
// - Let the player provide some detailed information
|
|
//
|
|
// CustomForm form2("Information Collection Form"); // Initialize the form with title
|
|
// form2.addLabel("label1", "Personal Information") // Add a label shows "Personal Information"
|
|
// .addInput("username", "Your Name") // Add an input line to gather player's name
|
|
// .addDropdown("sex", "Your Sex", { "Male","Female","Secret" }) // Add a dropdown to gather player's sex
|
|
// .addSlider("age", "Your Age", 3, 100) // Add a slider to gather player's age
|
|
//
|
|
// .addLabel("label2", "MC Information") // Add a label shows "MC Information"
|
|
// .addToggle("licensed", "Purchased a licensed Minecraft?", true) // Add a toggle about whether he buys a licensed mc or not
|
|
// .addStepSlider("skill", "Skill Lvl", { "Beginner", "Amateur", "Pro" }) // Add a step slider shows his game skill level
|
|
//
|
|
// .sendTo(Level::getPlayer("yqs112358"), // Send the form to a player called "yqs112358"
|
|
// [](Player* player, auto result) // Callback function to process the result
|
|
// {
|
|
// if (result.empty()) // Player cancelled the form
|
|
// return;
|
|
// player->sendText("You have commited the form.");
|
|
// player->sendFormattedText("Your name: {}", result["username"]->getString());
|
|
// player->sendFormattedText("Your sex: {}", result["sex"]->getString());
|
|
// player->sendFormattedText("Your age: {}", result["age"]->getNumber());
|
|
// player->sendFormattedText("Your license: {}", result["licensed"]->getBool() ? "yes" : "no");
|
|
// player->sendFormattedText("Your skill level: {}:", result["skill"]->getString());
|
|
// });
|
|
//
|
|
//
|
|
// Tips: The <key> of std::map "result" equals the first argument "name" you pass to these elements
|
|
// So, "name" must be *unique* or error will occur
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#include <utility>
|
|
#include "Global.h"
|
|
|
|
class ServerPlayer;
|
|
class Player;
|
|
|
|
|
|
namespace Form {
|
|
//////////////////////////////// Simple Form Elements ////////////////////////////////
|
|
class SimpleFormElement {
|
|
protected:
|
|
virtual string serialize() = 0;
|
|
friend class SimpleForm;
|
|
};
|
|
|
|
class Button : public SimpleFormElement {
|
|
protected:
|
|
LIAPI string serialize() override;
|
|
|
|
public:
|
|
using ButtonCallback = std::function<void(Player*)>;
|
|
string text, image;
|
|
ButtonCallback callback;
|
|
|
|
public:
|
|
inline explicit Button(string text, string image = "", ButtonCallback callback = ButtonCallback())
|
|
: text(std::move(text))
|
|
, image(std::move(image))
|
|
, callback(std::move(callback)) {
|
|
}
|
|
inline void setText(const string& _text) {
|
|
this->text = _text;
|
|
}
|
|
inline void setImage(const string& _image) {
|
|
this->image = _image;
|
|
}
|
|
inline void setCallback(ButtonCallback _callback) {
|
|
this->callback = std::move(_callback);
|
|
}
|
|
};
|
|
|
|
//////////////////////////////// Custom Form Elements ////////////////////////////////
|
|
class CustomFormElement {
|
|
protected:
|
|
LIAPI virtual string serialize() = 0;
|
|
friend class CustomForm;
|
|
|
|
public:
|
|
enum class Type {
|
|
Label,
|
|
Input,
|
|
Toggle,
|
|
Dropdown,
|
|
Slider,
|
|
StepSlider
|
|
};
|
|
string name;
|
|
string value;
|
|
Type type{};
|
|
inline void setName(const string& _name) {
|
|
this->name = _name;
|
|
}
|
|
inline virtual Type getType() = 0;
|
|
LIAPI std::string getString();
|
|
[[deprecated("Please use getInt")]]
|
|
LIAPI int getNumber();
|
|
LIAPI int getInt();
|
|
LIAPI float getFloat();
|
|
LIAPI double getDouble();
|
|
LIAPI bool getBool();
|
|
};
|
|
|
|
class Label : public CustomFormElement {
|
|
protected:
|
|
LIAPI string serialize() override;
|
|
|
|
public:
|
|
string text;
|
|
|
|
public:
|
|
inline Label(const string& name, string text)
|
|
: text(std::move(text)) {
|
|
setName(name);
|
|
}
|
|
inline Type getType() override {
|
|
return Type::Label;
|
|
}
|
|
inline void setText(const string& _text) {
|
|
this->text = _text;
|
|
}
|
|
};
|
|
|
|
class Input : public CustomFormElement {
|
|
protected:
|
|
LIAPI string serialize() override;
|
|
|
|
public:
|
|
string title, placeholder, def;
|
|
inline Input(const string& name, string title, string placeholder = "", string def = "")
|
|
: title(std::move(title))
|
|
, placeholder(std::move(placeholder))
|
|
, def(std::move(def)) {
|
|
setName(name);
|
|
}
|
|
inline Type getType() override {
|
|
return Type::Input;
|
|
}
|
|
inline void setTitle(const string& _title) {
|
|
this->title = _title;
|
|
}
|
|
inline void setPlaceHolder(const string& _placeholder) {
|
|
this->placeholder = _placeholder;
|
|
}
|
|
inline void setDefault(const string& _def) {
|
|
this->def = _def;
|
|
}
|
|
};
|
|
|
|
class Toggle : public CustomFormElement {
|
|
protected:
|
|
LIAPI string serialize() override;
|
|
|
|
public:
|
|
public:
|
|
string title;
|
|
bool def;
|
|
|
|
public:
|
|
inline Toggle(const string& name, string title, bool def = false)
|
|
: title(std::move(title))
|
|
, def(def) {
|
|
setName(name);
|
|
}
|
|
inline virtual Type getType() override {
|
|
return Type::Toggle;
|
|
}
|
|
inline void setTitle(const string& _title) {
|
|
this->title = _title;
|
|
}
|
|
inline void setDefault(bool _def) {
|
|
this->def = _def;
|
|
}
|
|
};
|
|
|
|
class Dropdown : public CustomFormElement {
|
|
protected:
|
|
LIAPI string serialize() override;
|
|
|
|
public:
|
|
string title;
|
|
vector<string> options;
|
|
int def;
|
|
|
|
public:
|
|
inline Dropdown(const string& name, string title, const vector<string>& options, int defId = 0)
|
|
: title(std::move(title))
|
|
, options(options)
|
|
, def(defId) {
|
|
setName(name);
|
|
}
|
|
inline Type getType() override {
|
|
return Type::Dropdown;
|
|
}
|
|
inline void setTitle(const string& _title) {
|
|
this->title = _title;
|
|
}
|
|
inline void setOptions(const vector<string>& _options) {
|
|
this->options = _options;
|
|
}
|
|
inline void addOption(const string& option) {
|
|
options.push_back(option);
|
|
}
|
|
inline void setDefault(int defId) {
|
|
this->def = defId;
|
|
}
|
|
};
|
|
|
|
class Slider : public CustomFormElement {
|
|
protected:
|
|
LIAPI string serialize() override;
|
|
|
|
public:
|
|
string title;
|
|
double minValue, maxValue, step, def;
|
|
|
|
public:
|
|
inline Slider(const string& name, string title, double minValue, double maxValue, double step = 1, double def = 0)
|
|
: title(std::move(title))
|
|
, minValue(minValue)
|
|
, maxValue(maxValue)
|
|
, step(step)
|
|
, def(def) {
|
|
setName(name);
|
|
}
|
|
inline Type getType() override {
|
|
return Type::Slider;
|
|
}
|
|
inline void setTitle(const string& _title) {
|
|
this->title = _title;
|
|
}
|
|
inline void setMin(double _minValue) {
|
|
this->minValue = _minValue;
|
|
}
|
|
inline void setMax(double _maxValue) {
|
|
this->maxValue = _maxValue;
|
|
}
|
|
inline void setStep(double _step) {
|
|
this->step = _step;
|
|
}
|
|
inline void setDefault(double _def) {
|
|
this->def = _def;
|
|
}
|
|
};
|
|
|
|
class StepSlider : public CustomFormElement {
|
|
protected:
|
|
LIAPI string serialize() override;
|
|
|
|
public:
|
|
string title;
|
|
vector<string> options;
|
|
int def;
|
|
|
|
public:
|
|
inline StepSlider(const string& name, string title, const vector<string>& options, int defId = 0)
|
|
: title(std::move(title))
|
|
, options(options)
|
|
, def(defId) {
|
|
setName(name);
|
|
}
|
|
inline Type getType() override {
|
|
return Type::StepSlider;
|
|
}
|
|
inline void setTitle(const string& _title) {
|
|
this->title = _title;
|
|
}
|
|
inline void setOptions(const vector<string>& _options) {
|
|
this->options = _options;
|
|
}
|
|
inline void addOption(const string& option) {
|
|
options.push_back(option);
|
|
}
|
|
inline void setDefault(int defId) {
|
|
this->def = defId;
|
|
}
|
|
};
|
|
|
|
//////////////////////////////// Forms ////////////////////////////////
|
|
class FormImpl {
|
|
protected:
|
|
// fifo_json json;
|
|
virtual string serialize() = 0;
|
|
};
|
|
|
|
class SimpleForm : public FormImpl {
|
|
protected:
|
|
LIAPI string serialize() override;
|
|
|
|
public:
|
|
using Callback = std::function<void(Player*, int)>;
|
|
string title, content;
|
|
vector<std::shared_ptr<SimpleFormElement>> elements;
|
|
Callback callback;
|
|
|
|
public:
|
|
SimpleForm(string title, string content)
|
|
: title(std::move(title))
|
|
, content(std::move(content)) {
|
|
}
|
|
template <typename T, typename... Args>
|
|
SimpleForm(const string& title, const string& content, T element, Args... args) {
|
|
append(element);
|
|
SimpleForm(title, content, args...);
|
|
}
|
|
LIAPI SimpleForm& setTitle(const string& title);
|
|
LIAPI SimpleForm& setContent(const string& content);
|
|
LIAPI SimpleForm& addButton(string text, string image = "", Button::ButtonCallback callback = Button::ButtonCallback());
|
|
LIAPI SimpleForm& append(const Button& element);
|
|
LIAPI bool sendTo(Player* player, Callback callback = Callback());
|
|
};
|
|
|
|
class ModalForm : public FormImpl {
|
|
protected:
|
|
LIAPI string serialize() override;
|
|
|
|
public:
|
|
using Callback = std::function<void(Player*, bool)>;
|
|
string title, content, confirmButton, cancelButton;
|
|
Callback callback;
|
|
|
|
public:
|
|
ModalForm(string title, string content, string button1, string button2)
|
|
: title(std::move(title))
|
|
, content(std::move(content))
|
|
, confirmButton(std::move(button1))
|
|
, cancelButton(std::move(button2)) {
|
|
}
|
|
template <typename T, typename... Args>
|
|
ModalForm(const string& title, const string& content, const string& confirmButton, const string& cancelButton, Args... args) {
|
|
ModalForm(title, content, confirmButton, cancelButton, args...);
|
|
}
|
|
LIAPI ModalForm& setTitle(const string& title);
|
|
LIAPI ModalForm& setContent(const string& content);
|
|
LIAPI ModalForm& setConfirmButton(const string& text);
|
|
LIAPI ModalForm& setCancelButton(const string& text);
|
|
LIAPI bool sendTo(Player* player, Callback callback = Callback());
|
|
};
|
|
|
|
class CustomForm : public FormImpl {
|
|
protected:
|
|
LIAPI string serialize() override;
|
|
|
|
public:
|
|
using Callback = std::function<void(Player*, std::map<string, std::shared_ptr<CustomFormElement>>)>;
|
|
using Callback2 = std::function<void(Player*, std::string)>;
|
|
string title;
|
|
std::vector<std::pair<string, std::shared_ptr<CustomFormElement>>> elements;
|
|
Callback callback;
|
|
|
|
public:
|
|
explicit CustomForm(string title)
|
|
: title(std::move(title)) {
|
|
}
|
|
template <typename T, typename... Args>
|
|
CustomForm(const string& title, T element, Args... args) {
|
|
append(element);
|
|
CustomForm(title, args...);
|
|
}
|
|
LIAPI CustomForm& setTitle(const string& title);
|
|
|
|
LIAPI CustomForm& addLabel(const string& name, string text);
|
|
LIAPI CustomForm& addInput(const string& name, string title, string placeholder = "", string def = "");
|
|
LIAPI CustomForm& addToggle(const string& name, string title, bool def = false);
|
|
LIAPI CustomForm& addDropdown(const string& name, string title, const vector<string>& options, int defId = 0);
|
|
LIAPI CustomForm& addSlider(const string& name, string title, double min, double max, double step = 1, double def = 0);
|
|
LIAPI CustomForm& addStepSlider(const string& name, string title, const vector<string>& options, int defId = 0);
|
|
|
|
LIAPI CustomForm& append(const Label& element);
|
|
LIAPI CustomForm& append(const Input& element);
|
|
LIAPI CustomForm& append(const Toggle& element);
|
|
LIAPI CustomForm& append(const Dropdown& element);
|
|
LIAPI CustomForm& append(const Slider& element);
|
|
LIAPI CustomForm& append(const StepSlider& element);
|
|
|
|
LIAPI bool sendTo(Player* player, Callback callback);
|
|
LIAPI bool sendToForRawJson(Player* player, Callback2 callback);
|
|
LIAPI CustomFormElement* getElement(const string& name);
|
|
LIAPI CustomFormElement* getElement(int index);
|
|
LIAPI CustomFormElement::Type getType(int index);
|
|
|
|
LIAPI string getString(const string& name);
|
|
[[deprecated("Please use getInt")]]
|
|
LIAPI int getNumber(const string& name);
|
|
LIAPI int getInt(const string& name);
|
|
LIAPI float getFloat(const string& name);
|
|
LIAPI double getDouble(const string& name);
|
|
LIAPI bool getBool(const string& name);
|
|
LIAPI string getString(int index);
|
|
[[deprecated("Please use getInt")]]
|
|
LIAPI int getNumber(int index);
|
|
LIAPI int getInt(int index);
|
|
LIAPI float getFloat(int index);
|
|
LIAPI double getDouble(int index);
|
|
LIAPI bool getBool(int index);
|
|
|
|
// Tool Functions
|
|
template <typename T>
|
|
inline void setValue(int index, T value) {
|
|
elements[index].second->value = std::to_string(value);
|
|
}
|
|
inline void setValue(int index, string value) {
|
|
elements[index].second->value = value;
|
|
}
|
|
};
|
|
} // namespace Form
|