Improved text input.
This commit is contained in:
parent
59f054cefb
commit
921c937439
4 changed files with 116 additions and 41 deletions
52
src/Bob.cpp
52
src/Bob.cpp
|
@ -1,5 +1,6 @@
|
||||||
#include "Bob.hpp"
|
#include "Bob.hpp"
|
||||||
|
|
||||||
|
|
||||||
void Game::handle_event(SDL_Event *event)
|
void Game::handle_event(SDL_Event *event)
|
||||||
{
|
{
|
||||||
static SDL_Point window_size;
|
static SDL_Point window_size;
|
||||||
|
@ -16,7 +17,7 @@ void Game::handle_event(SDL_Event *event)
|
||||||
{
|
{
|
||||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||||
this->grid->update_dimensions({event->window.data1, event->window.data2});
|
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});
|
event->window.data2});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -71,7 +72,7 @@ void Game::handle_event(SDL_Event *event)
|
||||||
{
|
{
|
||||||
window_size = this->window->toggle_fullscreen();
|
window_size = this->window->toggle_fullscreen();
|
||||||
this->grid->update_dimensions(window_size);
|
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->next_turn_button->update_position({window_size.x - 100, window_size.y - 100});
|
||||||
this->upgrade_box->set_visible(false);
|
this->upgrade_box->set_visible(false);
|
||||||
}
|
}
|
||||||
|
@ -91,9 +92,9 @@ void Game::handle_event(SDL_Event *event)
|
||||||
break;
|
break;
|
||||||
case SDLK_RETURN:
|
case SDLK_RETURN:
|
||||||
input = this->text_input_box->get_input();
|
input = this->text_input_box->get_input();
|
||||||
if (input == "/quit")
|
if (this->text_input_box->get_active())
|
||||||
{
|
{
|
||||||
this->quit = true;
|
this->command(input);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
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()
|
int Game::game_loop()
|
||||||
{
|
{
|
||||||
this->frame_timer->start_timer();
|
this->frame_timer->start_timer();
|
||||||
|
@ -233,7 +275,7 @@ int main(int, char **)
|
||||||
SDL_Rect bounds;
|
SDL_Rect bounds;
|
||||||
SDL_GetDisplayBounds(0, &bounds);
|
SDL_GetDisplayBounds(0, &bounds);
|
||||||
SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600};
|
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;
|
int exit_status = 1;
|
||||||
exit_status = game->game_loop();
|
exit_status = game->game_loop();
|
||||||
delete game;
|
delete game;
|
||||||
|
|
15
src/Bob.hpp
15
src/Bob.hpp
|
@ -20,6 +20,7 @@ class Game
|
||||||
public:
|
public:
|
||||||
Game(SDL_Rect *window_dimensions, Sint16 size)
|
Game(SDL_Rect *window_dimensions, Sint16 size)
|
||||||
{
|
{
|
||||||
|
this->started = false;
|
||||||
this->layout = new Layout(pointy_orientation, 20,
|
this->layout = new Layout(pointy_orientation, 20,
|
||||||
{window_dimensions->w / 2, window_dimensions->h / 2},
|
{window_dimensions->w / 2, window_dimensions->h / 2},
|
||||||
{0, 0, window_dimensions->w, window_dimensions->h});
|
{0, 0, window_dimensions->w, window_dimensions->h});
|
||||||
|
@ -41,15 +42,14 @@ public:
|
||||||
| SDL_RENDERER_TARGETTEXTURE);
|
| SDL_RENDERER_TARGETTEXTURE);
|
||||||
this->grid = new HexagonGrid(size, this->layout, this->renderer);
|
this->grid = new HexagonGrid(size, this->layout, this->renderer);
|
||||||
FieldMeta *center = this->grid->get_field({0, 0, 0});
|
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->field_box = new FieldBox(this->renderer, {0, 0, 100, 100}, fg, this->font, center);
|
||||||
this->upgrade_box = new UpgradeBox(this->renderer, {0, 0, 1, 1}, 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, 1, 1}, fg, this->font);
|
this->test_box = new TextBox(this->renderer, {0, 0, 100, 20}, fg, this->font);
|
||||||
this->test_box->set_visible(true);
|
|
||||||
this->next_turn_button = new NextTurnButtonBox(this->renderer,
|
this->next_turn_button = new NextTurnButtonBox(this->renderer,
|
||||||
{window_size.x - 100, window_size.y - 100, 1, 1}, fg,
|
{window_size.x - 100, window_size.y - 100, 1, 1}, fg,
|
||||||
this->font, &(this->players));
|
this->font, &(this->players));
|
||||||
this->text_input_box = new TextInputBox(this->renderer, {0, window_size.y - 12, window_size.x, 12}, fg,
|
int font_height = TTF_FontHeight(this->font);
|
||||||
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();
|
this->text_input_box->stop();
|
||||||
}
|
}
|
||||||
catch (const SDL_Exception &sdl_except)
|
catch (const SDL_Exception &sdl_except)
|
||||||
|
@ -79,6 +79,8 @@ public:
|
||||||
delete this->layout;
|
delete this->layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void command(std::string command);
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
void handle_event(SDL_Event *event);
|
void handle_event(SDL_Event *event);
|
||||||
|
@ -86,6 +88,7 @@ public:
|
||||||
int game_loop();
|
int game_loop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool started;
|
||||||
TextInputBox *text_input_box;
|
TextInputBox *text_input_box;
|
||||||
std::vector<Player *> players;
|
std::vector<Player *> players;
|
||||||
NextTurnButtonBox *next_turn_button;
|
NextTurnButtonBox *next_turn_button;
|
||||||
|
|
64
src/Gui.cpp
64
src/Gui.cpp
|
@ -23,19 +23,25 @@ bool TextBox::load_text(std::string text)
|
||||||
{
|
{
|
||||||
this->renderer->set_draw_color({0, 0, 0, 0xff});
|
this->renderer->set_draw_color({0, 0, 0, 0xff});
|
||||||
const char *displayed_text = text.c_str();
|
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)
|
if (text_surface == nullptr)
|
||||||
{
|
{
|
||||||
SDL_FreeSurface(text_surface);
|
SDL_FreeSurface(text_surface);
|
||||||
throw SDL_TTFException();
|
throw SDL_TTFException();
|
||||||
}
|
}
|
||||||
this->dimensions.w = text_surface->w;
|
//this->dimensions.w = text_surface->w;
|
||||||
this->dimensions.h = text_surface->h;
|
//this->dimensions.h = text_surface->h;
|
||||||
SDL_Surface *surface = SDL_CreateRGBSurface(0, this->dimensions.w, this->dimensions.h, 32, rmask, gmask, bmask,
|
SDL_Surface *surface = SDL_CreateRGBSurface(0, this->dimensions.w, this->dimensions.h, 32, rmask, gmask, bmask,
|
||||||
amask);
|
amask);
|
||||||
if (surface == nullptr
|
if (surface == nullptr || SDL_LockSurface(surface) < 0 ||
|
||||||
|| SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 255, 255, 255)) < 0
|
SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 255, 255, 255)) < 0)
|
||||||
|| SDL_BlitSurface(text_surface, nullptr, surface, nullptr) < 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!");
|
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)
|
if (event->key.keysym.sym == SDLK_RETURN)
|
||||||
{
|
{
|
||||||
this->input = "";
|
this->input.str("");
|
||||||
changed = true;
|
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;
|
changed = true;
|
||||||
}
|
}
|
||||||
else if (event->key.keysym.sym == SDLK_c && SDL_GetModState() & KMOD_CTRL)
|
else if (event->key.keysym.sym == SDLK_c && SDL_GetModState() & KMOD_CTRL)
|
||||||
{
|
{
|
||||||
SDL_SetClipboardText(input.c_str());
|
SDL_SetClipboardText(input.str().c_str());
|
||||||
changed = true;
|
|
||||||
}
|
}
|
||||||
else if (event->key.keysym.sym == SDLK_v && SDL_GetModState() & KMOD_CTRL)
|
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)
|
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')
|
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))
|
&& (event->text.text[0] == 'v' || event->text.text[0] == 'V') && SDL_GetModState() & KMOD_CTRL))
|
||||||
{
|
{
|
||||||
input += event->text.text;
|
input << event->text.text;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,9 +368,26 @@ void TextInputBox::handle_event(const SDL_Event *event)
|
||||||
}
|
}
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
std::string foo = input; // because SDL_ttf will complain if not
|
std::string text;
|
||||||
foo += " ";
|
text = output.str();
|
||||||
this->load_text(foo);
|
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)
|
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));
|
ext_renderer->copy(this->texture, nullptr, &(this->dimensions));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextInputBox::update_dimensions(SDL_Rect rect)
|
void TextInputBox::update_dimensions(SDL_Rect rect)
|
||||||
{
|
{
|
||||||
this->bg_dimensions = rect;
|
this->dimensions.x = rect.x;
|
||||||
this->dimensions = bg_dimensions;
|
this->dimensions.y = rect.y;
|
||||||
|
this->dimensions.w = rect.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextInputBox::get_active()
|
bool TextInputBox::get_active()
|
||||||
|
|
26
src/Gui.hpp
26
src/Gui.hpp
|
@ -51,7 +51,10 @@ class TextBox : public Box
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextBox(Renderer *renderer, SDL_Rect dimensions, SDL_Color color, TTF_Font *font_)
|
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);
|
bool load_text(std::string text);
|
||||||
|
|
||||||
|
@ -59,16 +62,18 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TTF_Font *font;
|
TTF_Font *font;
|
||||||
|
int font_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextInputBox : TextBox
|
class TextInputBox : TextBox
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextInputBox(Renderer *renderer_, SDL_Rect dimensions_, SDL_Color color_, TTF_Font *font_)
|
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->visible = false;
|
||||||
this->load_text(" ");
|
this->output << "# ";
|
||||||
|
this->load_text(output.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
@ -83,11 +88,14 @@ public:
|
||||||
|
|
||||||
void update_dimensions(SDL_Rect rect);
|
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:
|
private:
|
||||||
SDL_Rect bg_dimensions;
|
Uint16 lines;
|
||||||
std::string input;
|
std::ostringstream output; // what is loaded to the texture - currnt input
|
||||||
|
std::stringstream input; // editable command prompt
|
||||||
};
|
};
|
||||||
|
|
||||||
class FieldBox : public TextBox
|
class FieldBox : public TextBox
|
||||||
|
@ -150,7 +158,6 @@ private:
|
||||||
std::vector<Player *>::iterator current_player;
|
std::vector<Player *>::iterator current_player;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class UpgradeBox : public Box
|
class UpgradeBox : public Box
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -160,13 +167,14 @@ public:
|
||||||
int y = dimensions.y;
|
int y = dimensions.y;
|
||||||
for (Upgrade upgrade : UPGRADES)
|
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));
|
box->load_text(UPGRADE_NAMES.at(upgrade));
|
||||||
y += 20;
|
y += 20;
|
||||||
this->marked_upgrade = box;
|
this->marked_upgrade = box;
|
||||||
this->upgrades.push_back(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()
|
~UpgradeBox()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue