#include "../include/Entry.hpp" #include "../include/ResourceLoader.hpp" #include "../include/Utils.hpp" #include #include #include #include const float background_margin_horizontal = std::floor(5.0f * QuickMedia::get_ui_scale()); const float padding_vertical = std::floor(3.0f * QuickMedia::get_ui_scale()); const float background_margin_vertical = std::floor(0.0f * QuickMedia::get_ui_scale()); namespace QuickMedia { Entry::Entry(const std::string &placeholder_text) : on_submit_callback(nullptr), draw_background(true), text("", false, std::floor(16 * get_ui_scale()), 0.0f), width(0.0f), background(sf::Vector2f(1.0f, 1.0f), 7.0f, 10), placeholder(placeholder_text, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(16 * get_ui_scale())), mouse_left_inside(false) { text.setEditable(true); background.setFillColor(sf::Color(55, 60, 68)); placeholder.setFillColor(sf::Color(255, 255, 255, 100)); } void Entry::process_event(sf::Event &event) { if(is_touch_enabled() && event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left) { sf::FloatRect box(background.getPosition(), background.getSize()); if(box.contains(event.mouseButton.x, event.mouseButton.y)) mouse_left_inside = true; else mouse_left_inside = false; } else if(is_touch_enabled() && event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left) { sf::FloatRect box(background.getPosition(), background.getSize()); if(mouse_left_inside && box.contains(event.mouseButton.x, event.mouseButton.y)) show_virtual_keyboard(); mouse_left_inside = false; } if(!text.isEditable()) return; text.processEvent(event); if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Enter && !event.key.shift) { if(on_submit_callback) { auto u8 = text.getString().toUtf8(); std::string *u8_str = (std::string*)&u8; bool clear_text = on_submit_callback(*u8_str); 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(sf::RenderWindow &window) { background.setSize(sf::Vector2f(width, get_height())); if(draw_background) window.draw(background); if(text.getString().isEmpty() && !text.isEditable()) { window.draw(placeholder); //sf::Vector2f placeholder_pos = placeholder.getPosition(); //const float caret_margin = 2.0f; //const float vspace = placeholder.getFont()->getLineSpacing(18); //sf::RectangleShape caret_rect(sf::Vector2f(2.0f, floor(vspace - caret_margin * 2.0f))); //caret_rect.setPosition(floor(placeholder_pos.x), floor(placeholder_pos.y + caret_margin)); //window.draw(caret_rect); } else { text.draw(window); } } void Entry::set_editable(bool editable) { text.setEditable(editable); } void Entry::set_text(std::string new_text) { text.setString(sf::String::fromUtf8(new_text.data(), new_text.data() + new_text.size())); } void Entry::move_caret_to_end() { text.updateGeometry(); text.moveCaretToEnd(); } void Entry::append_text(std::string str) { text.appendText(std::move(str)); } void Entry::set_position(const sf::Vector2f &pos) { background.setPosition(pos); text.setPosition(pos + sf::Vector2f(background_margin_horizontal, background_margin_vertical - std::floor(3.0f * get_ui_scale()))); placeholder.setPosition(pos + sf::Vector2f(background_margin_horizontal, background_margin_vertical + std::floor(3.0f * get_ui_scale()))); } void Entry::set_max_width(float width) { this->width = width; text.setMaxWidth(this->width - background_margin_horizontal * 2.0f); } float Entry::get_height() { text.updateGeometry(); return std::floor(text.getHeight() + background_margin_vertical * 2.0f + padding_vertical *2.0f); } }