#include "on_screen_keyboard.h" //#include // Constructor OnScreenKeyboard::OnScreenKeyboard(SDL_Renderer *renderer, Input *input, string iconFile, string bitmapFile, string textFile, options_t *options, int width, int height, color_t color) { // Inicializa variables this->renderer = renderer; this->options = options; this->input = input; this->width = width; this->height = height; // Crea objetos iconTexture = new Texture(renderer, iconFile); text = new Text(textFile, bitmapFile, renderer); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height); // Inicializa variables char_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char_lower = "abcdefghijklmnopqrstuvwxyz"; char_numbers = "0123456789"; char_symbol = " !\"#$%&'()*+,-./:;<=>?@[]"; use_char_upper = true; use_char_lower = false; use_char_numbers = false; use_char_symbol = false; setLayout(); caption = ""; dest = {(options->screen.nativeWidth - width) / 2, (options->screen.nativeHeight - height) / 2, width, height}; // Rellena la textura de fondo con el color y el texto fillTexture(); } // Destructor OnScreenKeyboard::~OnScreenKeyboard() { // Libera la memoria de los objetos if (iconTexture != nullptr) { delete iconTexture; } if (text != nullptr) { delete text; } if (texture != nullptr) { SDL_DestroyTexture(texture); } } // Rellena la textura de fondo con el color y el texto void OnScreenKeyboard::fillTexture() { // Destruye la textura si la hubiera if (texture) SDL_DestroyTexture(texture); // Crea la textura height = (text->getCharacterSize() * 4) + (text->getCharacterSize() * rows * 2); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height); dest = {(options->screen.nativeWidth - width) / 2, (options->screen.nativeHeight - height) / 2, width, height}; // Empieza a dibujar en la textura SDL_SetRenderTarget(renderer, texture); // Establece el color de fondo SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255); SDL_RenderClear(renderer); // Escribe el texto que aparece en el objeto text->write(text->getCharacterSize(), text->getCharacterSize(), caption); // Dibuja el cuadro donde va el texto que se escribirá const color_t darkColor = darkenColor(bgColor, 10); SDL_SetRenderDrawColor(renderer, darkColor.r, darkColor.g, darkColor.b, 255); const int x_rect = (text->getCharacterSize() * 2) + text->lenght(caption); const int y_rect = text->getCharacterSize(); const int w_rect = width - text->getCharacterSize() - x_rect; const int h_rect = text->getCharacterSize(); SDL_Rect rect = {x_rect, y_rect, w_rect, h_rect}; SDL_RenderFillRect(renderer, &rect); // Dibuja los caracteres que conformaran el teclado int dist = text->getCharacterSize() * 2; int offset_x = text->getCharacterSize(); int offset_y = text->getCharacterSize() * 3; for (int j = 0; j < rows; ++j) for (int i = 0; i < columns; ++i) { int pos = i + (j * columns); if (pos < (int)layout.size()) { color_t color = randColor(); SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 255); SDL_Rect rect = {offset_x + (layout.at(pos).col * dist), offset_y + (layout.at(pos).row * dist), dist, dist}; SDL_RenderFillRect(renderer, &rect); text->write(offset_x + (layout.at(pos).col * dist) + 4, offset_y + (layout.at(pos).row * dist) + 4, layout.at(pos).caption); } } // Deja de dibujar en la textura SDL_SetRenderTarget(renderer, nullptr); } // Calcula cuantos caracteres se utilizaran para crear el teclado int OnScreenKeyboard::getTotalChars() { int total = 0; total += use_char_upper ? char_upper.length() : 0; total += use_char_lower ? char_lower.length() : 0; total += use_char_numbers ? char_numbers.length() : 0; total += use_char_symbol ? char_symbol.length() : 0; return total; } // Calcula cuantas columnas necesita el teclado int OnScreenKeyboard::getColumns() { const int keyWidth = text->getCharacterSize() * 2; int rowWidth = width - text->getCharacterSize(); return rowWidth / keyWidth; } // Calcula cuantas filas necesita el teclado int OnScreenKeyboard::getRows() { return (totalChars / getColumns())+1; } // Establece la disposición del teclado void OnScreenKeyboard::setLayout() { totalChars = getTotalChars(); columns = getColumns(); rows = getRows(); int index_col = 0; int index_row = 0; // Establece los caracteres a escribir string allChars = ""; allChars = use_char_upper ? allChars + char_upper : allChars; allChars = use_char_lower ? allChars + char_lower : allChars; allChars = use_char_numbers ? allChars + char_numbers : allChars; allChars = use_char_symbol ? allChars + char_symbol : allChars; layout.clear(); for (int i = 0; i < allChars.length(); ++i) { key_t key; key.col = index_col; key.row = index_row; key.caption = allChars.substr(i, 1); layout.push_back(key); //std::cout << key.caption << " " << key.col << " " << key.row << " " << std::endl; ++index_col; if (index_col == columns) { index_col = 0; ++index_row; } } } // Actualiza la lógica del objeto void OnScreenKeyboard::update() { } // Dibuja el objeto en pantalla void OnScreenKeyboard::render() { SDL_RenderCopy(renderer, texture, nullptr, &dest); } // Establece el color de fondo void OnScreenKeyboard::setBgColor(color_t color) { bgColor = color; fillTexture(); } // Establece el texto a mostrar junto al texto a introducir void OnScreenKeyboard::setCaption(string text) { caption = text; fillTexture(); } // Establece qué caracteres ofrecerá el objeto void OnScreenKeyboard::setChars(Uint8 mode) { use_char_upper = ((mode & USE_UPPER) == USE_UPPER); use_char_lower = ((mode & USE_LOWER) == USE_LOWER); use_char_numbers = ((mode & USE_NUMBER) == USE_NUMBER); use_char_symbol = ((mode & USE_SYMBOL) == USE_SYMBOL); setLayout(); fillTexture(); }