diff options
author | Simon Howard | 2013-04-01 14:59:34 +0000 |
---|---|---|
committer | Simon Howard | 2013-04-01 14:59:34 +0000 |
commit | 47af28e16863f08efd7f8f8ab04b9bcf44846cbd (patch) | |
tree | 34a49cc30f9ff65c0e56fc6c2708a2eb17f81ecb | |
parent | 917aa5b184fdfc03a80ce46fb857c3a2780dc705 (diff) | |
parent | bd0f386997cccbeb41103d76f3dc6d9484800f0d (diff) | |
download | chocolate-doom-47af28e16863f08efd7f8f8ab04b9bcf44846cbd.tar.gz chocolate-doom-47af28e16863f08efd7f8f8ab04b9bcf44846cbd.tar.bz2 chocolate-doom-47af28e16863f08efd7f8f8ab04b9bcf44846cbd.zip |
Merge from trunk.
Subversion-branch: /branches/v2-branch
Subversion-revision: 2577
-rw-r--r-- | src/setup/multiplayer.c | 10 | ||||
-rw-r--r-- | textscreen/Makefile.am | 1 | ||||
-rw-r--r-- | textscreen/examples/guitest.c | 23 | ||||
-rw-r--r-- | textscreen/textscreen.h | 1 | ||||
-rw-r--r-- | textscreen/txt_fileselect.c | 676 | ||||
-rw-r--r-- | textscreen/txt_fileselect.h | 88 | ||||
-rw-r--r-- | textscreen/txt_inputbox.c | 25 | ||||
-rw-r--r-- | textscreen/txt_widget.h | 1 |
8 files changed, 813 insertions, 12 deletions
diff --git a/src/setup/multiplayer.c b/src/setup/multiplayer.c index e9f18799..eac9d550 100644 --- a/src/setup/multiplayer.c +++ b/src/setup/multiplayer.c @@ -68,6 +68,8 @@ static int found_iwad_selected; static char *iwadfile; +static char *wad_extensions[] = { "wad", "lmp", "deh", NULL }; + static char *doom_skills[] = { "I'm too young to die.", "Hey, not too rough.", "Hurt me plenty.", @@ -163,7 +165,7 @@ static void AddWADs(execute_context_t *exec) { int have_wads = 0; int i; - + for (i=0; i<NUM_WADS; ++i) { if (wads[i] != NULL && strlen(wads[i]) > 0) @@ -277,7 +279,7 @@ static void StartGame(int multiplayer) AddWADs(exec); TXT_Shutdown(); - + M_SaveDefaults(); PassThroughArguments(exec); @@ -610,7 +612,9 @@ static void OpenWadsWindow(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(user_data)) for (i=0; i<NUM_WADS; ++i) { - TXT_AddWidget(window, TXT_NewInputBox(&wads[i], 60)); + TXT_AddWidget(window, + TXT_NewFileSelector(&wads[i], 60, "Select a WAD file", + wad_extensions)); } } diff --git a/textscreen/Makefile.am b/textscreen/Makefile.am index 4fd87868..2c04ff0f 100644 --- a/textscreen/Makefile.am +++ b/textscreen/Makefile.am @@ -16,6 +16,7 @@ libtextscreen_a_SOURCES = \ txt_checkbox.c txt_checkbox.h \ txt_desktop.c txt_desktop.h \ txt_dropdown.c txt_dropdown.h \ + txt_fileselect.c txt_fileselect.h \ txt_gui.c txt_gui.h \ txt_inputbox.c txt_inputbox.h \ txt_io.c txt_io.h \ diff --git a/textscreen/examples/guitest.c b/textscreen/examples/guitest.c index a5aad93f..08faae98 100644 --- a/textscreen/examples/guitest.c +++ b/textscreen/examples/guitest.c @@ -39,10 +39,13 @@ enum RADIO_VALUE_MUSHROOM, RADIO_VALUE_SNAKE, }; +char *extensions[] = { "wad", "lmp", "txt", NULL }; char *radio_values[] = { "Badger", "Mushroom", "Snake" }; char *textbox_value = NULL; int numbox_value = 0; int radiobutton_value; +char *file_path = NULL; +char *dir_path = NULL; txt_label_t *value_label; txt_window_t *firstwin; int cheesy; @@ -187,12 +190,20 @@ void Window2(void) TXT_AddWidget(window, TXT_NewSeparator("Input boxes")); table = TXT_NewTable(2); TXT_AddWidget(window, table); - TXT_AddWidget(table, TXT_NewLabel("String: ")); - TXT_AddWidget(table, TXT_NewInputBox(&textbox_value, 20)); - TXT_AddWidget(table, TXT_NewLabel("Int: ")); - TXT_AddWidget(table, TXT_NewIntInputBox(&numbox_value, 10)); - TXT_AddWidget(table, TXT_NewLabel("Spin control:")); - TXT_AddWidget(table, TXT_NewSpinControl(&numbox_value, 0, 15)); + TXT_AddWidgets(table, + TXT_NewLabel("String: "), + TXT_NewInputBox(&textbox_value, 20), + TXT_NewLabel("Int: "), + TXT_NewIntInputBox(&numbox_value, 10), + TXT_NewLabel("Spin control:"), + TXT_NewSpinControl(&numbox_value, 0, 15), + TXT_NewLabel("File:"), + TXT_NewFileSelector(&file_path, 28, "Select file:", + extensions), + TXT_NewLabel("Directory:"), + TXT_NewFileSelector(&dir_path, 28, "Select directory:", + TXT_DIRECTORY), + NULL); TXT_AddWidget(window, TXT_NewSeparator("Scroll pane test")); scrollpane = TXT_NewScrollPane(40, 5, TXT_NewLabel( diff --git a/textscreen/textscreen.h b/textscreen/textscreen.h index c01e96c8..54397d88 100644 --- a/textscreen/textscreen.h +++ b/textscreen/textscreen.h @@ -29,6 +29,7 @@ #include "txt_checkbox.h" #include "txt_desktop.h" #include "txt_dropdown.h" +#include "txt_fileselect.h" #include "txt_inputbox.h" #include "txt_label.h" #include "txt_radiobutton.h" diff --git a/textscreen/txt_fileselect.c b/textscreen/txt_fileselect.c new file mode 100644 index 00000000..56fa1108 --- /dev/null +++ b/textscreen/txt_fileselect.c @@ -0,0 +1,676 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2013 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- +// +// Routines for selecting files. +// +//----------------------------------------------------------------------------- + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "doomkeys.h" + +#include "txt_fileselect.h" +#include "txt_inputbox.h" +#include "txt_main.h" +#include "txt_widget.h" + +struct txt_fileselect_s { + txt_widget_t widget; + txt_inputbox_t *inputbox; + int size; + char *prompt; + char **extensions; +}; + +// Dummy value to select a directory. + +char *TXT_DIRECTORY[] = { "__directory__", NULL }; + +#ifndef _WIN32 + +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <sys/wait.h> + +static char *ExecReadOutput(char **argv) +{ + char *result; + int completed; + int pid, status, result_len; + int pipefd[2]; + + if (pipe(pipefd) != 0) + { + return NULL; + } + + pid = fork(); + + if (pid == 0) + { + dup2(pipefd[1], fileno(stdout)); + execv(argv[0], argv); + exit(-1); + } + + fcntl(pipefd[0], F_SETFL, O_NONBLOCK); + + // Read program output into 'result' string. + // Wait until the program has completed and (if it was successful) + // a full line has been read. + + result = NULL; + result_len = 0; + completed = 0; + + while (!completed + || (status == 0 && (result == NULL || strchr(result, '\n') == NULL))) + { + char buf[64]; + int bytes; + + if (!completed && waitpid(pid, &status, WNOHANG) != 0) + { + completed = 1; + } + + bytes = read(pipefd[0], buf, sizeof(buf)); + + if (bytes < 0) + { + if (errno != EAGAIN && errno != EWOULDBLOCK) + { + status = -1; + break; + } + } + else + { + result = realloc(result, result_len + bytes + 1); + memcpy(result + result_len, buf, bytes); + result_len += bytes; + result[result_len] = '\0'; + } + + usleep(100 * 1000); + TXT_Sleep(1); + TXT_UpdateScreen(); + } + + close(pipefd[0]); + close(pipefd[1]); + + // Must have a success exit code. + + if (WEXITSTATUS(status) != 0) + { + free(result); + result = NULL; + } + + // Strip off newline from the end. + + if (result != NULL && result[result_len - 1] == '\n') + { + result[result_len - 1] = '\0'; + } + + return result; +} + +#endif + +#if defined(_WIN32) + +// Windows code. Use comdlg32 to pop up a dialog box. + +#include <windows.h> +#include <shlobj.h> + +static BOOL WINAPI (*MyGetOpenFileName)(LPOPENFILENAME) = NULL; +static LPITEMIDLIST (*MySHBrowseForFolder)(LPBROWSEINFO) = NULL; +static BOOL (*MySHGetPathFromIDList)(LPITEMIDLIST, LPTSTR) = NULL; + +// Load library functions from DLL files. + +static int LoadDLLs(void) +{ + HMODULE comdlg32 = LoadLibraryW(L"comdlg32.dll"); + HMODULE shell32 = LoadLibraryW(L"shell32.dll"); + + if (comdlg32 == NULL || shell32 == NULL) + { + return 0; + } + + MyGetOpenFileName = + (void *) GetProcAddress(comdlg32, "GetOpenFileNameA"); + MySHBrowseForFolder = + (void *) GetProcAddress(shell32, "SHBrowseForFolder"); + MySHGetPathFromIDList = + (void *) GetProcAddress(shell32, "SHGetPathFromIDList"); + + return MyGetOpenFileName != NULL + && MySHBrowseForFolder != NULL + && MySHGetPathFromIDList != NULL; +} + +static int InitLibraries(void) +{ + static int initted = 0, success = 0; + + if (!initted) + { + success = LoadDLLs(); + initted = 1; + } + + return success; +} + +// Generate the "filter" string from the list of extensions. + +static char *GenerateFilterString(char **extensions) +{ + unsigned int result_len = 1; + unsigned int i; + char *result, *out; + + if (extensions == NULL) + { + return NULL; + } + + for (i = 0; extensions[i] != NULL; ++i) + { + result_len += 16 + strlen(extensions[i]) * 3; + } + + result = malloc(result_len); + out = result; + + for (i = 0; extensions[i] != NULL; ++i) + { + // .wad files (*.wad)\0 + out += 1 + sprintf(out, "%s files (*.%s)", + extensions[i], extensions[i]); + // *.wad\0 + out += 1 + sprintf(out, "*.%s", extensions[i]); + } + + *out = '\0'; + + return result; +} + +int TXT_CanSelectFiles(void) +{ + return InitLibraries(); +} + +static char *SelectDirectory(char *window_title) +{ + LPITEMIDLIST pidl; + BROWSEINFO bi; + char selected[MAX_PATH] = ""; + char *result; + + ZeroMemory(&bi, sizeof(bi)); + bi.hwndOwner = NULL; + bi.lpszTitle = window_title; + bi.pszDisplayName = selected; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; + + pidl = MySHBrowseForFolder(&bi); + + result = NULL; + + if (pidl != NULL) + { + if (MySHGetPathFromIDList(pidl, selected)) + { + result = strdup(selected); + } + + // TODO: Free pidl + } + + return result; +} + +char *TXT_SelectFile(char *window_title, char **extensions) +{ + OPENFILENAME fm; + char selected[MAX_PATH] = ""; + char *filter_string, *result; + + if (!InitLibraries()) + { + return NULL; + } + + if (extensions == TXT_DIRECTORY) + { + return SelectDirectory(window_title); + } + + filter_string = GenerateFilterString(extensions); + + ZeroMemory(&fm, sizeof(fm)); + fm.lStructSize = sizeof(OPENFILENAME); + fm.hwndOwner = NULL; + fm.lpstrTitle = window_title; + fm.lpstrFilter = filter_string; + fm.lpstrFile = selected; + fm.nMaxFile = MAX_PATH; + fm.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + fm.lpstrDefExt = ""; + + if (!MyGetOpenFileName(&fm)) + { + result = NULL; + } + else + { + result = strdup(selected); + } + + free(filter_string); + + return result; +} + +#elif defined(__MACOSX__) + +// Mac OS X code. Popping up a dialog requires Objective C/Cocoa +// but we can get away with using AppleScript which avoids adding +// an Objective C dependency. This is rather silly. + +// Printf format string for the "wrapper" portion of the AppleScript: + +#define APPLESCRIPT_WRAPPER \ + "tell application (path to frontmost application as text)\n" \ + " set theFile to (%s)\n" \ + " copy POSIX path of theFile to stdout\n" \ + "end tell\n" + +static char *EscapedString(char *s) +{ + char *result; + char *in, *out; + + result = malloc(strlen(s) + 3); + out = result; + *out++ = '\"'; + for (in = s; *in != '\0'; ++in) + { + if (*in == '\"' || *in == '\\') + { + *out++ = '\\'; + } + *out++ = *in; + } + *out++ = '\"'; + *out = '\0'; + + return result; +} + +// Build list of extensions, like: {"wad","lmp","txt"} + +static char *ExtensionsList(char **extensions) +{ + char *result, *escaped; + unsigned int result_len; + unsigned int i; + + if (extensions == NULL) + { + return NULL; + } + + result_len = 3; + for (i = 0; extensions[i] != NULL; ++i) + { + result_len += 5 + strlen(extensions[i]) * 2; + } + + result = malloc(result_len); + strcpy(result, "{"); + + for (i = 0; extensions[i] != NULL; ++i) + { + escaped = EscapedString(extensions[i]); + strcat(result, escaped); + free(escaped); + + if (extensions[i + 1] != NULL) + strcat(result, ","); + } + + strcat(result, "}"); + + return result; +} + +static char *GenerateSelector(char *window_title, char **extensions) +{ + char *chooser, *ext_list, *result; + unsigned int result_len; + + result_len = 64; + + if (extensions == TXT_DIRECTORY) + { + chooser = "choose folder"; + ext_list = NULL; + } + else + { + chooser = "choose file"; + ext_list = ExtensionsList(extensions); + } + + // Calculate size. + + if (window_title != NULL) + { + window_title = EscapedString(window_title); + result_len += strlen(window_title); + } + if (ext_list != NULL) + { + result_len += strlen(ext_list); + } + + result = malloc(result_len); + + strcpy(result, chooser); + + if (window_title != NULL) + { + strcat(result, " with prompt "); + strcat(result, window_title); + free(window_title); + } + + if (ext_list != NULL) + { + strcat(result, "of type "); + strcat(result, ext_list); + free(ext_list); + } + + return result; +} + +static char *GenerateAppleScript(char *window_title, char **extensions) +{ + char *selector, *result; + + selector = GenerateSelector(window_title, extensions); + + result = malloc(strlen(APPLESCRIPT_WRAPPER) + strlen(selector)); + sprintf(result, APPLESCRIPT_WRAPPER, selector); + free(selector); + + return result; +} + +int TXT_CanSelectFiles(void) +{ + return 1; +} + +char *TXT_SelectFile(char *window_title, char **extensions) +{ + char *argv[4]; + char *result, *applescript; + + applescript = GenerateAppleScript(window_title, extensions); + + argv[0] = "/usr/bin/osascript"; + argv[1] = "-e"; + argv[2] = applescript; + argv[3] = NULL; + + result = ExecReadOutput(argv); + + free(applescript); + + return result; +} + +#else + +// Linux version: invoke the Zenity command line program to pop up a +// dialog box. This avoids adding Gtk+ as a compile dependency. + +#define ZENITY_BINARY "/usr/bin/zenity" + +static unsigned int NumExtensions(char **extensions) +{ + unsigned int result = 0; + + if (extensions != NULL) + { + for (result = 0; extensions[result] != NULL; ++result); + } + + return result; +} + +static int ZenityAvailable(void) +{ + return system(ZENITY_BINARY " --help >/dev/null 2>&1") == 0; +} + +int TXT_CanSelectFiles(void) +{ + return ZenityAvailable(); +} + +char *TXT_SelectFile(char *window_title, char **extensions) +{ + unsigned int i; + char *result; + char **argv; + int argc; + + if (!ZenityAvailable()) + { + return NULL; + } + + argv = calloc(4 + NumExtensions(extensions), sizeof(char *)); + argv[0] = ZENITY_BINARY; + argv[1] = "--file-selection"; + argc = 2; + + if (window_title != NULL) + { + argv[argc] = malloc(10 + strlen(window_title)); + sprintf(argv[argc], "--title=%s", window_title); + ++argc; + } + + if (extensions == TXT_DIRECTORY) + { + argv[argc] = strdup("--directory"); + ++argc; + } + else if (extensions != NULL) + { + for (i = 0; extensions[i] != NULL; ++i) + { + argv[argc] = malloc(30 + strlen(extensions[i]) * 2); + sprintf(argv[argc], "--file-filter=.%s | *.%s", + extensions[i], extensions[i]); + ++argc; + } + } + + argv[argc] = NULL; + + result = ExecReadOutput(argv); + + for (i = 2; i < argc; ++i) + { + free(argv[i]); + } + + free(argv); + + return result; +} + +#endif + +static void TXT_FileSelectSizeCalc(TXT_UNCAST_ARG(fileselect)) +{ + TXT_CAST_ARG(txt_fileselect_t, fileselect); + + // Calculate widget size, but override the width to always + // be the configured size. + + TXT_CalcWidgetSize(fileselect->inputbox); + fileselect->widget.w = fileselect->size; + fileselect->widget.h = fileselect->inputbox->widget.h; +} + +static void TXT_FileSelectDrawer(TXT_UNCAST_ARG(fileselect)) +{ + TXT_CAST_ARG(txt_fileselect_t, fileselect); + + // Input box widget inherits all the properties of the + // file selector. + + fileselect->inputbox->widget.x = fileselect->widget.x; + fileselect->inputbox->widget.y = fileselect->widget.y; + fileselect->inputbox->widget.w = fileselect->widget.w; + fileselect->inputbox->widget.h = fileselect->widget.h; + + TXT_DrawWidget(fileselect->inputbox); +} + +static void TXT_FileSelectDestructor(TXT_UNCAST_ARG(fileselect)) +{ + TXT_CAST_ARG(txt_fileselect_t, fileselect); + + TXT_DestroyWidget(fileselect->inputbox); +} + +static int DoSelectFile(txt_fileselect_t *fileselect) +{ + char *path; + char **var; + + if (TXT_CanSelectFiles()) + { + path = TXT_SelectFile(fileselect->prompt, + fileselect->extensions); + var = fileselect->inputbox->value; + free(*var); + *var = path; + return 1; + } + + return 0; +} + +static int TXT_FileSelectKeyPress(TXT_UNCAST_ARG(fileselect), int key) +{ + TXT_CAST_ARG(txt_fileselect_t, fileselect); + + // When the enter key is pressed, pop up a file selection dialog, + // if file selectors work. Allow holding down 'alt' to override + // use of the native file selector, so the user can just type a path. + + if (!fileselect->inputbox->editing + && !TXT_GetModifierState(TXT_MOD_ALT) + && key == KEY_ENTER) + { + if (DoSelectFile(fileselect)) + { + return 1; + } + } + + return TXT_WidgetKeyPress(fileselect->inputbox, key); +} + +static void TXT_FileSelectMousePress(TXT_UNCAST_ARG(fileselect), + int x, int y, int b) +{ + TXT_CAST_ARG(txt_fileselect_t, fileselect); + + if (!fileselect->inputbox->editing + && !TXT_GetModifierState(TXT_MOD_ALT) + && b == TXT_MOUSE_LEFT) + { + if (DoSelectFile(fileselect)) + { + return; + } + } + + return TXT_WidgetMousePress(fileselect->inputbox, x, y, b); +} + +static void TXT_FileSelectFocused(TXT_UNCAST_ARG(fileselect), int focused) +{ + TXT_CAST_ARG(txt_fileselect_t, fileselect); + + TXT_SetWidgetFocus(fileselect->inputbox, focused); +} + +txt_widget_class_t txt_fileselect_class = +{ + TXT_AlwaysSelectable, + TXT_FileSelectSizeCalc, + TXT_FileSelectDrawer, + TXT_FileSelectKeyPress, + TXT_FileSelectDestructor, + TXT_FileSelectMousePress, + NULL, + TXT_FileSelectFocused, +}; + +txt_fileselect_t *TXT_NewFileSelector(char **variable, int size, + char *prompt, char **extensions) +{ + txt_fileselect_t *fileselect; + + fileselect = malloc(sizeof(txt_fileselect_t)); + TXT_InitWidget(fileselect, &txt_fileselect_class); + fileselect->inputbox = TXT_NewInputBox(variable, 1024); + fileselect->inputbox->widget.parent = &fileselect->widget; + fileselect->size = size; + fileselect->prompt = prompt; + fileselect->extensions = extensions; + + return fileselect; +} + diff --git a/textscreen/txt_fileselect.h b/textscreen/txt_fileselect.h new file mode 100644 index 00000000..dc65643d --- /dev/null +++ b/textscreen/txt_fileselect.h @@ -0,0 +1,88 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2013 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- +// +// Routines for selecting files, and the txt_fileselect_t widget. +// +//----------------------------------------------------------------------------- + +#ifndef TXT_FILESELECT_H +#define TXT_FILESELECT_H + +/** + * @file txt_fileselect.h + * + * File selection widget. + */ + +/** + * File selection widget. + * + * A file selection widget resembles an input box (@ref txt_inputbox_t) + * but opens a file selector dialog box when clicked. + */ + +typedef struct txt_fileselect_s txt_fileselect_t; + +/** + * Returns non-zero if a native file selector is available on this + * platform. + */ + +int TXT_CanSelectFiles(void); + +/** + * Open a native file selector to select a file. + * + * @param prompt Pointer to a string containing a prompt to display + * in the window. + * @param extensions NULL-terminated list of filename extensions for + * files that can be selected, or @ref TXT_DIRECTORY + * to select directories. + */ + +char *TXT_SelectFile(char *prompt, char **extensions); + +/** + * Create a new txt_fileselect_t widget. + * + * @param variable Pointer to a char * variable in which the selected + * file should be stored. + * @param size Width of the file selector widget in characters. + * @param prompt Pointer to a string containing a prompt to display + * in the file selection window. + * @param extensions NULL-terminated list of filename extensions that + * can be used for this widget, or @ref TXT_DIRECTORY + * to select directories. + */ + +txt_fileselect_t *TXT_NewFileSelector(char **variable, int size, + char *prompt, char **extensions); + +/** + * Special value to use for 'extensions' that selects a directory + * instead of a file. + */ + +extern char *TXT_DIRECTORY[]; + +#endif /* #ifndef TXT_FILESELECT_H */ + diff --git a/textscreen/txt_inputbox.c b/textscreen/txt_inputbox.c index 0f2986cc..13d35aef 100644 --- a/textscreen/txt_inputbox.c +++ b/textscreen/txt_inputbox.c @@ -139,9 +139,21 @@ static void TXT_InputBoxDrawer(TXT_UNCAST_ARG(inputbox)) SetBufferFromValue(inputbox); } - TXT_DrawUTF8String(inputbox->buffer); + // If string size exceeds the widget's width, show only the end. - chars = TXT_UTF8_Strlen(inputbox->buffer); + if (TXT_UTF8_Strlen(inputbox->buffer) > w - 1) + { + TXT_DrawString("\xae"); + TXT_DrawUTF8String( + TXT_UTF8_SkipChars(inputbox->buffer, + TXT_UTF8_Strlen(inputbox->buffer) - w + 2)); + chars = w - 1; + } + else + { + TXT_DrawUTF8String(inputbox->buffer); + chars = TXT_UTF8_Strlen(inputbox->buffer); + } if (chars < w && inputbox->editing && focused) { @@ -204,6 +216,15 @@ static int TXT_InputBoxKeyPress(TXT_UNCAST_ARG(inputbox), int key) return 1; } + // Backspace or delete erases the contents of the box. + + if ((key == KEY_DEL || key == KEY_BACKSPACE) + && inputbox->widget.widget_class == &txt_inputbox_class) + { + free(*((char **)inputbox->value)); + *((char **) inputbox->value) = strdup(""); + } + return 0; } diff --git a/textscreen/txt_widget.h b/textscreen/txt_widget.h index f64b9517..3bde760d 100644 --- a/textscreen/txt_widget.h +++ b/textscreen/txt_widget.h @@ -168,7 +168,6 @@ int TXT_HoveringOverWidget(TXT_UNCAST_ARG(widget)); * whether it is selected and the mouse is hovering over it. * * @param widget The widget. - * @param selected Whether the widget is selected. */ void TXT_SetWidgetBG(TXT_UNCAST_ARG(widget)); |