Skip to content

Commit

Permalink
-Implement console input autocomplete preview
Browse files Browse the repository at this point in the history
-Add new config preference: ShowAutoCompletePreview
-Add new console command: console_autocomplete_preview
-Modify functionality of up/down arrow keys when in-game console is open: If autocomplete suggestions exist for current input, up/down arrows cycle through the suggestions
  • Loading branch information
SeanPesce committed Sep 5, 2017
1 parent b8e8bcd commit 5528826
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 22 deletions.
5 changes: 5 additions & 0 deletions include/SpD3D9OConsole.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#define _SP_D3D9O_C_PREF_KEY_CARET_BLINK_ "CaretBlinkDelay"
#define _SP_D3D9O_C_PREF_KEY_BORDER_WIDTH_ "BorderWidth"
#define _SP_D3D9O_C_PREF_KEY_OUTPUT_LINES_ "OutputLines"
#define _SP_D3D9O_C_PREF_KEY_AUTOCOMPLETE_PREVIEW_ "ShowAutoCompletePreview"
#define _SP_D3D9O_C_PREF_KEY_AUTOCOMPLETE_LIMIT_ "AutoCompleteLimit"
#define _SP_D3D9O_C_PREF_KEY_CURSOR_SHOW_ "ShowMouseCursor"
#define _SP_D3D9O_C_PREF_KEY_CURSOR_SIZE_ "MouseCursorSize"
Expand All @@ -57,12 +58,14 @@
#define _SP_D3D9O_C_DEFAULT_BACKGROUND_COLOR_ D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.5f) // Black
#define _SP_D3D9O_C_DEFAULT_BORDER_COLOR_ D3DXCOLOR(0.5f, 0.5f, 0.5f, 0.5f) // Gray
#define _SP_D3D9O_C_DEFAULT_BORDER_WIDTH_ 3
#define _SP_D3D9O_C_DEFAULT_AUTOCOMP_PREVIEW_COLOR_ D3DXCOLOR(0.65f, 0.65f, 0.65f, 0.5f) // Slightly lighter gray
#define _SP_D3D9O_C_DEFAULT_AUTOCOMP_BACKGROUND_COLOR_ _SP_D3D9O_C_DEFAULT_BACKGROUND_COLOR_
#define _SP_D3D9O_C_DEFAULT_AUTOCOMP_BACKGROUND_HOVER_COLOR_ D3DXCOLOR(0xFF1C1C1C) // Very dark gray
#define _SP_D3D9O_C_DEFAULT_AUTOCOMP_BACKGROUND_SELECT_COLOR_ D3DXCOLOR(0xFF333333) // Dark gray
#define _SP_D3D9O_C_DEFAULT_AUTOCOMP_BORDER_COLOR_ _SP_D3D9O_C_DEFAULT_BORDER_COLOR_
#define _SP_D3D9O_C_DEFAULT_AUTOCOMP_BORDER_WIDTH_ 1
#define _SP_D3D9O_C_DEFAULT_OUTPUT_LINES_ 15
#define _SP_D3D9O_C_DEFAULT_SHOW_AUTOCOMP_PREVIEW_ true
#define _SP_D3D9O_C_DEFAULT_AUTOCOMPLETE_LIMIT_ 5
#define _SP_D3D9O_C_DEFAULT_PROMPT_ELEMENTS_ (SP_D3D9O_PROMPT_ELEMENTS_DISABLED)
#define _SP_D3D9O_C_DEFAULT_CURSOR_SHOW_ true
Expand Down Expand Up @@ -90,6 +93,7 @@ typedef struct SP_D3D9O_CONSOLE_COLORS {
D3DXCOLOR text_cursor = _SP_D3D9O_C_DEFAULT_CURSOR_COLOR_; // Color of the text-selection cursor
D3DXCOLOR background = _SP_D3D9O_C_DEFAULT_BACKGROUND_COLOR_; // Main console window background color
D3DXCOLOR border = _SP_D3D9O_C_DEFAULT_BORDER_COLOR_; // Main console window border color
D3DXCOLOR autocomplete_preview = _SP_D3D9O_C_DEFAULT_AUTOCOMP_PREVIEW_COLOR_; // Autocomplete preview text (appears after current input string, showing the remaining substring of the selected autocomplete suggestion)
D3DXCOLOR autocomplete_bg = _SP_D3D9O_C_DEFAULT_AUTOCOMP_BACKGROUND_COLOR_; // Normal background color for autocomplete box
D3DXCOLOR autocomplete_border = _SP_D3D9O_C_DEFAULT_AUTOCOMP_BORDER_COLOR_; // Autocomplete box border color
D3DXCOLOR autocomplete_bg_hover = _SP_D3D9O_C_DEFAULT_AUTOCOMP_BACKGROUND_HOVER_COLOR_; // Background color for autocomplete entry when mouse cursor is hovering, but right mouse button is not pressed
Expand Down Expand Up @@ -185,6 +189,7 @@ class SpD3D9OConsole
CONSOLE_TEXT_SELECTION selection; // Struct that holds cursor selection data

unsigned int command_log_position = 0; // Used to obtain previous commands with the up/down keys
bool autocomplete_preview = _SP_D3D9O_C_DEFAULT_SHOW_AUTOCOMP_PREVIEW_; // Enable/disable currently-selected autocomplete suggestion preview in input field
unsigned int autocomplete_limit = _SP_D3D9O_C_DEFAULT_AUTOCOMPLETE_LIMIT_; // Maximum number of autocomplete suggestions to show

// Constructor/destructor
Expand Down
1 change: 1 addition & 0 deletions rsrc/d3d9_Mod.ini
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Caret=_
CaretBlinkDelay=500
BorderWidth=3
OutputLines=15
ShowAutoCompletePreview=1
AutoCompleteLimit=5
ShowMouseCursor=1
MouseCursorSize=16
Expand Down
75 changes: 54 additions & 21 deletions src/SpD3D9OConsole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ void SpD3D9OConsole::draw()
output_string.append(cur_cmd);
std::string input_line = cur_cmd;

// Get autocomplete options
// Build autocomplete options
std::string prompt_alignment_spaces;
for (int i = 0; i < (int)full_prompt.length(); i++)
{
Expand All @@ -224,6 +224,8 @@ void SpD3D9OConsole::draw()
overlay->device->Clear(1, &border, D3DCLEAR_TARGET, color.border, 0, 0);
overlay->device->Clear(1, &background, D3DCLEAR_TARGET, color.background, 0, 0);

std::string input_autocomplete_preview = full_prompt; // Autocomplete preview text (appears after current input string, showing the remaining substring of the selected autocomplete suggestion)

// Draw background for autocomplete dropdown
if (autocomplete_matches.size() > 0)
{
Expand All @@ -243,12 +245,18 @@ void SpD3D9OConsole::draw()
{
overlay->device->Clear(1, &background, D3DCLEAR_TARGET, color.autocomplete_bg_hover, 0, 0);
}

// Build autocomplete preview line
input_autocomplete_preview.append(autocomplete_matches.at(selection.autocomplete_selection).substr(input_display_start));
input_autocomplete_preview = input_autocomplete_preview.substr(0, max_chars);
}


// Render the console text
font->BeginDrawing();
font->DrawText((float)border_width, (float)border_width, color.text, output_string.c_str(), D3DFONT_COLORTABLE, 0);
if(autocomplete_preview)
font->DrawText((float)border_width, (float)border_width + (char_size.cy * output_log_displayed_lines), color.autocomplete_preview, input_autocomplete_preview.c_str(), 0, 0); // Autocomplete preview
font->DrawText((float)border_width, (float)border_width, color.text, output_string.c_str(), 0, 0); // Output, prompt, and visible input text
if (selection.focus == SP_D3D9O_SELECT_TEXT)
{
draw_highlighted_text(selection, &input_line);
Expand Down Expand Up @@ -633,8 +641,8 @@ void SpD3D9OConsole::handle_key_press(WPARAM wParam)
{
DWORD last_err;
std::string str; // Used when a temp string is needed
std::vector<std::string> matches; // Only used if tab key is pressed
int input_sel_start, input_sel_end; // Only used when obtaining selected input
std::vector<std::string> matches; // Used in cases that access autocomplete suggestions
int input_sel_start, input_sel_end; // Used in cases that need to obtain selected input

if (is_open() && !SpD3D9OInputHandler::get()->handled) // If the console is visible, take input
{
Expand Down Expand Up @@ -666,34 +674,52 @@ void SpD3D9OConsole::handle_key_press(WPARAM wParam)
SpD3D9OInputHandler::get()->handled = true;
break;
case VK_UP:
clear_selection();
if (command_log_position <= 1)
get_autocomplete_options(command.c_str(), autocomplete_limit, &matches);
if (command.length() > 0 && (int)matches.size() > 0)
{
command_log_position = 0;
if (selection.autocomplete_selection > 0)
selection.autocomplete_selection--;
else
selection.autocomplete_selection = ((int)matches.size() - 1);
}
else
{
command_log_position--;
clear_selection();
if (command_log_position <= 1)
command_log_position = 0;
else
command_log_position--;
caret_position = 0;
command = command_log.at(command_log_position);
caret_position = command.length();
}
caret_position = 0;
command = command_log.at(command_log_position);
caret_position = command.length();
SpD3D9OInputHandler::get()->handled = true;
break;
case VK_DOWN:
clear_selection();
if (command_log_position < (unsigned int)command_log.size() - 1)
get_autocomplete_options(command.c_str(), autocomplete_limit, &matches);
if (command.length() > 0 && (int)matches.size() > 0)
{
caret_position = 0;
command_log_position++;
command = command_log.at(command_log_position);
caret_position = command.length();
if (selection.autocomplete_selection < ((int)matches.size() - 1))
selection.autocomplete_selection++;
else
selection.autocomplete_selection = 0;
}
else if (command_log_position != (unsigned int)command_log.size())
else
{
caret_position = 0;
command_log_position = (int)command_log.size();
command.clear();
clear_selection();
if (command_log_position < (unsigned int)command_log.size() - 1)
{
caret_position = 0;
command_log_position++;
command = command_log.at(command_log_position);
caret_position = command.length();
}
else if (command_log_position != (unsigned int)command_log.size())
{
caret_position = 0;
command_log_position = (int)command_log.size();
command.clear();
}
}
SpD3D9OInputHandler::get()->handled = true;
break;
Expand Down Expand Up @@ -1497,6 +1523,12 @@ void SpD3D9OConsole::get_user_prefs()
output_log_displayed_lines = (int)GetPrivateProfileInt(_SP_D3D9O_C_PREF_SECTION_, _SP_D3D9O_C_PREF_KEY_OUTPUT_LINES_, _SP_D3D9O_C_DEFAULT_OUTPUT_LINES_, _SP_D3D9O_C_PREF_FILE_);
if (output_log_displayed_lines < 1)
output_log_displayed_lines = 1;

// Show current autocomplete suggestion preview in input field
if ((int)GetPrivateProfileInt(_SP_D3D9O_C_PREF_SECTION_, _SP_D3D9O_C_PREF_KEY_AUTOCOMPLETE_PREVIEW_, _SP_D3D9O_C_DEFAULT_SHOW_AUTOCOMP_PREVIEW_, _SP_D3D9O_C_PREF_FILE_) != 0)
autocomplete_preview = true;
else
autocomplete_preview = false;

// Max allowed autocomplete suggestions
autocomplete_limit = (int)GetPrivateProfileInt(_SP_D3D9O_C_PREF_SECTION_, _SP_D3D9O_C_PREF_KEY_AUTOCOMPLETE_LIMIT_, _SP_D3D9O_C_DEFAULT_AUTOCOMPLETE_LIMIT_, _SP_D3D9O_C_PREF_FILE_);
Expand Down Expand Up @@ -1576,6 +1608,7 @@ void SpD3D9OConsole::restore_default_settings()
output_log_displayed_lines = _SP_D3D9O_C_DEFAULT_OUTPUT_LINES_; // Number of lines of previous output to display
output_log_capacity = _SP_D3D9O_C_DEFAULT_OUTPUT_LOG_CAPACITY_; // Number of lines of output to keep in memory (oldest are deleted when max is hit)
command_log_capacity = _SP_D3D9O_C_DEFAULT_COMMAND_LOG_CAPACITY_; // Number of console commands to keep logged (oldest are deleted when max is hit)
autocomplete_preview = _SP_D3D9O_C_DEFAULT_SHOW_AUTOCOMP_PREVIEW_;
autocomplete_limit = _SP_D3D9O_C_DEFAULT_AUTOCOMPLETE_LIMIT_; // Maximum number of autocomplete suggestions to show

if (output_log_capacity < output_log_displayed_lines)
Expand Down
37 changes: 36 additions & 1 deletion src/SpD3D9OConsoleCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ void console_settings_to_string(std::string *output, const char* line_prefix = _
output->append(line_prefix).append("Console mouse cursor = disabled\n");
}
output->append(line_prefix).append("Console mouse cursor size = ").append(std::to_string(gl_pSpD3D9Device->overlay->console->cursor_size)).append("\n");
if (gl_pSpD3D9Device->overlay->console->autocomplete_preview)
output->append(line_prefix).append("Preview current autocomplete suggestion = enabled\n");
else
output->append(line_prefix).append("Preview current autocomplete suggestion = disabled\n");
output->append(line_prefix).append("Autocomplete suggestion limit = ").append(std::to_string(gl_pSpD3D9Device->overlay->console->autocomplete_limit)).append("\n");
output->append(line_prefix).append("Border width = ").append(std::to_string(gl_pSpD3D9Device->overlay->console->border_width)).append(" pixels\n");
if (gl_pSpD3D9Device->overlay->console->prompt_elements & SP_D3D9O_PROMPT_USER)
Expand Down Expand Up @@ -754,6 +758,36 @@ int cc_search_command(std::vector<std::string> args, std::string *output)
}


// Shows/hides remaining characters for the currently-highlighted autocomplete suggestion in the console input field
int cc_autocomplete_preview(std::vector<std::string> args, std::string *output)
{
int ret_val = CONSOLE_COMMAND_SUCCESS;
if (args.size() > 0)
{
switch (parse_toggle_arg(args.at(0).c_str()))
{
case 0:
gl_pSpD3D9Device->overlay->console->autocomplete_preview = false;
break;
case 1:
gl_pSpD3D9Device->overlay->console->autocomplete_preview = true;
break;
default:
output->append(ERROR_INVALID_TOGGLE_ARGUMENT);
ret_val = ERROR_INVALID_PARAMETER;
break;
}
}

if (gl_pSpD3D9Device->overlay->console->autocomplete_preview)
output->append("Preview current autocomplete suggestion = enabled");
else
output->append("Preview current autocomplete suggestion = disabled");

return ret_val;
}


// Sets the maximum number of autocomplete suggestions (0 = off)
int cc_autocomplete_limit(std::vector<std::string> args, std::string *output)
{
Expand Down Expand Up @@ -2303,7 +2337,8 @@ void register_default_console_commands()
SpD3D9OConsole::register_command("console_script", cc_console_script, "console_script <file>\n Opens a plain-text script file and executes each line as a separate console command.");
SpD3D9OConsole::register_alias("script", "console_script");
SpD3D9OConsole::register_command("console_font_size", cc_console_font_size, std::string("console_font_size [size]\n Sets the console overlay font size. Font size ranges from ").append(std::to_string(_SP_D3D9O_C_MIN_FONT_SIZE_)).append(" to ").append(std::to_string(_SP_D3D9O_C_MAX_FONT_SIZE_)).append(".").c_str());
SpD3D9OConsole::register_command("console_autocomplete_limit", cc_autocomplete_limit, "autocomplete_limit [limit]\n Sets the maximum number of autocomplete suggestions to be shown (0 = off).");
SpD3D9OConsole::register_command("console_autocomplete_preview", cc_autocomplete_preview, "console_autocomplete_preview [is_enabled]\n Shows/hides preview of remaining characters for the currently-highlighted autocomplete suggestion in the console input field (1 = enabled, 0 = disabled).");
SpD3D9OConsole::register_command("console_autocomplete_limit", cc_autocomplete_limit, "console_autocomplete_limit [limit]\n Sets the maximum number of autocomplete suggestions to be shown (0 = off).");
SpD3D9OConsole::register_command("console_prompt", cc_console_prompt, "console_prompt [prompt]\n Sets the console input prompt string.");
SpD3D9OConsole::register_command("console_prompt_user", cc_console_prompt_user, "console_prompt_user [is_enabled]\n Enables/disables the username element of the console input prompt.");
SpD3D9OConsole::register_command("console_prompt_hostname", cc_console_prompt_host, "console_prompt_hostname [is_enabled]\n Enables/disables the hostname element of the console input prompt.");
Expand Down

0 comments on commit 5528826

Please sign in to comment.