Improved text input.

This commit is contained in:
Tim Schubert 2016-01-28 03:06:19 +01:00
parent 59f054cefb
commit 921c937439
4 changed files with 116 additions and 41 deletions

View file

@ -1,5 +1,6 @@
#include "Bob.hpp"
void Game::handle_event(SDL_Event *event)
{
static SDL_Point window_size;
@ -16,7 +17,7 @@ void Game::handle_event(SDL_Event *event)
{
case SDL_WINDOWEVENT_SIZE_CHANGED:
this->grid->update_dimensions({event->window.data1, event->window.data2});
this->text_input_box->update_dimensions({0, event->window.data2 - 12, event->window.data1,
this->text_input_box->update_dimensions({0, 0, event->window.data1,
event->window.data2});
break;
default:
@ -71,7 +72,7 @@ void Game::handle_event(SDL_Event *event)
{
window_size = this->window->toggle_fullscreen();
this->grid->update_dimensions(window_size);
this->text_input_box->update_dimensions({0, window_size.y - window_size.x, 12});
this->text_input_box->update_dimensions({0, window_size.y - 20, 0, 20});
this->next_turn_button->update_position({window_size.x - 100, window_size.y - 100});
this->upgrade_box->set_visible(false);
}
@ -91,9 +92,9 @@ void Game::handle_event(SDL_Event *event)
break;
case SDLK_RETURN:
input = this->text_input_box->get_input();
if (input == "/quit")
if (this->text_input_box->get_active())
{
this->quit = true;
this->command(input);
}
break;
default:
@ -149,6 +150,47 @@ void Game::handle_event(SDL_Event *event)
}
}
void Game::command(std::string input)
{
std::ostringstream prompt;
if (input == "quit")
{
prompt << "Quitting the game";
this->quit = true;
}
else if (input == "test")
{
prompt << "This is a test!";
}
else if (input == "surrender")
{
//Player::current_player->surrender();
}
else if (!this->started)
{
if (input.substr(0, 11) == "add player")
{
Player *added = new Player(input.substr(11, std::string::npos));
/*if (!this->grid->place(added))
{
this->text_input_box->output << "Failed to add player:" << added->get_name();
delete added;
}
else
{
this->players.push_back(added);
}
*/
}
else if (input == "start")
{
//this->start_game();
prompt << "Started the game.";
}
}
this->text_input_box->prompt(prompt.str());
}
int Game::game_loop()
{
this->frame_timer->start_timer();
@ -233,7 +275,7 @@ int main(int, char **)
SDL_Rect bounds;
SDL_GetDisplayBounds(0, &bounds);
SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600};
Game *game = new Game(&window_dimensions, 20);
Game *game = new Game(&window_dimensions, 10);
int exit_status = 1;
exit_status = game->game_loop();
delete game;

View file

@ -20,6 +20,7 @@ class Game
public:
Game(SDL_Rect *window_dimensions, Sint16 size)
{
this->started = false;
this->layout = new Layout(pointy_orientation, 20,
{window_dimensions->w / 2, window_dimensions->h / 2},
{0, 0, window_dimensions->w, window_dimensions->h});
@ -41,15 +42,14 @@ public:
| SDL_RENDERER_TARGETTEXTURE);
this->grid = new HexagonGrid(size, this->layout, this->renderer);
FieldMeta *center = this->grid->get_field({0, 0, 0});
this->field_box = new FieldBox(this->renderer, {0, 0, 1, 1}, fg, this->font, center);
this->upgrade_box = new UpgradeBox(this->renderer, {0, 0, 1, 1}, fg, this->font, center);
this->test_box = new TextBox(this->renderer, {0, 0, 1, 1}, fg, this->font);
this->test_box->set_visible(true);
this->field_box = new FieldBox(this->renderer, {0, 0, 100, 100}, fg, this->font, center);
this->upgrade_box = new UpgradeBox(this->renderer, {0, 0, 100, 20}, fg, this->font, center);
this->test_box = new TextBox(this->renderer, {0, 0, 100, 20}, fg, this->font);
this->next_turn_button = new NextTurnButtonBox(this->renderer,
{window_size.x - 100, window_size.y - 100, 1, 1}, fg,
this->font, &(this->players));
this->text_input_box = new TextInputBox(this->renderer, {0, window_size.y - 12, window_size.x, 12}, fg,
this->font);
int font_height = TTF_FontHeight(this->font);
this->text_input_box = new TextInputBox(this->renderer, {0, 0, window_size.x, font_height}, fg, this->font);
this->text_input_box->stop();
}
catch (const SDL_Exception &sdl_except)
@ -79,6 +79,8 @@ public:
delete this->layout;
}
void command(std::string command);
void render();
void handle_event(SDL_Event *event);
@ -86,6 +88,7 @@ public:
int game_loop();
private:
bool started;
TextInputBox *text_input_box;
std::vector<Player *> players;
NextTurnButtonBox *next_turn_button;

