diff --git a/include/eepp/math/rect.hpp b/include/eepp/math/rect.hpp index bd69eef8c..1898b9576 100644 --- a/include/eepp/math/rect.hpp +++ b/include/eepp/math/rect.hpp @@ -63,6 +63,16 @@ template class tRECT { T getHeight() const; + tRECT ceil() const; + + tRECT floor() const; + + tRECT round() const; + + tRECT roundUp() const; + + tRECT roundDown() const; + void scale( T scale, const Vector2& center ); void scale( T scale ); @@ -143,44 +153,44 @@ template tRECT& operator-=( tRECT& R, tRECT X ) { } template tRECT operator*( const tRECT& R, Y X ) { - return tRECT( ( T )( (Y)R.Left * X ), ( T )( (Y)R.Top * X ), ( T )( (Y)R.Right * X ), - ( T )( (Y)R.Bottom * X ) ); + return tRECT( (T)( (Y)R.Left * X ), (T)( (Y)R.Top * X ), (T)( (Y)R.Right * X ), + (T)( (Y)R.Bottom * X ) ); } template tRECT& operator*=( tRECT& R, Y X ) { - R.Left = ( T )( (Y)R.Left * X ); - R.Top = ( T )( (Y)R.Top * X ); - R.Right = ( T )( (Y)R.Right * X ); - R.Bottom = ( T )( (Y)R.Bottom * X ); + R.Left = (T)( (Y)R.Left * X ); + R.Top = (T)( (Y)R.Top * X ); + R.Right = (T)( (Y)R.Right * X ); + R.Bottom = (T)( (Y)R.Bottom * X ); return R; } template tRECT& operator*( tRECT& R, Y X ) { - R.Left = ( T )( (Y)R.Left * X ); - R.Top = ( T )( (Y)R.Top * X ); - R.Right = ( T )( (Y)R.Right * X ); - R.Bottom = ( T )( (Y)R.Bottom * X ); + R.Left = (T)( (Y)R.Left * X ); + R.Top = (T)( (Y)R.Top * X ); + R.Right = (T)( (Y)R.Right * X ); + R.Bottom = (T)( (Y)R.Bottom * X ); return R; } template tRECT operator/( const tRECT& R, Y X ) { - return tRECT( ( T )( (Y)R.Left / X ), ( T )( (Y)R.Top / X ), ( T )( (Y)R.Right / X ), - ( T )( (Y)R.Bottom / X ) ); + return tRECT( (T)( (Y)R.Left / X ), (T)( (Y)R.Top / X ), (T)( (Y)R.Right / X ), + (T)( (Y)R.Bottom / X ) ); } template tRECT& operator/=( tRECT& R, Y X ) { - R.Left = ( T )( (Y)R.Left / X ); - R.Top = ( T )( (Y)R.Top / X ); - R.Right = ( T )( (Y)R.Right / X ); - R.Bottom = ( T )( (Y)R.Bottom / X ); + R.Left = (T)( (Y)R.Left / X ); + R.Top = (T)( (Y)R.Top / X ); + R.Right = (T)( (Y)R.Right / X ); + R.Bottom = (T)( (Y)R.Bottom / X ); return R; } template tRECT& operator/( tRECT& R, Y X ) { - R.Left = ( T )( (Y)R.Left / X ); - R.Top = ( T )( (Y)R.Top / X ); - R.Right = ( T )( (Y)R.Right / X ); - R.Bottom = ( T )( (Y)R.Bottom / X ); + R.Left = (T)( (Y)R.Left / X ); + R.Top = (T)( (Y)R.Top / X ); + R.Right = (T)( (Y)R.Right / X ); + R.Bottom = (T)( (Y)R.Bottom / X ); return R; } @@ -311,8 +321,8 @@ template bool tRECT::intersectCircle( Vector2 pos, const T& r } template bool tRECT::intersectCircles( const tRECT& b ) const { - Float ra = ( Float )( Right - Left ) * 0.5f; - Float rb = ( Float )( b.Right - b.Left ) * 0.5f; + Float ra = (Float)( Right - Left ) * 0.5f; + Float rb = (Float)( b.Right - b.Left ) * 0.5f; Float dist = ra + rb; Float dx = ( b.Left + rb ) - ( Left + ra ); Float dy = ( b.Top + rb ) - ( Top + ra ); @@ -363,6 +373,29 @@ template void tRECT::scale( Vector2 scale ) { scale( scale, getCenter() ); } +template tRECT tRECT::ceil() const { + return tRECT( eeceil( Left ), eeceil( Top ), eeceil( Right ), eeceil( Bottom ) ); +} + +template tRECT tRECT::floor() const { + return tRECT( eefloor( Left ), eefloor( Top ), eefloor( Right ), eefloor( Bottom ) ); +} + +template tRECT tRECT::round() const { + return tRECT( Math::round( Left ), Math::round( Top ), Math::round( Right ), + Math::round( Bottom ) ); +} + +template tRECT tRECT::roundUp() const { + return tRECT( Math::roundUp( Left ), Math::roundUp( Top ), Math::roundUp( Right ), + Math::roundUp( Bottom ) ); +} + +template tRECT tRECT::roundDown() const { + return tRECT( Math::roundDown( Left ), Math::roundDown( Top ), Math::roundDown( Right ), + Math::roundDown( Bottom ) ); +} + typedef tRECT Rectu; typedef tRECT Rectf; typedef tRECT Rect; diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 8b8f857ca..c4465b821 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -1203,7 +1203,6 @@ ecode-debug ProjectExplorer.CustomExecutableRunConfiguration - /home/programming/lad/lad-api/ true false false diff --git a/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp b/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp index 51b9d124f..a69728d59 100644 --- a/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp +++ b/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp @@ -132,11 +132,11 @@ static const Scancode asciiScancodeTable[] = { class TerminalDisplay : public ITerminalDisplay { public: - enum class EventType { TITLE, ICON_TITLE, UNKNOWN }; + enum class EventType { TITLE, ICON_TITLE, SCROLL_HISTORY, HISTORY_LENGTH_CHANGE, UNKNOWN }; struct Event { EventType type{ EventType::UNKNOWN }; - std::string eventData; + std::string eventData{}; }; typedef std::function EventFunc; @@ -217,9 +217,9 @@ class TerminalDisplay : public ITerminalDisplay { bool isBlinkingCursor(); - const Sizef& getPadding() const; + const Rectf& getPadding() const; - void setPadding( const Sizef& padding ); + void setPadding( const Rectf& padding ); const std::shared_ptr& getTerminal() const; @@ -247,7 +247,7 @@ class TerminalDisplay : public ITerminalDisplay { Font* mFont{ nullptr }; Float mFontSize{ 12 }; - Sizef mPadding; + Rectf mPadding; Vector2f mPosition; Sizef mSize; std::vector mDirtyLines; diff --git a/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp b/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp index f35aa769e..2c3fe436e 100644 --- a/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp +++ b/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp @@ -156,7 +156,7 @@ class TerminalEmulator final { inline int getNumRows() const { return mTerm.row; } - inline int getHistorySize() const { return mTerm.histi; } + int getHistorySize() const; int write( const char* buf, size_t buflen ); @@ -197,6 +197,8 @@ class TerminalEmulator final { void kscrollup( const TerminalArg* a ); + void kscrollto( const TerminalArg* a ); + bool isScrolling() const; void ttywrite( const char* s, size_t n, int may_echo ); @@ -209,6 +211,8 @@ class TerminalEmulator final { void clearHistory(); + int scrollPos(); + private: DpyPtr mDpy; PtyPtr mPty; diff --git a/src/modules/eterm/include/eterm/ui/uiterminal.hpp b/src/modules/eterm/include/eterm/ui/uiterminal.hpp index d511f86d9..d20f74b3b 100644 --- a/src/modules/eterm/include/eterm/ui/uiterminal.hpp +++ b/src/modules/eterm/include/eterm/ui/uiterminal.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -13,6 +14,8 @@ namespace eterm { namespace UI { class UITerminal : public UIWidget { public: + enum ScrollViewType { Inclusive, Exclusive }; + static UITerminal* New( Font* font, const Float& fontSize, const Sizef& pixelsSize, std::string program = "", const std::vector& args = {}, const std::string& workingDir = "", const size_t& historySize = 10000, @@ -72,6 +75,21 @@ class UITerminal : public UIWidget { bool isUsingCustomTitle() const; + void setVerticalScrollMode( const ScrollBarMode& Mode ); + + const ScrollBarMode& getVerticalScrollMode() const; + + UIScrollBar* getVerticalScrollBar() const; + + const ScrollViewType& getViewType() const; + + void setViewType( const ScrollViewType& viewType ); + + virtual bool applyProperty( const StyleSheetProperty& attribute ); + + virtual std::string getPropertyString( const PropertyDefinition* propertyDef, + const Uint32& propertyIndex = 0 ) const; + protected: std::string mTitle; bool mIsCustomTitle{ false }; @@ -82,6 +100,12 @@ class UITerminal : public UIWidget { std::map mCommands; UIPopUpMenu* mCurrentMenu{ nullptr }; size_t mMenuIconSize{ 16 }; + ScrollViewType mViewType{ Inclusive }; + ScrollBarMode mVScrollMode{ ScrollBarMode::Auto }; + UIScrollBar* mVScroll{ nullptr }; + int mScrollOffset; + bool mScrollByBar{ false }; + Clock mMouseClock; UITerminal( const std::shared_ptr& terminalDisplay ); @@ -105,10 +129,20 @@ class UITerminal : public UIWidget { virtual void onSizeChange(); + virtual void onAlphaChange(); + + virtual void onPaddingChange(); + virtual Uint32 onFocus(); virtual Uint32 onFocusLoss(); + virtual void updateScroll(); + + virtual void onContentSizeChange(); + + virtual int getContentSize() const; + UIMenuItem* menuAdd( UIPopUpMenu* menu, const std::string& translateKey, const String& translateString, const std::string& icon, const std::string& cmd ); @@ -118,6 +152,14 @@ class UITerminal : public UIWidget { Drawable* findIcon( const std::string& name ); void createDefaultContextMenuOptions( UIPopUpMenu* menu ); + + int getScrollableArea() const; + + int getVisibleArea() const; + + virtual void updateScrollPosition(); + + virtual void onScrollChange(); }; }} // namespace eterm::UI diff --git a/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp b/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp index 7d3f3009c..afa160073 100644 --- a/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp +++ b/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp @@ -499,11 +499,11 @@ bool TerminalDisplay::isBlinkingCursor() { mCursorMode == Terminal::BlinkUnderline || mCursorMode == Terminal::BlinkBar; } -const Sizef& TerminalDisplay::getPadding() const { +const Rectf& TerminalDisplay::getPadding() const { return mPadding; } -void TerminalDisplay::setPadding( const Sizef& padding ) { +void TerminalDisplay::setPadding( const Rectf& padding ) { if ( mPadding != padding.ceil() ) { mPadding = padding.ceil(); onSizeChange(); @@ -553,8 +553,12 @@ void TerminalDisplay::update() { mClock.restart(); invalidateCursor(); } - if ( mTerminal ) + if ( mTerminal ) { + int histi = mTerminal->getHistorySize(); mTerminal->update(); + if ( histi != mTerminal->getHistorySize() ) + sendEvent( { EventType::HISTORY_LENGTH_CHANGE } ); + } } void TerminalDisplay::action( TerminalShortcutAction action ) { @@ -574,31 +578,37 @@ void TerminalDisplay::action( TerminalShortcutAction action ) { case TerminalShortcutAction::SCROLLUP_SCREEN: { TerminalArg arg( (int)-1 ); mTerminal->kscrollup( &arg ); + sendEvent( { EventType::SCROLL_HISTORY } ); break; } case TerminalShortcutAction::SCROLLDOWN_SCREEN: { TerminalArg arg( (int)-1 ); mTerminal->kscrolldown( &arg ); + sendEvent( { EventType::SCROLL_HISTORY } ); break; } case TerminalShortcutAction::SCROLLUP_ROW: { TerminalArg arg( (int)1 ); mTerminal->kscrollup( &arg ); + sendEvent( { EventType::SCROLL_HISTORY } ); break; } case TerminalShortcutAction::SCROLLDOWN_ROW: { TerminalArg arg( (int)1 ); mTerminal->kscrolldown( &arg ); + sendEvent( { EventType::SCROLL_HISTORY } ); break; } case TerminalShortcutAction::SCROLLUP_HISTORY: { TerminalArg arg( (int)INT_MAX ); mTerminal->kscrollup( &arg ); + sendEvent( { EventType::SCROLL_HISTORY } ); break; } case TerminalShortcutAction::SCROLLDOWN_HISTORY: { TerminalArg arg( (int)INT_MAX ); mTerminal->kscrolldown( &arg ); + sendEvent( { EventType::SCROLL_HISTORY } ); break; } case TerminalShortcutAction::FONTSIZE_GROW: { @@ -682,7 +692,8 @@ void TerminalDisplay::drawCursor( int cx, int cy, TerminalGlyph g, int, int, Ter void TerminalDisplay::drawEnd() {} void TerminalDisplay::draw() { - draw( nullptr != mFrameBuffer ? mPadding : mPosition.floor() + mPadding ); + draw( nullptr != mFrameBuffer ? Vector2f( mPadding.Left, mPadding.Top ) + : mPosition.floor() + Vector2f( mPadding.Left, mPadding.Top ) ); } void TerminalDisplay::onMouseDoubleClick( const Vector2i& pos, const Uint32& flags ) { @@ -1194,7 +1205,7 @@ void TerminalDisplay::draw( const Vector2f& pos ) { } Vector2i TerminalDisplay::positionToGrid( const Vector2i& pos ) { - Vector2f relPos = { pos.x - mPosition.x - mPadding.x, pos.y - mPosition.y - mPadding.y }; + Vector2f relPos = { pos.x - mPosition.x - mPadding.Left, pos.y - mPosition.y - mPadding.Top }; int mouseX = 0; int mouseY = 0; @@ -1216,7 +1227,9 @@ Vector2i TerminalDisplay::positionToGrid( const Vector2i& pos ) { } void TerminalDisplay::onSizeChange() { - Sizei gridSize( gridSizeFromTermDimensions( mFont, mFontSize, mSize - mPadding * 2.f ) ); + Sizei gridSize( gridSizeFromTermDimensions( + mFont, mFontSize, + mSize - Vector2f( mPadding.Left + mPadding.Right, mPadding.Top + mPadding.Bottom ) ) ); if ( mTerminal ) { if ( gridSize.getWidth() != mTerminal->getNumColumns() || gridSize.getHeight() != mTerminal->getNumRows() ) { diff --git a/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp b/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp index eb9263383..98c9831fb 100644 --- a/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp +++ b/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp @@ -580,7 +580,7 @@ char* TerminalEmulator::getsel( void ) const { } bool TerminalEmulator::hasSelection() const { - return mSel.ob.x != -1; + return mSel.mode == SEL_READY; } std::string TerminalEmulator::getSelection() const { @@ -682,6 +682,16 @@ void TerminalEmulator::kscrollup( const TerminalArg* a ) { } } +void TerminalEmulator::kscrollto( const TerminalArg* a ) { + int n = a->i; + + if ( 0 <= n && n <= mTerm.histi ) { + mTerm.scr = n; + selscroll( 0, n ); + tfulldirt(); + } +} + int TerminalEmulator::tisaltscr() { return IS_SET( MODE_ALTSCREEN ); } @@ -701,6 +711,10 @@ void TerminalEmulator::clearHistory() { mTerm.histi = 0; } +int TerminalEmulator::scrollPos() { + return mTerm.scr; +} + bool TerminalEmulator::isScrolling() const { return mTerm.scr != 0; } @@ -2601,6 +2615,10 @@ int TerminalEmulator::getExitCode() const { return mExitCode; } +int TerminalEmulator::getHistorySize() const { + return mTerm.histi; +} + int TerminalEmulator::write( const char* buf, size_t buflen ) { return mPty->write( buf, (int)buflen ); } diff --git a/src/modules/eterm/src/eterm/ui/uiterminal.cpp b/src/modules/eterm/src/eterm/ui/uiterminal.cpp index da2574e5c..cce918079 100644 --- a/src/modules/eterm/src/eterm/ui/uiterminal.cpp +++ b/src/modules/eterm/src/eterm/ui/uiterminal.cpp @@ -43,16 +43,35 @@ void UITerminal::draw() { UITerminal::UITerminal( const std::shared_ptr& terminalDisplay ) : UIWidget( "terminal" ), mKeyBindings( getUISceneNode()->getWindow()->getInput() ), + mVScroll( UIScrollBar::NewVertical() ), 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 ); + switch ( event.type ) { + case TerminalDisplay::EventType::TITLE: { + if ( !mIsCustomTitle && mTitle != event.eventData ) { + mTitle = event.eventData; + sendTextEvent( Event::OnTitleChange, mTitle ); + } + break; + } + case TerminalDisplay::EventType::HISTORY_LENGTH_CHANGE: { + if ( !mTerm->getTerminal()->tisaltscr() ) + onContentSizeChange(); + break; + } + case TerminalDisplay::EventType::SCROLL_HISTORY: { + updateScrollPosition(); + break; + } + default: { } } } ); + + mVScroll->setParent( this ); + mVScroll->addEventListener( Event::OnValueChange, [&]( const Event* ) { updateScroll(); } ); + setCommand( "terminal-scroll-up-screen", [&] { mTerm->action( TerminalShortcutAction::SCROLLUP_SCREEN ); } ); setCommand( "terminal-scroll-down-screen", @@ -75,14 +94,197 @@ UITerminal::UITerminal( const std::shared_ptr& terminalDisplay subscribeScheduledUpdate(); } +int UITerminal::getContentSize() const { + if ( mTerm && mTerm->getTerminal() ) + return mTerm->getTerminal()->getHistorySize() + mTerm->getTerminal()->getNumRows(); + return 0; +} + +void UITerminal::onContentSizeChange() { + int contentSize( getContentSize() ); + int visibleArea( getVisibleArea() ); + + if ( ScrollBarMode::AlwaysOn == mVScrollMode ) { + mVScroll->setVisible( true )->setEnabled( true ); + } else if ( ScrollBarMode::AlwaysOff == mVScrollMode ) { + mVScroll->setVisible( false )->setEnabled( false ); + } else { + bool visible = !mTerm->getTerminal()->tisaltscr() && contentSize > visibleArea; + mVScroll->setVisible( visible )->setEnabled( visible ); + } + + mVScroll->setPixelsPosition( getPixelsSize().getWidth() - mVScroll->getPixelsSize().getWidth() - + mPaddingPx.Right, + mPaddingPx.Top ); + + mVScroll->setPixelsSize( mVScroll->getPixelsSize().getWidth(), + getPixelsSize().getHeight() - mPaddingPx.Top - mPaddingPx.Bottom ); + + mVScroll->setPageStep( visibleArea / (Float)contentSize ); + + updateScrollPosition(); + updateScroll(); +} + +const ScrollBarMode& UITerminal::getVerticalScrollMode() const { + return mVScrollMode; +} + +const UITerminal::ScrollViewType& UITerminal::getViewType() const { + return mViewType; +} + +void UITerminal::setViewType( const ScrollViewType& viewType ) { + if ( viewType != mViewType ) { + mViewType = viewType; + onContentSizeChange(); + } +} + +UIScrollBar* UITerminal::getVerticalScrollBar() const { + return mVScroll; +} + +void UITerminal::onAlphaChange() { + UIWidget::onAlphaChange(); + mVScroll->setAlpha( mAlpha ); +} + +void UITerminal::onPaddingChange() { + mTerm->setPadding( + { mPaddingPx.Left, mPaddingPx.Top, + mPaddingPx.Right + + ( mViewType == Exclusive ? mVScroll->getPixelsSize().getWidth() : 0.f ), + mPaddingPx.Bottom } ); + onContentSizeChange(); + UIWidget::onPaddingChange(); +} + +int UITerminal::getVisibleArea() const { + return ( mTerm && mTerm->getTerminal() ) ? mTerm->getTerminal()->getNumRows() : 0; +} + +void UITerminal::updateScrollPosition() { + if ( mTerm && mTerm->getTerminal() ) + mVScroll->setValue( 1.f - mTerm->getTerminal()->scrollPos() / + (Float)mTerm->getTerminal()->getHistorySize(), + false ); +} + +int UITerminal::getScrollableArea() const { + int contentSize( getContentSize() ); + int size( getVisibleArea() ); + return contentSize - size; +} + +void UITerminal::updateScroll() { + int totalScroll = getScrollableArea(); + int initScroll( mScrollOffset ); + mScrollOffset = 0; + + if ( mVScroll->isVisible() && totalScroll > 0 ) + mScrollOffset = totalScroll * mVScroll->getValue(); + + if ( initScroll != mScrollOffset ) + onScrollChange(); +} + +void UITerminal::onScrollChange() { + if ( !mTerm || !mTerm->getTerminal() ) + return; + int scrollTo = ( getScrollableArea() - mScrollOffset ); + TerminalArg arg( scrollTo ); + mTerm->getTerminal()->kscrollto( &arg ); +} + +void UITerminal::setVerticalScrollMode( const ScrollBarMode& Mode ) { + if ( Mode != mVScrollMode ) { + mVScrollMode = Mode; + onContentSizeChange(); + } +} + +std::string UITerminal::getPropertyString( const PropertyDefinition* propertyDef, + const Uint32& propertyIndex ) const { + if ( NULL == propertyDef ) + return ""; + + switch ( propertyDef->getPropertyId() ) { + case PropertyId::VScrollMode: + return getVerticalScrollMode() == ScrollBarMode::Auto + ? "auto" + : ( getVerticalScrollMode() == ScrollBarMode::AlwaysOn ? "on" : "off" ); + case PropertyId::ScrollBarStyle: + return mVScroll->getScrollBarType() == UIScrollBar::NoButtons ? "no-buttons" + : "two-buttons"; + case PropertyId::ScrollBarMode: + return getViewType() == Inclusive ? "inclusive" : "exclusive"; + default: + return UIWidget::getPropertyString( propertyDef, propertyIndex ); + } +} + +bool UITerminal::applyProperty( const StyleSheetProperty& attribute ) { + if ( !checkPropertyDefinition( attribute ) ) + return false; + + switch ( attribute.getPropertyDefinition()->getPropertyId() ) { + case PropertyId::ScrollBarMode: { + std::string val( attribute.asString() ); + String::toLowerInPlace( val ); + if ( "inclusive" == val || "inside" == val ) + setViewType( Inclusive ); + else if ( "exclusive" == val || "outside" == val ) + setViewType( Exclusive ); + break; + } + case PropertyId::VScrollMode: { + std::string val( attribute.asString() ); + String::toLowerInPlace( val ); + + if ( "on" == val ) + setVerticalScrollMode( ScrollBarMode::AlwaysOn ); + else if ( "off" == val ) + setVerticalScrollMode( ScrollBarMode::AlwaysOn ); + else if ( "auto" == val ) + setVerticalScrollMode( ScrollBarMode::Auto ); + break; + } + case PropertyId::ScrollBarStyle: { + std::string val( attribute.asString() ); + String::toLowerInPlace( val ); + + if ( "no-buttons" == val || "nobuttons" == val ) { + mVScroll->setScrollBarStyle( UIScrollBar::NoButtons ); + } else if ( "two-buttons" == val || "twobuttons" == val ) { + mVScroll->setScrollBarStyle( UIScrollBar::TwoButtons ); + } + break; + } + default: + return UIWidget::applyProperty( attribute ); + } + + return true; +} + const std::shared_ptr& UITerminal::getTerm() const { return mTerm; } void UITerminal::scheduledUpdate( const Time& ) { mTerm->update(); + if ( mTerm->isDirty() ) invalidateDraw(); + + if ( ScrollBarMode::AlwaysOn == mVScrollMode ) { + mVScroll->setVisible( !mTerm->getTerminal()->tisaltscr() ) + ->setEnabled( !mTerm->getTerminal()->tisaltscr() ); + } else if ( ScrollBarMode::Auto == mVScrollMode ) { + if ( mViewType == Inclusive && mMouseClock.getElapsedTime() > Seconds( 1 ) ) + mVScroll->setVisible( false )->setEnabled( false ); + } } const std::string& UITerminal::getTitle() const { @@ -188,6 +390,13 @@ Uint32 UITerminal::onKeyUp( const KeyEvent& ) { } Uint32 UITerminal::onMouseMove( const Vector2i& position, const Uint32& flags ) { + if ( mViewType == Inclusive && ScrollBarMode::Auto == mVScrollMode ) { + mMouseClock.restart(); + bool visible = !mTerm->getTerminal()->tisaltscr() && getContentSize() > getVisibleArea() && + !mTerm->getTerminal()->hasSelection(); + mVScroll->setVisible( visible )->setEnabled( visible ); + } + if ( getUISceneNode()->getUIEventDispatcher()->isNodeDragging() ) return 0; @@ -231,7 +440,13 @@ void UITerminal::onPositionChange() { } void UITerminal::onSizeChange() { - mTerm->setSize( getPixelsSize() ); + mTerm->setSize( { getPixelsSize().getWidth(), getPixelsSize().getHeight() } ); + mTerm->setPadding( + { mPaddingPx.Left, mPaddingPx.Top, + mPaddingPx.Right + + ( mViewType == Exclusive ? mVScroll->getPixelsSize().getWidth() : 0.f ), + mPaddingPx.Bottom } ); + onContentSizeChange(); UIWidget::onSizeChange(); } diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index cdcf6bd08..352907127 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -1806,7 +1806,7 @@ std::map App::getLocalKeybindings() { { { KEY_F3, KEYMOD_SHIFT }, "find-prev" }, { { KEY_F12, KEYMOD_NONE }, "console-toggle" }, { { KEY_F, KeyMod::getDefaultModifier() }, "find-replace" }, - { { KEY_Q, KeyMod::getDefaultModifier() }, "close-app" }, + { { KEY_Q, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "close-app" }, { { KEY_O, KeyMod::getDefaultModifier() }, "open-file" }, { { KEY_W, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "download-file-web" }, { { KEY_O, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-folder" }, @@ -3001,7 +3001,8 @@ FontTrueType* App::loadFont( const std::string& name, std::string fontPath, return FontTrueType::New( name, fontPath ); } -void App::init( std::string file, const Float& pidelDensity, const std::string& colorScheme ) { +void App::init( std::string file, const Float& pidelDensity, const std::string& colorScheme, + bool terminal ) { DisplayManager* displayManager = Engine::instance()->getDisplayManager(); Display* currentDisplay = displayManager->getDisplayIndex( 0 ); mDisplayDPI = currentDisplay->getDPI(); @@ -3498,7 +3499,11 @@ void App::init( std::string file, const Float& pidelDensity, const std::string& file = ""; #endif - initProjectTreeView( file ); + if ( terminal && file.empty() ) { + createNewTerminal(); + } else { + initProjectTreeView( file ); + } Log::info( "Init ProjectTreeView took: %.2fms", globalClock.getElapsedTime().asMilliseconds() ); @@ -3546,7 +3551,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { args::ValueFlag prefersColorScheme( parser, "prefers-color-scheme", "Set the preferred color scheme (\"light\" or \"dark\")", { 'c', "prefers-color-scheme" } ); - + args::Flag terminal( parser, "terminal", "Open a new terminal", { 't', "terminal", "folder" } ); try { #if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN parser.ParseCLI( argc, argv ); @@ -3569,7 +3574,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { appInstance = eeNew( App, () ); appInstance->init( filePos ? filePos.Get() : file.Get(), pixelDenstiyConf ? pixelDenstiyConf.Get() : 0.f, - prefersColorScheme ? prefersColorScheme.Get() : "" ); + prefersColorScheme ? prefersColorScheme.Get() : "", terminal.Get() ); eeSAFE_DELETE( appInstance ); Engine::destroySingleton(); diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index fe5ac17f5..8dcb5cc60 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -31,7 +31,8 @@ class App : public UICodeEditorSplitter::Client { void createWidgetTreeView(); - void init( std::string file, const Float& pidelDensity, const std::string& colorScheme ); + void init( std::string file, const Float& pidelDensity, const std::string& colorScheme, + bool terminal ); void setAppTitle( const std::string& title ); diff --git a/src/tools/ecode/version.hpp b/src/tools/ecode/version.hpp index a28b96778..2e6bbfe26 100644 --- a/src/tools/ecode/version.hpp +++ b/src/tools/ecode/version.hpp @@ -9,7 +9,7 @@ using namespace EE; #define ECODE_MAJOR_VERSION 0 #define ECODE_MINOR_VERSION 2 #define ECODE_PATCH_LEVEL 0 -#define ECODE_CODENAME "Viriya" +#define ECODE_CODENAME "Upādāna" /** The compiled version of the library */ #define ECODE_VERSION( x ) \