summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/misc_gui.cpp27
-rw-r--r--src/osk_gui.cpp44
-rw-r--r--src/querystring_gui.h3
-rw-r--r--src/window.cpp30
4 files changed, 41 insertions, 63 deletions
diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp
index a94e49a3b..3a87437d7 100644
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -706,16 +706,9 @@ void GuiShowTooltips(Window *parent, StringID str, uint paramcount, const uint64
new TooltipsWindow(parent, str, paramcount, params, close_tooltip);
}
-bool QueryString::HasEditBoxFocus(const Window *w, int wid) const
-{
- if (w->IsWidgetGloballyFocused(wid)) return true;
- if (w->window_class != WC_OSK || _focused_window != w->parent) return false;
- return w->parent->nested_focus != NULL && w->parent->nested_focus->type == WWT_EDITBOX;
-}
-
HandleEditBoxResult QueryString::HandleEditBoxKey(Window *w, int wid, uint16 key, uint16 keycode, EventState &state)
{
- if (!QueryString::HasEditBoxFocus(w, wid)) return HEBR_NOT_FOCUSED;
+ if (!w->IsWidgetGloballyFocused(wid)) return HEBR_NOT_FOCUSED;
state = ES_HANDLED;
@@ -757,24 +750,19 @@ HandleEditBoxResult QueryString::HandleEditBoxKey(Window *w, int wid, uint16 key
} else {
state = ES_NOT_HANDLED;
}
+ break;
}
- Window *osk = FindWindowById(WC_OSK, 0);
- if (osk != NULL && osk->parent == w) osk->InvalidateData();
-
return edited ? HEBR_EDITING : HEBR_CURSOR;
}
void QueryString::HandleEditBox(Window *w, int wid)
{
- if (HasEditBoxFocus(w, wid) && this->text.HandleCaret()) {
+ if (w->IsWidgetGloballyFocused(wid) && this->text.HandleCaret()) {
w->SetWidgetDirty(wid);
- /* When we're not the OSK, notify 'our' OSK to redraw the widget,
- * so the caret changes appropriately. */
- if (w->window_class != WC_OSK) {
- Window *w_osk = FindWindowById(WC_OSK, 0);
- if (w_osk != NULL && w_osk->parent == w) w_osk->InvalidateData();
- }
+
+ /* For the OSK also invalidate the parent window */
+ if (w->window_class == WC_OSK) w->InvalidateData();
}
}
@@ -818,7 +806,8 @@ void QueryString::DrawEditBox(const Window *w, int wid) const
if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs;
DrawString(delta, tb->pixels, 0, tb->buf, TC_YELLOW);
- if (HasEditBoxFocus(w, wid) && tb->caret) {
+ bool focussed = w->IsWidgetGloballyFocused(wid) || IsOSKOpenedFor(w, wid);
+ if (focussed && tb->caret) {
int caret_width = GetStringBoundingBox("_").width;
DrawString(tb->caretxoffs + delta, tb->caretxoffs + delta + caret_width, 0, "_", TC_WHITE);
}
diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp
index 0dc9aaded..ea66782e8 100644
--- a/src/osk_gui.cpp
+++ b/src/osk_gui.cpp
@@ -53,11 +53,13 @@ struct OskWindow : public Window {
this->caption = (par_wid->widget_data != STR_NULL) ? par_wid->widget_data : this->qs->caption;
this->text_btn = button;
this->text = &this->qs->text;
+ this->querystrings[WID_OSK_TEXT] = this->qs;
/* make a copy in case we need to reset later */
this->orig_str_buf = strdup(this->qs->text.buf);
this->InitNested(desc, 0);
+ this->SetFocusedWidget(WID_OSK_TEXT);
/* Not needed by default. */
this->DisableWidget(WID_OSK_SPECIAL);
@@ -105,13 +107,6 @@ struct OskWindow : public Window {
TC_BLACK);
}
- virtual void OnPaint()
- {
- this->DrawWidgets();
-
- this->qs->DrawEditBox(this, WID_OSK_TEXT);
- }
-
virtual void OnClick(Point pt, int widget, int click_count)
{
/* clicked a letter */
@@ -127,9 +122,6 @@ struct OskWindow : public Window {
this->UpdateOskState();
this->SetDirty();
}
- /* Return focus to the parent widget and window. */
- this->parent->SetFocusedWidget(this->text_btn);
- SetFocusedWindow(this->parent);
return;
}
@@ -195,9 +187,6 @@ struct OskWindow : public Window {
}
break;
}
- /* Return focus to the parent widget and window. */
- this->parent->SetFocusedWidget(this->text_btn);
- SetFocusedWindow(this->parent);
}
virtual void OnEditboxChanged(int widget)
@@ -207,24 +196,17 @@ struct OskWindow : public Window {
this->parent->SetWidgetDirty(this->text_btn);
}
- virtual void OnMouseLoop()
- {
- this->qs->HandleEditBox(this, WID_OSK_TEXT);
- /* make the caret of the parent window also blink */
- this->parent->SetWidgetDirty(this->text_btn);
- }
-
- /**
- * Some data on this window has become invalid.
- * @param data Information about the changed data.
- * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
- */
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
{
if (!gui_scope) return;
this->SetWidgetDirty(WID_OSK_TEXT);
this->parent->SetWidgetDirty(this->text_btn);
}
+
+ virtual void OnFocusLost()
+ {
+ delete this;
+ }
};
static const int HALF_KEY_WIDTH = 7; // Width of 1/2 key in pixels.
@@ -448,3 +430,15 @@ void UpdateOSKOriginalText(const Window *parent, int button)
osk->SetDirty();
}
+
+/**
+ * Check whether the OSK is opened for a specific editbox.
+ * @parent w Window to check for
+ * @param button Editbox of \a w to check for
+ * @return true if the OSK is oppened for \a button.
+ */
+bool IsOSKOpenedFor(const Window *w, int button)
+{
+ OskWindow *osk = dynamic_cast<OskWindow *>(FindWindowById(WC_OSK, 0));
+ return osk != NULL && osk->parent == w && osk->text_btn == button;
+}
diff --git a/src/querystring_gui.h b/src/querystring_gui.h
index 42facf70a..a7916a801 100644
--- a/src/querystring_gui.h
+++ b/src/querystring_gui.h
@@ -62,8 +62,6 @@ struct QueryString {
free(this->orig);
}
-private:
- bool HasEditBoxFocus(const Window *w, int wid) const;
public:
void DrawEditBox(const Window *w, int wid) const;
void ClickEditBox(Window *w, Point pt, int wid, int click_count, bool focus_changed);
@@ -73,5 +71,6 @@ public:
void ShowOnScreenKeyboard(Window *parent, int button);
void UpdateOSKOriginalText(const Window *parent, int button);
+bool IsOSKOpenedFor(const Window *w, int button);
#endif /* QUERYSTRING_GUI_H */
diff --git a/src/window.cpp b/src/window.cpp
index 08f773337..aa4e5a644 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -422,12 +422,6 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count)
(w->desc_flags & WDF_NO_FOCUS) == 0 && // Don't lose focus to toolbars
widget_type != WWT_CLOSEBOX) { // Don't change focused window if 'X' (close button) was clicked
focused_widget_changed = true;
- if (_focused_window != NULL) {
- _focused_window->OnFocusLost();
-
- /* The window that lost focus may have had opened a OSK, window so close it, unless the user has clicked on the OSK window. */
- if (w->window_class != WC_OSK) DeleteWindowById(WC_OSK, 0);
- }
SetFocusedWindow(w);
w->OnFocus();
}
@@ -440,13 +434,9 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count)
int widget_index = nw->index; ///< Index of the widget
/* Clicked on a widget that is not disabled.
- * So unless the clicked widget is the caption bar, change focus to this widget */
- if (widget_type != WWT_CAPTION) {
- /* Close the OSK window if a edit box loses focus */
- if (w->nested_focus != NULL && w->nested_focus->type == WWT_EDITBOX && w->nested_focus != nw && w->window_class != WC_OSK) {
- DeleteWindowById(WC_OSK, 0);
- }
-
+ * So unless the clicked widget is the caption bar, change focus to this widget.
+ * Exception: In the OSK we always want the editbox to stay focussed. */
+ if (widget_type != WWT_CAPTION && w->window_class != WC_OSK) {
/* focused_widget_changed is 'now' only true if the window this widget
* is in gained focus. In that case it must remain true, also if the
* local widget focus did not change. As such it's the logical-or of
@@ -1199,10 +1189,10 @@ void Window::InitializeData(const WindowDesc *desc, WindowNumber window_number)
this->resize.step_width = this->nested_root->resize_x;
this->resize.step_height = this->nested_root->resize_y;
- /* Give focus to the opened window unless it is the OSK window or a text box
+ /* Give focus to the opened window unless a text box
* of focused window has focus (so we don't interrupt typing). But if the new
* window has a text box, then take focus anyway. */
- if (this->window_class != WC_OSK && (!EditBoxInGlobalFocus() || this->nested_root->GetWidgetOfType(WWT_EDITBOX) != NULL)) SetFocusedWindow(this);
+ if (!EditBoxInGlobalFocus() || this->nested_root->GetWidgetOfType(WWT_EDITBOX) != NULL) SetFocusedWindow(this);
/* Insert the window into the correct location in the z-ordering. */
AddWindowToZOrdering(this);
@@ -2275,10 +2265,14 @@ EventState Window::HandleEditBoxKey(int wid, uint16 key, uint16 keycode)
case HEBR_CURSOR:
this->SetWidgetDirty(wid);
+ /* For the OSK also invalidate the parent window */
+ if (this->window_class == WC_OSK) this->InvalidateData();
break;
case HEBR_CONFIRM:
- if (query->ok_button >= 0) {
+ if (this->window_class == WC_OSK) {
+ this->OnClick(Point(), WID_OSK_OK, 1);
+ } else if (query->ok_button >= 0) {
this->OnClick(Point(), query->ok_button, 1);
} else {
action = query->ok_button;
@@ -2286,7 +2280,9 @@ EventState Window::HandleEditBoxKey(int wid, uint16 key, uint16 keycode)
break;
case HEBR_CANCEL:
- if (query->cancel_button >= 0) {
+ if (this->window_class == WC_OSK) {
+ this->OnClick(Point(), WID_OSK_CANCEL, 1);
+ } else if (query->cancel_button >= 0) {
this->OnClick(Point(), query->cancel_button, 1);
} else {
action = query->cancel_button;