TextBox validation + minor refactor, fixes
This commit is contained in:
parent
61ad839ebf
commit
e1d30732df
@ -28,7 +28,7 @@ void BlocksPreview::begin(const Viewport* viewport) {
|
||||
shader->uniformMatrix("u_projview",
|
||||
glm::ortho(0.0f, float(viewport->getWidth()),
|
||||
0.0f, float(viewport->getHeight()),
|
||||
-1000.0f, 1000.0f) *
|
||||
-100.0f, 100.0f) *
|
||||
glm::lookAt(glm::vec3(2, 2, 2), glm::vec3(0.0f), glm::vec3(0, 1, 0)));
|
||||
atlas->getTexture()->bind();
|
||||
}
|
||||
@ -42,15 +42,17 @@ void BlocksPreview::draw(const Block* def, int x, int y, int size, glm::vec4 tin
|
||||
x += 2;
|
||||
|
||||
if (def->model == BlockModel::aabb) {
|
||||
y += (1.0f - def->hitbox.size()).y * size * 0.5f;
|
||||
x += (1.0f - def->hitbox.size()).x * size * 0.5f;
|
||||
y += (1.0f - def->hitbox.size()).y * size * 0.25f;
|
||||
}
|
||||
|
||||
glm::vec3 offset (x/float(width) * 2, y/float(height) * 2, 0.0f);
|
||||
shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset));
|
||||
|
||||
blockid_t id = def->rt.id;
|
||||
const UVRegion texfaces[6]{ cache->getRegion(id, 0), cache->getRegion(id, 1),
|
||||
cache->getRegion(id, 2), cache->getRegion(id, 3),
|
||||
cache->getRegion(id, 4), cache->getRegion(id, 5)};
|
||||
const UVRegion texfaces[6]{cache->getRegion(id, 0), cache->getRegion(id, 1),
|
||||
cache->getRegion(id, 2), cache->getRegion(id, 3),
|
||||
cache->getRegion(id, 4), cache->getRegion(id, 5)};
|
||||
|
||||
switch (def->model) {
|
||||
case BlockModel::none:
|
||||
|
||||
@ -144,7 +144,19 @@ TextBox::TextBox(wstring placeholder, vec4 padding)
|
||||
void TextBox::drawBackground(Batch2D* batch, Assets* assets) {
|
||||
vec2 coord = calcCoord();
|
||||
batch->texture(nullptr);
|
||||
batch->color = (isfocused() ? focusedColor : (hover_ ? hoverColor : color_));
|
||||
|
||||
if (valid) {
|
||||
if (isfocused()) {
|
||||
batch->color = focusedColor;
|
||||
} else if (hover_) {
|
||||
batch->color = hoverColor;
|
||||
} else {
|
||||
batch->color = color_;
|
||||
}
|
||||
} else {
|
||||
batch->color = invalidColor;
|
||||
}
|
||||
|
||||
batch->rect(coord.x, coord.y, size_.x, size_.y);
|
||||
if (!focused_ && supplier) {
|
||||
input = supplier();
|
||||
@ -162,6 +174,24 @@ void TextBox::drawBackground(Batch2D* batch, Assets* assets) {
|
||||
|
||||
void TextBox::typed(unsigned int codepoint) {
|
||||
input += wstring({(wchar_t)codepoint});
|
||||
validate();
|
||||
}
|
||||
|
||||
bool TextBox::validate() {
|
||||
if (validator) {
|
||||
valid = validator(input);
|
||||
} else {
|
||||
valid = true;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
void TextBox::setValid(bool valid) {
|
||||
this->valid = valid;
|
||||
}
|
||||
|
||||
bool TextBox::isValid() const {
|
||||
return valid;
|
||||
}
|
||||
|
||||
void TextBox::keyPressed(int key) {
|
||||
@ -169,10 +199,11 @@ void TextBox::keyPressed(int key) {
|
||||
case KEY_BACKSPACE:
|
||||
if (!input.empty()){
|
||||
input = input.substr(0, input.length()-1);
|
||||
validate();
|
||||
}
|
||||
break;
|
||||
case KEY_ENTER:
|
||||
if (consumer) {
|
||||
if (validate() && consumer) {
|
||||
consumer(label->text());
|
||||
}
|
||||
defocus();
|
||||
@ -183,6 +214,7 @@ void TextBox::keyPressed(int key) {
|
||||
const char* text = Window::getClipboardText();
|
||||
if (text) {
|
||||
input += util::str2wstr_utf8(text);
|
||||
validate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -199,6 +231,10 @@ void TextBox::textConsumer(wstringconsumer consumer) {
|
||||
this->consumer = consumer;
|
||||
}
|
||||
|
||||
void TextBox::textValidator(wstringchecker validator) {
|
||||
this->validator = validator;
|
||||
}
|
||||
|
||||
wstring TextBox::text() const {
|
||||
if (input.empty())
|
||||
return placeholder;
|
||||
@ -297,6 +333,7 @@ void TrackBar::mouseMove(GUI*, int x, int y) {
|
||||
// ================================ CheckBox ==================================
|
||||
CheckBox::CheckBox(bool checked) : UINode(vec2(), vec2(32.0f)), checked_(checked) {
|
||||
color(vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||
margin(vec4(0.0f, 0.0f, 5.0f, 0.0f));
|
||||
}
|
||||
|
||||
void CheckBox::draw(Batch2D* batch, Assets* assets) {
|
||||
|
||||
@ -23,6 +23,8 @@ namespace gui {
|
||||
typedef std::function<bool()> boolsupplier;
|
||||
typedef std::function<void(bool)> boolconsumer;
|
||||
|
||||
typedef std::function<bool(const std::wstring&)> wstringchecker;
|
||||
|
||||
class Label : public UINode {
|
||||
protected:
|
||||
std::wstring text_;
|
||||
@ -71,11 +73,14 @@ namespace gui {
|
||||
protected:
|
||||
glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f};
|
||||
glm::vec4 focusedColor {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
glm::vec4 invalidColor {0.1f, 0.05f, 0.03f, 1.0f};
|
||||
Label* label;
|
||||
std::wstring input;
|
||||
std::wstring placeholder;
|
||||
wstringsupplier supplier = nullptr;
|
||||
wstringconsumer consumer = nullptr;
|
||||
wstringchecker validator = nullptr;
|
||||
bool valid = true;
|
||||
public:
|
||||
TextBox(std::wstring placeholder,
|
||||
glm::vec4 padding=glm::vec4(2.0f));
|
||||
@ -87,8 +92,12 @@ namespace gui {
|
||||
virtual void keyPressed(int key) override;
|
||||
virtual void textSupplier(wstringsupplier supplier);
|
||||
virtual void textConsumer(wstringconsumer consumer);
|
||||
virtual void textValidator(wstringchecker validator);
|
||||
virtual bool isfocuskeeper() const override {return true;}
|
||||
virtual std::wstring text() const;
|
||||
virtual bool validate();
|
||||
virtual void setValid(bool valid);
|
||||
virtual bool isValid() const;
|
||||
};
|
||||
|
||||
class InputBindBox : public Panel {
|
||||
|
||||
@ -135,22 +135,14 @@ void HudRenderer::createDebugPanel(Engine* engine) {
|
||||
}));
|
||||
{
|
||||
TrackBar* bar = new TrackBar(0.0f, 1.0f, 1.0f, 0.005f, 8);
|
||||
bar->supplier([=]() {
|
||||
return level->world->daytime;
|
||||
});
|
||||
bar->consumer([=](double val) {
|
||||
level->world->daytime = val;
|
||||
});
|
||||
bar->supplier([=]() {return level->world->daytime;});
|
||||
bar->consumer([=](double val) {level->world->daytime = val;});
|
||||
panel->add(bar);
|
||||
}
|
||||
{
|
||||
TrackBar* bar = new TrackBar(0.0f, 1.0f, 0.0f, 0.005f, 8);
|
||||
bar->supplier([=]() {
|
||||
return WorldRenderer::fog;
|
||||
});
|
||||
bar->consumer([=](double val) {
|
||||
WorldRenderer::fog = val;
|
||||
});
|
||||
bar->supplier([=]() {return WorldRenderer::fog;});
|
||||
bar->consumer([=](double val) {WorldRenderer::fog = val;});
|
||||
panel->add(bar);
|
||||
}
|
||||
{
|
||||
@ -159,7 +151,6 @@ void HudRenderer::createDebugPanel(Engine* engine) {
|
||||
checkpanel->orientation(Orientation::horizontal);
|
||||
|
||||
CheckBox* checkbox = new CheckBox();
|
||||
checkbox->margin(vec4(0.0f, 0.0f, 5.0f, 0.0f));
|
||||
checkbox->supplier([=]() {
|
||||
return engine->getSettings().debug.showChunkBorders;
|
||||
});
|
||||
@ -249,19 +240,25 @@ void HudRenderer::draw(const GfxContext& ctx){
|
||||
const uint width = viewport.getWidth();
|
||||
const uint height = viewport.getHeight();
|
||||
|
||||
debugPanel->visible(level->player->debug);
|
||||
Player* player = level->player;
|
||||
debugPanel->visible(player->debug);
|
||||
|
||||
uicamera->setFov(height);
|
||||
|
||||
Shader* uishader = assets->getShader("ui");
|
||||
uishader->use();
|
||||
uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView());
|
||||
|
||||
auto batch = ctx.getBatch2D();
|
||||
batch->begin();
|
||||
|
||||
// Chosen block preview
|
||||
batch->color = vec4(1.0f);
|
||||
Shader* uishader = assets->getShader("ui");
|
||||
uishader->use();
|
||||
uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView());
|
||||
|
||||
// Draw selected item preview
|
||||
hotbarView->setPosition(width-60, height-60);
|
||||
hotbarView->setItems({player->getChosenItem()});
|
||||
hotbarView->actAndDraw(&ctx);
|
||||
|
||||
// Crosshair
|
||||
batch->begin();
|
||||
if (Events::_cursor_locked && !level->player->debug) {
|
||||
batch->lineWidth(2);
|
||||
batch->line(width/2, height/2-6, width/2, height/2+6, 0.2f, 0.2f, 0.2f, 1.0f);
|
||||
@ -270,20 +267,16 @@ void HudRenderer::draw(const GfxContext& ctx){
|
||||
batch->line(width/2+5, height/2-5, width/2-5, height/2+5, 0.9f, 0.9f, 0.9f, 1.0f);
|
||||
}
|
||||
|
||||
Player* player = level->player;
|
||||
hotbarView->setPosition(width-56, height-56);
|
||||
hotbarView->setItems({player->getChosenItem()});
|
||||
hotbarView->actAndDraw(&ctx);
|
||||
|
||||
uishader->use();
|
||||
batch->begin();
|
||||
|
||||
if (pause) {
|
||||
// draw fullscreen dark overlay
|
||||
batch->texture(nullptr);
|
||||
batch->color = vec4(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
batch->rect(0, 0, width, height);
|
||||
}
|
||||
if (inventoryOpen) {
|
||||
// draw content access panel (all available items)
|
||||
contentAccess->setPosition(viewport.getWidth()-contentAccess->getWidth(), 0);
|
||||
contentAccess->actAndDraw(&ctx);
|
||||
}
|
||||
|
||||
@ -277,6 +277,12 @@ void create_new_world_panel(Engine* engine, PagesControl* menu) {
|
||||
panel->add(label);
|
||||
|
||||
TextBox* input = new TextBox(L"New World", vec4(6.0f));
|
||||
input->textValidator([=](const std::wstring& text) {
|
||||
EnginePaths* paths = engine->getPaths();
|
||||
std::string textutf8 = util::wstr2str_utf8(text);
|
||||
return util::is_valid_filename(text) &&
|
||||
!paths->isWorldNameUsed(textutf8);
|
||||
});
|
||||
panel->add(input);
|
||||
worldNameInput = input;
|
||||
}
|
||||
@ -287,29 +293,15 @@ void create_new_world_panel(Engine* engine, PagesControl* menu) {
|
||||
panel->add(seedInput);
|
||||
}
|
||||
|
||||
vec4 basecolor = worldNameInput->color();
|
||||
panel->add(create_button( L"Create World", vec4(10), vec4(1, 20, 1, 1),
|
||||
[=](GUI*) {
|
||||
if (!worldNameInput->validate())
|
||||
return;
|
||||
|
||||
std::wstring name = worldNameInput->text();
|
||||
std::string nameutf8 = util::wstr2str_utf8(name);
|
||||
EnginePaths* paths = engine->getPaths();
|
||||
|
||||
// Basic validation
|
||||
if (!util::is_valid_filename(name) ||
|
||||
paths->isWorldNameUsed(nameutf8)) {
|
||||
// blink red two times
|
||||
panel->listenInterval(0.1f, [worldNameInput, basecolor]() {
|
||||
static bool flag = true;
|
||||
if (flag) {
|
||||
worldNameInput->color(vec4(0.3f, 0.0f, 0.0f, 0.5f));
|
||||
} else {
|
||||
worldNameInput->color(basecolor);
|
||||
}
|
||||
flag = !flag;
|
||||
}, 4);
|
||||
return;
|
||||
}
|
||||
|
||||
std::wstring seedstr = seedInput->text();
|
||||
uint64_t seed = str2seed(seedstr);
|
||||
std::cout << "world seed: " << seed << std::endl;
|
||||
@ -447,7 +439,6 @@ void create_settings_panel(Engine* engine, PagesControl* menu) {
|
||||
checkpanel->orientation(Orientation::horizontal);
|
||||
|
||||
CheckBox* checkbox = new CheckBox();
|
||||
checkbox->margin(vec4(0.0f, 0.0f, 5.0f, 0.0f));
|
||||
checkbox->supplier([=]() {
|
||||
return engine->getSettings().display.swapInterval != 0;
|
||||
});
|
||||
@ -466,7 +457,6 @@ void create_settings_panel(Engine* engine, PagesControl* menu) {
|
||||
checkpanel->orientation(Orientation::horizontal);
|
||||
|
||||
CheckBox* checkbox = new CheckBox();
|
||||
checkbox->margin(vec4(0.0f, 0.0f, 5.0f, 0.0f));
|
||||
checkbox->supplier([=]() {
|
||||
return engine->getSettings().graphics.backlight != 0;
|
||||
});
|
||||
|
||||
@ -36,6 +36,7 @@ Batch2D::~Batch2D(){
|
||||
void Batch2D::begin(){
|
||||
_texture = nullptr;
|
||||
blank->bind();
|
||||
color = vec4(1.0f);
|
||||
}
|
||||
|
||||
void Batch2D::vertex(float x, float y,
|
||||
|
||||
@ -169,7 +169,7 @@ void Batch3D::xSprite(float w, float h, const UVRegion& uv, const vec4 tint, boo
|
||||
}
|
||||
|
||||
void Batch3D::blockCube(const vec3 size, const UVRegion(&texfaces)[6], const vec4 tint, bool shading) {
|
||||
vec3 coord = (1.0f - size) * -0.45f;
|
||||
vec3 coord = (1.0f - size) * -0.5f;
|
||||
face(coord+vec3(0.0f, 0.0f, 0.0f), size.x, size.y, vec3(1, 0, 0), vec3(0, 1, 0), texfaces[5], (shading ? do_tint(0.8)*tint : tint));
|
||||
face(coord+vec3(size.x, 0.0f, -size.z), size.x, size.y, vec3(-1, 0, 0), vec3(0, 1, 0), texfaces[4], (shading ? do_tint(0.8f)*tint : tint));
|
||||
face(coord+vec3(0.0f, size.y, 0.0f), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, -1), texfaces[3], (shading ? do_tint(1.0f)*tint : tint));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user