#include "textinputnode.h" #include #include "SparrowInput/input.h" #include "engine.h" #include "tools/font.h" #include "resourcemanager.h" TextInputNode::TextInputNode(glm::vec2 dimension): m_dimension(dimension), m_hasFocus(false), m_font_size(16.f), m_text_mesh(nullptr), m_text(""), m_text_updated(false), m_text_color(glm::vec3(1,1,1)), m_cursor_mesh(nullptr), m_cursor_pos(0), m_cursor_pos_updated(false), m_callback(nullptr), m_tab_callback(nullptr), m_history(std::vector()), m_history_pos(0), m_inputActions({NO_ACTION, NO_ACTION, NO_ACTION, NO_ACTION}) { // Font *shellfont = RESOURCE_GET(Font,"shellfont"); Mesh* mesh = new Mesh(); mesh->addRectangle2D(glm::vec2(0),glm::vec2(2, m_font_size)); PBRMaterial* mat = new PBRMaterial(); mat->albedo = glm::vec3(1,1,1); mesh->setMaterial(mat); mesh->setDepth(30); mesh->initGL(); m_cursor_mesh = new SceneNode(); m_cursor_mesh->setVisible(false); m_cursor_mesh->setMesh(mesh); addChild(m_cursor_mesh); } void TextInputNode::update() { if(m_hasFocus) { std::wstring text = getEngine().getInput()->getText(); auto input = getEngine().getInput(); for(auto action : input->getActions()){ if (action.action == m_inputActions[MOVE_CURSOR_LEFT]){ if (m_cursor_pos > 0){ m_cursor_pos--; m_cursor_pos_updated=true; } } else if(action.action == m_inputActions[MOVE_CURSOR_RIGHT]){ if(m_cursor_pos < m_text.length()){ m_cursor_pos++; m_cursor_pos_updated=true; } } else if(action.action == m_inputActions[HISTORY_PREVIOUS]){ if(m_history_pos > 0) { m_history_pos--; m_text = m_history[m_history_pos]; m_cursor_pos = m_text.size(); m_text_updated = true; m_cursor_pos_updated = true; } } else if(action.action == m_inputActions[HISTORY_NEXT]){ if (m_history_pos < m_history.size()) { m_history_pos++; if (m_history_pos == m_history.size()) { m_text.clear(); m_cursor_pos = 0; } else { m_text = m_history[m_history_pos]; m_cursor_pos = m_text.size(); } m_text_updated = true; m_cursor_pos_updated = true; } } } for(unsigned int i = 0 ; i < text.length() ; i++){ char c = text[i]; switch(c){ case 8: if(m_cursor_pos > 0) m_text.erase(--m_cursor_pos,1); m_text_updated = true; m_cursor_pos_updated=true; break; case 13: if (!m_text.empty()) { if(m_callback) m_callback->exec(); m_text_updated = true; m_cursor_pos = 0; m_cursor_pos_updated=true; } break; case 9: if (!m_text.empty()) { if(m_tab_callback) m_tab_callback->exec(); m_text_updated = true; m_cursor_pos_updated=true; } break; case 127: m_text.erase(m_cursor_pos,1); m_text_updated = true; break; default: m_text.insert(m_cursor_pos++,std::string(1,c)); m_text_updated = true; m_cursor_pos_updated=true; } } if(m_cursor_pos_updated) updateCursorMesh(); if(m_text_updated) updateTextMesh(); } GUINode::update(); } void TextInputNode::updateCursorMesh(){ Font *shellfont = RESOURCE_GET(Font,"shellfont"); m_cursor_mesh->moveTo2D(glm::vec2(m_cursor_pos*shellfont->getXAdvance()*(m_font_size/shellfont->getLineHeight()),0)); m_cursor_pos_updated = false; } void TextInputNode::updateTextMesh(){ Font *shellfont = RESOURCE_GET(Font,"shellfont"); if(m_text_mesh){ this->removeChild(m_text_mesh); m_text_mesh->destroyWhenOrphan(); } m_text_mesh = shellfont->getTextNode(m_text, m_text_color, m_font_size); if(m_text_mesh){ m_text_mesh->setTransform(glm::mat4()); m_text_mesh->setDepth(15); this->addChild(m_text_mesh); } m_text_updated = false; } void TextInputNode::setFocus(bool focus) { m_hasFocus = focus; m_cursor_mesh->setVisible(focus); } void TextInputNode::setText(std::string text){ m_text = text; m_text_updated = true; m_cursor_pos = text.length(); m_cursor_pos_updated = true; } void TextInputNode::setTextColor(glm::vec3 color) { m_text_color = color; } std::string TextInputNode::getText() { return m_text; } void TextInputNode::clearText() { m_history.push_back(m_text); m_history_pos=m_history.size(); m_text.clear(); } void TextInputNode::setInputs(int cursor_left, int cursor_right, int history_up, int history_down) { m_inputActions[TextInputAction::MOVE_CURSOR_LEFT] = cursor_left; m_inputActions[TextInputAction::MOVE_CURSOR_RIGHT] = cursor_right; m_inputActions[TextInputAction::HISTORY_NEXT] = history_down; m_inputActions[TextInputAction::HISTORY_PREVIOUS] = history_up; }