diff --git a/src/files/engine_files.cpp b/src/files/engine_files.cpp index a7e79c18..3dc920f8 100644 --- a/src/files/engine_files.cpp +++ b/src/files/engine_files.cpp @@ -4,14 +4,14 @@ #include #include "../typedefs.h" -namespace filesystem = std::filesystem; +namespace fs = std::filesystem; using std::string; -using filesystem::path; +using fs::path; path enginefs::get_screenshot_file(string ext) { path folder = SCREENSHOTS_FOLDER; - if (!filesystem::is_directory(folder)) { - filesystem::create_directory(folder); + if (!fs::is_directory(folder)) { + fs::create_directory(folder); } auto t = std::time(nullptr); @@ -23,15 +23,19 @@ path enginefs::get_screenshot_file(string ext) { ss << std::put_time(&tm, format); string datetimestr = ss.str(); - path filename = folder/("screenshot-"+datetimestr+"."+ext); + path filename = folder/path("screenshot-"+datetimestr+"."+ext); uint index = 0; - while (filesystem::exists(filename)) { - filename = folder/("screenshot-"+datetimestr+"-"+std::to_string(index)+"."+ext); + while (fs::exists(filename)) { + filename = folder/path("screenshot-"+datetimestr+"-"+std::to_string(index)+"."+ext); index++; } return filename; } path enginefs::get_worlds_folder() { - return "worlds"; + return path("worlds"); +} + +bool enginefs::is_world_name_used(std::string name) { + return fs::exists(enginefs::get_worlds_folder()/fs::u8path(name)); } \ No newline at end of file diff --git a/src/files/engine_files.h b/src/files/engine_files.h index 4dd1b3b5..783e1f6a 100644 --- a/src/files/engine_files.h +++ b/src/files/engine_files.h @@ -9,6 +9,7 @@ namespace enginefs { extern std::filesystem::path get_screenshot_file(std::string ext); extern std::filesystem::path get_worlds_folder(); + extern bool is_world_name_used(std::string name); } #endif // FILES_ENGINE_FILES_H_ \ No newline at end of file diff --git a/src/frontend/gui/controls.cpp b/src/frontend/gui/controls.cpp index d01c33d8..57a7599d 100644 --- a/src/frontend/gui/controls.cpp +++ b/src/frontend/gui/controls.cpp @@ -84,8 +84,11 @@ void Button::listenAction(onaction action) { actions.push_back(action); } -TextBox::TextBox(wstring text, vec4 padding) : Panel(vec2(200,32), padding, 0, false) { - label = new Label(text); +TextBox::TextBox(wstring placeholder, vec4 padding) + : Panel(vec2(200,32), padding, 0, false), + input(L""), + placeholder(placeholder) { + label = new Label(L""); label->align(Align::center); add(shared_ptr(label)); } @@ -96,20 +99,28 @@ void TextBox::drawBackground(Batch2D* batch, Assets* assets) { batch->color = (isfocused() ? focusedColor : (hover_ ? hoverColor : color_)); batch->rect(coord.x, coord.y, size_.x, size_.y); if (!focused_ && supplier) { - label->text(supplier()); + input = supplier(); + } + + if (input.empty()) { + label->color(vec4(0.5f)); + label->text(placeholder); + } else { + label->color(vec4(1.0f)); + label->text(input); } } void TextBox::typed(unsigned int codepoint) { - label->text(label->text() + wstring({(wchar_t)codepoint})); + input += wstring({(wchar_t)codepoint}); } void TextBox::keyPressed(int key) { - wstring src = label->text(); switch (key) { case KEY_BACKSPACE: - if (src.length()) - label->text(src.substr(0, src.length()-1)); + if (!input.empty()){ + input = input.substr(0, input.length()-1); + } break; case KEY_ENTER: if (consumer) { @@ -130,4 +141,10 @@ void TextBox::textSupplier(wstringsupplier supplier) { void TextBox::textConsumer(wstringconsumer consumer) { this->consumer = consumer; +} + +wstring TextBox::text() const { + if (input.empty()) + return placeholder; + return input; } \ No newline at end of file diff --git a/src/frontend/gui/controls.h b/src/frontend/gui/controls.h index 209013fb..f5da872c 100644 --- a/src/frontend/gui/controls.h +++ b/src/frontend/gui/controls.h @@ -53,10 +53,12 @@ namespace gui { glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f}; glm::vec4 focusedColor {0.0f, 0.0f, 0.0f, 1.0f}; Label* label; + std::wstring input; + std::wstring placeholder; wstringsupplier supplier = nullptr; wstringconsumer consumer = nullptr; public: - TextBox(std::wstring text, glm::vec4 padding=glm::vec4(2.0f)); + TextBox(std::wstring placeholder, glm::vec4 padding=glm::vec4(2.0f)); virtual std::shared_ptr getAt(glm::vec2 pos, std::shared_ptr self) override; @@ -66,6 +68,7 @@ namespace gui { virtual void textSupplier(wstringsupplier supplier); virtual void textConsumer(wstringconsumer consumer); virtual bool isfocuskeeper() const override {return true;} + virtual std::wstring text() const; }; } diff --git a/src/frontend/gui/panels.cpp b/src/frontend/gui/panels.cpp index 566365b5..2a0c9320 100644 --- a/src/frontend/gui/panels.cpp +++ b/src/frontend/gui/panels.cpp @@ -35,11 +35,22 @@ void Container::act(float delta) { if (event.timer > event.interval) { event.callback(); event.timer = fmod(event.timer, event.interval); + if (event.repeat > 0) { + event.repeat--; + } } } + intervalEvents.erase(std::remove_if( + intervalEvents.begin(), intervalEvents.end(), + [](const IntervalEvent& event) { + return event.repeat == 0; + } + ), intervalEvents.end()); + for (auto node : nodes) { - if (node->visible()) + if (node->visible()) { node->act(delta); + } } } @@ -66,18 +77,23 @@ void Container::add(shared_ptr node) { void Container::remove(shared_ptr selected) { selected->setParent(nullptr); - nodes.erase(std::remove_if(nodes.begin(), nodes.end(), [selected](const shared_ptr node) { - return node == selected; - }), nodes.end()); + nodes.erase(std::remove_if(nodes.begin(), nodes.end(), + [selected](const shared_ptr node) { + return node == selected; + } + ), nodes.end()); refresh(); } -void Container::listenInterval(float interval, ontimeout callback) { - intervalEvents.push_back({callback, interval, 0.0f}); +void Container::listenInterval(float interval, ontimeout callback, int repeat) { + intervalEvents.push_back({callback, interval, 0.0f, repeat}); } Panel::Panel(vec2 size, glm::vec4 padding, float interval, bool resizing) - : Container(vec2(), size), padding(padding), interval(interval), resizing_(resizing) { + : Container(vec2(), size), + padding(padding), + interval(interval), + resizing_(resizing) { color_ = vec4(0.0f, 0.0f, 0.0f, 0.75f); } @@ -103,13 +119,13 @@ void Panel::refresh() { y += margin.y; float ex; - + float spacex = size.x - margin.z - padding.z; switch (node->align()) { case Align::center: - ex = x + fmax(0.0f, (size.x - margin.z - padding.z) - node->size().x) / 2.0f; + ex = x + fmax(0.0f, spacex - node->size().x) / 2.0f; break; case Align::right: - ex = x + size.x - margin.z - padding.z - node->size().x; + ex = x + spacex - node->size().x; break; default: ex = x + margin.x; @@ -131,7 +147,7 @@ void Panel::refresh() { x += margin.x; node->setCoord(vec2(x, y+margin.y)); x += nodesize.x + margin.z + interval; - + float height = size.y - padding.y - padding.w - margin.y - margin.w; node->size(vec2(nodesize.x, height)); maxh = fmax(maxh, y+margin.y+node->size().y+margin.w+padding.w); diff --git a/src/frontend/gui/panels.h b/src/frontend/gui/panels.h index 8bc20aea..168ca1e4 100644 --- a/src/frontend/gui/panels.h +++ b/src/frontend/gui/panels.h @@ -15,6 +15,8 @@ namespace gui { ontimeout callback; float interval; float timer; + // -1 - infinity, 1 - one time event + int repeat; }; enum class Orientation { vertical, horizontal }; @@ -32,7 +34,7 @@ namespace gui { virtual std::shared_ptr getAt(glm::vec2 pos, std::shared_ptr self) override; virtual void add(std::shared_ptr node); virtual void remove(std::shared_ptr node); - void listenInterval(float interval, ontimeout callback); + void listenInterval(float interval, ontimeout callback, int repeat=-1); }; class Panel : public Container { diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 5af2fadd..d6fef300 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -57,23 +57,27 @@ HudRenderer::HudRenderer(Engine* engine, Level* level) : level(level), assets(en fpsMax = fps; }); panel->setCoord(vec2(10, 10)); - panel->add(shared_ptr