mirror of https://github.com/OpenRCT2/OpenRCT2.git
textbox widget
This commit is contained in:
parent
dd84ee8340
commit
9f9143a5c6
14
src/input.c
14
src/input.c
|
@ -736,6 +736,12 @@ static void input_widget_left(int x, int y, rct_window *w, int widgetIndex)
|
|||
if (widgetIndex == -1)
|
||||
return;
|
||||
|
||||
if (windowClass != gCurrentTextBox.window.classification ||
|
||||
windowNumber != gCurrentTextBox.window.number ||
|
||||
widgetIndex != gCurrentTextBox.widget_index) {
|
||||
window_cancel_textbox();
|
||||
}
|
||||
|
||||
widget = &w->widgets[widgetIndex];
|
||||
|
||||
switch (widget->type) {
|
||||
|
@ -1173,8 +1179,10 @@ void game_handle_keyboard_input()
|
|||
|
||||
// Reserve backtick for console
|
||||
if (key == SDL_SCANCODE_GRAVE) {
|
||||
if (gConfigGeneral.debugging_tools || gConsoleOpen)
|
||||
if (gConfigGeneral.debugging_tools || gConsoleOpen) {
|
||||
window_cancel_textbox();
|
||||
console_toggle();
|
||||
}
|
||||
continue;
|
||||
} else if (gConsoleOpen) {
|
||||
console_input(key);
|
||||
|
@ -1195,7 +1203,7 @@ void game_handle_keyboard_input()
|
|||
if (w != NULL){
|
||||
((void(*)(int, rct_window*))w->event_handlers[WE_TEXT_INPUT])(key, w);
|
||||
}
|
||||
else {
|
||||
else if (!gUsingWidgetTextBox) {
|
||||
keyboard_shortcut_handle(key);
|
||||
}
|
||||
}
|
||||
|
@ -1374,7 +1382,7 @@ void game_handle_key_scroll()
|
|||
rct_window *textWindow;
|
||||
|
||||
textWindow = window_find_by_class(WC_TEXTINPUT);
|
||||
if (textWindow) return;
|
||||
if (textWindow || gUsingWidgetTextBox) return;
|
||||
|
||||
scrollX = 0;
|
||||
scrollY = 0;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "../sprites.h"
|
||||
#include "widget.h"
|
||||
#include "window.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../localisation/localisation.h"
|
||||
|
||||
static void widget_frame_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
|
||||
static void widget_resize_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
|
||||
|
@ -35,6 +37,7 @@ static void widget_text_unknown(rct_drawpixelinfo *dpi, rct_window *w, int widge
|
|||
static void widget_text(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
|
||||
static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
|
||||
static void widget_text_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
|
||||
static void widget_text_box_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
|
||||
static void widget_groupbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
|
||||
static void widget_caption_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
|
||||
static void widget_checkbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
|
||||
|
@ -160,6 +163,9 @@ void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
|
|||
break;
|
||||
case WWT_25:
|
||||
break;
|
||||
case WWT_TEXT_BOX:
|
||||
widget_text_box_draw(dpi, w, widgetIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1124,4 +1130,77 @@ void widget_set_checkbox_value(rct_window *w, int widgetIndex, int value)
|
|||
w->pressed_widgets |= (1ULL << widgetIndex);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << widgetIndex);
|
||||
}
|
||||
}
|
||||
|
||||
static void widget_text_box_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
|
||||
{
|
||||
rct_widget* widget;
|
||||
int l, t, r, b;
|
||||
uint8 colour;
|
||||
int no_lines = 0;
|
||||
int font_height = 0;
|
||||
char wrapped_string[512];
|
||||
|
||||
// Get the widget
|
||||
widget = &w->widgets[widgetIndex];
|
||||
|
||||
// Resolve the absolute ltrb
|
||||
l = w->x + widget->left;
|
||||
t = w->y + widget->top;
|
||||
r = w->x + widget->right;
|
||||
b = w->y + widget->bottom;
|
||||
|
||||
// Get the colour
|
||||
colour = w->colours[widget->colour];
|
||||
|
||||
|
||||
bool active = w->classification == gCurrentTextBox.window.classification &&
|
||||
w->number == gCurrentTextBox.window.number &&
|
||||
widgetIndex == gCurrentTextBox.widget_index;
|
||||
|
||||
//gfx_fill_rect_inset(dpi, l, t, r, b, colour, 0x20 | (!active ? 0x40 : 0x00));
|
||||
gfx_fill_rect_inset(dpi, l, t, r, b, colour, 0x60);
|
||||
|
||||
|
||||
if (!active) {
|
||||
|
||||
if (w->widgets[widgetIndex].image != 0) {
|
||||
strcpy(wrapped_string, (char*)w->widgets[widgetIndex].image);
|
||||
gfx_wrap_string(wrapped_string, r - l - 5, &no_lines, &font_height);
|
||||
gfx_draw_string(dpi, wrapped_string, w->colours[1], l + 2, t);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
strcpy(wrapped_string, gTextBoxInput);
|
||||
|
||||
// String length needs to add 12 either side of box
|
||||
// +13 for cursor when max length.
|
||||
gfx_wrap_string(wrapped_string, r - l - 5 - 6, &no_lines, &font_height);
|
||||
|
||||
|
||||
gfx_draw_string(dpi, wrapped_string, w->colours[1], l + 2, t);
|
||||
|
||||
|
||||
int string_length = get_string_length(wrapped_string);
|
||||
|
||||
// Make a copy of the string for measuring the width.
|
||||
char temp_string[512] = { 0 };
|
||||
memcpy(temp_string, wrapped_string, min(string_length, gTextInputCursorPosition));
|
||||
int cur_x = l + gfx_get_string_width(temp_string) + 3;
|
||||
|
||||
int width = 6;
|
||||
if ((uint32)gTextInputCursorPosition < strlen(gTextBoxInput)){
|
||||
// Make a new 1 character wide string for measuring the width
|
||||
// of the character that the cursor is under.
|
||||
temp_string[1] = '\0';
|
||||
temp_string[0] = gTextBoxInput[gTextInputCursorPosition];
|
||||
width = max(gfx_get_string_width(temp_string) - 2, 4);
|
||||
}
|
||||
|
||||
if (gTextBoxFrameNo <= 15){
|
||||
uint8 colour = RCT2_ADDRESS(0x0141FC48, uint8)[w->colours[1] * 8];
|
||||
gfx_fill_rect(dpi, cur_x, t + 9, cur_x + width, t + 9, colour + 5);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,8 @@ typedef enum {
|
|||
WWT_CHECKBOX = 23,
|
||||
WWT_24,
|
||||
WWT_25,
|
||||
WWT_LAST = 26,
|
||||
WWT_TEXT_BOX = 26,
|
||||
WWT_LAST = 27,
|
||||
} WINDOW_WIDGET_TYPES;
|
||||
#define WIDGETS_END WWT_LAST, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "widget.h"
|
||||
#include "window.h"
|
||||
#include "viewport.h"
|
||||
#include "../localisation/string_ids.h"
|
||||
#include "../localisation/localisation.h"
|
||||
|
||||
#define RCT2_FIRST_WINDOW (RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window))
|
||||
#define RCT2_LAST_WINDOW (RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*) - 1)
|
||||
|
@ -39,6 +41,11 @@
|
|||
rct_window* g_window_list = RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window);
|
||||
|
||||
uint8 TextInputDescriptionArgs[8];
|
||||
widget_identifier gCurrentTextBox = { { 255, 0 }, 0 };
|
||||
char gTextBoxInput[512] = { 0 };
|
||||
int gMaxTextBoxInputLength = 0;
|
||||
int gTextBoxFrameNo = 0;
|
||||
bool gUsingWidgetTextBox = 0;
|
||||
|
||||
// converted from uint16 values at 0x009A41EC - 0x009A4230
|
||||
// these are percentage coordinates of the viewport to center to, if a window is obscuring a location, the next is tried
|
||||
|
@ -2177,4 +2184,70 @@ void textinput_cancel()
|
|||
window_event_textinput_call(w, RCT2_GLOBAL(RCT2_ADDRESS_TEXTINPUT_WIDGETINDEX, uint16), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void window_start_textbox(rct_window *call_w, int call_widget, rct_string_id existing_text, uint32 existing_args, int maxLength)
|
||||
{
|
||||
if (gUsingWidgetTextBox)
|
||||
window_cancel_textbox();
|
||||
|
||||
gUsingWidgetTextBox = true;
|
||||
gCurrentTextBox.window.classification = call_w->classification;
|
||||
gCurrentTextBox.window.number = call_w->number;
|
||||
gCurrentTextBox.widget_index = call_widget;
|
||||
gTextBoxFrameNo = 0;
|
||||
|
||||
gMaxTextBoxInputLength = maxLength;
|
||||
|
||||
window_close_by_class(WC_TEXTINPUT);
|
||||
|
||||
// Clear the text input buffer
|
||||
memset(gTextBoxInput, 0, maxLength);
|
||||
|
||||
// Enter in the the text input buffer any existing
|
||||
// text.
|
||||
if (existing_text != (rct_string_id)STR_NONE)
|
||||
format_string(gTextBoxInput, existing_text, &existing_args);
|
||||
|
||||
// In order to prevent strings that exceed the maxLength
|
||||
// from crashing the game.
|
||||
gTextBoxInput[maxLength - 1] = '\0';
|
||||
|
||||
platform_start_text_input(gTextBoxInput, maxLength);
|
||||
}
|
||||
|
||||
void window_cancel_textbox()
|
||||
{
|
||||
if (gUsingWidgetTextBox) {
|
||||
rct_window *w = window_find_by_number(
|
||||
gCurrentTextBox.window.classification,
|
||||
gCurrentTextBox.window.number
|
||||
);
|
||||
gCurrentTextBox.window.classification = 255;
|
||||
gCurrentTextBox.window.number = 0;
|
||||
platform_stop_text_input();
|
||||
gUsingWidgetTextBox = false;
|
||||
widget_invalidate(w, gCurrentTextBox.widget_index);
|
||||
gCurrentTextBox.widget_index = WWT_LAST;
|
||||
}
|
||||
}
|
||||
|
||||
void window_update_textbox_caret()
|
||||
{
|
||||
gTextBoxFrameNo++;
|
||||
if (gTextBoxFrameNo > 30)
|
||||
gTextBoxFrameNo = 0;
|
||||
}
|
||||
|
||||
void window_update_textbox()
|
||||
{
|
||||
if (gUsingWidgetTextBox) {
|
||||
gTextBoxFrameNo = 0;
|
||||
rct_window *w = window_find_by_number(
|
||||
gCurrentTextBox.window.classification,
|
||||
gCurrentTextBox.window.number
|
||||
);
|
||||
widget_invalidate(w, gCurrentTextBox.widget_index);
|
||||
window_event_textinput_call(w, gCurrentTextBox.widget_index, gTextBoxInput);
|
||||
}
|
||||
}
|
|
@ -31,6 +31,10 @@
|
|||
struct rct_window;
|
||||
union rct_window_event;
|
||||
extern uint8 TextInputDescriptionArgs[8];
|
||||
extern char gTextBoxInput[512];
|
||||
extern int gMaxTextBoxInputLength;
|
||||
extern int gTextBoxFrameNo;
|
||||
extern bool gUsingWidgetTextBox;
|
||||
|
||||
typedef void wndproc(struct rct_window*, union rct_window_event*);
|
||||
|
||||
|
@ -47,6 +51,8 @@ typedef struct {
|
|||
int widget_index;
|
||||
} widget_identifier;
|
||||
|
||||
extern widget_identifier gCurrentTextBox;
|
||||
|
||||
/**
|
||||
* Widget structure
|
||||
* size: 0x10
|
||||
|
@ -605,6 +611,11 @@ void textinput_cancel();
|
|||
void window_move_and_snap(rct_window *w, int newWindowX, int newWindowY, int snapProximity);
|
||||
int window_can_resize(rct_window *w);
|
||||
|
||||
void window_start_textbox(rct_window *call_w, int call_widget, rct_string_id existing_text, uint32 existing_args, int maxLength);
|
||||
void window_cancel_textbox();
|
||||
void window_update_textbox_caret();
|
||||
void window_update_textbox();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define window_get_register(w) \
|
||||
__asm mov w, esi
|
||||
|
|
|
@ -389,6 +389,7 @@ void platform_process_messages()
|
|||
gTextInputCursorPosition--;
|
||||
gTextInputLength--;
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
}
|
||||
if (e.key.keysym.sym == SDLK_END){
|
||||
gTextInputCursorPosition = gTextInputLength;
|
||||
|
@ -403,6 +404,10 @@ void platform_process_messages()
|
|||
gTextInput[gTextInputMaxLength - 1] = '\0';
|
||||
gTextInputLength--;
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
}
|
||||
if (e.key.keysym.sym == SDLK_RETURN && gTextInput) {
|
||||
window_cancel_textbox();
|
||||
}
|
||||
if (e.key.keysym.sym == SDLK_LEFT && gTextInput){
|
||||
if (gTextInputCursorPosition) gTextInputCursorPosition--;
|
||||
|
@ -432,7 +437,7 @@ void platform_process_messages()
|
|||
|
||||
gTextInputCursorPosition++;
|
||||
}
|
||||
|
||||
window_update_textbox();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -479,6 +484,7 @@ void platform_process_messages()
|
|||
|
||||
gTextInputCursorPosition++;
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -115,7 +115,7 @@ static rct_widget window_editor_object_selection_widgets[] = {
|
|||
{ WWT_FLATBTN, 1, 391, 504, 46, 159, 0xFFFFFFFF, STR_NONE },
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 384, 595, 24, 35, STR_INSTALL_NEW_TRACK_DESIGN, STR_INSTALL_NEW_TRACK_DESIGN_TIP },
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 350, 463, 23, 34, 5261, 5265 },
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 4, 214, 46, 57, STR_NONE, STR_NONE },
|
||||
{ WWT_TEXT_BOX, 1, 4, 214, 46, 57, (uint32)_filter_string, STR_NONE },
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 218, 287, 46, 57, 5277, STR_NONE },
|
||||
{ WIDGETS_END }
|
||||
};
|
||||
|
@ -130,6 +130,7 @@ static void window_editor_object_selection_close();
|
|||
static void window_editor_object_selection_mouseup();
|
||||
static void window_editor_object_selection_mousedown(int widgetIndex, rct_window*w, rct_widget* widget);
|
||||
static void window_editor_object_selection_dropdown();
|
||||
static void window_editor_object_selection_update(rct_window *w);
|
||||
static void window_editor_object_selection_scrollgetsize();
|
||||
static void window_editor_object_selection_scroll_mousedown();
|
||||
static void window_editor_object_selection_scroll_mouseover();
|
||||
|
@ -146,7 +147,7 @@ static void* window_editor_object_selection_events[] = {
|
|||
(void*)window_editor_object_selection_mousedown,
|
||||
(void*)window_editor_object_selection_dropdown,
|
||||
(void*)window_editor_object_selection_emptysub,
|
||||
(void*)window_editor_object_selection_emptysub,
|
||||
(void*)window_editor_object_selection_update,
|
||||
(void*)window_editor_object_selection_emptysub,
|
||||
(void*)window_editor_object_selection_emptysub,
|
||||
(void*)window_editor_object_selection_emptysub,
|
||||
|
@ -356,7 +357,8 @@ static void window_editor_object_selection_mouseup()
|
|||
window_loadsave_open(LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK);
|
||||
break;
|
||||
case WIDX_FILTER_STRING_BUTTON:
|
||||
window_text_input_open(w, widgetIndex, 5275, 5276, 1170, (uint32)_filter_string, 40);
|
||||
//window_text_input_open(w, widgetIndex, 5275, 5276, 1170, (uint32)_filter_string, 40);
|
||||
window_start_textbox(w, widgetIndex, 1170, (uint32)_filter_string, 40);
|
||||
break;
|
||||
case WIDX_FILTER_CLEAR_BUTTON:
|
||||
memset(_filter_string, 0, sizeof(_filter_string));
|
||||
|
@ -698,7 +700,7 @@ static void window_editor_object_selection_paint()
|
|||
|
||||
rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*);
|
||||
|
||||
gfx_fill_rect_inset(dpi,
|
||||
/*gfx_fill_rect_inset(dpi,
|
||||
w->x + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].left,
|
||||
w->y + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].top,
|
||||
w->x + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].right,
|
||||
|
@ -716,7 +718,7 @@ static void window_editor_object_selection_paint()
|
|||
w->x + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].left + 1,
|
||||
w->y + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].top,
|
||||
w->x + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].right
|
||||
);
|
||||
);*/
|
||||
|
||||
if (w->selected_list_item == -1 || stex_entry == NULL)
|
||||
return;
|
||||
|
@ -1034,6 +1036,15 @@ static void editor_load_selected_objects()
|
|||
}
|
||||
}
|
||||
|
||||
static void window_editor_object_selection_update(rct_window *w)
|
||||
{
|
||||
if (gCurrentTextBox.window.classification == w->classification &&
|
||||
gCurrentTextBox.window.number == w->number) {
|
||||
window_update_textbox_caret();
|
||||
widget_invalidate(w, WIDX_FILTER_STRING_BUTTON);
|
||||
}
|
||||
}
|
||||
|
||||
static void window_editor_object_selection_textinput()
|
||||
{
|
||||
uint8 result;
|
||||
|
@ -1045,6 +1056,10 @@ static void window_editor_object_selection_textinput()
|
|||
|
||||
if (widgetIndex != WIDX_FILTER_STRING_BUTTON || !result)
|
||||
return;
|
||||
|
||||
if (strcmp(_filter_string, text) == 0)
|
||||
return;
|
||||
|
||||
if (strlen(text) == 0) {
|
||||
memset(_filter_string, 0, sizeof(_filter_string));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue