refactor: add GUI instance reference to UI nodes
This commit is contained in:
parent
74a94f869c
commit
4c48afbb90
@ -19,13 +19,14 @@
|
|||||||
#include "items/ItemDef.hpp"
|
#include "items/ItemDef.hpp"
|
||||||
#include "Assets.hpp"
|
#include "Assets.hpp"
|
||||||
#include "assetload_funcs.hpp"
|
#include "assetload_funcs.hpp"
|
||||||
|
#include "engine/Engine.hpp"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
static debug::Logger logger("assets-loader");
|
static debug::Logger logger("assets-loader");
|
||||||
|
|
||||||
AssetsLoader::AssetsLoader(Assets* assets, const ResPaths* paths)
|
AssetsLoader::AssetsLoader(Engine& engine, Assets& assets, const ResPaths* paths)
|
||||||
: assets(assets), paths(paths) {
|
: engine(engine), assets(assets), paths(paths) {
|
||||||
addLoader(AssetType::SHADER, assetload::shader);
|
addLoader(AssetType::SHADER, assetload::shader);
|
||||||
addLoader(AssetType::TEXTURE, assetload::texture);
|
addLoader(AssetType::TEXTURE, assetload::texture);
|
||||||
addLoader(AssetType::FONT, assetload::font);
|
addLoader(AssetType::FONT, assetload::font);
|
||||||
@ -73,7 +74,7 @@ void AssetsLoader::loadNext() {
|
|||||||
aloader_func loader = getLoader(entry.tag);
|
aloader_func loader = getLoader(entry.tag);
|
||||||
auto postfunc =
|
auto postfunc =
|
||||||
loader(this, paths, entry.filename, entry.alias, entry.config);
|
loader(this, paths, entry.filename, entry.alias, entry.config);
|
||||||
postfunc(assets);
|
postfunc(&assets);
|
||||||
entries.pop();
|
entries.pop();
|
||||||
} catch (std::runtime_error& err) {
|
} catch (std::runtime_error& err) {
|
||||||
logger.error() << err.what();
|
logger.error() << err.what();
|
||||||
@ -101,7 +102,7 @@ static void add_layouts(
|
|||||||
AssetType::LAYOUT,
|
AssetType::LAYOUT,
|
||||||
file.string(),
|
file.string(),
|
||||||
name,
|
name,
|
||||||
std::make_shared<LayoutCfg>(env)
|
std::make_shared<LayoutCfg>(&loader.getEngine().getGUI(), env)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,6 +297,10 @@ bool AssetsLoader::loadExternalTexture(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Engine& AssetsLoader::getEngine() {
|
||||||
|
return engine;
|
||||||
|
}
|
||||||
|
|
||||||
const ResPaths* AssetsLoader::getPaths() const {
|
const ResPaths* AssetsLoader::getPaths() const {
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
@ -324,7 +329,7 @@ std::shared_ptr<Task> AssetsLoader::startTask(runnable onDone) {
|
|||||||
std::make_shared<util::ThreadPool<aloader_entry, assetload::postfunc>>(
|
std::make_shared<util::ThreadPool<aloader_entry, assetload::postfunc>>(
|
||||||
"assets-loader-pool",
|
"assets-loader-pool",
|
||||||
[=]() { return std::make_shared<LoaderWorker>(this); },
|
[=]() { return std::make_shared<LoaderWorker>(this); },
|
||||||
[=](const assetload::postfunc& func) { func(assets); }
|
[this](const assetload::postfunc& func) { func(&assets); }
|
||||||
);
|
);
|
||||||
pool->setOnComplete(std::move(onDone));
|
pool->setOnComplete(std::move(onDone));
|
||||||
while (!entries.empty()) {
|
while (!entries.empty()) {
|
||||||
|
|||||||
@ -18,6 +18,11 @@
|
|||||||
class ResPaths;
|
class ResPaths;
|
||||||
class AssetsLoader;
|
class AssetsLoader;
|
||||||
class Content;
|
class Content;
|
||||||
|
class Engine;
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
class GUI;
|
||||||
|
}
|
||||||
|
|
||||||
struct AssetCfg {
|
struct AssetCfg {
|
||||||
virtual ~AssetCfg() {
|
virtual ~AssetCfg() {
|
||||||
@ -25,9 +30,10 @@ struct AssetCfg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct LayoutCfg : AssetCfg {
|
struct LayoutCfg : AssetCfg {
|
||||||
|
gui::GUI* gui;
|
||||||
scriptenv env;
|
scriptenv env;
|
||||||
|
|
||||||
LayoutCfg(scriptenv env) : env(std::move(env)) {
|
LayoutCfg(gui::GUI* gui, scriptenv env) : gui(gui), env(std::move(env)) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,7 +67,8 @@ struct aloader_entry {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class AssetsLoader {
|
class AssetsLoader {
|
||||||
Assets* assets;
|
Engine& engine;
|
||||||
|
Assets& assets;
|
||||||
std::map<AssetType, aloader_func> loaders;
|
std::map<AssetType, aloader_func> loaders;
|
||||||
std::queue<aloader_entry> entries;
|
std::queue<aloader_entry> entries;
|
||||||
std::set<std::pair<AssetType, std::string>> enqueued;
|
std::set<std::pair<AssetType, std::string>> enqueued;
|
||||||
@ -76,7 +83,7 @@ class AssetsLoader {
|
|||||||
void processPreloadConfig(const io::path& file);
|
void processPreloadConfig(const io::path& file);
|
||||||
void processPreloadConfigs(const Content* content);
|
void processPreloadConfigs(const Content* content);
|
||||||
public:
|
public:
|
||||||
AssetsLoader(Assets* assets, const ResPaths* paths);
|
AssetsLoader(Engine& engine, Assets& assets, const ResPaths* paths);
|
||||||
void addLoader(AssetType tag, aloader_func func);
|
void addLoader(AssetType tag, aloader_func func);
|
||||||
|
|
||||||
/// @brief Enqueue asset load
|
/// @brief Enqueue asset load
|
||||||
@ -111,4 +118,6 @@ public:
|
|||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::vector<io::path>& alternatives
|
const std::vector<io::path>& alternatives
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Engine& getEngine();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -189,6 +189,7 @@ assetload::postfunc assetload::layout(
|
|||||||
auto prefix = name.substr(0, pos);
|
auto prefix = name.substr(0, pos);
|
||||||
assets->store(
|
assets->store(
|
||||||
UiDocument::read(
|
UiDocument::read(
|
||||||
|
*cfg->gui,
|
||||||
cfg->env,
|
cfg->env,
|
||||||
name,
|
name,
|
||||||
file,
|
file,
|
||||||
|
|||||||
@ -50,8 +50,6 @@
|
|||||||
|
|
||||||
static debug::Logger logger("engine");
|
static debug::Logger logger("engine");
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
static std::unique_ptr<ImageData> load_icon() {
|
static std::unique_ptr<ImageData> load_icon() {
|
||||||
try {
|
try {
|
||||||
auto file = "res:textures/misc/icon.png";
|
auto file = "res:textures/misc/icon.png";
|
||||||
@ -65,20 +63,21 @@ static std::unique_ptr<ImageData> load_icon() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Engine::Engine() = default;
|
Engine::Engine() = default;
|
||||||
|
Engine::~Engine() = default;
|
||||||
|
|
||||||
static std::unique_ptr<Engine> engine;
|
static std::unique_ptr<Engine> instance = nullptr;
|
||||||
|
|
||||||
Engine& Engine::getInstance() {
|
Engine& Engine::getInstance() {
|
||||||
if (!engine) {
|
if (!instance) {
|
||||||
engine = std::make_unique<Engine>();
|
instance = std::make_unique<Engine>();
|
||||||
}
|
}
|
||||||
return *engine;
|
return *instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initialize(CoreParameters coreParameters) {
|
void Engine::initialize(CoreParameters coreParameters) {
|
||||||
params = std::move(coreParameters);
|
params = std::move(coreParameters);
|
||||||
settingsHandler = std::make_unique<SettingsHandler>(settings);
|
settingsHandler = std::make_unique<SettingsHandler>(settings);
|
||||||
interpreter = std::make_unique<cmd::CommandsInterpreter>();
|
cmd = std::make_unique<cmd::CommandsInterpreter>();
|
||||||
network = network::Network::create(settings.network);
|
network = network::Network::create(settings.network);
|
||||||
|
|
||||||
logger.info() << "engine version: " << ENGINE_VERSION_STRING;
|
logger.info() << "engine version: " << ENGINE_VERSION_STRING;
|
||||||
@ -97,7 +96,7 @@ void Engine::initialize(CoreParameters coreParameters) {
|
|||||||
|
|
||||||
controller = std::make_unique<EngineController>(*this);
|
controller = std::make_unique<EngineController>(*this);
|
||||||
if (!params.headless) {
|
if (!params.headless) {
|
||||||
if (Window::initialize(&settings.display)){
|
if (!(input = Window::initialize(&settings.display))){
|
||||||
throw initialize_error("could not initialize window");
|
throw initialize_error("could not initialize window");
|
||||||
}
|
}
|
||||||
time.set(Window::time());
|
time.set(Window::time());
|
||||||
@ -107,9 +106,9 @@ void Engine::initialize(CoreParameters coreParameters) {
|
|||||||
}
|
}
|
||||||
loadControls();
|
loadControls();
|
||||||
|
|
||||||
gui = std::make_unique<gui::GUI>();
|
gui = std::make_unique<gui::GUI>(*this);
|
||||||
if (ENGINE_DEBUG_BUILD) {
|
if (ENGINE_DEBUG_BUILD) {
|
||||||
menus::create_version_label(*this);
|
menus::create_version_label(*gui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
audio::initialize(!params.headless, settings.audio);
|
audio::initialize(!params.headless, settings.audio);
|
||||||
@ -209,7 +208,7 @@ void Engine::nextFrame() {
|
|||||||
: settings.display.framerate.get()
|
: settings.display.framerate.get()
|
||||||
);
|
);
|
||||||
Window::swapBuffers();
|
Window::swapBuffers();
|
||||||
Events::pollEvents();
|
input->pollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::renderFrame() {
|
void Engine::renderFrame() {
|
||||||
@ -229,7 +228,7 @@ void Engine::saveSettings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::~Engine() {
|
void Engine::close() {
|
||||||
saveSettings();
|
saveSettings();
|
||||||
logger.info() << "shutting down";
|
logger.info() << "shutting down";
|
||||||
if (screen) {
|
if (screen) {
|
||||||
@ -238,7 +237,7 @@ Engine::~Engine() {
|
|||||||
}
|
}
|
||||||
content.reset();
|
content.reset();
|
||||||
assets.reset();
|
assets.reset();
|
||||||
interpreter.reset();
|
cmd.reset();
|
||||||
if (gui) {
|
if (gui) {
|
||||||
gui.reset();
|
gui.reset();
|
||||||
logger.info() << "gui finished";
|
logger.info() << "gui finished";
|
||||||
@ -256,17 +255,14 @@ Engine::~Engine() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Engine::terminate() {
|
void Engine::terminate() {
|
||||||
engine.reset();
|
instance->close();
|
||||||
|
instance.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
EngineController* Engine::getController() {
|
EngineController* Engine::getController() {
|
||||||
return controller.get();
|
return controller.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd::CommandsInterpreter* Engine::getCommandsInterpreter() {
|
|
||||||
return interpreter.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
PacksManager Engine::createPacksManager(const io::path& worldFolder) {
|
PacksManager Engine::createPacksManager(const io::path& worldFolder) {
|
||||||
PacksManager manager;
|
PacksManager manager;
|
||||||
manager.setSources({
|
manager.setSources({
|
||||||
@ -286,7 +282,7 @@ void Engine::loadAssets() {
|
|||||||
Shader::preprocessor->setPaths(resPaths.get());
|
Shader::preprocessor->setPaths(resPaths.get());
|
||||||
|
|
||||||
auto new_assets = std::make_unique<Assets>();
|
auto new_assets = std::make_unique<Assets>();
|
||||||
AssetsLoader loader(new_assets.get(), resPaths.get());
|
AssetsLoader loader(*this, *new_assets, resPaths.get());
|
||||||
AssetsLoader::addDefaults(loader, content.get());
|
AssetsLoader::addDefaults(loader, content.get());
|
||||||
|
|
||||||
// no need
|
// no need
|
||||||
@ -376,7 +372,6 @@ void Engine::loadContent() {
|
|||||||
load_configs(pack.folder);
|
load_configs(pack.folder);
|
||||||
}
|
}
|
||||||
content = contentBuilder.build();
|
content = contentBuilder.build();
|
||||||
interpreter->reset();
|
|
||||||
scripting::on_content_load(content.get());
|
scripting::on_content_load(content.get());
|
||||||
|
|
||||||
ContentLoader::loadScripts(*content);
|
ContentLoader::loadScripts(*content);
|
||||||
@ -468,10 +463,6 @@ bool Engine::isQuitSignal() const {
|
|||||||
return quitSignal;
|
return quitSignal;
|
||||||
}
|
}
|
||||||
|
|
||||||
gui::GUI* Engine::getGUI() {
|
|
||||||
return gui.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
EngineSettings& Engine::getSettings() {
|
EngineSettings& Engine::getSettings() {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
@ -518,10 +509,6 @@ SettingsHandler& Engine::getSettingsHandler() {
|
|||||||
return *settingsHandler;
|
return *settingsHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
network::Network& Engine::getNetwork() {
|
|
||||||
return *network;
|
|
||||||
}
|
|
||||||
|
|
||||||
Time& Engine::getTime() {
|
Time& Engine::getTime() {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ class ResPaths;
|
|||||||
class EngineController;
|
class EngineController;
|
||||||
class SettingsHandler;
|
class SettingsHandler;
|
||||||
struct EngineSettings;
|
struct EngineSettings;
|
||||||
|
class Input;
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
class GUI;
|
class GUI;
|
||||||
@ -66,8 +67,9 @@ class Engine : public util::ObjectsKeeper {
|
|||||||
std::unique_ptr<Content> content;
|
std::unique_ptr<Content> content;
|
||||||
std::unique_ptr<ResPaths> resPaths;
|
std::unique_ptr<ResPaths> resPaths;
|
||||||
std::unique_ptr<EngineController> controller;
|
std::unique_ptr<EngineController> controller;
|
||||||
std::unique_ptr<cmd::CommandsInterpreter> interpreter;
|
std::unique_ptr<cmd::CommandsInterpreter> cmd;
|
||||||
std::unique_ptr<network::Network> network;
|
std::unique_ptr<network::Network> network;
|
||||||
|
std::unique_ptr<Input> input;
|
||||||
std::vector<std::string> basePacks;
|
std::vector<std::string> basePacks;
|
||||||
std::unique_ptr<gui::GUI> gui;
|
std::unique_ptr<gui::GUI> gui;
|
||||||
PostRunnables postRunnables;
|
PostRunnables postRunnables;
|
||||||
@ -87,6 +89,7 @@ public:
|
|||||||
static Engine& getInstance();
|
static Engine& getInstance();
|
||||||
|
|
||||||
void initialize(CoreParameters coreParameters);
|
void initialize(CoreParameters coreParameters);
|
||||||
|
void close();
|
||||||
|
|
||||||
static void terminate();
|
static void terminate();
|
||||||
|
|
||||||
@ -129,9 +132,6 @@ public:
|
|||||||
/// @brief Get active assets storage instance
|
/// @brief Get active assets storage instance
|
||||||
Assets* getAssets();
|
Assets* getAssets();
|
||||||
|
|
||||||
/// @brief Get main UI controller
|
|
||||||
gui::GUI* getGUI();
|
|
||||||
|
|
||||||
/// @brief Get writeable engine settings structure instance
|
/// @brief Get writeable engine settings structure instance
|
||||||
EngineSettings& getSettings();
|
EngineSettings& getSettings();
|
||||||
|
|
||||||
@ -171,7 +171,6 @@ public:
|
|||||||
void saveScreenshot();
|
void saveScreenshot();
|
||||||
|
|
||||||
EngineController* getController();
|
EngineController* getController();
|
||||||
cmd::CommandsInterpreter* getCommandsInterpreter();
|
|
||||||
|
|
||||||
PacksManager createPacksManager(const io::path& worldFolder);
|
PacksManager createPacksManager(const io::path& worldFolder);
|
||||||
|
|
||||||
@ -179,11 +178,25 @@ public:
|
|||||||
|
|
||||||
SettingsHandler& getSettingsHandler();
|
SettingsHandler& getSettingsHandler();
|
||||||
|
|
||||||
network::Network& getNetwork();
|
|
||||||
|
|
||||||
Time& getTime();
|
Time& getTime();
|
||||||
|
|
||||||
const CoreParameters& getCoreParameters() const;
|
const CoreParameters& getCoreParameters() const;
|
||||||
|
|
||||||
bool isHeadless() const;
|
bool isHeadless() const;
|
||||||
|
|
||||||
|
gui::GUI& getGUI() {
|
||||||
|
return *gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input& getInput() {
|
||||||
|
return *input;
|
||||||
|
}
|
||||||
|
|
||||||
|
network::Network& getNetwork() {
|
||||||
|
return *network;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd::CommandsInterpreter& getCmd() {
|
||||||
|
return *cmd;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -54,6 +54,7 @@ scriptenv UiDocument::getEnvironment() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<UiDocument> UiDocument::read(
|
std::unique_ptr<UiDocument> UiDocument::read(
|
||||||
|
gui::GUI& gui,
|
||||||
const scriptenv& penv,
|
const scriptenv& penv,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const io::path& file,
|
const io::path& file,
|
||||||
@ -66,7 +67,7 @@ std::unique_ptr<UiDocument> UiDocument::read(
|
|||||||
? scripting::create_doc_environment(scripting::get_root_environment(), name)
|
? scripting::create_doc_environment(scripting::get_root_environment(), name)
|
||||||
: scripting::create_doc_environment(penv, name);
|
: scripting::create_doc_environment(penv, name);
|
||||||
|
|
||||||
gui::UiXmlReader reader(env);
|
gui::UiXmlReader reader(gui, env);
|
||||||
auto view = reader.readXML(file.string(), *xmldoc->getRoot());
|
auto view = reader.readXML(file.string(), *xmldoc->getRoot());
|
||||||
view->setId("root");
|
view->setId("root");
|
||||||
uidocscript script {};
|
uidocscript script {};
|
||||||
@ -80,8 +81,7 @@ std::unique_ptr<UiDocument> UiDocument::read(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<gui::UINode> UiDocument::readElement(
|
std::shared_ptr<gui::UINode> UiDocument::readElement(
|
||||||
const io::path& file, const std::string& fileName
|
gui::GUI& gui, const io::path& file, const std::string& fileName
|
||||||
) {
|
) {
|
||||||
auto document = read(nullptr, file.name(), file, fileName);
|
return read(gui, nullptr, file.name(), file, fileName)->getRoot();
|
||||||
return document->getRoot();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include "io/fwd.hpp"
|
#include "io/fwd.hpp"
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
class GUI;
|
||||||
class UINode;
|
class UINode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,12 +46,13 @@ public:
|
|||||||
scriptenv getEnvironment() const;
|
scriptenv getEnvironment() const;
|
||||||
|
|
||||||
static std::unique_ptr<UiDocument> read(
|
static std::unique_ptr<UiDocument> read(
|
||||||
|
gui::GUI&,
|
||||||
const scriptenv& parent_env,
|
const scriptenv& parent_env,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const io::path& file,
|
const io::path& file,
|
||||||
const std::string& fileName
|
const std::string& fileName
|
||||||
);
|
);
|
||||||
static std::shared_ptr<gui::UINode> readElement(
|
static std::shared_ptr<gui::UINode> readElement(
|
||||||
const io::path& file, const std::string& fileName
|
gui::GUI&, const io::path& file, const std::string& fileName
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -35,8 +35,8 @@
|
|||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
static std::shared_ptr<Label> create_label(wstringsupplier supplier) {
|
static std::shared_ptr<Label> create_label(GUI& gui, wstringsupplier supplier) {
|
||||||
auto label = std::make_shared<Label>(L"-");
|
auto label = std::make_shared<Label>(gui, L"-");
|
||||||
label->textSupplier(std::move(supplier));
|
label->textSupplier(std::move(supplier));
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
@ -50,7 +50,10 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
Player& player,
|
Player& player,
|
||||||
bool allowDebugCheats
|
bool allowDebugCheats
|
||||||
) {
|
) {
|
||||||
auto panel = std::make_shared<Panel>(glm::vec2(300, 200), glm::vec4(5.0f), 2.0f);
|
auto& gui = engine.getGUI();
|
||||||
|
auto panel = std::make_shared<Panel>(
|
||||||
|
gui, glm::vec2(300, 200), glm::vec4(5.0f), 2.0f
|
||||||
|
);
|
||||||
panel->setId("hud.debug-panel");
|
panel->setId("hud.debug-panel");
|
||||||
panel->setPos(glm::vec2(10, 10));
|
panel->setPos(glm::vec2(10, 10));
|
||||||
|
|
||||||
@ -87,48 +90,48 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
lastTotalUpload = totalUpload;
|
lastTotalUpload = totalUpload;
|
||||||
});
|
});
|
||||||
|
|
||||||
panel->add(create_label([]() { return L"fps: "+fpsString;}));
|
panel->add(create_label(gui, []() { return L"fps: "+fpsString;}));
|
||||||
|
|
||||||
panel->add(create_label([]() {
|
panel->add(create_label(gui, []() {
|
||||||
return L"meshes: " + std::to_wstring(Mesh::meshesCount);
|
return L"meshes: " + std::to_wstring(Mesh::meshesCount);
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([]() {
|
panel->add(create_label(gui, []() {
|
||||||
int drawCalls = Mesh::drawCalls;
|
int drawCalls = Mesh::drawCalls;
|
||||||
Mesh::drawCalls = 0;
|
Mesh::drawCalls = 0;
|
||||||
return L"draw-calls: " + std::to_wstring(drawCalls);
|
return L"draw-calls: " + std::to_wstring(drawCalls);
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([]() {
|
panel->add(create_label(gui, []() {
|
||||||
return L"speakers: " + std::to_wstring(audio::count_speakers())+
|
return L"speakers: " + std::to_wstring(audio::count_speakers())+
|
||||||
L" streams: " + std::to_wstring(audio::count_streams());
|
L" streams: " + std::to_wstring(audio::count_streams());
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([]() {
|
panel->add(create_label(gui, []() {
|
||||||
return L"lua-stack: " + std::to_wstring(scripting::get_values_on_stack());
|
return L"lua-stack: " + std::to_wstring(scripting::get_values_on_stack());
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([]() { return netSpeedString; }));
|
panel->add(create_label(gui, []() { return netSpeedString; }));
|
||||||
panel->add(create_label([&engine]() {
|
panel->add(create_label(gui, [&engine]() {
|
||||||
auto& settings = engine.getSettings();
|
auto& settings = engine.getSettings();
|
||||||
bool culling = settings.graphics.frustumCulling.get();
|
bool culling = settings.graphics.frustumCulling.get();
|
||||||
return L"frustum-culling: "+std::wstring(culling ? L"on" : L"off");
|
return L"frustum-culling: "+std::wstring(culling ? L"on" : L"off");
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([=]() {
|
panel->add(create_label(gui, [=]() {
|
||||||
return L"particles: " +
|
return L"particles: " +
|
||||||
std::to_wstring(ParticlesRenderer::visibleParticles) +
|
std::to_wstring(ParticlesRenderer::visibleParticles) +
|
||||||
L" emitters: " +
|
L" emitters: " +
|
||||||
std::to_wstring(ParticlesRenderer::aliveEmitters);
|
std::to_wstring(ParticlesRenderer::aliveEmitters);
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([&]() {
|
panel->add(create_label(gui, [&]() {
|
||||||
return L"chunks: "+std::to_wstring(level.chunks->size())+
|
return L"chunks: "+std::to_wstring(level.chunks->size())+
|
||||||
L" visible: "+std::to_wstring(ChunksRenderer::visibleChunks);
|
L" visible: "+std::to_wstring(ChunksRenderer::visibleChunks);
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([&]() {
|
panel->add(create_label(gui, [&]() {
|
||||||
return L"entities: "+std::to_wstring(level.entities->size())+L" next: "+
|
return L"entities: "+std::to_wstring(level.entities->size())+L" next: "+
|
||||||
std::to_wstring(level.entities->peekNextID());
|
std::to_wstring(level.entities->peekNextID());
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([&]() {
|
panel->add(create_label(gui, [&]() {
|
||||||
return L"players: "+std::to_wstring(level.players->size())+L" local: "+
|
return L"players: "+std::to_wstring(level.players->size())+L" local: "+
|
||||||
std::to_wstring(player.getId());
|
std::to_wstring(player.getId());
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([&]() -> std::wstring {
|
panel->add(create_label(gui, [&]() -> std::wstring {
|
||||||
const auto& vox = player.selection.vox;
|
const auto& vox = player.selection.vox;
|
||||||
std::wstringstream stream;
|
std::wstringstream stream;
|
||||||
stream << "r:" << vox.state.rotation << " s:"
|
stream << "r:" << vox.state.rotation << " s:"
|
||||||
@ -141,7 +144,7 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
L" "+stream.str();
|
L" "+stream.str();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([&]() -> std::wstring {
|
panel->add(create_label(gui, [&]() -> std::wstring {
|
||||||
const auto& selection = player.selection;
|
const auto& selection = player.selection;
|
||||||
const auto& vox = selection.vox;
|
const auto& vox = selection.vox;
|
||||||
if (vox.id == BLOCK_VOID) {
|
if (vox.id == BLOCK_VOID) {
|
||||||
@ -151,7 +154,7 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
L" y: " + std::to_wstring(selection.actualPosition.y) +
|
L" y: " + std::to_wstring(selection.actualPosition.y) +
|
||||||
L" z: " + std::to_wstring(selection.actualPosition.z);
|
L" z: " + std::to_wstring(selection.actualPosition.z);
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([&]() {
|
panel->add(create_label(gui, [&]() {
|
||||||
auto eid = player.getSelectedEntity();
|
auto eid = player.getSelectedEntity();
|
||||||
if (eid == ENTITY_NONE) {
|
if (eid == ENTITY_NONE) {
|
||||||
return std::wstring {L"entity: -"};
|
return std::wstring {L"entity: -"};
|
||||||
@ -162,7 +165,7 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
return std::wstring {L"entity: error (invalid UID)"};
|
return std::wstring {L"entity: error (invalid UID)"};
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([&](){
|
panel->add(create_label(gui, [&](){
|
||||||
auto indices = level.content.getIndices();
|
auto indices = level.content.getIndices();
|
||||||
if (auto def = indices->blocks.get(player.selection.vox.id)) {
|
if (auto def = indices->blocks.get(player.selection.vox.id)) {
|
||||||
return L"name: " + util::str2wstr_utf8(def->name);
|
return L"name: " + util::str2wstr_utf8(def->name);
|
||||||
@ -170,23 +173,23 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
return std::wstring {L"name: void"};
|
return std::wstring {L"name: void"};
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([&](){
|
panel->add(create_label(gui, [&](){
|
||||||
return L"seed: "+std::to_wstring(level.getWorld()->getSeed());
|
return L"seed: "+std::to_wstring(level.getWorld()->getSeed());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
for (int ax = 0; ax < 3; ax++) {
|
for (int ax = 0; ax < 3; ax++) {
|
||||||
auto sub = std::make_shared<Container>(glm::vec2(250, 27));
|
auto sub = std::make_shared<Container>(gui, glm::vec2(250, 27));
|
||||||
|
|
||||||
std::wstring str = L"x: ";
|
std::wstring str = L"x: ";
|
||||||
str[0] += ax;
|
str[0] += ax;
|
||||||
auto label = std::make_shared<Label>(str);
|
auto label = std::make_shared<Label>(gui, str);
|
||||||
label->setMargin(glm::vec4(2, 3, 2, 3));
|
label->setMargin(glm::vec4(2, 3, 2, 3));
|
||||||
label->setSize(glm::vec2(20, 27));
|
label->setSize(glm::vec2(20, 27));
|
||||||
sub->add(label);
|
sub->add(label);
|
||||||
sub->setColor(glm::vec4(0.0f));
|
sub->setColor(glm::vec4(0.0f));
|
||||||
|
|
||||||
// Coord input
|
// Coord input
|
||||||
auto box = std::make_shared<TextBox>(L"");
|
auto box = std::make_shared<TextBox>(gui, L"");
|
||||||
auto boxRef = box.get();
|
auto boxRef = box.get();
|
||||||
box->setTextSupplier([&player, ax]() {
|
box->setTextSupplier([&player, ax]() {
|
||||||
return util::to_wstring(player.getPosition()[ax], 2);
|
return util::to_wstring(player.getPosition()[ax], 2);
|
||||||
@ -212,7 +215,7 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
panel->add(sub);
|
panel->add(sub);
|
||||||
}
|
}
|
||||||
auto& worldInfo = level.getWorld()->getInfo();
|
auto& worldInfo = level.getWorld()->getInfo();
|
||||||
panel->add(create_label([&](){
|
panel->add(create_label(gui, [&](){
|
||||||
int hour, minute, second;
|
int hour, minute, second;
|
||||||
timeutil::from_value(worldInfo.daytime, hour, minute, second);
|
timeutil::from_value(worldInfo.daytime, hour, minute, second);
|
||||||
|
|
||||||
@ -222,20 +225,20 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
return L"time: "+timeString;
|
return L"time: "+timeString;
|
||||||
}));
|
}));
|
||||||
if (allowDebugCheats) {
|
if (allowDebugCheats) {
|
||||||
auto bar = std::make_shared<TrackBar>(0.0f, 1.0f, 1.0f, 0.005f, 8);
|
auto bar = std::make_shared<TrackBar>(gui, 0.0f, 1.0f, 1.0f, 0.005f, 8);
|
||||||
bar->setSupplier([&]() {return worldInfo.daytime;});
|
bar->setSupplier([&]() {return worldInfo.daytime;});
|
||||||
bar->setConsumer([&](double val) {worldInfo.daytime = val;});
|
bar->setConsumer([&](double val) {worldInfo.daytime = val;});
|
||||||
panel->add(bar);
|
panel->add(bar);
|
||||||
}
|
}
|
||||||
if (allowDebugCheats) {
|
if (allowDebugCheats) {
|
||||||
auto bar = std::make_shared<TrackBar>(0.0f, 1.0f, 0.0f, 0.005f, 8);
|
auto bar = std::make_shared<TrackBar>(gui, 0.0f, 1.0f, 0.0f, 0.005f, 8);
|
||||||
bar->setSupplier([&]() {return worldInfo.fog;});
|
bar->setSupplier([&]() {return worldInfo.fog;});
|
||||||
bar->setConsumer([&](double val) {worldInfo.fog = val;});
|
bar->setConsumer([&](double val) {worldInfo.fog = val;});
|
||||||
panel->add(bar);
|
panel->add(bar);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto checkbox = std::make_shared<FullCheckBox>(
|
auto checkbox = std::make_shared<FullCheckBox>(
|
||||||
L"Show Chunk Borders", glm::vec2(400, 24)
|
gui, L"Show Chunk Borders", glm::vec2(400, 24)
|
||||||
);
|
);
|
||||||
checkbox->setSupplier([=]() {
|
checkbox->setSupplier([=]() {
|
||||||
return WorldRenderer::showChunkBorders;
|
return WorldRenderer::showChunkBorders;
|
||||||
@ -247,7 +250,7 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto checkbox = std::make_shared<FullCheckBox>(
|
auto checkbox = std::make_shared<FullCheckBox>(
|
||||||
L"Show Hitboxes", glm::vec2(400, 24)
|
gui, L"Show Hitboxes", glm::vec2(400, 24)
|
||||||
);
|
);
|
||||||
checkbox->setSupplier([=]() {
|
checkbox->setSupplier([=]() {
|
||||||
return WorldRenderer::showEntitiesDebug;
|
return WorldRenderer::showEntitiesDebug;
|
||||||
@ -259,7 +262,7 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto checkbox = std::make_shared<FullCheckBox>(
|
auto checkbox = std::make_shared<FullCheckBox>(
|
||||||
L"Show Generator Minimap", glm::vec2(400, 24)
|
gui, L"Show Generator Minimap", glm::vec2(400, 24)
|
||||||
);
|
);
|
||||||
checkbox->setSupplier([=]() {
|
checkbox->setSupplier([=]() {
|
||||||
return Hud::showGeneratorMinimap;
|
return Hud::showGeneratorMinimap;
|
||||||
|
|||||||
@ -126,7 +126,7 @@ std::shared_ptr<InventoryView> Hud::createContentAccess() {
|
|||||||
inventory->getSlot(player.getChosenSlot()).set(item);
|
inventory->getSlot(player.getChosenSlot()).set(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
InventoryBuilder builder;
|
InventoryBuilder builder(gui);
|
||||||
builder.addGrid(8, itemsCount-1, glm::vec2(), glm::vec4(8, 8, 12, 8), true, slotLayout);
|
builder.addGrid(8, itemsCount-1, glm::vec2(), glm::vec4(8, 8, 12, 8), true, slotLayout);
|
||||||
auto view = builder.build();
|
auto view = builder.build();
|
||||||
view->bind(accessInventory, &content);
|
view->bind(accessInventory, &content);
|
||||||
@ -139,7 +139,7 @@ std::shared_ptr<InventoryView> Hud::createHotbar() {
|
|||||||
auto& content = frontend.getLevel().content;
|
auto& content = frontend.getLevel().content;
|
||||||
|
|
||||||
SlotLayout slotLayout(-1, glm::vec2(), false, false, nullptr, nullptr, nullptr);
|
SlotLayout slotLayout(-1, glm::vec2(), false, false, nullptr, nullptr, nullptr);
|
||||||
InventoryBuilder builder;
|
InventoryBuilder builder(gui);
|
||||||
builder.addGrid(10, 10, glm::vec2(), glm::vec4(4), true, slotLayout);
|
builder.addGrid(10, 10, glm::vec2(), glm::vec4(4), true, slotLayout);
|
||||||
auto view = builder.build();
|
auto view = builder.build();
|
||||||
view->setId("hud.hotbar");
|
view->setId("hud.hotbar");
|
||||||
@ -153,8 +153,10 @@ static constexpr uint WORLDGEN_IMG_SIZE = 128U;
|
|||||||
|
|
||||||
Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
|
Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
|
||||||
: engine(engine),
|
: engine(engine),
|
||||||
|
input(engine.getInput()),
|
||||||
assets(*engine.getAssets()),
|
assets(*engine.getAssets()),
|
||||||
gui(*engine.getGUI()),
|
gui(engine.getGUI()),
|
||||||
|
menu(*engine.getGUI().getMenu()),
|
||||||
frontend(frontend),
|
frontend(frontend),
|
||||||
player(player),
|
player(player),
|
||||||
debugImgWorldGen(std::make_unique<ImageData>(
|
debugImgWorldGen(std::make_unique<ImageData>(
|
||||||
@ -163,7 +165,7 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
|
|||||||
contentAccess = createContentAccess();
|
contentAccess = createContentAccess();
|
||||||
contentAccess->setId("hud.content-access");
|
contentAccess->setId("hud.content-access");
|
||||||
contentAccessPanel = std::make_shared<Panel>(
|
contentAccessPanel = std::make_shared<Panel>(
|
||||||
contentAccess->getSize(), glm::vec4(0.0f), 0.0f
|
gui, contentAccess->getSize(), glm::vec4(0.0f), 0.0f
|
||||||
);
|
);
|
||||||
contentAccessPanel->setColor(glm::vec4());
|
contentAccessPanel->setColor(glm::vec4());
|
||||||
contentAccessPanel->add(contentAccess);
|
contentAccessPanel->add(contentAccess);
|
||||||
@ -172,6 +174,7 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
|
|||||||
|
|
||||||
hotbarView = createHotbar();
|
hotbarView = createHotbar();
|
||||||
darkOverlay = guiutil::create(
|
darkOverlay = guiutil::create(
|
||||||
|
gui,
|
||||||
"<container size='4000' color='#00000080' z-index='-1' visible='false'/>"
|
"<container size='4000' color='#00000080' z-index='-1' visible='false'/>"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -183,13 +186,13 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
|
|||||||
engine, frontend.getLevel(), player, allowDebugCheats
|
engine, frontend.getLevel(), player, allowDebugCheats
|
||||||
);
|
);
|
||||||
debugPanel->setZIndex(2);
|
debugPanel->setZIndex(2);
|
||||||
gui.add(debugPanel);
|
|
||||||
|
|
||||||
|
gui.add(debugPanel);
|
||||||
gui.add(darkOverlay);
|
gui.add(darkOverlay);
|
||||||
gui.add(hotbarView);
|
gui.add(hotbarView);
|
||||||
gui.add(contentAccessPanel);
|
gui.add(contentAccessPanel);
|
||||||
|
|
||||||
auto dplotter = std::make_shared<Plotter>(350, 250, 2000, 16);
|
auto dplotter = std::make_shared<Plotter>(gui, 350, 250, 2000, 16);
|
||||||
dplotter->setGravity(Gravity::bottom_right);
|
dplotter->setGravity(Gravity::bottom_right);
|
||||||
dplotter->setInteractive(false);
|
dplotter->setInteractive(false);
|
||||||
add(HudElement(HudElementMode::PERMANENT, nullptr, dplotter, true));
|
add(HudElement(HudElementMode::PERMANENT, nullptr, dplotter, true));
|
||||||
@ -197,9 +200,10 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
|
|||||||
assets.store(Texture::from(debugImgWorldGen.get()), DEBUG_WORLDGEN_IMAGE);
|
assets.store(Texture::from(debugImgWorldGen.get()), DEBUG_WORLDGEN_IMAGE);
|
||||||
|
|
||||||
debugMinimap = guiutil::create(
|
debugMinimap = guiutil::create(
|
||||||
"<image src='"+DEBUG_WORLDGEN_IMAGE+
|
gui,
|
||||||
|
"<image src='" + DEBUG_WORLDGEN_IMAGE +
|
||||||
"' pos='0' size='256' gravity='top-right' margin='0,20,0,0'/>"
|
"' pos='0' size='256' gravity='top-right' margin='0,20,0,0'/>"
|
||||||
);
|
);
|
||||||
add(HudElement(HudElementMode::PERMANENT, nullptr, debugMinimap, true));
|
add(HudElement(HudElementMode::PERMANENT, nullptr, debugMinimap, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,11 +227,11 @@ void Hud::cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Hud::processInput(bool visible) {
|
void Hud::processInput(bool visible) {
|
||||||
auto menu = gui.getMenu();
|
if (!Window::isFocused() && !menu.hasOpenPage() && !isInventoryOpen()) {
|
||||||
if (!Window::isFocused() && !menu->hasOpenPage() && !isInventoryOpen()) {
|
|
||||||
setPause(true);
|
setPause(true);
|
||||||
}
|
}
|
||||||
if (!pause && visible && Events::jactive(BIND_HUD_INVENTORY)) {
|
const auto& bindings = input.getBindings();
|
||||||
|
if (!pause && visible && bindings.jactive(BIND_HUD_INVENTORY)) {
|
||||||
if (inventoryOpen) {
|
if (inventoryOpen) {
|
||||||
closeInventory();
|
closeInventory();
|
||||||
} else {
|
} else {
|
||||||
@ -240,9 +244,10 @@ void Hud::processInput(bool visible) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Hud::updateHotbarControl() {
|
void Hud::updateHotbarControl() {
|
||||||
if (!inventoryOpen && Events::scroll) {
|
int scroll = input.getScroll();
|
||||||
|
if (!inventoryOpen && scroll) {
|
||||||
int slot = player.getChosenSlot();
|
int slot = player.getChosenSlot();
|
||||||
slot = (slot - Events::scroll) % 10;
|
slot = (slot - scroll) % 10;
|
||||||
if (slot < 0) {
|
if (slot < 0) {
|
||||||
slot += 10;
|
slot += 10;
|
||||||
}
|
}
|
||||||
@ -253,11 +258,11 @@ void Hud::updateHotbarControl() {
|
|||||||
i <= static_cast<int>(keycode::NUM_9);
|
i <= static_cast<int>(keycode::NUM_9);
|
||||||
i++
|
i++
|
||||||
) {
|
) {
|
||||||
if (Events::jpressed(static_cast<keycode>(i))) {
|
if (input.jpressed(static_cast<keycode>(i))) {
|
||||||
player.setChosenSlot(i - static_cast<int>(keycode::NUM_1));
|
player.setChosenSlot(i - static_cast<int>(keycode::NUM_1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Events::jpressed(keycode::NUM_0)) {
|
if (input.jpressed(keycode::NUM_0)) {
|
||||||
player.setChosenSlot(9);
|
player.setChosenSlot(9);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,7 +316,6 @@ void Hud::updateWorldGenDebug() {
|
|||||||
|
|
||||||
void Hud::update(bool visible) {
|
void Hud::update(bool visible) {
|
||||||
const auto& chunks = *player.chunks;
|
const auto& chunks = *player.chunks;
|
||||||
const auto& menu = gui.getMenu();
|
|
||||||
|
|
||||||
debugPanel->setVisible(
|
debugPanel->setVisible(
|
||||||
debug && visible && !(inventoryOpen && inventoryView == nullptr)
|
debug && visible && !(inventoryOpen && inventoryView == nullptr)
|
||||||
@ -320,13 +324,13 @@ void Hud::update(bool visible) {
|
|||||||
if (!visible && inventoryOpen) {
|
if (!visible && inventoryOpen) {
|
||||||
closeInventory();
|
closeInventory();
|
||||||
}
|
}
|
||||||
if (pause && !menu->hasOpenPage()) {
|
if (pause && !menu.hasOpenPage()) {
|
||||||
setPause(false);
|
setPause(false);
|
||||||
}
|
}
|
||||||
if (!gui.isFocusCaught()) {
|
if (!gui.isFocusCaught()) {
|
||||||
processInput(visible);
|
processInput(visible);
|
||||||
}
|
}
|
||||||
if ((menu->hasOpenPage() || inventoryOpen) == Events::isCursorLocked()) {
|
if ((menu.hasOpenPage() || inventoryOpen) == input.getCursor().locked) {
|
||||||
Events::toggleCursor();
|
Events::toggleCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,6 +451,7 @@ void Hud::showExchangeSlot() {
|
|||||||
auto& content = level.content;
|
auto& content = level.content;
|
||||||
exchangeSlotInv = level.inventories->createVirtual(1);
|
exchangeSlotInv = level.inventories->createVirtual(1);
|
||||||
exchangeSlot = std::make_shared<SlotView>(
|
exchangeSlot = std::make_shared<SlotView>(
|
||||||
|
gui,
|
||||||
SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr, nullptr)
|
SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr, nullptr)
|
||||||
);
|
);
|
||||||
exchangeSlot->bind(exchangeSlotInv->getId(), exchangeSlotInv->getSlot(0), &content);
|
exchangeSlot->bind(exchangeSlotInv->getId(), exchangeSlotInv->getSlot(0), &content);
|
||||||
@ -590,11 +595,10 @@ void Hud::draw(const DrawContext& ctx){
|
|||||||
const Viewport& viewport = ctx.getViewport();
|
const Viewport& viewport = ctx.getViewport();
|
||||||
const uint width = viewport.getWidth();
|
const uint width = viewport.getWidth();
|
||||||
const uint height = viewport.getHeight();
|
const uint height = viewport.getHeight();
|
||||||
auto menu = gui.getMenu();
|
|
||||||
|
|
||||||
bool is_menu_open = menu->hasOpenPage();
|
bool is_menu_open = menu.hasOpenPage();
|
||||||
darkOverlay->setVisible(is_menu_open);
|
darkOverlay->setVisible(is_menu_open);
|
||||||
menu->setVisible(is_menu_open);
|
menu.setVisible(is_menu_open);
|
||||||
|
|
||||||
updateElementsPosition(viewport);
|
updateElementsPosition(viewport);
|
||||||
|
|
||||||
@ -663,7 +667,7 @@ void Hud::updateElementsPosition(const Viewport& viewport) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (exchangeSlot != nullptr) {
|
if (exchangeSlot != nullptr) {
|
||||||
exchangeSlot->setPos(glm::vec2(Events::cursor));
|
exchangeSlot->setPos(input.getCursor().pos);
|
||||||
}
|
}
|
||||||
hotbarView->setPos(glm::vec2(width/2, height-65));
|
hotbarView->setPos(glm::vec2(width/2, height-65));
|
||||||
hotbarView->setSelected(player.getChosenSlot());
|
hotbarView->setSelected(player.getChosenSlot());
|
||||||
@ -689,12 +693,11 @@ void Hud::setPause(bool pause) {
|
|||||||
closeInventory();
|
closeInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& menu = gui.getMenu();
|
if (!pause && menu.hasOpenPage()) {
|
||||||
if (!pause && menu->hasOpenPage()) {
|
menu.reset();
|
||||||
menu->reset();
|
|
||||||
}
|
}
|
||||||
if (pause && !menu->hasOpenPage()) {
|
if (pause && !menu.hasOpenPage()) {
|
||||||
menu->setPage("pause");
|
menu.setPage("pause");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,9 +733,8 @@ void Hud::setDebugCheats(bool flag) {
|
|||||||
|
|
||||||
void Hud::setAllowPause(bool flag) {
|
void Hud::setAllowPause(bool flag) {
|
||||||
if (pause) {
|
if (pause) {
|
||||||
auto menu = gui.getMenu();
|
|
||||||
setPause(false);
|
setPause(false);
|
||||||
menu->setPage("pause", true);
|
menu.setPage("pause", true);
|
||||||
}
|
}
|
||||||
allowPause = flag;
|
allowPause = flag;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,9 +20,11 @@ class UiDocument;
|
|||||||
class DrawContext;
|
class DrawContext;
|
||||||
class Viewport;
|
class Viewport;
|
||||||
class ImageData;
|
class ImageData;
|
||||||
|
class Input;
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
class GUI;
|
class GUI;
|
||||||
|
class Menu;
|
||||||
class UINode;
|
class UINode;
|
||||||
class Panel;
|
class Panel;
|
||||||
class Container;
|
class Container;
|
||||||
@ -71,9 +73,11 @@ public:
|
|||||||
|
|
||||||
class Hud : public util::ObjectsKeeper {
|
class Hud : public util::ObjectsKeeper {
|
||||||
Engine& engine;
|
Engine& engine;
|
||||||
|
Input& input;
|
||||||
Assets& assets;
|
Assets& assets;
|
||||||
std::unique_ptr<Camera> uicamera;
|
|
||||||
gui::GUI& gui;
|
gui::GUI& gui;
|
||||||
|
gui::Menu& menu;
|
||||||
|
std::unique_ptr<Camera> uicamera;
|
||||||
LevelFrontend& frontend;
|
LevelFrontend& frontend;
|
||||||
Player& player;
|
Player& player;
|
||||||
|
|
||||||
|
|||||||
@ -1,35 +1,35 @@
|
|||||||
#include "menu.hpp"
|
#include "menu.hpp"
|
||||||
|
|
||||||
#include "locale.hpp"
|
|
||||||
#include "UiDocument.hpp"
|
|
||||||
#include "screens/MenuScreen.hpp"
|
|
||||||
|
|
||||||
#include "delegates.hpp"
|
|
||||||
#include "engine/Engine.hpp"
|
|
||||||
#include "data/dv.hpp"
|
|
||||||
#include "interfaces/Task.hpp"
|
|
||||||
#include "io/engine_paths.hpp"
|
|
||||||
#include "graphics/ui/elements/Menu.hpp"
|
|
||||||
#include "graphics/ui/gui_util.hpp"
|
|
||||||
#include "graphics/ui/GUI.hpp"
|
|
||||||
#include "logic/scripting/scripting.hpp"
|
|
||||||
#include "settings.hpp"
|
|
||||||
#include "coders/commons.hpp"
|
|
||||||
#include "util/stringutil.hpp"
|
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "UiDocument.hpp"
|
||||||
|
#include "coders/commons.hpp"
|
||||||
|
#include "data/dv.hpp"
|
||||||
|
#include "delegates.hpp"
|
||||||
|
#include "engine/Engine.hpp"
|
||||||
|
#include "graphics/ui/GUI.hpp"
|
||||||
|
#include "graphics/ui/elements/Menu.hpp"
|
||||||
|
#include "graphics/ui/gui_util.hpp"
|
||||||
|
#include "interfaces/Task.hpp"
|
||||||
|
#include "io/engine_paths.hpp"
|
||||||
|
#include "locale.hpp"
|
||||||
|
#include "logic/scripting/scripting.hpp"
|
||||||
|
#include "screens/MenuScreen.hpp"
|
||||||
|
#include "settings.hpp"
|
||||||
|
#include "util/stringutil.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
void menus::create_version_label(Engine& engine) {
|
void menus::create_version_label(gui::GUI& gui) {
|
||||||
auto gui = engine.getGUI();
|
auto text = ENGINE_VERSION_STRING + " debug build";
|
||||||
auto text = ENGINE_VERSION_STRING+" debug build";
|
gui.add(guiutil::create(
|
||||||
gui->add(guiutil::create(
|
gui,
|
||||||
"<label z-index='1000' color='#FFFFFF80' gravity='top-right' margin='4'>"
|
"<label z-index='1000' color='#FFFFFF80' gravity='top-right' "
|
||||||
+text+
|
"margin='4'>" +
|
||||||
"</label>"
|
text + "</label>"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,14 +44,16 @@ bool menus::call(Engine& engine, runnable func) {
|
|||||||
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
||||||
// could not to find or read pack
|
// could not to find or read pack
|
||||||
guiutil::alert(
|
guiutil::alert(
|
||||||
engine, langs::get(L"error.pack-not-found")+L": "+
|
engine,
|
||||||
util::str2wstr_utf8(error.getPackId())
|
langs::get(L"error.pack-not-found") + L": " +
|
||||||
|
util::str2wstr_utf8(error.getPackId())
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
} catch (const assetload::error& error) {
|
} catch (const assetload::error& error) {
|
||||||
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
||||||
guiutil::alert(
|
guiutil::alert(
|
||||||
engine, langs::get(L"Assets Load Error", L"menu")+L":\n"+
|
engine,
|
||||||
|
langs::get(L"Assets Load Error", L"menu") + L":\n" +
|
||||||
util::str2wstr_utf8(error.what())
|
util::str2wstr_utf8(error.what())
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
@ -62,20 +64,27 @@ bool menus::call(Engine& engine, runnable func) {
|
|||||||
} catch (const std::runtime_error& error) {
|
} catch (const std::runtime_error& error) {
|
||||||
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
||||||
guiutil::alert(
|
guiutil::alert(
|
||||||
engine, langs::get(L"Content Error", L"menu")+L":\n"+
|
engine,
|
||||||
|
langs::get(L"Content Error", L"menu") + L":\n" +
|
||||||
util::str2wstr_utf8(error.what())
|
util::str2wstr_utf8(error.what())
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UiDocument* menus::show(Engine& engine, const std::string& name, std::vector<dv::value> args) {
|
UiDocument* menus::show(
|
||||||
auto menu = engine.getGUI()->getMenu();
|
Engine& engine, const std::string& name, std::vector<dv::value> args
|
||||||
auto file = engine.getResPaths()->find("layouts/"+name+".xml");
|
) {
|
||||||
auto fullname = "core:layouts/"+name;
|
auto menu = engine.getGUI().getMenu();
|
||||||
|
auto file = engine.getResPaths()->find("layouts/" + name + ".xml");
|
||||||
|
auto fullname = "core:layouts/" + name;
|
||||||
|
|
||||||
auto documentPtr = UiDocument::read(
|
auto documentPtr = UiDocument::read(
|
||||||
scripting::get_root_environment(), fullname, file, "core:layouts/"+name
|
engine.getGUI(),
|
||||||
|
scripting::get_root_environment(),
|
||||||
|
fullname,
|
||||||
|
file,
|
||||||
|
"core:layouts/" + name
|
||||||
);
|
);
|
||||||
auto document = documentPtr.get();
|
auto document = documentPtr.get();
|
||||||
engine.getAssets()->store(std::move(documentPtr), fullname);
|
engine.getAssets()->store(std::move(documentPtr), fullname);
|
||||||
@ -85,18 +94,20 @@ UiDocument* menus::show(Engine& engine, const std::string& name, std::vector<dv:
|
|||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
void menus::show_process_panel(Engine& engine, const std::shared_ptr<Task>& task, const std::wstring& text) {
|
void menus::show_process_panel(
|
||||||
|
Engine& engine, const std::shared_ptr<Task>& task, const std::wstring& text
|
||||||
|
) {
|
||||||
uint initialWork = task->getWorkTotal();
|
uint initialWork = task->getWorkTotal();
|
||||||
|
|
||||||
auto menu = engine.getGUI()->getMenu();
|
auto menu = engine.getGUI().getMenu();
|
||||||
menu->reset();
|
menu->reset();
|
||||||
auto doc = menus::show(engine, "process", {
|
auto doc =
|
||||||
util::wstr2str_utf8(langs::get(text))
|
menus::show(engine, "process", {util::wstr2str_utf8(langs::get(text))});
|
||||||
});
|
std::dynamic_pointer_cast<Container>(doc->getRoot())
|
||||||
std::dynamic_pointer_cast<Container>(doc->getRoot())->listenInterval(0.01f, [=]() {
|
->listenInterval(0.01f, [=]() {
|
||||||
task->update();
|
task->update();
|
||||||
|
|
||||||
uint tasksDone = task->getWorkDone();
|
uint tasksDone = task->getWorkDone();
|
||||||
scripting::on_ui_progress(doc, tasksDone, initialWork);
|
scripting::on_ui_progress(doc, tasksDone, initialWork);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ class UiDocument;
|
|||||||
|
|
||||||
namespace menus {
|
namespace menus {
|
||||||
/// @brief Create development version label at the top-right screen corner
|
/// @brief Create development version label at the top-right screen corner
|
||||||
void create_version_label(Engine& engine);
|
void create_version_label(gui::GUI& gui);
|
||||||
|
|
||||||
UiDocument* show(
|
UiDocument* show(
|
||||||
Engine& engine,
|
Engine& engine,
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#include "core_defs.hpp"
|
#include "core_defs.hpp"
|
||||||
#include "debug/Logger.hpp"
|
#include "debug/Logger.hpp"
|
||||||
#include "engine/Engine.hpp"
|
#include "engine/Engine.hpp"
|
||||||
#include "io/io.hpp"
|
#include "frontend/ContentGfxCache.hpp"
|
||||||
#include "frontend/LevelFrontend.hpp"
|
#include "frontend/LevelFrontend.hpp"
|
||||||
#include "frontend/hud.hpp"
|
#include "frontend/hud.hpp"
|
||||||
#include "graphics/core/DrawContext.hpp"
|
#include "graphics/core/DrawContext.hpp"
|
||||||
@ -17,8 +17,7 @@
|
|||||||
#include "graphics/render/WorldRenderer.hpp"
|
#include "graphics/render/WorldRenderer.hpp"
|
||||||
#include "graphics/ui/GUI.hpp"
|
#include "graphics/ui/GUI.hpp"
|
||||||
#include "graphics/ui/elements/Menu.hpp"
|
#include "graphics/ui/elements/Menu.hpp"
|
||||||
#include "graphics/ui/GUI.hpp"
|
#include "io/io.hpp"
|
||||||
#include "frontend/ContentGfxCache.hpp"
|
|
||||||
#include "logic/LevelController.hpp"
|
#include "logic/LevelController.hpp"
|
||||||
#include "logic/PlayerController.hpp"
|
#include "logic/PlayerController.hpp"
|
||||||
#include "logic/scripting/scripting.hpp"
|
#include "logic/scripting/scripting.hpp"
|
||||||
@ -43,12 +42,14 @@ LevelScreen::LevelScreen(
|
|||||||
)
|
)
|
||||||
: Screen(engine),
|
: Screen(engine),
|
||||||
world(*levelPtr->getWorld()),
|
world(*levelPtr->getWorld()),
|
||||||
postProcessing(std::make_unique<PostProcessing>()) {
|
postProcessing(std::make_unique<PostProcessing>()),
|
||||||
|
gui(engine.getGUI()),
|
||||||
|
input(engine.getInput()) {
|
||||||
Level* level = levelPtr.get();
|
Level* level = levelPtr.get();
|
||||||
|
|
||||||
auto& settings = engine.getSettings();
|
auto& settings = engine.getSettings();
|
||||||
auto& assets = *engine.getAssets();
|
auto& assets = *engine.getAssets();
|
||||||
auto menu = engine.getGUI()->getMenu();
|
auto menu = engine.getGUI().getMenu();
|
||||||
menu->reset();
|
menu->reset();
|
||||||
|
|
||||||
auto player = level->players->get(localPlayer);
|
auto player = level->players->get(localPlayer);
|
||||||
@ -57,10 +58,7 @@ LevelScreen::LevelScreen(
|
|||||||
controller =
|
controller =
|
||||||
std::make_unique<LevelController>(&engine, std::move(levelPtr), player);
|
std::make_unique<LevelController>(&engine, std::move(levelPtr), player);
|
||||||
playerController = std::make_unique<PlayerController>(
|
playerController = std::make_unique<PlayerController>(
|
||||||
settings,
|
settings, *level, *player, *controller->getBlocksController()
|
||||||
*level,
|
|
||||||
*player,
|
|
||||||
*controller->getBlocksController()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
frontend = std::make_unique<LevelFrontend>(
|
frontend = std::make_unique<LevelFrontend>(
|
||||||
@ -87,7 +85,7 @@ LevelScreen::LevelScreen(
|
|||||||
keepAlive(settings.camera.fov.observe([=](double value) {
|
keepAlive(settings.camera.fov.observe([=](double value) {
|
||||||
player->fpCamera->setFov(glm::radians(value));
|
player->fpCamera->setFov(glm::radians(value));
|
||||||
}));
|
}));
|
||||||
keepAlive(Events::getBinding(BIND_CHUNKS_RELOAD).onactived.add([=](){
|
keepAlive(input.addCallback(BIND_CHUNKS_RELOAD, [=]() {
|
||||||
player->chunks->saveAndClear();
|
player->chunks->saveAndClear();
|
||||||
renderer->clear();
|
renderer->clear();
|
||||||
return false;
|
return false;
|
||||||
@ -178,13 +176,14 @@ void LevelScreen::saveWorldPreview() {
|
|||||||
|
|
||||||
void LevelScreen::updateHotkeys() {
|
void LevelScreen::updateHotkeys() {
|
||||||
auto& settings = engine.getSettings();
|
auto& settings = engine.getSettings();
|
||||||
if (Events::jpressed(keycode::O)) {
|
|
||||||
|
if (input.jpressed(keycode::O)) {
|
||||||
settings.graphics.frustumCulling.toggle();
|
settings.graphics.frustumCulling.toggle();
|
||||||
}
|
}
|
||||||
if (Events::jpressed(keycode::F1)) {
|
if (input.jpressed(keycode::F1)) {
|
||||||
hudVisible = !hudVisible;
|
hudVisible = !hudVisible;
|
||||||
}
|
}
|
||||||
if (Events::jpressed(keycode::F3)) {
|
if (input.jpressed(keycode::F3)) {
|
||||||
debug = !debug;
|
debug = !debug;
|
||||||
hud->setDebug(debug);
|
hud->setDebug(debug);
|
||||||
renderer->setDebug(debug);
|
renderer->setDebug(debug);
|
||||||
@ -199,19 +198,16 @@ void LevelScreen::updateAudio() {
|
|||||||
audio::get_channel("regular")->setPaused(paused);
|
audio::get_channel("regular")->setPaused(paused);
|
||||||
audio::get_channel("ambient")->setPaused(paused);
|
audio::get_channel("ambient")->setPaused(paused);
|
||||||
glm::vec3 velocity {};
|
glm::vec3 velocity {};
|
||||||
if (auto hitbox = player->getHitbox()) {
|
if (auto hitbox = player->getHitbox()) {
|
||||||
velocity = hitbox->velocity;
|
velocity = hitbox->velocity;
|
||||||
}
|
}
|
||||||
audio::set_listener(
|
audio::set_listener(
|
||||||
camera->position,
|
camera->position, velocity, camera->dir, glm::vec3(0, 1, 0)
|
||||||
velocity,
|
|
||||||
camera->dir,
|
|
||||||
glm::vec3(0, 1, 0)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelScreen::update(float delta) {
|
void LevelScreen::update(float delta) {
|
||||||
auto& gui = *engine.getGUI();
|
auto& gui = engine.getGUI();
|
||||||
|
|
||||||
if (!gui.isFocusCaught()) {
|
if (!gui.isFocusCaught()) {
|
||||||
updateHotkeys();
|
updateHotkeys();
|
||||||
@ -225,10 +221,10 @@ void LevelScreen::update(float delta) {
|
|||||||
if (!paused) {
|
if (!paused) {
|
||||||
world.updateTimers(delta);
|
world.updateTimers(delta);
|
||||||
animator->update(delta);
|
animator->update(delta);
|
||||||
playerController->update(delta, !inputLocked);
|
playerController->update(delta, inputLocked ? nullptr : &engine.getInput());
|
||||||
}
|
}
|
||||||
controller->update(glm::min(delta, 0.2f), paused);
|
controller->update(glm::min(delta, 0.2f), paused);
|
||||||
playerController->postUpdate(delta, !inputLocked, paused);
|
playerController->postUpdate(delta, inputLocked ? nullptr : &engine.getInput(), paused);
|
||||||
|
|
||||||
hud->update(hudVisible);
|
hud->update(hudVisible);
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,11 @@ class ContentPackRuntime;
|
|||||||
class Decorator;
|
class Decorator;
|
||||||
class Level;
|
class Level;
|
||||||
class World;
|
class World;
|
||||||
|
class Input;
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
class GUI;
|
||||||
|
}
|
||||||
|
|
||||||
class LevelScreen : public Screen {
|
class LevelScreen : public Screen {
|
||||||
World& world;
|
World& world;
|
||||||
@ -27,6 +32,8 @@ class LevelScreen : public Screen {
|
|||||||
std::unique_ptr<PostProcessing> postProcessing;
|
std::unique_ptr<PostProcessing> postProcessing;
|
||||||
std::unique_ptr<Decorator> decorator;
|
std::unique_ptr<Decorator> decorator;
|
||||||
std::unique_ptr<Hud> hud;
|
std::unique_ptr<Hud> hud;
|
||||||
|
gui::GUI& gui;
|
||||||
|
Input& input;
|
||||||
|
|
||||||
void saveWorldPreview();
|
void saveWorldPreview();
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
MenuScreen::MenuScreen(Engine& engine) : Screen(engine) {
|
MenuScreen::MenuScreen(Engine& engine) : Screen(engine) {
|
||||||
engine.resetContent();
|
engine.resetContent();
|
||||||
|
|
||||||
auto menu = engine.getGUI()->getMenu();
|
auto menu = engine.getGUI().getMenu();
|
||||||
menu->reset();
|
menu->reset();
|
||||||
menu->setPage("main");
|
menu->setPage("main");
|
||||||
|
|
||||||
@ -22,8 +22,7 @@ MenuScreen::MenuScreen(Engine& engine) : Screen(engine) {
|
|||||||
uicamera->flipped = true;
|
uicamera->flipped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuScreen::~MenuScreen() {
|
MenuScreen::~MenuScreen() = default;
|
||||||
}
|
|
||||||
|
|
||||||
void MenuScreen::update(float delta) {
|
void MenuScreen::update(float delta) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
|
|
||||||
#include "gui_util.hpp"
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "elements/UINode.hpp"
|
#include "assets/Assets.hpp"
|
||||||
#include "elements/Label.hpp"
|
#include "elements/Label.hpp"
|
||||||
#include "elements/Menu.hpp"
|
#include "elements/Menu.hpp"
|
||||||
#include "elements/Panel.hpp"
|
#include "elements/Panel.hpp"
|
||||||
|
#include "elements/UINode.hpp"
|
||||||
#include "assets/Assets.hpp"
|
#include "engine/Engine.hpp"
|
||||||
#include "frontend/UiDocument.hpp"
|
#include "frontend/UiDocument.hpp"
|
||||||
#include "frontend/locale.hpp"
|
#include "frontend/locale.hpp"
|
||||||
#include "graphics/core/Batch2D.hpp"
|
#include "graphics/core/Batch2D.hpp"
|
||||||
@ -15,31 +17,36 @@
|
|||||||
#include "graphics/core/Shader.hpp"
|
#include "graphics/core/Shader.hpp"
|
||||||
#include "graphics/core/Font.hpp"
|
#include "graphics/core/Font.hpp"
|
||||||
#include "graphics/core/DrawContext.hpp"
|
#include "graphics/core/DrawContext.hpp"
|
||||||
|
#include "graphics/core/Shader.hpp"
|
||||||
|
#include "gui_util.hpp"
|
||||||
|
#include "window/Camera.hpp"
|
||||||
#include "window/Events.hpp"
|
#include "window/Events.hpp"
|
||||||
#include "window/Window.hpp"
|
#include "window/Window.hpp"
|
||||||
#include "window/input.hpp"
|
#include "window/input.hpp"
|
||||||
#include "window/Camera.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
GUI::GUI()
|
GUI::GUI(Engine& engine)
|
||||||
: batch2D(std::make_unique<Batch2D>(1024)),
|
: engine(engine),
|
||||||
container(std::make_shared<Container>(glm::vec2(1000))) {
|
input(engine.getInput()),
|
||||||
|
batch2D(std::make_unique<Batch2D>(1024)),
|
||||||
|
container(std::make_shared<Container>(*this, glm::vec2(1000))) {
|
||||||
container->setId("root");
|
container->setId("root");
|
||||||
uicamera = std::make_unique<Camera>(glm::vec3(), Window::height);
|
uicamera = std::make_unique<Camera>(glm::vec3(), Window::height);
|
||||||
uicamera->perspective = false;
|
uicamera->perspective = false;
|
||||||
uicamera->flipped = true;
|
uicamera->flipped = true;
|
||||||
|
|
||||||
menu = std::make_shared<Menu>();
|
menu = std::make_shared<Menu>(*this);
|
||||||
menu->setId("menu");
|
menu->setId("menu");
|
||||||
menu->setZIndex(10);
|
menu->setZIndex(10);
|
||||||
container->add(menu);
|
container->add(menu);
|
||||||
container->setScrollable(false);
|
container->setScrollable(false);
|
||||||
|
|
||||||
tooltip = guiutil::create(
|
tooltip = guiutil::create(
|
||||||
|
*this,
|
||||||
"<container color='#000000A0' interactive='false' z-index='999'>"
|
"<container color='#000000A0' interactive='false' z-index='999'>"
|
||||||
"<label id='tooltip.label' pos='2' autoresize='true' multiline='true' text-wrap='false'></label>"
|
"<label id='tooltip.label' pos='2' autoresize='true' multiline='true' text-wrap='false'></label>"
|
||||||
"</container>"
|
"</container>"
|
||||||
@ -65,12 +72,15 @@ std::shared_ptr<Menu> GUI::getMenu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GUI::onAssetsLoad(Assets* assets) {
|
void GUI::onAssetsLoad(Assets* assets) {
|
||||||
assets->store(std::make_unique<UiDocument>(
|
assets->store(
|
||||||
"core:root",
|
std::make_unique<UiDocument>(
|
||||||
uidocscript {},
|
"core:root",
|
||||||
std::dynamic_pointer_cast<gui::UINode>(container),
|
uidocscript {},
|
||||||
nullptr
|
std::dynamic_pointer_cast<gui::UINode>(container),
|
||||||
), "core:root");
|
nullptr
|
||||||
|
),
|
||||||
|
"core:root"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::resetTooltip() {
|
void GUI::resetTooltip() {
|
||||||
@ -79,11 +89,13 @@ void GUI::resetTooltip() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GUI::updateTooltip(float delta) {
|
void GUI::updateTooltip(float delta) {
|
||||||
if (hover == nullptr || !hover->isInside(Events::cursor)) {
|
const auto& cursor = input.getCursor();
|
||||||
|
if (hover == nullptr || !hover->isInside(cursor.pos)) {
|
||||||
return resetTooltip();
|
return resetTooltip();
|
||||||
}
|
}
|
||||||
if (tooltipTimer + delta >= hover->getTooltipDelay()) {
|
if (tooltipTimer + delta >= hover->getTooltipDelay()) {
|
||||||
auto label = std::dynamic_pointer_cast<gui::Label>(get("tooltip.label"));
|
auto label =
|
||||||
|
std::dynamic_pointer_cast<gui::Label>(get("tooltip.label"));
|
||||||
const auto& text = hover->getTooltip();
|
const auto& text = hover->getTooltip();
|
||||||
if (text.empty() && tooltip->isVisible()) {
|
if (text.empty() && tooltip->isVisible()) {
|
||||||
return resetTooltip();
|
return resetTooltip();
|
||||||
@ -91,11 +103,11 @@ void GUI::updateTooltip(float delta) {
|
|||||||
if (label && !text.empty()) {
|
if (label && !text.empty()) {
|
||||||
tooltip->setVisible(true);
|
tooltip->setVisible(true);
|
||||||
label->setText(langs::get(text));
|
label->setText(langs::get(text));
|
||||||
auto size = label->getSize()+glm::vec2(4.0f);
|
auto size = label->getSize() + glm::vec2(4.0f);
|
||||||
auto pos = Events::cursor+glm::vec2(10.0f);
|
auto pos = cursor.pos + glm::vec2(10.0f);
|
||||||
auto rootSize = container->getSize();
|
auto rootSize = container->getSize();
|
||||||
pos.x = glm::min(pos.x, rootSize.x-size.x);
|
pos.x = glm::min(pos.x, rootSize.x - size.x);
|
||||||
pos.y = glm::min(pos.y, rootSize.y-size.y);
|
pos.y = glm::min(pos.y, rootSize.y - size.y);
|
||||||
tooltip->setSize(size);
|
tooltip->setSize(size);
|
||||||
tooltip->setPos(pos);
|
tooltip->setPos(pos);
|
||||||
}
|
}
|
||||||
@ -104,8 +116,8 @@ void GUI::updateTooltip(float delta) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Mouse related input and logic handling
|
/// @brief Mouse related input and logic handling
|
||||||
void GUI::actMouse(float delta) {
|
void GUI::actMouse(float delta, const CursorState& cursor) {
|
||||||
float mouseDelta = glm::length(Events::delta);
|
float mouseDelta = glm::length(cursor.delta);
|
||||||
doubleClicked = false;
|
doubleClicked = false;
|
||||||
doubleClickTimer += delta + mouseDelta * 0.1f;
|
doubleClickTimer += delta + mouseDelta * 0.1f;
|
||||||
|
|
||||||
@ -116,21 +128,21 @@ void GUI::actMouse(float delta) {
|
|||||||
if (hover) {
|
if (hover) {
|
||||||
hover->setHover(true);
|
hover->setHover(true);
|
||||||
|
|
||||||
int scroll = Events::getScroll();
|
int scroll = input.getScroll();
|
||||||
if (scroll) {
|
if (scroll) {
|
||||||
hover->scrolled(scroll);
|
hover->scrolled(scroll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->hover = hover;
|
this->hover = hover;
|
||||||
|
|
||||||
if (Events::jclicked(mousecode::BUTTON_1)) {
|
if (input.jclicked(mousecode::BUTTON_1)) {
|
||||||
if (pressed == nullptr && this->hover) {
|
if (pressed == nullptr && this->hover) {
|
||||||
pressed = hover;
|
pressed = hover;
|
||||||
if (doubleClickTimer < doubleClickDelay) {
|
if (doubleClickTimer < doubleClickDelay) {
|
||||||
pressed->doubleClick(this, Events::cursor.x, Events::cursor.y);
|
pressed->doubleClick(cursor.pos.x, cursor.pos.y);
|
||||||
doubleClicked = true;
|
doubleClicked = true;
|
||||||
} else {
|
} else {
|
||||||
pressed->click(this, Events::cursor.x, Events::cursor.y);
|
pressed->click(cursor.pos.x, cursor.pos.y);
|
||||||
}
|
}
|
||||||
doubleClickTimer = 0.0f;
|
doubleClickTimer = 0.0f;
|
||||||
if (focus && focus != pressed) {
|
if (focus && focus != pressed) {
|
||||||
@ -138,7 +150,7 @@ void GUI::actMouse(float delta) {
|
|||||||
}
|
}
|
||||||
if (focus != pressed) {
|
if (focus != pressed) {
|
||||||
focus = pressed;
|
focus = pressed;
|
||||||
focus->onFocus(this);
|
focus->onFocus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,22 +158,22 @@ void GUI::actMouse(float delta) {
|
|||||||
focus->defocus();
|
focus->defocus();
|
||||||
focus = nullptr;
|
focus = nullptr;
|
||||||
}
|
}
|
||||||
} else if (!Events::clicked(mousecode::BUTTON_1) && pressed) {
|
} else if (!input.clicked(mousecode::BUTTON_1) && pressed) {
|
||||||
pressed->mouseRelease(this, Events::cursor.x, Events::cursor.y);
|
pressed->mouseRelease(cursor.pos.x, cursor.pos.y);
|
||||||
pressed = nullptr;
|
pressed = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hover) {
|
if (hover) {
|
||||||
for (mousecode code : MOUSECODES_ALL) {
|
for (mousecode code : MOUSECODES_ALL) {
|
||||||
if (Events::jclicked(code)) {
|
if (input.jclicked(code)) {
|
||||||
hover->clicked(this, code);
|
hover->clicked(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::actFocused() {
|
void GUI::actFocused() {
|
||||||
if (Events::jpressed(keycode::ESCAPE)) {
|
if (input.jpressed(keycode::ESCAPE)) {
|
||||||
focus->defocus();
|
focus->defocus();
|
||||||
focus = nullptr;
|
focus = nullptr;
|
||||||
return;
|
return;
|
||||||
@ -173,12 +185,13 @@ void GUI::actFocused() {
|
|||||||
focus->keyPressed(key);
|
focus->keyPressed(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Events::isCursorLocked()) {
|
const auto& cursor = input.getCursor();
|
||||||
if (Events::clicked(mousecode::BUTTON_1) &&
|
if (!cursor.locked) {
|
||||||
(Events::jclicked(mousecode::BUTTON_1) || Events::delta.x || Events::delta.y))
|
if (input.clicked(mousecode::BUTTON_1) &&
|
||||||
{
|
(input.jclicked(mousecode::BUTTON_1) || cursor.delta.x ||
|
||||||
|
cursor.delta.y)) {
|
||||||
if (!doubleClicked) {
|
if (!doubleClicked) {
|
||||||
focus->mouseMove(this, Events::cursor.x, Events::cursor.y);
|
focus->mouseMove(cursor.pos.x, cursor.pos.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,15 +203,16 @@ void GUI::act(float delta, const Viewport& vp) {
|
|||||||
auto prevfocus = focus;
|
auto prevfocus = focus;
|
||||||
|
|
||||||
updateTooltip(delta);
|
updateTooltip(delta);
|
||||||
|
|
||||||
|
const auto& cursor = input.getCursor();
|
||||||
if (!Events::isCursorLocked()) {
|
if (!Events::isCursorLocked()) {
|
||||||
actMouse(delta);
|
actMouse(delta, cursor);
|
||||||
} else {
|
} else {
|
||||||
if (hover) {
|
if (hover) {
|
||||||
hover->setHover(false);
|
hover->setHover(false);
|
||||||
hover = nullptr;
|
hover = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (focus) {
|
if (focus) {
|
||||||
actFocused();
|
actFocused();
|
||||||
}
|
}
|
||||||
@ -316,7 +330,7 @@ void GUI::setFocus(std::shared_ptr<UINode> node) {
|
|||||||
}
|
}
|
||||||
focus = std::move(node);
|
focus = std::move(node);
|
||||||
if (focus) {
|
if (focus) {
|
||||||
focus->onFocus(this);
|
focus->onFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,3 +353,7 @@ float GUI::getDoubleClickDelay() const {
|
|||||||
void GUI::toggleDebug() {
|
void GUI::toggleDebug() {
|
||||||
debug = !debug;
|
debug = !debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Input& GUI::getInput() const {
|
||||||
|
return engine.getInput();
|
||||||
|
}
|
||||||
|
|||||||
@ -14,7 +14,9 @@ class DrawContext;
|
|||||||
class Assets;
|
class Assets;
|
||||||
class Camera;
|
class Camera;
|
||||||
class Batch2D;
|
class Batch2D;
|
||||||
class LineBatch;
|
struct CursorState;
|
||||||
|
class Engine;
|
||||||
|
class Input;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some info about padding and margin.
|
Some info about padding and margin.
|
||||||
@ -56,6 +58,8 @@ namespace gui {
|
|||||||
|
|
||||||
/// @brief The main UI controller
|
/// @brief The main UI controller
|
||||||
class GUI {
|
class GUI {
|
||||||
|
Engine& engine;
|
||||||
|
Input& input;
|
||||||
std::unique_ptr<Batch2D> batch2D;
|
std::unique_ptr<Batch2D> batch2D;
|
||||||
std::shared_ptr<Container> container;
|
std::shared_ptr<Container> container;
|
||||||
std::shared_ptr<UINode> hover;
|
std::shared_ptr<UINode> hover;
|
||||||
@ -76,12 +80,12 @@ namespace gui {
|
|||||||
bool doubleClicked = false;
|
bool doubleClicked = false;
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
|
|
||||||
void actMouse(float delta);
|
void actMouse(float delta, const CursorState& cursor);
|
||||||
void actFocused();
|
void actFocused();
|
||||||
void updateTooltip(float delta);
|
void updateTooltip(float delta);
|
||||||
void resetTooltip();
|
void resetTooltip();
|
||||||
public:
|
public:
|
||||||
GUI();
|
GUI(Engine& engine);
|
||||||
~GUI();
|
~GUI();
|
||||||
|
|
||||||
void setPageLoader(PageLoaderFunc pageLoader);
|
void setPageLoader(PageLoaderFunc pageLoader);
|
||||||
@ -152,5 +156,6 @@ namespace gui {
|
|||||||
float getDoubleClickDelay() const;
|
float getDoubleClickDelay() const;
|
||||||
|
|
||||||
void toggleDebug();
|
void toggleDebug();
|
||||||
|
const Input& getInput() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,12 +26,13 @@ namespace gui {
|
|||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
BasePanel(
|
BasePanel(
|
||||||
|
GUI& gui,
|
||||||
glm::vec2 size,
|
glm::vec2 size,
|
||||||
glm::vec4 padding = glm::vec4(0.0f),
|
glm::vec4 padding = glm::vec4(0.0f),
|
||||||
float interval = 2.0f,
|
float interval = 2.0f,
|
||||||
Orientation orientation = Orientation::vertical
|
Orientation orientation = Orientation::vertical
|
||||||
)
|
)
|
||||||
: Container(std::move(size)),
|
: Container(gui, std::move(size)),
|
||||||
padding(std::move(padding)),
|
padding(std::move(padding)),
|
||||||
interval(interval) {
|
interval(interval) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,17 +3,23 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "Label.hpp"
|
#include "Label.hpp"
|
||||||
#include "graphics/core/DrawContext.hpp"
|
|
||||||
#include "graphics/core/Batch2D.hpp"
|
#include "graphics/core/Batch2D.hpp"
|
||||||
|
#include "graphics/core/DrawContext.hpp"
|
||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
Button::Button(const std::shared_ptr<UINode>& content, glm::vec4 padding)
|
Button::Button(
|
||||||
: Panel(glm::vec2(), padding, 0) {
|
GUI& gui, const std::shared_ptr<UINode>& content, glm::vec4 padding
|
||||||
|
)
|
||||||
|
: Panel(gui, glm::vec2(), padding, 0) {
|
||||||
glm::vec4 margin = getMargin();
|
glm::vec4 margin = getMargin();
|
||||||
setSize(content->getSize()+
|
setSize(
|
||||||
glm::vec2(padding[0]+padding[2]+margin[0]+margin[2],
|
content->getSize() +
|
||||||
padding[1]+padding[3]+margin[1]+margin[3]));
|
glm::vec2(
|
||||||
|
padding[0] + padding[2] + margin[0] + margin[2],
|
||||||
|
padding[1] + padding[3] + margin[1] + margin[3]
|
||||||
|
)
|
||||||
|
);
|
||||||
add(content);
|
add(content);
|
||||||
setScrollable(false);
|
setScrollable(false);
|
||||||
setHoverColor(glm::vec4(0.05f, 0.1f, 0.15f, 0.75f));
|
setHoverColor(glm::vec4(0.05f, 0.1f, 0.15f, 0.75f));
|
||||||
@ -22,15 +28,16 @@ Button::Button(const std::shared_ptr<UINode>& content, glm::vec4 padding)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Button::Button(
|
Button::Button(
|
||||||
|
GUI& gui,
|
||||||
const std::wstring& text,
|
const std::wstring& text,
|
||||||
glm::vec4 padding,
|
glm::vec4 padding,
|
||||||
const onaction& action,
|
const onaction& action,
|
||||||
glm::vec2 size
|
glm::vec2 size
|
||||||
) : Panel(size, padding, 0)
|
)
|
||||||
{
|
: Panel(gui, size, padding, 0) {
|
||||||
if (size.y < 0.0f) {
|
if (size.y < 0.0f) {
|
||||||
size = glm::vec2(
|
size = glm::vec2(
|
||||||
glm::max(padding.x + padding.z + text.length()*8, size.x),
|
glm::max(padding.x + padding.z + text.length() * 8, size.x),
|
||||||
glm::max(padding.y + padding.w + 16, size.y)
|
glm::max(padding.y + padding.w + 16, size.y)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -41,9 +48,11 @@ Button::Button(
|
|||||||
}
|
}
|
||||||
setScrollable(false);
|
setScrollable(false);
|
||||||
|
|
||||||
label = std::make_shared<Label>(text);
|
label = std::make_shared<Label>(gui, text);
|
||||||
label->setAlign(Align::center);
|
label->setAlign(Align::center);
|
||||||
label->setSize(size-glm::vec2(padding.z+padding.x, padding.w+padding.y));
|
label->setSize(
|
||||||
|
size - glm::vec2(padding.z + padding.x, padding.w + padding.y)
|
||||||
|
);
|
||||||
label->setInteractive(false);
|
label->setInteractive(false);
|
||||||
add(label);
|
add(label);
|
||||||
setHoverColor(glm::vec4(0.05f, 0.1f, 0.15f, 0.75f));
|
setHoverColor(glm::vec4(0.05f, 0.1f, 0.15f, 0.75f));
|
||||||
@ -73,7 +82,9 @@ Button* Button::textSupplier(wstringsupplier supplier) {
|
|||||||
void Button::refresh() {
|
void Button::refresh() {
|
||||||
Panel::refresh();
|
Panel::refresh();
|
||||||
if (label) {
|
if (label) {
|
||||||
label->setSize(size-glm::vec2(padding.z+padding.x, padding.w+padding.y));
|
label->setSize(
|
||||||
|
size - glm::vec2(padding.z + padding.x, padding.w + padding.y)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,13 +9,19 @@ namespace gui {
|
|||||||
protected:
|
protected:
|
||||||
std::shared_ptr<Label> label;
|
std::shared_ptr<Label> label;
|
||||||
public:
|
public:
|
||||||
Button(const std::shared_ptr<UINode>& content,
|
Button(
|
||||||
glm::vec4 padding=glm::vec4(2.0f));
|
GUI& gui,
|
||||||
|
const std::shared_ptr<UINode>& content,
|
||||||
|
glm::vec4 padding = glm::vec4(2.0f)
|
||||||
|
);
|
||||||
|
|
||||||
Button(const std::wstring& text,
|
Button(
|
||||||
glm::vec4 padding,
|
GUI& gui,
|
||||||
const onaction& action,
|
const std::wstring& text,
|
||||||
glm::vec2 size=glm::vec2(-1));
|
glm::vec4 padding,
|
||||||
|
const onaction& action,
|
||||||
|
glm::vec2 size = glm::vec2(-1)
|
||||||
|
);
|
||||||
|
|
||||||
virtual void drawBackground(
|
virtual void drawBackground(
|
||||||
const DrawContext& pctx, const Assets& assets
|
const DrawContext& pctx, const Assets& assets
|
||||||
|
|||||||
@ -4,7 +4,8 @@
|
|||||||
#include "graphics/core/DrawContext.hpp"
|
#include "graphics/core/DrawContext.hpp"
|
||||||
#include "graphics/core/Texture.hpp"
|
#include "graphics/core/Texture.hpp"
|
||||||
|
|
||||||
gui::Canvas::Canvas(ImageFormat inFormat, glm::uvec2 inSize) : UINode(inSize) {
|
gui::Canvas::Canvas(GUI& gui, ImageFormat inFormat, glm::uvec2 inSize)
|
||||||
|
: UINode(gui, inSize) {
|
||||||
auto data = std::make_shared<ImageData>(inFormat, inSize.x, inSize.y);
|
auto data = std::make_shared<ImageData>(inFormat, inSize.x, inSize.y);
|
||||||
mTexture = Texture::from(data.get());
|
mTexture = Texture::from(data.get());
|
||||||
mData = std::move(data);
|
mData = std::move(data);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ class Texture;
|
|||||||
namespace gui {
|
namespace gui {
|
||||||
class Canvas final : public UINode {
|
class Canvas final : public UINode {
|
||||||
public:
|
public:
|
||||||
explicit Canvas(ImageFormat inFormat, glm::uvec2 inSize);
|
explicit Canvas(GUI& gui, ImageFormat inFormat, glm::uvec2 inSize);
|
||||||
|
|
||||||
~Canvas() override = default;
|
~Canvas() override = default;
|
||||||
|
|
||||||
|
|||||||
@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "graphics/core/DrawContext.hpp"
|
|
||||||
#include "graphics/core/Batch2D.hpp"
|
|
||||||
#include "Label.hpp"
|
#include "Label.hpp"
|
||||||
|
#include "graphics/core/Batch2D.hpp"
|
||||||
|
#include "graphics/core/DrawContext.hpp"
|
||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
CheckBox::CheckBox(bool checked) : UINode(glm::vec2(32.0f)), checked(checked) {
|
CheckBox::CheckBox(GUI& gui, bool checked)
|
||||||
|
: UINode(gui, glm::vec2(32.0f)), checked(checked) {
|
||||||
setColor({0.0f, 0.0f, 0.0f, 0.5f});
|
setColor({0.0f, 0.0f, 0.0f, 0.5f});
|
||||||
setHoverColor({0.05f, 0.1f, 0.2f, 0.75f});
|
setHoverColor({0.05f, 0.1f, 0.2f, 0.75f});
|
||||||
}
|
}
|
||||||
@ -24,7 +25,7 @@ void CheckBox::draw(const DrawContext& pctx, const Assets&) {
|
|||||||
batch->rect(pos.x, pos.y, size.x, size.y);
|
batch->rect(pos.x, pos.y, size.x, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckBox::mouseRelease(GUI*, int, int) {
|
void CheckBox::mouseRelease(int, int) {
|
||||||
checked = !checked;
|
checked = !checked;
|
||||||
if (consumer) {
|
if (consumer) {
|
||||||
consumer(checked);
|
consumer(checked);
|
||||||
@ -44,10 +45,12 @@ CheckBox* CheckBox::setChecked(bool flag) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
FullCheckBox::FullCheckBox(const std::wstring& text, glm::vec2 size, bool checked)
|
FullCheckBox::FullCheckBox(
|
||||||
: Panel(size),
|
GUI& gui, const std::wstring& text, glm::vec2 size, bool checked
|
||||||
checkbox(std::make_shared<CheckBox>(checked)),
|
)
|
||||||
label(std::make_shared<Label>(text)) {
|
: Panel(gui, size),
|
||||||
|
checkbox(std::make_shared<CheckBox>(gui, checked)),
|
||||||
|
label(std::make_shared<Label>(gui, text)) {
|
||||||
setColor(glm::vec4(0.0f));
|
setColor(glm::vec4(0.0f));
|
||||||
setOrientation(Orientation::horizontal);
|
setOrientation(Orientation::horizontal);
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "Panel.hpp"
|
|
||||||
#include "Label.hpp"
|
#include "Label.hpp"
|
||||||
|
#include "Panel.hpp"
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
class CheckBox : public UINode {
|
class CheckBox : public UINode {
|
||||||
@ -13,11 +13,12 @@ namespace gui {
|
|||||||
boolconsumer consumer = nullptr;
|
boolconsumer consumer = nullptr;
|
||||||
bool checked = false;
|
bool checked = false;
|
||||||
public:
|
public:
|
||||||
CheckBox(bool checked=false);
|
explicit CheckBox(GUI& gui, bool checked = false);
|
||||||
|
|
||||||
virtual void draw(const DrawContext& pctx, const Assets& assets) override;
|
virtual void draw(const DrawContext& pctx, const Assets& assets)
|
||||||
|
override;
|
||||||
|
|
||||||
virtual void mouseRelease(GUI*, int x, int y) override;
|
virtual void mouseRelease(int x, int y) override;
|
||||||
|
|
||||||
virtual void setSupplier(boolsupplier supplier);
|
virtual void setSupplier(boolsupplier supplier);
|
||||||
virtual void setConsumer(boolconsumer consumer);
|
virtual void setConsumer(boolconsumer consumer);
|
||||||
@ -25,8 +26,7 @@ namespace gui {
|
|||||||
virtual CheckBox* setChecked(bool flag);
|
virtual CheckBox* setChecked(bool flag);
|
||||||
|
|
||||||
virtual bool isChecked() const {
|
virtual bool isChecked() const {
|
||||||
if (supplier)
|
if (supplier) return supplier();
|
||||||
return supplier();
|
|
||||||
return checked;
|
return checked;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -36,7 +36,12 @@ namespace gui {
|
|||||||
std::shared_ptr<CheckBox> checkbox;
|
std::shared_ptr<CheckBox> checkbox;
|
||||||
std::shared_ptr<Label> label;
|
std::shared_ptr<Label> label;
|
||||||
public:
|
public:
|
||||||
FullCheckBox(const std::wstring& text, glm::vec2 size, bool checked=false);
|
explicit FullCheckBox(
|
||||||
|
GUI& gui,
|
||||||
|
const std::wstring& text,
|
||||||
|
glm::vec2 size,
|
||||||
|
bool checked = false
|
||||||
|
);
|
||||||
|
|
||||||
virtual void setSupplier(boolsupplier supplier) {
|
virtual void setSupplier(boolsupplier supplier) {
|
||||||
checkbox->setSupplier(std::move(supplier));
|
checkbox->setSupplier(std::move(supplier));
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
Container::Container(glm::vec2 size) : UINode(size) {
|
Container::Container(GUI& gui, glm::vec2 size) : UINode(gui, size) {
|
||||||
actualLength = size.y;
|
actualLength = size.y;
|
||||||
setColor(glm::vec4());
|
setColor(glm::vec4());
|
||||||
}
|
}
|
||||||
@ -41,8 +41,8 @@ std::shared_ptr<UINode> Container::getAt(const glm::vec2& pos) {
|
|||||||
return UINode::getAt(pos);
|
return UINode::getAt(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::mouseMove(GUI* gui, int x, int y) {
|
void Container::mouseMove(int x, int y) {
|
||||||
UINode::mouseMove(gui, x, y);
|
UINode::mouseMove(x, y);
|
||||||
if (!scrollable) {
|
if (!scrollable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -65,8 +65,8 @@ void Container::mouseMove(GUI* gui, int x, int y) {
|
|||||||
prevScrollY = y;
|
prevScrollY = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::mouseRelease(GUI* gui, int x, int y) {
|
void Container::mouseRelease(int x, int y) {
|
||||||
UINode::mouseRelease(gui, x, y);
|
UINode::mouseRelease(x, y);
|
||||||
prevScrollY = -1;
|
prevScrollY = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
class Container : public UINode, public util::ObjectsKeeper {
|
class Container : public UINode, public ::util::ObjectsKeeper {
|
||||||
int prevScrollY = -1;
|
int prevScrollY = -1;
|
||||||
protected:
|
protected:
|
||||||
std::vector<std::shared_ptr<UINode>> nodes;
|
std::vector<std::shared_ptr<UINode>> nodes;
|
||||||
@ -22,7 +22,7 @@ namespace gui {
|
|||||||
return prevScrollY != -1;
|
return prevScrollY != -1;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
Container(glm::vec2 size);
|
Container(GUI& gui, glm::vec2 size);
|
||||||
virtual ~Container();
|
virtual ~Container();
|
||||||
|
|
||||||
virtual void act(float delta) override;
|
virtual void act(float delta) override;
|
||||||
@ -44,8 +44,8 @@ namespace gui {
|
|||||||
virtual void refresh() override;
|
virtual void refresh() override;
|
||||||
void setScroll(int scroll);
|
void setScroll(int scroll);
|
||||||
|
|
||||||
virtual void mouseMove(GUI*, int x, int y) override;
|
virtual void mouseMove(int x, int y) override;
|
||||||
virtual void mouseRelease(GUI*, int x, int y) override;
|
virtual void mouseRelease(int x, int y) override;
|
||||||
|
|
||||||
const std::vector<std::shared_ptr<UINode>>& getNodes() const;
|
const std::vector<std::shared_ptr<UINode>>& getNodes() const;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,16 +2,17 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "graphics/core/DrawContext.hpp"
|
|
||||||
#include "graphics/core/Batch2D.hpp"
|
|
||||||
#include "graphics/core/Texture.hpp"
|
|
||||||
#include "graphics/core/Atlas.hpp"
|
|
||||||
#include "assets/Assets.hpp"
|
#include "assets/Assets.hpp"
|
||||||
|
#include "graphics/core/Atlas.hpp"
|
||||||
|
#include "graphics/core/Batch2D.hpp"
|
||||||
|
#include "graphics/core/DrawContext.hpp"
|
||||||
|
#include "graphics/core/Texture.hpp"
|
||||||
#include "maths/UVRegion.hpp"
|
#include "maths/UVRegion.hpp"
|
||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
Image::Image(std::string texture, glm::vec2 size) : UINode(size), texture(std::move(texture)) {
|
Image::Image(GUI& gui, std::string texture, glm::vec2 size)
|
||||||
|
: UINode(gui, size), texture(std::move(texture)) {
|
||||||
setInteractive(false);
|
setInteractive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,14 +31,16 @@ void Image::draw(const DrawContext& pctx, const Assets& assets) {
|
|||||||
} else {
|
} else {
|
||||||
auto atlasName = this->texture.substr(0, separator);
|
auto atlasName = this->texture.substr(0, separator);
|
||||||
if (auto atlas = assets.get<Atlas>(atlasName)) {
|
if (auto atlas = assets.get<Atlas>(atlasName)) {
|
||||||
if (auto region = atlas->getIf(this->texture.substr(separator+1))) {
|
if (auto region =
|
||||||
|
atlas->getIf(this->texture.substr(separator + 1))) {
|
||||||
texture = atlas->getTexture();
|
texture = atlas->getTexture();
|
||||||
batch->texture(atlas->getTexture());
|
batch->texture(atlas->getTexture());
|
||||||
batch->setRegion(*region);
|
batch->setRegion(*region);
|
||||||
if (autoresize) {
|
if (autoresize) {
|
||||||
setSize(glm::vec2(
|
setSize(glm::vec2(
|
||||||
texture->getWidth()*region->getWidth(),
|
texture->getWidth() * region->getWidth(),
|
||||||
texture->getHeight()*region->getHeight()));
|
texture->getHeight() * region->getHeight()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
@ -45,8 +48,17 @@ void Image::draw(const DrawContext& pctx, const Assets& assets) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
batch->rect(
|
batch->rect(
|
||||||
pos.x, pos.y, size.x, size.y,
|
pos.x,
|
||||||
0, 0, 0, UVRegion(), false, true, calcColor()
|
pos.y,
|
||||||
|
size.x,
|
||||||
|
size.y,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
UVRegion(),
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
calcColor()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ namespace gui {
|
|||||||
std::string texture;
|
std::string texture;
|
||||||
bool autoresize = false;
|
bool autoresize = false;
|
||||||
public:
|
public:
|
||||||
Image(std::string texture, glm::vec2 size=glm::vec2(32,32));
|
Image(GUI& gui, std::string texture, glm::vec2 size=glm::vec2(32,32));
|
||||||
|
|
||||||
virtual void draw(const DrawContext& pctx, const Assets& assets) override;
|
virtual void draw(const DrawContext& pctx, const Assets& assets) override;
|
||||||
|
|
||||||
|
|||||||
@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
InputBindBox::InputBindBox(Binding& binding, glm::vec4 padding)
|
InputBindBox::InputBindBox(GUI& gui, Binding& binding, glm::vec4 padding)
|
||||||
: Panel(glm::vec2(100,32), padding, 0),
|
: Panel(gui, glm::vec2(100,32), padding, 0),
|
||||||
binding(binding),
|
binding(binding),
|
||||||
label(std::make_shared<Label>(L"")) {
|
label(std::make_shared<Label>(gui, L"")) {
|
||||||
add(label);
|
add(label);
|
||||||
setScrollable(false);
|
setScrollable(false);
|
||||||
hoverColor = glm::vec4(0.05f, 0.1f, 0.2f, 0.75f);
|
hoverColor = glm::vec4(0.05f, 0.1f, 0.2f, 0.75f);
|
||||||
@ -25,7 +25,7 @@ void InputBindBox::drawBackground(const DrawContext& pctx, const Assets&) {
|
|||||||
label->setText(util::str2wstr_utf8(binding.text()));
|
label->setText(util::str2wstr_utf8(binding.text()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputBindBox::clicked(GUI*, mousecode button) {
|
void InputBindBox::clicked(mousecode button) {
|
||||||
if (isFocused()) {
|
if (isFocused()) {
|
||||||
binding.reset(button);
|
binding.reset(button);
|
||||||
defocus();
|
defocus();
|
||||||
|
|||||||
@ -11,14 +11,18 @@ namespace gui {
|
|||||||
glm::vec4 focusedColor {0.1f, 0.15f, 0.35f, 0.75f};
|
glm::vec4 focusedColor {0.1f, 0.15f, 0.35f, 0.75f};
|
||||||
std::shared_ptr<Label> label;
|
std::shared_ptr<Label> label;
|
||||||
public:
|
public:
|
||||||
InputBindBox(Binding& binding, glm::vec4 padding=glm::vec4(6.0f));
|
explicit InputBindBox(
|
||||||
|
GUI& gui, Binding& binding, glm::vec4 padding = glm::vec4(6.0f)
|
||||||
|
);
|
||||||
|
|
||||||
virtual void drawBackground(
|
virtual void drawBackground(
|
||||||
const DrawContext& pctx, const Assets& assets
|
const DrawContext& pctx, const Assets& assets
|
||||||
) override;
|
) override;
|
||||||
|
|
||||||
virtual void clicked(GUI*, mousecode button) override;
|
virtual void clicked(mousecode button) override;
|
||||||
virtual void keyPressed(keycode key) override;
|
virtual void keyPressed(keycode key) override;
|
||||||
virtual bool isFocuskeeper() const override {return true;}
|
virtual bool isFocuskeeper() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,8 +46,8 @@ SlotLayout::SlotLayout(
|
|||||||
shareFunc(std::move(shareFunc)),
|
shareFunc(std::move(shareFunc)),
|
||||||
rightClick(std::move(rightClick)) {}
|
rightClick(std::move(rightClick)) {}
|
||||||
|
|
||||||
InventoryBuilder::InventoryBuilder() {
|
InventoryBuilder::InventoryBuilder(GUI& gui) : gui(gui) {
|
||||||
view = std::make_shared<InventoryView>();
|
view = std::make_shared<InventoryView>(gui);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryBuilder::addGrid(
|
void InventoryBuilder::addGrid(
|
||||||
@ -75,7 +75,8 @@ void InventoryBuilder::addGrid(
|
|||||||
view->setSize(vsize);
|
view->setSize(vsize);
|
||||||
|
|
||||||
if (addpanel) {
|
if (addpanel) {
|
||||||
auto panel = std::make_shared<gui::Container>(glm::vec2(width, height));
|
auto panel =
|
||||||
|
std::make_shared<gui::Container>(gui, glm::vec2(width, height));
|
||||||
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f));
|
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f));
|
||||||
view->add(panel, pos);
|
view->add(panel, pos);
|
||||||
}
|
}
|
||||||
@ -106,8 +107,8 @@ std::shared_ptr<InventoryView> InventoryBuilder::build() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SlotView::SlotView(
|
SlotView::SlotView(
|
||||||
SlotLayout layout
|
GUI& gui, SlotLayout layout
|
||||||
) : UINode(glm::vec2(InventoryView::SLOT_SIZE)),
|
) : UINode(gui, glm::vec2(InventoryView::SLOT_SIZE)),
|
||||||
layout(std::move(layout))
|
layout(std::move(layout))
|
||||||
{
|
{
|
||||||
setColor(glm::vec4(0, 0, 0, 0.2f));
|
setColor(glm::vec4(0, 0, 0, 0.2f));
|
||||||
@ -347,11 +348,11 @@ void SlotView::performRightClick(ItemStack& stack, ItemStack& grabbed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlotView::clicked(gui::GUI* gui, mousecode button) {
|
void SlotView::clicked(mousecode button) {
|
||||||
if (bound == nullptr)
|
if (bound == nullptr)
|
||||||
return;
|
return;
|
||||||
auto exchangeSlot =
|
auto exchangeSlot =
|
||||||
std::dynamic_pointer_cast<SlotView>(gui->get(EXCHANGE_SLOT_NAME));
|
std::dynamic_pointer_cast<SlotView>(gui.get(EXCHANGE_SLOT_NAME));
|
||||||
if (exchangeSlot == nullptr) {
|
if (exchangeSlot == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -368,8 +369,8 @@ void SlotView::clicked(gui::GUI* gui, mousecode button) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlotView::onFocus(gui::GUI* gui) {
|
void SlotView::onFocus() {
|
||||||
clicked(gui, mousecode::BUTTON_1);
|
clicked(mousecode::BUTTON_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::wstring& SlotView::getTooltip() const {
|
const std::wstring& SlotView::getTooltip() const {
|
||||||
@ -398,7 +399,7 @@ ItemStack& SlotView::getStack() {
|
|||||||
return *bound;
|
return *bound;
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryView::InventoryView() : Container(glm::vec2()) {
|
InventoryView::InventoryView(GUI& gui) : Container(gui, glm::vec2()) {
|
||||||
setColor(glm::vec4(0, 0, 0, 0.0f));
|
setColor(glm::vec4(0, 0, 0, 0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,7 +420,7 @@ std::shared_ptr<SlotView> InventoryView::addSlot(const SlotLayout& layout) {
|
|||||||
}
|
}
|
||||||
setSize(vsize);
|
setSize(vsize);
|
||||||
|
|
||||||
auto slot = std::make_shared<SlotView>(layout);
|
auto slot = std::make_shared<SlotView>(gui, layout);
|
||||||
if (!layout.background) {
|
if (!layout.background) {
|
||||||
slot->setColor(glm::vec4());
|
slot->setColor(glm::vec4());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,15 +86,15 @@ namespace gui {
|
|||||||
|
|
||||||
void refreshTooltip(const ItemStack& stack, const ItemDef& item);
|
void refreshTooltip(const ItemStack& stack, const ItemDef& item);
|
||||||
public:
|
public:
|
||||||
SlotView(SlotLayout layout);
|
SlotView(GUI& gui, SlotLayout layout);
|
||||||
|
|
||||||
virtual void draw(const DrawContext& pctx, const Assets& assets) override;
|
virtual void draw(const DrawContext& pctx, const Assets& assets) override;
|
||||||
|
|
||||||
void setHighlighted(bool flag);
|
void setHighlighted(bool flag);
|
||||||
bool isHighlighted() const;
|
bool isHighlighted() const;
|
||||||
|
|
||||||
virtual void clicked(gui::GUI*, mousecode) override;
|
virtual void clicked(mousecode) override;
|
||||||
virtual void onFocus(gui::GUI*) override;
|
virtual void onFocus() override;
|
||||||
virtual const std::wstring& getTooltip() const override;
|
virtual const std::wstring& getTooltip() const override;
|
||||||
|
|
||||||
void bind(
|
void bind(
|
||||||
@ -117,7 +117,7 @@ namespace gui {
|
|||||||
std::vector<SlotView*> slots;
|
std::vector<SlotView*> slots;
|
||||||
glm::vec2 origin {};
|
glm::vec2 origin {};
|
||||||
public:
|
public:
|
||||||
InventoryView();
|
InventoryView(GUI& gui);
|
||||||
virtual ~InventoryView();
|
virtual ~InventoryView();
|
||||||
|
|
||||||
virtual void setPos(glm::vec2 pos) override;
|
virtual void setPos(glm::vec2 pos) override;
|
||||||
@ -145,9 +145,10 @@ namespace gui {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class InventoryBuilder {
|
class InventoryBuilder {
|
||||||
|
GUI& gui;
|
||||||
std::shared_ptr<InventoryView> view;
|
std::shared_ptr<InventoryView> view;
|
||||||
public:
|
public:
|
||||||
InventoryBuilder();
|
InventoryBuilder(GUI& gui);
|
||||||
|
|
||||||
/// @brief Add slots grid to inventory view
|
/// @brief Add slots grid to inventory view
|
||||||
/// @param cols grid columns
|
/// @param cols grid columns
|
||||||
|
|||||||
@ -83,8 +83,8 @@ void LabelCache::update(std::wstring_view text, bool multiline, bool wrap) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label::Label(const std::string& text, std::string fontName)
|
Label::Label(GUI& gui, const std::string& text, std::string fontName)
|
||||||
: UINode(glm::vec2(text.length() * 8, 16)),
|
: UINode(gui, glm::vec2(text.length() * 8, 16)),
|
||||||
text(util::str2wstr_utf8(text)),
|
text(util::str2wstr_utf8(text)),
|
||||||
fontName(std::move(fontName))
|
fontName(std::move(fontName))
|
||||||
{
|
{
|
||||||
@ -93,8 +93,8 @@ Label::Label(const std::string& text, std::string fontName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Label::Label(const std::wstring& text, std::string fontName)
|
Label::Label(GUI& gui, const std::wstring& text, std::string fontName)
|
||||||
: UINode(glm::vec2(text.length() * 8, 16)),
|
: UINode(gui, glm::vec2(text.length() * 8, 16)),
|
||||||
text(text),
|
text(text),
|
||||||
fontName(std::move(fontName))
|
fontName(std::move(fontName))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -63,8 +63,8 @@ namespace gui {
|
|||||||
|
|
||||||
std::unique_ptr<FontStylesScheme> styles;
|
std::unique_ptr<FontStylesScheme> styles;
|
||||||
public:
|
public:
|
||||||
Label(const std::string& text, std::string fontName=FONT_DEFAULT);
|
Label(GUI& gui, const std::string& text, std::string fontName="normal");
|
||||||
Label(const std::wstring& text, std::string fontName=FONT_DEFAULT);
|
Label(GUI& gui, const std::wstring& text, std::string fontName="normal");
|
||||||
|
|
||||||
virtual ~Label();
|
virtual ~Label();
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
Menu::Menu() : Container(glm::vec2(1)){
|
Menu::Menu(GUI& gui) : Container(gui, glm::vec2(1)){
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Menu::has(const std::string& name) {
|
bool Menu::has(const std::string& name) {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ namespace gui {
|
|||||||
std::unordered_map<std::string, supplier<std::shared_ptr<UINode>>> pageSuppliers;
|
std::unordered_map<std::string, supplier<std::shared_ptr<UINode>>> pageSuppliers;
|
||||||
PageLoaderFunc pagesLoader = nullptr;
|
PageLoaderFunc pagesLoader = nullptr;
|
||||||
public:
|
public:
|
||||||
Menu();
|
explicit Menu(GUI& gui);
|
||||||
|
|
||||||
/// @brief Check menu have page or page supplier
|
/// @brief Check menu have page or page supplier
|
||||||
/// @param name page name
|
/// @param name page name
|
||||||
|
|||||||
@ -4,14 +4,12 @@
|
|||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
Panel::Panel(glm::vec2 size, glm::vec4 padding, float interval)
|
Panel::Panel(GUI& gui, glm::vec2 size, glm::vec4 padding, float interval)
|
||||||
: BasePanel(size, padding, interval, Orientation::vertical)
|
: BasePanel(gui, size, padding, interval) {
|
||||||
{
|
|
||||||
setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.75f));
|
setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.75f));
|
||||||
}
|
}
|
||||||
|
|
||||||
Panel::~Panel() {
|
Panel::~Panel() = default;
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::setMaxLength(int value) {
|
void Panel::setMaxLength(int value) {
|
||||||
maxLength = value;
|
maxLength = value;
|
||||||
@ -46,7 +44,7 @@ void Panel::fullRefresh() {
|
|||||||
Container::fullRefresh();
|
Container::fullRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::add(const std::shared_ptr<UINode> &node) {
|
void Panel::add(const std::shared_ptr<UINode>& node) {
|
||||||
node->setResizing(true);
|
node->setResizing(true);
|
||||||
Container::add(node);
|
Container::add(node);
|
||||||
fullRefresh();
|
fullRefresh();
|
||||||
@ -80,7 +78,7 @@ void Panel::refresh() {
|
|||||||
node->refresh();
|
node->refresh();
|
||||||
glm::vec2 nodeSize = node->getSize();
|
glm::vec2 nodeSize = node->getSize();
|
||||||
y += nodeSize.y + margin.w + interval;
|
y += nodeSize.y + margin.w + interval;
|
||||||
maxw = fmax(maxw, ex+nodeSize.x+margin.z+padding.z);
|
maxw = fmax(maxw, ex + nodeSize.x + margin.z + padding.z);
|
||||||
}
|
}
|
||||||
actualLength = y + padding.w;
|
actualLength = y + padding.w;
|
||||||
} else {
|
} else {
|
||||||
@ -89,11 +87,13 @@ void Panel::refresh() {
|
|||||||
glm::vec2 nodesize = node->getSize();
|
glm::vec2 nodesize = node->getSize();
|
||||||
const glm::vec4 margin = node->getMargin();
|
const glm::vec4 margin = node->getMargin();
|
||||||
x += margin.x;
|
x += margin.x;
|
||||||
node->setPos(glm::vec2(x, y+margin.y));
|
node->setPos(glm::vec2(x, y + margin.y));
|
||||||
x += nodesize.x + margin.z + interval;
|
x += nodesize.x + margin.z + interval;
|
||||||
|
|
||||||
node->refresh();
|
node->refresh();
|
||||||
maxh = fmax(maxh, y+margin.y+node->getSize().y+margin.w+padding.w);
|
maxh = fmax(
|
||||||
|
maxh, y + margin.y + node->getSize().y + margin.w + padding.w
|
||||||
|
);
|
||||||
}
|
}
|
||||||
actualLength = size.y;
|
actualLength = size.y;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "commons.hpp"
|
|
||||||
#include "BasePanel.hpp"
|
#include "BasePanel.hpp"
|
||||||
|
#include "commons.hpp"
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
class Panel : public BasePanel {
|
class Panel : public BasePanel {
|
||||||
public:
|
public:
|
||||||
Panel(
|
Panel(
|
||||||
|
GUI& gui,
|
||||||
glm::vec2 size,
|
glm::vec2 size,
|
||||||
glm::vec4 padding=glm::vec4(0.0f),
|
glm::vec4 padding = glm::vec4(2.0f),
|
||||||
float interval=2.0f
|
float interval = 2.0f
|
||||||
);
|
);
|
||||||
virtual ~Panel();
|
virtual ~Panel();
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "UINode.hpp"
|
#include "UINode.hpp"
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class Assets;
|
class Assets;
|
||||||
class DrawContext;
|
class DrawContext;
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
class Plotter : public gui::UINode {
|
class Plotter : public UINode {
|
||||||
std::unique_ptr<int[]> points;
|
std::unique_ptr<int[]> points;
|
||||||
float multiplier;
|
float multiplier;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -17,13 +18,18 @@ namespace gui {
|
|||||||
int dmheight;
|
int dmheight;
|
||||||
int labelsInterval;
|
int labelsInterval;
|
||||||
public:
|
public:
|
||||||
Plotter(uint width, uint height, float multiplier, int labelsInterval)
|
Plotter(
|
||||||
: gui::UINode(glm::vec2(width, height)),
|
GUI& gui,
|
||||||
multiplier(multiplier),
|
uint width,
|
||||||
dmwidth(width-50),
|
uint height,
|
||||||
dmheight(height),
|
float multiplier,
|
||||||
labelsInterval(labelsInterval)
|
int labelsInterval
|
||||||
{
|
)
|
||||||
|
: UINode(gui, glm::vec2(width, height)),
|
||||||
|
multiplier(multiplier),
|
||||||
|
dmwidth(width - 50),
|
||||||
|
dmheight(height),
|
||||||
|
labelsInterval(labelsInterval) {
|
||||||
points = std::make_unique<int[]>(dmwidth);
|
points = std::make_unique<int[]>(dmwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
SplitBox::SplitBox(const glm::vec2& size, float splitPos, Orientation orientation)
|
SplitBox::SplitBox(GUI& gui, const glm::vec2& size, float splitPos, Orientation orientation)
|
||||||
: BasePanel(size, glm::vec4(), 4.0f, orientation), splitPos(splitPos) {
|
: BasePanel(gui, size, glm::vec4(), 4.0f, orientation), splitPos(splitPos) {
|
||||||
setCursor(
|
setCursor(
|
||||||
orientation == Orientation::vertical ? CursorShape::NS_RESIZE
|
orientation == Orientation::vertical ? CursorShape::NS_RESIZE
|
||||||
: CursorShape::EW_RESIZE
|
: CursorShape::EW_RESIZE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitBox::mouseMove(GUI*, int x, int y) {
|
void SplitBox::mouseMove(int x, int y) {
|
||||||
auto pos = calcPos();
|
auto pos = calcPos();
|
||||||
auto size = getSize();
|
auto size = getSize();
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ void SplitBox::refresh() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitBox::doubleClick(GUI*, int x, int y) {
|
void SplitBox::doubleClick(int x, int y) {
|
||||||
if (nodes.size() < 2) {
|
if (nodes.size() < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,12 +5,12 @@
|
|||||||
namespace gui {
|
namespace gui {
|
||||||
class SplitBox : public BasePanel {
|
class SplitBox : public BasePanel {
|
||||||
public:
|
public:
|
||||||
SplitBox(const glm::vec2& size, float splitPos, Orientation orientation);
|
SplitBox(GUI& gui, const glm::vec2& size, float splitPos, Orientation orientation);
|
||||||
|
|
||||||
virtual void mouseMove(GUI*, int x, int y) override;
|
virtual void mouseMove(int x, int y) override;
|
||||||
virtual void refresh() override;
|
virtual void refresh() override;
|
||||||
virtual void fullRefresh() override;
|
virtual void fullRefresh() override;
|
||||||
virtual void doubleClick(GUI*, int x, int y) override;
|
virtual void doubleClick(int x, int y) override;
|
||||||
private:
|
private:
|
||||||
float splitPos;
|
float splitPos;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,9 +4,12 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "../GUI.hpp"
|
||||||
|
#include "../markdown.hpp"
|
||||||
#include "Label.hpp"
|
#include "Label.hpp"
|
||||||
#include "assets/Assets.hpp"
|
#include "assets/Assets.hpp"
|
||||||
#include "devtools/syntax_highlighting.hpp"
|
#include "devtools/syntax_highlighting.hpp"
|
||||||
|
#include "engine/Engine.hpp"
|
||||||
#include "graphics/core/Batch2D.hpp"
|
#include "graphics/core/Batch2D.hpp"
|
||||||
#include "graphics/core/DrawContext.hpp"
|
#include "graphics/core/DrawContext.hpp"
|
||||||
#include "graphics/core/Font.hpp"
|
#include "graphics/core/Font.hpp"
|
||||||
@ -186,8 +189,9 @@ namespace gui {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
TextBox::TextBox(std::wstring placeholder, glm::vec4 padding)
|
TextBox::TextBox(GUI& gui, std::wstring placeholder, glm::vec4 padding)
|
||||||
: Container(glm::vec2(200, 32)),
|
: Container(gui, glm::vec2(200, 32)),
|
||||||
|
inputEvents(gui.getInput()),
|
||||||
history(std::make_shared<ActionsHistory>()),
|
history(std::make_shared<ActionsHistory>()),
|
||||||
historian(std::make_unique<TextBoxHistorian>(*this, *history)),
|
historian(std::make_unique<TextBoxHistorian>(*this, *history)),
|
||||||
padding(padding),
|
padding(padding),
|
||||||
@ -197,16 +201,21 @@ TextBox::TextBox(std::wstring placeholder, glm::vec4 padding)
|
|||||||
setOnUpPressed(nullptr);
|
setOnUpPressed(nullptr);
|
||||||
setOnDownPressed(nullptr);
|
setOnDownPressed(nullptr);
|
||||||
setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.75f));
|
setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.75f));
|
||||||
label = std::make_shared<Label>(L"");
|
|
||||||
label->setSize(size-glm::vec2(padding.z+padding.x, padding.w+padding.y));
|
label = std::make_shared<Label>(gui, L"");
|
||||||
|
label->setSize(
|
||||||
|
size - glm::vec2(padding.z + padding.x, padding.w + padding.y)
|
||||||
|
);
|
||||||
label->setPos(glm::vec2(
|
label->setPos(glm::vec2(
|
||||||
padding.x + LINE_NUMBERS_PANE_WIDTH * showLineNumbers, padding.y
|
padding.x + LINE_NUMBERS_PANE_WIDTH * showLineNumbers, padding.y
|
||||||
));
|
));
|
||||||
add(label);
|
add(label);
|
||||||
|
|
||||||
lineNumbersLabel = std::make_shared<Label>(L"");
|
lineNumbersLabel = std::make_shared<Label>(gui, L"");
|
||||||
lineNumbersLabel->setMultiline(true);
|
lineNumbersLabel->setMultiline(true);
|
||||||
lineNumbersLabel->setSize(size-glm::vec2(padding.z+padding.x, padding.w+padding.y));
|
lineNumbersLabel->setSize(
|
||||||
|
size - glm::vec2(padding.z + padding.x, padding.w + padding.y)
|
||||||
|
);
|
||||||
lineNumbersLabel->setVerticalAlign(Align::top);
|
lineNumbersLabel->setVerticalAlign(Align::top);
|
||||||
add(lineNumbersLabel);
|
add(lineNumbersLabel);
|
||||||
|
|
||||||
@ -342,7 +351,7 @@ void TextBox::drawBackground(const DrawContext& pctx, const Assets&) {
|
|||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
|
|
||||||
auto subctx = pctx.sub();
|
auto subctx = pctx.sub();
|
||||||
subctx.setScissors(glm::vec4(pos.x, pos.y-0.5, size.x, size.y+1));
|
subctx.setScissors(glm::vec4(pos.x, pos.y - 0.5, size.x, size.y + 1));
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (isFocused() && !multiline) {
|
if (isFocused() && !multiline) {
|
||||||
@ -371,7 +380,8 @@ void TextBox::refreshLabel() {
|
|||||||
|
|
||||||
const auto& displayText = input.empty() && !hint.empty() ? hint : getText();
|
const auto& displayText = input.empty() && !hint.empty() ? hint : getText();
|
||||||
if (markup == "md") {
|
if (markup == "md") {
|
||||||
auto [processedText, styles] = markdown::process(displayText, !focused || !editable);
|
auto [processedText, styles] =
|
||||||
|
markdown::process(displayText, !focused || !editable);
|
||||||
label->setText(std::move(processedText));
|
label->setText(std::move(processedText));
|
||||||
label->setStyles(std::move(styles));
|
label->setStyles(std::move(styles));
|
||||||
} else {
|
} else {
|
||||||
@ -386,7 +396,7 @@ void TextBox::refreshLabel() {
|
|||||||
std::wstringstream ss;
|
std::wstringstream ss;
|
||||||
int n = 1;
|
int n = 1;
|
||||||
for (int i = 1; i <= label->getLinesNumber(); i++) {
|
for (int i = 1; i <= label->getLinesNumber(); i++) {
|
||||||
if (!label->isFakeLine(i-1)) {
|
if (!label->isFakeLine(i - 1)) {
|
||||||
ss << n;
|
ss << n;
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
@ -402,11 +412,12 @@ void TextBox::refreshLabel() {
|
|||||||
|
|
||||||
if (autoresize && font) {
|
if (autoresize && font) {
|
||||||
auto size = getSize();
|
auto size = getSize();
|
||||||
int newy = glm::min(static_cast<int>(parent->getSize().y),
|
int newy = glm::min(
|
||||||
static_cast<int>(
|
static_cast<int>(parent->getSize().y),
|
||||||
label->getLinesNumber() *
|
static_cast<int>(
|
||||||
label->getLineInterval() *
|
label->getLinesNumber() * label->getLineInterval() *
|
||||||
font->getLineHeight()) + 1
|
font->getLineHeight()
|
||||||
|
) + 1
|
||||||
);
|
);
|
||||||
if (newy != static_cast<int>(size.y)) {
|
if (newy != static_cast<int>(size.y)) {
|
||||||
size.y = newy;
|
size.y = newy;
|
||||||
@ -475,7 +486,7 @@ bool TextBox::eraseSelected() {
|
|||||||
input.substr(selectionStart, selectionEnd - selectionStart),
|
input.substr(selectionStart, selectionEnd - selectionStart),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
erase(selectionStart, selectionEnd-selectionStart);
|
erase(selectionStart, selectionEnd - selectionStart);
|
||||||
resetSelection();
|
resetSelection();
|
||||||
onInput();
|
onInput();
|
||||||
return true;
|
return true;
|
||||||
@ -495,7 +506,7 @@ void TextBox::extendSelection(int index) {
|
|||||||
|
|
||||||
size_t TextBox::getLineLength(uint line) const {
|
size_t TextBox::getLineLength(uint line) const {
|
||||||
size_t position = label->getTextLineOffset(line);
|
size_t position = label->getTextLineOffset(line);
|
||||||
size_t lineLength = label->getTextLineOffset(line+1)-position;
|
size_t lineLength = label->getTextLineOffset(line + 1) - position;
|
||||||
if (lineLength == 0) {
|
if (lineLength == 0) {
|
||||||
lineLength = label->getText().length() - position + 1;
|
lineLength = label->getText().length() - position + 1;
|
||||||
}
|
}
|
||||||
@ -593,9 +604,9 @@ bool TextBox::isAutoResize() const {
|
|||||||
return autoresize;
|
return autoresize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::onFocus(GUI* gui) {
|
void TextBox::onFocus() {
|
||||||
Container::onFocus(gui);
|
Container::onFocus();
|
||||||
if (onEditStart){
|
if (onEditStart) {
|
||||||
setCaret(input.size());
|
setCaret(input.size());
|
||||||
onEditStart();
|
onEditStart();
|
||||||
resetSelection();
|
resetSelection();
|
||||||
@ -609,7 +620,9 @@ void TextBox::reposition() {
|
|||||||
|
|
||||||
void TextBox::refresh() {
|
void TextBox::refresh() {
|
||||||
Container::refresh();
|
Container::refresh();
|
||||||
label->setSize(size-glm::vec2(padding.z+padding.x, padding.w+padding.y));
|
label->setSize(
|
||||||
|
size - glm::vec2(padding.z + padding.x, padding.w + padding.y)
|
||||||
|
);
|
||||||
label->setPos(glm::vec2(
|
label->setPos(glm::vec2(
|
||||||
padding.x + LINE_NUMBERS_PANE_WIDTH * showLineNumbers + textInitX -
|
padding.x + LINE_NUMBERS_PANE_WIDTH * showLineNumbers + textInitX -
|
||||||
static_cast<int>(textOffset),
|
static_cast<int>(textOffset),
|
||||||
@ -629,24 +642,27 @@ size_t TextBox::normalizeIndex(int index) {
|
|||||||
/// @param y screen Y position
|
/// @param y screen Y position
|
||||||
/// @return non-normalized character index
|
/// @return non-normalized character index
|
||||||
int TextBox::calcIndexAt(int x, int y) const {
|
int TextBox::calcIndexAt(int x, int y) const {
|
||||||
if (font == nullptr)
|
if (font == nullptr) return 0;
|
||||||
return 0;
|
|
||||||
const auto& labelText = label->getText();
|
const auto& labelText = label->getText();
|
||||||
glm::vec2 lcoord = label->calcPos();
|
glm::vec2 lcoord = label->calcPos();
|
||||||
uint line = label->getLineByYOffset(y-lcoord.y);
|
uint line = label->getLineByYOffset(y - lcoord.y);
|
||||||
line = std::min(line, label->getLinesNumber()-1);
|
line = std::min(line, label->getLinesNumber() - 1);
|
||||||
size_t lineLength = getLineLength(line);
|
size_t lineLength = getLineLength(line);
|
||||||
uint offset = 0;
|
uint offset = 0;
|
||||||
while (lcoord.x + font->calcWidth(labelText, offset) < x && offset < lineLength-1) {
|
while (lcoord.x + font->calcWidth(labelText, offset) < x &&
|
||||||
|
offset < lineLength - 1) {
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
return std::min(offset+label->getTextLineOffset(line), labelText.length());
|
return std::min(
|
||||||
|
offset + label->getTextLineOffset(line), labelText.length()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline std::wstring get_alphabet(wchar_t c) {
|
static inline std::wstring get_alphabet(wchar_t c) {
|
||||||
std::wstring alphabet {c};
|
std::wstring alphabet {c};
|
||||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_') {
|
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_') {
|
||||||
return L"abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
return L"abcdefghijklmnopqrstuvwxyz_"
|
||||||
|
L"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
} else if (c >= '0' && c <= '9') {
|
} else if (c >= '0' && c <= '9') {
|
||||||
return L"0123456789";
|
return L"0123456789";
|
||||||
}
|
}
|
||||||
@ -674,23 +690,23 @@ void TextBox::tokenSelectAt(int index) {
|
|||||||
}
|
}
|
||||||
right++;
|
right++;
|
||||||
}
|
}
|
||||||
select(left+1, right);
|
select(left + 1, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::doubleClick(GUI* gui, int x, int y) {
|
void TextBox::doubleClick(int x, int y) {
|
||||||
UINode::doubleClick(gui, x, y);
|
UINode::doubleClick(x, y);
|
||||||
tokenSelectAt(normalizeIndex(calcIndexAt(x, y)-1));
|
tokenSelectAt(normalizeIndex(calcIndexAt(x, y) - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::click(GUI*, int x, int y) {
|
void TextBox::click(int x, int y) {
|
||||||
int index = normalizeIndex(calcIndexAt(x, y));
|
int index = normalizeIndex(calcIndexAt(x, y));
|
||||||
selectionStart = index;
|
selectionStart = index;
|
||||||
selectionEnd = index;
|
selectionEnd = index;
|
||||||
selectionOrigin = index;
|
selectionOrigin = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::mouseMove(GUI* gui, int x, int y) {
|
void TextBox::mouseMove(int x, int y) {
|
||||||
Container::mouseMove(gui, x, y);
|
Container::mouseMove(x, y);
|
||||||
if (isScrolling()) {
|
if (isScrolling()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -701,7 +717,8 @@ void TextBox::mouseMove(GUI* gui, int x, int y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::resetMaxLocalCaret() {
|
void TextBox::resetMaxLocalCaret() {
|
||||||
maxLocalCaret = caret - label->getTextLineOffset(label->getLineByTextIndex(caret));
|
maxLocalCaret =
|
||||||
|
caret - label->getTextLineOffset(label->getLineByTextIndex(caret));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::stepLeft(bool shiftPressed, bool breakSelection) {
|
void TextBox::stepLeft(bool shiftPressed, bool breakSelection) {
|
||||||
@ -709,9 +726,9 @@ void TextBox::stepLeft(bool shiftPressed, bool breakSelection) {
|
|||||||
size_t caret = breakSelection ? selectionStart : this->caret;
|
size_t caret = breakSelection ? selectionStart : this->caret;
|
||||||
if (caret > 0) {
|
if (caret > 0) {
|
||||||
if (caret > input.length()) {
|
if (caret > input.length()) {
|
||||||
setCaret(input.length()-1);
|
setCaret(input.length() - 1);
|
||||||
} else {
|
} else {
|
||||||
setCaret(caret-1);
|
setCaret(caret - 1);
|
||||||
}
|
}
|
||||||
if (shiftPressed) {
|
if (shiftPressed) {
|
||||||
if (selectionStart == selectionEnd) {
|
if (selectionStart == selectionEnd) {
|
||||||
@ -732,7 +749,7 @@ void TextBox::stepRight(bool shiftPressed, bool breakSelection) {
|
|||||||
uint previousCaret = this->caret;
|
uint previousCaret = this->caret;
|
||||||
size_t caret = breakSelection ? selectionEnd : this->caret;
|
size_t caret = breakSelection ? selectionEnd : this->caret;
|
||||||
if (caret < input.length()) {
|
if (caret < input.length()) {
|
||||||
setCaret(caret+1);
|
setCaret(caret + 1);
|
||||||
caretLastMove = Window::time();
|
caretLastMove = Window::time();
|
||||||
if (shiftPressed) {
|
if (shiftPressed) {
|
||||||
if (selectionStart == selectionEnd) {
|
if (selectionStart == selectionEnd) {
|
||||||
@ -753,9 +770,10 @@ void TextBox::stepDefaultDown(bool shiftPressed, bool breakSelection) {
|
|||||||
uint previousCaret = this->caret;
|
uint previousCaret = this->caret;
|
||||||
uint caret = breakSelection ? selectionEnd : this->caret;
|
uint caret = breakSelection ? selectionEnd : this->caret;
|
||||||
uint caretLine = label->getLineByTextIndex(caret);
|
uint caretLine = label->getLineByTextIndex(caret);
|
||||||
if (caretLine < label->getLinesNumber()-1) {
|
if (caretLine < label->getLinesNumber() - 1) {
|
||||||
uint offset = std::min(size_t(maxLocalCaret), getLineLength(caretLine+1)-1);
|
uint offset =
|
||||||
setCaret(label->getTextLineOffset(caretLine+1) + offset);
|
std::min(size_t(maxLocalCaret), getLineLength(caretLine + 1) - 1);
|
||||||
|
setCaret(label->getTextLineOffset(caretLine + 1) + offset);
|
||||||
} else {
|
} else {
|
||||||
setCaret(input.length());
|
setCaret(input.length());
|
||||||
}
|
}
|
||||||
@ -774,8 +792,9 @@ void TextBox::stepDefaultUp(bool shiftPressed, bool breakSelection) {
|
|||||||
uint caret = breakSelection ? selectionStart : this->caret;
|
uint caret = breakSelection ? selectionStart : this->caret;
|
||||||
uint caretLine = label->getLineByTextIndex(caret);
|
uint caretLine = label->getLineByTextIndex(caret);
|
||||||
if (caretLine > 0) {
|
if (caretLine > 0) {
|
||||||
uint offset = std::min(size_t(maxLocalCaret), getLineLength(caretLine-1)-1);
|
uint offset =
|
||||||
setCaret(label->getTextLineOffset(caretLine-1) + offset);
|
std::min(size_t(maxLocalCaret), getLineLength(caretLine - 1) - 1);
|
||||||
|
setCaret(label->getTextLineOffset(caretLine - 1) + offset);
|
||||||
} else {
|
} else {
|
||||||
setCaret(static_cast<size_t>(0));
|
setCaret(static_cast<size_t>(0));
|
||||||
}
|
}
|
||||||
@ -805,7 +824,7 @@ void TextBox::onInput() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::performEditingKeyboardEvents(keycode key) {
|
void TextBox::performEditingKeyboardEvents(keycode key) {
|
||||||
bool shiftPressed = Events::pressed(keycode::LEFT_SHIFT);
|
bool shiftPressed = gui.getInput().pressed(keycode::LEFT_SHIFT);
|
||||||
bool breakSelection = getSelectionLength() != 0 && !shiftPressed;
|
bool breakSelection = getSelectionLength() != 0 && !shiftPressed;
|
||||||
if (key == keycode::BACKSPACE) {
|
if (key == keycode::BACKSPACE) {
|
||||||
if (!eraseSelected() && caret > 0 && input.length() > 0) {
|
if (!eraseSelected() && caret > 0 && input.length() > 0) {
|
||||||
@ -813,8 +832,8 @@ void TextBox::performEditingKeyboardEvents(keycode key) {
|
|||||||
caret = input.length();
|
caret = input.length();
|
||||||
}
|
}
|
||||||
historian->onErase(caret - 1, input.substr(caret - 1, 1));
|
historian->onErase(caret - 1, input.substr(caret - 1, 1));
|
||||||
input = input.substr(0, caret-1) + input.substr(caret);
|
input = input.substr(0, caret - 1) + input.substr(caret);
|
||||||
setCaret(caret-1);
|
setCaret(caret - 1);
|
||||||
if (validate()) {
|
if (validate()) {
|
||||||
onInput();
|
onInput();
|
||||||
}
|
}
|
||||||
@ -850,10 +869,11 @@ void TextBox::performEditingKeyboardEvents(keycode key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::keyPressed(keycode key) {
|
void TextBox::keyPressed(keycode key) {
|
||||||
|
const auto& inputEvents = gui.getInput();
|
||||||
if (editable) {
|
if (editable) {
|
||||||
performEditingKeyboardEvents(key);
|
performEditingKeyboardEvents(key);
|
||||||
}
|
}
|
||||||
if (Events::pressed(keycode::LEFT_CONTROL) && key != keycode::LEFT_CONTROL) {
|
if (inputEvents.pressed(keycode::LEFT_CONTROL) && key != keycode::LEFT_CONTROL) {
|
||||||
if (controlCombinationsHandler) {
|
if (controlCombinationsHandler) {
|
||||||
if (controlCombinationsHandler(static_cast<int>(key))) {
|
if (controlCombinationsHandler(static_cast<int>(key))) {
|
||||||
return;
|
return;
|
||||||
@ -871,7 +891,7 @@ void TextBox::keyPressed(keycode key) {
|
|||||||
}
|
}
|
||||||
// Paste text from clipboard
|
// Paste text from clipboard
|
||||||
if (key == keycode::V && editable) {
|
if (key == keycode::V && editable) {
|
||||||
const char* text = Window::getClipboardText();
|
const char* text = inputEvents.getClipboardText();
|
||||||
if (text) {
|
if (text) {
|
||||||
historian->sync(); // flush buffer before combination
|
historian->sync(); // flush buffer before combination
|
||||||
// Combine deleting selected text and pasing a clipboard content
|
// Combine deleting selected text and pasing a clipboard content
|
||||||
@ -924,14 +944,14 @@ std::shared_ptr<UINode> TextBox::getAt(const glm::vec2& pos) {
|
|||||||
return UINode::getAt(pos);
|
return UINode::getAt(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::setOnUpPressed(const runnable &callback) {
|
void TextBox::setOnUpPressed(const runnable& callback) {
|
||||||
if (callback == nullptr) {
|
if (callback == nullptr) {
|
||||||
onUpPressed = [this]() {
|
onUpPressed = [this]() {
|
||||||
if (Events::pressed(keycode::LEFT_CONTROL)) {
|
if (inputEvents.pressed(keycode::LEFT_CONTROL)) {
|
||||||
scrolled(1);
|
scrolled(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool shiftPressed = Events::pressed(keycode::LEFT_SHIFT);
|
bool shiftPressed = inputEvents.pressed(keycode::LEFT_SHIFT);
|
||||||
bool breakSelection = getSelectionLength() != 0 && !shiftPressed;
|
bool breakSelection = getSelectionLength() != 0 && !shiftPressed;
|
||||||
stepDefaultUp(shiftPressed, breakSelection);
|
stepDefaultUp(shiftPressed, breakSelection);
|
||||||
};
|
};
|
||||||
@ -940,14 +960,14 @@ void TextBox::setOnUpPressed(const runnable &callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::setOnDownPressed(const runnable &callback) {
|
void TextBox::setOnDownPressed(const runnable& callback) {
|
||||||
if (callback == nullptr) {
|
if (callback == nullptr) {
|
||||||
onDownPressed = [this]() {
|
onDownPressed = [this]() {
|
||||||
if (Events::pressed(keycode::LEFT_CONTROL)) {
|
if (inputEvents.pressed(keycode::LEFT_CONTROL)) {
|
||||||
scrolled(-1);
|
scrolled(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool shiftPressed = Events::pressed(keycode::LEFT_SHIFT);
|
bool shiftPressed = inputEvents.pressed(keycode::LEFT_SHIFT);
|
||||||
bool breakSelection = getSelectionLength() != 0 && !shiftPressed;
|
bool breakSelection = getSelectionLength() != 0 && !shiftPressed;
|
||||||
stepDefaultDown(shiftPressed, breakSelection);
|
stepDefaultDown(shiftPressed, breakSelection);
|
||||||
};
|
};
|
||||||
@ -984,7 +1004,6 @@ glm::vec4 TextBox::getFocusedColor() const {
|
|||||||
return focusedColor;
|
return focusedColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TextBox::setTextColor(glm::vec4 color) {
|
void TextBox::setTextColor(glm::vec4 color) {
|
||||||
this->textColor = color;
|
this->textColor = color;
|
||||||
}
|
}
|
||||||
@ -1002,8 +1021,7 @@ glm::vec4 TextBox::getErrorColor() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const std::wstring& TextBox::getText() const {
|
const std::wstring& TextBox::getText() const {
|
||||||
if (input.empty())
|
if (input.empty()) return placeholder;
|
||||||
return placeholder;
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1024,7 +1042,6 @@ void TextBox::setPlaceholder(const std::wstring& placeholder) {
|
|||||||
this->placeholder = placeholder;
|
this->placeholder = placeholder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::wstring& TextBox::getHint() const {
|
const std::wstring& TextBox::getHint() const {
|
||||||
return hint;
|
return hint;
|
||||||
}
|
}
|
||||||
@ -1035,7 +1052,7 @@ void TextBox::setHint(const std::wstring& text) {
|
|||||||
|
|
||||||
std::wstring TextBox::getSelection() const {
|
std::wstring TextBox::getSelection() const {
|
||||||
const auto& text = label->getText();
|
const auto& text = label->getText();
|
||||||
return text.substr(selectionStart, selectionEnd-selectionStart);
|
return text.substr(selectionStart, selectionEnd - selectionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TextBox::getCaret() const {
|
size_t TextBox::getCaret() const {
|
||||||
@ -1057,24 +1074,25 @@ void TextBox::setCaret(size_t position) {
|
|||||||
|
|
||||||
uint line = rawTextCache.getLineByTextIndex(caret);
|
uint line = rawTextCache.getLineByTextIndex(caret);
|
||||||
int offset = label->getLineYOffset(line) + getContentOffset().y;
|
int offset = label->getLineYOffset(line) + getContentOffset().y;
|
||||||
uint lineHeight = font->getLineHeight()*label->getLineInterval();
|
uint lineHeight = font->getLineHeight() * label->getLineInterval();
|
||||||
if (scrollStep == 0) {
|
if (scrollStep == 0) {
|
||||||
scrollStep = lineHeight;
|
scrollStep = lineHeight;
|
||||||
}
|
}
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
scrolled(-glm::floor(offset / static_cast<double>(scrollStep)+0.5f));
|
scrolled(-glm::floor(offset / static_cast<double>(scrollStep) + 0.5f));
|
||||||
} else if (offset >= getSize().y) {
|
} else if (offset >= getSize().y) {
|
||||||
offset -= getSize().y;
|
offset -= getSize().y;
|
||||||
scrolled(-glm::ceil(offset / static_cast<double>(scrollStep)+0.5f));
|
scrolled(-glm::ceil(offset / static_cast<double>(scrollStep) + 0.5f));
|
||||||
}
|
}
|
||||||
int lcaret = caret - rawTextCache.getTextLineOffset(line);
|
int lcaret = caret - rawTextCache.getTextLineOffset(line);
|
||||||
int realoffset =
|
int realoffset =
|
||||||
font->calcWidth(labelText, lcaret) - static_cast<int>(textOffset) + 2;
|
font->calcWidth(labelText, lcaret) - static_cast<int>(textOffset) + 2;
|
||||||
|
|
||||||
if (realoffset-width > 0) {
|
if (realoffset - width > 0) {
|
||||||
setTextOffset(textOffset + realoffset-width);
|
setTextOffset(textOffset + realoffset - width);
|
||||||
} else if (realoffset < 0) {
|
} else if (realoffset < 0) {
|
||||||
setTextOffset(std::max(textOffset + realoffset, static_cast<size_t>(0)));
|
setTextOffset(std::max(textOffset + realoffset, static_cast<size_t>(0))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ class ActionsHistory;
|
|||||||
namespace gui {
|
namespace gui {
|
||||||
class TextBoxHistorian;
|
class TextBoxHistorian;
|
||||||
class TextBox : public Container {
|
class TextBox : public Container {
|
||||||
|
const Input& inputEvents;
|
||||||
LabelCache rawTextCache;
|
LabelCache rawTextCache;
|
||||||
std::shared_ptr<ActionsHistory> history;
|
std::shared_ptr<ActionsHistory> history;
|
||||||
std::unique_ptr<TextBoxHistorian> historian;
|
std::unique_ptr<TextBoxHistorian> historian;
|
||||||
@ -94,7 +95,8 @@ namespace gui {
|
|||||||
|
|
||||||
void refreshSyntax();
|
void refreshSyntax();
|
||||||
public:
|
public:
|
||||||
TextBox(
|
explicit TextBox(
|
||||||
|
GUI& gui,
|
||||||
std::wstring placeholder,
|
std::wstring placeholder,
|
||||||
glm::vec4 padding=glm::vec4(4.0f)
|
glm::vec4 padding=glm::vec4(4.0f)
|
||||||
);
|
);
|
||||||
@ -227,11 +229,11 @@ namespace gui {
|
|||||||
virtual bool isShowLineNumbers() const;
|
virtual bool isShowLineNumbers() const;
|
||||||
|
|
||||||
virtual void reposition() override;
|
virtual void reposition() override;
|
||||||
virtual void onFocus(GUI*) override;
|
virtual void onFocus() override;
|
||||||
virtual void refresh() override;
|
virtual void refresh() override;
|
||||||
virtual void doubleClick(GUI*, int x, int y) override;
|
virtual void doubleClick(int x, int y) override;
|
||||||
virtual void click(GUI*, int, int) override;
|
virtual void click(int, int) override;
|
||||||
virtual void mouseMove(GUI*, int x, int y) override;
|
virtual void mouseMove(int x, int y) override;
|
||||||
virtual bool isFocuskeeper() const override {return true;}
|
virtual bool isFocuskeeper() const override {return true;}
|
||||||
virtual void draw(const DrawContext& pctx, const Assets& assets) override;
|
virtual void draw(const DrawContext& pctx, const Assets& assets) override;
|
||||||
virtual void drawBackground(const DrawContext& pctx, const Assets& assets) override;
|
virtual void drawBackground(const DrawContext& pctx, const Assets& assets) override;
|
||||||
|
|||||||
@ -9,12 +9,13 @@
|
|||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
TrackBar::TrackBar(
|
TrackBar::TrackBar(
|
||||||
|
GUI& gui,
|
||||||
double min,
|
double min,
|
||||||
double max,
|
double max,
|
||||||
double value,
|
double value,
|
||||||
double step,
|
double step,
|
||||||
int trackWidth
|
int trackWidth
|
||||||
) : UINode(glm::vec2(26)),
|
) : UINode(gui, glm::vec2(26)),
|
||||||
min(min),
|
min(min),
|
||||||
max(max),
|
max(max),
|
||||||
value(value),
|
value(value),
|
||||||
@ -54,7 +55,7 @@ void TrackBar::setSubConsumer(doubleconsumer consumer) {
|
|||||||
this->subconsumer = std::move(consumer);
|
this->subconsumer = std::move(consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackBar::mouseMove(GUI*, int x, int) {
|
void TrackBar::mouseMove(int x, int) {
|
||||||
glm::vec2 pos = calcPos();
|
glm::vec2 pos = calcPos();
|
||||||
value = x - trackWidth/2;
|
value = x - trackWidth/2;
|
||||||
value -= pos.x;
|
value -= pos.x;
|
||||||
@ -62,7 +63,7 @@ void TrackBar::mouseMove(GUI*, int x, int) {
|
|||||||
value += min;
|
value += min;
|
||||||
value = (value > max) ? max : value;
|
value = (value > max) ? max : value;
|
||||||
value = (value < min) ? min : value;
|
value = (value < min) ? min : value;
|
||||||
value = (int64_t)round(value / step) * step;
|
value = static_cast<int64_t>(std::round(value / step)) * step;
|
||||||
|
|
||||||
if (consumer && !changeOnRelease) {
|
if (consumer && !changeOnRelease) {
|
||||||
consumer(value);
|
consumer(value);
|
||||||
@ -72,7 +73,7 @@ void TrackBar::mouseMove(GUI*, int x, int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackBar::mouseRelease(GUI*, int, int) {
|
void TrackBar::mouseRelease(int, int) {
|
||||||
if (consumer && changeOnRelease) {
|
if (consumer && changeOnRelease) {
|
||||||
consumer(value);
|
consumer(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,19 +16,22 @@ namespace gui {
|
|||||||
int trackWidth;
|
int trackWidth;
|
||||||
bool changeOnRelease = false;
|
bool changeOnRelease = false;
|
||||||
public:
|
public:
|
||||||
TrackBar(double min,
|
TrackBar(
|
||||||
double max,
|
GUI& gui,
|
||||||
double value,
|
double min,
|
||||||
double step=1.0,
|
double max,
|
||||||
int trackWidth=12);
|
double value,
|
||||||
|
double step = 1.0,
|
||||||
|
int trackWidth = 12
|
||||||
|
);
|
||||||
virtual void draw(const DrawContext& pctx, const Assets& assets) override;
|
virtual void draw(const DrawContext& pctx, const Assets& assets) override;
|
||||||
|
|
||||||
virtual void setSupplier(doublesupplier);
|
virtual void setSupplier(doublesupplier);
|
||||||
virtual void setConsumer(doubleconsumer);
|
virtual void setConsumer(doubleconsumer);
|
||||||
virtual void setSubConsumer(doubleconsumer);
|
virtual void setSubConsumer(doubleconsumer);
|
||||||
|
|
||||||
virtual void mouseMove(GUI*, int x, int y) override;
|
virtual void mouseMove(int x, int y) override;
|
||||||
virtual void mouseRelease(GUI*, int x, int y) override;
|
virtual void mouseRelease(int x, int y) override;
|
||||||
|
|
||||||
virtual double getValue() const;
|
virtual double getValue() const;
|
||||||
virtual double getMin() const;
|
virtual double getMin() const;
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
using gui::UINode;
|
using gui::UINode;
|
||||||
using gui::Align;
|
using gui::Align;
|
||||||
|
|
||||||
UINode::UINode(glm::vec2 size) : size(size) {
|
UINode::UINode(GUI& gui, glm::vec2 size) : gui(gui), size(size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
UINode::~UINode() {
|
UINode::~UINode() {
|
||||||
@ -74,18 +74,18 @@ UINode* UINode::listenDoubleClick(const onaction& action) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::click(GUI*, int, int) {
|
void UINode::click(int, int) {
|
||||||
pressed = true;
|
pressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::doubleClick(GUI* gui, int x, int y) {
|
void UINode::doubleClick(int x, int y) {
|
||||||
pressed = true;
|
pressed = true;
|
||||||
if (isInside(glm::vec2(x, y))) {
|
if (isInside(glm::vec2(x, y))) {
|
||||||
doubleClickCallbacks.notify(gui);
|
doubleClickCallbacks.notify(gui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::mouseRelease(GUI* gui, int x, int y) {
|
void UINode::mouseRelease(int x, int y) {
|
||||||
pressed = false;
|
pressed = false;
|
||||||
if (isInside(glm::vec2(x, y))) {
|
if (isInside(glm::vec2(x, y))) {
|
||||||
actions.notify(gui);
|
actions.notify(gui);
|
||||||
|
|||||||
@ -19,8 +19,8 @@ namespace gui {
|
|||||||
class GUI;
|
class GUI;
|
||||||
class Container;
|
class Container;
|
||||||
|
|
||||||
using onaction = std::function<void(GUI*)>;
|
using onaction = std::function<void(GUI&)>;
|
||||||
using onnumberchange = std::function<void(GUI*, double)>;
|
using onnumberchange = std::function<void(GUI&, double)>;
|
||||||
|
|
||||||
class ActionsSet {
|
class ActionsSet {
|
||||||
std::unique_ptr<std::vector<onaction>> callbacks;
|
std::unique_ptr<std::vector<onaction>> callbacks;
|
||||||
@ -32,7 +32,7 @@ namespace gui {
|
|||||||
callbacks->push_back(callback);
|
callbacks->push_back(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void notify(GUI* gui) {
|
void notify(GUI& gui) {
|
||||||
if (callbacks) {
|
if (callbacks) {
|
||||||
for (auto& callback : *callbacks) {
|
for (auto& callback : *callbacks) {
|
||||||
callback(gui);
|
callback(gui);
|
||||||
@ -64,6 +64,9 @@ namespace gui {
|
|||||||
|
|
||||||
/// @brief Base abstract class for all UI elements
|
/// @brief Base abstract class for all UI elements
|
||||||
class UINode : public std::enable_shared_from_this<UINode> {
|
class UINode : public std::enable_shared_from_this<UINode> {
|
||||||
|
protected:
|
||||||
|
GUI& gui;
|
||||||
|
private:
|
||||||
/// @brief element identifier used for direct access in UiDocument
|
/// @brief element identifier used for direct access in UiDocument
|
||||||
std::string id = "";
|
std::string id = "";
|
||||||
/// @brief element enabled state
|
/// @brief element enabled state
|
||||||
@ -118,7 +121,7 @@ namespace gui {
|
|||||||
/// @brief cursor shape when mouse is over the element
|
/// @brief cursor shape when mouse is over the element
|
||||||
CursorShape cursor = CursorShape::ARROW;
|
CursorShape cursor = CursorShape::ARROW;
|
||||||
|
|
||||||
UINode(glm::vec2 size);
|
UINode(GUI& gui, glm::vec2 size);
|
||||||
public:
|
public:
|
||||||
virtual ~UINode();
|
virtual ~UINode();
|
||||||
|
|
||||||
@ -169,12 +172,12 @@ namespace gui {
|
|||||||
virtual UINode* listenAction(const onaction &action);
|
virtual UINode* listenAction(const onaction &action);
|
||||||
virtual UINode* listenDoubleClick(const onaction &action);
|
virtual UINode* listenDoubleClick(const onaction &action);
|
||||||
|
|
||||||
virtual void onFocus(GUI*) {focused = true;}
|
virtual void onFocus() {focused = true;}
|
||||||
virtual void doubleClick(GUI*, int x, int y);
|
virtual void doubleClick(int x, int y);
|
||||||
virtual void click(GUI*, int x, int y);
|
virtual void click(int x, int y);
|
||||||
virtual void clicked(GUI*, mousecode button) {}
|
virtual void clicked(mousecode button) {}
|
||||||
virtual void mouseMove(GUI*, int x, int y) {};
|
virtual void mouseMove(int x, int y) {};
|
||||||
virtual void mouseRelease(GUI*, int x, int y);
|
virtual void mouseRelease(int x, int y);
|
||||||
virtual void scrolled(int value);
|
virtual void scrolled(int value);
|
||||||
|
|
||||||
bool isPressed() const;
|
bool isPressed() const;
|
||||||
|
|||||||
@ -1,37 +1,36 @@
|
|||||||
#include "gui_util.hpp"
|
#include "gui_util.hpp"
|
||||||
|
|
||||||
#include "elements/Label.hpp"
|
|
||||||
#include "elements/Menu.hpp"
|
|
||||||
#include "elements/Button.hpp"
|
|
||||||
#include "elements/TextBox.hpp"
|
|
||||||
#include "gui_xml.hpp"
|
|
||||||
|
|
||||||
#include "logic/scripting/scripting.hpp"
|
|
||||||
#include "frontend/locale.hpp"
|
|
||||||
#include "util/stringutil.hpp"
|
|
||||||
#include "delegates.hpp"
|
|
||||||
|
|
||||||
#include "window/Events.hpp"
|
|
||||||
#include "engine/Engine.hpp"
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "delegates.hpp"
|
||||||
|
#include "elements/Button.hpp"
|
||||||
|
#include "elements/Label.hpp"
|
||||||
|
#include "elements/Menu.hpp"
|
||||||
|
#include "elements/TextBox.hpp"
|
||||||
|
#include "engine/Engine.hpp"
|
||||||
|
#include "frontend/locale.hpp"
|
||||||
|
#include "gui_xml.hpp"
|
||||||
|
#include "logic/scripting/scripting.hpp"
|
||||||
|
#include "util/stringutil.hpp"
|
||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
std::shared_ptr<gui::UINode> guiutil::create(const std::string& source, scriptenv env) {
|
std::shared_ptr<gui::UINode> guiutil::create(
|
||||||
|
GUI& gui, const std::string& source, scriptenv env
|
||||||
|
) {
|
||||||
if (env == nullptr) {
|
if (env == nullptr) {
|
||||||
env = scripting::get_root_environment();
|
env = scripting::get_root_environment();
|
||||||
}
|
}
|
||||||
UiXmlReader reader(env);
|
UiXmlReader reader(gui, env);
|
||||||
return reader.readXML("[string]", source);
|
return reader.readXML("[string]", source);
|
||||||
}
|
}
|
||||||
|
|
||||||
void guiutil::alert(
|
void guiutil::alert(
|
||||||
Engine& engine,
|
Engine& engine, const std::wstring& text, const runnable& on_hidden
|
||||||
const std::wstring& text,
|
|
||||||
const runnable& on_hidden
|
|
||||||
) {
|
) {
|
||||||
|
GUI& gui = engine.getGUI();
|
||||||
auto panel = std::make_shared<Panel>(
|
auto panel = std::make_shared<Panel>(
|
||||||
|
gui,
|
||||||
glm::vec2(
|
glm::vec2(
|
||||||
glm::min(
|
glm::min(
|
||||||
static_cast<size_t>(650),
|
static_cast<size_t>(650),
|
||||||
@ -44,7 +43,7 @@ void guiutil::alert(
|
|||||||
);
|
);
|
||||||
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||||
|
|
||||||
auto menuPtr = engine.getGUI()->getMenu();
|
auto menuPtr = gui.getMenu();
|
||||||
auto& menu = *menuPtr;
|
auto& menu = *menuPtr;
|
||||||
runnable on_hidden_final = [on_hidden, &menu]() {
|
runnable on_hidden_final = [on_hidden, &menu]() {
|
||||||
menu.removePage("<alert>");
|
menu.removePage("<alert>");
|
||||||
@ -55,24 +54,25 @@ void guiutil::alert(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto label = std::make_shared<Label>(text);
|
auto label = std::make_shared<Label>(gui, text);
|
||||||
label->setMultiline(true);
|
label->setMultiline(true);
|
||||||
label->setSize(glm::vec2(1, 24));
|
label->setSize(glm::vec2(1, 24));
|
||||||
label->setAutoResize(true);
|
label->setAutoResize(true);
|
||||||
panel->add(label);
|
panel->add(label);
|
||||||
panel->add(std::make_shared<Button>(
|
panel->add(std::make_shared<Button>(
|
||||||
langs::get(L"Ok"), glm::vec4(10.f),
|
gui,
|
||||||
[on_hidden_final](GUI*) {
|
langs::get(L"Ok"),
|
||||||
on_hidden_final();
|
glm::vec4(10.f),
|
||||||
}
|
[on_hidden_final](GUI&) { on_hidden_final(); }
|
||||||
));
|
));
|
||||||
panel->refresh();
|
panel->refresh();
|
||||||
|
|
||||||
panel->keepAlive(Events::addKeyCallback(keycode::ENTER, [on_hidden_final](){
|
auto& input = engine.getInput();
|
||||||
|
panel->keepAlive(input.addKeyCallback(keycode::ENTER, [on_hidden_final]() {
|
||||||
on_hidden_final();
|
on_hidden_final();
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
panel->keepAlive(Events::addKeyCallback(keycode::ESCAPE, [on_hidden_final](){
|
panel->keepAlive(input.addKeyCallback(keycode::ESCAPE, [on_hidden_final]() {
|
||||||
on_hidden_final();
|
on_hidden_final();
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
@ -91,17 +91,25 @@ void guiutil::confirm(
|
|||||||
if (yestext.empty()) yestext = langs::get(L"Yes");
|
if (yestext.empty()) yestext = langs::get(L"Yes");
|
||||||
if (notext.empty()) notext = langs::get(L"No");
|
if (notext.empty()) notext = langs::get(L"No");
|
||||||
|
|
||||||
auto container = std::make_shared<Container>(glm::vec2(5000, 5000));
|
auto& gui = engine.getGUI();
|
||||||
|
auto& input = engine.getInput();
|
||||||
|
|
||||||
|
auto container = std::make_shared<Container>(gui, glm::vec2(5000, 5000));
|
||||||
container->setColor(glm::vec4(0.05f, 0.05f, 0.05f, 0.7f));
|
container->setColor(glm::vec4(0.05f, 0.05f, 0.05f, 0.7f));
|
||||||
auto panel = std::make_shared<Panel>(glm::vec2(600, 200), glm::vec4(8.0f), 8.0f);
|
|
||||||
|
auto panel = std::make_shared<Panel>(
|
||||||
|
gui, glm::vec2(600, 200), glm::vec4(8.0f), 8.0f
|
||||||
|
);
|
||||||
|
|
||||||
panel->setGravity(Gravity::center_center);
|
panel->setGravity(Gravity::center_center);
|
||||||
container->add(panel);
|
container->add(panel);
|
||||||
|
|
||||||
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||||
panel->add(std::make_shared<Label>(text));
|
panel->add(std::make_shared<Label>(gui, text));
|
||||||
auto subpanel = std::make_shared<Panel>(glm::vec2(600, 53));
|
auto subpanel = std::make_shared<Panel>(gui, glm::vec2(600, 53));
|
||||||
subpanel->setColor(glm::vec4(0));
|
subpanel->setColor(glm::vec4(0));
|
||||||
|
|
||||||
auto menu = engine.getGUI()->getMenu();
|
auto menu = gui.getMenu();
|
||||||
|
|
||||||
runnable on_confirm_final = [on_confirm, menu]() {
|
runnable on_confirm_final = [on_confirm, menu]() {
|
||||||
menu->removePage("<confirm>");
|
menu->removePage("<confirm>");
|
||||||
@ -121,20 +129,20 @@ void guiutil::confirm(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
subpanel->add(std::make_shared<Button>(yestext, glm::vec4(8.f), [=](GUI*){
|
subpanel->add(std::make_shared<Button>(gui, yestext, glm::vec4(8.f), [=](GUI&) {
|
||||||
on_confirm_final();
|
on_confirm_final();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
subpanel->add(std::make_shared<Button>(notext, glm::vec4(8.f), [=](GUI*){
|
subpanel->add(std::make_shared<Button>(gui, notext, glm::vec4(8.f), [=](GUI&) {
|
||||||
on_deny_final();
|
on_deny_final();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
panel->add(subpanel);
|
panel->add(subpanel);
|
||||||
panel->keepAlive(Events::addKeyCallback(keycode::ENTER, [=](){
|
panel->keepAlive(input.addKeyCallback(keycode::ENTER, [=]() {
|
||||||
on_confirm_final();
|
on_confirm_final();
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
panel->keepAlive(Events::addKeyCallback(keycode::ESCAPE, [=](){
|
panel->keepAlive(input.addKeyCallback(keycode::ESCAPE, [=]() {
|
||||||
on_deny_final();
|
on_deny_final();
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
@ -145,21 +153,25 @@ void guiutil::confirm(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void guiutil::confirm_with_memo(
|
void guiutil::confirm_with_memo(
|
||||||
const std::shared_ptr<gui::Menu>& menu,
|
Engine& engine,
|
||||||
const std::wstring& text,
|
const std::wstring& text,
|
||||||
const std::wstring& memo,
|
const std::wstring& memo,
|
||||||
const runnable& on_confirm,
|
const runnable& on_confirm,
|
||||||
std::wstring yestext,
|
std::wstring yestext,
|
||||||
std::wstring notext) {
|
std::wstring notext
|
||||||
|
) {
|
||||||
|
auto& gui = engine.getGUI();
|
||||||
|
auto menu = gui.getMenu();
|
||||||
if (yestext.empty()) yestext = langs::get(L"Yes");
|
if (yestext.empty()) yestext = langs::get(L"Yes");
|
||||||
if (notext.empty()) notext = langs::get(L"No");
|
if (notext.empty()) notext = langs::get(L"No");
|
||||||
|
|
||||||
auto panel = std::make_shared<Panel>(glm::vec2(600, 500), glm::vec4(8.0f), 8.0f);
|
auto panel = std::make_shared<Panel>(
|
||||||
|
gui, glm::vec2(600, 500), glm::vec4(8.0f), 8.0f
|
||||||
|
);
|
||||||
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||||
panel->add(std::make_shared<Label>(text));
|
panel->add(std::make_shared<Label>(gui, text));
|
||||||
|
|
||||||
auto textbox = std::make_shared<TextBox>(L"");
|
auto textbox = std::make_shared<TextBox>(gui, L"");
|
||||||
textbox->setMultiline(true);
|
textbox->setMultiline(true);
|
||||||
textbox->setTextWrapping(true);
|
textbox->setTextWrapping(true);
|
||||||
textbox->setSize(glm::vec2(600, 300));
|
textbox->setSize(glm::vec2(600, 300));
|
||||||
@ -167,16 +179,15 @@ void guiutil::confirm_with_memo(
|
|||||||
textbox->setEditable(false);
|
textbox->setEditable(false);
|
||||||
panel->add(textbox);
|
panel->add(textbox);
|
||||||
|
|
||||||
auto subpanel = std::make_shared<Panel>(glm::vec2(600, 53));
|
auto subpanel = std::make_shared<Panel>(gui, glm::vec2(600, 53));
|
||||||
subpanel->setColor(glm::vec4(0));
|
subpanel->setColor(glm::vec4(0));
|
||||||
|
|
||||||
subpanel->add(std::make_shared<Button>(yestext, glm::vec4(8.f), [=](GUI*){
|
subpanel->add(std::make_shared<Button>(gui, yestext, glm::vec4(8.f), [=](GUI&) {
|
||||||
if (on_confirm)
|
if (on_confirm) on_confirm();
|
||||||
on_confirm();
|
|
||||||
menu->back();
|
menu->back();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
subpanel->add(std::make_shared<Button>(notext, glm::vec4(8.f), [=](GUI*){
|
subpanel->add(std::make_shared<Button>(gui, notext, glm::vec4(8.f), [=](GUI&) {
|
||||||
menu->back();
|
menu->back();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@ -1,38 +1,42 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GUI.hpp"
|
|
||||||
#include "typedefs.hpp"
|
|
||||||
#include "delegates.hpp"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "GUI.hpp"
|
||||||
|
#include "delegates.hpp"
|
||||||
|
#include "typedefs.hpp"
|
||||||
|
|
||||||
class Engine;
|
class Engine;
|
||||||
|
|
||||||
namespace guiutil {
|
namespace guiutil {
|
||||||
/// @brief Create element from XML
|
/// @brief Create element from XML
|
||||||
/// @param source XML
|
/// @param source XML
|
||||||
std::shared_ptr<gui::UINode> create(const std::string& source, scriptenv env=0);
|
std::shared_ptr<gui::UINode> create(
|
||||||
|
gui::GUI& gui, const std::string& source, scriptenv env = 0
|
||||||
|
);
|
||||||
|
|
||||||
void alert(
|
void alert(
|
||||||
Engine& engine,
|
Engine& engine,
|
||||||
const std::wstring& text,
|
const std::wstring& text,
|
||||||
const runnable& on_hidden=nullptr
|
const runnable& on_hidden = nullptr
|
||||||
);
|
);
|
||||||
|
|
||||||
void confirm(
|
void confirm(
|
||||||
Engine& engine,
|
Engine& engine,
|
||||||
const std::wstring& text,
|
const std::wstring& text,
|
||||||
const runnable& on_confirm=nullptr,
|
const runnable& on_confirm = nullptr,
|
||||||
const runnable& on_deny=nullptr,
|
const runnable& on_deny = nullptr,
|
||||||
std::wstring yestext=L"",
|
std::wstring yestext = L"",
|
||||||
std::wstring notext=L"");
|
std::wstring notext = L""
|
||||||
|
);
|
||||||
|
|
||||||
void confirm_with_memo(
|
void confirm_with_memo(
|
||||||
const std::shared_ptr<gui::Menu>& menu,
|
Engine& engine,
|
||||||
const std::wstring& text,
|
const std::wstring& text,
|
||||||
const std::wstring& memo,
|
const std::wstring& memo,
|
||||||
const runnable& on_confirm=nullptr,
|
const runnable& on_confirm = nullptr,
|
||||||
std::wstring yestext=L"",
|
std::wstring yestext = L"",
|
||||||
std::wstring notext=L"");
|
std::wstring notext = L""
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,30 +1,31 @@
|
|||||||
#include "gui_xml.hpp"
|
#include "gui_xml.hpp"
|
||||||
|
|
||||||
#include "elements/Panel.hpp"
|
#include <stdexcept>
|
||||||
#include "elements/Image.hpp"
|
#include <utility>
|
||||||
#include "elements/Menu.hpp"
|
|
||||||
|
#include "GUI.hpp"
|
||||||
#include "elements/Button.hpp"
|
#include "elements/Button.hpp"
|
||||||
#include "elements/Canvas.hpp"
|
#include "elements/Canvas.hpp"
|
||||||
#include "elements/CheckBox.hpp"
|
#include "elements/CheckBox.hpp"
|
||||||
#include "elements/TextBox.hpp"
|
#include "elements/TextBox.hpp"
|
||||||
#include "elements/SplitBox.hpp"
|
#include "elements/SplitBox.hpp"
|
||||||
#include "elements/TrackBar.hpp"
|
#include "elements/TrackBar.hpp"
|
||||||
|
#include "elements/Image.hpp"
|
||||||
#include "elements/InputBindBox.hpp"
|
#include "elements/InputBindBox.hpp"
|
||||||
#include "elements/InventoryView.hpp"
|
#include "elements/InventoryView.hpp"
|
||||||
#include "GUI.hpp"
|
#include "elements/Menu.hpp"
|
||||||
|
#include "elements/Panel.hpp"
|
||||||
|
#include "elements/TextBox.hpp"
|
||||||
|
#include "elements/TrackBar.hpp"
|
||||||
#include "engine/Engine.hpp"
|
#include "engine/Engine.hpp"
|
||||||
|
|
||||||
#include "frontend/menu.hpp"
|
|
||||||
#include "frontend/locale.hpp"
|
#include "frontend/locale.hpp"
|
||||||
|
#include "frontend/menu.hpp"
|
||||||
#include "items/Inventory.hpp"
|
#include "items/Inventory.hpp"
|
||||||
#include "logic/scripting/scripting.hpp"
|
#include "logic/scripting/scripting.hpp"
|
||||||
#include "maths/voxmaths.hpp"
|
#include "maths/voxmaths.hpp"
|
||||||
#include "util/stringutil.hpp"
|
#include "util/stringutil.hpp"
|
||||||
#include "window/Events.hpp"
|
#include "window/Events.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
static Align align_from_string(const std::string& str, Align def) {
|
static Align align_from_string(const std::string& str, Align def) {
|
||||||
@ -80,7 +81,7 @@ static onaction create_action(
|
|||||||
if (callback == nullptr) {
|
if (callback == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return [callback](GUI*) {callback();};
|
return [callback](GUI&) { callback(); };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Read basic UINode properties
|
/// @brief Read basic UINode properties
|
||||||
@ -152,9 +153,7 @@ static void read_uinode(
|
|||||||
node.setAlign(align_from_string(alignName, node.getAlign()));
|
node.setAlign(align_from_string(alignName, node.getAlign()));
|
||||||
|
|
||||||
if (element.has("gravity")) {
|
if (element.has("gravity")) {
|
||||||
node.setGravity(gravity_from_string(
|
node.setGravity(gravity_from_string(element.attr("gravity").getText()));
|
||||||
element.attr("gravity").getText()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.has("tooltip")) {
|
if (element.has("tooltip")) {
|
||||||
@ -184,7 +183,9 @@ static void read_uinode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_container_impl(UiXmlReader& reader, const xml::xmlelement& element, Container& container) {
|
static void read_container_impl(
|
||||||
|
UiXmlReader& reader, const xml::xmlelement& element, Container& container
|
||||||
|
) {
|
||||||
read_uinode(reader, element, container);
|
read_uinode(reader, element, container);
|
||||||
|
|
||||||
if (element.has("scrollable")) {
|
if (element.has("scrollable")) {
|
||||||
@ -194,8 +195,7 @@ static void read_container_impl(UiXmlReader& reader, const xml::xmlelement& elem
|
|||||||
container.setScrollStep(element.attr("scroll-step").asInt());
|
container.setScrollStep(element.attr("scroll-step").asInt());
|
||||||
}
|
}
|
||||||
for (auto& sub : element.getElements()) {
|
for (auto& sub : element.getElements()) {
|
||||||
if (sub->isText())
|
if (sub->isText()) continue;
|
||||||
continue;
|
|
||||||
auto subnode = reader.readUINode(*sub);
|
auto subnode = reader.readUINode(*sub);
|
||||||
if (subnode) {
|
if (subnode) {
|
||||||
container.add(subnode);
|
container.add(subnode);
|
||||||
@ -203,7 +203,9 @@ static void read_container_impl(UiXmlReader& reader, const xml::xmlelement& elem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiXmlReader::readUINode(UiXmlReader& reader, const xml::xmlelement& element, Container& container) {
|
void UiXmlReader::readUINode(
|
||||||
|
UiXmlReader& reader, const xml::xmlelement& element, Container& container
|
||||||
|
) {
|
||||||
read_container_impl(reader, element, container);
|
read_container_impl(reader, element, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,8 +227,7 @@ static void read_base_panel_impl(
|
|||||||
panel.setPadding(padding);
|
panel.setPadding(padding);
|
||||||
glm::vec2 size = panel.getSize();
|
glm::vec2 size = panel.getSize();
|
||||||
panel.setSize(glm::vec2(
|
panel.setSize(glm::vec2(
|
||||||
size.x + padding.x + padding.z,
|
size.x + padding.x + padding.z, size.y + padding.y + padding.w
|
||||||
size.y + padding.y + padding.w
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if (element.has("orientation")) {
|
if (element.has("orientation")) {
|
||||||
@ -254,10 +255,15 @@ static void read_panel_impl(
|
|||||||
if (element.has("min-length")) {
|
if (element.has("min-length")) {
|
||||||
panel.setMinLength(element.attr("min-length").asInt());
|
panel.setMinLength(element.attr("min-length").asInt());
|
||||||
}
|
}
|
||||||
|
if (element.has("orientation")) {
|
||||||
|
auto& oname = element.attr("orientation").getText();
|
||||||
|
if (oname == "horizontal") {
|
||||||
|
panel.setOrientation(Orientation::horizontal);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (subnodes) {
|
if (subnodes) {
|
||||||
for (auto& sub : element.getElements()) {
|
for (auto& sub : element.getElements()) {
|
||||||
if (sub->isText())
|
if (sub->isText()) continue;
|
||||||
continue;
|
|
||||||
auto subnode = reader.readUINode(*sub);
|
auto subnode = reader.readUINode(*sub);
|
||||||
if (subnode) {
|
if (subnode) {
|
||||||
panel.add(subnode);
|
panel.add(subnode);
|
||||||
@ -289,12 +295,12 @@ static std::shared_ptr<UINode> readLabel(
|
|||||||
const UiXmlReader& reader, const xml::xmlelement& element
|
const UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
std::wstring text = parse_inner_text(element, reader.getContext());
|
std::wstring text = parse_inner_text(element, reader.getContext());
|
||||||
auto label = std::make_shared<Label>(text);
|
auto label = std::make_shared<Label>(reader.getGUI(), text);
|
||||||
read_uinode(reader, element, *label);
|
read_uinode(reader, element, *label);
|
||||||
if (element.has("valign")) {
|
if (element.has("valign")) {
|
||||||
label->setVerticalAlign(
|
label->setVerticalAlign(align_from_string(
|
||||||
align_from_string(element.attr("valign").getText(), label->getVerticalAlign())
|
element.attr("valign").getText(), label->getVerticalAlign()
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
if (element.has("supplier")) {
|
if (element.has("supplier")) {
|
||||||
label->textSupplier(scripting::create_wstring_supplier(
|
label->textSupplier(scripting::create_wstring_supplier(
|
||||||
@ -324,7 +330,7 @@ static std::shared_ptr<UINode> readLabel(
|
|||||||
static std::shared_ptr<UINode> read_container(
|
static std::shared_ptr<UINode> read_container(
|
||||||
UiXmlReader& reader, const xml::xmlelement& element
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
auto container = std::make_shared<Container>(glm::vec2());
|
auto container = std::make_shared<Container>(reader.getGUI(), glm::vec2());
|
||||||
read_container_impl(reader, element, *container);
|
read_container_impl(reader, element, *container);
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
@ -337,8 +343,9 @@ static std::shared_ptr<UINode> read_split_box(
|
|||||||
element.attr("orientation", "vertical").getText() == "horizontal"
|
element.attr("orientation", "vertical").getText() == "horizontal"
|
||||||
? Orientation::horizontal
|
? Orientation::horizontal
|
||||||
: Orientation::vertical;
|
: Orientation::vertical;
|
||||||
auto splitBox =
|
auto splitBox = std::make_shared<SplitBox>(
|
||||||
std::make_shared<SplitBox>(glm::vec2(), splitPos, orientation);
|
reader.getGUI(), glm::vec2(), splitPos, orientation
|
||||||
|
);
|
||||||
read_base_panel_impl(reader, element, *splitBox);
|
read_base_panel_impl(reader, element, *splitBox);
|
||||||
for (auto& sub : element.getElements()) {
|
for (auto& sub : element.getElements()) {
|
||||||
if (sub->isText())
|
if (sub->isText())
|
||||||
@ -355,7 +362,9 @@ static std::shared_ptr<UINode> read_panel(
|
|||||||
UiXmlReader& reader, const xml::xmlelement& element
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
float interval = element.attr("interval", "2").asFloat();
|
float interval = element.attr("interval", "2").asFloat();
|
||||||
auto panel = std::make_shared<Panel>(glm::vec2(), glm::vec4(), interval);
|
auto panel = std::make_shared<Panel>(
|
||||||
|
reader.getGUI(), glm::vec2(), glm::vec4(), interval
|
||||||
|
);
|
||||||
read_panel_impl(reader, element, *panel);
|
read_panel_impl(reader, element, *panel);
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
@ -363,6 +372,7 @@ static std::shared_ptr<UINode> read_panel(
|
|||||||
static std::shared_ptr<UINode> read_button(
|
static std::shared_ptr<UINode> read_button(
|
||||||
UiXmlReader& reader, const xml::xmlelement& element
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
|
auto& gui = reader.getGUI();
|
||||||
glm::vec4 padding = element.attr("padding", "10").asVec4();
|
glm::vec4 padding = element.attr("padding", "10").asVec4();
|
||||||
|
|
||||||
std::shared_ptr<Button> button;
|
std::shared_ptr<Button> button;
|
||||||
@ -370,14 +380,14 @@ static std::shared_ptr<UINode> read_button(
|
|||||||
if (!elements.empty() && elements[0]->getTag() != "#") {
|
if (!elements.empty() && elements[0]->getTag() != "#") {
|
||||||
auto inner = reader.readUINode(*elements.at(0));
|
auto inner = reader.readUINode(*elements.at(0));
|
||||||
if (inner != nullptr) {
|
if (inner != nullptr) {
|
||||||
button = std::make_shared<Button>(inner, padding);
|
button = std::make_shared<Button>(gui, inner, padding);
|
||||||
} else {
|
} else {
|
||||||
button = std::make_shared<Button>(L"", padding, nullptr);
|
button = std::make_shared<Button>(gui, L"", padding, nullptr);
|
||||||
}
|
}
|
||||||
read_panel_impl(reader, element, *button, false);
|
read_panel_impl(reader, element, *button, false);
|
||||||
} else {
|
} else {
|
||||||
std::wstring text = parse_inner_text(element, reader.getContext());
|
std::wstring text = parse_inner_text(element, reader.getContext());
|
||||||
button = std::make_shared<Button>(text, padding, nullptr);
|
button = std::make_shared<Button>(gui, text, padding, nullptr);
|
||||||
read_panel_impl(reader, element, *button, true);
|
read_panel_impl(reader, element, *button, true);
|
||||||
}
|
}
|
||||||
if (element.has("text-align")) {
|
if (element.has("text-align")) {
|
||||||
@ -393,7 +403,9 @@ static std::shared_ptr<UINode> read_check_box(
|
|||||||
) {
|
) {
|
||||||
auto text = parse_inner_text(element, reader.getContext());
|
auto text = parse_inner_text(element, reader.getContext());
|
||||||
bool checked = element.attr("checked", "false").asBool();
|
bool checked = element.attr("checked", "false").asBool();
|
||||||
auto checkbox = std::make_shared<FullCheckBox>(text, glm::vec2(32), checked);
|
auto checkbox = std::make_shared<FullCheckBox>(
|
||||||
|
reader.getGUI(), text, glm::vec2(32), checked
|
||||||
|
);
|
||||||
read_panel_impl(reader, element, *checkbox);
|
read_panel_impl(reader, element, *checkbox);
|
||||||
|
|
||||||
if (element.has("consumer")) {
|
if (element.has("consumer")) {
|
||||||
@ -417,10 +429,13 @@ static std::shared_ptr<UINode> read_check_box(
|
|||||||
static std::shared_ptr<UINode> read_text_box(
|
static std::shared_ptr<UINode> read_text_box(
|
||||||
UiXmlReader& reader, const xml::xmlelement& element
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
auto placeholder = util::str2wstr_utf8(element.attr("placeholder", "").getText());
|
auto placeholder =
|
||||||
|
util::str2wstr_utf8(element.attr("placeholder", "").getText());
|
||||||
auto hint = util::str2wstr_utf8(element.attr("hint", "").getText());
|
auto hint = util::str2wstr_utf8(element.attr("hint", "").getText());
|
||||||
auto text = parse_inner_text(element, reader.getContext());
|
auto text = parse_inner_text(element, reader.getContext());
|
||||||
auto textbox = std::make_shared<TextBox>(placeholder, glm::vec4(0.0f));
|
auto textbox = std::make_shared<TextBox>(
|
||||||
|
reader.getGUI(), placeholder, glm::vec4(0.0f)
|
||||||
|
);
|
||||||
textbox->setHint(hint);
|
textbox->setHint(hint);
|
||||||
|
|
||||||
read_container_impl(reader, element, *textbox);
|
read_container_impl(reader, element, *textbox);
|
||||||
@ -429,8 +444,7 @@ static std::shared_ptr<UINode> read_text_box(
|
|||||||
textbox->setPadding(padding);
|
textbox->setPadding(padding);
|
||||||
glm::vec2 size = textbox->getSize();
|
glm::vec2 size = textbox->getSize();
|
||||||
textbox->setSize(glm::vec2(
|
textbox->setSize(glm::vec2(
|
||||||
size.x + padding.x + padding.z,
|
size.x + padding.x + padding.z, size.y + padding.y + padding.w
|
||||||
size.y + padding.y + padding.w
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
textbox->setText(text);
|
textbox->setText(text);
|
||||||
@ -513,7 +527,7 @@ static std::shared_ptr<UINode> read_image(
|
|||||||
const UiXmlReader& reader, const xml::xmlelement& element
|
const UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
std::string src = element.attr("src", "").getText();
|
std::string src = element.attr("src", "").getText();
|
||||||
auto image = std::make_shared<Image>(src);
|
auto image = std::make_shared<Image>(reader.getGUI(), src);
|
||||||
read_uinode(reader, element, *image);
|
read_uinode(reader, element, *image);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
@ -521,11 +535,12 @@ static std::shared_ptr<UINode> read_image(
|
|||||||
static std::shared_ptr<UINode> read_canvas(
|
static std::shared_ptr<UINode> read_canvas(
|
||||||
const UiXmlReader& reader, const xml::xmlelement& element
|
const UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
auto size = glm::uvec2{32, 32};
|
auto size = glm::uvec2 {32, 32};
|
||||||
if (element.has("size")) {
|
if (element.has("size")) {
|
||||||
size = element.attr("size").asVec2();
|
size = element.attr("size").asVec2();
|
||||||
}
|
}
|
||||||
auto image = std::make_shared<Canvas>(ImageFormat::rgba8888, size);
|
auto image =
|
||||||
|
std::make_shared<Canvas>(reader.getGUI(), ImageFormat::rgba8888, size);
|
||||||
read_uinode(reader, element, *image);
|
read_uinode(reader, element, *image);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
@ -540,19 +555,24 @@ static std::shared_ptr<UINode> read_track_bar(
|
|||||||
float def = element.attr("value", "0.0").asFloat();
|
float def = element.attr("value", "0.0").asFloat();
|
||||||
float step = element.attr("step", "1.0").asFloat();
|
float step = element.attr("step", "1.0").asFloat();
|
||||||
int trackWidth = element.attr("track-width", "12").asInt();
|
int trackWidth = element.attr("track-width", "12").asInt();
|
||||||
auto bar = std::make_shared<TrackBar>(minv, maxv, def, step, trackWidth);
|
auto bar = std::make_shared<TrackBar>(
|
||||||
|
reader.getGUI(), minv, maxv, def, step, trackWidth
|
||||||
|
);
|
||||||
read_uinode(reader, element, *bar);
|
read_uinode(reader, element, *bar);
|
||||||
if (element.has("consumer")) {
|
if (element.has("consumer")) {
|
||||||
bar->setConsumer(scripting::create_number_consumer(
|
bar->setConsumer(scripting::create_number_consumer(
|
||||||
env, element.attr("consumer").getText(), file));
|
env, element.attr("consumer").getText(), file
|
||||||
|
));
|
||||||
}
|
}
|
||||||
if (element.has("sub-consumer")) {
|
if (element.has("sub-consumer")) {
|
||||||
bar->setSubConsumer(scripting::create_number_consumer(
|
bar->setSubConsumer(scripting::create_number_consumer(
|
||||||
env, element.attr("sub-consumer").getText(), file));
|
env, element.attr("sub-consumer").getText(), file
|
||||||
|
));
|
||||||
}
|
}
|
||||||
if (element.has("supplier")) {
|
if (element.has("supplier")) {
|
||||||
bar->setSupplier(scripting::create_number_supplier(
|
bar->setSupplier(scripting::create_number_supplier(
|
||||||
env, element.attr("supplier").getText(), file));
|
env, element.attr("supplier").getText(), file
|
||||||
|
));
|
||||||
}
|
}
|
||||||
if (element.has("track-color")) {
|
if (element.has("track-color")) {
|
||||||
bar->setTrackColor(element.attr("track-color").asColor());
|
bar->setTrackColor(element.attr("track-color").asColor());
|
||||||
@ -567,14 +587,11 @@ static std::shared_ptr<UINode> read_input_bind_box(
|
|||||||
UiXmlReader& reader, const xml::xmlelement& element
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
auto bindname = element.attr("binding").getText();
|
auto bindname = element.attr("binding").getText();
|
||||||
auto found = Events::bindings.find(bindname);
|
auto& found = Events::requireBinding(bindname);
|
||||||
if (found == Events::bindings.end()) {
|
|
||||||
throw std::runtime_error("binding does not exists "+util::quote(bindname));
|
|
||||||
}
|
|
||||||
glm::vec4 padding = element.attr("padding", "6").asVec4();
|
glm::vec4 padding = element.attr("padding", "6").asVec4();
|
||||||
auto bindbox = std::make_shared<InputBindBox>(found->second, padding);
|
auto bindbox =
|
||||||
|
std::make_shared<InputBindBox>(reader.getGUI(), found, padding);
|
||||||
read_panel_impl(reader, element, *bindbox);
|
read_panel_impl(reader, element, *bindbox);
|
||||||
|
|
||||||
return bindbox;
|
return bindbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,11 +602,12 @@ static slotcallback read_slot_func(
|
|||||||
const std::string& attr
|
const std::string& attr
|
||||||
) {
|
) {
|
||||||
auto consumer = scripting::create_int_array_consumer(
|
auto consumer = scripting::create_int_array_consumer(
|
||||||
reader.getEnvironment(),
|
reader.getEnvironment(), element.attr(attr).getText()
|
||||||
element.attr(attr).getText()
|
|
||||||
);
|
);
|
||||||
return [=](uint slot, ItemStack&) {
|
return [=](uint slot, ItemStack&) {
|
||||||
int args[] {int(view->getInventory()->getId()), int(slot)};
|
int args[] {
|
||||||
|
static_cast<int>(view->getInventory()->getId()),
|
||||||
|
static_cast<int>(slot)};
|
||||||
consumer(args, 2);
|
consumer(args, 2);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -601,7 +619,9 @@ static void readSlot(
|
|||||||
bool itemSource = element.attr("item-source", "false").asBool();
|
bool itemSource = element.attr("item-source", "false").asBool();
|
||||||
bool taking = element.attr("taking", "true").asBool();
|
bool taking = element.attr("taking", "true").asBool();
|
||||||
bool placing = element.attr("placing", "true").asBool();
|
bool placing = element.attr("placing", "true").asBool();
|
||||||
SlotLayout layout(index, glm::vec2(), true, itemSource, nullptr, nullptr, nullptr);
|
SlotLayout layout(
|
||||||
|
index, glm::vec2(), true, itemSource, nullptr, nullptr, nullptr
|
||||||
|
);
|
||||||
if (element.has("pos")) {
|
if (element.has("pos")) {
|
||||||
layout.position = element.attr("pos").asVec2();
|
layout.position = element.attr("pos").asVec2();
|
||||||
}
|
}
|
||||||
@ -612,7 +632,8 @@ static void readSlot(
|
|||||||
layout.shareFunc = read_slot_func(view, reader, element, "sharefunc");
|
layout.shareFunc = read_slot_func(view, reader, element, "sharefunc");
|
||||||
}
|
}
|
||||||
if (element.has("onrightclick")) {
|
if (element.has("onrightclick")) {
|
||||||
layout.rightClick = read_slot_func(view, reader, element, "onrightclick");
|
layout.rightClick =
|
||||||
|
read_slot_func(view, reader, element, "onrightclick");
|
||||||
}
|
}
|
||||||
layout.taking = taking;
|
layout.taking = taking;
|
||||||
layout.placing = placing;
|
layout.placing = placing;
|
||||||
@ -622,7 +643,9 @@ static void readSlot(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void readSlotsGrid(
|
static void readSlotsGrid(
|
||||||
InventoryView* view, const UiXmlReader& reader, const xml::xmlelement& element
|
InventoryView* view,
|
||||||
|
const UiXmlReader& reader,
|
||||||
|
const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
int startIndex = element.attr("start-index", "0").asInt();
|
int startIndex = element.attr("start-index", "0").asInt();
|
||||||
int rows = element.attr("rows", "0").asInt();
|
int rows = element.attr("rows", "0").asInt();
|
||||||
@ -647,7 +670,9 @@ static void readSlotsGrid(
|
|||||||
count = rows * cols;
|
count = rows * cols;
|
||||||
}
|
}
|
||||||
bool itemSource = element.attr("item-source", "false").asBool();
|
bool itemSource = element.attr("item-source", "false").asBool();
|
||||||
SlotLayout layout(-1, glm::vec2(), true, itemSource, nullptr, nullptr, nullptr);
|
SlotLayout layout(
|
||||||
|
-1, glm::vec2(), true, itemSource, nullptr, nullptr, nullptr
|
||||||
|
);
|
||||||
if (element.has("pos")) {
|
if (element.has("pos")) {
|
||||||
layout.position = element.attr("pos").asVec2();
|
layout.position = element.attr("pos").asVec2();
|
||||||
}
|
}
|
||||||
@ -658,7 +683,8 @@ static void readSlotsGrid(
|
|||||||
layout.shareFunc = read_slot_func(view, reader, element, "sharefunc");
|
layout.shareFunc = read_slot_func(view, reader, element, "sharefunc");
|
||||||
}
|
}
|
||||||
if (element.has("onrightclick")) {
|
if (element.has("onrightclick")) {
|
||||||
layout.rightClick = read_slot_func(view, reader, element, "onrightclick");
|
layout.rightClick =
|
||||||
|
read_slot_func(view, reader, element, "onrightclick");
|
||||||
}
|
}
|
||||||
layout.padding = padding;
|
layout.padding = padding;
|
||||||
layout.taking = taking;
|
layout.taking = taking;
|
||||||
@ -674,7 +700,7 @@ static void readSlotsGrid(
|
|||||||
slotLayout.index = startIndex + idx;
|
slotLayout.index = startIndex + idx;
|
||||||
slotLayout.position += glm::vec2(
|
slotLayout.position += glm::vec2(
|
||||||
padding + col * (slotSize + interval),
|
padding + col * (slotSize + interval),
|
||||||
padding + (rows-row-1) * (slotSize + interval)
|
padding + (rows - row - 1) * (slotSize + interval)
|
||||||
);
|
);
|
||||||
auto slot = view->addSlot(slotLayout);
|
auto slot = view->addSlot(slotLayout);
|
||||||
view->add(slot, slotLayout.position);
|
view->add(slot, slotLayout.position);
|
||||||
@ -685,8 +711,8 @@ static void readSlotsGrid(
|
|||||||
static std::shared_ptr<UINode> read_inventory(
|
static std::shared_ptr<UINode> read_inventory(
|
||||||
UiXmlReader& reader, const xml::xmlelement& element
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
auto view = std::make_shared<InventoryView>();
|
auto view = std::make_shared<InventoryView>(reader.getGUI());
|
||||||
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f)); // todo: fixme
|
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f)); // TODO: fixme
|
||||||
reader.addIgnore("slot");
|
reader.addIgnore("slot");
|
||||||
reader.addIgnore("slots-grid");
|
reader.addIgnore("slots-grid");
|
||||||
reader.readUINode(reader, element, *view);
|
reader.readUINode(reader, element, *view);
|
||||||
@ -704,16 +730,15 @@ static std::shared_ptr<UINode> read_inventory(
|
|||||||
static std::shared_ptr<UINode> read_page_box(
|
static std::shared_ptr<UINode> read_page_box(
|
||||||
UiXmlReader& reader, const xml::xmlelement& element
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
auto menu = std::make_shared<Menu>();
|
auto& gui = reader.getGUI();
|
||||||
menu->setPageLoader(
|
auto menu = std::make_shared<Menu>(gui);
|
||||||
Engine::getInstance().getGUI()->getMenu()->getPageLoader()
|
menu->setPageLoader(gui.getMenu()->getPageLoader());
|
||||||
);
|
|
||||||
read_container_impl(reader, element, *menu);
|
read_container_impl(reader, element, *menu);
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
UiXmlReader::UiXmlReader(const scriptenv& env) : env(env) {
|
UiXmlReader::UiXmlReader(gui::GUI& gui, const scriptenv& env) : gui(gui), env(env) {
|
||||||
contextStack.emplace("");
|
contextStack.emplace("");
|
||||||
add("image", read_image);
|
add("image", read_image);
|
||||||
add("canvas", read_canvas);
|
add("canvas", read_canvas);
|
||||||
@ -742,16 +767,15 @@ void UiXmlReader::addIgnore(const std::string& tag) {
|
|||||||
ignored.insert(tag);
|
ignored.insert(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<UINode> UiXmlReader::readUINode(const xml::xmlelement& element) {
|
std::shared_ptr<UINode> UiXmlReader::readUINode(const xml::xmlelement& element
|
||||||
|
) {
|
||||||
if (element.has("if")) {
|
if (element.has("if")) {
|
||||||
const auto& cond = element.attr("if").getText();
|
const auto& cond = element.attr("if").getText();
|
||||||
if (cond.empty() || cond == "false" || cond == "nil")
|
if (cond.empty() || cond == "false" || cond == "nil") return nullptr;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
if (element.has("ifnot")) {
|
if (element.has("ifnot")) {
|
||||||
const auto& cond = element.attr("ifnot").getText();
|
const auto& cond = element.attr("ifnot").getText();
|
||||||
if (!(cond.empty() || cond == "false" || cond == "nil"))
|
if (!(cond.empty() || cond == "false" || cond == "nil")) return nullptr;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& tag = element.getTag();
|
const std::string& tag = element.getTag();
|
||||||
@ -760,7 +784,7 @@ std::shared_ptr<UINode> UiXmlReader::readUINode(const xml::xmlelement& element)
|
|||||||
if (ignored.find(tag) != ignored.end()) {
|
if (ignored.find(tag) != ignored.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
throw std::runtime_error("unsupported element '"+tag+"'");
|
throw std::runtime_error("unsupported element '" + tag + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hascontext = element.has("context");
|
bool hascontext = element.has("context");
|
||||||
@ -775,8 +799,7 @@ std::shared_ptr<UINode> UiXmlReader::readUINode(const xml::xmlelement& element)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<UINode> UiXmlReader::readXML(
|
std::shared_ptr<UINode> UiXmlReader::readXML(
|
||||||
const std::string& filename,
|
const std::string& filename, const std::string& source
|
||||||
const std::string& source
|
|
||||||
) {
|
) {
|
||||||
this->filename = filename;
|
this->filename = filename;
|
||||||
auto document = xml::parse(filename, source);
|
auto document = xml::parse(filename, source);
|
||||||
@ -784,8 +807,7 @@ std::shared_ptr<UINode> UiXmlReader::readXML(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<UINode> UiXmlReader::readXML(
|
std::shared_ptr<UINode> UiXmlReader::readXML(
|
||||||
const std::string& filename,
|
const std::string& filename, const xml::xmlelement& root
|
||||||
const xml::xmlelement& root
|
|
||||||
) {
|
) {
|
||||||
this->filename = filename;
|
this->filename = filename;
|
||||||
return readUINode(root);
|
return readUINode(root);
|
||||||
@ -802,3 +824,7 @@ const std::string& UiXmlReader::getFilename() const {
|
|||||||
const scriptenv& UiXmlReader::getEnvironment() const {
|
const scriptenv& UiXmlReader::getEnvironment() const {
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gui::GUI& UiXmlReader::getGUI() const {
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
|||||||
@ -15,13 +15,14 @@ namespace gui {
|
|||||||
std::shared_ptr<UINode>(UiXmlReader&, const xml::xmlelement&)>;
|
std::shared_ptr<UINode>(UiXmlReader&, const xml::xmlelement&)>;
|
||||||
|
|
||||||
class UiXmlReader {
|
class UiXmlReader {
|
||||||
|
gui::GUI& gui;
|
||||||
std::unordered_map<std::string, uinode_reader> readers;
|
std::unordered_map<std::string, uinode_reader> readers;
|
||||||
std::unordered_set<std::string> ignored;
|
std::unordered_set<std::string> ignored;
|
||||||
std::stack<std::string> contextStack;
|
std::stack<std::string> contextStack;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
const scriptenv& env;
|
const scriptenv& env;
|
||||||
public:
|
public:
|
||||||
UiXmlReader(const scriptenv& env);
|
UiXmlReader(gui::GUI& gui, const scriptenv& env);
|
||||||
|
|
||||||
void add(const std::string& tag, uinode_reader reader);
|
void add(const std::string& tag, uinode_reader reader);
|
||||||
bool hasReader(const std::string& tag) const;
|
bool hasReader(const std::string& tag) const;
|
||||||
@ -54,5 +55,6 @@ namespace gui {
|
|||||||
const std::string& getContext() const;
|
const std::string& getContext() const;
|
||||||
const scriptenv& getEnvironment() const;
|
const scriptenv& getEnvironment() const;
|
||||||
const std::string& getFilename() const;
|
const std::string& getFilename() const;
|
||||||
|
gui::GUI& getGUI() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ void EngineController::deleteWorld(const std::string& name) {
|
|||||||
logger.info() << "deleting " << folder.string();
|
logger.info() << "deleting " << folder.string();
|
||||||
io::remove_all(folder);
|
io::remove_all(folder);
|
||||||
if (!engine.isHeadless()) {
|
if (!engine.isHeadless()) {
|
||||||
engine.getGUI()->getMenu()->back();
|
engine.getGUI().getMenu()->back();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ static void show_convert_request(
|
|||||||
text += util::str2wstr_utf8(line) + L"\n";
|
text += util::str2wstr_utf8(line) + L"\n";
|
||||||
}
|
}
|
||||||
guiutil::confirm_with_memo(
|
guiutil::confirm_with_memo(
|
||||||
engine.getGUI()->getMenu(),
|
engine,
|
||||||
langs::get(message),
|
langs::get(message),
|
||||||
text,
|
text,
|
||||||
on_confirm,
|
on_confirm,
|
||||||
|
|||||||
@ -4,9 +4,10 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "BlocksController.hpp"
|
||||||
#include "content/Content.hpp"
|
#include "content/Content.hpp"
|
||||||
#include "core_defs.hpp"
|
#include "core_defs.hpp"
|
||||||
#include "settings.hpp"
|
#include "engine/Engine.hpp"
|
||||||
#include "items/Inventory.hpp"
|
#include "items/Inventory.hpp"
|
||||||
#include "items/ItemDef.hpp"
|
#include "items/ItemDef.hpp"
|
||||||
#include "items/ItemStack.hpp"
|
#include "items/ItemStack.hpp"
|
||||||
@ -16,17 +17,15 @@
|
|||||||
#include "objects/Players.hpp"
|
#include "objects/Players.hpp"
|
||||||
#include "physics/Hitbox.hpp"
|
#include "physics/Hitbox.hpp"
|
||||||
#include "physics/PhysicsSolver.hpp"
|
#include "physics/PhysicsSolver.hpp"
|
||||||
|
#include "scripting/scripting.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "voxels/Block.hpp"
|
#include "voxels/Block.hpp"
|
||||||
#include "voxels/Chunks.hpp"
|
#include "voxels/Chunks.hpp"
|
||||||
#include "voxels/voxel.hpp"
|
#include "voxels/voxel.hpp"
|
||||||
#include "window/Camera.hpp"
|
#include "window/Camera.hpp"
|
||||||
#include "window/Events.hpp"
|
|
||||||
#include "window/Window.hpp"
|
#include "window/Window.hpp"
|
||||||
#include "window/input.hpp"
|
#include "window/input.hpp"
|
||||||
#include "world/Level.hpp"
|
#include "world/Level.hpp"
|
||||||
#include "BlocksController.hpp"
|
|
||||||
#include "scripting/scripting.hpp"
|
|
||||||
|
|
||||||
const float INTERACTION_RELOAD = 0.160f;
|
const float INTERACTION_RELOAD = 0.160f;
|
||||||
const float STEPS_SPEED = 2.2f;
|
const float STEPS_SPEED = 2.2f;
|
||||||
@ -40,9 +39,7 @@ const float RUN_ZOOM = 1.1f;
|
|||||||
const float C_ZOOM = 0.1f;
|
const float C_ZOOM = 0.1f;
|
||||||
const float CROUCH_SHIFT_Y = -0.2f;
|
const float CROUCH_SHIFT_Y = -0.2f;
|
||||||
|
|
||||||
CameraControl::CameraControl(
|
CameraControl::CameraControl(Player& player, const CameraSettings& settings)
|
||||||
Player& player, const CameraSettings& settings
|
|
||||||
)
|
|
||||||
: player(player),
|
: player(player),
|
||||||
camera(player.fpCamera),
|
camera(player.fpCamera),
|
||||||
settings(settings),
|
settings(settings),
|
||||||
@ -70,7 +67,9 @@ void CameraControl::updateMouse(PlayerInput& input) {
|
|||||||
(input.zoom ? settings.sensitivity.get() / 4.f
|
(input.zoom ? settings.sensitivity.get() / 4.f
|
||||||
: settings.sensitivity.get());
|
: settings.sensitivity.get());
|
||||||
|
|
||||||
auto d = glm::degrees(Events::delta / (float)Window::height * sensitivity);
|
auto d = glm::degrees(
|
||||||
|
input.delta / static_cast<float>(Window::height) * sensitivity
|
||||||
|
);
|
||||||
rotation.x -= d.x;
|
rotation.x -= d.x;
|
||||||
rotation.y -= d.y;
|
rotation.y -= d.y;
|
||||||
|
|
||||||
@ -147,15 +146,16 @@ void CameraControl::updateFovEffects(
|
|||||||
// more extensible but uglier
|
// more extensible but uglier
|
||||||
void CameraControl::switchCamera() {
|
void CameraControl::switchCamera() {
|
||||||
const std::vector<std::shared_ptr<Camera>> playerCameras {
|
const std::vector<std::shared_ptr<Camera>> playerCameras {
|
||||||
camera, player.tpCamera, player.spCamera
|
camera, player.tpCamera, player.spCamera};
|
||||||
};
|
|
||||||
|
|
||||||
auto index = std::distance(
|
auto index = std::distance(
|
||||||
playerCameras.begin(),
|
playerCameras.begin(),
|
||||||
std::find_if(
|
std::find_if(
|
||||||
playerCameras.begin(),
|
playerCameras.begin(),
|
||||||
playerCameras.end(),
|
playerCameras.end(),
|
||||||
[this](auto& ptr) { return ptr.get() == player.currentCamera.get(); }
|
[this](auto& ptr) {
|
||||||
|
return ptr.get() == player.currentCamera.get();
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
if (static_cast<size_t>(index) != playerCameras.size()) {
|
if (static_cast<size_t>(index) != playerCameras.size()) {
|
||||||
@ -205,8 +205,8 @@ void CameraControl::update(
|
|||||||
tpCamera->front = camera->front;
|
tpCamera->front = camera->front;
|
||||||
tpCamera->right = camera->right;
|
tpCamera->right = camera->right;
|
||||||
}
|
}
|
||||||
if (player.currentCamera == spCamera ||
|
if (player.currentCamera == spCamera || player.currentCamera == tpCamera ||
|
||||||
player.currentCamera == tpCamera || player.currentCamera == camera) {
|
player.currentCamera == camera) {
|
||||||
player.currentCamera->setFov(glm::radians(settings.fov.get()));
|
player.currentCamera->setFov(glm::radians(settings.fov.get()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,10 +239,7 @@ void PlayerController::onFootstep(const Hitbox& hitbox) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
blocksController.onBlockInteraction(
|
blocksController.onBlockInteraction(
|
||||||
&player,
|
&player, glm::ivec3(x, y, z), def, BlockInteraction::step
|
||||||
glm::ivec3(x, y, z),
|
|
||||||
def,
|
|
||||||
BlockInteraction::step
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -265,9 +262,9 @@ void PlayerController::updateFootsteps(float delta) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::update(float delta, bool input) {
|
void PlayerController::update(float delta, const Input* inputEvents) {
|
||||||
if (input) {
|
if (inputEvents) {
|
||||||
updateKeyboard();
|
updateKeyboard(*inputEvents);
|
||||||
player.updateSelectedEntity();
|
player.updateSelectedEntity();
|
||||||
} else {
|
} else {
|
||||||
resetKeyboard();
|
resetKeyboard();
|
||||||
@ -275,7 +272,7 @@ void PlayerController::update(float delta, bool input) {
|
|||||||
updatePlayer(delta);
|
updatePlayer(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::postUpdate(float delta, bool input, bool pause) {
|
void PlayerController::postUpdate(float delta, const Input* input, bool pause) {
|
||||||
if (!pause) {
|
if (!pause) {
|
||||||
updateFootsteps(delta);
|
updateFootsteps(delta);
|
||||||
}
|
}
|
||||||
@ -287,23 +284,25 @@ void PlayerController::postUpdate(float delta, bool input, bool pause) {
|
|||||||
player.postUpdate();
|
player.postUpdate();
|
||||||
camControl.update(this->input, pause ? 0.0f : delta, *player.chunks);
|
camControl.update(this->input, pause ? 0.0f : delta, *player.chunks);
|
||||||
if (input) {
|
if (input) {
|
||||||
updateInteraction(delta);
|
updateInteraction(*input, delta);
|
||||||
} else {
|
} else {
|
||||||
player.selection = {};
|
player.selection = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::updateKeyboard() {
|
void PlayerController::updateKeyboard(const Input& inputEvents) {
|
||||||
input.moveForward = Events::active(BIND_MOVE_FORWARD);
|
const auto& bindings = inputEvents.getBindings();
|
||||||
input.moveBack = Events::active(BIND_MOVE_BACK);
|
input.moveForward = bindings.active(BIND_MOVE_FORWARD);
|
||||||
input.moveLeft = Events::active(BIND_MOVE_LEFT);
|
input.moveBack = bindings.active(BIND_MOVE_BACK);
|
||||||
input.moveRight = Events::active(BIND_MOVE_RIGHT);
|
input.moveLeft = bindings.active(BIND_MOVE_LEFT);
|
||||||
input.sprint = Events::active(BIND_MOVE_SPRINT);
|
input.moveRight = bindings.active(BIND_MOVE_RIGHT);
|
||||||
input.shift = Events::active(BIND_MOVE_CROUCH);
|
input.sprint = bindings.active(BIND_MOVE_SPRINT);
|
||||||
input.cheat = Events::active(BIND_MOVE_CHEAT);
|
input.shift = bindings.active(BIND_MOVE_CROUCH);
|
||||||
input.jump = Events::active(BIND_MOVE_JUMP);
|
input.cheat = bindings.active(BIND_MOVE_CHEAT);
|
||||||
input.zoom = Events::active(BIND_CAM_ZOOM);
|
input.jump = bindings.active(BIND_MOVE_JUMP);
|
||||||
input.cameraMode = Events::jactive(BIND_CAM_MODE);
|
input.zoom = bindings.active(BIND_CAM_ZOOM);
|
||||||
|
input.cameraMode = bindings.jactive(BIND_CAM_MODE);
|
||||||
|
input.delta = inputEvents.getCursor().delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::resetKeyboard() {
|
void PlayerController::resetKeyboard() {
|
||||||
@ -316,6 +315,7 @@ void PlayerController::resetKeyboard() {
|
|||||||
input.shift = false;
|
input.shift = false;
|
||||||
input.cheat = false;
|
input.cheat = false;
|
||||||
input.jump = false;
|
input.jump = false;
|
||||||
|
input.delta = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::updatePlayer(float delta) {
|
void PlayerController::updatePlayer(float delta) {
|
||||||
@ -328,18 +328,12 @@ static int determine_rotation(
|
|||||||
if (def && def->rotatable) {
|
if (def && def->rotatable) {
|
||||||
const std::string& name = def->rotations.name;
|
const std::string& name = def->rotations.name;
|
||||||
if (name == "pipe") {
|
if (name == "pipe") {
|
||||||
if (norm.x < 0.0f)
|
if (norm.x < 0.0f) return BLOCK_DIR_WEST;
|
||||||
return BLOCK_DIR_WEST;
|
if (norm.x > 0.0f) return BLOCK_DIR_EAST;
|
||||||
if (norm.x > 0.0f)
|
if (norm.y > 0.0f) return BLOCK_DIR_UP;
|
||||||
return BLOCK_DIR_EAST;
|
if (norm.y < 0.0f) return BLOCK_DIR_DOWN;
|
||||||
if (norm.y > 0.0f)
|
if (norm.z > 0.0f) return BLOCK_DIR_NORTH;
|
||||||
return BLOCK_DIR_UP;
|
if (norm.z < 0.0f) return BLOCK_DIR_SOUTH;
|
||||||
if (norm.y < 0.0f)
|
|
||||||
return BLOCK_DIR_DOWN;
|
|
||||||
if (norm.z > 0.0f)
|
|
||||||
return BLOCK_DIR_NORTH;
|
|
||||||
if (norm.z < 0.0f)
|
|
||||||
return BLOCK_DIR_SOUTH;
|
|
||||||
} else if (name == "pane") {
|
} else if (name == "pane") {
|
||||||
if (abs(camDir.x) > abs(camDir.z)) {
|
if (abs(camDir.x) > abs(camDir.z)) {
|
||||||
if (camDir.x > 0.0f) return BLOCK_DIR_EAST;
|
if (camDir.x > 0.0f) return BLOCK_DIR_EAST;
|
||||||
@ -417,7 +411,9 @@ voxel* PlayerController::updateSelection(float maxDistance) {
|
|||||||
return vox;
|
return vox;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::processRightClick(const Block& def, const Block& target) {
|
void PlayerController::processRightClick(
|
||||||
|
const Block& def, const Block& target
|
||||||
|
) {
|
||||||
const auto& selection = player.selection;
|
const auto& selection = player.selection;
|
||||||
auto& chunks = *player.chunks;
|
auto& chunks = *player.chunks;
|
||||||
auto camera = player.fpCamera.get();
|
auto camera = player.fpCamera.get();
|
||||||
@ -427,8 +423,8 @@ void PlayerController::processRightClick(const Block& def, const Block& target)
|
|||||||
|
|
||||||
if (!input.shift && target.rt.funcsset.oninteract) {
|
if (!input.shift && target.rt.funcsset.oninteract) {
|
||||||
if (scripting::on_block_interact(
|
if (scripting::on_block_interact(
|
||||||
&player, target, selection.actualPosition
|
&player, target, selection.actualPosition
|
||||||
)) {
|
)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -443,7 +439,8 @@ void PlayerController::processRightClick(const Block& def, const Block& target)
|
|||||||
if (def.obstacle) {
|
if (def.obstacle) {
|
||||||
const auto& hitboxes = def.rt.hitboxes[state.rotation];
|
const auto& hitboxes = def.rt.hitboxes[state.rotation];
|
||||||
for (const AABB& blockAABB : hitboxes) {
|
for (const AABB& blockAABB : hitboxes) {
|
||||||
if (level.entities->hasBlockingInside(blockAABB.translated(coord))) {
|
if (level.entities->hasBlockingInside(blockAABB.translated(coord)
|
||||||
|
)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,7 +463,7 @@ void PlayerController::processRightClick(const Block& def, const Block& target)
|
|||||||
if (chosenBlock != vox->id && chosenBlock) {
|
if (chosenBlock != vox->id && chosenBlock) {
|
||||||
if (!player.isInfiniteItems()) {
|
if (!player.isInfiniteItems()) {
|
||||||
auto& slot = player.getInventory()->getSlot(player.getChosenSlot());
|
auto& slot = player.getInventory()->getSlot(player.getChosenSlot());
|
||||||
slot.setCount(slot.getCount()-1);
|
slot.setCount(slot.getCount() - 1);
|
||||||
}
|
}
|
||||||
blocksController.placeBlock(
|
blocksController.placeBlock(
|
||||||
&player, def, state, coord.x, coord.y, coord.z
|
&player, def, state, coord.x, coord.y, coord.z
|
||||||
@ -490,21 +487,22 @@ void PlayerController::updateEntityInteraction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::updateInteraction(float delta) {
|
void PlayerController::updateInteraction(const Input& inputEvents, float delta) {
|
||||||
auto indices = level.content.getIndices();
|
auto indices = level.content.getIndices();
|
||||||
const auto& selection = player.selection;
|
const auto& selection = player.selection;
|
||||||
|
|
||||||
if (interactionTimer > 0.0f) {
|
if (interactionTimer > 0.0f) {
|
||||||
interactionTimer -= delta;
|
interactionTimer -= delta;
|
||||||
}
|
}
|
||||||
bool xkey = Events::active(BIND_PLAYER_FAST_INTERACTOIN);
|
const auto& bindings = inputEvents.getBindings();
|
||||||
|
bool xkey = bindings.active(BIND_PLAYER_FAST_INTERACTOIN);
|
||||||
float maxDistance = xkey ? 200.0f : 10.0f;
|
float maxDistance = xkey ? 200.0f : 10.0f;
|
||||||
bool longInteraction = interactionTimer <= 0 || xkey;
|
bool longInteraction = interactionTimer <= 0 || xkey;
|
||||||
bool lclick = Events::jactive(BIND_PLAYER_DESTROY) ||
|
bool lclick = bindings.jactive(BIND_PLAYER_DESTROY) ||
|
||||||
(longInteraction && Events::active(BIND_PLAYER_DESTROY));
|
(longInteraction && bindings.active(BIND_PLAYER_DESTROY));
|
||||||
bool lattack = Events::jactive(BIND_PLAYER_ATTACK);
|
bool lattack = bindings.jactive(BIND_PLAYER_ATTACK);
|
||||||
bool rclick = Events::jactive(BIND_PLAYER_BUILD) ||
|
bool rclick = bindings.jactive(BIND_PLAYER_BUILD) ||
|
||||||
(longInteraction && Events::active(BIND_PLAYER_BUILD));
|
(longInteraction && bindings.active(BIND_PLAYER_BUILD));
|
||||||
if (lclick || rclick) {
|
if (lclick || rclick) {
|
||||||
interactionTimer = INTERACTION_RELOAD;
|
interactionTimer = INTERACTION_RELOAD;
|
||||||
}
|
}
|
||||||
@ -527,8 +525,8 @@ void PlayerController::updateInteraction(float delta) {
|
|||||||
auto iend = selection.position;
|
auto iend = selection.position;
|
||||||
if (lclick && !input.shift && item.rt.funcsset.on_block_break_by) {
|
if (lclick && !input.shift && item.rt.funcsset.on_block_break_by) {
|
||||||
if (scripting::on_item_break_block(
|
if (scripting::on_item_break_block(
|
||||||
&player, item, iend.x, iend.y, iend.z
|
&player, item, iend.x, iend.y, iend.z
|
||||||
)) {
|
)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include "objects/Player.hpp"
|
#include "objects/Player.hpp"
|
||||||
#include "util/Clock.hpp"
|
#include "util/Clock.hpp"
|
||||||
|
|
||||||
|
class Input;
|
||||||
class Engine;
|
class Engine;
|
||||||
class Camera;
|
class Camera;
|
||||||
class Level;
|
class Level;
|
||||||
@ -54,11 +55,11 @@ class PlayerController {
|
|||||||
BlocksController& blocksController;
|
BlocksController& blocksController;
|
||||||
float interactionTimer = 0.0f;
|
float interactionTimer = 0.0f;
|
||||||
|
|
||||||
void updateKeyboard();
|
void updateKeyboard(const Input& inputEvents);
|
||||||
void resetKeyboard();
|
void resetKeyboard();
|
||||||
void updatePlayer(float delta);
|
void updatePlayer(float delta);
|
||||||
void updateEntityInteraction(entityid_t eid, bool lclick, bool rclick);
|
void updateEntityInteraction(entityid_t eid, bool lclick, bool rclick);
|
||||||
void updateInteraction(float delta);
|
void updateInteraction(const Input& inputEvents, float delta);
|
||||||
|
|
||||||
float stepsTimer = 0.0f;
|
float stepsTimer = 0.0f;
|
||||||
void onFootstep(const Hitbox& hitbox);
|
void onFootstep(const Hitbox& hitbox);
|
||||||
@ -76,13 +77,13 @@ public:
|
|||||||
|
|
||||||
/// @brief Called after blocks update if not paused
|
/// @brief Called after blocks update if not paused
|
||||||
/// @param delta delta time
|
/// @param delta delta time
|
||||||
/// @param input process user input
|
/// @param inputEvents nullable window inputs
|
||||||
void update(float delta, bool input);
|
void update(float delta, const Input* inputEvents);
|
||||||
|
|
||||||
/// @brief Called after whole level update
|
/// @brief Called after whole level update
|
||||||
/// @param delta delta time
|
/// @param delta delta time
|
||||||
/// @param input process user input
|
/// @param inputEvents nullable window inputs
|
||||||
/// @param pause is game paused
|
/// @param pause is game paused
|
||||||
void postUpdate(float delta, bool input, bool pause);
|
void postUpdate(float delta, const Input* inputEvents, bool pause);
|
||||||
Player* getPlayer();
|
Player* getPlayer();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -14,7 +14,7 @@ static int l_add_command(lua::State* L) {
|
|||||||
lua::pushvalue(L, 3);
|
lua::pushvalue(L, 3);
|
||||||
auto func = lua::create_lambda(L);
|
auto func = lua::create_lambda(L);
|
||||||
try {
|
try {
|
||||||
engine->getCommandsInterpreter()->getRepository()->add(
|
engine->getCmd().getRepository()->add(
|
||||||
scheme,
|
scheme,
|
||||||
description,
|
description,
|
||||||
[func](auto, auto args, auto kwargs) {
|
[func](auto, auto args, auto kwargs) {
|
||||||
@ -32,7 +32,7 @@ static int l_add_command(lua::State* L) {
|
|||||||
static int l_execute(lua::State* L) {
|
static int l_execute(lua::State* L) {
|
||||||
auto prompt = lua::require_string(L, 1);
|
auto prompt = lua::require_string(L, 1);
|
||||||
try {
|
try {
|
||||||
auto result = engine->getCommandsInterpreter()->execute(prompt);
|
auto result = engine->getCmd().execute(prompt);
|
||||||
lua::pushvalue(L, result);
|
lua::pushvalue(L, result);
|
||||||
return 1;
|
return 1;
|
||||||
} catch (const parsing_error& err) {
|
} catch (const parsing_error& err) {
|
||||||
@ -45,19 +45,18 @@ static int l_execute(lua::State* L) {
|
|||||||
|
|
||||||
static int l_get(lua::State* L) {
|
static int l_get(lua::State* L) {
|
||||||
auto name = lua::require_string(L, 1);
|
auto name = lua::require_string(L, 1);
|
||||||
return lua::pushvalue(L, (*engine->getCommandsInterpreter())[name]);
|
return lua::pushvalue(L, engine->getCmd()[name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_set(lua::State* L) {
|
static int l_set(lua::State* L) {
|
||||||
auto name = lua::require_string(L, 1);
|
auto name = lua::require_string(L, 1);
|
||||||
auto value = lua::tovalue(L, 2);
|
auto value = lua::tovalue(L, 2);
|
||||||
(*engine->getCommandsInterpreter())[name] = value;
|
engine->getCmd()[name] = value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_get_commands_list(lua::State* L) {
|
static int l_get_commands_list(lua::State* L) {
|
||||||
auto interpreter = engine->getCommandsInterpreter();
|
auto repo = engine->getCmd().getRepository();
|
||||||
auto repo = interpreter->getRepository();
|
|
||||||
const auto& commands = repo->getCommands();
|
const auto& commands = repo->getCommands();
|
||||||
|
|
||||||
lua::createtable(L, commands.size(), 0);
|
lua::createtable(L, commands.size(), 0);
|
||||||
@ -71,8 +70,7 @@ static int l_get_commands_list(lua::State* L) {
|
|||||||
|
|
||||||
static int l_get_command_info(lua::State* L) {
|
static int l_get_command_info(lua::State* L) {
|
||||||
auto name = lua::require_string(L, 1);
|
auto name = lua::require_string(L, 1);
|
||||||
auto interpreter = engine->getCommandsInterpreter();
|
auto repo = engine->getCmd().getRepository();
|
||||||
auto repo = interpreter->getRepository();
|
|
||||||
auto command = repo->get(name);
|
auto command = repo->get(name);
|
||||||
if (command == nullptr) {
|
if (command == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -17,7 +17,6 @@
|
|||||||
#include "logic/LevelController.hpp"
|
#include "logic/LevelController.hpp"
|
||||||
#include "util/listutil.hpp"
|
#include "util/listutil.hpp"
|
||||||
#include "util/platform.hpp"
|
#include "util/platform.hpp"
|
||||||
#include "window/Events.hpp"
|
|
||||||
#include "world/Level.hpp"
|
#include "world/Level.hpp"
|
||||||
#include "world/generator/WorldGenerator.hpp"
|
#include "world/generator/WorldGenerator.hpp"
|
||||||
|
|
||||||
|
|||||||
@ -80,8 +80,9 @@ static int l_container_add(lua::State* L) {
|
|||||||
}
|
}
|
||||||
auto xmlsrc = lua::require_string(L, 2);
|
auto xmlsrc = lua::require_string(L, 2);
|
||||||
try {
|
try {
|
||||||
auto subnode =
|
auto subnode = guiutil::create(
|
||||||
guiutil::create(xmlsrc, docnode.document->getEnvironment());
|
engine->getGUI(), xmlsrc, docnode.document->getEnvironment()
|
||||||
|
);
|
||||||
node->add(subnode);
|
node->add(subnode);
|
||||||
UINode::getIndices(subnode, docnode.document->getMapWriteable());
|
UINode::getIndices(subnode, docnode.document->getMapWriteable());
|
||||||
} catch (const std::exception& err) {
|
} catch (const std::exception& err) {
|
||||||
@ -93,7 +94,7 @@ static int l_container_add(lua::State* L) {
|
|||||||
static int l_node_destruct(lua::State* L) {
|
static int l_node_destruct(lua::State* L) {
|
||||||
auto docnode = get_document_node(L);
|
auto docnode = get_document_node(L);
|
||||||
auto node = docnode.node;
|
auto node = docnode.node;
|
||||||
engine->getGUI()->postRunnable([node]() {
|
engine->getGUI().postRunnable([node]() {
|
||||||
auto parent = node->getParent();
|
auto parent = node->getParent();
|
||||||
if (auto container = dynamic_cast<Container*>(parent)) {
|
if (auto container = dynamic_cast<Container*>(parent)) {
|
||||||
container->remove(node.get());
|
container->remove(node.get());
|
||||||
@ -651,7 +652,7 @@ static void p_set_focused(
|
|||||||
const std::shared_ptr<UINode>& node, lua::State* L, int idx
|
const std::shared_ptr<UINode>& node, lua::State* L, int idx
|
||||||
) {
|
) {
|
||||||
if (lua::toboolean(L, idx) && !node->isFocused()) {
|
if (lua::toboolean(L, idx) && !node->isFocused()) {
|
||||||
engine->getGUI()->setFocus(node);
|
engine->getGUI().setFocus(node);
|
||||||
} else if (node->isFocused()) {
|
} else if (node->isFocused()) {
|
||||||
node->defocus();
|
node->defocus();
|
||||||
}
|
}
|
||||||
@ -782,7 +783,7 @@ static int l_gui_get_locales_info(lua::State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int l_gui_getviewport(lua::State* L) {
|
static int l_gui_getviewport(lua::State* L) {
|
||||||
return lua::pushvec2(L, engine->getGUI()->getContainer()->getSize());
|
return lua::pushvec2(L, engine->getGUI().getContainer()->getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_gui_clear_markup(lua::State* L) {
|
static int l_gui_clear_markup(lua::State* L) {
|
||||||
@ -845,6 +846,7 @@ static int l_gui_load_document(lua::State* L) {
|
|||||||
auto args = lua::tovalue(L, 3);
|
auto args = lua::tovalue(L, 3);
|
||||||
|
|
||||||
auto documentPtr = UiDocument::read(
|
auto documentPtr = UiDocument::read(
|
||||||
|
engine->getGUI(),
|
||||||
scripting::get_root_environment(),
|
scripting::get_root_environment(),
|
||||||
alias,
|
alias,
|
||||||
filename,
|
filename,
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include "engine/Engine.hpp"
|
#include "engine/Engine.hpp"
|
||||||
#include "io/io.hpp"
|
|
||||||
#include "frontend/hud.hpp"
|
#include "frontend/hud.hpp"
|
||||||
#include "frontend/screens/Screen.hpp"
|
#include "frontend/screens/Screen.hpp"
|
||||||
#include "graphics/ui/GUI.hpp"
|
#include "graphics/ui/GUI.hpp"
|
||||||
#include "graphics/ui/elements/Container.hpp"
|
#include "graphics/ui/elements/Container.hpp"
|
||||||
|
#include "io/io.hpp"
|
||||||
|
#include "libgui.hpp"
|
||||||
#include "util/stringutil.hpp"
|
#include "util/stringutil.hpp"
|
||||||
#include "window/Events.hpp"
|
#include "window/Events.hpp"
|
||||||
#include "window/input.hpp"
|
#include "window/input.hpp"
|
||||||
#include "libgui.hpp"
|
|
||||||
|
|
||||||
namespace scripting {
|
namespace scripting {
|
||||||
extern Hud* hud;
|
extern Hud* hud;
|
||||||
@ -38,25 +38,25 @@ static int l_add_callback(lua::State* L) {
|
|||||||
auto actual_callback = lua::create_simple_handler(L);
|
auto actual_callback = lua::create_simple_handler(L);
|
||||||
observer_handler handler;
|
observer_handler handler;
|
||||||
|
|
||||||
|
auto& gui = engine->getGUI();
|
||||||
|
auto& input = engine->getInput();
|
||||||
|
|
||||||
if (pos != std::string::npos) {
|
if (pos != std::string::npos) {
|
||||||
std::string prefix = bindname.substr(0, pos);
|
std::string prefix = bindname.substr(0, pos);
|
||||||
if (prefix == "key") {
|
if (prefix == "key") {
|
||||||
auto key = input_util::keycode_from(bindname.substr(pos + 1));
|
auto key = input_util::keycode_from(bindname.substr(pos + 1));
|
||||||
handler = Events::addKeyCallback(key, actual_callback);
|
handler = input.addKeyCallback(key, actual_callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto callback = [=]() -> bool {
|
auto callback = [&gui, actual_callback]() -> bool {
|
||||||
if (!scripting::engine->getGUI()->isFocusCaught()) {
|
if (!gui.isFocusCaught()) {
|
||||||
return actual_callback();
|
return actual_callback();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if (handler == nullptr) {
|
if (handler == nullptr) {
|
||||||
const auto& bind = Events::bindings.find(bindname);
|
auto& bind = input.requireBinding(bindname);
|
||||||
if (bind == Events::bindings.end()) {
|
handler = bind.onactived.add(callback);
|
||||||
throw std::runtime_error("unknown binding " + util::quote(bindname));
|
|
||||||
}
|
|
||||||
handler = bind->second.onactived.add(callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hud) {
|
if (hud) {
|
||||||
@ -64,7 +64,8 @@ static int l_add_callback(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
} else if (lua::gettop(L) >= 3) {
|
} else if (lua::gettop(L) >= 3) {
|
||||||
auto node = get_document_node(L, 3);
|
auto node = get_document_node(L, 3);
|
||||||
if (auto container = std::dynamic_pointer_cast<gui::Container>(node.node)) {
|
if (auto container =
|
||||||
|
std::dynamic_pointer_cast<gui::Container>(node.node)) {
|
||||||
container->keepAlive(handler);
|
container->keepAlive(handler);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -74,11 +75,11 @@ static int l_add_callback(lua::State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int l_get_mouse_pos(lua::State* L) {
|
static int l_get_mouse_pos(lua::State* L) {
|
||||||
return lua::pushvec2(L, Events::cursor);
|
return lua::pushvec2(L, engine->getInput().getCursor().pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_get_bindings(lua::State* L) {
|
static int l_get_bindings(lua::State* L) {
|
||||||
auto& bindings = Events::bindings;
|
const auto& bindings = engine->getInput().getBindings().getAll();
|
||||||
lua::createtable(L, bindings.size(), 0);
|
lua::createtable(L, bindings.size(), 0);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -92,25 +93,14 @@ static int l_get_bindings(lua::State* L) {
|
|||||||
|
|
||||||
static int l_get_binding_text(lua::State* L) {
|
static int l_get_binding_text(lua::State* L) {
|
||||||
auto bindname = lua::require_string(L, 1);
|
auto bindname = lua::require_string(L, 1);
|
||||||
auto index = Events::bindings.find(bindname);
|
const auto& bind = engine->getInput().requireBinding(bindname);
|
||||||
|
return lua::pushstring(L, bind.text());
|
||||||
if (index == Events::bindings.end()) {
|
|
||||||
throw std::runtime_error("unknown binding " + util::quote(bindname));
|
|
||||||
lua::pushstring(L, "");
|
|
||||||
} else {
|
|
||||||
lua::pushstring(L, index->second.text());
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_is_active(lua::State* L) {
|
static int l_is_active(lua::State* L) {
|
||||||
auto bindname = lua::require_string(L, 1);
|
auto bindname = lua::require_string(L, 1);
|
||||||
const auto& bind = Events::bindings.find(bindname);
|
auto& bind = engine->getInput().requireBinding(bindname);
|
||||||
if (bind == Events::bindings.end()) {
|
return lua::pushboolean(L, bind.active());
|
||||||
throw std::runtime_error("unknown binding " + util::quote(bindname));
|
|
||||||
}
|
|
||||||
return lua::pushboolean(L, bind->second.active());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_is_pressed(lua::State* L) {
|
static int l_is_pressed(lua::State* L) {
|
||||||
@ -123,12 +113,11 @@ static int l_is_pressed(lua::State* L) {
|
|||||||
auto name = code.substr(sep + 1);
|
auto name = code.substr(sep + 1);
|
||||||
if (prefix == "key") {
|
if (prefix == "key") {
|
||||||
return lua::pushboolean(
|
return lua::pushboolean(
|
||||||
L, Events::pressed(static_cast<int>(input_util::keycode_from(name)))
|
L, engine->getInput().pressed(input_util::keycode_from(name))
|
||||||
);
|
);
|
||||||
} else if (prefix == "mouse") {
|
} else if (prefix == "mouse") {
|
||||||
return lua::pushboolean(
|
return lua::pushboolean(
|
||||||
L,
|
L, engine->getInput().clicked(input_util::mousecode_from(name))
|
||||||
Events::clicked(static_cast<int>(input_util::mousecode_from(name)))
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("unknown input type " + util::quote(code));
|
throw std::runtime_error("unknown input type " + util::quote(code));
|
||||||
@ -140,9 +129,7 @@ static void reset_pack_bindings(const io::path& packFolder) {
|
|||||||
auto bindsFile = configFolder / "bindings.toml";
|
auto bindsFile = configFolder / "bindings.toml";
|
||||||
if (io::is_regular_file(bindsFile)) {
|
if (io::is_regular_file(bindsFile)) {
|
||||||
Events::loadBindings(
|
Events::loadBindings(
|
||||||
bindsFile.string(),
|
bindsFile.string(), io::read_string(bindsFile), BindType::REBIND
|
||||||
io::read_string(bindsFile),
|
|
||||||
BindType::REBIND
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,12 +144,8 @@ static int l_reset_bindings(lua::State*) {
|
|||||||
|
|
||||||
static int l_set_enabled(lua::State* L) {
|
static int l_set_enabled(lua::State* L) {
|
||||||
std::string bindname = lua::require_string(L, 1);
|
std::string bindname = lua::require_string(L, 1);
|
||||||
bool enable = lua::toboolean(L, 2);
|
bool enabled = lua::toboolean(L, 2);
|
||||||
const auto& bind = Events::bindings.find(bindname);
|
engine->getInput().requireBinding(bindname).enabled = enabled;
|
||||||
if (bind == Events::bindings.end()) {
|
|
||||||
throw std::runtime_error("unknown binding " + util::quote(bindname));
|
|
||||||
}
|
|
||||||
Events::bindings[bindname].enable = enable;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,13 +6,13 @@
|
|||||||
|
|
||||||
using namespace scripting;
|
using namespace scripting;
|
||||||
|
|
||||||
static int l_get(lua::State* L) {
|
static int l_get(lua::State* L, network::Network& network) {
|
||||||
std::string url(lua::require_lstring(L, 1));
|
std::string url(lua::require_lstring(L, 1));
|
||||||
|
|
||||||
lua::pushvalue(L, 2);
|
lua::pushvalue(L, 2);
|
||||||
auto onResponse = lua::create_lambda_nothrow(L);
|
auto onResponse = lua::create_lambda_nothrow(L);
|
||||||
|
|
||||||
engine->getNetwork().get(url, [onResponse](std::vector<char> bytes) {
|
network.get(url, [onResponse](std::vector<char> bytes) {
|
||||||
engine->postRunnable([=]() {
|
engine->postRunnable([=]() {
|
||||||
onResponse({std::string(bytes.data(), bytes.size())});
|
onResponse({std::string(bytes.data(), bytes.size())});
|
||||||
});
|
});
|
||||||
@ -20,13 +20,13 @@ static int l_get(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_get_binary(lua::State* L) {
|
static int l_get_binary(lua::State* L, network::Network& network) {
|
||||||
std::string url(lua::require_lstring(L, 1));
|
std::string url(lua::require_lstring(L, 1));
|
||||||
|
|
||||||
lua::pushvalue(L, 2);
|
lua::pushvalue(L, 2);
|
||||||
auto onResponse = lua::create_lambda_nothrow(L);
|
auto onResponse = lua::create_lambda_nothrow(L);
|
||||||
|
|
||||||
engine->getNetwork().get(url, [onResponse](std::vector<char> bytes) {
|
network.get(url, [onResponse](std::vector<char> bytes) {
|
||||||
auto buffer = std::make_shared<util::Buffer<ubyte>>(
|
auto buffer = std::make_shared<util::Buffer<ubyte>>(
|
||||||
reinterpret_cast<const ubyte*>(bytes.data()), bytes.size()
|
reinterpret_cast<const ubyte*>(bytes.data()), bytes.size()
|
||||||
);
|
);
|
||||||
@ -37,7 +37,7 @@ static int l_get_binary(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_post(lua::State* L) {
|
static int l_post(lua::State* L, network::Network& network) {
|
||||||
std::string url(lua::require_lstring(L, 1));
|
std::string url(lua::require_lstring(L, 1));
|
||||||
auto data = lua::tovalue(L, 2);
|
auto data = lua::tovalue(L, 2);
|
||||||
|
|
||||||
@ -61,12 +61,12 @@ static int l_post(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_connect(lua::State* L) {
|
static int l_connect(lua::State* L, network::Network& network) {
|
||||||
std::string address = lua::require_string(L, 1);
|
std::string address = lua::require_string(L, 1);
|
||||||
int port = lua::tointeger(L, 2);
|
int port = lua::tointeger(L, 2);
|
||||||
lua::pushvalue(L, 3);
|
lua::pushvalue(L, 3);
|
||||||
auto callback = lua::create_lambda_nothrow(L);
|
auto callback = lua::create_lambda_nothrow(L);
|
||||||
u64id_t id = engine->getNetwork().connect(address, port, [callback](u64id_t id) {
|
u64id_t id = network.connect(address, port, [callback](u64id_t id) {
|
||||||
engine->postRunnable([=]() {
|
engine->postRunnable([=]() {
|
||||||
callback({id});
|
callback({id});
|
||||||
});
|
});
|
||||||
@ -75,25 +75,25 @@ static int l_connect(lua::State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int l_close(lua::State* L) {
|
static int l_close(lua::State* L, network::Network& network) {
|
||||||
u64id_t id = lua::tointeger(L, 1);
|
u64id_t id = lua::tointeger(L, 1);
|
||||||
if (auto connection = engine->getNetwork().getConnection(id)) {
|
if (auto connection = network.getConnection(id)) {
|
||||||
connection->close(true);
|
connection->close(true);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_closeserver(lua::State* L) {
|
static int l_closeserver(lua::State* L, network::Network& network) {
|
||||||
u64id_t id = lua::tointeger(L, 1);
|
u64id_t id = lua::tointeger(L, 1);
|
||||||
if (auto server = engine->getNetwork().getServer(id)) {
|
if (auto server = network.getServer(id)) {
|
||||||
server->close();
|
server->close();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_send(lua::State* L) {
|
static int l_send(lua::State* L, network::Network& network) {
|
||||||
u64id_t id = lua::tointeger(L, 1);
|
u64id_t id = lua::tointeger(L, 1);
|
||||||
auto connection = engine->getNetwork().getConnection(id);
|
auto connection = network.getConnection(id);
|
||||||
if (connection == nullptr ||
|
if (connection == nullptr ||
|
||||||
connection->getState() == network::ConnectionState::CLOSED) {
|
connection->getState() == network::ConnectionState::CLOSED) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -120,7 +120,7 @@ static int l_send(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_recv(lua::State* L) {
|
static int l_recv(lua::State* L, network::Network& network) {
|
||||||
u64id_t id = lua::tointeger(L, 1);
|
u64id_t id = lua::tointeger(L, 1);
|
||||||
int length = lua::tointeger(L, 2);
|
int length = lua::tointeger(L, 2);
|
||||||
auto connection = engine->getNetwork().getConnection(id);
|
auto connection = engine->getNetwork().getConnection(id);
|
||||||
@ -149,19 +149,19 @@ static int l_recv(lua::State* L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_available(lua::State* L) {
|
static int l_available(lua::State* L, network::Network& network) {
|
||||||
u64id_t id = lua::tointeger(L, 1);
|
u64id_t id = lua::tointeger(L, 1);
|
||||||
if (auto connection = engine->getNetwork().getConnection(id)) {
|
if (auto connection = network.getConnection(id)) {
|
||||||
return lua::pushinteger(L, connection->available());
|
return lua::pushinteger(L, connection->available());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_open(lua::State* L) {
|
static int l_open(lua::State* L, network::Network& network) {
|
||||||
int port = lua::tointeger(L, 1);
|
int port = lua::tointeger(L, 1);
|
||||||
lua::pushvalue(L, 2);
|
lua::pushvalue(L, 2);
|
||||||
auto callback = lua::create_lambda_nothrow(L);
|
auto callback = lua::create_lambda_nothrow(L);
|
||||||
u64id_t id = engine->getNetwork().openServer(port, [callback](u64id_t id) {
|
u64id_t id = network.openServer(port, [callback](u64id_t id) {
|
||||||
engine->postRunnable([=]() {
|
engine->postRunnable([=]() {
|
||||||
callback({id});
|
callback({id});
|
||||||
});
|
});
|
||||||
@ -169,9 +169,9 @@ static int l_open(lua::State* L) {
|
|||||||
return lua::pushinteger(L, id);
|
return lua::pushinteger(L, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_is_alive(lua::State* L) {
|
static int l_is_alive(lua::State* L, network::Network& network) {
|
||||||
u64id_t id = lua::tointeger(L, 1);
|
u64id_t id = lua::tointeger(L, 1);
|
||||||
if (auto connection = engine->getNetwork().getConnection(id)) {
|
if (auto connection = network.getConnection(id)) {
|
||||||
return lua::pushboolean(
|
return lua::pushboolean(
|
||||||
L,
|
L,
|
||||||
connection->getState() != network::ConnectionState::CLOSED ||
|
connection->getState() != network::ConnectionState::CLOSED ||
|
||||||
@ -181,9 +181,9 @@ static int l_is_alive(lua::State* L) {
|
|||||||
return lua::pushboolean(L, false);
|
return lua::pushboolean(L, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_is_connected(lua::State* L) {
|
static int l_is_connected(lua::State* L, network::Network& network) {
|
||||||
u64id_t id = lua::tointeger(L, 1);
|
u64id_t id = lua::tointeger(L, 1);
|
||||||
if (auto connection = engine->getNetwork().getConnection(id)) {
|
if (auto connection = network.getConnection(id)) {
|
||||||
return lua::pushboolean(
|
return lua::pushboolean(
|
||||||
L, connection->getState() == network::ConnectionState::CONNECTED
|
L, connection->getState() == network::ConnectionState::CONNECTED
|
||||||
);
|
);
|
||||||
@ -191,9 +191,9 @@ static int l_is_connected(lua::State* L) {
|
|||||||
return lua::pushboolean(L, false);
|
return lua::pushboolean(L, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_get_address(lua::State* L) {
|
static int l_get_address(lua::State* L, network::Network& network) {
|
||||||
u64id_t id = lua::tointeger(L, 1);
|
u64id_t id = lua::tointeger(L, 1);
|
||||||
if (auto connection = engine->getNetwork().getConnection(id)) {
|
if (auto connection = network.getConnection(id)) {
|
||||||
lua::pushstring(L, connection->getAddress());
|
lua::pushstring(L, connection->getAddress());
|
||||||
lua::pushinteger(L, connection->getPort());
|
lua::pushinteger(L, connection->getPort());
|
||||||
return 2;
|
return 2;
|
||||||
@ -201,47 +201,65 @@ static int l_get_address(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_is_serveropen(lua::State* L) {
|
static int l_is_serveropen(lua::State* L, network::Network& network) {
|
||||||
u64id_t id = lua::tointeger(L, 1);
|
u64id_t id = lua::tointeger(L, 1);
|
||||||
if (auto server = engine->getNetwork().getServer(id)) {
|
if (auto server = network.getServer(id)) {
|
||||||
return lua::pushboolean(L, server->isOpen());
|
return lua::pushboolean(L, server->isOpen());
|
||||||
}
|
}
|
||||||
return lua::pushboolean(L, false);
|
return lua::pushboolean(L, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_get_serverport(lua::State* L) {
|
static int l_get_serverport(lua::State* L, network::Network& network) {
|
||||||
u64id_t id = lua::tointeger(L, 1);
|
u64id_t id = lua::tointeger(L, 1);
|
||||||
if (auto server = engine->getNetwork().getServer(id)) {
|
if (auto server = network.getServer(id)) {
|
||||||
return lua::pushinteger(L, server->getPort());
|
return lua::pushinteger(L, server->getPort());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_get_total_upload(lua::State* L) {
|
static int l_get_total_upload(lua::State* L, network::Network& network) {
|
||||||
return lua::pushinteger(L, engine->getNetwork().getTotalUpload());
|
return lua::pushinteger(L, network.getTotalUpload());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_get_total_download(lua::State* L) {
|
static int l_get_total_download(lua::State* L, network::Network& network) {
|
||||||
return lua::pushinteger(L, engine->getNetwork().getTotalDownload());
|
return lua::pushinteger(L, network.getTotalDownload());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <int(*func)(lua::State*, network::Network&)>
|
||||||
|
int wrap(lua_State* L) {
|
||||||
|
int result = 0;
|
||||||
|
try {
|
||||||
|
result = func(L, engine->getNetwork());
|
||||||
|
}
|
||||||
|
// transform exception with description into lua_error
|
||||||
|
catch (std::exception& e) {
|
||||||
|
luaL_error(L, e.what());
|
||||||
|
}
|
||||||
|
// Rethrow any other exception (lua error for example)
|
||||||
|
catch (...) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const luaL_Reg networklib[] = {
|
const luaL_Reg networklib[] = {
|
||||||
{"get", lua::wrap<l_get>},
|
{"get", wrap<l_get>},
|
||||||
{"get_binary", lua::wrap<l_get_binary>},
|
{"get_binary", wrap<l_get_binary>},
|
||||||
{"post", lua::wrap<l_post>},
|
{"post", wrap<l_post>},
|
||||||
{"get_total_upload", lua::wrap<l_get_total_upload>},
|
{"get_total_upload", wrap<l_get_total_upload>},
|
||||||
{"get_total_download", lua::wrap<l_get_total_download>},
|
{"get_total_download", wrap<l_get_total_download>},
|
||||||
{"__open", lua::wrap<l_open>},
|
{"__open", wrap<l_open>},
|
||||||
{"__closeserver", lua::wrap<l_closeserver>},
|
{"__closeserver", wrap<l_closeserver>},
|
||||||
{"__connect", lua::wrap<l_connect>},
|
{"__connect", wrap<l_connect>},
|
||||||
{"__close", lua::wrap<l_close>},
|
{"__close", wrap<l_close>},
|
||||||
{"__send", lua::wrap<l_send>},
|
{"__send", wrap<l_send>},
|
||||||
{"__recv", lua::wrap<l_recv>},
|
{"__recv", wrap<l_recv>},
|
||||||
{"__available", lua::wrap<l_available>},
|
{"__available", wrap<l_available>},
|
||||||
{"__is_alive", lua::wrap<l_is_alive>},
|
{"__is_alive", wrap<l_is_alive>},
|
||||||
{"__is_connected", lua::wrap<l_is_connected>},
|
{"__is_connected", wrap<l_is_connected>},
|
||||||
{"__get_address", lua::wrap<l_get_address>},
|
{"__get_address", wrap<l_get_address>},
|
||||||
{"__is_serveropen", lua::wrap<l_is_serveropen>},
|
{"__is_serveropen", wrap<l_is_serveropen>},
|
||||||
{"__get_serverport", lua::wrap<l_get_serverport>},
|
{"__get_serverport", wrap<l_get_serverport>},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -259,7 +259,7 @@ static int l_pack_request_writeable(lua::State* L) {
|
|||||||
util::replaceAll(str, L"%{0}", util::str2wstr_utf8(packid));
|
util::replaceAll(str, L"%{0}", util::str2wstr_utf8(packid));
|
||||||
guiutil::confirm(*engine, str, [packid, handler]() {
|
guiutil::confirm(*engine, str, [packid, handler]() {
|
||||||
handler({engine->getPaths().createWriteablePackDevice(packid)});
|
handler({engine->getPaths().createWriteablePackDevice(packid)});
|
||||||
engine->getGUI()->getMenu()->reset();
|
engine->getGUI().getMenu()->reset();
|
||||||
});
|
});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -268,21 +268,21 @@ void scripting::on_world_load(LevelController* controller) {
|
|||||||
lua::call_nothrow(L, 0, 0);
|
lua::call_nothrow(L, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& pack : scripting::engine->getAllContentPacks()) {
|
for (auto& pack : Engine::getInstance().getAllContentPacks()) {
|
||||||
lua::emit_event(L, pack.id + ":.worldopen");
|
lua::emit_event(L, pack.id + ":.worldopen");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::on_world_tick() {
|
void scripting::on_world_tick() {
|
||||||
auto L = lua::get_main_state();
|
auto L = lua::get_main_state();
|
||||||
for (auto& pack : scripting::engine->getAllContentPacks()) {
|
for (auto& pack : Engine::getInstance().getAllContentPacks()) {
|
||||||
lua::emit_event(L, pack.id + ":.worldtick");
|
lua::emit_event(L, pack.id + ":.worldtick");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::on_world_save() {
|
void scripting::on_world_save() {
|
||||||
auto L = lua::get_main_state();
|
auto L = lua::get_main_state();
|
||||||
for (auto& pack : scripting::engine->getAllContentPacks()) {
|
for (auto& pack : Engine::getInstance().getAllContentPacks()) {
|
||||||
lua::emit_event(L, pack.id + ":.worldsave");
|
lua::emit_event(L, pack.id + ":.worldsave");
|
||||||
}
|
}
|
||||||
if (lua::getglobal(L, "__vc_on_world_save")) {
|
if (lua::getglobal(L, "__vc_on_world_save")) {
|
||||||
@ -292,7 +292,7 @@ void scripting::on_world_save() {
|
|||||||
|
|
||||||
void scripting::on_world_quit() {
|
void scripting::on_world_quit() {
|
||||||
auto L = lua::get_main_state();
|
auto L = lua::get_main_state();
|
||||||
for (auto& pack : scripting::engine->getAllContentPacks()) {
|
for (auto& pack : Engine::getInstance().getAllContentPacks()) {
|
||||||
lua::emit_event(L, pack.id + ":.worldquit");
|
lua::emit_event(L, pack.id + ":.worldquit");
|
||||||
}
|
}
|
||||||
if (lua::getglobal(L, "__vc_on_world_quit")) {
|
if (lua::getglobal(L, "__vc_on_world_quit")) {
|
||||||
@ -308,7 +308,7 @@ void scripting::on_world_quit() {
|
|||||||
void scripting::cleanup() {
|
void scripting::cleanup() {
|
||||||
auto L = lua::get_main_state();
|
auto L = lua::get_main_state();
|
||||||
lua::requireglobal(L, "pack");
|
lua::requireglobal(L, "pack");
|
||||||
for (auto& pack : scripting::engine->getAllContentPacks()) {
|
for (auto& pack : Engine::getInstance().getAllContentPacks()) {
|
||||||
lua::requirefield(L, "unload");
|
lua::requirefield(L, "unload");
|
||||||
lua::pushstring(L, pack.id);
|
lua::pushstring(L, pack.id);
|
||||||
lua::call_nothrow(L, 1);
|
lua::call_nothrow(L, 1);
|
||||||
|
|||||||
@ -44,7 +44,7 @@ void scripting::on_frontend_init(Hud* hud, WorldRenderer* renderer) {
|
|||||||
lua::call_nothrow(L, 0, 0);
|
lua::call_nothrow(L, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& pack : engine->getAllContentPacks()) {
|
for (auto& pack : Engine::getInstance().getAllContentPacks()) {
|
||||||
lua::emit_event(
|
lua::emit_event(
|
||||||
lua::get_main_state(),
|
lua::get_main_state(),
|
||||||
pack.id + ":.hudopen",
|
pack.id + ":.hudopen",
|
||||||
@ -56,7 +56,7 @@ void scripting::on_frontend_init(Hud* hud, WorldRenderer* renderer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void scripting::on_frontend_render() {
|
void scripting::on_frontend_render() {
|
||||||
for (auto& pack : engine->getAllContentPacks()) {
|
for (auto& pack : Engine::getInstance().getAllContentPacks()) {
|
||||||
lua::emit_event(
|
lua::emit_event(
|
||||||
lua::get_main_state(),
|
lua::get_main_state(),
|
||||||
pack.id + ":.hudrender",
|
pack.id + ":.hudrender",
|
||||||
@ -67,7 +67,7 @@ void scripting::on_frontend_render() {
|
|||||||
|
|
||||||
void scripting::on_frontend_close() {
|
void scripting::on_frontend_close() {
|
||||||
auto L = lua::get_main_state();
|
auto L = lua::get_main_state();
|
||||||
for (auto& pack : engine->getAllContentPacks()) {
|
for (auto& pack : Engine::getInstance().getAllContentPacks()) {
|
||||||
lua::emit_event(
|
lua::emit_event(
|
||||||
L,
|
L,
|
||||||
pack.id + ":.hudclose",
|
pack.id + ":.hudclose",
|
||||||
@ -109,7 +109,7 @@ gui::PageLoaderFunc scripting::create_page_loader() {
|
|||||||
auto func = lua::create_lambda(L);
|
auto func = lua::create_lambda(L);
|
||||||
return [func](const std::string& name) -> std::shared_ptr<gui::UINode> {
|
return [func](const std::string& name) -> std::shared_ptr<gui::UINode> {
|
||||||
auto docname = func({name}).asString();
|
auto docname = func({name}).asString();
|
||||||
return engine->getAssets()->require<UiDocument>(docname).getRoot();
|
return Engine::getInstance().getAssets()->require<UiDocument>(docname).getRoot();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@ -260,7 +260,7 @@ std::unique_ptr<GeneratorScript> scripting::load_generator(
|
|||||||
const io::path& file,
|
const io::path& file,
|
||||||
const std::string& dirPath
|
const std::string& dirPath
|
||||||
) {
|
) {
|
||||||
auto L = create_state(engine->getPaths(), StateType::GENERATOR);
|
auto L = create_state(Engine::getInstance().getPaths(), StateType::GENERATOR);
|
||||||
|
|
||||||
return std::make_unique<LuaGeneratorScript>(L, def, file, dirPath);
|
return std::make_unique<LuaGeneratorScript>(L, def, file, dirPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,16 +18,19 @@ struct Hitbox;
|
|||||||
struct EngineSettings;
|
struct EngineSettings;
|
||||||
|
|
||||||
struct PlayerInput {
|
struct PlayerInput {
|
||||||
bool zoom : 1;
|
struct {
|
||||||
bool cameraMode : 1;
|
bool zoom : 1;
|
||||||
bool moveForward : 1;
|
bool cameraMode : 1;
|
||||||
bool moveBack : 1;
|
bool moveForward : 1;
|
||||||
bool moveRight : 1;
|
bool moveBack : 1;
|
||||||
bool moveLeft : 1;
|
bool moveRight : 1;
|
||||||
bool sprint : 1;
|
bool moveLeft : 1;
|
||||||
bool shift : 1;
|
bool sprint : 1;
|
||||||
bool cheat : 1;
|
bool shift : 1;
|
||||||
bool jump : 1;
|
bool cheat : 1;
|
||||||
|
bool jump : 1;
|
||||||
|
};
|
||||||
|
glm::vec2 delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CursorSelection {
|
struct CursorSelection {
|
||||||
|
|||||||
@ -28,7 +28,6 @@ void Camera::rotate(float x, float y, float z) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Camera::getProjection() const {
|
glm::mat4 Camera::getProjection() const {
|
||||||
constexpr float epsilon = 1e-6f;
|
|
||||||
if (perspective) {
|
if (perspective) {
|
||||||
return glm::perspective(fov * zoom, ar, near, far);
|
return glm::perspective(fov * zoom, ar, near, far);
|
||||||
} else if (flipped) {
|
} else if (flipped) {
|
||||||
|
|||||||
@ -28,7 +28,7 @@ glm::vec2 Events::cursor = {};
|
|||||||
|
|
||||||
std::vector<uint> Events::codepoints;
|
std::vector<uint> Events::codepoints;
|
||||||
std::vector<keycode> Events::pressedKeys;
|
std::vector<keycode> Events::pressedKeys;
|
||||||
std::unordered_map<std::string, Binding> Events::bindings;
|
Bindings Events::bindings {};
|
||||||
|
|
||||||
int Events::getScroll() {
|
int Events::getScroll() {
|
||||||
return scroll;
|
return scroll;
|
||||||
@ -86,9 +86,9 @@ void Events::pollEvents() {
|
|||||||
pressedKeys.clear();
|
pressedKeys.clear();
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
for (auto& entry : bindings) {
|
for (auto& entry : bindings.getAll()) {
|
||||||
auto& binding = entry.second;
|
auto& binding = entry.second;
|
||||||
if (!binding.enable) {
|
if (!binding.enabled) {
|
||||||
binding.state = false;
|
binding.state = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -119,12 +119,15 @@ void Events::pollEvents() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding& Events::getBinding(const std::string& name) {
|
Binding* Events::getBinding(const std::string& name) {
|
||||||
const auto found = bindings.find(name);
|
return bindings.get(name);
|
||||||
if (found == bindings.end()) {
|
}
|
||||||
throw std::runtime_error("binding '" + name + "' does not exist");
|
|
||||||
|
Binding& Events::requireBinding(const std::string& name) {
|
||||||
|
if (const auto found = getBinding(name)) {
|
||||||
|
return *found;
|
||||||
}
|
}
|
||||||
return found->second;
|
throw std::runtime_error("binding '" + name + "' does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::bind(const std::string& name, inputtype type, keycode code) {
|
void Events::bind(const std::string& name, inputtype type, keycode code) {
|
||||||
@ -136,31 +139,19 @@ void Events::bind(const std::string& name, inputtype type, mousecode code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Events::bind(const std::string& name, inputtype type, int code) {
|
void Events::bind(const std::string& name, inputtype type, int code) {
|
||||||
bindings.try_emplace(name, Binding(type, code));
|
bindings.bind(name, type, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::rebind(const std::string& name, inputtype type, int code) {
|
void Events::rebind(const std::string& name, inputtype type, int code) {
|
||||||
const auto& found = bindings.find(name);
|
requireBinding(name) = Binding(type, code);
|
||||||
if (found == bindings.end()) {
|
|
||||||
throw std::runtime_error("binding '" + name + "' does not exist");
|
|
||||||
}
|
|
||||||
bindings[name] = Binding(type, code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Events::active(const std::string& name) {
|
bool Events::active(const std::string& name) {
|
||||||
const auto& found = bindings.find(name);
|
return bindings.active(name);
|
||||||
if (found == bindings.end()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return found->second.active();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Events::jactive(const std::string& name) {
|
bool Events::jactive(const std::string& name) {
|
||||||
const auto& found = bindings.find(name);
|
return bindings.jactive(name);
|
||||||
if (found == bindings.end()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return found->second.jactive();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::setKey(int key, bool b) {
|
void Events::setKey(int key, bool b) {
|
||||||
@ -198,7 +189,7 @@ observer_handler Events::addKeyCallback(keycode key, KeyCallback callback) {
|
|||||||
|
|
||||||
std::string Events::writeBindings() {
|
std::string Events::writeBindings() {
|
||||||
auto obj = dv::object();
|
auto obj = dv::object();
|
||||||
for (auto& entry : Events::bindings) {
|
for (auto& entry : bindings.getAll()) {
|
||||||
const auto& binding = entry.second;
|
const auto& binding = entry.second;
|
||||||
std::string value;
|
std::string value;
|
||||||
switch (binding.type) {
|
switch (binding.type) {
|
||||||
@ -253,9 +244,8 @@ void Events::loadBindings(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Events::enableBindings() {
|
void Events::enableBindings() {
|
||||||
for (auto& entry : bindings) {
|
for (auto& entry : bindings.getAll()) {
|
||||||
auto& binding = entry.second;
|
entry.second.enabled = true;
|
||||||
binding.enable = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ namespace Events {
|
|||||||
extern glm::vec2 cursor;
|
extern glm::vec2 cursor;
|
||||||
extern std::vector<uint> codepoints;
|
extern std::vector<uint> codepoints;
|
||||||
extern std::vector<keycode> pressedKeys;
|
extern std::vector<keycode> pressedKeys;
|
||||||
extern std::unordered_map<std::string, Binding> bindings;
|
extern Bindings bindings;
|
||||||
|
|
||||||
void pollEvents();
|
void pollEvents();
|
||||||
|
|
||||||
@ -39,7 +39,8 @@ namespace Events {
|
|||||||
|
|
||||||
void toggleCursor();
|
void toggleCursor();
|
||||||
|
|
||||||
Binding& getBinding(const std::string& name);
|
Binding* getBinding(const std::string& name);
|
||||||
|
Binding& requireBinding(const std::string& name);
|
||||||
void bind(const std::string& name, inputtype type, keycode code);
|
void bind(const std::string& name, inputtype type, keycode code);
|
||||||
void bind(const std::string& name, inputtype type, mousecode code);
|
void bind(const std::string& name, inputtype type, mousecode code);
|
||||||
void bind(const std::string& name, inputtype type, int code);
|
void bind(const std::string& name, inputtype type, int code);
|
||||||
|
|||||||
@ -175,7 +175,61 @@ static void glfw_error_callback(int error, const char* description) {
|
|||||||
|
|
||||||
static GLFWcursor* standard_cursors[static_cast<int>(CursorShape::LAST) + 1] = {};
|
static GLFWcursor* standard_cursors[static_cast<int>(CursorShape::LAST) + 1] = {};
|
||||||
|
|
||||||
int Window::initialize(DisplaySettings* settings) {
|
class GLFWInput : public Input {
|
||||||
|
public:
|
||||||
|
void pollEvents() override {
|
||||||
|
Events::pollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* getClipboardText() const override {
|
||||||
|
return glfwGetClipboardString(::window);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getScroll() override {
|
||||||
|
return Events::getScroll();
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding& requireBinding(const std::string& name) override {
|
||||||
|
return Events::requireBinding(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pressed(keycode keycode) const override {
|
||||||
|
return Events::pressed(keycode);
|
||||||
|
}
|
||||||
|
bool jpressed(keycode keycode) const override {
|
||||||
|
return Events::jpressed(keycode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool clicked(mousecode mousecode) const override {
|
||||||
|
return Events::clicked(mousecode);
|
||||||
|
}
|
||||||
|
bool jclicked(mousecode mousecode) const override {
|
||||||
|
return Events::jclicked(mousecode);
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorState getCursor() const override {
|
||||||
|
return {
|
||||||
|
Events::isCursorLocked(),
|
||||||
|
Events::cursor,
|
||||||
|
Events::delta
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Bindings& getBindings() override {
|
||||||
|
return Events::bindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Bindings& getBindings() const override {
|
||||||
|
return Events::bindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
observer_handler addKeyCallback(keycode key, KeyCallback callback) override {
|
||||||
|
return Events::addKeyCallback(key, std::move(callback));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(!std::is_abstract<GLFWInput>());
|
||||||
|
|
||||||
|
std::unique_ptr<Input> Window::initialize(DisplaySettings* settings) {
|
||||||
::settings = settings;
|
::settings = settings;
|
||||||
Window::width = settings->width.get();
|
Window::width = settings->width.get();
|
||||||
Window::height = settings->height.get();
|
Window::height = settings->height.get();
|
||||||
@ -190,7 +244,7 @@ int Window::initialize(DisplaySettings* settings) {
|
|||||||
glfwSetErrorCallback(glfw_error_callback);
|
glfwSetErrorCallback(glfw_error_callback);
|
||||||
if (glfwInit() == GLFW_FALSE) {
|
if (glfwInit() == GLFW_FALSE) {
|
||||||
logger.error() << "failed to initialize GLFW";
|
logger.error() << "failed to initialize GLFW";
|
||||||
return -1;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
@ -209,7 +263,7 @@ int Window::initialize(DisplaySettings* settings) {
|
|||||||
if (window == nullptr) {
|
if (window == nullptr) {
|
||||||
logger.error() << "failed to create GLFW window";
|
logger.error() << "failed to create GLFW window";
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return -1;
|
return nullptr;
|
||||||
}
|
}
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
|
|
||||||
@ -224,7 +278,7 @@ int Window::initialize(DisplaySettings* settings) {
|
|||||||
} else {
|
} else {
|
||||||
logger.error() << "failed to initialize GLEW:\n"
|
logger.error() << "failed to initialize GLEW:\n"
|
||||||
<< glewGetErrorString(glewErr);
|
<< glewGetErrorString(glewErr);
|
||||||
return -1;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +337,7 @@ int Window::initialize(DisplaySettings* settings) {
|
|||||||
}
|
}
|
||||||
standard_cursors[i] = glfwCreateStandardCursor(cursor);
|
standard_cursors[i] = glfwCreateStandardCursor(cursor);
|
||||||
}
|
}
|
||||||
return 0;
|
return std::make_unique<GLFWInput>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::clear() {
|
void Window::clear() {
|
||||||
@ -467,10 +521,6 @@ std::unique_ptr<ImageData> Window::takeScreenshot() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Window::getClipboardText() {
|
|
||||||
return glfwGetClipboardString(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::setClipboardText(const char* text) {
|
void Window::setClipboardText(const char* text) {
|
||||||
glfwSetClipboardString(window, text);
|
glfwSetClipboardString(window, text);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,13 +9,14 @@
|
|||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
|
|
||||||
class ImageData;
|
class ImageData;
|
||||||
|
class Input;
|
||||||
struct DisplaySettings;
|
struct DisplaySettings;
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
extern uint width;
|
extern uint width;
|
||||||
extern uint height;
|
extern uint height;
|
||||||
|
|
||||||
int initialize(DisplaySettings* settings);
|
std::unique_ptr<Input> initialize(DisplaySettings* settings);
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
void viewport(int x, int y, int width, int height);
|
void viewport(int x, int y, int width, int height);
|
||||||
@ -41,7 +42,6 @@ namespace Window {
|
|||||||
void setBgColor(glm::vec3 color);
|
void setBgColor(glm::vec3 color);
|
||||||
void setBgColor(glm::vec4 color);
|
void setBgColor(glm::vec4 color);
|
||||||
double time();
|
double time();
|
||||||
const char* getClipboardText();
|
|
||||||
void setClipboardText(const char* text);
|
void setClipboardText(const char* text);
|
||||||
DisplaySettings* getSettings();
|
DisplaySettings* getSettings();
|
||||||
void setIcon(const ImageData* image);
|
void setIcon(const ImageData* image);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
#include "util/HandlersList.hpp"
|
#include "util/HandlersList.hpp"
|
||||||
|
|
||||||
@ -143,7 +144,7 @@ struct Binding {
|
|||||||
int code;
|
int code;
|
||||||
bool state = false;
|
bool state = false;
|
||||||
bool justChange = false;
|
bool justChange = false;
|
||||||
bool enable = true;
|
bool enabled = true;
|
||||||
|
|
||||||
Binding() = default;
|
Binding() = default;
|
||||||
Binding(inputtype type, int code) : type(type), code(code) {
|
Binding(inputtype type, int code) : type(type), code(code) {
|
||||||
@ -173,3 +174,77 @@ struct Binding {
|
|||||||
return "<unknown input type>";
|
return "<unknown input type>";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Bindings {
|
||||||
|
std::unordered_map<std::string, Binding> bindings;
|
||||||
|
public:
|
||||||
|
bool active(const std::string& name) const {
|
||||||
|
const auto& found = bindings.find(name);
|
||||||
|
if (found == bindings.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return found->second.active();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool jactive(const std::string& name) const {
|
||||||
|
const auto& found = bindings.find(name);
|
||||||
|
if (found == bindings.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return found->second.jactive();
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding* get(const std::string& name) {
|
||||||
|
const auto found = bindings.find(name);
|
||||||
|
if (found == bindings.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return &found->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind(const std::string& name, inputtype type, int code) {
|
||||||
|
bindings.try_emplace(name, Binding(type, code));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& getAll() {
|
||||||
|
return bindings;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CursorState {
|
||||||
|
bool locked = false;
|
||||||
|
glm::vec2 pos {};
|
||||||
|
glm::vec2 delta {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Input {
|
||||||
|
public:
|
||||||
|
virtual ~Input() = default;
|
||||||
|
|
||||||
|
virtual void pollEvents() = 0;
|
||||||
|
|
||||||
|
virtual const char* getClipboardText() const = 0;
|
||||||
|
|
||||||
|
virtual int getScroll() = 0;
|
||||||
|
|
||||||
|
virtual Binding& requireBinding(const std::string& name) = 0;
|
||||||
|
|
||||||
|
virtual bool pressed(keycode keycode) const = 0;
|
||||||
|
virtual bool jpressed(keycode keycode) const = 0;
|
||||||
|
|
||||||
|
virtual bool clicked(mousecode mousecode) const = 0;
|
||||||
|
virtual bool jclicked(mousecode mousecode) const = 0;
|
||||||
|
|
||||||
|
virtual CursorState getCursor() const = 0;
|
||||||
|
|
||||||
|
virtual Bindings& getBindings() = 0;
|
||||||
|
|
||||||
|
virtual const Bindings& getBindings() const = 0;
|
||||||
|
|
||||||
|
virtual observer_handler addKeyCallback(keycode key, KeyCallback callback) = 0;
|
||||||
|
|
||||||
|
observer_handler addCallback(const std::string& name, KeyCallback callback) {
|
||||||
|
return requireBinding(name).onactived.add(callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user