Changeset View
Standalone View
source/gui/CInput.cpp
/* Copyright (C) 2017 Wildfire Games. | /* Copyright (C) 2018 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
Show All 25 Lines | |||||
#include "ps/Globals.h" | #include "ps/Globals.h" | ||||
#include "ps/Hotkey.h" | #include "ps/Hotkey.h" | ||||
#include "renderer/Renderer.h" | #include "renderer/Renderer.h" | ||||
#include <sstream> | #include <sstream> | ||||
extern int g_yres; | extern int g_yres; | ||||
CInput::CInput() | CInput::CInput() | ||||
: m_iBufferPos(-1), m_iBufferPos_Tail(-1), m_SelectingText(false), m_HorizontalScroll(0.f), | : m_Focus(false), m_iBufferPos(-1), m_iBufferPos_Tail(-1), m_SelectingText(false), | ||||
vladislavbelov: It's the 112 characters long for no reason. | |||||
m_PrevTime(0.0), m_CursorVisState(true), m_CursorBlinkRate(0.5), m_ComposingText(false), | m_HorizontalScroll(0.f), m_PrevTime(0.0), m_CursorVisState(true), m_CursorBlinkRate(0.5), | ||||
m_iComposedLength(0), m_iComposedPos(0), m_iInsertPos(0), m_Readonly(false) | m_ComposingText(false), m_iComposedLength(0), m_iComposedPos(0), m_iInsertPos(0), m_Readonly(false) | ||||
{ | { | ||||
AddSetting(GUIST_int, "buffer_position"); | AddSetting(GUIST_int, "buffer_position"); | ||||
AddSetting(GUIST_float, "buffer_zone"); | AddSetting(GUIST_float, "buffer_zone"); | ||||
AddSetting(GUIST_CStrW, "caption"); | AddSetting(GUIST_CStrW, "caption"); | ||||
AddSetting(GUIST_int, "cell_id"); | AddSetting(GUIST_int, "cell_id"); | ||||
AddSetting(GUIST_CStrW, "font"); | AddSetting(GUIST_CStrW, "font"); | ||||
AddSetting(GUIST_CStrW, "mask_char"); | AddSetting(GUIST_CStrW, "mask_char"); | ||||
AddSetting(GUIST_bool, "mask"); | AddSetting(GUIST_bool, "mask"); | ||||
Show All 13 Lines | CInput::CInput() | ||||
CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(); | CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(); | ||||
bar->SetRightAligned(true); | bar->SetRightAligned(true); | ||||
AddScrollBar(bar); | AddScrollBar(bar); | ||||
} | } | ||||
CInput::~CInput() | CInput::~CInput() | ||||
{ | { | ||||
} | } | ||||
Not Done Inline Actions
Which could be fixed in the previously focused object, when it loses the focus? Shouldn't this just be if m_Focused then SDL_StartTextInput? Does calling the stop then the start function differ from noop? elexis: > the old field is still focussed
Which could be fixed in the previously focused object, when… | |||||
Not Done Inline ActionsThis reference to the top-page sounds investigateable. It may not always the topmost page that that creates the CInput object. Would a reference to the GUI page that owns this object be more precise / universal / reliable? elexis: This reference to the top-page sounds investigateable.
It may not always the topmost page that… | |||||
Done Inline Actionscertainly investigation It doen't matter that the topmost page has the CInput object or not, but I would expect any other page than the top page would not recieve textInputs, even if it is the only page with a textinput. What we want to achieve with this call is that whatever happens, the the SDL_TEXTINPTUT thingy is set correctly for the topmost page, so every time a gui page switches we need to check it (whether it is pushing, switching or popping a page, doesn't matter). So I guess these two calls could get a better location. bb: certainly investigation
It doen't matter that the topmost page has the CInput object or not… | |||||
Not Done Inline Actions
If the topmost page differs from the the page that owns this object, then the call to the topmost page would be unrelated to this GUI object instance, no? If m_pGUI is not used here, there should be a very good reason for a GUIObject of page X to do something for GUI page Y. elexis: > It doen't matter that the topmost page has the CInput object or not
If the topmost page… | |||||
void CInput::ActivatePage() | |||||
{ | |||||
if (m_Focus) | |||||
SDL_StartTextInput(); | |||||
else | |||||
SDL_StopTextInput(); | |||||
} | |||||
void CInput::UpdateBufferPositionSetting() | void CInput::UpdateBufferPositionSetting() | ||||
{ | { | ||||
int* bufferPos = (int*)m_Settings["buffer_position"].m_pSetting; | int* bufferPos = (int*)m_Settings["buffer_position"].m_pSetting; | ||||
*bufferPos = m_iBufferPos; | *bufferPos = m_iBufferPos; | ||||
} | } | ||||
void CInput::ClearComposedText() | void CInput::ClearComposedText() | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 993 Lines • ▼ Show 20 Lines | case GUIM_LOAD: | ||||
UpdateText(); | UpdateText(); | ||||
UpdateAutoScroll(); | UpdateAutoScroll(); | ||||
GUI<bool>::GetSetting(this, "readonly", m_Readonly); | GUI<bool>::GetSetting(this, "readonly", m_Readonly); | ||||
break; | break; | ||||
} | } | ||||
case GUIM_GOT_FOCUS: | case GUIM_GOT_FOCUS: | ||||
{ | { | ||||
m_Focus = true; | |||||
Not Done Inline ActionsPerhaps we don't need the "activate" function at all, but just call SDL_StartTextInput(); here (perhaps only if the GUI page is the topmost one too)? elexis: Perhaps we don't need the "activate" function at all, but just call `SDL_StartTextInput();`… | |||||
Done Inline Actionswell no, that call already is there 12 lines below... bb: well no, that call already is there 12 lines below... | |||||
Not Done Inline ActionsThen one could consider whether sending the GUIM_GOT_FOCUS message upon pagestack changes would be more versatile or shorter. (I'm uninformed) elexis: Then one could consider whether sending the `GUIM_GOT_FOCUS` message upon pagestack changes… | |||||
Done Inline Actions^ bb: ^ | |||||
m_iBufferPos = 0; | m_iBufferPos = 0; | ||||
m_PrevTime = 0.0; | m_PrevTime = 0.0; | ||||
m_CursorVisState = false; | m_CursorVisState = false; | ||||
// Tell the IME where to draw the candidate list | // Tell the IME where to draw the candidate list | ||||
SDL_Rect rect; | SDL_Rect rect; | ||||
rect.h = m_CachedActualSize.GetSize().cy; | rect.h = m_CachedActualSize.GetSize().cy; | ||||
rect.w = m_CachedActualSize.GetSize().cx; | rect.w = m_CachedActualSize.GetSize().cx; | ||||
Show All 14 Lines | if (m_ComposingText) | ||||
evt.ev.edit.start = 0; | evt.ev.edit.start = 0; | ||||
evt.ev.edit.text[0] = 0; | evt.ev.edit.text[0] = 0; | ||||
ManuallyHandleEvent(&evt); | ManuallyHandleEvent(&evt); | ||||
} | } | ||||
SDL_StopTextInput(); | SDL_StopTextInput(); | ||||
m_iBufferPos = -1; | m_iBufferPos = -1; | ||||
m_iBufferPos_Tail = -1; | m_iBufferPos_Tail = -1; | ||||
m_Focus = false; | |||||
break; | break; | ||||
} | } | ||||
default: | default: | ||||
{ | { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
UpdateBufferPositionSetting(); | UpdateBufferPositionSetting(); | ||||
▲ Show 20 Lines • Show All 1,005 Lines • ▼ Show 20 Lines | if (m_HorizontalScroll != 0.f && | ||||
x_total - m_HorizontalScroll + buffer_zone*2.f < m_CachedActualSize.GetWidth()) | x_total - m_HorizontalScroll + buffer_zone*2.f < m_CachedActualSize.GetWidth()) | ||||
m_HorizontalScroll = x_total - m_CachedActualSize.GetWidth() + buffer_zone*2.f; | m_HorizontalScroll = x_total - m_CachedActualSize.GetWidth() + buffer_zone*2.f; | ||||
// Now this is the fail-safe, if x_total isn't even the length of the control, | // Now this is the fail-safe, if x_total isn't even the length of the control, | ||||
// remove all scrolling | // remove all scrolling | ||||
if (x_total + buffer_zone*2.f < m_CachedActualSize.GetWidth()) | if (x_total + buffer_zone*2.f < m_CachedActualSize.GetWidth()) | ||||
m_HorizontalScroll = 0.f; | m_HorizontalScroll = 0.f; | ||||
} | } | ||||
} | } | ||||
Not Done Inline ActionsI think, it may lead to weird behaviour with GUI (not sure that it exists in the public, but it's real in mods), when a player entering a chat text and at the same time some text field is closing. I.e. a temporal message box with the CInput. Did you test it? vladislavbelov: I think, it may lead to weird behaviour with GUI (not sure that it exists in the public, but… | |||||
Not Done Inline ActionsIsnt this only called when the GUI page is irrecoverably closed and deleted in c++? So the only way this to be wrong is having a text field focused in page 1, then opening page 2 that has a text field, closing page 2, then the textfield in page 1 might still be focused without the SDL_StartTextInput thign being called? elexis: Isnt this only called when the GUI page is irrecoverably closed and deleted in c++?
So the… | |||||
Not Done Inline ActionsWell probably even easier: have two pages open simultaneously, focus a textfield on one, close the other (without dropping focus) That is a very hypothetical case however, since closing a page without dropping focus would be meh. But for the sake of completeness we could add a check for being focussed on this inputfield (we would still bug then if both fields have a inputfield which both are focussed, but considering that a bug already) bb: Well probably even easier: have two pages open simultaneously, focus a textfield on one, close… | |||||
Not Done Inline ActionsThere is not really a situation where two GUI pages are open and processed simultaneously. elexis: There is not really a situation where two GUI pages are open and processed simultaneously.
You… |
It's the 112 characters long for no reason.