View file

@ -23,19 +23,25 @@ bool TextBox::load_text(std::string text)
{
this->renderer->set_draw_color({0, 0, 0, 0xff});
const char *displayed_text = text.c_str();
SDL_Surface *text_surface = TTF_RenderUTF8_Blended_Wrapped(this->font, displayed_text, this->color, 100);
SDL_Surface *text_surface = TTF_RenderUTF8_Blended_Wrapped(this->font, displayed_text, this->color,
this->dimensions.w);
if (text_surface == nullptr)
{
SDL_FreeSurface(text_surface);
throw SDL_TTFException();
}
this->dimensions.w = text_surface->w;
this->dimensions.h = text_surface->h;
//this->dimensions.w = text_surface->w;
//this->dimensions.h = text_surface->h;
SDL_Surface *surface = SDL_CreateRGBSurface(0, this->dimensions.w, this->dimensions.h, 32, rmask, gmask, bmask,
amask);
if (surface == nullptr
|| SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 255, 255, 255)) < 0
|| SDL_BlitSurface(text_surface, nullptr, surface, nullptr) < 0)
if (surface == nullptr || SDL_LockSurface(surface) < 0 ||
SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 255, 255, 255)) < 0)
{
throw SDL_Exception("Failed to fill rect behind text!");
}
//SDL_Rect text_rect = {this->dimensions.x, this->dimensions.y, surface->w, surface->h};
SDL_UnlockSurface(surface);
if (SDL_BlitSurface(text_surface, nullptr, surface, nullptr) < 0)
{
throw SDL_Exception("Failed to create background text_surface!");
}
@ -328,23 +334,23 @@ void TextInputBox::handle_event(const SDL_Event *event)
{
if (event->key.keysym.sym == SDLK_RETURN)
{
this->input = "";
this->input.str("");
changed = true;
}
else if (event->key.keysym.sym == SDLK_BACKSPACE && this->input.length() > 0)
else if (event->key.keysym.sym == SDLK_BACKSPACE)
{
input.pop_back();
input << '\b';
input << " ";
changed = true;
}
else if (event->key.keysym.sym == SDLK_c && SDL_GetModState() & KMOD_CTRL)
{
SDL_SetClipboardText(input.c_str());
changed = true;
SDL_SetClipboardText(input.str().c_str());
}
else if (event->key.keysym.sym == SDLK_v && SDL_GetModState() & KMOD_CTRL)
{
input = SDL_GetClipboardText();
input << SDL_GetClipboardText();
changed = true;
}
}
else if (event->type == SDL_TEXTINPUT)
@ -352,7 +358,7 @@ void TextInputBox::handle_event(const SDL_Event *event)
if (!((event->text.text[0] == 'c' || event->text.text[0] == 'C')
&& (event->text.text[0] == 'v' || event->text.text[0] == 'V') && SDL_GetModState() & KMOD_CTRL))
{
input += event->text.text;
input << event->text.text;
changed = true;
}
}
@ -362,9 +368,26 @@ void TextInputBox::handle_event(const SDL_Event *event)
}
if (changed)
{
std::string foo = input; // because SDL_ttf will complain if not
foo += " ";
this->load_text(foo);
std::string text;
text = output.str();
text += input.str();
if (text.empty())
text += " ";
this->load_text(text);
}
}
void TextInputBox::prompt(std::string message)
{
this->output << this->input.str() << "\n" << message << "\n# ";
this->lines += 2;
this->dimensions.h = (this->font_height * lines);
this->load_text(output.str());
if (this->dimensions.h > 500)
{
this->lines = 2;
output.str("");
this->prompt(message);
}
}
@ -372,16 +395,15 @@ void TextInputBox::render(Renderer *ext_renderer)
{
if (this->texture != nullptr && this->visible)
{
ext_renderer->set_draw_color({0xff, 0xff, 0xff, 0x00});
SDL_RenderFillRect(ext_renderer->get_renderer(), &(bg_dimensions));
ext_renderer->copy(this->texture, nullptr, &(this->dimensions));
}
}
void TextInputBox::update_dimensions(SDL_Rect rect)
{
this->bg_dimensions = rect;
this->dimensions = bg_dimensions;
this->dimensions.x = rect.x;
this->dimensions.y = rect.y;
this->dimensions.w = rect.w;
}
bool TextInputBox::get_active()

