mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-14 13:15:14 +03:00
Improve context menu in tab widget.
This commit is contained in:
@@ -53,7 +53,21 @@ class EE_API UICodeEditorSplitter {
|
||||
|
||||
virtual ~UICodeEditorSplitter();
|
||||
|
||||
virtual bool tryTabClose( UIWidget* widget, UITabWidget::FocusTabBehavior focusTabBehavior );
|
||||
virtual bool tryTabClose( UIWidget* widget, UITabWidget::FocusTabBehavior focusTabBehavior,
|
||||
std::function<void()> onMsgBoxCloseCb = {} );
|
||||
|
||||
virtual bool tryCloseAllTabs( UIWidget* widget,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior );
|
||||
|
||||
virtual bool tryCloseOtherTabs( UIWidget* widget,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior );
|
||||
|
||||
virtual bool tryCloseCleanTabs( UIWidget* widget,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior );
|
||||
|
||||
virtual bool tryCloseTabsToDirection( UIWidget* widget,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior,
|
||||
bool toTheRight );
|
||||
|
||||
void closeTab( UIWidget* widget, UITabWidget::FocusTabBehavior focusTabBehavior );
|
||||
|
||||
@@ -223,6 +237,21 @@ class EE_API UICodeEditorSplitter {
|
||||
t.setCommand( "close-tab", [this] {
|
||||
tryTabClose( mCurWidget, UITabWidget::FocusTabBehavior::Default );
|
||||
} );
|
||||
t.setCommand( "close-other-tabs", [this] {
|
||||
tryCloseOtherTabs( mCurWidget, UITabWidget::FocusTabBehavior::Default );
|
||||
} );
|
||||
t.setCommand( "close-all-tabs", [this] {
|
||||
tryCloseAllTabs( mCurWidget, UITabWidget::FocusTabBehavior::Default );
|
||||
} );
|
||||
t.setCommand( "close-clean-tabs", [this] {
|
||||
tryCloseCleanTabs( mCurWidget, UITabWidget::FocusTabBehavior::Default );
|
||||
} );
|
||||
t.setCommand( "close-tabs-to-the-left", [this] {
|
||||
tryCloseTabsToDirection( mCurWidget, UITabWidget::FocusTabBehavior::Default, false );
|
||||
} );
|
||||
t.setCommand( "close-tabs-to-the-right", [this] {
|
||||
tryCloseTabsToDirection( mCurWidget, UITabWidget::FocusTabBehavior::Default, true );
|
||||
} );
|
||||
t.setCommand( "create-new", [this] {
|
||||
auto d = createCodeEditorInTabWidget( tabWidgetFromWidget( mCurWidget ) );
|
||||
if ( d.first != nullptr && d.second != nullptr ) {
|
||||
@@ -308,6 +337,10 @@ class EE_API UICodeEditorSplitter {
|
||||
|
||||
void setThreadPool( const std::shared_ptr<ThreadPool>& threadPool );
|
||||
|
||||
bool checkEditorExists( UICodeEditor* ) const;
|
||||
|
||||
bool checkWidgetExists( UIWidget* ) const;
|
||||
|
||||
protected:
|
||||
UISceneNode* mUISceneNode{ nullptr };
|
||||
std::shared_ptr<ThreadPool> mThreadPool;
|
||||
@@ -336,9 +369,9 @@ class EE_API UICodeEditorSplitter {
|
||||
const std::vector<SyntaxColorScheme>& colorSchemes,
|
||||
const std::string& initColorScheme );
|
||||
|
||||
bool checkEditorExists( UICodeEditor* ) const;
|
||||
|
||||
virtual void onTabClosed( const TabEvent* tabEvent );
|
||||
|
||||
void closeAllTabs( std::vector<UITab*> tabs, UITabWidget::FocusTabBehavior focusTabBehavior );
|
||||
};
|
||||
|
||||
}}} // namespace EE::UI::Tools
|
||||
|
||||
@@ -63,7 +63,12 @@ std::vector<std::string> UICodeEditorSplitter::getUnlockedCommands() {
|
||||
"switch-to-previous-split",
|
||||
"switch-to-next-split",
|
||||
"switch-to-previous-colorscheme",
|
||||
"switch-to-next-colorscheme" };
|
||||
"switch-to-next-colorscheme",
|
||||
"close-other-tabs",
|
||||
"close-all-tabs",
|
||||
"close-clean-tabs",
|
||||
"close-tabs-to-the-left",
|
||||
"close-tabs-to-the-right" };
|
||||
return unlockedCmds;
|
||||
}
|
||||
|
||||
@@ -920,7 +925,8 @@ void UICodeEditorSplitter::zoomReset() {
|
||||
}
|
||||
|
||||
bool UICodeEditorSplitter::tryTabClose( UIWidget* widget,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior ) {
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior,
|
||||
std::function<void()> onMsgBoxCloseCb ) {
|
||||
if ( !widget )
|
||||
return false;
|
||||
|
||||
@@ -932,17 +938,24 @@ bool UICodeEditorSplitter::tryTabClose( UIWidget* widget,
|
||||
return false;
|
||||
mTryCloseMsgBox = UIMessageBox::New(
|
||||
UIMessageBox::OK_CANCEL,
|
||||
widget->getUISceneNode()->getTranslatorString(
|
||||
"@string/confirm_close_tab",
|
||||
"Do you really want to close this tab?\nAll changes will be lost." ) );
|
||||
mTryCloseMsgBox->addEventListener( Event::OnConfirm, [&, editor]( const Event* ) {
|
||||
closeTab( editor, focusTabBehavior );
|
||||
} );
|
||||
mTryCloseMsgBox->addEventListener( Event::OnClose, [this]( const Event* ) {
|
||||
mTryCloseMsgBox = nullptr;
|
||||
if ( mCurEditor )
|
||||
mCurEditor->setFocus();
|
||||
} );
|
||||
String::format( widget->getUISceneNode()
|
||||
->i18n( "@string/confirm_close_tab",
|
||||
"Do you really want to close this tab?\nAll changes in "
|
||||
"\"%s\" will be lost." )
|
||||
.toUtf8(),
|
||||
editor->getDocument().getFilename() ) );
|
||||
mTryCloseMsgBox->addEventListener( Event::OnConfirm,
|
||||
[this, editor, focusTabBehavior]( const Event* ) {
|
||||
closeTab( editor, focusTabBehavior );
|
||||
} );
|
||||
mTryCloseMsgBox->addEventListener( Event::OnClose,
|
||||
[this, onMsgBoxCloseCb]( const Event* ) {
|
||||
mTryCloseMsgBox = nullptr;
|
||||
if ( mCurEditor )
|
||||
mCurEditor->setFocus();
|
||||
if ( onMsgBoxCloseCb )
|
||||
onMsgBoxCloseCb();
|
||||
} );
|
||||
mTryCloseMsgBox->setTitle( widget->getUISceneNode()->getTranslatorString(
|
||||
"@string/ask_close_tab", "Close Tab?" ) );
|
||||
mTryCloseMsgBox->center();
|
||||
@@ -958,6 +971,108 @@ bool UICodeEditorSplitter::tryTabClose( UIWidget* widget,
|
||||
}
|
||||
}
|
||||
|
||||
void UICodeEditorSplitter::closeAllTabs( std::vector<UITab*> tabs,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior ) {
|
||||
while ( !tabs.empty() ) {
|
||||
UITab* tab = tabs.back();
|
||||
if ( tab && !tryTabClose( tab->getOwnedWidget()->asType<UIWidget>(), focusTabBehavior,
|
||||
[this, tabs, focusTabBehavior]() mutable {
|
||||
tabs.pop_back();
|
||||
closeAllTabs( tabs, focusTabBehavior );
|
||||
} ) ) {
|
||||
return;
|
||||
} else {
|
||||
tabs.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool UICodeEditorSplitter::tryCloseAllTabs( UIWidget* widget,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior ) {
|
||||
UITabWidget* tabW = tabWidgetFromWidget( widget );
|
||||
if ( !tabW )
|
||||
return false;
|
||||
|
||||
size_t tabCount = tabW->getTabCount();
|
||||
std::vector<UITab*> tabs;
|
||||
for ( size_t i = 0; i < tabCount; i++ )
|
||||
tabs.push_back( tabW->getTab( i ) );
|
||||
|
||||
closeAllTabs( tabs, focusTabBehavior );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UICodeEditorSplitter::tryCloseOtherTabs( UIWidget* widget,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior ) {
|
||||
UITabWidget* tabW = tabWidgetFromWidget( widget );
|
||||
if ( !tabW )
|
||||
return false;
|
||||
|
||||
size_t tabCount = tabW->getTabCount();
|
||||
std::vector<UITab*> tabs;
|
||||
for ( size_t i = 0; i < tabCount; i++ ) {
|
||||
if ( tabW->getTab( i )->getOwnedWidget() != widget )
|
||||
tabs.push_back( tabW->getTab( i ) );
|
||||
}
|
||||
|
||||
closeAllTabs( tabs, focusTabBehavior );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UICodeEditorSplitter::tryCloseCleanTabs( UIWidget* widget,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior ) {
|
||||
UITabWidget* tabW = tabWidgetFromWidget( widget );
|
||||
if ( !tabW )
|
||||
return false;
|
||||
|
||||
size_t tabCount = tabW->getTabCount();
|
||||
std::vector<UITab*> tabs;
|
||||
for ( size_t i = 0; i < tabCount; i++ ) {
|
||||
UITab* tab = tabW->getTab( i );
|
||||
UIWidget* widget =
|
||||
tab->getOwnedWidget()->isWidget() ? tab->getOwnedWidget()->asType<UIWidget>() : nullptr;
|
||||
if ( widget && widget->isType( UI_TYPE_CODEEDITOR ) &&
|
||||
!widget->asType<UICodeEditor>()->isDirty() )
|
||||
tabs.push_back( tabW->getTab( i ) );
|
||||
}
|
||||
|
||||
closeAllTabs( tabs, focusTabBehavior );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UICodeEditorSplitter::tryCloseTabsToDirection( UIWidget* widget,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior,
|
||||
bool toTheRight ) {
|
||||
UITabWidget* tabW = tabWidgetFromWidget( widget );
|
||||
if ( !tabW )
|
||||
return false;
|
||||
|
||||
UITab* tab = tabW->getTabFromOwnedWidget( widget );
|
||||
if ( !tab )
|
||||
return false;
|
||||
size_t tabIndex = tabW->getTabIndex( tab );
|
||||
if ( tabIndex == eeINDEX_NOT_FOUND )
|
||||
return false;
|
||||
|
||||
size_t tabCount = tabW->getTabCount();
|
||||
std::vector<UITab*> tabs;
|
||||
|
||||
if ( toTheRight ) {
|
||||
for ( size_t i = tabIndex + 1; i < tabCount; i++ )
|
||||
tabs.push_back( tabW->getTab( i ) );
|
||||
} else {
|
||||
for ( size_t i = 0; i < tabIndex; i++ )
|
||||
tabs.push_back( tabW->getTab( i ) );
|
||||
}
|
||||
|
||||
closeAllTabs( tabs, focusTabBehavior );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UICodeEditorSplitter::closeTab( UIWidget* widget,
|
||||
UITabWidget::FocusTabBehavior focusTabBehavior ) {
|
||||
if ( widget ) {
|
||||
@@ -1158,6 +1273,18 @@ void UICodeEditorSplitter::closeTabWidgets( UISplitter* splitter ) {
|
||||
}
|
||||
}
|
||||
|
||||
bool UICodeEditorSplitter::checkWidgetExists( UIWidget* checkWidget ) const {
|
||||
bool found = false;
|
||||
forEachWidgetStoppable( [&]( UIWidget* widget ) {
|
||||
if ( widget == checkWidget ) {
|
||||
found = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
return found || checkWidget == nullptr;
|
||||
}
|
||||
|
||||
bool UICodeEditorSplitter::checkEditorExists( UICodeEditor* checkEditor ) const {
|
||||
bool found = false;
|
||||
forEachEditorStoppable( [&found, checkEditor]( UICodeEditor* editor ) {
|
||||
|
||||
@@ -1183,6 +1183,8 @@ Drawable* App::findIcon( const std::string& name ) {
|
||||
}
|
||||
|
||||
Drawable* App::findIcon( const std::string& name, const size_t iconSize ) {
|
||||
if ( name.empty() )
|
||||
return nullptr;
|
||||
UIIcon* icon = mUISceneNode->findIcon( name );
|
||||
if ( icon )
|
||||
return icon->getSize( iconSize );
|
||||
@@ -1659,39 +1661,72 @@ void App::onTabCreated( UITab* tab, UIWidget* ) {
|
||||
UITab* tab = event->getNode()->asType<UITab>();
|
||||
if ( !tab->getTabWidget() )
|
||||
return;
|
||||
menu->add( i18n( "editor_tab_menu_close_tab", "Close Tab" ) )->setId( "close-tab" );
|
||||
menu->add( i18n( "editor_tab_menu_close_other_tabs", "Close Other Tabs" ) )
|
||||
->setId( "close-other-tabs" );
|
||||
menu->add( i18n( "editor_tab_menu_close_all_tabs", "Close All Tabs" ) )
|
||||
->setId( "close-all-tabs" );
|
||||
const auto menuAdd = [menu, this]( const std::string& translateKey,
|
||||
const String& translateString, const std::string& icon,
|
||||
const std::string& cmd ) {
|
||||
UIMenuItem* menuItem = menu->add( i18n( translateKey, translateString ),
|
||||
findIcon( icon ), getKeybind( cmd ) );
|
||||
menuItem->setId( cmd );
|
||||
return menuItem;
|
||||
};
|
||||
|
||||
menuAdd( "editor_tab_menu_close_tab", "Close Tab", "document-close", "close-tab" );
|
||||
menuAdd( "editor_tab_menu_close_other_tabs", "Close Other Tabs", "", "close-other-tabs" );
|
||||
menuAdd( "editor_tab_menu_close_clean_tabs", "Close Clean Tabs", "", "close-clean-tabs" );
|
||||
menuAdd( "editor_tab_menu_close_all_tabs", "Close All Tabs", "", "close-all-tabs" );
|
||||
menuAdd( "editor_tab_menu_close_tabs_to_the_left", "Close Tabs To The Left", "",
|
||||
"close-tabs-to-the-left" );
|
||||
menuAdd( "editor_tab_menu_close_tabs_to_the_right", "Close Tabs To The Right", "",
|
||||
"close-tabs-to-the-right" );
|
||||
|
||||
if ( tab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
menu->addSeparator();
|
||||
|
||||
menuAdd( "split_left", "Split Left", "split-horizontal", "split-left" );
|
||||
menuAdd( "split_right", "Split Right", "split-horizontal", "split-right" );
|
||||
menuAdd( "split_top", "Split Top", "split-vertical", "split-top" );
|
||||
menuAdd( "split_bottom", "Split Bottom", "split-vertical", "split-bottom" );
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
menuAdd( "open_containing_folder", "Open Containing Folder...", "folder-open",
|
||||
"open-containing-folder" );
|
||||
|
||||
menuAdd( "copy_containing_folder_path", "Copy Containing Folder Path...", "copy",
|
||||
"copy-containing-folder-path" );
|
||||
|
||||
menuAdd( "copy_file_path", "Copy File Path", "copy", "copy-file-path" );
|
||||
|
||||
menuAdd( "copy_file_path_and_position", "Copy File Path and Position", "copy",
|
||||
"copy-file-path-and-position" );
|
||||
}
|
||||
|
||||
menu->addEventListener( Event::OnItemClicked, [tab, this]( const Event* event ) {
|
||||
if ( !event->getNode()->isType( UI_TYPE_MENUITEM ) )
|
||||
return;
|
||||
UIMenuItem* item = event->getNode()->asType<UIMenuItem>();
|
||||
UITabWidget* tabW = tab->getTabWidget();
|
||||
if ( "close-tab" == item->getId() ) {
|
||||
mSplitter->closeTab( tab->getOwnedWidget()->asType<UIWidget>(),
|
||||
UITabWidget::FocusTabBehavior::Closest );
|
||||
} else if ( "close-other-tabs" == item->getId() ) {
|
||||
size_t tabCount = tabW->getTabCount();
|
||||
std::vector<UITab*> tabs;
|
||||
for ( size_t i = 0; i < tabCount; i++ ) {
|
||||
if ( tabW->getTab( i ) != tab )
|
||||
tabs.push_back( tabW->getTab( i ) );
|
||||
}
|
||||
for ( auto* tab : tabs ) {
|
||||
mSplitter->closeTab( tab->getOwnedWidget()->asType<UIWidget>(),
|
||||
UITabWidget::FocusTabBehavior::Closest );
|
||||
}
|
||||
} else if ( "close-all-tabs" == item->getId() ) {
|
||||
size_t tabCount = tabW->getTabCount();
|
||||
std::vector<UITab*> tabs;
|
||||
for ( size_t i = 0; i < tabCount; i++ )
|
||||
tabs.push_back( tabW->getTab( i ) );
|
||||
for ( auto* tab : tabs ) {
|
||||
mSplitter->closeTab( tab->getOwnedWidget()->asType<UIWidget>(),
|
||||
UITabWidget::FocusTabBehavior::Closest );
|
||||
}
|
||||
UICodeEditor* nce = nullptr;
|
||||
UICodeEditor* ce = nullptr;
|
||||
UIWidget* ncw = nullptr;
|
||||
UIWidget* cw = nullptr;
|
||||
if ( tab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
nce = tab->getOwnedWidget()->asType<UICodeEditor>();
|
||||
ce = mSplitter->getCurEditor();
|
||||
if ( nce != ce )
|
||||
mSplitter->setCurrentEditor( nce );
|
||||
} else {
|
||||
ncw = tab->getOwnedWidget()->asType<UIWidget>();
|
||||
cw = mSplitter->getCurWidget();
|
||||
if ( ncw != cw )
|
||||
mSplitter->setCurrentWidget( ncw );
|
||||
}
|
||||
runCommand( item->getId() );
|
||||
if ( tab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
if ( nce != ce && mSplitter->checkEditorExists( ce ) )
|
||||
mSplitter->setCurrentEditor( ce );
|
||||
} else {
|
||||
if ( ncw != cw && mSplitter->checkWidgetExists( cw ) )
|
||||
mSplitter->setCurrentWidget( cw );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
Reference in New Issue
Block a user