Merge branch 'main' of https://github.com/MihailRis/VoxelEngine-Cpp
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 779 B |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 357 B |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.8 KiB |
@@ -97,7 +97,14 @@ void ContentPack::scan(fs::path rootfolder,
|
|||||||
continue;
|
continue;
|
||||||
if (!is_pack(folder))
|
if (!is_pack(folder))
|
||||||
continue;
|
continue;
|
||||||
packs.push_back(read(folder));
|
try {
|
||||||
|
packs.push_back(read(folder));
|
||||||
|
} catch (const contentpack_error& err) {
|
||||||
|
std::cerr << "package.json error at " << err.getFolder().u8string();
|
||||||
|
std::cerr << ": " << err.what() << std::endl;
|
||||||
|
} catch (const std::runtime_error& err) {
|
||||||
|
std::cerr << err.what() << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,11 @@ std::vector<fs::path> EnginePaths::scanForWorlds() {
|
|||||||
}
|
}
|
||||||
folders.push_back(worldFolder);
|
folders.push_back(worldFolder);
|
||||||
}
|
}
|
||||||
|
std::sort(folders.begin(), folders.end(), [](fs::path a, fs::path b) {
|
||||||
|
a = a/fs::u8path(WorldFiles::WORLD_FILE);
|
||||||
|
b = b/fs::u8path(WorldFiles::WORLD_FILE);
|
||||||
|
return fs::last_write_time(a) > fs::last_write_time(b);
|
||||||
|
});
|
||||||
return folders;
|
return folders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ GUI::GUI() {
|
|||||||
|
|
||||||
menu = std::make_shared<PagesControl>();
|
menu = std::make_shared<PagesControl>();
|
||||||
container->add(menu);
|
container->add(menu);
|
||||||
container->scrollable(false);
|
container->setScrollable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI::~GUI() {
|
GUI::~GUI() {
|
||||||
|
|||||||
@@ -95,8 +95,9 @@ Button::Button(std::shared_ptr<UINode> content, glm::vec4 padding)
|
|||||||
setSize(content->getSize()+vec2(padding[0]+padding[2]+margin[0]+margin[2],
|
setSize(content->getSize()+vec2(padding[0]+padding[2]+margin[0]+margin[2],
|
||||||
padding[1]+padding[3]+margin[1]+margin[3]));
|
padding[1]+padding[3]+margin[1]+margin[3]));
|
||||||
add(content);
|
add(content);
|
||||||
scrollable(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));
|
||||||
|
content->setInteractive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Button::Button(
|
Button::Button(
|
||||||
@@ -117,11 +118,12 @@ Button::Button(
|
|||||||
if (action) {
|
if (action) {
|
||||||
listenAction(action);
|
listenAction(action);
|
||||||
}
|
}
|
||||||
scrollable(false);
|
setScrollable(false);
|
||||||
|
|
||||||
label = std::make_shared<Label>(text);
|
label = std::make_shared<Label>(text);
|
||||||
label->setAlign(Align::center);
|
label->setAlign(Align::center);
|
||||||
label->setSize(size-vec2(padding.z+padding.x, padding.w+padding.y));
|
label->setSize(size-vec2(padding.z+padding.x, padding.w+padding.y));
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
@@ -161,10 +163,6 @@ void Button::drawBackground(const GfxContext* pctx, Assets* assets) {
|
|||||||
batch->rect(coord.x, coord.y, size.x, size.y);
|
batch->rect(coord.x, coord.y, size.x, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<UINode> Button::getAt(vec2 pos, std::shared_ptr<UINode> self) {
|
|
||||||
return UINode::getAt(pos, self);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Button::mouseRelease(GUI* gui, int x, int y) {
|
void Button::mouseRelease(GUI* gui, int x, int y) {
|
||||||
UINode::mouseRelease(gui, x, y);
|
UINode::mouseRelease(gui, x, y);
|
||||||
if (isInside(vec2(x, y))) {
|
if (isInside(vec2(x, y))) {
|
||||||
@@ -219,6 +217,7 @@ TextBox::TextBox(std::wstring placeholder, vec4 padding)
|
|||||||
input(L""),
|
input(L""),
|
||||||
placeholder(placeholder) {
|
placeholder(placeholder) {
|
||||||
label = std::make_shared<Label>(L"");
|
label = std::make_shared<Label>(L"");
|
||||||
|
label->setSize(size-vec2(padding.z+padding.x, padding.w+padding.y));
|
||||||
add(label);
|
add(label);
|
||||||
setHoverColor(glm::vec4(0.05f, 0.1f, 0.2f, 0.75f));
|
setHoverColor(glm::vec4(0.05f, 0.1f, 0.2f, 0.75f));
|
||||||
}
|
}
|
||||||
@@ -253,7 +252,7 @@ void TextBox::drawBackground(const GfxContext* pctx, Assets* assets) {
|
|||||||
label->setColor(vec4(1.0f));
|
label->setColor(vec4(1.0f));
|
||||||
label->setText(input);
|
label->setText(input);
|
||||||
}
|
}
|
||||||
scrollable(false);
|
setScrollable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::typed(unsigned int codepoint) {
|
void TextBox::typed(unsigned int codepoint) {
|
||||||
@@ -289,6 +288,11 @@ void TextBox::focus(GUI* gui) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextBox::refresh() {
|
||||||
|
Panel::refresh();
|
||||||
|
label->setSize(size-vec2(padding.z+padding.x, padding.w+padding.y));
|
||||||
|
}
|
||||||
|
|
||||||
void TextBox::keyPressed(int key) {
|
void TextBox::keyPressed(int key) {
|
||||||
if (key == keycode::BACKSPACE) {
|
if (key == keycode::BACKSPACE) {
|
||||||
if (!input.empty()){
|
if (!input.empty()){
|
||||||
@@ -327,13 +331,13 @@ void TextBox::textValidator(wstringchecker validator) {
|
|||||||
this->validator = validator;
|
this->validator = validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring TextBox::text() const {
|
std::wstring TextBox::getText() const {
|
||||||
if (input.empty())
|
if (input.empty())
|
||||||
return placeholder;
|
return placeholder;
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::text(std::wstring value) {
|
void TextBox::setText(std::wstring value) {
|
||||||
this->input = value;
|
this->input = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,7 +347,7 @@ InputBindBox::InputBindBox(Binding& binding, vec4 padding)
|
|||||||
binding(binding) {
|
binding(binding) {
|
||||||
label = std::make_shared<Label>(L"");
|
label = std::make_shared<Label>(L"");
|
||||||
add(label);
|
add(label);
|
||||||
scrollable(false);
|
setScrollable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputBindBox::drawBackground(const GfxContext* pctx, Assets* assets) {
|
void InputBindBox::drawBackground(const GfxContext* pctx, Assets* assets) {
|
||||||
|
|||||||
@@ -70,8 +70,6 @@ namespace gui {
|
|||||||
|
|
||||||
virtual void drawBackground(const GfxContext* pctx, Assets* assets) override;
|
virtual void drawBackground(const GfxContext* pctx, Assets* assets) override;
|
||||||
|
|
||||||
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
|
|
||||||
|
|
||||||
virtual void mouseRelease(GUI*, int x, int y) override;
|
virtual void mouseRelease(GUI*, int x, int y) override;
|
||||||
virtual Button* listenAction(onaction action);
|
virtual Button* listenAction(onaction action);
|
||||||
|
|
||||||
@@ -123,13 +121,14 @@ namespace gui {
|
|||||||
virtual void textConsumer(wstringconsumer consumer);
|
virtual void textConsumer(wstringconsumer consumer);
|
||||||
virtual void textValidator(wstringchecker validator);
|
virtual void textValidator(wstringchecker validator);
|
||||||
virtual bool isFocuskeeper() const override {return true;}
|
virtual bool isFocuskeeper() const override {return true;}
|
||||||
virtual std::wstring text() const;
|
virtual std::wstring getText() const;
|
||||||
virtual void text(std::wstring value);
|
virtual void setText(std::wstring value);
|
||||||
virtual bool validate();
|
virtual bool validate();
|
||||||
virtual void setValid(bool valid);
|
virtual void setValid(bool valid);
|
||||||
virtual bool isValid() const;
|
virtual bool isValid() const;
|
||||||
virtual void setOnEditStart(runnable oneditstart);
|
virtual void setOnEditStart(runnable oneditstart);
|
||||||
virtual void focus(GUI*) override;
|
virtual void focus(GUI*) override;
|
||||||
|
virtual void refresh() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InputBindBox : public Panel {
|
class InputBindBox : public Panel {
|
||||||
|
|||||||
@@ -0,0 +1,222 @@
|
|||||||
|
#include "gui_xml.h"
|
||||||
|
|
||||||
|
#include <charconv>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "panels.h"
|
||||||
|
#include "controls.h"
|
||||||
|
|
||||||
|
#include "../locale/langs.h"
|
||||||
|
#include "../../logic/scripting/scripting.h"
|
||||||
|
#include "../../util/stringutil.h"
|
||||||
|
|
||||||
|
using namespace gui;
|
||||||
|
|
||||||
|
static double readDouble(const std::string& str, size_t offset, size_t len) {
|
||||||
|
double value;
|
||||||
|
auto res = std::from_chars(str.data()+offset, str.data()+offset+len, value);
|
||||||
|
if (res.ptr != str.data()+offset+len) {
|
||||||
|
throw std::runtime_error("invalid number format "+escape_string(str));
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read 2d vector formatted `x,y`*/
|
||||||
|
static glm::vec2 readVec2(const std::string& str) {
|
||||||
|
size_t pos = str.find(',');
|
||||||
|
if (pos == std::string::npos) {
|
||||||
|
throw std::runtime_error("invalid vec2 value "+escape_string(str));
|
||||||
|
}
|
||||||
|
return glm::vec2(
|
||||||
|
readDouble(str, 0, pos),
|
||||||
|
readDouble(str, pos+1, str.length()-pos-1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read 3d vector formatted `x,y,z`*/
|
||||||
|
[[maybe_unused]]
|
||||||
|
static glm::vec3 readVec3(const std::string& str) {
|
||||||
|
size_t pos1 = str.find(',');
|
||||||
|
if (pos1 == std::string::npos) {
|
||||||
|
throw std::runtime_error("invalid vec3 value "+escape_string(str));
|
||||||
|
}
|
||||||
|
size_t pos2 = str.find(',', pos1+1);
|
||||||
|
if (pos2 == std::string::npos) {
|
||||||
|
throw std::runtime_error("invalid vec3 value "+escape_string(str));
|
||||||
|
}
|
||||||
|
return glm::vec3(
|
||||||
|
readDouble(str, 0, pos1),
|
||||||
|
readDouble(str, pos1+1, pos2),
|
||||||
|
readDouble(str, pos2+1, str.length()-pos2-1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read 4d vector formatted `x,y,z,w`*/
|
||||||
|
static glm::vec4 readVec4(const std::string& str) {
|
||||||
|
size_t pos1 = str.find(',');
|
||||||
|
if (pos1 == std::string::npos) {
|
||||||
|
throw std::runtime_error("invalid vec4 value "+escape_string(str));
|
||||||
|
}
|
||||||
|
size_t pos2 = str.find(',', pos1+1);
|
||||||
|
if (pos2 == std::string::npos) {
|
||||||
|
throw std::runtime_error("invalid vec4 value "+escape_string(str));
|
||||||
|
}
|
||||||
|
size_t pos3 = str.find(',', pos2+1);
|
||||||
|
if (pos3 == std::string::npos) {
|
||||||
|
throw std::runtime_error("invalid vec4 value "+escape_string(str));
|
||||||
|
}
|
||||||
|
return glm::vec4(
|
||||||
|
readDouble(str, 0, pos1),
|
||||||
|
readDouble(str, pos1+1, pos2-pos1-1),
|
||||||
|
readDouble(str, pos2+1, pos3-pos2-1),
|
||||||
|
readDouble(str, pos3+1, str.length()-pos3-1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read RGBA color. Supported formats:
|
||||||
|
- "#RRGGBB" or "#RRGGBBAA" hex color */
|
||||||
|
static glm::vec4 readColor(const std::string& str) {
|
||||||
|
if (str[0] == '#') {
|
||||||
|
if (str.length() != 7 && str.length() != 9) {
|
||||||
|
throw std::runtime_error("#RRGGBB or #RRGGBBAA required");
|
||||||
|
}
|
||||||
|
int a = 255;
|
||||||
|
int r = (hexchar2int(str[1]) << 4) | hexchar2int(str[2]);
|
||||||
|
int g = (hexchar2int(str[3]) << 4) | hexchar2int(str[4]);
|
||||||
|
int b = (hexchar2int(str[5]) << 4) | hexchar2int(str[6]);
|
||||||
|
if (str.length() == 9) {
|
||||||
|
a = (hexchar2int(str[7]) << 4) | hexchar2int(str[8]);
|
||||||
|
}
|
||||||
|
return glm::vec4(
|
||||||
|
r / 255.f,
|
||||||
|
g / 255.f,
|
||||||
|
b / 255.f,
|
||||||
|
a / 255.f
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("hex colors are only supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read basic UINode properties */
|
||||||
|
static void readUINode(xml::xmlelement element, UINode& node) {
|
||||||
|
if (element->has("coord")) {
|
||||||
|
node.setCoord(readVec2(element->attr("coord").getText()));
|
||||||
|
}
|
||||||
|
if (element->has("size")) {
|
||||||
|
node.setSize(readVec2(element->attr("size").getText()));
|
||||||
|
}
|
||||||
|
if (element->has("color")) {
|
||||||
|
node.setColor(readColor(element->attr("color").getText()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container) {
|
||||||
|
readUINode(element, container);
|
||||||
|
|
||||||
|
for (auto& sub : element->getElements()) {
|
||||||
|
if (sub->isText())
|
||||||
|
continue;
|
||||||
|
container.add(reader.readUINode(sub));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _readPanel(UiXmlReader& reader, xml::xmlelement element, Panel& panel) {
|
||||||
|
readUINode(element, panel);
|
||||||
|
|
||||||
|
if (element->has("padding")) {
|
||||||
|
panel.setPadding(readVec4(element->attr("padding").getText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element->has("margin")) {
|
||||||
|
panel.setMargin(readVec4(element->attr("margin").getText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element->has("size")) {
|
||||||
|
panel.setResizing(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& sub : element->getElements()) {
|
||||||
|
if (sub->isText())
|
||||||
|
continue;
|
||||||
|
panel.add(reader.readUINode(sub));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static std::wstring readAndProcessInnerText(xml::xmlelement element) {
|
||||||
|
std::wstring text = L"";
|
||||||
|
if (element->size() == 1) {
|
||||||
|
text = util::str2wstr_utf8(element->sub(0)->attr("#").getText());
|
||||||
|
if (text[0] == '@') {
|
||||||
|
text = langs::get(text.substr(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<UINode> readLabel(UiXmlReader& reader, xml::xmlelement element) {
|
||||||
|
std::wstring text = readAndProcessInnerText(element);
|
||||||
|
auto label = std::make_shared<Label>(text);
|
||||||
|
readUINode(element, *label);
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<UINode> readContainer(UiXmlReader& reader, xml::xmlelement element) {
|
||||||
|
auto container = std::make_shared<Container>(glm::vec2(), glm::vec2());
|
||||||
|
_readContainer(reader, element, *container);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<UINode> readButton(UiXmlReader& reader, xml::xmlelement element) {
|
||||||
|
std::wstring text = readAndProcessInnerText(element);
|
||||||
|
auto button = std::make_shared<Button>(text, glm::vec4(0.0f), nullptr);
|
||||||
|
_readPanel(reader, element, *button);
|
||||||
|
|
||||||
|
if (element->has("onclick")) {
|
||||||
|
runnable callback = scripting::create_runnable("<onclick>", element->attr("onclick").getText());
|
||||||
|
button->listenAction([callback](GUI*) {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, xml::xmlelement element) {
|
||||||
|
auto placeholder = util::str2wstr_utf8(element->attr("placeholder", "").getText());
|
||||||
|
auto text = readAndProcessInnerText(element);
|
||||||
|
auto textbox = std::make_shared<TextBox>(placeholder, glm::vec4(0.0f));
|
||||||
|
_readPanel(reader, element, *textbox);
|
||||||
|
textbox->setText(text);
|
||||||
|
return textbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
UiXmlReader::UiXmlReader() {
|
||||||
|
add("label", readLabel);
|
||||||
|
add("button", readButton);
|
||||||
|
add("textbox", readTextBox);
|
||||||
|
add("container", readContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiXmlReader::add(const std::string& tag, uinode_reader reader) {
|
||||||
|
readers[tag] = reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<UINode> UiXmlReader::readUINode(xml::xmlelement element) {
|
||||||
|
const std::string& tag = element->getTag();
|
||||||
|
|
||||||
|
auto found = readers.find(tag);
|
||||||
|
if (found == readers.end()) {
|
||||||
|
throw std::runtime_error("unsupported element '"+tag+"'");
|
||||||
|
}
|
||||||
|
return found->second(*this, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<UINode> UiXmlReader::readXML(
|
||||||
|
const std::string& filename,
|
||||||
|
const std::string& source
|
||||||
|
) {
|
||||||
|
auto document = xml::parse(filename, source);
|
||||||
|
auto root = document->getRoot();
|
||||||
|
return readUINode(root);
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef FRONTEND_GUI_GUI_XML_H_
|
||||||
|
#define FRONTEND_GUI_GUI_XML_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "GUI.h"
|
||||||
|
#include "../../coders/xml.h"
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
class UiXmlReader;
|
||||||
|
|
||||||
|
using uinode_reader = std::function<std::shared_ptr<UINode>(UiXmlReader&, xml::xmlelement)>;
|
||||||
|
|
||||||
|
class UiXmlReader {
|
||||||
|
std::unordered_map<std::string, uinode_reader> readers;
|
||||||
|
public:
|
||||||
|
UiXmlReader();
|
||||||
|
|
||||||
|
void add(const std::string& tag, uinode_reader reader);
|
||||||
|
|
||||||
|
std::shared_ptr<UINode> readUINode(xml::xmlelement element);
|
||||||
|
|
||||||
|
std::shared_ptr<UINode> readXML(
|
||||||
|
const std::string& filename,
|
||||||
|
const std::string& source
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FRONTEND_GUI_GUI_XML_H_
|
||||||
@@ -62,7 +62,7 @@ void Container::act(float delta) {
|
|||||||
|
|
||||||
void Container::scrolled(int value) {
|
void Container::scrolled(int value) {
|
||||||
int diff = (actualLength-getSize().y);
|
int diff = (actualLength-getSize().y);
|
||||||
if (diff > 0 && scrollable_) {
|
if (diff > 0 && scrollable) {
|
||||||
scroll += value * 40;
|
scroll += value * 40;
|
||||||
if (scroll > 0)
|
if (scroll > 0)
|
||||||
scroll = 0;
|
scroll = 0;
|
||||||
@@ -74,8 +74,8 @@ void Container::scrolled(int value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::scrollable(bool flag) {
|
void Container::setScrollable(bool flag) {
|
||||||
scrollable_ = flag;
|
scrollable = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::draw(const GfxContext* pctx, Assets* assets) {
|
void Container::draw(const GfxContext* pctx, Assets* assets) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace gui {
|
|||||||
std::vector<IntervalEvent> intervalEvents;
|
std::vector<IntervalEvent> intervalEvents;
|
||||||
int scroll = 0;
|
int scroll = 0;
|
||||||
int actualLength = 0;
|
int actualLength = 0;
|
||||||
bool scrollable_ = true;
|
bool scrollable = true;
|
||||||
public:
|
public:
|
||||||
Container(glm::vec2 coord, glm::vec2 size);
|
Container(glm::vec2 coord, glm::vec2 size);
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ namespace gui {
|
|||||||
virtual void add(std::shared_ptr<UINode> node, glm::vec2 coord);
|
virtual void add(std::shared_ptr<UINode> node, glm::vec2 coord);
|
||||||
virtual void remove(std::shared_ptr<UINode> node);
|
virtual void remove(std::shared_ptr<UINode> node);
|
||||||
virtual void scrolled(int value) override;
|
virtual void scrolled(int value) override;
|
||||||
virtual void scrollable(bool flag);
|
virtual void setScrollable(bool flag);
|
||||||
void listenInterval(float interval, ontimeout callback, int repeat=-1);
|
void listenInterval(float interval, ontimeout callback, int repeat=-1);
|
||||||
virtual glm::vec2 contentOffset() override {return glm::vec2(0.0f, scroll);};
|
virtual glm::vec2 contentOffset() override {return glm::vec2(0.0f, scroll);};
|
||||||
virtual void setSize(glm::vec2 size);
|
virtual void setSize(glm::vec2 size);
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ std::shared_ptr<UINode> HudRenderer::createDebugPanel(Engine* engine) {
|
|||||||
});
|
});
|
||||||
box->setOnEditStart([=](){
|
box->setOnEditStart([=](){
|
||||||
Hitbox* hitbox = level->player->hitbox.get();
|
Hitbox* hitbox = level->player->hitbox.get();
|
||||||
box->text(std::to_wstring(int(hitbox->position[ax])));
|
box->setText(std::to_wstring(int(hitbox->position[ax])));
|
||||||
});
|
});
|
||||||
|
|
||||||
sub->add(box);
|
sub->add(box);
|
||||||
@@ -276,7 +276,7 @@ HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend)
|
|||||||
);
|
);
|
||||||
contentAccessPanel->setColor(glm::vec4());
|
contentAccessPanel->setColor(glm::vec4());
|
||||||
contentAccessPanel->add(contentAccess);
|
contentAccessPanel->add(contentAccess);
|
||||||
contentAccessPanel->scrollable(true);
|
contentAccessPanel->setScrollable(true);
|
||||||
|
|
||||||
hotbarView = createHotbar();
|
hotbarView = createHotbar();
|
||||||
inventoryView = createInventory();
|
inventoryView = createInventory();
|
||||||
|
|||||||
@@ -96,6 +96,9 @@ static void show_content_missing(
|
|||||||
|
|
||||||
auto subpanel = std::make_shared<Panel>(vec2(500, 100));
|
auto subpanel = std::make_shared<Panel>(vec2(500, 100));
|
||||||
subpanel->setColor(vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
subpanel->setColor(vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||||
|
subpanel->setScrollable(true);
|
||||||
|
subpanel->setMaxLength(400);
|
||||||
|
panel->add(subpanel);
|
||||||
|
|
||||||
for (auto& entry : lut->getMissingContent()) {
|
for (auto& entry : lut->getMissingContent()) {
|
||||||
auto hpanel = std::make_shared<Panel>(vec2(500, 30));
|
auto hpanel = std::make_shared<Panel>(vec2(500, 30));
|
||||||
@@ -112,8 +115,7 @@ static void show_content_missing(
|
|||||||
hpanel->add(namelabel);
|
hpanel->add(namelabel);
|
||||||
subpanel->add(hpanel);
|
subpanel->add(hpanel);
|
||||||
}
|
}
|
||||||
subpanel->setMaxLength(400);
|
|
||||||
panel->add(subpanel);
|
|
||||||
|
|
||||||
panel->add(std::make_shared<Button>(
|
panel->add(std::make_shared<Button>(
|
||||||
langs::get(L"Back to Main Menu", L"menu"), vec4(8.0f), [=](GUI*){
|
langs::get(L"Back to Main Menu", L"menu"), vec4(8.0f), [=](GUI*){
|
||||||
@@ -143,7 +145,7 @@ void show_convert_request(
|
|||||||
void create_languages_panel(Engine* engine) {
|
void create_languages_panel(Engine* engine) {
|
||||||
auto menu = engine->getGUI()->getMenu();
|
auto menu = engine->getGUI()->getMenu();
|
||||||
auto panel = create_page(engine, "languages", 400, 0.5f, 1);
|
auto panel = create_page(engine, "languages", 400, 0.5f, 1);
|
||||||
panel->scrollable(true);
|
panel->setScrollable(true);
|
||||||
|
|
||||||
std::vector<std::string> locales;
|
std::vector<std::string> locales;
|
||||||
for (auto& entry : langs::locales_info) {
|
for (auto& entry : langs::locales_info) {
|
||||||
@@ -211,7 +213,7 @@ void open_world(std::string name, Engine* engine) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Panel> create_worlds_panel(Engine* engine) {
|
std::shared_ptr<Panel> create_worlds_panel(Engine* engine) {
|
||||||
auto panel = std::make_shared<Panel>(vec2(390, 200), vec4(5.0f));
|
auto panel = std::make_shared<Panel>(vec2(390, 0), vec4(5.0f));
|
||||||
panel->setColor(vec4(1.0f, 1.0f, 1.0f, 0.07f));
|
panel->setColor(vec4(1.0f, 1.0f, 1.0f, 0.07f));
|
||||||
panel->setMaxLength(400);
|
panel->setMaxLength(400);
|
||||||
|
|
||||||
@@ -278,7 +280,7 @@ std::shared_ptr<Panel> create_packs_panel(
|
|||||||
auto panel = std::make_shared<Panel>(vec2(PACKS_PANEL_WIDTH, 200), vec4(5.0f));
|
auto panel = std::make_shared<Panel>(vec2(PACKS_PANEL_WIDTH, 200), vec4(5.0f));
|
||||||
panel->setColor(vec4(1.0f, 1.0f, 1.0f, 0.07f));
|
panel->setColor(vec4(1.0f, 1.0f, 1.0f, 0.07f));
|
||||||
panel->setMaxLength(400);
|
panel->setMaxLength(400);
|
||||||
panel->scrollable(true);
|
panel->setScrollable(true);
|
||||||
|
|
||||||
for (auto& pack : packs) {
|
for (auto& pack : packs) {
|
||||||
auto packpanel = std::make_shared<RichButton>(vec2(390, 80));
|
auto packpanel = std::make_shared<RichButton>(vec2(390, 80));
|
||||||
@@ -415,8 +417,8 @@ void create_new_world_panel(Engine* engine) {
|
|||||||
if (!nameInput->validate())
|
if (!nameInput->validate())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string name = util::wstr2str_utf8(nameInput->text());
|
std::string name = util::wstr2str_utf8(nameInput->getText());
|
||||||
uint64_t seed = str2seed(seedInput->text());
|
uint64_t seed = str2seed(seedInput->getText());
|
||||||
std::cout << "world seed: " << seed << std::endl;
|
std::cout << "world seed: " << seed << std::endl;
|
||||||
|
|
||||||
EnginePaths* paths = engine->getPaths();
|
EnginePaths* paths = engine->getPaths();
|
||||||
|
|||||||
@@ -49,9 +49,30 @@ void TextureAnimator::update(float delta) {
|
|||||||
|
|
||||||
float srcPosY = elem.srcTexture->height - frame.size.y - frame.srcPos.y; // vertical flip
|
float srcPosY = elem.srcTexture->height - frame.size.y - frame.srcPos.y; // vertical flip
|
||||||
|
|
||||||
glBlitFramebuffer(frame.srcPos.x, srcPosY, frame.srcPos.x + frame.size.x, srcPosY + frame.size.y,
|
// Extensions
|
||||||
frame.dstPos.x, frame.dstPos.y, frame.dstPos.x + frame.size.x, frame.dstPos.y + frame.size.y,
|
const int ext = 2;
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
for (int y = -1; y <= 1; y++) {
|
||||||
|
for (int x = -1; x <= 1; x++) {
|
||||||
|
if (x == 0 && y == 0)
|
||||||
|
continue;
|
||||||
|
glBlitFramebuffer(
|
||||||
|
frame.srcPos.x, srcPosY, frame.srcPos.x + frame.size.x, srcPosY + frame.size.y,
|
||||||
|
frame.dstPos.x+x*ext, frame.dstPos.y+y*ext,
|
||||||
|
frame.dstPos.x + frame.size.x+x*ext, frame.dstPos.y + frame.size.y+y*ext,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glBlitFramebuffer(
|
||||||
|
frame.srcPos.x, srcPosY,
|
||||||
|
frame.srcPos.x + frame.size.x,
|
||||||
|
srcPosY + frame.size.y,
|
||||||
|
frame.dstPos.x, frame.dstPos.y,
|
||||||
|
frame.dstPos.x + frame.size.x,
|
||||||
|
frame.dstPos.y + frame.size.y,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST
|
||||||
|
);
|
||||||
}
|
}
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
|||||||