(svn r26024) [1.3] -Backport: number of prerequisites for key handling fixes/improvements

This commit is contained in:
rubidium
2013-11-17 13:35:48 +00:00
parent c13d1d6362
commit 10fdf41107
32 changed files with 1147 additions and 101 deletions
+136 -4
View File
@@ -33,6 +33,7 @@
#include "statusbar_gui.h"
#include "error.h"
#include "game/game.hpp"
#include "video/video_driver.hpp"
/** Values for _settings_client.gui.auto_scrolling */
enum ViewportAutoscrolling {
@@ -249,6 +250,89 @@ QueryString *Window::GetQueryString(uint widnum)
return query != this->querystrings.End() ? query->second : NULL;
}
/**
* Get the current input text if an edit box has the focus.
* @return The currently focused input text or NULL if no input focused.
*/
/* virtual */ const char *Window::GetFocusedText() const
{
if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) {
return this->GetQueryString(this->nested_focus->index)->GetText();
}
return NULL;
}
/**
* Get the string at the caret if an edit box has the focus.
* @return The text at the caret or NULL if no edit box is focused.
*/
/* virtual */ const char *Window::GetCaret() const
{
if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) {
return this->GetQueryString(this->nested_focus->index)->GetCaret();
}
return NULL;
}
/**
* Get the range of the currently marked input text.
* @param[out] length Length of the marked text.
* @return Pointer to the start of the marked text or NULL if no text is marked.
*/
/* virtual */ const char *Window::GetMarkedText(size_t *length) const
{
if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) {
return this->GetQueryString(this->nested_focus->index)->GetMarkedText(length);
}
return NULL;
}
/**
* Get the current caret position if an edit box has the focus.
* @return Top-left location of the caret, relative to the window.
*/
/* virtual */ Point Window::GetCaretPosition() const
{
if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) {
return this->GetQueryString(this->nested_focus->index)->GetCaretPosition(this, this->nested_focus->index);
}
Point pt = {0, 0};
return pt;
}
/**
* Get the bounding rectangle for a text range if an edit box has the focus.
* @param from Start of the string range.
* @param to End of the string range.
* @return Rectangle encompassing the string range, relative to the window.
*/
/* virtual */ Rect Window::GetTextBoundingRect(const char *from, const char *to) const
{
if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) {
return this->GetQueryString(this->nested_focus->index)->GetBoundingRect(this, this->nested_focus->index, from, to);
}
Rect r = {0, 0, 0, 0};
return r;
}
/**
* Get the character that is rendered at a position by the focused edit box.
* @param pt The position to test.
* @return Pointer to the character at the position or NULL if no character is at the position.
*/
/* virtual */ const char *Window::GetTextCharacterAtPosition(const Point &pt) const
{
if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) {
return this->GetQueryString(this->nested_focus->index)->GetCharAtPosition(this, this->nested_focus->index, pt);
}
return NULL;
}
/**
* Set the window that has the focus
@@ -293,6 +377,8 @@ bool EditBoxInGlobalFocus()
void Window::UnfocusFocusedWidget()
{
if (this->nested_focus != NULL) {
if (this->nested_focus->type == WWT_EDITBOX) _video_driver->EditBoxLostFocus();
/* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */
this->nested_focus->SetDirty(this);
this->nested_focus = NULL;
@@ -315,11 +401,20 @@ bool Window::SetFocusedWidget(int widget_index)
/* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */
this->nested_focus->SetDirty(this);
if (this->nested_focus->type == WWT_EDITBOX) _video_driver->EditBoxLostFocus();
}
this->nested_focus = this->GetWidget<NWidgetCore>(widget_index);
return true;
}
/**
* Called when window looses focus
*/
void Window::OnFocusLost()
{
if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) _video_driver->EditBoxLostFocus();
}
/**
* Sets the enabled/disabled status of a list of widgets.
* By default, widgets are enabled.
@@ -823,7 +918,10 @@ Window::~Window()
if (_last_scroll_window == this) _last_scroll_window = NULL;
/* Make sure we don't try to access this window as the focused window when it doesn't exist anymore. */
if (_focused_window == this) _focused_window = NULL;
if (_focused_window == this) {
this->OnFocusLost();
_focused_window = NULL;
}
this->DeleteChildWindows();
@@ -2299,9 +2397,14 @@ EventState Window::HandleEditBoxKey(int wid, WChar key, uint16 keycode)
break;
case QueryString::ACTION_CLEAR:
query->text.DeleteAll();
this->SetWidgetDirty(wid);
this->OnEditboxChanged(wid);
if (query->text.bytes <= 1) {
/* If already empty, unfocus instead */
this->UnfocusFocusedWidget();
} else {
query->text.DeleteAll();
this->SetWidgetDirty(wid);
this->OnEditboxChanged(wid);
}
break;
default:
@@ -2372,6 +2475,35 @@ void HandleCtrlChanged()
}
}
/**
* Insert a text string at the cursor position into the edit box widget.
* @param wid Edit box widget.
* @param str Text string to insert.
*/
/* virtual */ void Window::InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
{
QueryString *query = this->GetQueryString(wid);
if (query == NULL) return;
if (query->text.InsertString(str, marked, caret, insert_location, replacement_end) || marked) {
this->SetWidgetDirty(wid);
this->OnEditboxChanged(wid);
}
}
/**
* Handle text input.
* @param str Text string to input.
* @param marked Is the input a marked composition string from an IME?
* @param caret Move the caret to this point in the insertion string.
*/
void HandleTextInput(const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
{
if (!EditBoxInGlobalFocus()) return;
_focused_window->InsertTextString(_focused_window->window_class == WC_CONSOLE ? 0 : _focused_window->nested_focus->index, str, marked, caret, insert_location, replacement_end);
}
/**
* Local counter that is incremented each time an mouse input event is detected.
* The counter is used to stop auto-scrolling.