UICodeEditorSplitter: several fixes and added some sanity checks for debug builds.

ecode: Some minor fixes.
This commit is contained in:
Martín Lucas Golini
2022-06-11 02:39:27 -03:00
parent 3b4fba4099
commit 6ffda35039
11 changed files with 127 additions and 34 deletions
+2
View File
@@ -155,6 +155,8 @@ class EE_API SceneNode : public Node {
void addToCloseQueue( Node* node );
bool removeFromCloseQueue( Node* node );
void checkClose();
void createFrameBuffer();
+11 -5
View File
@@ -101,11 +101,11 @@ class EE_API UICodeEditorSplitter {
void applyColorScheme( const SyntaxColorScheme& colorScheme );
void forEachEditor( std::function<void( UICodeEditor* )> run );
void forEachEditor( std::function<void( UICodeEditor* )> run ) const;
void forEachDoc( std::function<void( TextDocument& doc )> run );
void forEachDoc( std::function<void( TextDocument& doc )> run ) const;
void forEachTabWidget( std::function<void( UITabWidget* )> run );
void forEachTabWidget( std::function<void( UITabWidget* )> run ) const;
void zoomIn();
@@ -133,11 +133,11 @@ class EE_API UICodeEditorSplitter {
bool isAnyEditorDirty();
void forEachEditorStoppable( std::function<bool( UICodeEditor* )> run );
void forEachEditorStoppable( std::function<bool( UICodeEditor* )> run ) const;
std::vector<UICodeEditor*> getAllEditors();
void forEachDocStoppable( std::function<bool( TextDocument& )> run );
void forEachDocStoppable( std::function<bool( TextDocument& )> run ) const;
std::shared_ptr<TextDocument> findDocFromPath( const std::string& path );
@@ -158,11 +158,17 @@ class EE_API UICodeEditorSplitter {
Node* mBaseLayout{ nullptr };
Client* mClient;
bool mHideTabBarOnSingleTab{ true };
bool mFirstCodeEditor{ true };
UICodeEditor* mAboutToAddEditor{ nullptr };
UICodeEditorSplitter( UICodeEditorSplitter::Client* client, UISceneNode* sceneNode,
const std::vector<SyntaxColorScheme>& colorSchemes,
const std::string& initColorScheme );
bool curEditorExists() const;
bool checkEditorExists( UICodeEditor* ) const;
virtual void onTabClosed( const TabEvent* tabEvent );
};
+1
View File
@@ -948,6 +948,7 @@ void Node::forEachChild( std::function<void( Node* )> func ) {
void Node::onSceneChange() {
mSceneNode = findSceneNode();
eeASSERT( !mSceneNode->removeFromCloseQueue( this ) );
Node* child = mChild;
+9
View File
@@ -219,6 +219,15 @@ void SceneNode::addToCloseQueue( Node* node ) {
mCloseList.insert( node );
}
bool SceneNode::removeFromCloseQueue( Node* node ) {
auto it = mCloseList.find( node );
if ( it != mCloseList.end() ) {
mCloseList.erase( it );
return true;
}
return false;
}
void SceneNode::checkClose() {
if ( !mCloseList.empty() ) {
// First we need to create a temporal copy of the close list because it can change its
+1 -1
View File
@@ -205,7 +205,7 @@ SyntaxColorScheme::getEditorSyntaxStyle( const std::string& type ) const {
auto it = mEditorColors.find( type );
if ( it != mEditorColors.end() )
return it->second;
if ( type == "gutter_background" || "minimap_background" )
if ( type == "gutter_background" || type == "minimap_background" )
return getEditorSyntaxStyle( "background" );
else if ( type == "whitespace" || type == "line_break_column" || type == "matching_bracket" ||
type == "matching_selection" || type == "selection_region" )
+7 -6
View File
@@ -235,10 +235,10 @@ SyntaxDefinitionManager::SyntaxDefinitionManager() {
{ "normal", "keyword2", "function", "operator", "keyword" } },
{ { "([%w_][%w_]+)%.([%w_][%w%d_]*)%s*(=)%s*(async%s*function)" },
{ "normal", "keyword2", "function", "operator", "keyword" } },
{ { "([%w_][%w_]+)%.([%w_][%w%d_]*)%s*(=)%s*%b()%s*(=>)" },
{ "normal", "keyword2", "function", "operator", "operator" } },
{ { "([%w_][%w_]+)%.([%w_][%w%d_]*)%s*(=)%s*(async)%s*%b()%s*(=>)" },
{ "normal", "keyword2", "function", "operator", "function", "operator" } },
{ { "([%w_][%w_]+)%.([%w_][%w%d_]*)%s*(=)%s*%f[(]" },
{ "normal", "keyword2", "function", "operator" } },
{ { "([%w_][%w_]+)%.([%w_][%w%d_]*)%s*(=)%s*(async)%s*%f[(]" },
{ "normal", "keyword2", "function", "operator", "function" } },
{ { "[%a_][%w_]*%s*%f[(]" }, "function" },
{ { "[%a_][%w_]*" }, "symbol" },
},
@@ -1021,9 +1021,10 @@ SyntaxDefinitionManager::SyntaxDefinitionManager() {
add( { "Config File",
{ "%.ini$", "%.conf$", "%.desktop$", "%.service$", "%.cfg$", "%.env$", "%.properties$",
"Doxyfile" },
{ { { "^#.-\n" }, "comment" },
{ { { "%s?#%x%x%x%x%x%x%x%x" }, "string" },
{ { "%s?#%x%x%x%x%x%x" }, "string" },
{ { "^#.-\n" }, "comment" },
{ { "%s#.-\n" }, "comment" },
{ { "%s?#%x+" }, "string" },
{ { "[%a_][%w-+_%s%p]-%f[=]" }, "keyword" },
{ { "\"", "\"", "\\" }, "string" },
{ { "'", "'", "\\" }, "string" },
+78 -18
View File
@@ -263,9 +263,11 @@ UICodeEditor* UICodeEditorSplitter::createCodeEditor() {
"switch-to-next-split", "switch-to-previous-colorscheme",
"switch-to-next-colorscheme" } );
if ( nullptr == mCurEditor )
if ( nullptr == mCurEditor ) {
mAboutToAddEditor = editor;
setCurrentEditor( editor );
mAboutToAddEditor = nullptr;
}
mClient->onCodeEditorCreated( editor, doc );
return editor;
@@ -382,6 +384,7 @@ void UICodeEditorSplitter::loadAsyncFileFromPathInNewTab(
}
void UICodeEditorSplitter::setCurrentEditor( UICodeEditor* editor ) {
eeASSERT( checkEditorExists( editor ) );
bool isNew = mCurEditor != editor;
mCurEditor = editor;
if ( isNew )
@@ -392,9 +395,11 @@ void UICodeEditorSplitter::setCurrentEditor( UICodeEditor* editor ) {
std::pair<UITab*, UICodeEditor*>
UICodeEditorSplitter::createCodeEditorInTabWidget( UITabWidget* tabWidget ) {
eeASSERT( curEditorExists() );
if ( nullptr == tabWidget )
return std::make_pair( (UITab*)nullptr, (UICodeEditor*)nullptr );
UICodeEditor* editor = createCodeEditor();
mAboutToAddEditor = editor;
editor->addEventListener( Event::OnDocumentChanged, [&]( const Event* event ) {
mClient->onDocumentStateChanged( event->getNode()->asType<UICodeEditor>(),
event->getNode()->asType<UICodeEditor>()->getDocument() );
@@ -403,6 +408,8 @@ UICodeEditorSplitter::createCodeEditorInTabWidget( UITabWidget* tabWidget ) {
editor->setData( (UintPtr)tab );
DocEvent docEvent( editor, &editor->getDocument(), Event::OnEditorTabReady );
editor->sendEvent( static_cast<const Event*>( &docEvent ) );
mAboutToAddEditor = nullptr;
mFirstCodeEditor = false;
return std::make_pair( tab, editor );
}
@@ -418,6 +425,7 @@ void UICodeEditorSplitter::removeUnusedTab( UITabWidget* tabWidget ) {
}
UITabWidget* UICodeEditorSplitter::createEditorWithTabWidget( Node* parent, bool openCurEditor ) {
eeASSERT( curEditorExists() );
if ( nullptr == mBaseLayout )
mBaseLayout = parent;
UICodeEditor* prevCurEditor = mCurEditor;
@@ -441,10 +449,12 @@ UITabWidget* UICodeEditorSplitter::createEditorWithTabWidget( Node* parent, bool
onTabClosed( static_cast<const TabEvent*>( event ) );
} );
auto editorData = createCodeEditorInTabWidget( tabWidget );
mAboutToAddEditor = editorData.second;
// Open same document in the new split
if ( openCurEditor && prevCurEditor && prevCurEditor != editorData.second &&
!prevCurEditor->getDocument().isEmpty() )
editorData.second->setDocument( prevCurEditor->getDocumentRef() );
mAboutToAddEditor = nullptr;
mTabWidgets.push_back( tabWidget );
return tabWidget;
}
@@ -484,25 +494,26 @@ void UICodeEditorSplitter::applyColorScheme( const SyntaxColorScheme& colorSchem
mClient->onColorSchemeChanged( mCurrentColorScheme );
}
void UICodeEditorSplitter::forEachEditor( std::function<void( UICodeEditor* )> run ) {
void UICodeEditorSplitter::forEachEditor( std::function<void( UICodeEditor* )> run ) const {
for ( auto tabWidget : mTabWidgets )
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ )
run( tabWidget->getTab( i )->getOwnedWidget()->asType<UICodeEditor>() );
}
void UICodeEditorSplitter::forEachDoc( std::function<void( TextDocument& )> run ) {
void UICodeEditorSplitter::forEachDoc( std::function<void( TextDocument& )> run ) const {
std::unordered_set<TextDocument*> docs;
forEachEditor( [&]( UICodeEditor* editor ) { docs.insert( editor->getDocumentRef().get() ); } );
for ( auto doc : docs )
run( *doc );
}
void UICodeEditorSplitter::forEachTabWidget( std::function<void( UITabWidget* )> run ) {
void UICodeEditorSplitter::forEachTabWidget( std::function<void( UITabWidget* )> run ) const {
for ( auto widget : mTabWidgets )
run( widget );
}
void UICodeEditorSplitter::forEachEditorStoppable( std::function<bool( UICodeEditor* )> run ) {
void UICodeEditorSplitter::forEachEditorStoppable(
std::function<bool( UICodeEditor* )> run ) const {
for ( auto tabWidget : mTabWidgets ) {
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) {
if ( run( tabWidget->getTab( i )->getOwnedWidget()->asType<UICodeEditor>() ) ) {
@@ -512,7 +523,7 @@ void UICodeEditorSplitter::forEachEditorStoppable( std::function<bool( UICodeEdi
}
}
void UICodeEditorSplitter::forEachDocStoppable( std::function<bool( TextDocument& )> run ) {
void UICodeEditorSplitter::forEachDocStoppable( std::function<bool( TextDocument& )> run ) const {
for ( auto tabWidget : mTabWidgets ) {
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) {
if ( run( *tabWidget->getTab( i )
@@ -741,19 +752,40 @@ void UICodeEditorSplitter::focusSomeEditor( Node* searchFrom ) {
UICodeEditor* editor =
searchFrom ? searchFrom->findByType<UICodeEditor>( UI_TYPE_CODEEDITOR )
: mUISceneNode->getRoot()->findByType<UICodeEditor>( UI_TYPE_CODEEDITOR );
if ( searchFrom && !editor )
editor = mUISceneNode->getRoot()->findByType<UICodeEditor>( UI_TYPE_CODEEDITOR );
if ( editor && tabWidgetFromEditor( editor ) && !tabWidgetFromEditor( editor )->isClosing() ) {
if ( editor && tabWidgetFromEditor( editor ) && !tabWidgetFromEditor( editor )->isClosing() &&
tabWidgetFromEditor( editor )->getTabCount() > 1 ) {
UITabWidget* tabW = tabWidgetFromEditor( editor );
if ( tabW && tabW->getTabCount() > 0 ) {
tabW->setTabSelected( tabW->getTabSelected() );
}
} else {
UITabWidget* tabW = mUISceneNode->getRoot()->findByType<UITabWidget>( UI_TYPE_TABWIDGET );
if ( tabW && tabW->getTabCount() > 0 ) {
if ( tabW && tabW->getTabSelected()->getOwnedWidget() != editor ) {
tabW->setTabSelected( tabW->getTabSelected() );
return;
} else if ( tabW ) {
for ( size_t i = 0; i < tabW->getTabCount(); ++i ) {
if ( tabW->getTab( i )->getOwnedWidget() != editor ) {
tabW->setTabSelected( i );
return;
}
}
}
}
for ( auto widget : mTabWidgets ) {
if ( !widget->isClosing() && widget->getTabCount() > 0 ) {
if ( widget->getTabSelected() != nullptr ) {
widget->setTabSelected( widget->getTabSelected() );
} else {
widget->setTabSelected( (Uint32)0 );
}
return;
}
}
UITabWidget* tabW = mUISceneNode->getRoot()->findByType<UITabWidget>( UI_TYPE_TABWIDGET );
if ( tabW && tabW->getTabCount() > 0 )
tabW->setTabSelected( tabW->getTabSelected() );
}
void UICodeEditorSplitter::closeTabWidgets( UISplitter* splitter ) {
@@ -772,7 +804,32 @@ void UICodeEditorSplitter::closeTabWidgets( UISplitter* splitter ) {
}
}
bool UICodeEditorSplitter::checkEditorExists( UICodeEditor* checkEditor ) const {
bool found = false;
forEachEditorStoppable( [&found, checkEditor]( UICodeEditor* editor ) {
if ( editor == checkEditor ) {
found = true;
return true;
}
return false;
} );
return found || checkEditor == nullptr || mAboutToAddEditor == checkEditor || mFirstCodeEditor;
}
bool UICodeEditorSplitter::curEditorExists() const {
bool found = false;
forEachEditorStoppable( [&]( UICodeEditor* editor ) {
if ( editor == mCurEditor ) {
found = true;
return true;
}
return false;
} );
return found || mCurEditor == nullptr || mAboutToAddEditor == mCurEditor || mFirstCodeEditor;
}
UICodeEditor* UICodeEditorSplitter::getCurEditor() const {
eeASSERT( curEditorExists() );
return mCurEditor;
}
@@ -798,7 +855,7 @@ void UICodeEditorSplitter::closeSplitter( UISplitter* splitter ) {
}
void UICodeEditorSplitter::onTabClosed( const TabEvent* tabEvent ) {
UICodeEditor* editor = mCurEditor;
UICodeEditor* editor = tabEvent->getTab()->getOwnedWidget()->asType<UICodeEditor>();
UITabWidget* tabWidget = tabEvent->getTab()->getTabWidget();
if ( tabWidget->getTabCount() == 0 ) {
UISplitter* splitter = splitterFromEditor( editor );
@@ -839,11 +896,13 @@ void UICodeEditorSplitter::onTabClosed( const TabEvent* tabEvent ) {
addRemainingTabWidgets( remainingNode );
focusSomeEditor( nullptr );
}
if ( tabEvent->getTab()->getOwnedWidget() == mCurEditor )
setCurrentEditor( nullptr );
eeASSERT( !mTabWidgets.empty() );
eeASSERT( !( mTabWidgets.size() == 1 && mTabWidgets[0]->getTabCount() == 0 ) );
return;
}
}
mCurEditor = nullptr;
auto d = createCodeEditorInTabWidget( tabWidget );
d.first->getTabWidget()->setTabSelected( d.first );
} else {
@@ -852,7 +911,8 @@ void UICodeEditorSplitter::onTabClosed( const TabEvent* tabEvent ) {
eemin( tabWidget->getTabCount() - 1, tabEvent->getTabIndex() ) );
}
if ( tabEvent->getTab()->getOwnedWidget() == mCurEditor )
setCurrentEditor( nullptr );
focusSomeEditor( nullptr );
eeASSERT( curEditorExists() );
}
}}} // namespace EE::UI::Tools
+4
View File
@@ -1205,6 +1205,10 @@ Uint32 UICodeEditor::onMouseOver( const Vector2i& position, const Uint32& flags
}
Uint32 UICodeEditor::onMouseLeave( const Vector2i& position, const Uint32& flags ) {
if ( mMinimapHover ) {
mMinimapHover = false;
invalidateDraw();
}
for ( auto& plugin : mPlugins )
if ( plugin->onMouseLeave( this, position, flags ) )
return UIWidget::onMouseLeave( position, flags );
+1 -1
View File
@@ -125,7 +125,7 @@ EE_MAIN_FUNC int main( int, char*[] ) {
// Create the Vertex Buffer, the vertex buffer stores the vertex data in the GPU, making the
// rendering much faster In the case that Vertex Buffer Object is not supported by the GPU,
// it will fallback to a inmediate-mode vertex buffer
// it will fallback to a immediate-mode vertex buffer
VBO = VertexBuffer::New( VERTEX_FLAGS_PRIMITIVE, PRIMITIVE_TRIANGLE_FAN );
VBO2 = VertexBuffer::New( VERTEX_FLAGS_PRIMITIVE, PRIMITIVE_TRIANGLE_FAN );
+3
View File
@@ -165,6 +165,9 @@ void DocSearchController::showFindView() {
mSearchState.wholeWord = mSearchBarLayout->find<UICheckBox>( "whole_word" )->isChecked();
mSearchState.escapeSequences =
mSearchBarLayout->find<UICheckBox>( "escape_sequence" )->isChecked();
mSearchState.type = mSearchBarLayout->find<UICheckBox>( "lua_pattern" )->isChecked()
? TextDocument::FindReplaceType::LuaPattern
: TextDocument::FindReplaceType::Normal;
mSearchBarLayout->setEnabled( true )->setVisible( true );
UITextInput* findInput = mSearchBarLayout->find<UITextInput>( "search_find" );
+10 -3
View File
@@ -1725,10 +1725,15 @@ std::vector<std::string> App::getUnlockedCommands() {
void App::closeEditors() {
mConfig.saveProject( mCurrentProject, mEditorSplitter, mConfigPath, mProjectDocConfig );
std::vector<UICodeEditor*> editors = mEditorSplitter->getAllEditors();
for ( auto editor : editors ) {
while ( !editors.empty() ) {
UICodeEditor* editor = editors[0];
UITabWidget* tabWidget = mEditorSplitter->tabWidgetFromEditor( editor );
tabWidget->removeTab( (UITab*)editor->getData(), true, true );
}
editors = mEditorSplitter->getAllEditors();
if ( editors.size() == 1 && editors[0]->getDocument().isEmpty() )
break;
};
mCurrentProject = "";
mDirTree = nullptr;
if ( mFileSystemListener )
@@ -1736,7 +1741,9 @@ void App::closeEditors() {
mProjectDocConfig = ProjectDocumentConfig( mConfig.doc );
updateProjectSettingsMenu();
mEditorSplitter->createCodeEditorInTabWidget( mEditorSplitter->getTabWidgets()[0] );
if ( !mEditorSplitter->getTabWidgets().empty() &&
mEditorSplitter->getTabWidgets()[0]->getTabCount() == 0 )
mEditorSplitter->createCodeEditorInTabWidget( mEditorSplitter->getTabWidgets()[0] );
}
void App::closeFolder() {