Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor script text input #955

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

AllyTally
Copy link
Contributor

@AllyTally AllyTally commented Mar 22, 2023

Changes

This PR adds an input system with selection, copying, pasting, and all of that fun stuff, to the script editor.

NOTE: I'm still new to text input, so if someone else sees issues then feel free to contribute.

Legal Stuff:

By submitting this pull request, I confirm that...

  • My changes may be used in a future commercial release of VVVVVV
  • I will be credited in a CONTRIBUTORS file and the "GitHub Friends"
    section of the credits for all of said releases, but will NOT be compensated
    for these changes

@AllyTally AllyTally force-pushed the textinput branch 2 times, most recently from 964238a to 5b99b38 Compare March 22, 2023 19:31
@InfoTeddy InfoTeddy self-assigned this Mar 29, 2023
@AllyTally AllyTally force-pushed the textinput branch 4 times, most recently from e8e6b89 to 2e887f9 Compare April 2, 2023 21:11
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.
This commit adds HOME, END, PAGEUP, PAGEDOWN, CTRL+LEFT/RIGHT, DEL,
CTRL+BACKSPACE and CTRL+DEL. It also rewrites the text insertion
function to not use stringstreams.
This commit makes the system support single-line text input, and moves
every remaining text input to it. This disables selection and cursor
movement for single line input, since drawing that seems a bit hard
right now.
Copy link
Contributor

@InfoTeddy InfoTeddy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are the warnings I get.

Also, please fix your brace style. There are several places where you use same-line brace instead of next-line brace.

desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/Editor.cpp Outdated Show resolved Hide resolved
Copy link
Contributor

@InfoTeddy InfoTeddy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A warning and some style stuff.

desktop_version/src/Editor.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
desktop_version/src/TextInput.cpp Outdated Show resolved Hide resolved
@AllyTally AllyTally force-pushed the textinput branch 3 times, most recently from 27fc980 to 502a7e0 Compare April 4, 2023 19:48
Co-authored-by: Misa Elizabeth Kai <[email protected]>
Drawing selection & the cursor was very hardcoded before, so why not
let other things use it as well?

This also fixes a bug where selected text is drawn above the text's Y
position.
@InfoTeddy
Copy link
Contributor

Here's a proof-of-concept for drawing the selection box and cursor with centered text (it's just placing the base x-coordinate at the center point and subtracting an offset). The only issue is that moving between lines is still treated as left-aligned and not based on how the text visually looks. With this, you should be able to get the new input working for level descriptions. It can even be trivially adapted to support right-aligned text, too.

diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp
index 79fefb51..aa19cf4b 100644
--- a/desktop_version/src/Editor.cpp
+++ b/desktop_version/src/Editor.cpp
@@ -1571,7 +1571,7 @@ void editorrender(void)
             info.visible_lines = 200 / font::height(PR_FONT_LEVEL);
             info.visible_padding = 48 / font::height(PR_FONT_LEVEL);
 
-            TextInput::draw_text(PR_FONT_LEVEL | PR_CJK_LOW, 16, 20, &ed.script_buffer, info);
+            TextInput::draw_text(PR_CEN | PR_FONT_LEVEL | PR_CJK_LOW, -1, 20, &ed.script_buffer, info);
             break;
         }
         default:
diff --git a/desktop_version/src/TextInput.cpp b/desktop_version/src/TextInput.cpp
index 400e5180..ddf74cab 100644
--- a/desktop_version/src/TextInput.cpp
+++ b/desktop_version/src/TextInput.cpp
@@ -4,6 +4,7 @@
 #include <string>
 #include <vector>
 
+#include "Constants.h"
 #include "Font.h"
 #include "Graphics.h"
 #include "KeyPoll.h"
@@ -776,6 +777,11 @@ namespace TextInput
         const int visible_lines = info.visible_lines;
         const int visible_padding = info.visible_padding;
 
+        if ((flags & PR_CEN) && text_x == -1)
+        {
+            text_x = SCREEN_WIDTH_PIXELS / 2;
+        }
+
         if (cursor_pos.y < display_offset + visible_padding)
         {
             display_offset = SDL_max(0, TextInput::cursor_pos.y - visible_padding);
@@ -792,7 +798,12 @@ namespace TextInput
         {
             if (i + display_offset < (int) text->size())
             {
-                font::print(flags, text_x, text_y + (i * font_height), text->at(i + display_offset), text_color.r, text_color.g, text_color.b);
+                int align_offset = 0;
+                if (flags & PR_CEN)
+                {
+                    align_offset = font::len(flags, text->at(i + display_offset).c_str()) / 2;
+                }
+                font::print(flags & ~PR_CEN, text_x - align_offset, text_y + (i * font_height), text->at(i + display_offset), text_color.r, text_color.g, text_color.b);
             }
         }
 
@@ -813,9 +824,14 @@ namespace TextInput
 
                 char* offset_x = UTF8_substr(text->at(rect.y).c_str(), 0, rect.x);
                 char* cut_string = UTF8_substr(text->at(rect.y).c_str(), rect.x, rect.x2);
+                int align_offset = 0;
+                if (flags & PR_CEN)
+                {
+                    align_offset = font::len(flags, text->at(rect.y).c_str()) / 2;
+                }
 
-                graphics.fill_rect(text_x + font::len(flags, offset_x), text_y + (y - display_offset) * font_height, font::len(flags, cut_string), font_height, text_color);
-                font::print(flags, text_x + font::len(flags, offset_x), text_y + (rect.y2 - display_offset) * font_height, cut_string, selected_color.r, selected_color.g, selected_color.b);
+                graphics.fill_rect(text_x + font::len(flags, offset_x) - align_offset, text_y + (y - display_offset) * font_height, font::len(flags, cut_string), font_height, text_color);
+                font::print(flags & ~PR_CEN, text_x + font::len(flags, offset_x) - align_offset, text_y + (rect.y2 - display_offset) * font_height, cut_string, selected_color.r, selected_color.g, selected_color.b);
 
                 SDL_free(offset_x);
                 SDL_free(cut_string);
@@ -829,9 +845,14 @@ namespace TextInput
                     const char* line = text->at(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));
+                    int align_offset = 0;
+                    if (flags & PR_CEN)
+                    {
+                        align_offset = font::len(flags, line) / 2;
+                    }
 
-                    graphics.fill_rect(text_x + font::len(flags, offset_x), text_y + (rect.y - display_offset) * font_height, SDL_max(font::len(PR_FONT_LEVEL, selection_w), 1), font_height, text_color);
-                    font::print(flags, text_x + font::len(flags, offset_x), text_y + (rect.y - display_offset) * font_height, selection_w, selected_color.r, selected_color.g, selected_color.b);
+                    graphics.fill_rect(text_x + font::len(flags, offset_x) - align_offset, text_y + (rect.y - display_offset) * font_height, SDL_max(font::len(PR_FONT_LEVEL, selection_w), 1), font_height, text_color);
+                    font::print(flags & ~PR_CEN, text_x + font::len(flags, offset_x) - align_offset, text_y + (rect.y - display_offset) * font_height, selection_w, selected_color.r, selected_color.g, selected_color.b);
 
                     SDL_free(offset_x);
                     SDL_free(selection_w);
@@ -843,9 +864,14 @@ namespace TextInput
                     if (local_y >= 0 && local_y < visible_lines)
                     {
                         const int line_width = SDL_max(font::len(flags, text->at(rect.y + i).c_str()), 1);
+                        int align_offset = 0;
+                        if (flags & PR_CEN)
+                        {
+                            align_offset = font::len(flags, text->at(rect.y + i).c_str()) / 2;
+                        }
 
-                        graphics.fill_rect(text_x, text_y + local_y * font_height, line_width, font_height, text_color);
-                        font::print(flags, text_x, text_y + local_y * font_height, text->at(rect.y + i).c_str(), selected_color.r, selected_color.g, selected_color.b);
+                        graphics.fill_rect(text_x - align_offset, text_y + local_y * font_height, line_width, font_height, text_color);
+                        font::print(flags & ~PR_CEN, text_x - align_offset, text_y + local_y * font_height, text->at(rect.y + i).c_str(), selected_color.r, selected_color.g, selected_color.b);
                     }
                 }
 
@@ -854,9 +880,14 @@ namespace TextInput
                     const char* line_2 = text->at(rect.y2).c_str();
                     char* selection_w = UTF8_substr(line_2, 0, rect.x2);
                     const int line_width = SDL_max(font::len(flags, selection_w), 1);
+                    int align_offset = 0;
+                    if (flags & PR_CEN)
+                    {
+                        align_offset = font::len(flags, text->at(rect.y2).c_str()) / 2;
+                    }
 
-                    graphics.fill_rect(text_x, text_y + (rect.y2 - display_offset) * font_height, line_width, font_height, text_color);
-                    font::print(flags, text_x, text_y + (rect.y2 - display_offset) * font_height, selection_w, selected_color.r, selected_color.g, selected_color.b);
+                    graphics.fill_rect(text_x - align_offset, text_y + (rect.y2 - display_offset) * font_height, line_width, font_height, text_color);
+                    font::print(flags & ~PR_CEN, text_x - align_offset, text_y + (rect.y2 - display_offset) * font_height, selection_w, selected_color.r, selected_color.g, selected_color.b);
 
                     SDL_free(selection_w);
                 }
@@ -867,17 +898,22 @@ namespace TextInput
         if (TextInput::flash_timer < 15)
         {
             char* substr = UTF8_substr(text->at(TextInput::cursor_pos.y).c_str(), 0, TextInput::cursor_pos.x);
+            int align_offset = 0;
+            if (flags & PR_CEN)
+            {
+                align_offset = font::len(flags, text->at(TextInput::cursor_pos.y).c_str()) / 2;
+            }
 
             if (TextInput::cursor_pos.x < (int) text->at(TextInput::cursor_pos.y).size() || TextInput::selecting)
             {
                 graphics.set_color(text_color);
-                int x = text_x + font::len(flags, substr);
+                int x = text_x + font::len(flags, substr) - align_offset;
                 int y = text_y + ((TextInput::cursor_pos.y - display_offset) * font_height);
                 SDL_RenderDrawLine(gameScreen.m_renderer, x, y, x, y + font_height - 1);
             }
             else
             {
-                font::print(flags, text_x + font::len(flags, substr), text_y + ((TextInput::cursor_pos.y - display_offset) * font_height), "_", text_color.r, text_color.g, text_color.b);
+                font::print(flags & ~PR_CEN, text_x + font::len(flags, substr) - align_offset, text_y + ((TextInput::cursor_pos.y - display_offset) * font_height), "_", text_color.r, text_color.g, text_color.b);
             }
             SDL_free(substr);
         }

This commit also fixes broken selection copying.
@NyakoFox
Copy link
Contributor

NyakoFox commented Jul 8, 2024

note to self: apparently this breaks terminals/script boxes making new scripts, though a fix is simple (stop using key.keybuffer in input_submitted())

@InfoTeddy
Copy link
Contributor

Conflicts need to be resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants