Skip to content

Commit

Permalink
Make script editor use new input system
Browse files Browse the repository at this point in the history
The old input system still exists for one-line inputs, but the script
editor really needs the upgrade. This commit fixes a few bugs with the
input system, and makes the script editor use it.
  • Loading branch information
AllyTally committed Mar 22, 2023
1 parent 8bf5657 commit 964238a
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 92 deletions.
153 changes: 81 additions & 72 deletions desktop_version/src/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "Music.h"
#include "Screen.h"
#include "Script.h"
#include "TextInput.h"
#include "UTF8.h"
#include "UtilityClass.h"
#include "VFormat.h"
Expand Down Expand Up @@ -103,8 +104,6 @@ void editorclass::reset(void)

clear_script_buffer();

script_cursor_x = 0;
script_cursor_y = 0;
script_offset = 0;
lines_visible = 25;
current_script = "null";
Expand Down Expand Up @@ -1509,6 +1508,7 @@ void editorrender(void)

// Draw text
int font_height = font::height(PR_FONT_LEVEL);

for (int i = 0; i < ed.lines_visible; i++)
{
if (i + ed.script_offset < (int) ed.script_buffer.size())
Expand All @@ -1517,10 +1517,77 @@ void editorrender(void)
}
}

// Draw selection

if (TextInput::selecting) {
int x = TextInput::cursor_select_pos.x;
int y = TextInput::cursor_select_pos.y;
int w = TextInput::cursor_pos.x - x;
int h = TextInput::cursor_pos.y - y;

if (h == 0)
{
Selection_Rect rect = TextInput::reorder_selection_positions();
char* offset_x = UTF8_substr(ed.script_buffer[rect.y].c_str(), 0, rect.x);
char* cut_string = UTF8_substr(ed.script_buffer[rect.y].c_str(), rect.x, rect.x2);

graphics.fill_rect(16 + font::len(PR_FONT_LEVEL, offset_x), 20 + (y - ed.script_offset) * font_height, font::len(PR_FONT_LEVEL,cut_string), font_height, graphics.getRGB(123, 111, 218));
font::print(PR_FONT_LEVEL | PR_CJK_LOW, 16 + font::len(PR_FONT_LEVEL, offset_x), 20 + (rect.y2 - ed.script_offset) * font_height, cut_string, 61, 48, 162);

SDL_free(offset_x);
SDL_free(cut_string);
}
else
{
Selection_Rect rect = TextInput::reorder_selection_positions();

const char* line = ed.script_buffer[rect.y].c_str();

char* offset_x = UTF8_substr(line, 0, rect.x);
char* selection_w = UTF8_substr(line, rect.x, UTF8_total_codepoints(line));
graphics.fill_rect(16 + font::len(PR_FONT_LEVEL, offset_x), 20 + (rect.y - ed.script_offset) * font_height, SDL_max(font::len(PR_FONT_LEVEL, selection_w), 1), font_height, graphics.getRGB(123, 111, 218));
font::print(PR_FONT_LEVEL | PR_CJK_LOW, 16 + font::len(PR_FONT_LEVEL, offset_x), 20 + (rect.y - ed.script_offset) * font_height, selection_w, 61, 48, 162);
SDL_free(offset_x);
SDL_free(selection_w);
for (int i = 1; i < rect.y2 - rect.y; i++)
{
if (rect.y + i - ed.script_offset < ed.lines_visible)
{
graphics.fill_rect(16, 20 + (rect.y + i - ed.script_offset) * font_height, SDL_max(font::len(PR_FONT_LEVEL, ed.script_buffer[rect.y + i].c_str()), 1), font_height, graphics.getRGB(123, 111, 218));
font::print(PR_FONT_LEVEL | PR_CJK_LOW, 16, 20 + (rect.y + i - ed.script_offset) * font_height, ed.script_buffer[rect.y + i].c_str(), 61, 48, 162);
}
}

if (rect.y2 - ed.script_offset < ed.lines_visible)
{
const char* line_2 = ed.script_buffer[rect.y2].c_str();

selection_w = UTF8_substr(line_2, 0, rect.x2);
graphics.fill_rect(16, 20 + (rect.y2 - ed.script_offset) * font_height, SDL_max(font::len(PR_FONT_LEVEL, selection_w), 1), font_height, graphics.getRGB(123, 111, 218));
font::print(PR_FONT_LEVEL | PR_CJK_LOW, 16, 20 + (rect.y2 - ed.script_offset) * font_height, selection_w, 61, 48, 162);
SDL_free(offset_x);
SDL_free(selection_w);
}
}
}

