IME refactor. Added support for IME in Terminal.

This commit is contained in:
Martín Lucas Golini
2023-10-29 20:30:17 -03:00
parent 28421fd598
commit 398a6341d0
17 changed files with 144 additions and 53 deletions
+1
View File
@@ -129,6 +129,7 @@ class EE_API EventDispatcher {
Vector2i mMouseDownPos;
Vector2i mClickPos;
Int32 mCbId;
Uint32 mIMECbId;
bool mFirstPress;
bool mDisableMousePress{ false };
bool mJustDisabledMousePress{ false };
-4
View File
@@ -1,7 +1,6 @@
#ifndef EE_SCENENODE_HPP
#define EE_SCENENODE_HPP
#include <eepp/scene/inputmethod.hpp>
#include <eepp/scene/node.hpp>
#include <eepp/system/translator.hpp>
#include <eepp/window/cursor.hpp>
@@ -109,8 +108,6 @@ class EE_API SceneNode : public Node {
const Float& getDPI() const;
InputMethod& getIME();
protected:
friend class Node;
typedef UnorderedSet<Node*> CloseList;
@@ -138,7 +135,6 @@ class EE_API SceneNode : public Node {
UnorderedSet<Node*> mScheduledUpdateRemove;
UnorderedSet<Node*> mMouseOverNodes;
Float mDPI;
InputMethod mIMEState;
virtual void onSizeChange();
@@ -1,5 +1,5 @@
#ifndef EE_SCENE_IMESTATE_HPP
#define EE_SCENE_IMESTATE_HPP
#ifndef EE_WINDOW_IMESTATE_HPP
#define EE_WINDOW_IMESTATE_HPP
#include <eepp/core/string.hpp>
#include <eepp/graphics/fontstyleconfig.hpp>
@@ -8,12 +8,14 @@
using namespace EE::Math;
using namespace EE::Graphics;
namespace EE { namespace Scene {
namespace EE { namespace Window {
class SceneNode;
class Window;
class EE_API InputMethod {
public:
typedef std::function<void( const String&, Int32, Int32 )> TextEditingCb;
struct State {
String text;
Int32 start{ 0 };
@@ -36,17 +38,25 @@ class EE_API InputMethod {
const Color& lineColor = Color::Transparent,
const Color& backgroundColor = Color::Transparent, bool drawText = false );
Uint32 addTextEditingCb( TextEditingCb cb );
void removeTextEditingCb( Uint32 cbId );
protected:
friend class SceneNode;
friend class Window;
explicit InputMethod( SceneNode* sceneNode ) : mSceneNode( sceneNode ) {}
explicit InputMethod( EE::Window::Window* window );
SceneNode* mSceneNode{ nullptr };
EE::Window::Window* mWindow{ nullptr };
InputMethod::State mState;
bool mEditing{ false };
Rect mLastLocation;
Uint32 mLastCb{ 0 };
std::map<Uint32, TextEditingCb> mEditingCbs;
void sendTextEditing( const String& txt, Int32 start, Int32 length );
};
}} // namespace EE::Scene
}} // namespace EE::Window
#endif // EE_SCENE_IMESTATE_HPP
#endif // EE_WINDOW_IMESTATE_HPP
+4
View File
@@ -5,6 +5,7 @@
#include <eepp/graphics/pixeldensity.hpp>
#include <eepp/graphics/view.hpp>
#include <eepp/window/base.hpp>
#include <eepp/window/inputmethod.hpp>
namespace EE { namespace Window {
@@ -501,6 +502,8 @@ class EE_API Window {
virtual bool showMessageBox( const MessageBoxType& type, const std::string& title,
const std::string& message );
InputMethod& getIME();
protected:
friend class Engine;
friend class Input;
@@ -516,6 +519,7 @@ class EE_API Window {
WindowRequestCloseCallback mCloseRequestCallback;
WindowQuitCallback mQuitCallback;
Sizei mLastWindowedSize;
InputMethod mIME;
class FrameData {
public:
+2 -2
View File
@@ -225,7 +225,6 @@
../../include/eepp/scene/eventdispatcher.hpp
../../include/eepp/scene/event.hpp
../../include/eepp/scene.hpp
../../include/eepp/scene/inputmethod.hpp
../../include/eepp/scene/keyevent.hpp
../../include/eepp/scene/mouseevent.hpp
../../include/eepp/scene/node.hpp
@@ -454,6 +453,7 @@
../../include/eepp/window/inputevent.hpp
../../include/eepp/window/inputfinger.hpp
../../include/eepp/window/inputhelper.hpp
../../include/eepp/window/inputmethod.hpp
../../include/eepp/window/input.hpp
../../include/eepp/window/joycodes.hpp
../../include/eepp/window/joystick.hpp
@@ -624,7 +624,6 @@
../../src/eepp/graphics/vertexbuffervbo.cpp
../../src/eepp/graphics/view.cpp
../../src/eepp/main/eepp_main.cpp
../../src/eepp/scene/inputmethod.cpp
../../src/eepp/ui/doc/languages/angelscript.cpp
../../src/eepp/ui/doc/languages/angelscript.hpp
../../src/eepp/ui/doc/languages/batchscript.cpp
@@ -1125,6 +1124,7 @@
../../src/eepp/window/input.cpp
../../src/eepp/window/inputfinger.cpp
../../src/eepp/window/inputhelper.cpp
../../src/eepp/window/inputmethod.cpp
../../src/eepp/window/joystick.cpp
../../src/eepp/window/joystickmanager.cpp
../../src/eepp/window/keycodes.cpp
+2 -2
View File
@@ -225,7 +225,6 @@
../../include/eepp/scene/eventdispatcher.hpp
../../include/eepp/scene/event.hpp
../../include/eepp/scene.hpp
../../include/eepp/scene/inputmethod.hpp
../../include/eepp/scene/keyevent.hpp
../../include/eepp/scene/mouseevent.hpp
../../include/eepp/scene/node.hpp
@@ -454,6 +453,7 @@
../../include/eepp/window/inputevent.hpp
../../include/eepp/window/inputfinger.hpp
../../include/eepp/window/inputhelper.hpp
../../include/eepp/window/inputmethod.hpp
../../include/eepp/window/input.hpp
../../include/eepp/window/joycodes.hpp
../../include/eepp/window/joystick.hpp
@@ -624,7 +624,6 @@
../../src/eepp/graphics/vertexbuffervbo.cpp
../../src/eepp/graphics/view.cpp
../../src/eepp/main/eepp_main.cpp
../../src/eepp/scene/inputmethod.cpp
../../src/eepp/ui/doc/languages/angelscript.cpp
../../src/eepp/ui/doc/languages/angelscript.hpp
../../src/eepp/ui/doc/languages/batchscript.cpp
@@ -1119,6 +1118,7 @@
../../src/eepp/window/input.cpp
../../src/eepp/window/inputfinger.cpp
../../src/eepp/window/inputhelper.cpp
../../src/eepp/window/inputmethod.cpp
../../src/eepp/window/joystick.cpp
../../src/eepp/window/joystickmanager.cpp
../../src/eepp/window/keycodes.cpp
+12 -3
View File
@@ -26,6 +26,10 @@ EventDispatcher::EventDispatcher( SceneNode* sceneNode ) :
mNodeWasDragging( NULL ),
mNodeDragging( NULL ) {
mCbId = mInput->pushCallback( cb::Make1( this, &EventDispatcher::inputCallback ) );
mIMECbId = mWindow->getIME().addTextEditingCb(
[this]( const String& text, Int32 start, Int32 length ) {
sendTextEditing( text, start, length );
} );
}
EventDispatcher::~EventDispatcher() {
@@ -33,13 +37,18 @@ EventDispatcher::~EventDispatcher() {
Engine::instance()->existsWindow( mWindow ) ) {
mInput->popCallback( mCbId );
}
if ( mIMECbId && NULL != Engine::existsSingleton() &&
Engine::instance()->existsWindow( mWindow ) ) {
mWindow->getIME().removeTextEditingCb( mIMECbId );
}
}
void EventDispatcher::inputCallback( InputEvent* event ) {
switch ( event->Type ) {
case InputEvent::Window: {
if ( event->window.type == InputEvent::WindowEventType::WindowKeyboardFocusLost )
mSceneNode->getIME().stop();
mWindow->getIME().stop();
break;
}
case InputEvent::KeyUp:
@@ -211,7 +220,7 @@ void EventDispatcher::sendTextInput( const Uint32& textChar, const Uint32& times
void EventDispatcher::sendTextEditing( const String& text, const Int32& start,
const Int32& length ) {
mSceneNode->getIME().onTextEditing( text, start, length );
mWindow->getIME().onTextEditing( text, start, length );
TextEditingEvent textEditingEvent =
TextEditingEvent( mFocusNode, Event::TextInput, text, start, length );
Node* node = mFocusNode;
@@ -266,7 +275,7 @@ void EventDispatcher::sendMouseDown( Node* toNode, const Vector2i& pos, const Ui
void EventDispatcher::setFocusNode( Node* node ) {
if ( NULL != mFocusNode && NULL != node && node != mFocusNode ) {
mSceneNode->getIME().stop();
mWindow->getIME().stop();
mLossFocusNode = mFocusNode;
+1 -6
View File
@@ -33,8 +33,7 @@ SceneNode::SceneNode( EE::Window::Window* window ) :
mHighlightInvalidation( false ),
mHighlightFocusColor( 234, 195, 123, 255 ),
mHighlightOverColor( 195, 123, 234, 255 ),
mHighlightInvalidationColor( 220, 0, 0, 255 ),
mIMEState( this ) {
mHighlightInvalidationColor( 220, 0, 0, 255 ) {
mNodeFlags |= NODE_FLAG_SCENENODE;
mSceneNode = this;
@@ -499,8 +498,4 @@ const Float& SceneNode::getDPI() const {
return mDPI;
}
InputMethod& SceneNode::getIME() {
return mIMEState;
}
}} // namespace EE::Scene
+6 -6
View File
@@ -344,13 +344,13 @@ void UICodeEditor::draw() {
}
}
if ( hasFocus() && getUISceneNode()->getIME().isEditing() ) {
if ( hasFocus() && getUISceneNode()->getWindow()->getIME().isEditing() ) {
Vector2f cursorPos( startScroll.x + getXOffsetCol( cursor ),
startScroll.y + cursor.line() * lineHeight + getLineOffset() );
FontStyleConfig config( mFontStyleConfig );
config.FontColor = mFontStyleConfig.getFontSelectedColor();
getUISceneNode()->getIME().draw( cursorPos, getFontHeight(), mFontStyleConfig,
Color( mCaretColor ).blendAlpha( mAlpha ) );
getUISceneNode()->getWindow()->getIME().draw( cursorPos, getFontHeight(), config,
Color( mCaretColor ).blendAlpha( mAlpha ) );
} else {
for ( const auto& sel : mDoc->getSelections() )
drawCursor( startScroll, lineHeight, sel.start() );
@@ -898,7 +898,7 @@ Uint32 UICodeEditor::onFocusLoss() {
}
Uint32 UICodeEditor::onTextInput( const TextInputEvent& event ) {
if ( getUISceneNode()->getIME().isEditing() )
if ( getUISceneNode()->getWindow()->getIME().isEditing() )
return 0;
mLastActivity.restart();
@@ -931,7 +931,7 @@ void UICodeEditor::updateIMELocation() {
return;
updateScreenPos();
Rectf r( getScreenPosition( mDoc->getSelection( true ).start() ) );
getUISceneNode()->getIME().setLocation( r.asInt() );
getUISceneNode()->getWindow()->getIME().setLocation( r.asInt() );
}
Uint32 UICodeEditor::onTextEditing( const TextEditingEvent& event ) {
@@ -944,7 +944,7 @@ Uint32 UICodeEditor::onTextEditing( const TextEditingEvent& event ) {
}
Uint32 UICodeEditor::onKeyDown( const KeyEvent& event ) {
if ( getUISceneNode()->getIME().isEditing() )
if ( getUISceneNode()->getWindow()->getIME().isEditing() )
return 0;
mLastActivity.restart();
+7 -6
View File
@@ -516,11 +516,12 @@ void UIConsole::draw() {
mFontStyleConfig );
Rectf r( { mScreenPos.x + mPaddingPx.Left + cursorPos, curY }, { cursorPos, lineHeight } );
updateIMELocation( r );
if ( hasFocus() && getUISceneNode()->getIME().isEditing() ) {
if ( hasFocus() && getUISceneNode()->getWindow()->getIME().isEditing() ) {
FontStyleConfig config( mFontStyleConfig );
config.FontColor = mFontStyleConfig.getFontSelectedColor();
getUISceneNode()->getIME().draw( r.getPosition(), getLineHeight(), mFontStyleConfig,
Color( fontColor ).blendAlpha( mAlpha ) );
getUISceneNode()->getWindow()->getIME().draw( r.getPosition(), getLineHeight(),
mFontStyleConfig,
Color( fontColor ).blendAlpha( mAlpha ) );
} else {
Text& text2 = mTextCache[mTextCache.size() - 2].text;
text2.setStyleConfig( mFontStyleConfig );
@@ -794,7 +795,7 @@ void UIConsole::paste() {
}
Uint32 UIConsole::onKeyDown( const KeyEvent& event ) {
if ( getUISceneNode()->getIME().isEditing() )
if ( getUISceneNode()->getWindow()->getIME().isEditing() )
return 0;
if ( ( event.getKeyCode() == KEY_TAB ) &&
@@ -888,7 +889,7 @@ Uint32 UIConsole::onKeyDown( const KeyEvent& event ) {
}
Uint32 UIConsole::onTextInput( const TextInputEvent& event ) {
if ( getUISceneNode()->getIME().isEditing() )
if ( getUISceneNode()->getWindow()->getIME().isEditing() )
return 0;
Input* input = getUISceneNode()->getWindow()->getInput();
@@ -923,7 +924,7 @@ Uint32 UIConsole::onTextEditing( const TextEditingEvent& event ) {
void UIConsole::updateIMELocation( const Rectf& loc ) {
if ( mDoc.getActiveClient() != this )
return;
getUISceneNode()->getIME().setLocation( loc.asInt() );
getUISceneNode()->getWindow()->getIME().setLocation( loc.asInt() );
}
Uint32 UIConsole::onPressEnter() {
+7 -6
View File
@@ -147,14 +147,15 @@ void UITextInput::draw() {
}
}
if ( hasFocus() && getUISceneNode()->getIME().isEditing() ) {
if ( hasFocus() && getUISceneNode()->getWindow()->getIME().isEditing() ) {
updateIMELocation();
Vector2f cursor( eefloor( mScreenPos.x + mRealAlignOffset.x + mCurPos.x + mPaddingPx.Left ),
mScreenPos.y + mRealAlignOffset.y + mCurPos.y + mPaddingPx.Top );
FontStyleConfig config( mFontStyleConfig );
config.FontColor = mFontStyleConfig.getFontSelectedColor();
getUISceneNode()->getIME().draw( cursor, getTextHeight(), mFontStyleConfig,
Color( mFontStyleConfig.FontColor ).blendAlpha( mAlpha ) );
getUISceneNode()->getWindow()->getIME().draw(
cursor, getTextHeight(), mFontStyleConfig,
Color( mFontStyleConfig.FontColor ).blendAlpha( mAlpha ) );
} else {
drawWaitingCursor();
}
@@ -767,7 +768,7 @@ void UITextInput::registerKeybindings() {
}
Uint32 UITextInput::onKeyDown( const KeyEvent& event ) {
if ( getUISceneNode()->getIME().isEditing() )
if ( getUISceneNode()->getWindow()->getIME().isEditing() )
return 0;
std::string cmd = mKeyBindings.getCommandFromKeyBind( { event.getKeyCode(), event.getMod() } );
@@ -783,7 +784,7 @@ Uint32 UITextInput::onKeyDown( const KeyEvent& event ) {
}
Uint32 UITextInput::onTextInput( const TextInputEvent& event ) {
if ( getUISceneNode()->getIME().isEditing() )
if ( getUISceneNode()->getWindow()->getIME().isEditing() )
return 0;
if ( !mAllowEditing )
@@ -822,7 +823,7 @@ void UITextInput::updateIMELocation() {
Vector2f cursor( eefloor( mScreenPos.x + mRealAlignOffset.x + mCurPos.x + mPaddingPx.Left ),
mScreenPos.y + mRealAlignOffset.y + mCurPos.y + mPaddingPx.Top );
Float h = mTextCache->getFont()->getFontHeight( mTextCache->getCharacterSize() );
getUISceneNode()->getIME().setLocation( Rectf( cursor, { 0, h } ).asInt() );
getUISceneNode()->getWindow()->getIME().setLocation( Rectf( cursor, { 0, h } ).asInt() );
}
Uint32 UITextInput::onTextEditing( const TextEditingEvent& event ) {
@@ -1,17 +1,23 @@
#include <eepp/graphics/primitives.hpp>
#include <eepp/graphics/text.hpp>
#include <eepp/scene/inputmethod.hpp>
#include <eepp/scene/scenenode.hpp>
#include <eepp/window/inputmethod.hpp>
#include <eepp/window/window.hpp>
namespace EE { namespace Scene {
namespace EE { namespace Window {
InputMethod::InputMethod( EE::Window::Window* window ) : mWindow( window ) {}
void InputMethod::sendTextEditing( const String& txt, Int32 start, Int32 length ) {
for ( const auto& cb : mEditingCbs )
cb.second( txt, start, length );
}
void InputMethod::setLocation( Rect rect ) {
#if EE_PLATFORM == EE_PLATFORM_MACOS || EE_PLATFORM == EE_PLATFORM_IOS
rect = PixelDensity::pxToDpI( rect );
#endif
if ( rect != mLastLocation ) {
mSceneNode->getWindow()->setTextInputRect( rect );
mWindow->setTextInputRect( rect );
mLastLocation = std::move( rect );
}
}
@@ -27,9 +33,9 @@ void InputMethod::reset() {
void InputMethod::stop() {
if ( mEditing ) {
mSceneNode->getWindow()->clearComposition();
mSceneNode->getEventDispatcher()->sendTextEditing( "", 0, 0 );
mWindow->clearComposition();
reset();
sendTextEditing( "", 0, 0 );
}
}
@@ -73,4 +79,13 @@ void InputMethod::draw( const Vector2f& screenPos, const Float& lineHeight,
Text::draw( mState.text, screenPos, fontStyle );
}
}} // namespace EE::Scene
Uint32 InputMethod::addTextEditingCb( TextEditingCb cb ) {
mEditingCbs[++mLastCb] = std::move( cb );
return mLastCb;
}
void InputMethod::removeTextEditingCb( Uint32 cbId ) {
mEditingCbs.erase( cbId );
}
}} // namespace EE::Window
+6 -1
View File
@@ -44,7 +44,8 @@ Window::Window( WindowSettings Settings, ContextSettings Context, Clipboard* Cli
mInput( Input ),
mCursorManager( CursorManager ),
mCurrentView( NULL ),
mNumCallBacks( 0 ) {
mNumCallBacks( 0 ),
mIME( this ) {
mWindow.WindowConfig = Settings;
mWindow.ContextConfig = Context;
setFrameRateLimit( Context.FrameRateLimit );
@@ -349,6 +350,10 @@ bool Window::showMessageBox( const MessageBoxType&, const std::string&, const st
return false;
}
InputMethod& Window::getIME() {
return mIME;
}
void Window::calculateFps() {
if ( mFrameData.FPS.LastCheck.getElapsedTime().asSeconds() >= 1.f ) {
mFrameData.FPS.Current = mFrameData.FPS.Count;
@@ -195,6 +195,8 @@ class TerminalDisplay : public ITerminalDisplay {
virtual void onTextInput( const Uint32& chr );
virtual void onTextEditing( const String& text, const Int32& start, const Int32& length );
virtual void onKeyDown( const Keycode& keyCode, const Uint32& chr, const Uint32& mod,
const Scancode& scancode );
@@ -345,6 +347,8 @@ class TerminalDisplay : public ITerminalDisplay {
const float& h );
void drawboxlines( float x, float y, float w, float h, Color fg, ushort bd );
Rectf updateIMELocation();
};
}} // namespace eterm::Terminal
@@ -133,6 +133,8 @@ class UITerminal : public UIWidget {
virtual Uint32 onTextInput( const TextInputEvent& event );
virtual Uint32 onTextEditing( const TextEditingEvent& event );
virtual Uint32 onKeyDown( const KeyEvent& event );
virtual Uint32 onKeyUp( const KeyEvent& event );
@@ -1402,6 +1402,16 @@ void TerminalDisplay::draw( const Vector2f& pos ) {
if ( mFrameBuffer )
drawFrameBuffer();
if ( hasFocus() && mWindow->getIME().isEditing() ) {
Rectf r = updateIMELocation();
FontStyleConfig config;
config.Font = mFont;
config.CharacterSize = mFontSize;
config.FontColor = termColor( mCursorGlyph.bg, mColors );
mWindow->getIME().draw( r.getPosition(), r.getHeight(), config, config.FontColor,
termColor( mCursorGlyph.fg, mColors ), true );
}
mDrawing = false;
mDirty = false;
}
@@ -1489,7 +1499,7 @@ void TerminalDisplay::onProcessExit( int exitCode ) {
}
void TerminalDisplay::onTextInput( const Uint32& chr ) {
if ( !mTerminal )
if ( !mTerminal || mWindow->getIME().isEditing() )
return;
String input;
input.push_back( chr );
@@ -1497,8 +1507,17 @@ void TerminalDisplay::onTextInput( const Uint32& chr ) {
mTerminal->ttywrite( utf8Input.c_str(), utf8Input.size(), 1 );
}
void TerminalDisplay::onTextEditing( const String& text, const Int32& start, const Int32& length ) {
if ( !mTerminal )
return;
invalidateCursor();
updateIMELocation();
}
void TerminalDisplay::onKeyDown( const Keycode& keyCode, const Uint32& /*chr*/, const Uint32& mod,
const Scancode& scancode ) {
if ( mWindow->getIME().isEditing() )
return;
Uint32 smod = sanitizeMod( mod );
auto scIt = terminalKeyMap.Shortcuts().find( keyCode );
@@ -1651,6 +1670,9 @@ void TerminalDisplay::invalidateLines() {
mDirty = true;
}
void TerminalDisplay::setFocus( bool focus ) {
if ( focus )
updateIMELocation();
if ( focus == mFocus )
return;
mFocus = focus;
@@ -1727,4 +1749,16 @@ void TerminalDisplay::initVBOs() {
mVBStyles.emplace_back( createRowVBO( false ) );
}
Rectf TerminalDisplay::updateIMELocation() {
if ( !Engine::isRunninMainThread() )
return {};
auto fontSize = mFont->getFontHeight( mFontSize );
auto spaceCharAdvanceX = mFont->getGlyph( 'A', mFontSize, false, false ).advance;
auto pos = mPosition.floor() + Vector2f( mPadding.Left, mPadding.Top );
Rectf r( { pos.x + mCursor.x * spaceCharAdvanceX, pos.y + mCursor.y * fontSize },
{ spaceCharAdvanceX, fontSize } );
mWindow->getIME().setLocation( r.asInt() );
return r;
}
}} // namespace eterm::Terminal
@@ -429,6 +429,16 @@ Uint32 UITerminal::onTextInput( const TextInputEvent& event ) {
return 1;
}
Uint32 UITerminal::onTextEditing( const TextEditingEvent& event ) {
UIWidget::onTextEditing( event );
if ( mTerm ) {
mTerm->onTextEditing( event.getText(), event.getStart(), event.getLength() );
invalidateDraw();
return 1;
}
return 0;
}
Uint32 UITerminal::onKeyDown( const KeyEvent& event ) {
if ( mUISceneNode->getUIEventDispatcher()->justGainedFocus() )
return 0;
@@ -502,12 +512,16 @@ void UITerminal::onSizeChange() {
}
Uint32 UITerminal::onFocus() {
getUISceneNode()->getWindow()->startTextInput();
updateScreenPos();
mTerm->setPosition( mScreenPosi.asFloat() );
mTerm->setFocus( true );
invalidateDraw();
return UIWidget::onFocus();
}
Uint32 UITerminal::onFocusLoss() {
getUISceneNode()->getWindow()->stopTextInput();
mTerm->setFocus( false );
invalidateDraw();
return UIWidget::onFocusLoss();