diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 5151fe191..aefccb0f6 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -29,6 +29,8 @@ #if defined(BSPF_MACOS) || defined(MACOS_KEYS) static constexpr int MOD3 = KBDM_GUI; +static constexpr int CMD = KBDM_GUI; +static constexpr int OPTION = KBDM_ALT; #else static constexpr int MOD3 = KBDM_ALT; #endif @@ -60,6 +62,7 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(OSystem& system, EventHandler& setDefaultMapping(Event::NoType, EventMode::kEmulationMode, updateDefaults); setDefaultMapping(Event::NoType, EventMode::kMenuMode, updateDefaults); + setDefaultMapping(Event::NoType, EventMode::kEditMode, updateDefaults); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -151,6 +154,12 @@ void PhysicalKeyboardHandler::setDefaultMapping(Event::Type event, EventMode mod setDefaultKey(item, event, EventMode::kMenuMode, updateDefaults); break; + case EventMode::kEditMode: + // Edit mode events are always set because they are not saved + for(const auto& item : FixedEditMapping) + setDefaultKey(item, event, EventMode::kEditMode); + break; + default: break; } @@ -641,6 +650,73 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultMenuM #endif }; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::FixedEditMapping = { +// TOOD: check MacOS mappings + {Event::MoveLeftChar, KBDK_LEFT}, + {Event::MoveRightChar, KBDK_RIGHT}, + {Event::SelectLeftChar, KBDK_LEFT, KBDM_SHIFT}, + {Event::SelectRightChar, KBDK_RIGHT, KBDM_SHIFT}, +#ifdef BSPF_MACOS + {Event::MoveLeftWord, KBDK_LEFT, CMD}, +// {Event::MoveRightWord, KBDK_RIGHT, KBDM_CTRL}, + {Event::MoveHome, KBDK_LEFT, CMD}, + {Event::MoveHome, KBDK_A, KBDM_CTRL}, + {Event::MoveEnd, KBDK_RIGHT, CMD}, + {Event::MoveEnd, KBDK_E, KBDM_CTRL}, + {Event::SelectLeftWord, KBDK_LEFT, KBDM_SHIFT | OPTION}, +// {Event::SelectRightWord, KBDK_RIGHT, KBDM_SHIFT | OPTION}, + {Event::SelectHome, KBDK_A, KBDM_SHIFT | KBDM_CTRL}, + {Event::SelectHome, KBDK_LEFT, KBDM_SHIFT | CMD}, + {Event::SelectEnd, KBDK_E, KBDM_SHIFT | KBDM_CTRL}, + {Event::SelectEnd, KBDK_RIGHT, KBDM_SHIFT | CMD}, + {Event::SelectAll, KBDK_A, CMD}, + {Event::Delete, KBDK_DELETE}, + {Event::Delete, KBDK_KP_PERIOD}, // ??? +// {Event::DeleteChar, }, // ??? + {Event::DeleteWord, KBDK_W, OPTION}, + {Event::DeleteHome, KBDK_BACKSPACE, CMD}, + {Event::DeleteEnd, KBDK_BACKSPACE, KBDM_SHIFT | KBDM_CTRL}, + {Event::Backspace, KBDK_BACKSPACE}, // ??? + {Event::Undo, KBDK_Z, CMD}, + {Event::Redo, KBDK_Y, CMD}, + {Event::Redo, KBDK_Z, KBDM_SHIFT | CMD}, + {Event::Cut, KBDK_X, CMD}, + {Event::Copy, KBDK_C, CMD}, + {Event::Paste, KBDK_V, CMD}, +#else + {Event::MoveLeftWord, KBDK_LEFT, KBDM_CTRL}, + {Event::MoveRightWord, KBDK_RIGHT, KBDM_CTRL}, + {Event::MoveHome, KBDK_HOME}, + {Event::MoveEnd, KBDK_END}, + {Event::SelectLeftWord, KBDK_LEFT, KBDM_SHIFT | KBDM_CTRL}, + {Event::SelectRightWord, KBDK_RIGHT, KBDM_SHIFT | KBDM_CTRL}, + {Event::SelectHome, KBDK_HOME, KBDM_SHIFT}, + {Event::SelectEnd, KBDK_END, KBDM_SHIFT}, + {Event::SelectAll, KBDK_A, KBDM_CTRL}, + {Event::Delete, KBDK_DELETE}, + {Event::Delete, KBDK_KP_PERIOD}, + {Event::DeleteChar, KBDK_D, KBDM_CTRL}, + {Event::DeleteWord, KBDK_W, KBDM_CTRL}, + {Event::DeleteHome, KBDK_U, KBDM_CTRL}, + {Event::DeleteEnd, KBDK_K, KBDM_CTRL}, + {Event::Backspace, KBDK_BACKSPACE}, + {Event::Undo, KBDK_Z, KBDM_CTRL}, + {Event::Redo, KBDK_Y, KBDM_CTRL}, + {Event::Redo, KBDK_Z, KBDM_SHIFT | KBDM_CTRL}, + {Event::Cut, KBDK_X, KBDM_CTRL}, + {Event::Cut, KBDK_DELETE, KBDM_SHIFT}, + {Event::Cut, KBDK_KP_PERIOD, KBDM_SHIFT}, + {Event::Copy, KBDK_C, KBDM_CTRL}, + {Event::Copy, KBDK_INSERT, KBDM_CTRL}, + {Event::Paste, KBDK_V, KBDM_CTRL}, + {Event::Paste, KBDK_INSERT, KBDM_SHIFT}, +#endif + {Event::EndEdit, KBDK_RETURN}, + {Event::EndEdit, KBDK_KP_ENTER}, + {Event::AbortEdit, KBDK_ESCAPE}, +}; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultJoystickMapping = { {Event::JoystickZeroUp, KBDK_UP}, diff --git a/src/common/PKeyboardHandler.hxx b/src/common/PKeyboardHandler.hxx index ede6aa55a..8ebfd5acb 100644 --- a/src/common/PKeyboardHandler.hxx +++ b/src/common/PKeyboardHandler.hxx @@ -132,6 +132,7 @@ class PhysicalKeyboardHandler // Controller menu and common emulation mappings static EventMappingArray DefaultMenuMapping; + static EventMappingArray FixedEditMapping; static EventMappingArray DefaultCommonMapping; // Controller specific mappings static EventMappingArray DefaultJoystickMapping; diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index d71f9a2e6..87a609834 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -136,6 +136,14 @@ class Event ToggleCorrectAspectRatio, + MoveLeftChar, MoveRightChar, MoveLeftWord, MoveRightWord, + MoveHome, MoveEnd, + SelectLeftChar, SelectRightChar, SelectLeftWord, SelectRightWord, + SelectHome, SelectEnd, SelectAll, + Delete, DeleteChar, DeleteWord, DeleteHome, DeleteEnd, Backspace, + Cut, Copy, Paste, Undo, Redo, + AbortEdit, EndEdit, + LastType }; diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index f0da1226c..3ce9a4da5 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -2830,3 +2830,8 @@ const Event::EventSet EventHandler::DebugEvents = { Event::ToggleColorLoss, Event::ToggleJitter, }; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +const Event::EventSet EventHandler::EditEvents = { + +}; diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 3833f7bec..5671e1291 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -511,6 +511,7 @@ class EventHandler static const Event::EventSet KeyboardEvents; static const Event::EventSet ComboEvents; static const Event::EventSet DebugEvents; + static const Event::EventSet EditEvents; /** The following methods take care of assigning action mappings. diff --git a/src/emucore/EventHandlerConstants.hxx b/src/emucore/EventHandlerConstants.hxx index 0009af3d3..b67df420f 100644 --- a/src/emucore/EventHandlerConstants.hxx +++ b/src/emucore/EventHandlerConstants.hxx @@ -79,6 +79,7 @@ static const int NUM_PORTS = 2; enum class EventMode { kEmulationMode, // active mapping used for emulation kMenuMode, // mapping used for dialogs + kEditMode, // mapping used in editable widgets kJoystickMode, // 4 extra modes for mapping controller keys separately for emulation mode kPaddlesMode, kKeypadMode, diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 48bc79013..810d3f1d3 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -89,6 +89,7 @@ bool EditableWidget::tryInsertChar(char c, int pos) { if(_filter(tolower(c))) { + killSelectedText(); _editString.insert(pos, 1, c); myUndoHandler->doChar(); // aggregate single chars return true; @@ -105,7 +106,7 @@ bool EditableWidget::handleText(char text) if(tryInsertChar(text, _caretPos)) { _caretPos++; - _selectSize = 0; + //_selectSize = 0; sendCommand(EditableWidget::kChangedCmd, 0, _id); setDirty(); return true; @@ -119,94 +120,139 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) if(!_editable) return true; - // Ignore all alt-mod keys - if(StellaModTest::isAlt(mod)) - return true; - - // Handle Control and Control-Shift keys - if(StellaModTest::isControl(mod) && handleControlKeys(key, mod)) - return true; - - // Handle Shift keys - if(StellaModTest::isShift(mod) && handleShiftKeys(key)) - return true; - - // Handle keys without modifiers - return handleNormalKeys(key); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) -{ - bool shift = StellaModTest::isShift(mod); bool handled = true; + Event::Type event = instance().eventHandler().eventForKey(EventMode::kEditMode, key, mod); - switch(key) + switch(event) { - case KBDK_A: + case Event::MoveLeftChar: + if(_selectSize) + handled = setCaretPos(selectStartPos()); + else if(_caretPos > 0) + handled = setCaretPos(_caretPos - 1); + _selectSize = 0; + break; + + case Event::MoveRightChar: + if(_selectSize) + handled = setCaretPos(selectEndPos()); + else if(_caretPos < int(_editString.size())) + handled = setCaretPos(_caretPos + 1); + _selectSize = 0; + break; + + case Event::MoveLeftWord: + handled = moveWord(-1, false); + _selectSize = 0; + break; + + case Event::MoveRightWord: + handled = moveWord(+1, false); + _selectSize = 0; + break; + + case Event::MoveHome: + handled = setCaretPos(0); + _selectSize = 0; + break; + + case Event::MoveEnd: + handled = setCaretPos(int(_editString.size())); + _selectSize = 0; + break; + + case Event::SelectLeftChar: + if(_caretPos > 0) + handled = moveCaretPos(-1); + break; + + case Event::SelectRightChar: + if(_caretPos < int(_editString.size())) + handled = moveCaretPos(+1); + break; + + case Event::SelectLeftWord: + handled = moveWord(-1, true); + break; + + case Event::SelectRightWord: + handled = moveWord(+1, true); + break; + + case Event::SelectHome: + handled = moveCaretPos(-_caretPos); + break; + + case Event::SelectEnd: + handled = moveCaretPos(int(_editString.size()) - _caretPos); + break; + + case Event::SelectAll: if(setCaretPos(int(_editString.size()))) _selectSize = -int(_editString.size()); break; - case KBDK_C: - case KBDK_INSERT: - handled = copySelectedText(); + case Event::Delete: + handled = killSelectedText(); + if(!handled) + handled = killChar(+1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - //case KBDK_E: - // if(shift) - // _selectSize += _caretPos - int(_editString.size()); - // else - // _selectSize = 0; - // setCaretPos(int(_editString.size())); - // break; - - case KBDK_D: + case Event::DeleteChar: handled = killChar(+1); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case KBDK_K: - handled = killLine(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_U: - handled = killLine(-1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_V: - handled = pasteSelectedText(); - if(handled) - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_W: + case Event::DeleteWord: handled = killLastWord(); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case KBDK_X: + case Event::DeleteEnd: + handled = killLine(+1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case Event::DeleteHome: + handled = killLine(-1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case Event::Backspace: + handled = killSelectedText(); + if(!handled) + handled = killChar(-1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case Event::Cut: handled = cutSelectedText(); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case KBDK_Y: - case KBDK_Z: + case Event::Copy: + handled = copySelectedText(); + break; + + case Event::Paste: + handled = pasteSelectedText(); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case Event::Undo: + case Event::Redo: { string oldString = _editString; myUndoHandler->endChars(_editString); // Reverse Y and Z for QWERTZ keyboards - if(key == KBDK_Y != instance().eventHandler().isQwertz()) + if(event == Event::Redo != instance().eventHandler().isQwertz()) handled = myUndoHandler->redo(_editString); else - if(shift) - handled = myUndoHandler->redo(_editString); - else - handled = myUndoHandler->undo(_editString); + handled = myUndoHandler->undo(_editString); if(handled) { @@ -219,152 +265,20 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) break; } - case KBDK_LEFT: - handled = moveWord(-1, shift); - if(!shift) - _selectSize = 0; - break; - - case KBDK_RIGHT: - handled = moveWord(+1, shift); - if(!shift) - _selectSize = 0; - break; - - default: - handled = false; - } - - if(handled) - { - myUndoHandler->endChars(_editString); - setDirty(); - } - - return handled; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::handleShiftKeys(StellaKey key) -{ - bool handled = true; - - switch(key) - { - case KBDK_DELETE: - case KBDK_KP_PERIOD: - handled = cutSelectedText(); - if(handled) - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_INSERT: - handled = pasteSelectedText(); - if(handled) - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_LEFT: - if(_caretPos > 0) - handled = moveCaretPos(-1); - break; - - case KBDK_RIGHT: - if(_caretPos < int(_editString.size())) - handled = moveCaretPos(+1); - break; - - case KBDK_HOME: - handled = moveCaretPos(-_caretPos); - break; - - case KBDK_END: - handled = moveCaretPos(int(_editString.size()) - _caretPos); - break; - - - default: - handled = false; - } - - if(handled) - { - myUndoHandler->endChars(_editString); - setDirty(); - } - - return handled; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::handleNormalKeys(StellaKey key) -{ - bool selectMode = false; - bool handled = true; - - switch(key) - { - case KBDK_LSHIFT: - case KBDK_RSHIFT: - case KBDK_LCTRL: - case KBDK_RCTRL: - // stay in select mode - selectMode = _selectSize; - handled = false; - break; - - case KBDK_RETURN: - case KBDK_KP_ENTER: + case Event::EndEdit: // confirm edit and exit editmode endEditMode(); sendCommand(EditableWidget::kAcceptCmd, 0, _id); break; - case KBDK_ESCAPE: + case Event::AbortEdit: abortEditMode(); sendCommand(EditableWidget::kCancelCmd, 0, _id); break; - case KBDK_BACKSPACE: - handled = killSelectedText(); - if(!handled) - handled = killChar(-1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_DELETE: - case KBDK_KP_PERIOD: - handled = killSelectedText(); - if(!handled) - handled = killChar(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_LEFT: - if(_selectSize) - handled = setCaretPos(selectStartPos()); - else if(_caretPos > 0) - handled = setCaretPos(_caretPos - 1); - break; - - case KBDK_RIGHT: - if(_selectSize) - handled = setCaretPos(selectEndPos()); - else if(_caretPos < int(_editString.size())) - handled = setCaretPos(_caretPos + 1); - break; - - case KBDK_HOME: - handled = setCaretPos(0); - break; - - case KBDK_END: - handled = setCaretPos(int(_editString.size())); - break; - default: - killSelectedText(); handled = false; + break; } if(handled) @@ -372,8 +286,6 @@ bool EditableWidget::handleNormalKeys(StellaKey key) myUndoHandler->endChars(_editString); setDirty(); } - if(!selectMode) - _selectSize = 0; return handled; } diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 66c8dc20e..6c3a1bda1 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -87,9 +87,6 @@ class EditableWidget : public Widget, public CommandSender private: // Line editing - bool handleControlKeys(StellaKey key, StellaMod mod); - bool handleShiftKeys(StellaKey key); - bool handleNormalKeys(StellaKey key); bool killChar(int direction, bool addEdit = true); bool killLine(int direction); bool killLastWord();