diff --git a/docs/articles/cssspecification.md b/docs/articles/cssspecification.md index d2158424d..248655270 100644 --- a/docs/articles/cssspecification.md +++ b/docs/articles/cssspecification.md @@ -1672,11 +1672,11 @@ Defines how the scrollbar should fit inside an scrollable element. * Applicable to: EE::UI::UIScrollView (ScrollView) * Data Type: [string-list](#string-list-data-type) * Value List: - * `inclusive`: The scrollbar is part of the scrollable element container, this means that it will + * `overlay`: The scrollbar is part of the scrollable element container, this means that it will be on top of the content (scrollbars on mobile usually behave like this). - * `exclusive`: The scrollbar is outside the scrollable element container, this means that it will not + * `outside`: The scrollbar is outside the scrollable element container, this means that it will not be on top of the content (scrollbars on desktop usually behave like this). -* Default value: `exclusive` +* Default value: `outside` --- diff --git a/include/eepp/ui/uihelper.hpp b/include/eepp/ui/uihelper.hpp index 43602f57f..599dcd4b4 100644 --- a/include/eepp/ui/uihelper.hpp +++ b/include/eepp/ui/uihelper.hpp @@ -112,6 +112,8 @@ enum UINodeType { enum class ScrollBarMode : Uint32 { Auto, AlwaysOn, AlwaysOff }; +enum class ScrollViewType { Overlay, Outside }; + enum class UIOrientation : Uint32 { Vertical, Horizontal }; enum class SizePolicy : Uint32 { Fixed, MatchParent, WrapContent }; diff --git a/include/eepp/ui/uiscrollablewidget.hpp b/include/eepp/ui/uiscrollablewidget.hpp index 513a09587..c53566a98 100644 --- a/include/eepp/ui/uiscrollablewidget.hpp +++ b/include/eepp/ui/uiscrollablewidget.hpp @@ -9,8 +9,6 @@ class UIScrollBar; class EE_API UIScrollableWidget : public UIWidget { public: - enum ScrollViewType { Inclusive, Exclusive }; - virtual Uint32 getType() const; virtual bool isType( const Uint32& type ) const; diff --git a/include/eepp/ui/uiscrollview.hpp b/include/eepp/ui/uiscrollview.hpp index 38c4cd287..75575b2ac 100644 --- a/include/eepp/ui/uiscrollview.hpp +++ b/include/eepp/ui/uiscrollview.hpp @@ -9,8 +9,6 @@ class UIScrollBar; class EE_API UIScrollView : public UITouchDraggableWidget { public: - enum ScrollViewType { Inclusive, Exclusive }; - static UIScrollView* New(); UIScrollView(); diff --git a/src/eepp/ui/abstract/uiabstracttableview.cpp b/src/eepp/ui/abstract/uiabstracttableview.cpp index b31fa830c..930114f4d 100644 --- a/src/eepp/ui/abstract/uiabstracttableview.cpp +++ b/src/eepp/ui/abstract/uiabstracttableview.cpp @@ -347,11 +347,12 @@ void UIAbstractTableView::columnResizeToContent( const size_t& colIndex ) { } Float UIAbstractTableView::getContentSpaceWidth() const { - return eefloor( - getPixelsSize().getWidth() - getPixelsPadding().Left - getPixelsPadding().Right - - ( mVScroll->isVisible() && ( mScrollViewType == Exclusive || mVScroll->getAlpha() != 0.f ) - ? mVScroll->getPixelsSize().getWidth() - : 0 ) ); + return eefloor( getPixelsSize().getWidth() - getPixelsPadding().Left - + getPixelsPadding().Right - + ( mVScroll->isVisible() && ( mScrollViewType == ScrollViewType::Outside || + mVScroll->getAlpha() != 0.f ) + ? mVScroll->getPixelsSize().getWidth() + : 0 ) ); } void UIAbstractTableView::updateColumnsWidth() { @@ -360,7 +361,7 @@ void UIAbstractTableView::updateColumnsWidth() { if ( visibleColumnCount() == 1 && ( col = visibleColumn() ) != -1 ) { Float width = eemax( getContentSpaceWidth(), getMaxColumnContentWidth( col, true ) ); bool shouldVScrollBeVisible = shouldVerticalScrollBeVisible(); - if ( mScrollViewType == Exclusive || mVScroll->getAlpha() != 0.f ) { + if ( mScrollViewType == ScrollViewType::Outside || mVScroll->getAlpha() != 0.f ) { if ( !mVScroll->isVisible() && shouldVScrollBeVisible ) width -= getVerticalScrollBar()->getPixelsSize().getWidth(); else if ( mVScroll->isVisible() && !shouldVScrollBeVisible ) diff --git a/src/eepp/ui/uiscrollablewidget.cpp b/src/eepp/ui/uiscrollablewidget.cpp index 385f5c59f..e8843b912 100644 --- a/src/eepp/ui/uiscrollablewidget.cpp +++ b/src/eepp/ui/uiscrollablewidget.cpp @@ -6,7 +6,7 @@ namespace EE { namespace UI { UIScrollableWidget::UIScrollableWidget( const std::string& tag ) : UIWidget( tag ), - mScrollViewType( Exclusive ), + mScrollViewType( ScrollViewType::Outside ), mVScrollMode( ScrollBarMode::Auto ), mHScrollMode( ScrollBarMode::Auto ), mVScroll( UIScrollBar::NewVertical() ), @@ -79,7 +79,7 @@ void UIScrollableWidget::setScrollMode( const ScrollBarMode& verticalMode, } } -const UIScrollableWidget::ScrollViewType& UIScrollableWidget::getViewType() const { +const ScrollViewType& UIScrollableWidget::getViewType() const { return mScrollViewType; } @@ -109,7 +109,7 @@ void UIScrollableWidget::onContentSizeChange() { Float totW = getPixelsSize().getWidth() - getPixelsPadding().Left - getPixelsPadding().Right; - if ( mScrollViewType == Exclusive ) + if ( mScrollViewType == ScrollViewType::Outside ) totW -= mVScroll->getPixelsSize().getWidth(); bool visible = contentSize.getWidth() > totW; @@ -133,12 +133,12 @@ void UIScrollableWidget::onContentSizeChange() { } if ( ScrollBarMode::Auto == mHScrollMode ) { - Float totW = getPixelsSize().getWidth() - getPixelsPadding().Left - - getPixelsPadding().Right - - ( mVScroll->isVisible() && - ( mScrollViewType == Exclusive || mVScroll->getAlpha() != 0.f ) - ? mVScroll->getPixelsSize().getWidth() - : 0 ); + Float totW = + getPixelsSize().getWidth() - getPixelsPadding().Left - getPixelsPadding().Right - + ( mVScroll->isVisible() && + ( mScrollViewType == ScrollViewType::Outside || mVScroll->getAlpha() != 0.f ) + ? mVScroll->getPixelsSize().getWidth() + : 0 ); bool visible = contentSize.getWidth() > totW; @@ -147,7 +147,7 @@ void UIScrollableWidget::onContentSizeChange() { Sizef size = getPixelsSize() - mPaddingPx; - if ( Exclusive == mScrollViewType ) { + if ( ScrollViewType::Outside == mScrollViewType ) { if ( mVScroll->isVisible() ) size.x -= mVScroll->getPixelsSize().getWidth(); @@ -258,7 +258,7 @@ std::string UIScrollableWidget::getPropertyString( const PropertyDefinition* pro return mVScroll->getScrollBarType() == UIScrollBar::NoButtons ? "no-buttons" : "two-buttons"; case PropertyId::ScrollBarMode: - return getViewType() == Inclusive ? "inclusive" : "exclusive"; + return getViewType() == ScrollViewType::Overlay ? "overlay" : "outside"; default: return UIWidget::getPropertyString( propertyDef, propertyIndex ); } @@ -313,10 +313,10 @@ bool UIScrollableWidget::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::ScrollBarMode: { std::string val( attribute.asString() ); String::toLowerInPlace( val ); - if ( "inclusive" == val || "inside" == val ) - setScrollViewType( Inclusive ); - else if ( "exclusive" == val || "outside" == val ) - setScrollViewType( Exclusive ); + if ( "overlay" == val || "inclusive" == val || "inside" == val ) + setScrollViewType( ScrollViewType::Overlay ); + else if ( "outside" == val || "exclusive" == val || "outside" == val ) + setScrollViewType( ScrollViewType::Outside ); break; } case PropertyId::VScrollMode: { diff --git a/src/eepp/ui/uiscrollview.cpp b/src/eepp/ui/uiscrollview.cpp index a8b21c2c1..0479b3625 100644 --- a/src/eepp/ui/uiscrollview.cpp +++ b/src/eepp/ui/uiscrollview.cpp @@ -10,7 +10,7 @@ UIScrollView* UIScrollView::New() { UIScrollView::UIScrollView() : UITouchDraggableWidget( "scrollview" ), - mViewType( Exclusive ), + mViewType( ScrollViewType::Outside ), mVScrollMode( ScrollBarMode::Auto ), mHScrollMode( ScrollBarMode::Auto ), mVScroll( UIScrollBar::NewVertical() ), @@ -114,7 +114,7 @@ const ScrollBarMode& UIScrollView::getHorizontalScrollMode() const { return mHScrollMode; } -const UIScrollView::ScrollViewType& UIScrollView::getViewType() const { +const ScrollViewType& UIScrollView::getViewType() const { return mViewType; } @@ -175,7 +175,7 @@ void UIScrollView::containerUpdate() { Sizef size = getSize() - mPadding; - if ( Exclusive == mViewType ) { + if ( ScrollViewType::Outside == mViewType ) { if ( mVScroll->isVisible() ) size.x -= mVScroll->getSize().getWidth(); @@ -280,7 +280,7 @@ void UIScrollView::onTouchDragValueChange( Vector2f diff ) { } bool UIScrollView::isTouchOverAllowedChildren() { - bool ret = mViewType == Exclusive + bool ret = mViewType == ScrollViewType::Outside ? !mVScroll->isMouseOverMeOrChildren() && !mHScroll->isMouseOverMeOrChildren() : true; return isMouseOverMeOrChildren() && mScrollView->isMouseOverMeOrChildren() && ret; @@ -304,7 +304,7 @@ std::string UIScrollView::getPropertyString( const PropertyDefinition* propertyD return mVScroll->getScrollBarType() == UIScrollBar::NoButtons ? "no-buttons" : "two-buttons"; case PropertyId::ScrollBarMode: - return getViewType() == Inclusive ? "inclusive" : "exclusive"; + return getViewType() == ScrollViewType::Overlay ? "overlay" : "outside"; default: return UITouchDraggableWidget::getPropertyString( propertyDef, propertyIndex ); } @@ -326,10 +326,10 @@ bool UIScrollView::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::ScrollBarMode: { std::string val( attribute.asString() ); String::toLowerInPlace( val ); - if ( "inclusive" == val || "inside" == val ) - setViewType( Inclusive ); + if ( "overlay" == val || "inclusive" == val || "inside" == val ) + setViewType( ScrollViewType::Overlay ); else if ( "exclusive" == val || "outside" == val ) - setViewType( Exclusive ); + setViewType( ScrollViewType::Outside ); break; } case PropertyId::VScrollMode: { diff --git a/src/modules/eterm/include/eterm/ui/uiterminal.hpp b/src/modules/eterm/include/eterm/ui/uiterminal.hpp index 3b7e507b4..0243bde4d 100644 --- a/src/modules/eterm/include/eterm/ui/uiterminal.hpp +++ b/src/modules/eterm/include/eterm/ui/uiterminal.hpp @@ -14,15 +14,12 @@ namespace eterm { namespace UI { class UITerminal : public UIWidget { public: - enum ScrollViewType { Inclusive, Exclusive }; - static UITerminal* New( Font* font, const Float& fontSize, const Sizef& pixelsSize, const std::string& program = "", const std::vector& args = {}, const std::unordered_map& env = {}, const std::string& workingDir = "", const size_t& historySize = 10000, - IProcessFactory* processFactory = nullptr, - bool useFrameBuffer = false, + IProcessFactory* processFactory = nullptr, bool useFrameBuffer = false, bool keepAlive = true ); typedef std::function TerminalCommand; @@ -95,9 +92,9 @@ class UITerminal : public UIWidget { UIScrollBar* getVerticalScrollBar() const; - const ScrollViewType& getViewType() const; + const ScrollViewType& getScrollViewType() const; - void setViewType( const ScrollViewType& viewType ); + void setScrollViewType( const ScrollViewType& viewType ); virtual bool applyProperty( const StyleSheetProperty& attribute ); @@ -125,7 +122,7 @@ class UITerminal : public UIWidget { std::map mCommands; UIPopUpMenu* mCurrentMenu{ nullptr }; size_t mMenuIconSize{ 16 }; - ScrollViewType mViewType{ Inclusive }; + ScrollViewType mViewType{ ScrollViewType::Overlay }; ScrollBarMode mVScrollMode{ ScrollBarMode::Auto }; UIScrollBar* mVScroll{ nullptr }; int mScrollOffset; diff --git a/src/modules/eterm/src/eterm/ui/uiterminal.cpp b/src/modules/eterm/src/eterm/ui/uiterminal.cpp index 7ba9d1769..046e645c9 100644 --- a/src/modules/eterm/src/eterm/ui/uiterminal.cpp +++ b/src/modules/eterm/src/eterm/ui/uiterminal.cpp @@ -147,14 +147,14 @@ const ScrollBarMode& UITerminal::getVerticalScrollMode() const { return mVScrollMode; } -const UITerminal::ScrollViewType& UITerminal::getViewType() const { +const ScrollViewType& UITerminal::getScrollViewType() const { return mViewType; } -void UITerminal::setViewType( const ScrollViewType& viewType ) { +void UITerminal::setScrollViewType( const ScrollViewType& viewType ) { if ( viewType != mViewType ) { mViewType = viewType; - onContentSizeChange(); + onSizeChange(); } } @@ -171,7 +171,7 @@ void UITerminal::onPaddingChange() { mTerm->setPadding( { mPaddingPx.Left, mPaddingPx.Top, mPaddingPx.Right + - ( mViewType == Exclusive ? mVScroll->getPixelsSize().getWidth() : 0.f ), + ( mViewType == ScrollViewType::Outside ? mVScroll->getPixelsSize().getWidth() : 0.f ), mPaddingPx.Bottom } ); onContentSizeChange(); UIWidget::onPaddingChange(); @@ -235,7 +235,7 @@ std::string UITerminal::getPropertyString( const PropertyDefinition* propertyDef return mVScroll->getScrollBarType() == UIScrollBar::NoButtons ? "no-buttons" : "two-buttons"; case PropertyId::ScrollBarMode: - return getViewType() == Inclusive ? "inclusive" : "exclusive"; + return getScrollViewType() == ScrollViewType::Overlay ? "overlay" : "outside"; default: return UIWidget::getPropertyString( propertyDef, propertyIndex ); } @@ -274,10 +274,10 @@ bool UITerminal::applyProperty( const StyleSheetProperty& attribute ) { 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 ); + if ( "overlay" == val || "inclusive" == val || "inside" == val ) + setScrollViewType( ScrollViewType::Overlay ); + else if ( "outside" == val || "exclusive" == val || "outside" == val ) + setScrollViewType( ScrollViewType::Outside ); break; } case PropertyId::VScrollMode: { @@ -317,7 +317,11 @@ const std::shared_ptr& UITerminal::getTerm() const { void UITerminal::scheduledUpdate( const Time& ) { if ( !mTerm ) return; - mTerm->update( isMouseOverMeOrChildren() ); + + auto mousePos = getInput()->getRelativeMousePos(); + bool mouseOutsideBounds = + mousePos.y < 0 || mousePos.y > getUISceneNode()->getWindow()->getSize().getHeight(); + mTerm->update( isMouseOverMeOrChildren() && !mouseOutsideBounds ); if ( mTerm->isDirty() && isVisible() ) invalidateDraw(); @@ -326,7 +330,7 @@ void UITerminal::scheduledUpdate( const Time& ) { mVScroll->setVisible( !mTerm->getTerminal()->tisaltscr() ) ->setEnabled( !mTerm->getTerminal()->tisaltscr() ); } else if ( ScrollBarMode::Auto == mVScrollMode ) { - if ( mViewType == Inclusive && mMouseClock.getElapsedTime() > Seconds( 1 ) && + if ( mViewType == ScrollViewType::Overlay && mMouseClock.getElapsedTime() > Seconds( 1 ) && !mVScroll->isDragging() ) mVScroll->setVisible( false )->setEnabled( false ); } @@ -472,7 +476,7 @@ Uint32 UITerminal::onKeyUp( const KeyEvent& ) { } Uint32 UITerminal::onMouseMove( const Vector2i& position, const Uint32& flags ) { - if ( mViewType == Inclusive && ScrollBarMode::Auto == mVScrollMode ) { + if ( mViewType == ScrollViewType::Overlay && ScrollBarMode::Auto == mVScrollMode ) { mMouseClock.restart(); bool visible = !mTerm->getTerminal()->tisaltscr() && getContentSize() > getVisibleArea() && !mTerm->getTerminal()->hasSelection(); @@ -518,7 +522,7 @@ void UITerminal::onSizeChange() { mTerm->setPadding( { mPaddingPx.Left, mPaddingPx.Top, mPaddingPx.Right + - ( mViewType == Exclusive ? mVScroll->getPixelsSize().getWidth() : 0.f ), + ( mViewType == ScrollViewType::Outside ? mVScroll->getPixelsSize().getWidth() : 0.f ), mPaddingPx.Bottom } ); onContentSizeChange(); UIWidget::onSizeChange(); diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index 841a634d4..d756b95b2 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -232,6 +232,14 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath, term.warnBeforeClosingTab = ini.getValueB( "terminal", "warn_before_closing_tab", true ); term.cursorStyle = TerminalCursorHelper::modeFromString( ini.getValue( "terminal", "cursor_style", "steady_underline" ) ); + term.scrollBarType = ini.getValue( "terminal", "scrollbar_type", "overlay" ) == "overlay" + ? ScrollViewType::Overlay + : ScrollViewType::Outside; + auto scrollbarMode = ini.getValue( "terminal", "scrollbar_mode", "auto" ); + term.scrollBarMode = + scrollbarMode == "auto" + ? ScrollBarMode::Auto + : ( scrollbarMode == "on" ? ScrollBarMode::AlwaysOn : ScrollBarMode::AlwaysOff ); workspace.restoreLastSession = ini.getValueB( "workspace", "restore_last_session", false ); workspace.checkForUpdatesAtStartup = @@ -263,7 +271,7 @@ void AppConfig::save( const std::vector& recentFiles, EE::Window::Window* win, const std::string& colorSchemeName, const SearchBarConfig& searchBarConfig, const GlobalSearchBarConfig& globalSearchBarConfig, - PluginManager* pluginManager ) { + PluginManager* pluginManager, bool terminalMode ) { FileInfo configInfo( ini.path() ); if ( iniInfo.getModificationTime() != 0 && @@ -309,7 +317,8 @@ void AppConfig::save( const std::vector& recentFiles, ini.setValue( "editor", "font_size", editor.fontSize.toString() ); ini.setValue( "ui", "font_size", ui.fontSize.toString() ); ini.setValue( "ui", "panel_font_size", ui.panelFontSize.toString() ); - ini.setValueB( "ui", "show_side_panel", ui.showSidePanel ); + if ( !terminalMode ) + ini.setValueB( "ui", "show_side_panel", ui.showSidePanel ); ini.setValueB( "ui", "show_status_bar", ui.showStatusBar ); ini.setValueB( "ui", "show_menu_bar", ui.showMenuBar ); ini.setValueB( "ui", "welcome_screen", ui.welcomeScreen ); @@ -396,6 +405,12 @@ void AppConfig::save( const std::vector& recentFiles, ini.setValueB( "terminal", "warn_before_closing_tab", term.warnBeforeClosingTab ); ini.setValue( "terminal", "cursor_style", TerminalCursorHelper::modeToString( term.cursorStyle ) ); + ini.setValue( "terminal", "scrollbar_type", + term.scrollBarType == ScrollViewType::Overlay ? "overlay"sv : "outside"sv ); + ini.setValue( "terminal", "scrollbar_mode", + term.scrollBarMode == ScrollBarMode::Auto + ? "auto"sv + : ( term.scrollBarMode == ScrollBarMode::AlwaysOn ? "on"sv : "off" ) ); ini.setValueB( "window", "vsync", context.VSync ); ini.setValue( "window", "glversion", diff --git a/src/tools/ecode/appconfig.hpp b/src/tools/ecode/appconfig.hpp index 10c6e65fc..bb3826757 100644 --- a/src/tools/ecode/appconfig.hpp +++ b/src/tools/ecode/appconfig.hpp @@ -10,6 +10,7 @@ #include #include +#include #include @@ -21,6 +22,7 @@ using namespace EE::UI::Tools; using namespace EE::System; using namespace EE::Window; using namespace eterm::Terminal; +using namespace eterm::UI; namespace ecode { class App; @@ -184,6 +186,8 @@ struct TerminalConfig { bool closeTerminalTabOnExit{ false }; bool warnBeforeClosingTab{ true }; TerminalCursorMode cursorStyle{ TerminalCursorMode::SteadyUnderline }; + ScrollViewType scrollBarType{ ScrollViewType::Overlay }; + ScrollBarMode scrollBarMode{ ScrollBarMode::Auto }; }; struct WorkspaceConfig { @@ -243,7 +247,8 @@ class AppConfig { const std::vector& recentFolders, const std::string& panelPartition, const std::string& statusBarPartition, EE::Window::Window* win, const std::string& colorSchemeName, const SearchBarConfig& searchBarConfig, - const GlobalSearchBarConfig& globalSearchBarConfig, PluginManager* pluginManager ); + const GlobalSearchBarConfig& globalSearchBarConfig, PluginManager* pluginManager, + bool terminalMode ); void saveProject( std::string projectFolder, UICodeEditorSplitter* editorSplitter, const std::string& configPath, const ProjectDocumentConfig& docConfig, diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index c36d515dd..d76ad1779 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -790,7 +790,8 @@ void App::saveConfig() { mMainSplitter ? mMainSplitter->getSplitPartition().toString() : "85%", mWindow, mSplitter ? mSplitter->getCurrentColorSchemeName() : mConfig.editor.colorScheme, mDocSearchController->getSearchBarConfig(), - mGlobalSearchController->getGlobalSearchBarConfig(), mPluginManager.get() ); + mGlobalSearchController->getGlobalSearchBarConfig(), mPluginManager.get(), + mTerminalMode ); } std::string App::getKeybind( const std::string& command ) { @@ -2831,6 +2832,17 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { editor->showLinesRelativePosition( config.linesRelativePosition ); mPluginManager->onNewEditor( editor ); + + if ( mTerminalMode && mTerminalModeSidePanelWasVisible && + mSplitter->getTabWidgets().size() == 1 && + ( mSplitter->getTabWidgets()[0]->getTabCount() == 0 || + ( mSplitter->getTabWidgets()[0]->getTabCount() == 1 && mSplitter->getCurEditor() && + mSplitter->getCurEditor()->getDocument().isUntitledEmpty() ) ) ) { + showSidePanel( true ); + mConfig.ui.showSidePanel = true; + if ( mSettings ) + getSettingsMenu()->updateViewMenu(); + } } void App::loadCurrentDirectory() { @@ -3239,7 +3251,7 @@ void App::initProjectTreeViewUI() { mProjectTreeView->setHeadersVisible( false ); mProjectTreeView->setExpandersAsIcons( true ); mProjectTreeView->setSingleClickNavigation( mConfig.editor.singleClickNavigation ); - mProjectTreeView->setScrollViewType( UIScrollableWidget::Inclusive ); + mProjectTreeView->setScrollViewType( ScrollViewType::Overlay ); mProjectTreeView->on( Event::OnModelEvent, [this]( const Event* event ) { const ModelEvent* modelEvent = static_cast( event ); ModelEventType type = modelEvent->getModelEventType(); @@ -4423,8 +4435,13 @@ void App::init( InitParameters& params ) { #endif if ( params.terminal && params.file.empty() && params.fileToOpen.empty() ) { + mTerminalMode = true; + mTerminalModeSidePanelWasVisible = mConfig.ui.showSidePanel; + mConfig.ui.showSidePanel = false; showSidePanel( false ); showStatusBar( false ); + if ( mSettings ) + getSettingsMenu()->updateViewMenu(); initProjectViewEmptyCont(); mTerminalManager->createNewTerminal(); } else { diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index d3877c3b9..71cbc0507 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -678,6 +678,8 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider { std::condition_variable mAsyncResourcesLoadCond; std::vector mColorSchemes; bool mAsyncResourcesLoaded{ false }; + bool mTerminalMode{ false }; + bool mTerminalModeSidePanelWasVisible{ false }; std::string mProfilePath; void sortSidePanel(); diff --git a/src/tools/ecode/plugins/git/gitplugin.cpp b/src/tools/ecode/plugins/git/gitplugin.cpp index f996dd452..da1b15e1b 100644 --- a/src/tools/ecode/plugins/git/gitplugin.cpp +++ b/src/tools/ecode/plugins/git/gitplugin.cpp @@ -1511,7 +1511,7 @@ void GitPlugin::buildSidePanelTab() { mBranchesTree->setHeadersVisible( false ); mBranchesTree->setExpandersAsIcons( true ); mBranchesTree->setIndentWidth( PixelDensity::dpToPx( 16 ) ); - mBranchesTree->setScrollViewType( UIScrollableWidget::Inclusive ); + mBranchesTree->setScrollViewType( ScrollViewType::Overlay ); mBranchesTree->on( Event::OnModelEvent, [this]( const Event* event ) { const ModelEvent* modelEvent = static_cast( event ); if ( !modelEvent->getModelIndex().hasParent() ) @@ -1577,7 +1577,7 @@ void GitPlugin::buildSidePanelTab() { mStatusTree->setAutoColumnsWidth( true ); mStatusTree->setHeadersVisible( false ); mStatusTree->setExpandersAsIcons( true ); - mStatusTree->setScrollViewType( UIScrollableWidget::Inclusive ); + mStatusTree->setScrollViewType( ScrollViewType::Overlay ); mStatusTree->setIndentWidth( PixelDensity::dpToPx( 4 ) ); mStatusTree->on( Event::OnRowCreated, [this]( const Event* event ) { UITableRow* row = event->asRowCreatedEvent()->getRow(); diff --git a/src/tools/ecode/settingsmenu.cpp b/src/tools/ecode/settingsmenu.cpp index 871cb44ed..981034f77 100644 --- a/src/tools/ecode/settingsmenu.cpp +++ b/src/tools/ecode/settingsmenu.cpp @@ -1018,6 +1018,90 @@ UIMenu* SettingsMenu::createTerminalMenu() { } ); } ); + UIPopUpMenu* scrollBarTypeMenu = UIPopUpMenu::New(); + + const auto scrollBarTypeMenuRefresh = [this, scrollBarTypeMenu] { + const auto& cfg = mApp->getConfig(); + auto el = scrollBarTypeMenu->find( + "tscrolltype_" + + ( cfg.term.scrollBarType == ScrollViewType::Overlay ? "overlay"sv : "outside"sv ) ); + if ( el && el->isType( UI_TYPE_MENURADIOBUTTON ) ) + el->asType()->setActive( true ); + }; + + scrollBarTypeMenu->on( + Event::OnMenuShow, [this, scrollBarTypeMenu, scrollBarTypeMenuRefresh]( auto ) { + if ( scrollBarTypeMenu->getCount() == 0 ) { + scrollBarTypeMenu->addRadioButton( i18n( "overlay", "Overlay" ) ) + ->setTooltipText( + i18n( "scroll_overlay_tooltip", "Scrollbar appears over content." ) ) + ->setId( "tscrolltype_overlay" ); + scrollBarTypeMenu->addRadioButton( i18n( "outside", "Outside" ) ) + ->setTooltipText( i18n( "scroll_outside_tooltip", + "Scrollbar has its own space, never covers content." ) ) + ->setId( "tscrolltype_outside" ); + } + scrollBarTypeMenuRefresh(); + } ); + + scrollBarTypeMenu->on( Event::OnItemClicked, [this]( const Event* event ) { + const std::string& id( event->getNode()->getId() ); + std::string cursor = id.substr( 12 ); + mApp->getConfig().term.scrollBarType = + cursor == "overlay" ? ScrollViewType::Overlay : ScrollViewType::Outside; + mSplitter->forEachWidgetType( UI_TYPE_TERMINAL, [this]( UIWidget* widget ) { + widget->asType()->setScrollViewType( mApp->getConfig().term.scrollBarType ); + } ); + } ); + + mTerminalMenu->addSubMenu( i18n( "scrollbar_type", "ScrollBar Type" ), nullptr, + scrollBarTypeMenu ); + + UIPopUpMenu* scrollBarModeMenu = UIPopUpMenu::New(); + + const auto scrollBarModeMenuRefresh = [this, scrollBarModeMenu] { + const auto& cfg = mApp->getConfig(); + auto el = scrollBarModeMenu->find( + "tscrollmode_" + + ( cfg.term.scrollBarMode == ScrollBarMode::Auto + ? "auto"sv + : ( cfg.term.scrollBarMode == ScrollBarMode::AlwaysOn ? "on"sv : "off"sv ) ) ); + if ( el && el->isType( UI_TYPE_MENURADIOBUTTON ) ) + el->asType()->setActive( true ); + }; + + scrollBarModeMenu->on( + Event::OnMenuShow, [this, scrollBarModeMenu, scrollBarModeMenuRefresh]( auto ) { + if ( scrollBarModeMenu->getCount() == 0 ) { + scrollBarModeMenu->addRadioButton( i18n( "auto", "Auto" ) ) + ->setTooltipText( i18n( "scrollbar_mode_auto_tooltip", + "In overlay type Scrollbar will be visible only when " + "mouse moves over the terminal.\nIn outside type it " + "will be visible if there's any scrollable area." ) ) + ->setId( "tscrollmode_auto" ); + scrollBarModeMenu->addRadioButton( i18n( "always_visible", "Always Visible" ) ) + ->setId( "tscrollmode_on" ); + scrollBarModeMenu->addRadioButton( i18n( "always_hidden", "Always Hidden" ) ) + ->setId( "tscrollmode_off" ); + } + scrollBarModeMenuRefresh(); + } ); + + scrollBarModeMenu->on( Event::OnItemClicked, [this]( const Event* event ) { + const std::string& id( event->getNode()->getId() ); + std::string mode = id.substr( 12 ); + mApp->getConfig().term.scrollBarMode = + mode == "auto" ? ScrollBarMode::Auto + : ( mode == "on" ? ScrollBarMode::AlwaysOn : ScrollBarMode::AlwaysOff ); + mSplitter->forEachWidgetType( UI_TYPE_TERMINAL, [this]( UIWidget* widget ) { + widget->asType()->setVerticalScrollMode( + mApp->getConfig().term.scrollBarMode ); + } ); + } ); + + mTerminalMenu->addSubMenu( i18n( "scrollbar_mode", "ScrollBar Mode" ), nullptr, + scrollBarModeMenu ); + mTerminalMenu->addSeparator(); mTerminalMenu diff --git a/src/tools/ecode/terminalmanager.cpp b/src/tools/ecode/terminalmanager.cpp index f6fa621fd..1bc0c71ac 100644 --- a/src/tools/ecode/terminalmanager.cpp +++ b/src/tools/ecode/terminalmanager.cpp @@ -534,6 +534,8 @@ UITerminal* TerminalManager::createNewTerminal( } term->getTerm()->setCursorMode( mApp->termConfig().cursorStyle ); + term->setScrollViewType( mApp->termConfig().scrollBarType ); + term->setVerticalScrollMode( mApp->termConfig().scrollBarMode ); auto ret = mApp->getSplitter()->createWidgetInTabWidget( tabWidget, term, title.empty() ? mApp->i18n( "shell", "Shell" ).toUtf8() : title, true );