diff --git a/include/eepp/ui/uicheckbox.hpp b/include/eepp/ui/uicheckbox.hpp index 2cde649aa..ba8ad29f7 100644 --- a/include/eepp/ui/uicheckbox.hpp +++ b/include/eepp/ui/uicheckbox.hpp @@ -75,6 +75,8 @@ class EE_API UICheckBox : public UITextView { virtual void onPaddingChange(); + virtual void onTextChanged(); + virtual void alignFix(); }; diff --git a/src/eepp/ui/uicheckbox.cpp b/src/eepp/ui/uicheckbox.cpp index 891f3f895..1f26580aa 100644 --- a/src/eepp/ui/uicheckbox.cpp +++ b/src/eepp/ui/uicheckbox.cpp @@ -114,6 +114,11 @@ void UICheckBox::onSizeChange() { UITextView::onSizeChange(); } +void UICheckBox::onTextChanged() { + sendCommonEvent( Event::OnTextChanged ); + invalidateDraw(); +} + Uint32 UICheckBox::onMessage( const NodeMessage* msg ) { switch ( msg->getMsg() ) { case NodeMessage::MouseClick: { diff --git a/src/tools/ecode/applayout.xml.hpp b/src/tools/ecode/applayout.xml.hpp index 733d94788..14d55314e 100644 --- a/src/tools/ecode/applayout.xml.hpp +++ b/src/tools/ecode/applayout.xml.hpp @@ -558,11 +558,11 @@ R"html( - - - - - + + + + + diff --git a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp index 5f306fe94..1fcbcdd65 100644 --- a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp +++ b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp @@ -2,8 +2,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -76,10 +78,14 @@ fuzzyMatchSymbols( const std::vector& sy } Plugin* AutoCompletePlugin::New( PluginManager* pluginManager ) { - return eeNew( AutoCompletePlugin, ( pluginManager ) ); + return eeNew( AutoCompletePlugin, ( pluginManager, false ) ); } -AutoCompletePlugin::AutoCompletePlugin( PluginManager* pluginManager ) : +Plugin* AutoCompletePlugin::NewSync( PluginManager* pluginManager ) { + return eeNew( AutoCompletePlugin, ( pluginManager, true ) ); +} + +AutoCompletePlugin::AutoCompletePlugin( PluginManager* pluginManager, bool sync ) : Plugin( pluginManager ), mSymbolPattern( "[%a_ñàáâãäåèéêëìíîïòóôõöùúûüýÿÑÀÁÂÃÄÅÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝ][%w_" "ñàáâãäåèéêëìíîïòóôõöùúûüýÿÑÀÁÂÃÄÅÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝ]*" ), @@ -87,13 +93,21 @@ AutoCompletePlugin::AutoCompletePlugin( PluginManager* pluginManager ) : mManager->subscribeMessages( this, [this]( const PluginMessage& msg ) -> PluginRequestHandle { return processResponse( msg ); } ); - mReady = true; - setReady(); + if ( sync ) { + load( pluginManager ); + } else { +#if defined( AUTO_COMPLETE_THREADED ) && AUTO_COMPLETE_THREADED == 1 + mThreadPool->run( [this, pluginManager] { load( pluginManager ); } ); +#else + load( pluginManager ); +#endif + } } AutoCompletePlugin::~AutoCompletePlugin() { mShuttingDown = true; mManager->unsubscribeMessages( this ); + unsubscribeFileSystemListener(); Lock l( mDocMutex ); Lock l2( mLangSymbolsMutex ); @@ -105,6 +119,62 @@ AutoCompletePlugin::~AutoCompletePlugin() { } } +void AutoCompletePlugin::load( PluginManager* pluginManager ) { + AtomicBoolScopedOp loading( mLoading, true ); + std::string path = pluginManager->getPluginsPath() + "autocomplete.json"; + if ( FileSystem::fileExists( path ) || + FileSystem::fileWrite( path, "{\n \"config\":{},\n \"keybindings\":{}\n}\n" ) ) { + mConfigPath = path; + } + std::string data; + if ( !FileSystem::fileGet( path, data ) ) + return; + mConfigHash = String::hash( data ); + + json j; + try { + j = json::parse( data, nullptr, true, true ); + } catch ( const json::exception& e ) { + Log::error( + "AutoCompletePlugin::load - Error parsing config from path %s, error: %s, config " + "file content:\n%s", + path.c_str(), e.what(), data.c_str() ); + // Recreate it + j = json::parse( "{\n \"config\":{},\n \"keybindings\":{},\n}\n", nullptr, true, true ); + } + + bool updateConfigFile = false; + + if ( j.contains( "config" ) ) { + auto& config = j["config"]; + if ( config.contains( "suggestions_syntax_highlight" ) ) + mHighlightSuggestions = config.value( "suggestions_syntax_highlight", false ); + else { + config["suggestions_syntax_highlight"] = mHighlightSuggestions; + updateConfigFile = true; + } + if ( config.contains( "max_label_characters" ) ) + mMaxLabelCharacters = config.value( "max_label_characters", 100 ); + else { + config["max_label_characters"] = mMaxLabelCharacters; + updateConfigFile = true; + } + } + + if ( updateConfigFile ) { + std::string newData = j.dump( 2 ); + if ( newData != data ) { + FileSystem::fileWrite( path, newData ); + mConfigHash = String::hash( newData ); + } + } + + subscribeFileSystemListener(); + mReady = true; + fireReadyCbs(); + setReady(); +} + void AutoCompletePlugin::onRegister( UICodeEditor* editor ) { Lock l( mDocMutex ); std::vector listeners; diff --git a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp index 43075a7ea..e6cc79c1b 100644 --- a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp +++ b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp @@ -63,11 +63,14 @@ class AutoCompletePlugin : public Plugin { "Auto complete shows the completion popup as you type, so you can fill " "in long words by typing only a few characters.", AutoCompletePlugin::New, - { 0, 2, 3 } }; + { 0, 2, 3 }, + AutoCompletePlugin::NewSync }; } static Plugin* New( PluginManager* pluginManager ); + static Plugin* NewSync( PluginManager* pluginManager ); + virtual ~AutoCompletePlugin(); std::string getId() { return Definition().id; } @@ -150,11 +153,14 @@ class AutoCompletePlugin : public Plugin { Mutex mDocsUpdatingMutex; Text mSuggestionDoc; size_t mMaxLabelCharacters{ 100 }; + String::HashType mConfigHash{ 0 }; Float mRowHeight{ 0 }; Rectf mBoxRect; - explicit AutoCompletePlugin( PluginManager* pluginManager ); + explicit AutoCompletePlugin( PluginManager* pluginManager, bool sync ); + + void load( PluginManager* pluginManager ); void resetSuggestions( UICodeEditor* editor );