diff --git a/src/eepp/ui/mouseshortcut.cpp b/src/eepp/ui/mouseshortcut.cpp index 49b8ffd74..1071f0f5b 100644 --- a/src/eepp/ui/mouseshortcut.cpp +++ b/src/eepp/ui/mouseshortcut.cpp @@ -41,7 +41,7 @@ MouseAction MouseBindings::mouseActionFromString( std::string_view action ) { } MouseButtonsMask MouseBindings::getMouseButtonsMask( const std::string& strc ) { - MouseButtonsMask mask; + MouseButtonsMask mask = 0; String::readBySeparator( strc, [&mask]( std::string_view str ) { diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 0d4fa90d7..6fb29b34a 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -1592,6 +1592,8 @@ Uint32 UICodeEditor::onMouseDown( const Vector2i& position, const Uint32& flags } else if ( !mDoc->hasSelection() ) { mDoc->setSelection( textScreenPos ); } + } else if ( !( flags & ( EE_BUTTON_LMASK | EE_BUTTON_RMASK ) ) ) { + tryExecuteMouseBinding( shortcut ); } return UIWidget::onMouseDown( position, flags ); } @@ -2641,6 +2643,10 @@ KeyBindings& UICodeEditor::getKeyBindings() { return mKeyBindings; } +MouseBindings& UICodeEditor::getMouseBindings() { + return mMouseBindings; +} + void UICodeEditor::setKeyBindings( const KeyBindings& keyBindings ) { mKeyBindings = keyBindings; } diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index c794f5fae..90dcf9093 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -1302,6 +1302,11 @@ void App::loadKeybindings() { DocSearchController::getDefaultKeybindings(), forceRebind, getMigrateKeybindings(), mConfig.iniState ); + KeybindingsHelper::updateKeybindings( ini, "editor_mouse_bindings", mWindow->getInput(), + mMousebindings, mMousebindingsInvert, + UICodeEditor::getDefaultMousebindings(), forceRebind, + getMigrateKeybindings(), mConfig.iniState ); + auto localKeybindings = getLocalKeybindings(); for ( const auto& kb : localKeybindings ) { auto found = mKeybindingsInvert.find( kb.second ); @@ -1340,10 +1345,15 @@ void App::reloadKeybindings() { mRealSplitterKeybindings.clear(); mRealTerminalKeybindings.clear(); mRealDefaultKeybindings.clear(); + mMousebindings.clear(); + mMousebindingsInvert.clear(); loadKeybindings(); mSplitter->forEachEditor( [this]( UICodeEditor* ed ) { ed->getKeyBindings().reset(); ed->getKeyBindings().addKeybindsStringUnordered( mKeybindings ); + ed->getMouseBindings().reset(); + ed->getMouseBindings().addMousebindsString( mMousebindings ); + } ); mSplitter->forEachWidgetType( UI_TYPE_TERMINAL, [this]( UIWidget* widget ) { mTerminalManager->setKeybindings( widget->asType() ); @@ -2547,6 +2557,11 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { editor->getKeyBindings().addKeybindsStringUnordered( mKeybindings ); } + if ( !mMousebindings.empty() ) { + editor->getMouseBindings().reset(); + editor->getMouseBindings().addMousebindsString( mMousebindings ); + } + editor->on( Event::OnClose, [this, editor]( auto ) { if ( SceneManager::existsSingleton() && !SceneManager::instance()->isShuttingDown() && editor->hasClass( NOT_UNIQUE_FILENAME ) ) diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index 54f598bee..33f3342f1 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -583,6 +583,8 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider { std::map mRealSplitterKeybindings; std::map mRealTerminalKeybindings; std::map mRealDefaultKeybindings; + std::unordered_map mMousebindings; + std::unordered_map mMousebindingsInvert; std::string mConfigPath; std::string mPluginsPath; std::string mColorSchemesPath; diff --git a/src/tools/ecode/keybindingshelper.cpp b/src/tools/ecode/keybindingshelper.cpp index c5de74da3..940539806 100644 --- a/src/tools/ecode/keybindingshelper.cpp +++ b/src/tools/ecode/keybindingshelper.cpp @@ -172,4 +172,92 @@ void KeybindingsHelper::updateKeybindings( ini.writeFile(); } +void KeybindingsHelper::updateKeybindings( + IniFile& ini, const std::string& group, Input* input, + std::unordered_map& keybindings, + std::unordered_map& invertedKeybindings, + const MouseBindings::ShortcutMap& defKeybindings, bool forceRebind, + const std::map& migrateKeyindings, IniFile& iniState ) { + MouseBindings bindings; + bool added = false; + bool migrated = false; + + if ( ini.findKey( group ) != IniFile::noID ) { + keybindings = ini.getKeyUnorderedMap( group ); + } else { + for ( const auto& it : defKeybindings ) + ini.setValue( group, bindings.getShortcutString( it.first ), it.second ); + added = true; + } + for ( const auto& key : keybindings ) + invertedKeybindings[key.second] = key.first; + + if ( !added && forceRebind ) { + for ( const auto& migrate : migrateKeyindings ) { + auto foundCmd = invertedKeybindings.find( migrate.first ); + if ( foundCmd != invertedKeybindings.end() && foundCmd->second == migrate.second ) { + MouseBindings::Shortcut shortcut; + for ( const auto& defKb : defKeybindings ) { + if ( defKb.second == foundCmd->first ) { + shortcut = defKb.first; + break; + } + } + if ( !iniState.keyValueExists( "migrated_keybindings_" + group, migrate.first ) ) { + if ( !shortcut.empty() ) { + auto newShortcutStr = bindings.getShortcutString( shortcut ); + ini.setValue( group, newShortcutStr, foundCmd->first ); + invertedKeybindings[foundCmd->first] = newShortcutStr; + } else { + invertedKeybindings.erase( foundCmd->first ); + } + ini.deleteValue( group, migrate.second ); + keybindings.erase( migrate.second ); + iniState.setValue( "migrated_keybindings_" + group, migrate.first, + migrate.second ); + added = true; + migrated = true; + } + } + } + } + + bool keybindingsWereEmpty = keybindings.empty(); + + if ( defKeybindings.size() != keybindings.size() || forceRebind ) { + for ( auto& key : defKeybindings ) { + auto foundCmd = invertedKeybindings.find( key.second ); + auto shortcutStr = bindings.getShortcutString( key.first ); + + if ( ( foundCmd == invertedKeybindings.end() || keybindingsWereEmpty ) && + keybindings.find( shortcutStr ) == keybindings.end() ) { + keybindings[shortcutStr] = key.second; + invertedKeybindings[key.second] = shortcutStr; + ini.setValue( group, shortcutStr, key.second ); + added = true; + } else if ( foundCmd == invertedKeybindings.end() ) { + // Override the shortcut if the command that holds that + // shortcut does not exists anymore + auto kb = keybindings.find( shortcutStr ); + if ( kb != keybindings.end() ) { + bool found = false; + for ( const auto& val : defKeybindings ) + if ( val.second == kb->second ) + found = true; + if ( !found ) { + keybindings[shortcutStr] = key.second; + invertedKeybindings[key.second] = shortcutStr; + ini.setValue( group, shortcutStr, key.second ); + added = true; + } + } + } + } + } + if ( migrated ) + iniState.writeFile(); + if ( added ) + ini.writeFile(); +} + } // namespace ecode diff --git a/src/tools/ecode/keybindingshelper.hpp b/src/tools/ecode/keybindingshelper.hpp index 52c1102ce..f583966aa 100644 --- a/src/tools/ecode/keybindingshelper.hpp +++ b/src/tools/ecode/keybindingshelper.hpp @@ -3,6 +3,7 @@ #include #include +#include #include using namespace EE::System; @@ -24,6 +25,14 @@ class KeybindingsHelper { std::unordered_map& invertedKeybindings, const std::map& defKeybindings, bool forceRebind, const std::map& migrateKeyindings, IniFile& iniState ); + + static void + updateKeybindings( IniFile& ini, const std::string& group, Input* input, + std::unordered_map& keybindings, + std::unordered_map& invertedKeybindings, + const MouseBindings::ShortcutMap& defKeybindings, bool forceRebind, + const std::map& migrateKeyindings, + IniFile& iniState ); }; } // namespace ecode