mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2026-07-24 03:56:43 +00:00
(svn r26024) [1.3] -Backport: number of prerequisites for key handling fixes/improvements
This commit is contained in:
+136
-4
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user