[Scummvm-git-logs] scummvm master -> 595a3d77241f51a6218f51d5570edbf72d548d40
sev-
noreply at scummvm.org
Tue Oct 24 17:01:16 UTC 2023
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
595a3d7724 GUI: Use Keymapper for EditableWidget
Commit: 595a3d77241f51a6218f51d5570edbf72d548d40
https://github.com/scummvm/scummvm/commit/595a3d77241f51a6218f51d5570edbf72d548d40
Author: Kurian Jojo (kurianjojo2004 at gmail.com)
Date: 2023-10-24T19:01:12+02:00
Commit Message:
GUI: Use Keymapper for EditableWidget
Changed paths:
backends/keymapper/standard-actions.cpp
backends/keymapper/standard-actions.h
gui/dialog.cpp
gui/dialog.h
gui/gui-manager.cpp
gui/gui-manager.h
gui/widget.h
gui/widgets/editable.cpp
gui/widgets/editable.h
diff --git a/backends/keymapper/standard-actions.cpp b/backends/keymapper/standard-actions.cpp
index dda9a7f80b1..e8b440eaf99 100644
--- a/backends/keymapper/standard-actions.cpp
+++ b/backends/keymapper/standard-actions.cpp
@@ -38,5 +38,8 @@ const char *kStandardActionLoad = "LOAD";
const char *kStandardActionSave = "SAVE";
const char *kStandardActionOpenSettings = "OPTS";
const char *kStandardActionEE = "WTF";
+const char *kStandardActionCut = "CUT";
+const char *kStandardActionCopy = "COPY";
+const char *kStandardActionPaste = "PASTE";
} //namespace Common
diff --git a/backends/keymapper/standard-actions.h b/backends/keymapper/standard-actions.h
index a397386b4ff..da996021f26 100644
--- a/backends/keymapper/standard-actions.h
+++ b/backends/keymapper/standard-actions.h
@@ -52,6 +52,9 @@ extern const char *kStandardActionLoad;
extern const char *kStandardActionSave;
extern const char *kStandardActionOpenSettings;
extern const char *kStandardActionEE;
+extern const char *kStandardActionCut;
+extern const char *kStandardActionCopy;
+extern const char *kStandardActionPaste;
} //namespace Common
diff --git a/gui/dialog.cpp b/gui/dialog.cpp
index dfda0bbf71b..0dd3a821cde 100644
--- a/gui/dialog.cpp
+++ b/gui/dialog.cpp
@@ -374,6 +374,11 @@ void Dialog::handleTickle() {
_tickleWidget->handleTickle();
}
+void Dialog::handleOtherEvent(const Common::Event &evt) {
+ if (_focusedWidget)
+ _focusedWidget->handleOtherEvent(evt);
+}
+
void Dialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kCloseCmd:
diff --git a/gui/dialog.h b/gui/dialog.h
index bcd0cf2fb82..2a60987b829 100644
--- a/gui/dialog.h
+++ b/gui/dialog.h
@@ -113,7 +113,7 @@ protected:
virtual void handleKeyUp(Common::KeyState state);
virtual void handleMouseMoved(int x, int y, int button);
virtual void handleMouseLeft(int button) {}
- virtual void handleOtherEvent(const Common::Event &evt) {}
+ virtual void handleOtherEvent(const Common::Event &evt);
void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) override;
Widget *findWidget(int x, int y); // Find the widget at pos x,y if any
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index ae946f62d19..765048b237f 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -191,6 +191,96 @@ Common::Keymap *GuiManager::getKeymap() const {
act->allowKbdRepeats();
guiMap->addAction(act);
+ act = new Action("ENTER", _("New Line"));
+ act->setCustomEngineActionEvent(kActionEnter);
+ act->addDefaultInputMapping("RETURN");
+ act->addDefaultInputMapping("KP_ENTER");
+ act->allowKbdRepeats();
+ guiMap->addAction(act);
+
+ act = new Action("ESC", _("Close Dialog"));
+ act->setCustomEngineActionEvent(kActionEscape);
+ act->addDefaultInputMapping("ESCAPE");
+ guiMap->addAction(act);
+
+ act = new Action("BACKSPACE", _("Backspace"));
+ act->setCustomEngineActionEvent(kActionBackspace);
+ act->addDefaultInputMapping("BACKSPACE");
+ act->allowKbdRepeats();
+ guiMap->addAction(act);
+
+ act = new Action("DEL", _("Delete Character"));
+ act->setCustomEngineActionEvent(kActionDelete);
+ act->addDefaultInputMapping("DELETE");
+ act->allowKbdRepeats();
+ guiMap->addAction(act);
+
+ act = new Action("END", _("Go to end of line"));
+ act->setCustomEngineActionEvent(kActionEnd);
+
+#ifdef MACOSX
+ act->addDefaultInputMapping("C+e");
+#endif
+
+ act->addDefaultInputMapping("DOWN");
+ act->addDefaultInputMapping("END");
+ guiMap->addAction(act);
+
+ act = new Action("CHAR_LEFT", _("Move cursor left"));
+ act->setCustomEngineActionEvent(kActionLeft);
+ act->addDefaultInputMapping("LEFT");
+ act->allowKbdRepeats();
+ guiMap->addAction(act);
+
+ act = new Action("CHAR_RIGHT", _("Move cursor right"));
+ act->setCustomEngineActionEvent(kActionRight);
+ act->addDefaultInputMapping("RIGHT");
+ act->allowKbdRepeats();
+ guiMap->addAction(act);
+
+ act = new Action("HOME", _("Go to start of line"));
+ act->setCustomEngineActionEvent(kActionHome);
+
+#ifdef MACOSX
+ act->addDefaultInputMapping("C+a");
+#endif
+
+ act->addDefaultInputMapping("UP");
+ act->addDefaultInputMapping("HOME");
+ guiMap->addAction(act);
+
+#ifdef MACOSX
+ act = new Action(kStandardActionCut, _("Cut"));
+ act->setCustomEngineActionEvent(kActionCut);
+ act->addDefaultInputMapping("M+x");
+ guiMap->addAction(act);
+
+ act = new Action(kStandardActionPaste, _("Paste"));
+ act->setCustomEngineActionEvent(kActionPaste);
+ act->addDefaultInputMapping("M+v");
+ guiMap->addAction(act);
+
+ act = new Action(kStandardActionCopy, _("Copy"));
+ act->setCustomEngineActionEvent(kActionCopy);
+ act->addDefaultInputMapping("M+c");
+ guiMap->addAction(act);
+#else
+ act = new Action(kStandardActionCut, _("Cut"));
+ act->setCustomEngineActionEvent(kActionCut);
+ act->addDefaultInputMapping("C+x");
+ guiMap->addAction(act);
+
+ act = new Action(kStandardActionPaste, _("Paste"));
+ act->setCustomEngineActionEvent(kActionPaste);
+ act->addDefaultInputMapping("C+v");
+ guiMap->addAction(act);
+
+ act = new Action(kStandardActionCopy, _("Copy"));
+ act->setCustomEngineActionEvent(kActionCopy);
+ act->addDefaultInputMapping("C+c");
+ guiMap->addAction(act);
+#endif
+
act = new Action(kStandardActionEE, _("???"));
act->setKeyEvent(KEYCODE_v);
guiMap->addAction(act);
@@ -758,7 +848,6 @@ void GuiManager::processEvent(const Common::Event &event, Dialog *const activeDi
if (g_gui.useRTL()) {
mouse.x = g_system->getOverlayWidth() - event.mouse.x - activeDialog->_x + g_gui.getOverlayOffset();
}
-
switch (event.type) {
case Common::EVENT_KEYDOWN:
activeDialog->handleKeyDown(event.kbd);
diff --git a/gui/gui-manager.h b/gui/gui-manager.h
index 544c43bffb3..6ea98e604bc 100644
--- a/gui/gui-manager.h
+++ b/gui/gui-manager.h
@@ -46,6 +46,20 @@ namespace Common {
namespace GUI {
+enum {
+ kActionEnter,
+ kActionEscape,
+ kActionBackspace,
+ kActionDelete,
+ kActionEnd,
+ kActionLeft,
+ kActionRight,
+ kActionHome,
+ kActionCopy,
+ kActionCut,
+ kActionPaste,
+};
+
enum {
kIconsSetLoadedCmd = 'icns'
};
diff --git a/gui/widget.h b/gui/widget.h
index a7c8ce22c67..1c0e825967f 100644
--- a/gui/widget.h
+++ b/gui/widget.h
@@ -33,6 +33,7 @@
#include "common/text-to-speech.h"
#include "common/system.h"
#include "common/config-manager.h"
+#include "common/events.h"
namespace GUI {
@@ -144,6 +145,7 @@ public:
void handleMouseWheel(int x, int y, int direction) override { assert(_boss); _boss->handleMouseWheel(x, y, direction); }
virtual bool handleKeyDown(Common::KeyState state) { return false; } // Return true if the event was handled
virtual bool handleKeyUp(Common::KeyState state) { return false; } // Return true if the event was handled
+ virtual void handleOtherEvent(const Common::Event &evt) {}
virtual void handleTickle() {}
/** Mark the widget and its children as dirty so they are redrawn on the next screen update */
diff --git a/gui/widgets/editable.cpp b/gui/widgets/editable.cpp
index 82d4a386eac..0ab17c83dd6 100644
--- a/gui/widgets/editable.cpp
+++ b/gui/widgets/editable.cpp
@@ -209,7 +209,6 @@ bool EditableWidget::handleKeyDown(Common::KeyState state) {
bool handled = true;
bool dirty = false;
bool forcecaret = false;
- int deleteIndex;
if (!isEnabled())
return false;
@@ -242,123 +241,218 @@ bool EditableWidget::handleKeyDown(Common::KeyState state) {
state.keycode = remap[state.keycode - Common::KEYCODE_KP0];
}
- switch (state.keycode) {
- case Common::KEYCODE_RETURN:
- case Common::KEYCODE_KP_ENTER:
- // confirm edit and exit editmode
- endEditMode();
- dirty = true;
- break;
+ defaultKeyDownHandler(state, dirty, forcecaret, handled);
- case Common::KEYCODE_ESCAPE:
- abortEditMode();
- dirty = true;
- break;
+ if (dirty)
+ markAsDirty();
- case Common::KEYCODE_BACKSPACE:
- deleteIndex = caretLogicalPos();
- if (deleteIndex > 0 && _selOffset == 0) {
- deleteIndex--;
- _editString.deleteChar(deleteIndex);
- setCaretPos(caretVisualPos(deleteIndex));
- _selCaretPos = -1;
- dirty = true;
+ if (forcecaret)
+ makeCaretVisible();
+
+ return handled;
+}
- sendCommand(_cmd, 0);
- } else if (deleteIndex >= 0 && _selOffset != 0) {
+void EditableWidget::defaultKeyDownHandler(Common::KeyState &state, bool &dirty, bool &forcecaret, bool &handled) {
+ if (isCharAllowed(state.ascii)) {
+ // Incase of a selection, replace the selection with the character
+ if (_selCaretPos >= 0) {
int selBegin = _selCaretPos;
int selEnd = _selCaretPos + _selOffset;
if (selBegin > selEnd)
SWAP(selBegin, selEnd);
- _editString.erase(selBegin, selEnd - selBegin);
+ _editString.replace(selBegin, selEnd - selBegin, Common::U32String(state.ascii));
+ if (_editString.size() > 0)
+ selBegin++;
setCaretPos(caretVisualPos(selBegin));
_selCaretPos = -1;
_selOffset = 0;
- dirty = true;
-
- sendCommand(_cmd, 0);
+ } else {
+ // Insert char normally at caretPos
+ const int logicalPosition = caretLogicalPos();
+ _editString.insertChar(state.ascii, logicalPosition);
+ setCaretPos(caretVisualPos(logicalPosition + 1));
}
+ dirty = true;
forcecaret = true;
- break;
+ sendCommand(_cmd, 0);
+ } else {
+ handled = false;
+ }
+}
- case Common::KEYCODE_DELETE:
- deleteIndex = caretLogicalPos();
- if (deleteIndex < (int)_editString.size()) {
- _editString.deleteChar(deleteIndex);
- setCaretPos(caretVisualPos(deleteIndex));
- _selCaretPos = -1;
- _selOffset = 0;
+void EditableWidget::handleOtherEvent(const Common::Event &evt) {
+ bool dirty = false;
+ bool forcecaret = false;
+ int deleteIndex;
+
+ if (!isEnabled())
+ return;
+
+ // First remove caret
+ if (_caretVisible)
+ drawCaret(true);
+
+ switch (evt.type) {
+ case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
+ switch (evt.customType) {
+ case kActionEnter:
+ endEditMode();
dirty = true;
+ break;
- sendCommand(_cmd, 0);
- }
- forcecaret = true;
- break;
+ case kActionEscape:
+ abortEditMode();
+ dirty = true;
+ break;
- case Common::KEYCODE_DOWN:
- case Common::KEYCODE_END:
- // Move caret to end
- setCaretPos(caretVisualPos(_editString.size()));
- if (state.hasFlags(Common::KBD_SHIFT))
- setSelectionOffset(_editString.size() - _selCaretPos);
- else
- clearSelection();
- forcecaret = true;
- dirty = true;
- break;
+ case kActionBackspace:
+ deleteIndex = caretLogicalPos();
+ if (deleteIndex > 0 && _selOffset == 0) {
+ deleteIndex--;
+ _editString.deleteChar(deleteIndex);
+ setCaretPos(caretVisualPos(deleteIndex));
+ _selCaretPos = -1;
+ dirty = true;
- case Common::KEYCODE_LEFT:
- if (state.hasFlags(Common::KBD_SHIFT)) {
- if (_disableSelection)
- break;
- if (_selCaretPos < 0)
- _selCaretPos = _caretPos;
- if (_caretPos > 0)
- _selOffset--;
- } else {
- clearSelection();
- }
- // Move caret one left (if possible)
- if (_caretPos > 0) {
- dirty = setCaretPos(_caretPos - 1);
- }
- forcecaret = true;
- dirty = true;
- break;
+ sendCommand(_cmd, 0);
+ } else if (deleteIndex >= 0 && _selOffset != 0) {
+ int selBegin = _selCaretPos;
+ int selEnd = _selCaretPos + _selOffset;
+ if (selBegin > selEnd)
+ SWAP(selBegin, selEnd);
+ _editString.erase(selBegin, selEnd - selBegin);
+ setCaretPos(caretVisualPos(selBegin));
+ _selCaretPos = -1;
+ _selOffset = 0;
+ dirty = true;
- case Common::KEYCODE_RIGHT:
- if (state.hasFlags(Common::KBD_SHIFT)) {
- if (_disableSelection)
- break;
- if (_selCaretPos < 0)
- _selCaretPos = _caretPos;
- if (_selOffset + _selCaretPos < (int)_editString.size())
- _selOffset++;
- } else {
- clearSelection();
- }
- // Move caret one right (if possible)
- if (_caretPos < (int)_editString.size()) {
- dirty = setCaretPos(_caretPos + 1);
- }
- forcecaret = true;
- dirty = true;
- break;
+ sendCommand(_cmd, 0);
+ }
+ forcecaret = true;
+ break;
- case Common::KEYCODE_UP:
- case Common::KEYCODE_HOME:
- // Move caret to start
- setCaretPos(caretVisualPos(0));
- if (state.hasFlags(Common::KBD_SHIFT))
- setSelectionOffset(0 - _selCaretPos);
- else
- clearSelection();
- forcecaret = true;
- dirty = true;
- break;
+ case kActionDelete:
+ deleteIndex = caretLogicalPos();
+ if (deleteIndex >= 0 && _selOffset == 0) {
+ _editString.deleteChar(deleteIndex);
+ setCaretPos(caretVisualPos(deleteIndex));
+ _selCaretPos = -1;
+ dirty = true;
+
+ sendCommand(_cmd, 0);
+ } else if (deleteIndex >= 0 && _selOffset != 0) {
+ int selBegin = _selCaretPos;
+ int selEnd = _selCaretPos + _selOffset;
+ if (selBegin > selEnd)
+ SWAP(selBegin, selEnd);
+ _editString.erase(selBegin, selEnd - selBegin);
+ setCaretPos(caretVisualPos(selBegin));
+ _selCaretPos = -1;
+ _selOffset = 0;
+ dirty = true;
+ }
+ forcecaret = true;
+ break;
+
+ case kActionEnd:
+ if (_shiftPressed) {
+ if (_selCaretPos < 0)
+ _selCaretPos = _caretPos;
+
+ setSelectionOffset(_editString.size() - _selCaretPos);
+ } else {
+ clearSelection();
+ }
- case Common::KEYCODE_v:
- if (state.flags & Common::KBD_CTRL) {
+ // Move caret to end
+ setCaretPos(caretVisualPos(_editString.size()));
+
+ forcecaret = true;
+ dirty = true;
+ break;
+
+ case kActionLeft:
+ if (_shiftPressed) {
+ if (_disableSelection)
+ break;
+ if (_selCaretPos < 0)
+ _selCaretPos = _caretPos;
+ if (_caretPos > 0)
+ _selOffset--;
+ } else {
+ clearSelection();
+ }
+ // Move caret one left (if possible)
+ if (_caretPos > 0) {
+ dirty = setCaretPos(_caretPos - 1);
+ }
+ forcecaret = true;
+ dirty = true;
+ break;
+
+ case kActionRight:
+ if (_shiftPressed) {
+ if (_disableSelection)
+ break;
+ if (_selCaretPos < 0)
+ _selCaretPos = _caretPos;
+ if (_selOffset + _selCaretPos < (int)_editString.size())
+ _selOffset++;
+ } else {
+ clearSelection();
+ }
+ // Move caret one right (if possible)
+ if (_caretPos < (int)_editString.size()) {
+ dirty = setCaretPos(_caretPos + 1);
+ }
+ forcecaret = true;
+ dirty = true;
+ break;
+
+ case kActionHome:
+ if (_shiftPressed) {
+ if (_selCaretPos < 0)
+ _selCaretPos = _caretPos;
+ setSelectionOffset(0 - _selCaretPos);
+ } else {
+ clearSelection();
+ }
+ // Move caret to start
+ setCaretPos(caretVisualPos(0));
+
+ forcecaret = true;
+ dirty = true;
+ break;
+
+ case kActionCut:
+ if (!getEditString().empty() && _selOffset != 0) {
+ int selBegin = _selCaretPos;
+ int selEnd = _selCaretPos + _selOffset;
+ if (selBegin > selEnd)
+ SWAP(selBegin, selEnd);
+ const Common::U32String selected(getEditString().begin() + selBegin, getEditString().begin() + selEnd);
+ g_system->setTextInClipboard(selected);
+
+ _editString.erase(selBegin, selEnd - selBegin);
+ setCaretPos(caretVisualPos(selBegin));
+ _selCaretPos = -1;
+ _selOffset = 0;
+ dirty = true;
+ }
+ break;
+
+ case kActionCopy:
+ if (!getEditString().empty()) {
+ int selBegin = _selCaretPos;
+ int selEnd = _selCaretPos + _selOffset;
+ if (selBegin > selEnd)
+ SWAP(selBegin, selEnd);
+ const Common::U32String selected(getEditString().begin() + selBegin, getEditString().begin() + selEnd);
+ g_system->setTextInClipboard(selected);
+ }
+ break;
+
+ case kActionPaste:
if (g_system->hasTextInClipboard()) {
Common::U32String text = g_system->getTextFromClipboard();
if (_selOffset != 0) {
@@ -373,69 +467,19 @@ bool EditableWidget::handleKeyDown(Common::KeyState state) {
clearSelection();
} else {
for (uint32 i = 0; i < text.size(); ++i) {
- const int logicalPosition = caretLogicalPos();
- if (tryInsertChar(text[i], logicalPosition))
- setCaretPos(caretVisualPos(logicalPosition + 1));
+ const int logicalPosition = caretLogicalPos();
+ if (tryInsertChar(text[i], logicalPosition))
+ setCaretPos(caretVisualPos(logicalPosition + 1));
}
}
dirty = true;
}
- } else {
- defaultKeyDownHandler(state, dirty, forcecaret, handled);
- }
- break;
-
- case Common::KEYCODE_c:
- if (state.flags & Common::KBD_CTRL) {
- if (!getEditString().empty()) {
- int selBegin = _selCaretPos;
- int selEnd = _selCaretPos + _selOffset;
- if (selBegin > selEnd)
- SWAP(selBegin, selEnd);
- const Common::U32String selected(getEditString().begin() + selBegin, getEditString().begin() + selEnd);
- g_system->setTextInClipboard(selected);
- }
- } else {
- defaultKeyDownHandler(state, dirty, forcecaret, handled);
- }
- break;
-
-#ifdef MACOSX
- // Let ctrl-a / ctrl-e move the caret to the start / end of the line.
- //
- // These shortcuts go back a long time for command line programs. As
- // for edit fields in GUIs, they are supported natively on macOS,
- // which is why I enabled these shortcuts there.
- // On other systems (Windows, Gnome), Ctrl-A by default means
- // "select all", which is why I didn't enable the shortcuts there
- // for now, to avoid potential confusion.
- //
- // But since we don't support text selection, and since at least Gnome
- // can be configured to also support ctrl-a and ctrl-e, we may want
- // to extend this code to other targets, maybe even all. I'll leave
- // this to other porters to decide, though.
- case Common::KEYCODE_a:
- case Common::KEYCODE_e:
- if (state.flags & Common::KBD_CTRL) {
- if (state.keycode == Common::KEYCODE_a) {
- // Move caret to start
- dirty = setCaretPos(0);
- forcecaret = true;
- } else if (state.keycode == Common::KEYCODE_e) {
- // Move caret to end
- dirty = setCaretPos(_editString.size());
- forcecaret = true;
- }
- clearSelection();
break;
- } else {
- defaultKeyDownHandler(state, dirty, forcecaret, handled);
- }
- break;
-#endif
-
+ default:
+ break;
+ }
default:
- defaultKeyDownHandler(state, dirty, forcecaret, handled);
+ break;
}
if (dirty)
@@ -443,36 +487,6 @@ bool EditableWidget::handleKeyDown(Common::KeyState state) {
if (forcecaret)
makeCaretVisible();
-
- return handled;
-}
-
-void EditableWidget::defaultKeyDownHandler(Common::KeyState &state, bool &dirty, bool &forcecaret, bool &handled) {
- if (isCharAllowed(state.ascii)) {
- // Incase of a selection, replace the selection with the character
- if (_selCaretPos >= 0) {
- int selBegin = _selCaretPos;
- int selEnd = _selCaretPos + _selOffset;
- if (selBegin > selEnd)
- SWAP(selBegin, selEnd);
- _editString.replace(selBegin, selEnd - selBegin, Common::U32String(state.ascii));
- if(_editString.size() > 0)
- selBegin++;
- setCaretPos(caretVisualPos(selBegin));
- _selCaretPos = -1;
- _selOffset = 0;
- } else {
- // Insert char normally at caretPos
- const int logicalPosition = caretLogicalPos();
- _editString.insertChar(state.ascii, logicalPosition);
- setCaretPos(caretVisualPos(logicalPosition + 1));
- }
- dirty = true;
- forcecaret = true;
- sendCommand(_cmd, 0);
- } else {
- handled = false;
- }
}
int EditableWidget::getCaretOffset() const {
diff --git a/gui/widgets/editable.h b/gui/widgets/editable.h
index b66d7085f0d..575eb5fd497 100644
--- a/gui/widgets/editable.h
+++ b/gui/widgets/editable.h
@@ -82,6 +82,7 @@ public:
void handleMouseMoved(int x, int y, int button) override;
bool handleKeyDown(Common::KeyState state) override;
bool handleKeyUp(Common::KeyState state) override;
+ void handleOtherEvent(const Common::Event& evt) override;
void reflowLayout() override;
bool setCaretPos(int newPos);
More information about the Scummvm-git-logs
mailing list