View file

@ -51,7 +51,10 @@ class TextBox : public Box
{
public:
TextBox(Renderer *renderer, SDL_Rect dimensions, SDL_Color color, TTF_Font *font_)
: Box(renderer, dimensions, color), font(font_) { }
: Box(renderer, dimensions, color), font(font_)
{
this->font_height = TTF_FontHeight(font);
}
bool load_text(std::string text);
@ -59,16 +62,18 @@ public:
protected:
TTF_Font *font;
int font_height;
};
class TextInputBox : TextBox
{
public:
TextInputBox(Renderer *renderer_, SDL_Rect dimensions_, SDL_Color color_, TTF_Font *font_)
: TextBox(renderer_, dimensions_, color_, font_), bg_dimensions(dimensions_), input("")
: TextBox(renderer_, dimensions_, color_, font_), input(""), lines(1)
{
this->visible = false;
this->load_text(" ");
this->output << "# ";
this->load_text(output.str());
}
void start();
@ -83,11 +88,14 @@ public:
void update_dimensions(SDL_Rect rect);
std::string get_input() { return this->input; }
std::string get_input() { return this->input.str(); }
void prompt(std::string message);
private:
SDL_Rect bg_dimensions;
std::string input;
Uint16 lines;
std::ostringstream output; // what is loaded to the texture - currnt input
std::stringstream input; // editable command prompt
};
class FieldBox : public TextBox
@ -150,7 +158,6 @@ private:
std::vector<Player *>::iterator current_player;
};
class UpgradeBox : public Box
{
public:
@ -160,13 +167,14 @@ public:
int y = dimensions.y;
for (Upgrade upgrade : UPGRADES)
{
UpgradeButtonBox *box = new UpgradeButtonBox(renderer, {0, y, 1, 1}, color, font, this, upgrade);
UpgradeButtonBox *box = new UpgradeButtonBox(renderer, {0, y, dimensions.w, 20}, color, font, this,
upgrade);
box->load_text(UPGRADE_NAMES.at(upgrade));
y += 20;
this->marked_upgrade = box;
this->upgrades.push_back(box);
}
this->upgrade_info = new TextBox(renderer, {0, 0, 1, 1}, color, font);
this->upgrade_info = new TextBox(renderer, {0, 0, dimensions.w, 200}, color, font);
}
~UpgradeBox()