Added eterm::UITerminal.

Many changes over ecode. Working on adding terminal support in ecode. Basic support is working, may contain some bugs.
This commit is contained in:
Martín Lucas Golini
2022-07-05 22:34:48 -03:00
parent c06eaa8d78
commit 00c5515fd0
34 changed files with 772 additions and 198 deletions

View File

@@ -178,7 +178,7 @@ class TerminalDisplay : public ITerminalDisplay {
virtual void onMouseDoubleClick( const Vector2i& pos, const Uint32& flags );
virtual void onMouseMotion( const Vector2i& pos, const Uint32& flags );
virtual void onMouseMove( const Vector2i& pos, const Uint32& flags );
virtual void onMouseDown( const Vector2i& pos, const Uint32& flags );

View File

@@ -0,0 +1,72 @@
#ifndef ETERM_UI_UITERMINAL_HPP
#define ETERM_UI_UITERMINAL_HPP
#include <eepp/ui/uiwidget.hpp>
#include <eterm/terminal/terminaldisplay.hpp>
using namespace EE::UI;
using namespace eterm::Terminal;
namespace eterm { namespace UI {
class EE_API UITerminal : public UIWidget {
public:
static UITerminal* New( Font* font, const Float& fontSize, const Sizef& pixelsSize,
std::string program = "", const std::vector<std::string>& args = {},
const std::string& workingDir = "", const size_t& historySize = 10000,
IProcessFactory* processFactory = nullptr,
const bool& useFrameBuffer = false );
static UITerminal* New( const std::shared_ptr<TerminalDisplay>& terminalDisplay );
virtual ~UITerminal();
virtual Uint32 getType() const;
virtual bool isType( const Uint32& type ) const;
virtual void draw();
const std::shared_ptr<TerminalDisplay>& getTerm() const;
virtual void scheduledUpdate( const Time& time );
const std::string& getTitle() const;
void setTitle( const std::string& title );
protected:
std::string mTitle;
bool mIsCustomTitle{ false };
bool mDraggingSel{ false };
UITerminal( const std::shared_ptr<TerminalDisplay>& terminalDisplay );
std::shared_ptr<TerminalDisplay> mTerm;
virtual Uint32 onTextInput( const TextInputEvent& event );
virtual Uint32 onKeyDown( const KeyEvent& event );
virtual Uint32 onKeyUp( const KeyEvent& event );
virtual Uint32 onMouseMove( const Vector2i& position, const Uint32& flags );
virtual Uint32 onMouseDown( const Vector2i& position, const Uint32& flags );
virtual Uint32 onMouseDoubleClick( const Vector2i& position, const Uint32& flags );
virtual Uint32 onMouseUp( const Vector2i& position, const Uint32& flags );
virtual void onPositionChange();
virtual void onSizeChange();
virtual Uint32 onFocus();
virtual Uint32 onFocusLoss();
};
}} // namespace eterm::UI
#endif

View File

@@ -695,7 +695,7 @@ void TerminalDisplay::onMouseDoubleClick( const Vector2i& pos, const Uint32& fla
}
}
void TerminalDisplay::onMouseMotion( const Vector2i& pos, const Uint32& flags ) {
void TerminalDisplay::onMouseMove( const Vector2i& pos, const Uint32& flags ) {
if ( ( flags & EE_BUTTON_LMASK ) &&
( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_EMPTY ||
mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_READY ) ) {
@@ -712,6 +712,28 @@ void TerminalDisplay::onMouseMotion( const Vector2i& pos, const Uint32& flags )
void TerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) {
auto gridPos{ positionToGrid( pos ) };
if ( ( flags & EE_BUTTON_LMASK ) &&
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 ) {
mTerminal->selstart( gridPos.x, gridPos.y, 0 );
invalidateLines();
} 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() );
}
void TerminalDisplay::onMouseUp( const Vector2i& pos, const Uint32& flags ) {
Uint32 smod = sanitizeMod( mWindow->getInput()->getModState() );
auto scIt = terminalKeyMap.MouseShortcuts().find( flags );
@@ -738,29 +760,6 @@ void TerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) {
}
}
if ( ( flags & EE_BUTTON_LMASK ) &&
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 );
invalidateLines();
} 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() );
}
void TerminalDisplay::onMouseUp( const Vector2i& pos, const Uint32& flags ) {
if ( ( flags & EE_BUTTON_LMASK ) ) {
auto selection = mTerminal->getSelection();
if ( !selection.empty() && selection != "\n" )
@@ -1089,7 +1088,8 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
y += lineHeight;
}
if ( !mEmulator->isScrolling() && !IS_SET( MODE_HIDE ) && mDirtyCursor ) {
if ( !mEmulator->isScrolling() && !IS_SET( MODE_HIDE ) &&
( !mUseFrameBuffer || mDirtyCursor ) ) {
mDirtyCursor = false;
Color drawcol;
if ( IS_SET( MODE_REVERSE ) ) {
@@ -1172,7 +1172,7 @@ void TerminalDisplay::draw( const Vector2f& pos ) {
Primitives p;
p.setForceDraw( false );
p.setColor( defaultBg );
p.drawRectangle( Rectf( mPosition.asFloat(), mSize.asFloat() ) );
p.drawRectangle( Rectf( mPosition.floor().asFloat(), mSize.asFloat() ) );
if ( !mFrameBuffer || mDirty )
drawGrid( pos );

View File

@@ -0,0 +1,140 @@
#include <eepp/scene/scenemanager.hpp>
#include <eepp/ui/uiscenenode.hpp>
#include <eepp/ui/uitabwidget.hpp>
#include <eterm/ui/uiterminal.hpp>
using namespace EE::Scene;
namespace eterm { namespace UI {
UITerminal* UITerminal::New( Font* font, const Float& fontSize, const Sizef& pixelsSize,
std::string program, const std::vector<std::string>& args,
const std::string& workingDir, const size_t& historySize,
IProcessFactory* processFactory, const bool& useFrameBuffer ) {
auto win = SceneManager::instance()->getUISceneNode()->getWindow();
auto terminal =
TerminalDisplay::create( win, font, fontSize, pixelsSize, program, args, workingDir,
historySize, processFactory, useFrameBuffer );
return UITerminal::New( terminal );
}
UITerminal* UITerminal::New( const std::shared_ptr<TerminalDisplay>& terminalDisplay ) {
return eeNew( UITerminal, ( terminalDisplay ) );
}
UITerminal::~UITerminal() {}
Uint32 UITerminal::getType() const {
return UI_TYPE_TERMINAL;
}
bool UITerminal::isType( const Uint32& type ) const {
return getType() == type || UIWidget::isType( type );
}
void UITerminal::draw() {
mTerm->setPosition( mScreenPosi.asFloat() );
mTerm->draw();
}
UITerminal::UITerminal( const std::shared_ptr<TerminalDisplay>& terminalDisplay ) :
UIWidget( "terminal" ), mTerm( terminalDisplay ) {
mFlags |= UI_TAB_STOP;
mTerm->pushEventCallback( [&]( const TerminalDisplay::Event& event ) {
if ( event.type == TerminalDisplay::EventType::TITLE && getParent() ) {
if ( !mIsCustomTitle && mTitle != event.eventData ) {
mTitle = event.eventData;
sendTextEvent( Event::OnTitleChange, mTitle );
}
}
} );
subscribeScheduledUpdate();
}
const std::shared_ptr<TerminalDisplay>& UITerminal::getTerm() const {
return mTerm;
}
void UITerminal::scheduledUpdate( const Time& ) {
mTerm->update();
if ( mTerm->isDirty() )
invalidateDraw();
}
const std::string& UITerminal::getTitle() const {
return mTitle;
}
void UITerminal::setTitle( const std::string& title ) {
if ( title != mTitle ) {
mTitle = title;
mIsCustomTitle = true;
sendTextEvent( Event::OnTitleChange, title );
}
}
Uint32 UITerminal::onTextInput( const TextInputEvent& event ) {
mTerm->onTextInput( event.getChar() );
return 1;
}
Uint32 UITerminal::onKeyDown( const KeyEvent& event ) {
mTerm->onKeyDown( event.getKeyCode(), event.getChar(), event.getMod(), event.getScancode() );
return 1;
}
Uint32 UITerminal::onKeyUp( const KeyEvent& ) {
return 1;
}
Uint32 UITerminal::onMouseMove( const Vector2i& position, const Uint32& flags ) {
mTerm->onMouseMove( position, flags );
return 1;
}
Uint32 UITerminal::onMouseDown( const Vector2i& position, const Uint32& flags ) {
if ( ( flags & EE_BUTTON_LMASK ) &&
mTerm->getTerminal()->getSelectionMode() == TerminalSelectionMode::SEL_IDLE ) {
mDraggingSel = true;
} else if ( ( flags & EE_BUTTON_LMASK ) && mDraggingSel ) {
return 1;
}
mTerm->onMouseDown( position, flags );
return 1;
}
Uint32 UITerminal::onMouseDoubleClick( const Vector2i& position, const Uint32& flags ) {
mTerm->onMouseDoubleClick( position, flags );
return 1;
}
Uint32 UITerminal::onMouseUp( const Vector2i& position, const Uint32& flags ) {
if ( ( flags & EE_BUTTON_LMASK ) && mDraggingSel )
mDraggingSel = false;
mTerm->onMouseUp( position, flags );
return 1;
}
void UITerminal::onPositionChange() {
mTerm->setPosition( mScreenPosi.asFloat() );
UIWidget::onPositionChange();
}
void UITerminal::onSizeChange() {
mTerm->setSize( getPixelsSize() );
UIWidget::onSizeChange();
}
Uint32 UITerminal::onFocus() {
mTerm->setFocus( true );
invalidateDraw();
return UIWidget::onFocus();
}
Uint32 UITerminal::onFocusLoss() {
mTerm->setFocus( false );
invalidateDraw();
return UIWidget::onFocusLoss();
}
}} // namespace eterm::UI