diff options
author | frosch <frosch@openttd.org> | 2012-11-28 21:14:28 +0000 |
---|---|---|
committer | frosch <frosch@openttd.org> | 2012-11-28 21:14:28 +0000 |
commit | 5dfd5e58ee58cc8205c430075ec1325aa9fda0ca (patch) | |
tree | dcd42222d5d1492237a22e24f0f85cffb93a4a16 | |
parent | bfba90f8648cdb8b10ddd1322f46411761a9c29b (diff) | |
download | openttd-5dfd5e58ee58cc8205c430075ec1325aa9fda0ca.tar.xz |
(svn r24774) -Fix: Invert the focus handling of the OSK. Keep the focus at the OSK and close it on losing focus. This makes the editbox in the OSK behave correctly.
-rw-r--r-- | src/misc_gui.cpp | 27 | ||||
-rw-r--r-- | src/osk_gui.cpp | 44 | ||||
-rw-r--r-- | src/querystring_gui.h | 3 | ||||
-rw-r--r-- | src/window.cpp | 30 |
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; |