// Draw cursor
if (ed.entframe < 2)
if (TextInput::flash_timer < 15)
{
font::print(PR_FONT_LEVEL | PR_CJK_LOW, 16 + font::len(PR_FONT_LEVEL, ed.script_buffer[ed.script_cursor_y].c_str()), 20 + ((ed.script_cursor_y - ed.script_offset) * font_height), "_", 123, 111, 218);
char* substr = UTF8_substr(ed.script_buffer[TextInput::cursor_pos.y].c_str(), 0, TextInput::cursor_pos.x);

if (TextInput::cursor_pos.x < (int)ed.script_buffer[TextInput::cursor_pos.y].size() || TextInput::selecting)
{
graphics.set_color(123, 111, 218);
int x = 16 + font::len(PR_FONT_LEVEL, substr);
int y = 20 + ((TextInput::cursor_pos.y - ed.script_offset) * font_height);
SDL_RenderDrawLine(gameScreen.m_renderer, x, y, x, y + font_height - 1);
}
else
{
font::print(PR_FONT_LEVEL | PR_CJK_LOW, 16 + font::len(PR_FONT_LEVEL, substr), 20 + ((TextInput::cursor_pos.y - ed.script_offset) * font_height), "_", 123, 111, 218);
}
SDL_free(substr);
}
break;
}
Expand Down Expand Up @@ -1832,6 +1899,8 @@ void editorlogic(void)
ed.entframedelay = 8;
}

TextInput::flash_timer = (TextInput::flash_timer + 1) % 30;

ed.old_note_timer = ed.note_timer;
ed.note_timer = SDL_max(ed.note_timer - 1, 0);

Expand Down Expand Up @@ -2301,8 +2370,6 @@ static void editormenuactionpress(void)
ed.script_list_offset = 0;
ed.selected_script = 0;

ed.script_cursor_y = 0;
ed.script_cursor_x = 0;
ed.script_offset = 0;
ed.lines_visible = 200 / font::height(PR_FONT_LEVEL);
break;
Expand Down Expand Up @@ -3217,17 +3284,13 @@ void editorinput(void)
{
game.mapheld = true;
ed.substate = EditorSubState_SCRIPTS_EDIT;
key.enabletextentry();
key.keybuffer = "";
ed.current_text_ptr = &(key.keybuffer);

ed.current_script = script.customscripts[(script.customscripts.size() - 1) - ed.selected_script].name;
ed.load_script_in_editor(ed.current_script);

ed.script_cursor_y = ed.script_buffer.size() - 1;
ed.script_offset = SDL_max(ed.script_cursor_y - (ed.lines_visible - SCRIPT_LINE_PADDING), 0);
ed.script_offset = 0;

key.keybuffer = ed.script_buffer[ed.script_cursor_y];
ed.script_cursor_x = UTF8_total_codepoints(ed.script_buffer[ed.script_cursor_y].c_str());
TextInput::attach_input(&ed.script_buffer);

music.playef(11);
}
Expand All @@ -3244,41 +3307,11 @@ void editorinput(void)

// Alright, now re-add the script.
ed.create_script(ed.current_script, ed.script_buffer);
TextInput::detach_input();
}

if (ed.keydelay > 0) ed.keydelay--;

if (up_pressed && ed.keydelay <= 0)
{
ed.keydelay = 3;
ed.script_cursor_y = SDL_max(0, ed.script_cursor_y - 1);

key.keybuffer = ed.script_buffer[ed.script_cursor_y];
}

if (down_pressed && ed.keydelay <= 0)
{
ed.keydelay = 3;
ed.script_cursor_y = SDL_min((int) ed.script_buffer.size() - 1, ed.script_cursor_y + 1);

key.keybuffer = ed.script_buffer[ed.script_cursor_y];
}

if (key.linealreadyemptykludge)
{
ed.keydelay = 6;
key.linealreadyemptykludge = false;
}

if (key.pressedbackspace && ed.script_buffer[ed.script_cursor_y] == "" && ed.keydelay <= 0)
{
//Remove this line completely
ed.remove_line(ed.script_cursor_y);
ed.script_cursor_y = SDL_max(0, ed.script_cursor_y - 1);
key.keybuffer = ed.script_buffer[ed.script_cursor_y];
ed.keydelay = 6;
}

/* Remove all pipes, they are the line separator in the XML
* When this loop reaches the end, it wraps to SIZE_MAX; SIZE_MAX + 1 is 0 */
{size_t i; for (i = key.keybuffer.length() - 1; i + 1 > 0; --i)
Expand All @@ -3289,38 +3322,14 @@ void editorinput(void)
}
}}

ed.script_buffer[ed.script_cursor_y] = key.keybuffer;
ed.script_cursor_x = UTF8_total_codepoints(ed.script_buffer[ed.script_cursor_y].c_str());

if (enter_pressed)
{
//Continue to next line
if (ed.script_cursor_y >= (int)ed.script_buffer.size()) //we're on the last line
{
ed.script_cursor_y++;

key.keybuffer = ed.script_buffer[ed.script_cursor_y];
ed.script_cursor_x = UTF8_total_codepoints(ed.script_buffer[ed.script_cursor_y].c_str());
}
else
{
//We're not, insert a line instead
ed.script_cursor_y++;

ed.insert_line(ed.script_cursor_y);
key.keybuffer = "";
ed.script_cursor_x = 0;
}
}

if (ed.script_cursor_y < ed.script_offset + SCRIPT_LINE_PADDING)
if (TextInput::cursor_pos.y < ed.script_offset + SCRIPT_LINE_PADDING)
{
ed.script_offset = SDL_max(0, ed.script_cursor_y - SCRIPT_LINE_PADDING);
ed.script_offset = SDL_max(0, TextInput::cursor_pos.y - SCRIPT_LINE_PADDING);
}

if (ed.script_cursor_y > ed.script_offset + ed.lines_visible - SCRIPT_LINE_PADDING)
if (TextInput::cursor_pos.y > ed.script_offset + ed.lines_visible - SCRIPT_LINE_PADDING)
{
ed.script_offset = SDL_min((int) ed.script_buffer.size() - ed.lines_visible + SCRIPT_LINE_PADDING, ed.script_cursor_y - ed.lines_visible + SCRIPT_LINE_PADDING);
ed.script_offset = SDL_min((int) ed.script_buffer.size() - ed.lines_visible + SCRIPT_LINE_PADDING, TextInput::cursor_pos.y - ed.lines_visible + SCRIPT_LINE_PADDING);
}

break;
Expand Down
1 change: 0 additions & 1 deletion desktop_version/src/Editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@ class editorclass

std::vector<std::string> script_buffer;
std::string current_script;
int script_cursor_x, script_cursor_y;
int script_offset;
int lines_visible;

Expand Down
2 changes: 1 addition & 1 deletion desktop_version/src/KeyPoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void KeyPoll::disabletextentry(void)

bool KeyPoll::textentry(void)
{
return SDL_IsTextInputActive() == SDL_TRUE;
return SDL_IsTextInputActive() == SDL_TRUE && !TextInput::taking_input;
}

void KeyPoll::toggleFullscreen(void)
Expand Down
27 changes: 18 additions & 9 deletions desktop_version/src/TextInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,20 @@ namespace TextInput {
current_text = text;
selecting = false;
flash_timer = 0;
SDL_StartTextInput();

send_cursor_to_end();
}

void detach_input(void) {
taking_input = false;
SDL_StopTextInput();
}

void send_cursor_to_end(void)
{
cursor_pos.x = current_text->size() - 1;
cursor_pos.y = current_text->at(cursor_pos.x).size();
cursor_pos.y = current_text->size() - 1;
cursor_pos.x = UTF8_total_codepoints(current_text->at(cursor_pos.y).c_str());
cursor_x_tallest = cursor_pos.x;
}

