[Scummvm-git-logs] scummvm master -> 7ab57607da9e07d07a248468176ed7289a82980e

mduggan noreply at scummvm.org
Fri Jul 12 12:03:28 UTC 2024


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:
7ab57607da DGDS: Add keyboard navigation for menus


Commit: 7ab57607da9e07d07a248468176ed7289a82980e
    https://github.com/scummvm/scummvm/commit/7ab57607da9e07d07a248468176ed7289a82980e
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-07-12T22:01:04+10:00

Commit Message:
DGDS: Add keyboard navigation for menus

Also add ability to select dialog options on keyboard.

Changed paths:
    engines/dgds/dgds.cpp
    engines/dgds/menu.cpp
    engines/dgds/menu.h
    engines/dgds/metaengine.cpp
    engines/dgds/request.cpp
    engines/dgds/request.h
    engines/dgds/scene.cpp
    engines/dgds/scene.h


diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index 2d87a9b4796..e7d4730b4a5 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -436,10 +436,20 @@ Common::Error DgdsEngine::run() {
 					warning("TODO: Implement kDgdsKeyPrevItem");
 					break;
 				case kDgdsKeyPickUp:
-					warning("TODO: Implement kDgdsKeyPickUp");
+					if (_menu->menuShown())
+						_menu->activateChoice();
+					else if (_scene->hasVisibleDialog())
+						_scene->activateChoice();
+					else
+						warning("TODO: Implement kDgdsKeyPickUp");
 					break;
 				case kDgdsKeyLook:
-					warning("TODO: Implement kDgdsKeyLook");
+					if (_menu->menuShown())
+						_menu->activateChoice();
+					else if (_scene->hasVisibleDialog())
+						_scene->activateChoice();
+					else
+						warning("TODO: Implement kDgdsKeyLook");
 					break;
 				case kDgdsKeyActivate:
 					warning("TODO: Implement kDgdsKeyActivate");
diff --git a/engines/dgds/menu.cpp b/engines/dgds/menu.cpp
index b402af9b0e8..9a9887dd00b 100644
--- a/engines/dgds/menu.cpp
+++ b/engines/dgds/menu.cpp
@@ -115,7 +115,7 @@ enum MenuButtonIds {
 	kMenuGameOverRestore = 170,
 };
 
-Menu::Menu() : _curMenu(kMenuNone), _dragGadget(nullptr) {
+Menu::Menu() : _curMenu(kMenuNone), _dragGadget(nullptr), _selectedItem(0), _numSelectable(0) {
 	_screenBuffer.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
 }
 
@@ -207,14 +207,20 @@ void Menu::drawMenu(MenuId menu) {
 	managed.blitFrom(*screen);
 	_menuRequests[_curMenu].drawBg(&managed);
 
+	_numSelectable = 0;
 	for (Common::SharedPtr<Gadget> &gptr : gadgets) {
 		Gadget *gadget = gptr.get();
 		if (gadget->_gadgetType == kGadgetButton || gadget->_gadgetType == kGadgetSlider) {
 			if (firstDraw)
 				configureGadget(menu, gadget);
 			gadget->draw(&managed);
+			_numSelectable++;
 		}
 	}
+	if (firstDraw) {
+		_selectedItem = _numSelectable - 1;
+		putMouseOnSelectedItem();
+	}
 
 	drawMenuText(managed);
 
@@ -225,6 +231,32 @@ void Menu::drawMenu(MenuId menu) {
 	g_system->updateScreen();
 }
 
+Gadget *Menu::getSelectedItem() {
+	int item = 0;
+	Common::Array<Common::SharedPtr<Gadget> > gadgets = _menuRequests[_curMenu]._gadgets;
+	for (Common::SharedPtr<Gadget> &gptr : gadgets) {
+		Gadget *gadget = gptr.get();
+		if (gadget->_gadgetType == kGadgetButton || gadget->_gadgetType == kGadgetSlider) {
+			if (item == _selectedItem)
+				return gadget;
+			item++;
+		}
+	}
+	return nullptr;
+}
+
+void Menu::putMouseOnSelectedItem() {
+	Gadget *selected = getSelectedItem();
+	if (!selected)
+		return;
+
+	const Common::Point midPt = selected->midPoint();
+	// put the mouse on the first button/slider
+	g_system->warpMouse(midPt.x, midPt.y);
+	return;
+}
+
+
 void Menu::drawMenuText(Graphics::ManagedSurface &dst) {
 	Common::Array<Common::SharedPtr<Gadget> > gadgets = _menuRequests[_curMenu]._gadgets;
 	Common::Array<TextItem> textItems = _menuRequests[_curMenu]._textItemList;
@@ -548,13 +580,30 @@ void Menu::toggleGadget(int16 gadgetId, bool enable) {
 	}
 }
 
-void Menu::prevChoice() {
-	warning("TODO: Implement Menu::prevChoice");
+/**
+ * Choose the next menu item via keyboard - items are numbered backwards
+ * so this *decreases* the counter.
+ */
+void Menu::nextChoice() {
+	_selectedItem--;
+	if (_selectedItem < 0)
+		_selectedItem = _numSelectable - 1;
+	putMouseOnSelectedItem();
 }
 
-void Menu::nextChoice() {
-	warning("TODO: Implement Menu::nextChoice");
+void Menu::prevChoice() {
+	_selectedItem++;
+	if (_selectedItem >= _numSelectable)
+		_selectedItem = 0;
+	putMouseOnSelectedItem();
 }
 
+void Menu::activateChoice() {
+	Gadget *selected = getSelectedItem();
+	if (!selected)
+		return;
+
+	handleClick(selected->midPoint());
+}
 
 } // End of namespace Dgds
diff --git a/engines/dgds/menu.h b/engines/dgds/menu.h
index acb057b24f6..25a499de670 100644
--- a/engines/dgds/menu.h
+++ b/engines/dgds/menu.h
@@ -90,6 +90,7 @@ public:
 	void setRequestData(const REQFileData &data);
 	void prevChoice();
 	void nextChoice();
+	void activateChoice();
 
 private:
 	Gadget *getClickedMenuItem(const Common::Point &mouseClick);
@@ -101,10 +102,15 @@ private:
 	void handleClickOptionsMenu(const Common::Point &mouse);
 	void handleClickSkipPlayIntroMenu(const Common::Point &mouse);
 
+	void putMouseOnSelectedItem();
+	Gadget *getSelectedItem();
+
 	Common::HashMap<int, RequestData> _menuRequests;
 
 	SliderGadget *_dragGadget;
 	Common::Point _dragStartPt;
+	int _selectedItem;
+	int _numSelectable;
 };
 
 } // End of namespace Dgds
diff --git a/engines/dgds/metaengine.cpp b/engines/dgds/metaengine.cpp
index 72aed1df36f..b9418f80b5f 100644
--- a/engines/dgds/metaengine.cpp
+++ b/engines/dgds/metaengine.cpp
@@ -79,7 +79,7 @@ Common::KeymapArray DgdsMetaEngine::initKeymaps(const char *target) const {
 		{ Dgds::kDgdsKeyNextItem, "NEXT_ITEM", _("Next object"), "TAB", "w" },
 		{ Dgds::kDgdsKeyPrevItem, "PREV_ITEM", _("Previous object"), "S+TAB", "q" },
 		{ Dgds::kDgdsKeyPickUp, "PICK_UP", _("Pick up / Operate"), "SPACE", "KP5" },
-		{ Dgds::kDgdsKeyLook, "LOOK", _("Look"), "ENTER", "," },
+		{ Dgds::kDgdsKeyLook, "LOOK", _("Look"), "RETURN", "," },
 		{ Dgds::kDgdsKeyActivate, "ACTIVATE", _("Activate Inventory Object"), "BACKSPACE", nullptr },
 	};
 
diff --git a/engines/dgds/request.cpp b/engines/dgds/request.cpp
index 1011fdada56..a83f05a5c23 100644
--- a/engines/dgds/request.cpp
+++ b/engines/dgds/request.cpp
@@ -306,6 +306,10 @@ Common::Point Gadget::topLeft() const {
 	return Common::Point(_x + _parentX, _y + _parentY);
 }
 
+Common::Point Gadget::midPoint() const {
+	return topLeft() + Common::Point(_width / 2, _height / 2);
+}
+
 bool Gadget::containsPoint(const Common::Point &pt) {
 	Common::Point tl = topLeft();
 	Common::Rect gadgetRect(tl, _width, _height - 1);
diff --git a/engines/dgds/request.h b/engines/dgds/request.h
index 7a95ddf7a1d..200ad4b4e22 100644
--- a/engines/dgds/request.h
+++ b/engines/dgds/request.h
@@ -103,6 +103,7 @@ public:
 	bool containsPoint(const Common::Point &pt);
 
 	Common::Point topLeft() const;
+	Common::Point midPoint() const;
 };
 
 // Button gadget has no additional fields, but some behavior differences.
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index 89dd0a59400..4e460033200 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -1812,6 +1812,13 @@ void SDSScene::nextChoice() {
 	dlg->updateSelectedAction(1);
 }
 
+void SDSScene::activateChoice() {
+	Dialog *dlg = getVisibleDialog();
+	if (!dlg)
+		return;
+	_shouldClearDlg = true;
+}
+
 
 GDSScene::GDSScene() : _field38(0), _field3a(0), _field3c(0), _field3e(0), _field40(0) {
 }
diff --git a/engines/dgds/scene.h b/engines/dgds/scene.h
index 9954ce56e1a..38c373221ff 100644
--- a/engines/dgds/scene.h
+++ b/engines/dgds/scene.h
@@ -459,6 +459,7 @@ public:
 
 	void prevChoice();
 	void nextChoice();
+	void activateChoice();
 
 protected:
 	HotArea *findAreaUnderMouse(const Common::Point &pt);




More information about the Scummvm-git-logs mailing list