#include "../include/Entry.hpp" #include "../include/ResourceLoader.hpp" #include "../include/Config.hpp" #include "../include/Utils.hpp" #include "../include/Theme.hpp" #include #include #include #include namespace QuickMedia { static float floor(float v) { return (int)v; } static const float background_margin_horizontal = 5.0f + floor(get_config().input.font_size * get_config().scale * get_config().font_scale * 0.6f); static const float background_margin_vertical = 2.0f + floor(get_config().input.font_size * get_config().scale * get_config().font_scale * 0.25f); Entry::Entry(const std::string &placeholder_text, mgl::Shader *rounded_rectangle_shader) : on_submit_callback(nullptr), draw_background(true), text("", false, floor(get_config().input.font_size * get_config().scale * get_config().font_scale), 0.0f), width(0.0f), background(mgl::vec2f(1.0f, 1.0f), 10.0f * get_config().scale, get_theme().shade_color, rounded_rectangle_shader), placeholder(placeholder_text, *FontLoader::get_font(FontLoader::FontType::LATIN, get_config().input.font_size * get_config().scale * get_config().font_scale)), mouse_left_inside(false) { text.setEditable(true); text.set_color(get_theme().text_color); placeholder.set_color(get_theme().placeholder_text_color); } void Entry::process_event(mgl::Window &window, mgl::Event &event) { if(is_touch_enabled() && event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) { mgl::FloatRect box(background.get_position(), background.get_size()); if(box.contains(mgl::vec2f(event.mouse_button.x, event.mouse_button.y))) mouse_left_inside = true; else mouse_left_inside = false; } else if(is_touch_enabled() && event.type == mgl::Event::MouseButtonReleased && event.mouse_button.button == mgl::Mouse::Left) { mgl::FloatRect box(background.get_position(), background.get_size()); if(mouse_left_inside && box.contains(mgl::vec2f(event.mouse_button.x, event.mouse_button.y))) show_virtual_keyboard(); mouse_left_inside = false; } if(!text.isEditable()) return; text.processEvent(window, event); if(event.type == mgl::Event::KeyPressed && event.key.code == mgl::Keyboard::Enter && !event.key.shift) { if(on_submit_callback) { bool clear_text = on_submit_callback(text.getString()); if(clear_text) text.setString(""); } } } // TODO: Set the max number of visible lines and use glScissor to cut off the lines outsides // (and also split text into lines to not draw them at all once they are not inside the scissor box) void Entry::draw(mgl::Window &window) { background.set_size(mgl::vec2f(width, get_height())); if(draw_background) background.draw(window); if(text.getString().empty() && !text.isEditable()) { window.draw(placeholder); //mgl::vec2f placeholder_pos = placeholder.get_position(); //const float caret_margin = 2.0f; //const float vspace = placeholder.getFont()->getLineSpacing(18); //mgl::Rectangle caret_rect(mgl::vec2f(2.0f, floor(vspace - caret_margin * 2.0f))); //caret_rect.set_position(floor(placeholder_pos.x), floor(placeholder_pos.y + caret_margin)); //window.draw(caret_rect); } else { text.draw(window); } } void Entry::set_single_line(bool single_line) { text.single_line_edit = single_line; } void Entry::set_editable(bool editable) { text.setEditable(editable); } void Entry::set_text(std::string new_text) { text.setString(std::move(new_text)); } void Entry::move_caret_to_end() { text.updateGeometry(); text.moveCaretToEnd(); } void Entry::insert_text_at_caret_position(const std::string &str) { text.insert_text_at_caret_position(str); } void Entry::replace(size_t start_index, size_t length, const std::string &insert_str) { text.replace(start_index, length, insert_str); } int Entry::get_caret_index() const { return text.getCaretIndex(); } void Entry::set_position(const mgl::vec2f &pos) { background.set_position(pos); text.set_position(pos + mgl::vec2f(background_margin_horizontal * padding_scale, background_margin_vertical * padding_scale - text.get_character_size() * 0.3f).floor()); placeholder.set_position(pos + mgl::vec2f(background_margin_horizontal * padding_scale, background_margin_vertical * padding_scale - text.get_character_size() * 0.005f).floor()); } void Entry::set_max_width(float width) { this->width = width; text.setMaxWidth(this->width - background_margin_horizontal * padding_scale * 2.0f); } bool Entry::is_editable() const { return text.isEditable(); } float Entry::get_height() { text.updateGeometry(); return floor(text.getHeight() + background_margin_vertical * padding_scale * 2.0f); } const std::string& Entry::get_text() const { return text.getString(); } void Entry::set_background_color(mgl::Color color) { background.set_color(color); } void Entry::set_padding_scale(float scale) { padding_scale = scale; set_max_width(width); } }