From 469ca05e9fb584a3b6d475f372ff3823f25ea835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Tue, 31 Dec 2024 19:01:32 -0300 Subject: [PATCH] Refactor how App is exposed. Expose more functionality to the Plugins. --- projects/linux/ee.files | 1 + src/tools/ecode/ecode.cpp | 4 +- src/tools/ecode/ecode.hpp | 3 +- .../debugger/debuggerclientlistener.cpp | 20 ++- .../ecode/plugins/debugger/debuggerplugin.cpp | 5 +- .../ecode/plugins/plugincontextprovider.hpp | 120 ++++++++++++++++++ src/tools/ecode/plugins/pluginmanager.cpp | 6 +- src/tools/ecode/plugins/pluginmanager.hpp | 7 +- src/tools/ecode/statusappoutputcontroller.cpp | 114 +++++++++-------- src/tools/ecode/statusappoutputcontroller.hpp | 13 +- .../ecode/statusbuildoutputcontroller.cpp | 113 +++++++++-------- .../ecode/statusbuildoutputcontroller.hpp | 10 +- src/tools/ecode/statusterminalcontroller.cpp | 50 ++++---- src/tools/ecode/statusterminalcontroller.hpp | 2 + src/tools/ecode/uistatusbar.cpp | 84 +++++++++--- src/tools/ecode/uistatusbar.hpp | 23 +++- 16 files changed, 395 insertions(+), 180 deletions(-) create mode 100644 src/tools/ecode/plugins/plugincontextprovider.hpp diff --git a/projects/linux/ee.files b/projects/linux/ee.files index d418d369c..54a63dd7e 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -1621,6 +1621,7 @@ ../../src/tools/ecode/plugins/lsp/lspprotocol.hpp ../../src/tools/ecode/plugins/plugin.cpp ../../src/tools/ecode/plugins/plugin.hpp +../../src/tools/ecode/plugins/plugincontextprovider.hpp ../../src/tools/ecode/plugins/pluginmanager.cpp ../../src/tools/ecode/plugins/pluginmanager.hpp ../../src/tools/ecode/plugins/xmltools/xmltoolsplugin.cpp diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 950792f74..4bcdf29dd 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -564,7 +564,7 @@ void App::initPluginManager() { cb( tab->getOwnedWidget()->asType(), path ); } }, - [this] { return getProjectBuildManager(); } ); + this ); mPluginManager->onPluginEnabled = [this]( Plugin* plugin ) { if ( nullptr == mUISceneNode || plugin->isReady() ) { onPluginEnabled( plugin ); @@ -3829,7 +3829,7 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe initImageView(); - mStatusBar->setApp( this ); + mStatusBar->setPluginContextProvider( this ); mSettings = std::make_unique(); mSettings->createSettingsMenu( this, mMenuBar ); diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index 7a59efb11..6d78dbf68 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -7,6 +7,7 @@ #include "filesystemlistener.hpp" #include "globalsearchcontroller.hpp" #include "notificationcenter.hpp" +#include "plugins/plugincontextprovider.hpp" #include "plugins/pluginmanager.hpp" #include "projectbuild.hpp" #include "projectdirectorytree.hpp" @@ -35,7 +36,7 @@ class LinterPlugin; class FormatterPlugin; class SettingsMenu; -class App : public UICodeEditorSplitter::Client { +class App : public UICodeEditorSplitter::Client, public PluginContextProvider { public: explicit App( const size_t& jobs = 0, const std::vector& args = {} ); diff --git a/src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp b/src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp index a463d51e9..70fffa4c2 100644 --- a/src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp +++ b/src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp @@ -1,4 +1,5 @@ #include "debuggerclientlistener.hpp" +#include "../../statusappoutputcontroller.hpp" #include "debuggerplugin.hpp" namespace ecode { @@ -8,7 +9,16 @@ DebuggerClientListener::DebuggerClientListener( DebuggerClient* client, Debugger eeASSERT( mClient && mPlugin ); } -void DebuggerClientListener::stateChanged( DebuggerClient::State ) {} +void DebuggerClientListener::stateChanged( DebuggerClient::State state ) { + if ( state == DebuggerClient::State::Initializing ) { + mPlugin->getManager()->getUISceneNode()->runOnMainThread( [this] { + mPlugin->getManager() + ->getPluginContext() + ->getStatusAppOutputController() + ->initNewOutput( {} ); + } ); + } +} void DebuggerClientListener::initialized() { // mClient->setBreakpoints( "/home/programming/eepp/src/tools/ecode/ecode.cpp", @@ -40,7 +50,13 @@ void DebuggerClientListener::debuggeeStopped( const StoppedEvent& event ) { void DebuggerClientListener::debuggeeContinued( const ContinuedEvent& ) {} -void DebuggerClientListener::outputProduced( const Output& ) {} +void DebuggerClientListener::outputProduced( const Output& output ) { + if ( Output::Category::Stdout == output.category || + Output::Category::Stderr == output.category ) { + mPlugin->getManager()->getPluginContext()->getStatusAppOutputController()->insertBuffer( + output.output ); + } +} void DebuggerClientListener::debuggingProcess( const ProcessInfo& ) {} diff --git a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp index a6231019e..6563c9c86 100644 --- a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp +++ b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp @@ -1,7 +1,7 @@ -#include "debuggerplugin.hpp" #include "../../projectbuild.hpp" #include "busprocess.hpp" #include "dap/debuggerclientdap.hpp" +#include "debuggerplugin.hpp" #include #include #include @@ -303,7 +303,8 @@ void DebuggerPlugin::replaceKeysInJson( nlohmann::json& json ) { static constexpr auto KEY_CWD = "${cwd}"; static constexpr auto KEY_ENV = "${env}"; static constexpr auto KEY_STOPONENTRY = "${stopOnEntry}"; - auto runConfig = getManager()->getProjectBuildManager()->getCurrentRunConfig(); + auto runConfig = + getManager()->getPluginContext()->getProjectBuildManager()->getCurrentRunConfig(); for ( auto& j : json ) { if ( j.is_object() ) { diff --git a/src/tools/ecode/plugins/plugincontextprovider.hpp b/src/tools/ecode/plugins/plugincontextprovider.hpp new file mode 100644 index 000000000..d16763e63 --- /dev/null +++ b/src/tools/ecode/plugins/plugincontextprovider.hpp @@ -0,0 +1,120 @@ +#pragma once + +#include +#include + +namespace EE { + +namespace Window { +class Window; +} + +namespace Graphics { +class Drawable; +class Font; +} // namespace Graphics + +namespace UI { + +class UISplitter; +class UITabWidget; +class UISceneNode; +class UICodeEditor; + +namespace Tools { +class UICodeEditorSplitter; +} + +} // namespace UI + +} // namespace EE + +using namespace EE; +using namespace EE::Graphics; +using namespace EE::UI; +using namespace EE::UI::Tools; + +namespace ecode { + +class UIStatusBar; +class TerminalManager; +class UniversalLocator; +class GlobalSearchController; +class StatusTerminalController; +class StatusBuildOutputController; +class StatusAppOutputController; +class ProjectBuildManager; +class NotificationCenter; +class ProjectDirectoryTree; +class TerminalConfig; + +class PluginContextProvider { + public: + + virtual UIStatusBar* getStatusBar() const = 0; + + virtual UISplitter* getMainSplitter() const = 0; + + virtual void hideGlobalSearchBar() = 0; + + virtual void hideSearchBar() = 0; + + virtual void hideLocateBar() = 0; + + virtual std::string getKeybind( const std::string& command ) = 0; + + virtual UniversalLocator* getUniversalLocator() const = 0; + + virtual TerminalManager* getTerminalManager() const = 0; + + virtual UICodeEditorSplitter* getSplitter() const = 0; + + virtual GlobalSearchController* getGlobalSearchController() const = 0; + + virtual StatusTerminalController* getStatusTerminalController() const = 0; + + virtual StatusBuildOutputController* getStatusBuildOutputController() const = 0; + + virtual StatusAppOutputController* getStatusAppOutputController() const = 0; + + virtual ProjectBuildManager* getProjectBuildManager() const = 0; + + virtual UITabWidget* getSidePanel() const = 0; + + virtual String i18n( const std::string& key, const String& def ) = 0; + + virtual const std::string& getWindowTitle() const = 0; + + virtual EE::Window::Window* getWindow() const = 0; + + virtual UISceneNode* getUISceneNode() const = 0; + + virtual NotificationCenter* getNotificationCenter() const = 0; + + virtual bool + loadFileFromPath( std::string path, bool inNewTab = true, UICodeEditor* codeEditor = nullptr, + std::function onLoaded = + std::function() ) = 0; + + virtual ProjectDirectoryTree* getDirTree() const = 0; + + virtual Drawable* findIcon( const std::string& name ) = 0; + + virtual Drawable* findIcon( const std::string& name, const size_t iconSize ) = 0; + + virtual TerminalConfig& termConfig() = 0; + + virtual Font* getTerminalFont() const = 0; + + virtual Font* getFontMono() const = 0; + + virtual Font* getFallbackFont() const = 0; + + virtual const Float& getDisplayDPI() const = 0; + + virtual const std::string& getCurrentProject() const = 0; + + virtual std::string getCurrentWorkingDir() const = 0; +}; + +} // namespace ecode diff --git a/src/tools/ecode/plugins/pluginmanager.cpp b/src/tools/ecode/plugins/pluginmanager.cpp index 5564bbf96..9f4563796 100644 --- a/src/tools/ecode/plugins/pluginmanager.cpp +++ b/src/tools/ecode/plugins/pluginmanager.cpp @@ -12,12 +12,12 @@ namespace ecode { PluginManager::PluginManager( const std::string& resourcesPath, const std::string& pluginsPath, std::shared_ptr pool, const OnLoadFileCb& loadFileCb, - const std::function& getPBM ) : + PluginContextProvider* context ) : mResourcesPath( resourcesPath ), mPluginsPath( pluginsPath ), mThreadPool( pool ), - mLoadFileFn( loadFileCb ), - mProjectBuildManagerFn( getPBM ) {} + mPluginContext( context ), + mLoadFileFn( loadFileCb ) {} PluginManager::~PluginManager() { mClosing = true; diff --git a/src/tools/ecode/plugins/pluginmanager.hpp b/src/tools/ecode/plugins/pluginmanager.hpp index fed271883..36b9f6e16 100644 --- a/src/tools/ecode/plugins/pluginmanager.hpp +++ b/src/tools/ecode/plugins/pluginmanager.hpp @@ -3,6 +3,7 @@ #include "../projectsearch.hpp" #include "lsp/lspprotocol.hpp" +#include "plugincontextprovider.hpp" #include #include #include @@ -275,7 +276,7 @@ class PluginManager { PluginManager( const std::string& resourcesPath, const std::string& pluginsPath, std::shared_ptr pool, const OnLoadFileCb& loadFileCb, - const std::function& getPBM ); + PluginContextProvider* context ); ~PluginManager(); @@ -362,7 +363,7 @@ class PluginManager { bool isClosing() const; - ProjectBuildManager* getProjectBuildManager() const { return mProjectBuildManagerFn(); }; + PluginContextProvider* getPluginContext() const { return mPluginContext; } protected: using SubscribedPlugins = @@ -378,6 +379,7 @@ class PluginManager { UICodeEditorSplitter* mSplitter{ nullptr }; UISplitter* mMainSplitter{ nullptr }; FileSystemListener* mFileSystemListener{ nullptr }; + PluginContextProvider* mPluginContext{ nullptr }; Mutex mSubscribedPluginsMutex; Mutex mPluginsFSSubsMutex; SubscribedPlugins mSubscribedPlugins; @@ -386,7 +388,6 @@ class PluginManager { UnorderedSet mPluginsFSSubs; bool mClosing{ false }; bool mPluginReloadEnabled{ false }; - std::function mProjectBuildManagerFn; bool hasDefinition( const std::string& id ); diff --git a/src/tools/ecode/statusappoutputcontroller.cpp b/src/tools/ecode/statusappoutputcontroller.cpp index 56faabd1b..bd0ca50be 100644 --- a/src/tools/ecode/statusappoutputcontroller.cpp +++ b/src/tools/ecode/statusappoutputcontroller.cpp @@ -1,5 +1,7 @@ #include "statusappoutputcontroller.hpp" -#include "ecode.hpp" +#include "notificationcenter.hpp" +#include "plugins/plugincontextprovider.hpp" +#include namespace ecode { @@ -16,29 +18,20 @@ static std::string getProjectOutputParserTypeToString( const ProjectOutputParser } StatusAppOutputController::StatusAppOutputController( UISplitter* mainSplitter, - UISceneNode* uiSceneNode, App* app ) : - StatusBarElement( mainSplitter, uiSceneNode, app ) {} + UISceneNode* uiSceneNode, + PluginContextProvider* pluginContext ) : + StatusBarElement( mainSplitter, uiSceneNode, pluginContext ) {} -static void safeInsertBuffer( TextDocument& doc, const std::string& buffer ) { - doc.insert( 0, doc.endOfDoc(), buffer ); -} - -UIPushButton* StatusAppOutputController::getRunButton( App* app ) { - if ( app->getSidePanel() ) { - UIWidget* tab = app->getSidePanel()->find( "build_tab_view" ); +UIPushButton* StatusAppOutputController::getRunButton() { + if ( mContext->getSidePanel() ) { + UIWidget* tab = mContext->getSidePanel()->find( "build_tab_view" ); if ( tab ) return tab->find( "run_button" ); } return nullptr; } -void StatusAppOutputController::run( const ProjectBuildCommand& runData, - const ProjectBuildOutputParser& outputParser ) { - if ( nullptr == mApp->getProjectBuildManager() ) - return; - - auto pbm = mApp->getProjectBuildManager(); - +void StatusAppOutputController::initNewOutput( const ProjectBuildOutputParser& outputParser ) { show(); mAppOutput->getDocument().reset(); mAppOutput->invalidateLongestLineWidth(); @@ -73,55 +66,53 @@ void StatusAppOutputController::run( const ProjectBuildCommand& runData, mAppOutput->setLineWrapMode( LineWrapMode::Word ); mScrollLocked = true; - UIPushButton* runButton = getRunButton( mApp ); + UIPushButton* runButton = getRunButton(); if ( runButton ) - runButton->setText( mApp->i18n( "cancel_run", "Cancel Run" ) ); + runButton->setText( mContext->i18n( "cancel_run", "Cancel Run" ) ); mRunButton->setEnabled( false ); mStopButton->setEnabled( true ); +} - const auto updateRunButton = [this]() { - UIPushButton* runButton = getRunButton( mApp ); - if ( runButton ) { - runButton->runOnMainThread( - [this, runButton] { runButton->setText( mApp->i18n( "run", "Run" ) ); } ); - } - mRunButton->setEnabled( true ); - mStopButton->setEnabled( false ); - }; +void StatusAppOutputController::insertBuffer( const std::string& buffer ) { + if ( mAppOutput == nullptr ) + return; + mAppOutput->runOnMainThread( [this, buffer]() { + mAppOutput->getDocument().insert( 0, mAppOutput->getDocument().endOfDoc(), buffer ); + if ( mScrollLocked ) + mAppOutput->setScrollY( mAppOutput->getMaxScroll().y ); + } ); +} - auto res = pbm->run( - runData, [this]( const auto& key, const auto& def ) { return mApp->i18n( key, def ); }, - [this]( auto, std::string buffer, const ProjectBuildCommand* ) { - mAppOutput->runOnMainThread( [this, buffer]() { - safeInsertBuffer( mAppOutput->getDocument(), buffer ); - if ( mScrollLocked ) - mAppOutput->setScrollY( mAppOutput->getMaxScroll().y ); - } ); - }, - [this, updateRunButton]( auto exitCode, const ProjectBuildCommand* ) { +void StatusAppOutputController::run( const ProjectBuildCommand& runData, + const ProjectBuildOutputParser& outputParser ) { + if ( nullptr == mContext->getProjectBuildManager() ) + return; + + initNewOutput( outputParser ); + + auto res = mContext->getProjectBuildManager()->run( + runData, [this]( const auto& key, const auto& def ) { return mContext->i18n( key, def ); }, + [this]( auto, std::string buffer, const ProjectBuildCommand* ) { insertBuffer( buffer ); }, + [this]( auto exitCode, const ProjectBuildCommand* ) { String buffer; if ( EXIT_SUCCESS == exitCode ) { buffer = Sys::getDateTimeStr() + ": " + - mApp->i18n( "run_successful", "Run successfully\n" ); + mContext->i18n( "run_successful", "Run successfully\n" ); } else { - buffer = - Sys::getDateTimeStr() + ": " + mApp->i18n( "run_failed", "Run with errors\n" ); + buffer = Sys::getDateTimeStr() + ": " + + mContext->i18n( "run_failed", "Run with errors\n" ); } - mAppOutput->runOnMainThread( [this, buffer]() { - safeInsertBuffer( mAppOutput->getDocument(), buffer ); - if ( mScrollLocked ) - mAppOutput->setScrollY( mAppOutput->getMaxScroll().y ); - } ); + insertBuffer( buffer ); updateRunButton(); } ); if ( !res.isValid() ) { - mApp->getNotificationCenter()->addNotification( res.errorMsg ); + mContext->getNotificationCenter()->addNotification( res.errorMsg ); updateRunButton(); } @@ -164,7 +155,7 @@ void StatusAppOutputController::createContainer() { mMainSplitter->getLastWidget()->setParent( mUISceneNode ); } - mContainer = mApp->getUISceneNode() + mContainer = mContext->getUISceneNode() ->loadLayoutFromString( XML, mMainSplitter ) ->asType(); auto editor = mContainer->find( "app_output_output" ); @@ -192,18 +183,19 @@ void StatusAppOutputController::createContainer() { } ); mRunButton->onClick( [this]( auto ) { - auto pbm = mApp->getProjectBuildManager(); + auto pbm = mContext->getProjectBuildManager(); if ( nullptr == pbm ) return; if ( !pbm->hasRunConfig() ) { - UIMessageBox::New( UIMessageBox::OK, - mApp->i18n( "must_configure_build_and_run_config", - "You must first add a build and run configuration" ) ) + UIMessageBox::New( + UIMessageBox::OK, + mContext->i18n( "must_configure_build_and_run_config", + "You must first add a build and run configuration" ) ) ->setCloseShortcut( { KEY_ESCAPE } ) - ->setTitle( mApp->getWindowTitle() ) + ->setTitle( mContext->getWindowTitle() ) ->showWhenReady() ->on( Event::OnConfirm, [this]( auto ) { - auto pbm = mApp->getProjectBuildManager(); + auto pbm = mContext->getProjectBuildManager(); if ( nullptr != pbm ) pbm->selectTab(); } ); @@ -213,7 +205,7 @@ void StatusAppOutputController::createContainer() { } ); mStopButton->onClick( [this]( auto ) { - auto pbm = mApp->getProjectBuildManager(); + auto pbm = mContext->getProjectBuildManager(); if ( nullptr == pbm ) return; pbm->cancelRun(); @@ -229,7 +221,7 @@ void StatusAppOutputController::createContainer() { } ); mConfigureButton->onClick( [this]( auto ) { - auto pbm = mApp->getProjectBuildManager(); + auto pbm = mContext->getProjectBuildManager(); if ( nullptr == pbm ) return; pbm->editCurrentBuild(); @@ -237,4 +229,14 @@ void StatusAppOutputController::createContainer() { } ); } +void StatusAppOutputController::updateRunButton() { + UIPushButton* runButton = getRunButton(); + if ( runButton ) { + runButton->runOnMainThread( + [this, runButton] { runButton->setText( mContext->i18n( "run", "Run" ) ); } ); + } + mRunButton->setEnabled( true ); + mStopButton->setEnabled( false ); +} + } // namespace ecode diff --git a/src/tools/ecode/statusappoutputcontroller.hpp b/src/tools/ecode/statusappoutputcontroller.hpp index d9f3ed5b3..6f1c290f2 100644 --- a/src/tools/ecode/statusappoutputcontroller.hpp +++ b/src/tools/ecode/statusappoutputcontroller.hpp @@ -22,19 +22,26 @@ class App; class StatusAppOutputController : public StatusBarElement { public: - StatusAppOutputController( UISplitter* mainSplitter, UISceneNode* uiSceneNode, App* app ); + StatusAppOutputController( UISplitter* mainSplitter, UISceneNode* uiSceneNode, + PluginContextProvider* pluginContext ); - virtual ~StatusAppOutputController(){}; + virtual ~StatusAppOutputController() {}; + + void initNewOutput( const ProjectBuildOutputParser& outputParser ); void run( const ProjectBuildCommand& runData, const ProjectBuildOutputParser& outputParser ); + void insertBuffer( const std::string& buffer ); + UIWidget* getWidget(); UIWidget* createWidget(); UICodeEditor* getContainer(); - UIPushButton* getRunButton( App* app ); + UIPushButton* getRunButton(); + + void updateRunButton(); protected: UILinearLayout* mContainer{ nullptr }; diff --git a/src/tools/ecode/statusbuildoutputcontroller.cpp b/src/tools/ecode/statusbuildoutputcontroller.cpp index 5c79ba5e1..291ab7922 100644 --- a/src/tools/ecode/statusbuildoutputcontroller.cpp +++ b/src/tools/ecode/statusbuildoutputcontroller.cpp @@ -1,12 +1,16 @@ +#include "notificationcenter.hpp" +#include "plugins/plugincontextprovider.hpp" +#include "projectdirectorytree.hpp" #include "statusbuildoutputcontroller.hpp" -#include "ecode.hpp" #include "widgetcommandexecuter.hpp" +#include namespace ecode { StatusBuildOutputController::StatusBuildOutputController( UISplitter* mainSplitter, - UISceneNode* uiSceneNode, App* app ) : - StatusBarElement( mainSplitter, uiSceneNode, app ) {} + UISceneNode* uiSceneNode, + PluginContextProvider* pluginContext ) : + StatusBarElement( mainSplitter, uiSceneNode, pluginContext ) {} static std::string getProjectOutputParserTypeToString( const ProjectOutputParserTypes& type ) { switch ( type ) { @@ -20,18 +24,18 @@ static std::string getProjectOutputParserTypeToString( const ProjectOutputParser return "notice"; } -UIPushButton* StatusBuildOutputController::getBuildButton( App* app ) { - if ( app->getSidePanel() ) { - UIWidget* tab = app->getSidePanel()->find( "build_tab_view" ); +UIPushButton* StatusBuildOutputController::getBuildButton() { + if ( mContext->getSidePanel() ) { + UIWidget* tab = mContext->getSidePanel()->find( "build_tab_view" ); if ( tab ) return tab->find( "build_button" ); } return nullptr; } -UIPushButton* StatusBuildOutputController::getCleanButton( App* app ) { - if ( app->getSidePanel() ) { - UIWidget* tab = app->getSidePanel()->find( "build_tab_view" ); +UIPushButton* StatusBuildOutputController::getCleanButton() { + if ( mContext->getSidePanel() ) { + UIWidget* tab = mContext->getSidePanel()->find( "build_tab_view" ); if ( tab ) return tab->find( "clean_button" ); } @@ -105,10 +109,10 @@ void StatusBuildOutputController::runBuild( const std::string& buildName, const ProjectBuildOutputParser& outputParser, bool isClean, std::function doneFn ) { - if ( nullptr == mApp->getProjectBuildManager() ) + if ( nullptr == mContext->getProjectBuildManager() ) return; - auto pbm = mApp->getProjectBuildManager(); + auto pbm = mContext->getProjectBuildManager(); show(); showBuildOutput(); @@ -153,8 +157,8 @@ void StatusBuildOutputController::runBuild( const std::string& buildName, mScrollLocked = true; - UIPushButton* buildButton = getBuildButton( mApp ); - UIPushButton* cleanButton = getCleanButton( mApp ); + UIPushButton* buildButton = getBuildButton(); + UIPushButton* cleanButton = getCleanButton(); bool enableBuildButton = false; bool enableCleanButton = false; @@ -171,27 +175,29 @@ void StatusBuildOutputController::runBuild( const std::string& buildName, if ( isClean ) { if ( cleanButton ) - cleanButton->setText( mApp->i18n( "cancel_clean", "Cancel Clean" ) ); + cleanButton->setText( mContext->i18n( "cancel_clean", "Cancel Clean" ) ); } else { if ( buildButton ) - buildButton->setText( mApp->i18n( "cancel_build", "Cancel Build" ) ); + buildButton->setText( mContext->i18n( "cancel_build", "Cancel Build" ) ); } mBuildButton->setEnabled( false ); mStopButton->setEnabled( true ); const auto updateBuildButton = [this, isClean, enableBuildButton, enableCleanButton]() { - UIPushButton* buildButton = getBuildButton( mApp ); - UIPushButton* cleanButton = getCleanButton( mApp ); + UIPushButton* buildButton = getBuildButton(); + UIPushButton* cleanButton = getCleanButton(); if ( !isClean && buildButton ) { - buildButton->runOnMainThread( - [this, buildButton] { buildButton->setText( mApp->i18n( "build", "Build" ) ); } ); + buildButton->runOnMainThread( [this, buildButton] { + buildButton->setText( mContext->i18n( "build", "Build" ) ); + } ); } if ( isClean && cleanButton ) { - cleanButton->runOnMainThread( - [this, cleanButton] { cleanButton->setText( mApp->i18n( "clean", "Clean" ) ); } ); + cleanButton->runOnMainThread( [this, cleanButton] { + cleanButton->setText( mContext->i18n( "clean", "Clean" ) ); + } ); } if ( enableBuildButton && buildButton ) @@ -205,7 +211,8 @@ void StatusBuildOutputController::runBuild( const std::string& buildName, }; auto res = pbm->build( - buildName, [this]( const auto& key, const auto& def ) { return mApp->i18n( key, def ); }, + buildName, + [this]( const auto& key, const auto& def ) { return mContext->i18n( key, def ); }, buildType, [this]( auto, std::string buffer, const ProjectBuildCommand* cmd ) { mBuildOutput->runOnMainThread( [this, buffer]() { @@ -237,13 +244,14 @@ void StatusBuildOutputController::runBuild( const std::string& buildName, String buffer; if ( EXIT_SUCCESS == exitCode ) { - buffer = Sys::getDateTimeStr() + ": " + - ( isClean ? mApp->i18n( "clean_successful", "Clean run successfully\n" ) - : mApp->i18n( "build_successful", "Build run successfully\n" ) ); + buffer = + Sys::getDateTimeStr() + ": " + + ( isClean ? mContext->i18n( "clean_successful", "Clean run successfully\n" ) + : mContext->i18n( "build_successful", "Build run successfully\n" ) ); } else { buffer = Sys::getDateTimeStr() + ": " + - ( isClean ? mApp->i18n( "clean_failed", "Clean run with errors\n" ) - : mApp->i18n( "build_failed", "Build run with errors\n" ) ); + ( isClean ? mContext->i18n( "clean_failed", "Clean run with errors\n" ) + : mContext->i18n( "build_failed", "Build run with errors\n" ) ); } mBuildOutput->runOnMainThread( [this, buffer]() { @@ -254,9 +262,10 @@ void StatusBuildOutputController::runBuild( const std::string& buildName, updateBuildButton(); - if ( !mApp->getWindow()->hasFocus() ) { - mApp->getUISceneNode()->runOnMainThread( - [this] { mApp->getWindow()->flash( WindowFlashOperation::UntilFocused ); } ); + if ( !mContext->getWindow()->hasFocus() ) { + mContext->getUISceneNode()->runOnMainThread( [this] { + mContext->getWindow()->flash( WindowFlashOperation::UntilFocused ); + } ); } if ( doneFn ) @@ -265,7 +274,7 @@ void StatusBuildOutputController::runBuild( const std::string& buildName, isClean ); if ( !res.isValid() ) { - mApp->getNotificationCenter()->addNotification( res.errorMsg ); + mContext->getNotificationCenter()->addNotification( res.errorMsg ); updateBuildButton(); if ( doneFn ) doneFn( EXIT_FAILURE ); @@ -426,7 +435,7 @@ void StatusBuildOutputController::createContainer() { mMainSplitter->getLastWidget()->setParent( mUISceneNode ); } - mContainer = mApp->getUISceneNode() + mContainer = mContext->getUISceneNode() ->loadLayoutFromString( XML, mMainSplitter ) ->asType(); mRelLayCE = mContainer->find( "build_output_command_executer" ) @@ -436,14 +445,15 @@ void StatusBuildOutputController::createContainer() { editor->setLineBreakingColumn( 0 ); editor->setShowLineNumber( false ); editor->getDocument().reset(); - editor->getDocument().textInput( mApp->i18n( "no_build_has_been_run", "No build has been run" ), - false ); + editor->getDocument().textInput( + mContext->i18n( "no_build_has_been_run", "No build has been run" ), false ); editor->setScrollY( editor->getMaxScroll().y ); mButOutput = mContainer->find( "but_build_output_output" ); mButIssues = mContainer->find( "but_build_output_issues" ); mTableIssues = mContainer->find( "build_output_issues" ); mTableIssues->setHeadersVisible( true ); - mTableIssues->setModel( StatusMessageModel::create( mStatusResults, mApp->getUISceneNode() ) ); + mTableIssues->setModel( + StatusMessageModel::create( mStatusResults, mContext->getUISceneNode() ) ); setHeaderWidth(); mTableIssues->on( Event::OnSizeChange, [this]( auto ) { setHeaderWidth(); } ); mTableIssues->onModelEvent( [this]( const ModelEvent* modelEvent ) { @@ -461,7 +471,7 @@ void StatusBuildOutputController::createContainer() { if ( !tab ) { FileInfo fileInfo( path ); if ( fileInfo.exists() && fileInfo.isRegularFile() ) { - mApp->loadFileFromPath( + mContext->loadFileFromPath( path, true, nullptr, [this, lineNum, colNum]( UICodeEditor*, const std::string& ) { onLoadDone( lineNum, colNum ); @@ -469,7 +479,7 @@ void StatusBuildOutputController::createContainer() { } else { #if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) removeRelativeSubPaths( path ); - mApp->getDirTree()->asyncMatchTree( + mContext->getDirTree()->asyncMatchTree( ProjectDirectoryTree::MatchType::Fuzzy, path, 1, [this, colNum, lineNum]( std::shared_ptr res ) { if ( res->rowCount( {} ) == 0 ) @@ -481,7 +491,7 @@ void StatusBuildOutputController::createContainer() { mUISceneNode->runOnMainThread( [this, path, lineNum, colNum] { UITab* tab = mSplitter->isDocumentOpen( path ); if ( !tab ) { - mApp->loadFileFromPath( + mContext->loadFileFromPath( path, true, nullptr, [this, lineNum, colNum]( auto, auto ) { onLoadDone( lineNum, colNum ); @@ -501,26 +511,27 @@ void StatusBuildOutputController::createContainer() { } } else if ( modelEvent->getModelEventType() == ModelEventType::OpenMenu ) { UIPopUpMenu* menu = UIPopUpMenu::New(); - menu->add( mApp->i18n( "copy_error_message", "Copy Error Message" ), - mApp->findIcon( "copy" ) ) + menu->add( mContext->i18n( "copy_error_message", "Copy Error Message" ), + mContext->findIcon( "copy" ) ) ->setId( "copy-error-message" ); - menu->add( mApp->i18n( "copy_file_path", "Copy File Path" ), mApp->findIcon( "copy" ) ) + menu->add( mContext->i18n( "copy_file_path", "Copy File Path" ), + mContext->findIcon( "copy" ) ) ->setId( "copy-file-path" ); menu->on( Event::OnItemClicked, [this, model, idx]( const Event* event ) { UIMenuItem* item = event->getNode()->asType(); std::string id( item->getId() ); if ( id == "copy-error-message" ) { Variant msg( model->data( model->index( idx.row(), 0 ), ModelRole::Display ) ); - mApp->getWindow()->getClipboard()->setText( msg.toString() ); + mContext->getWindow()->getClipboard()->setText( msg.toString() ); } else if ( id == "copy-file-path" ) { Variant msg( model->data( idx, ModelRole::Custom ) ); - mApp->getWindow()->getClipboard()->setText( msg.toString() ); + mContext->getWindow()->getClipboard()->setText( msg.toString() ); } } ); UITableCell* cell = mTableIssues->getCellFromIndex( idx ); if ( modelEvent->getTriggerEvent()->getType() == Event::MouseClick || cell == nullptr ) { - Vector2f pos( mApp->getWindow()->getInput()->getMousePos().asFloat() ); + Vector2f pos( mContext->getWindow()->getInput()->getMousePos().asFloat() ); menu->nodeToWorldTranslation( pos ); UIMenu::findBestMenuPos( pos, menu ); menu->setPixelsPosition( pos ); @@ -565,18 +576,18 @@ void StatusBuildOutputController::createContainer() { } ); mBuildButton->onClick( [this]( auto ) { - auto pbm = mApp->getProjectBuildManager(); + auto pbm = mContext->getProjectBuildManager(); if ( nullptr == pbm ) return; if ( !pbm->hasBuildConfig() ) { UIMessageBox::New( UIMessageBox::OK, - mApp->i18n( "must_configure_build_config", - "You must first add a build configuration" ) ) + mContext->i18n( "must_configure_build_config", + "You must first add a build configuration" ) ) ->setCloseShortcut( { KEY_ESCAPE } ) - ->setTitle( mApp->getWindowTitle() ) + ->setTitle( mContext->getWindowTitle() ) ->showWhenReady() ->on( Event::OnConfirm, [this]( auto ) { - auto pbm = mApp->getProjectBuildManager(); + auto pbm = mContext->getProjectBuildManager(); if ( nullptr != pbm ) pbm->selectTab(); } ); @@ -586,7 +597,7 @@ void StatusBuildOutputController::createContainer() { } ); mStopButton->onClick( [this]( auto ) { - auto pbm = mApp->getProjectBuildManager(); + auto pbm = mContext->getProjectBuildManager(); if ( nullptr == pbm ) return; pbm->cancelBuild(); @@ -603,7 +614,7 @@ void StatusBuildOutputController::createContainer() { } ); mConfigureButton->onClick( [this]( auto ) { - auto pbm = mApp->getProjectBuildManager(); + auto pbm = mContext->getProjectBuildManager(); if ( nullptr == pbm ) return; pbm->editCurrentBuild(); diff --git a/src/tools/ecode/statusbuildoutputcontroller.hpp b/src/tools/ecode/statusbuildoutputcontroller.hpp index b978eb9a2..7c1756268 100644 --- a/src/tools/ecode/statusbuildoutputcontroller.hpp +++ b/src/tools/ecode/statusbuildoutputcontroller.hpp @@ -17,7 +17,6 @@ using namespace EE::UI::Tools; namespace ecode { -class App; class UIRelativeLayoutCommandExecuter; struct StatusMessage { @@ -37,9 +36,10 @@ struct PatternHolder { class StatusBuildOutputController : public StatusBarElement { public: - StatusBuildOutputController( UISplitter* mainSplitter, UISceneNode* uiSceneNode, App* app ); + StatusBuildOutputController( UISplitter* mainSplitter, UISceneNode* uiSceneNode, + PluginContextProvider* pluginContext ); - virtual ~StatusBuildOutputController(){}; + virtual ~StatusBuildOutputController() {}; void runBuild( const std::string& buildName, const std::string& buildType, const ProjectBuildOutputParser& outputParser = {}, bool isClean = false, @@ -75,9 +75,9 @@ class StatusBuildOutputController : public StatusBarElement { void createContainer(); - UIPushButton* getBuildButton( App* app ); + UIPushButton* getBuildButton(); - UIPushButton* getCleanButton( App* app ); + UIPushButton* getCleanButton(); bool searchFindAndAddStatusResult( const std::vector& patterns, const std::string& text, const ProjectBuildCommand* cmd ); diff --git a/src/tools/ecode/statusterminalcontroller.cpp b/src/tools/ecode/statusterminalcontroller.cpp index 923b4afa6..7f2991c6f 100644 --- a/src/tools/ecode/statusterminalcontroller.cpp +++ b/src/tools/ecode/statusterminalcontroller.cpp @@ -4,8 +4,9 @@ namespace ecode { StatusTerminalController::StatusTerminalController( UISplitter* mainSplitter, - UISceneNode* uiSceneNode, App* app ) : - StatusBarElement( mainSplitter, uiSceneNode, app ) {} + UISceneNode* uiSceneNode, + App* app ) : + StatusBarElement( mainSplitter, uiSceneNode, app ), mApp( app ) {} UIWidget* StatusTerminalController::getWidget() { return mUITerminal; @@ -25,54 +26,55 @@ UITerminal* StatusTerminalController::createTerminal( const std::string& working std::string program, const std::vector& args ) { Sizef initialSize( 16, 16 ); - if ( program.empty() && !mApp->termConfig().shell.empty() ) - program = mApp->termConfig().shell; + if ( program.empty() && !mContext->termConfig().shell.empty() ) + program = mContext->termConfig().shell; UITerminal* term = UITerminal::New( - mApp->getTerminalFont() ? mApp->getTerminalFont() : mApp->getFontMono(), - mApp->termConfig().fontSize.asPixels( 0, Sizef(), mApp->getDisplayDPI() ), initialSize, - program, args, !workingDir.empty() ? workingDir : mApp->getCurrentWorkingDir(), 10000, - nullptr, false ); + mContext->getTerminalFont() ? mContext->getTerminalFont() : mContext->getFontMono(), + mContext->termConfig().fontSize.asPixels( 0, Sizef(), mContext->getDisplayDPI() ), + initialSize, program, args, + !workingDir.empty() ? workingDir : mContext->getCurrentWorkingDir(), 10000, nullptr, + false ); if ( term == nullptr || term->getTerm() == nullptr ) { - mApp->getTerminalManager()->displayError( workingDir ); + mContext->getTerminalManager()->displayError( workingDir ); return nullptr; } - const auto& terminalColorSchemes = mApp->getTerminalManager()->getTerminalColorSchemes(); + const auto& terminalColorSchemes = mContext->getTerminalManager()->getTerminalColorSchemes(); const auto& currentTerminalColorScheme = - mApp->getTerminalManager()->getTerminalCurrentColorScheme(); + mContext->getTerminalManager()->getTerminalCurrentColorScheme(); auto csIt = terminalColorSchemes.find( currentTerminalColorScheme ); term->getTerm()->getTerminal()->setAllowMemoryTrimnming( true ); term->setColorScheme( csIt != terminalColorSchemes.end() ? terminalColorSchemes.at( currentTerminalColorScheme ) : TerminalColorScheme::getDefault() ); - mApp->getTerminalManager()->setKeybindings( term ); + mContext->getTerminalManager()->setKeybindings( term ); term->setCommand( "switch-to-previous-colorscheme", [this] { - auto it = mApp->getTerminalManager()->getTerminalColorSchemes().find( - mApp->getTerminalManager()->getTerminalCurrentColorScheme() ); + auto it = mContext->getTerminalManager()->getTerminalColorSchemes().find( + mContext->getTerminalManager()->getTerminalCurrentColorScheme() ); auto prev = std::prev( it, 1 ); - if ( prev != mApp->getTerminalManager()->getTerminalColorSchemes().end() ) { - mApp->getTerminalManager()->setTerminalColorScheme( prev->first ); + if ( prev != mContext->getTerminalManager()->getTerminalColorSchemes().end() ) { + mContext->getTerminalManager()->setTerminalColorScheme( prev->first ); } else { - mApp->getTerminalManager()->setTerminalColorScheme( - mApp->getTerminalManager()->getTerminalColorSchemes().rbegin()->first ); + mContext->getTerminalManager()->setTerminalColorScheme( + mContext->getTerminalManager()->getTerminalColorSchemes().rbegin()->first ); } } ); term->setCommand( "switch-to-next-colorscheme", [this] { - auto it = mApp->getTerminalManager()->getTerminalColorSchemes().find( - mApp->getTerminalManager()->getTerminalCurrentColorScheme() ); - mApp->getTerminalManager()->setTerminalColorScheme( - ++it != mApp->getTerminalManager()->getTerminalColorSchemes().end() + auto it = mContext->getTerminalManager()->getTerminalColorSchemes().find( + mContext->getTerminalManager()->getTerminalCurrentColorScheme() ); + mContext->getTerminalManager()->setTerminalColorScheme( + ++it != mContext->getTerminalManager()->getTerminalColorSchemes().end() ? it->first - : mApp->getTerminalManager()->getTerminalColorSchemes().begin()->first ); + : mContext->getTerminalManager()->getTerminalColorSchemes().begin()->first ); } ); term->setCommand( UITerminal::getExclusiveModeToggleCommandName(), [term, this] { term->setExclusiveMode( !term->getExclusiveMode() ); mApp->updateTerminalMenu(); } ); mApp->registerUnlockedCommands( *term ); - mApp->getSplitter()->registerSplitterCommands( *term ); + mContext->getSplitter()->registerSplitterCommands( *term ); term->setFocus(); term->setId( "terminal" ); return term; diff --git a/src/tools/ecode/statusterminalcontroller.hpp b/src/tools/ecode/statusterminalcontroller.hpp index 32044a059..dd5253bee 100644 --- a/src/tools/ecode/statusterminalcontroller.hpp +++ b/src/tools/ecode/statusterminalcontroller.hpp @@ -30,6 +30,8 @@ class StatusTerminalController : public StatusBarElement { UITerminal* getUITerminal(); protected: + App* mApp; + UITerminal* mUITerminal{ nullptr }; UITerminal* createTerminal( const std::string& workingDir = "", std::string program = "", diff --git a/src/tools/ecode/uistatusbar.cpp b/src/tools/ecode/uistatusbar.cpp index 07670eeac..acd53327c 100644 --- a/src/tools/ecode/uistatusbar.cpp +++ b/src/tools/ecode/uistatusbar.cpp @@ -1,15 +1,21 @@ -#include "ecode.hpp" #include "uistatusbar.hpp" +#include "globalsearchcontroller.hpp" +#include "plugins/plugincontextprovider.hpp" +#include "statusappoutputcontroller.hpp" +#include "statusbuildoutputcontroller.hpp" +#include "statusterminalcontroller.hpp" +#include "universallocator.hpp" #include #include namespace ecode { -StatusBarElement::StatusBarElement( UISplitter* mainSplitter, UISceneNode* uiSceneNode, App* app ) : +StatusBarElement::StatusBarElement( UISplitter* mainSplitter, UISceneNode* uiSceneNode, + PluginContextProvider* app ) : mMainSplitter( mainSplitter ), mUISceneNode( uiSceneNode ), - mApp( app ), - mSplitter( mApp->getSplitter() ) {} + mContext( app ), + mSplitter( mContext->getSplitter() ) {} void StatusBarElement::toggle() { if ( nullptr == getWidget() ) { @@ -32,7 +38,7 @@ void StatusBarElement::hide() { if ( getWidget() && getWidget()->isVisible() ) { getWidget()->setParent( mUISceneNode ); getWidget()->setVisible( false ); - mApp->getStatusBar()->updateState(); + mContext->getStatusBar()->updateState(); if ( mSplitter->getCurWidget() ) mSplitter->getCurWidget()->setFocus(); } @@ -48,9 +54,9 @@ void StatusBarElement::show() { } if ( !getWidget()->isVisible() ) { - mApp->hideLocateBar(); - mApp->hideSearchBar(); - mApp->hideGlobalSearchBar(); + mContext->hideLocateBar(); + mContext->hideSearchBar(); + mContext->hideGlobalSearchBar(); if ( mMainSplitter->getLastWidget() != nullptr ) { mMainSplitter->getLastWidget()->setVisible( false ); mMainSplitter->getLastWidget()->setParent( mUISceneNode ); @@ -58,7 +64,7 @@ void StatusBarElement::show() { getWidget()->setParent( mMainSplitter ); getWidget()->setVisible( true ); getWidget()->setFocus(); - mApp->getStatusBar()->updateState(); + mContext->getStatusBar()->updateState(); } } @@ -78,7 +84,7 @@ void UIStatusBar::updateState() { if ( nullptr == widget->getTooltip() ) { std::string name( widget->getId() ); String::replaceAll( name, "_", "-" ); - auto kb = mApp->getKeybind( "toggle-" + name ); + auto kb = mContext->getKeybind( "toggle-" + name ); if ( !kb.empty() ) widget->setTooltipText( kb ); } @@ -96,8 +102,8 @@ void UIStatusBar::updateState() { } } ); - if ( mApp->getMainSplitter() && mApp->getMainSplitter()->getLastWidget() ) { - UIWidget* widget = mApp->getMainSplitter()->getLastWidget(); + if ( mContext->getMainSplitter() && mContext->getMainSplitter()->getLastWidget() ) { + UIWidget* widget = mContext->getMainSplitter()->getLastWidget(); UIWidget* but = find( "status_" + widget->getId() ); if ( but && but != this ) { if ( widget->isVisible() ) { @@ -110,7 +116,7 @@ void UIStatusBar::updateState() { } Uint32 UIStatusBar::onMessage( const NodeMessage* msg ) { - if ( !isVisible() || nullptr == mApp || msg->getMsg() != NodeMessage::MouseClick || + if ( !isVisible() || nullptr == mContext || msg->getMsg() != NodeMessage::MouseClick || 0 == ( msg->getFlags() & EE_BUTTON_LMASK ) || !msg->getSender()->isWidget() ) return 0; @@ -122,19 +128,26 @@ Uint32 UIStatusBar::onMessage( const NodeMessage* msg ) { int ret = 0; if ( widget->getId() == "status_locate_bar" ) { - mApp->getUniversalLocator()->toggleLocateBar(); + mContext->getUniversalLocator()->toggleLocateBar(); ret = 1; } else if ( widget->getId() == "status_global_search_bar" ) { - mApp->getGlobalSearchController()->toggleGlobalSearchBar(); + mContext->getGlobalSearchController()->toggleGlobalSearchBar(); ret = 1; } else if ( widget->getId() == "status_terminal" ) { - mApp->getStatusTerminalController()->toggle(); + mContext->getStatusTerminalController()->toggle(); ret = 1; } else if ( widget->getId() == "status_build_output" ) { - mApp->getStatusBuildOutputController()->toggle(); + mContext->getStatusBuildOutputController()->toggle(); ret = 1; } else if ( widget->getId() == "status_app_output" ) { - mApp->getStatusAppOutputController()->toggle(); + mContext->getStatusAppOutputController()->toggle(); + ret = 1; + } else { + auto elemIt = mElements.find( widget->getId() ); + if ( elemIt != mElements.end() ) { + elemIt->second.second->toggle(); + ret = 1; + } } if ( ret ) @@ -142,8 +155,8 @@ Uint32 UIStatusBar::onMessage( const NodeMessage* msg ) { return ret; } -void UIStatusBar::setApp( App* app ) { - mApp = app; +void UIStatusBar::setPluginContextProvider( PluginContextProvider* app ) { + mContext = app; updateState(); } @@ -155,8 +168,37 @@ void UIStatusBar::onVisibilityChange() { void UIStatusBar::onChildCountChange( Node* node, const bool& removed ) { UILinearLayout::onChildCountChange( node, removed ); - if ( mApp ) + if ( mContext ) updateState(); } +UIPushButton* UIStatusBar::insertStatusBarElement( std::string id, const String& text, + const std::string& icon, + std::shared_ptr element ) { + auto elemIt = mElements.find( id ); + UIPushButton* button = nullptr; + if ( elemIt != mElements.end() ) { + button = elemIt->second.first; + mElements.erase( elemIt ); + } else { + button = UIPushButton::New(); + button->beginAttributesTransaction(); + button->setText( text ); + button->setParent( this )->setId( id ); + UIWidget* statusSep = findByClass( "status_sep" ); + if ( statusSep ) + button->toPosition( statusSep->getNodeIndex() ); + button->applyProperty( + StyleSheetProperty( "icon", icon, false, StyleSheetSelectorRule::SpecificityInline ) ); + button->endAttributesTransaction(); + } + + mElements[id] = { button, element }; + return button; +} + +void UIStatusBar::removeStatusBarElement( const std::string& id ) { + mElements.erase( id ); +} + } // namespace ecode diff --git a/src/tools/ecode/uistatusbar.hpp b/src/tools/ecode/uistatusbar.hpp index 2b8431b12..7ba9ef89a 100644 --- a/src/tools/ecode/uistatusbar.hpp +++ b/src/tools/ecode/uistatusbar.hpp @@ -11,11 +11,12 @@ using namespace EE::UI; namespace ecode { -class App; +class PluginContextProvider; class StatusBarElement { public: - StatusBarElement( UISplitter* mainSplitter, UISceneNode* uiSceneNode, App* app ); + StatusBarElement( UISplitter* mainSplitter, UISceneNode* uiSceneNode, + PluginContextProvider* app ); virtual void toggle(); @@ -30,7 +31,7 @@ class StatusBarElement { protected: UISplitter* mMainSplitter; UISceneNode* mUISceneNode; - App* mApp; + PluginContextProvider* mContext; Tools::UICodeEditorSplitter* mSplitter; }; @@ -42,13 +43,21 @@ class UIStatusBar : public UILinearLayout, public WidgetCommandExecuter { void updateState(); + UIPushButton* insertStatusBarElement( std::string id, const String& text, + const std::string& icon, + std::shared_ptr element ); + + void removeStatusBarElement( const std::string& id ); + + void setPluginContextProvider( PluginContextProvider* app ); + protected: - friend class App; + UnorderedMap>> + mElements; + virtual Uint32 onMessage( const NodeMessage* msg ); - void setApp( App* app ); - - App* mApp{ nullptr }; + PluginContextProvider* mContext{ nullptr }; virtual void onVisibilityChange();