Expand All @@ -48,8 +50,8 @@ namespace TextInput {
std::string output; // We'll need the output later
while (std::getline(string_stream, output)) { // Iterate through all lines,
output.erase(std::remove(output.begin(), output.end(), '\r'), output.end()); // Strip \r... dammit Windows.
(*current_text)[cursor_pos.y].insert(cursor_pos.x, output); // Insert the current line of text into our text
cursor_pos.x += output.length(); // Update cursor position
current_text->at(cursor_pos.y).insert(cursor_pos.x, output); // Insert the current line of text into our text
cursor_pos.x += UTF8_total_codepoints(output.c_str()); // Update cursor position
if (!string_stream.eof()) { // If we haven't hit the end of the file,
insert_newline(); // Insert a newline
}
Expand Down Expand Up @@ -180,7 +182,7 @@ namespace TextInput {
Selection_Rect rect = reorder_selection_positions();

if (rect.y == rect.y2) {
return UTF8_substr(current_text->at(rect.y).c_str(), rect.x, rect.x2 - rect.x);
return UTF8_substr(current_text->at(rect.y).c_str(), rect.x, rect.x2);
}

char* select_part_first_line = UTF8_substr(current_text->at(rect.y).c_str(), rect.x, UTF8_total_codepoints(current_text->at(rect.y).c_str()) - rect.x);
Expand Down Expand Up @@ -244,9 +246,9 @@ namespace TextInput {
return;
}
// Get the rest of the last line
char* rest_of_string = UTF8_substr(current_text->at(y2).c_str(), x2, UTF8_total_codepoints(current_text->at(y2).c_str()) - x2);
char* rest_of_string = UTF8_substr(current_text->at(y2).c_str(), x2, UTF8_total_codepoints(current_text->at(y2).c_str()));

for (int i = y2; i >= y; i--)
for (int i = y2; i > y; i--)
{
if (cursor_pos.y >= i)
{
Expand All @@ -262,10 +264,11 @@ namespace TextInput {
}

// Erase from the start of the selection to the end
char* erased = UTF8_erase(current_text->at(y).c_str(), x, x2 - x);
char* erased = UTF8_erase(current_text->at(y).c_str(), x, UTF8_total_codepoints(current_text->at(y).c_str()));
current_text->at(y) = erased;
// Add the rest of the last line to the end of the first line
current_text->at(y) += rest_of_string;
cursor_pos.x = x;
SDL_free(erased);
SDL_free(rest_of_string);
}
Expand Down Expand Up @@ -310,7 +313,7 @@ namespace TextInput {
else
{
// Erase the character before the cursor
char* erased = UTF8_erase(current_text->at(cursor_pos.y).c_str(), cursor_pos.x - 1, 1);
char* erased = UTF8_erase(current_text->at(cursor_pos.y).c_str(), cursor_pos.x - 1, cursor_pos.x);
current_text->at(cursor_pos.y) = erased;
SDL_free(erased);

Expand All @@ -324,6 +327,9 @@ namespace TextInput {
if (!taking_input) return;

if (e.type == SDL_KEYDOWN) {
// Show cursor!!
flash_timer = 0;

// Handle backspace
if (e.key.keysym.sym == SDLK_BACKSPACE)
{
Expand Down Expand Up @@ -374,6 +380,9 @@ namespace TextInput {
//Special text input event
else if (e.type == SDL_TEXTINPUT)
{
// Show cursor!!
flash_timer = 0;

//Append character(s)
if (selecting) {
remove_selection();
Expand Down
8 changes: 8 additions & 0 deletions desktop_version/src/TextInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,18 @@ struct Selection_Rect

namespace TextInput
{
extern bool taking_input;
extern bool selecting;
extern int flash_timer;
extern SDL_Point cursor_pos;
extern SDL_Point cursor_select_pos;

void send_cursor_to_end(void);
void insert_newline(void);
Selection_Rect reorder_selection_positions(void);
void handle_events(SDL_Event e);
void attach_input(std::vector<std::string>* text);
void detach_input(void);
}

#endif /* TEXTINPUT_H */
Loading

0 comments on commit 964238a

Please sign in to comment.