mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-26 16:17:57 +03:00
UICodeEditorSplitter: several fixes and added some sanity checks for debug builds.
ecode: Some minor fixes.
This commit is contained in:
@@ -155,6 +155,8 @@ class EE_API SceneNode : public Node {
|
||||
|
||||
void addToCloseQueue( Node* node );
|
||||
|
||||
bool removeFromCloseQueue( Node* node );
|
||||
|
||||
void checkClose();
|
||||
|
||||
void createFrameBuffer();
|
||||
|
||||
@@ -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 );
|
||||
};
|
||||
|
||||
|
||||
@@ -948,6 +948,7 @@ void Node::forEachChild( std::function<void( Node* )> func ) {
|
||||
|
||||
void Node::onSceneChange() {
|
||||
mSceneNode = findSceneNode();
|
||||
eeASSERT( !mSceneNode->removeFromCloseQueue( this ) );
|
||||
|
||||
Node* child = mChild;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" )
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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" );
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user