mirror of https://github.com/stella-emu/stella.git
refactored EditableWidget to use events instead of scancodes (TODO: text, MacOS keys)
This commit is contained in:
parent
d0d55a8fec
commit
9bb30a9bc2
|
@ -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},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -2830,3 +2830,8 @@ const Event::EventSet EventHandler::DebugEvents = {
|
|||
Event::ToggleColorLoss,
|
||||
Event::ToggleJitter,
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const Event::EventSet EventHandler::EditEvents = {
|
||||
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue