diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 420c372dd..0aa551710 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -108,7 +108,7 @@ {388e5431-b31b-42b3-b9ad-9002d279d75d} 10 0 - 0 + 20 ../../make/linux @@ -1521,8 +1521,6 @@ UserStickyKeys - ProjectExplorer.Project.Target.0 - ProjectExplorer.Project.Target.0/ProjectExplorer.Target.ActiveRunConfiguration ProjectExplorer.Project.Target.1 ProjectExplorer.Project.Target.1/ProjectExplorer.ProjectConfiguration.DefaultDisplayName ProjectExplorer.Project.Target.1/ProjectExplorer.ProjectConfiguration.DisplayName diff --git a/src/tools/eterm/eterm.cpp b/src/tools/eterm/eterm.cpp index c47dece8d..817e2903d 100644 --- a/src/tools/eterm/eterm.cpp +++ b/src/tools/eterm/eterm.cpp @@ -22,6 +22,12 @@ void inputCallback( InputEvent* event ) { case InputEvent::MouseButtonUp: { terminal->onMouseUp( win->getInput()->getMousePos(), win->getInput()->getReleaseTrigger() ); + + if ( win->getInput()->getDoubleClickTrigger() ) { + terminal->onMouseDoubleClick( win->getInput()->getMousePos(), + win->getInput()->getDoubleClickTrigger() ); + } + break; } case InputEvent::Window: { diff --git a/src/tools/eterm/eterminaldisplay.cpp b/src/tools/eterm/eterminaldisplay.cpp index a0c8e9af4..ee8482d90 100644 --- a/src/tools/eterm/eterminaldisplay.cpp +++ b/src/tools/eterm/eterminaldisplay.cpp @@ -515,6 +515,19 @@ void ETerminalDisplay::draw() { draw( mPosition ); } +void ETerminalDisplay::onMouseDoubleClick( const Vector2i& pos, const Uint32& flags ) { + if ( flags & EE_BUTTON_LMASK ) + mLastDoubleClick.restart(); + + if ( ( flags & EE_BUTTON_LMASK ) && + ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_EMPTY || + mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_IDLE ) ) { + auto gridPos{ positionToGrid( pos ) }; + mTerminal->selstart( gridPos.x, gridPos.y, SNAP_WORD ); + invalidate(); + } +} + void ETerminalDisplay::onMouseMotion( const Vector2i& pos, const Uint32& flags ) { if ( ( flags & EE_BUTTON_LMASK ) && ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_EMPTY || @@ -522,7 +535,7 @@ void ETerminalDisplay::onMouseMotion( const Vector2i& pos, const Uint32& flags ) auto gridPos{ positionToGrid( pos ) }; mTerminal->selextend( gridPos.x, gridPos.y, - mWindow->getInput()->getModState() == KEYMOD_SHIFT ? SEL_RECTANGULAR : SEL_REGULAR, 0 ); + mWindow->getInput()->getModState() & KEYMOD_SHIFT ? SEL_RECTANGULAR : SEL_REGULAR, 0 ); invalidate(); } mTerminal->mousereport( TerminalMouseEventType::MouseMotion, positionToGrid( pos ), flags, @@ -530,11 +543,24 @@ void ETerminalDisplay::onMouseMotion( const Vector2i& pos, const Uint32& flags ) } void ETerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) { + auto gridPos{ positionToGrid( pos ) }; if ( ( flags & EE_BUTTON_LMASK ) && - ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_IDLE ) ) { - auto gridPos{ positionToGrid( pos ) }; - mTerminal->selstart( gridPos.x, gridPos.y, 0 ); - invalidate(); + mLastDoubleClick.getElapsedTime() < Milliseconds( 300.f ) ) { + mTerminal->selstart( gridPos.x, gridPos.y, SNAP_LINE ); + } else if ( flags & EE_BUTTON_LMASK ) { + if ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_IDLE ) { + auto gridPos{ positionToGrid( pos ) }; + mTerminal->selstart( gridPos.x, gridPos.y, 0 ); + invalidate(); + } else if ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_READY ) { + mTerminal->selclear(); + } + } else if ( flags & EE_BUTTON_MMASK ) { + auto selection = mTerminal->getSelection(); + if ( !selection.empty() ) { + for ( auto& chr : selection ) + onTextInput( chr ); + } } mTerminal->mousereport( TerminalMouseEventType::MouseButtonDown, positionToGrid( pos ), flags, mWindow->getInput()->getModState() ); @@ -542,10 +568,9 @@ void ETerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) { void ETerminalDisplay::onMouseUp( const Vector2i& pos, const Uint32& flags ) { if ( ( flags & EE_BUTTON_LMASK ) ) { - auto selection = mTerminal->getsel(); - if ( selection ) - setClipboard( selection ); - mTerminal->selclear(); + auto selection = mTerminal->getSelection(); + if ( !selection.empty() ) + setClipboard( selection.c_str() ); invalidate(); } mTerminal->mousereport( TerminalMouseEventType::MouseButtonRelease, positionToGrid( pos ), @@ -564,6 +589,15 @@ static inline Color termColor( unsigned int terminalColor, #define BETWEEN( x, a, b ) ( ( a ) <= ( x ) && ( x ) <= ( b ) ) #define IS_SET( flag ) ( ( mMode & ( flag ) ) != 0 ) +Float ETerminalDisplay::getYOffset() const { + auto fontSize = (Float)mFont->getFontHeight( mFontSize ); + auto height = mRows * fontSize; + float y = 0; + if ( height < mSize.getHeight() ) + y = std::floor( mPosition.y + ( ( mSize.getHeight() - height ) / 2.0f ) ); + return y; +} + void ETerminalDisplay::draw( Vector2f pos ) { mDrawing = true; @@ -776,7 +810,7 @@ void ETerminalDisplay::draw( Vector2f pos ) { } Vector2i ETerminalDisplay::positionToGrid( const Vector2i& pos ) { - Vector2f relPos = { pos.x - mPosition.x, pos.y - mPosition.y }; + Vector2f relPos = { pos.x - mPosition.x, pos.y - mPosition.y - getYOffset() }; int mouseX = 0; int mouseY = 0; diff --git a/src/tools/eterm/eterminaldisplay.hpp b/src/tools/eterm/eterminaldisplay.hpp index 3da7ec02b..59e4b3c8d 100644 --- a/src/tools/eterm/eterminaldisplay.hpp +++ b/src/tools/eterm/eterminaldisplay.hpp @@ -143,6 +143,8 @@ class ETerminalDisplay : public TerminalDisplay { void draw(); + virtual void onMouseDoubleClick( const Vector2i& pos, const Uint32& flags ); + virtual void onMouseMotion( const Vector2i& pos, const Uint32& flags ); virtual void onMouseDown( const Vector2i& pos, const Uint32& flags ); @@ -198,6 +200,7 @@ class ETerminalDisplay : public TerminalDisplay { bool mPasteNewlineFix{ true }; bool mFocus{ true }; Clock mClock; + Clock mLastDoubleClick; ETerminalDisplay( EE::Window::Window* window, Font* font, const Float& fontSize, const Sizef& pixelsSize, TerminalConfig* config ); @@ -207,6 +210,8 @@ class ETerminalDisplay : public TerminalDisplay { Vector2i positionToGrid( const Vector2i& pos ); void onSizeChange(); + + Float getYOffset() const; }; #endif // ETERMINALDISPLAY_HPP diff --git a/src/tools/eterm/terminal/terminalemulator.cpp b/src/tools/eterm/terminal/terminalemulator.cpp index 4893bea74..f6be947e1 100644 --- a/src/tools/eterm/terminal/terminalemulator.cpp +++ b/src/tools/eterm/terminal/terminalemulator.cpp @@ -295,7 +295,7 @@ void TerminalEmulator::selinit( void ) { mSel.ob.x = -1; } -int TerminalEmulator::tlinelen( int y ) { +int TerminalEmulator::tlinelen( int y ) const { int i = mTerm.col; if ( mTerm.line[y][i - 1].mode & ATTR_WRAP ) @@ -460,7 +460,7 @@ void TerminalEmulator::selsnap( int* x, int* y, int direction ) { } } -char* TerminalEmulator::getsel( void ) { +char* TerminalEmulator::getsel( void ) const { char *str, *ptr; int y, bufsize, lastx, linelen; TerminalGlyph *gp, *last; @@ -513,6 +513,16 @@ char* TerminalEmulator::getsel( void ) { return str; } +std::string TerminalEmulator::getSelection() const { + char* sel = getsel(); + if ( sel ) { + std::string selection( sel ); + free( sel ); + return selection; + } + return ""; +} + void TerminalEmulator::selclear( void ) { if ( mSel.ob.x == -1 ) return; diff --git a/src/tools/eterm/terminal/terminalemulator.hpp b/src/tools/eterm/terminal/terminalemulator.hpp index 5572ba6c4..2e7bc1be7 100644 --- a/src/tools/eterm/terminal/terminalemulator.hpp +++ b/src/tools/eterm/terminal/terminalemulator.hpp @@ -172,7 +172,9 @@ class TerminalEmulator final { int selected( int, int ); - char* getsel(); + char* getsel() const; + + std::string getSelection() const; void mousereport( const TerminalMouseEventType& type, const Vector2i& pos, const Uint32& flags, const Uint32& mod ); @@ -235,7 +237,7 @@ class TerminalEmulator final { void tdeleteline( int ); void tinsertblank( int ); void tinsertblankline( int ); - int tlinelen( int ); + int tlinelen( int ) const; void tmoveto( int, int ); void tmoveato( int, int ); void tnewline( int );