[Scummvm-git-logs] scummvm master -> 76d1590ccc4d2f680cbbd0dd480084fb010536ba

sev- noreply at scummvm.org
Sun May 28 11:50:24 UTC 2023


This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
5bb6e06624 GRAPHICS: Expose internal macmenu structs for reusing in popmenu
014712bbc5 GRAPHICS: Add menu by id and support custom menu
e12d3053cc GRAPHICS: Implement macpopupmenu while reusing macmenu
8aa6ed2110 DIRECTOR: Implement popupmenuxobj for macpopmenu
fd5977b911 GRAPHICS: Add blinking animation when selecting item
76d1590ccc GRAPHICS: Implement smartmenu for macpopups


Commit: 5bb6e06624d8e79ae22bb7f5a6dbe7daca498dd9
    https://github.com/scummvm/scummvm/commit/5bb6e06624d8e79ae22bb7f5a6dbe7daca498dd9
Author: Harishankar Kumar (hari01584 at gmail.com)
Date: 2023-05-28T13:50:18+02:00

Commit Message:
GRAPHICS: Expose internal macmenu structs for reusing in popmenu

Exposed MacMenuItem, MacMenuSubMenu, MacMenuItem and MacMenuData to headers and changed visibility of needed functions to protected.

These structs and functions is used in popupmenu for reusing macmenu code.

Changed paths:
    graphics/macgui/macmenu.cpp
    graphics/macgui/macmenu.h


diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index 5d3ce3c9b63..c3369eed518 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -64,47 +64,6 @@ enum {
 
 struct MacMenuSubMenu;
 
-struct MacMenuSubMenu {
-	ItemArray items;
-	Common::Rect bbox;
-	int highlight;
-
-	MacMenuSubMenu() : highlight(-1) {}
-
-	~MacMenuSubMenu();
-
-	void enableAllItems();
-
-	int ytoItem(int y, int itemHeight) { return MIN<int>((y - bbox.top) / itemHeight, items.size() - 1); }
-};
-
-struct MacMenuItem {
-	Common::String text;
-	Common::U32String unicodeText;
-	bool unicode;
-	int action;
-	int style;
-	char shortcut;
-	int shortcutPos;
-	bool enabled;
-	bool checked;
-	Common::Rect bbox;
-
-	MacMenuSubMenu *submenu;
-
-	MacMenuItem(const Common::String &t, int a = -1, int s = 0, char sh = 0, int sp = -1, bool e = true, bool c = false) :
-			text(t), unicode(false), action(a), style(s), shortcut(sh),
-			shortcutPos(sp), enabled(e), submenu(nullptr), checked(c) {}
-	MacMenuItem(const Common::U32String &t, int a = -1, int s = 0, char sh = 0, int sp = -1, bool e = true, bool c = false) :
-			unicodeText(t), unicode(true), action(a), style(s), shortcut(sh),
-			shortcutPos(sp), enabled(e), submenu(nullptr), checked(c) {}
-
-	~MacMenuItem() {
-		if (submenu)
-			delete submenu;
-	}
-};
-
 MacMenuSubMenu::~MacMenuSubMenu() {
 	for (uint i = 0; i < items.size(); i++)
 		delete items[i];
diff --git a/graphics/macgui/macmenu.h b/graphics/macgui/macmenu.h
index d474a961db9..5603ef2ec8f 100644
--- a/graphics/macgui/macmenu.h
+++ b/graphics/macgui/macmenu.h
@@ -24,6 +24,7 @@
 
 #include "common/str-array.h"
 #include "graphics/macgui/macfontmanager.h"
+#include "graphics/macgui/macwindow.h"
 #include "graphics/font.h"
 
 namespace Common {
@@ -38,6 +39,47 @@ struct MacMenuItem;
 struct MacMenuSubMenu;
 typedef Common::Array<MacMenuItem *> ItemArray;
 
+struct MacMenuSubMenu {
+	ItemArray items;
+	Common::Rect bbox;
+	int highlight;
+
+	MacMenuSubMenu() : highlight(-1) {}
+
+	~MacMenuSubMenu();
+
+	void enableAllItems();
+
+	int ytoItem(int y, int itemHeight) { return MIN<int>((y - bbox.top) / itemHeight, items.size() - 1); }
+};
+
+struct MacMenuItem {
+	Common::String text;
+	Common::U32String unicodeText;
+	bool unicode;
+	int action;
+	int style;
+	char shortcut;
+	int shortcutPos;
+	bool enabled;
+	bool checked;
+	Common::Rect bbox;
+
+	MacMenuSubMenu *submenu;
+
+	MacMenuItem(const Common::String &t, int a = -1, int s = 0, char sh = 0, int sp = -1, bool e = true, bool c = false) :
+			text(t), unicode(false), action(a), style(s), shortcut(sh),
+			shortcutPos(sp), enabled(e), submenu(nullptr), checked(c) {}
+	MacMenuItem(const Common::U32String &t, int a = -1, int s = 0, char sh = 0, int sp = -1, bool e = true, bool c = false) :
+			unicodeText(t), unicode(true), action(a), style(s), shortcut(sh),
+			shortcutPos(sp), enabled(e), submenu(nullptr), checked(c) {}
+
+	~MacMenuItem() {
+		if (submenu)
+			delete submenu;
+	}
+};
+
 struct MacMenuData {
 	int menunum;
 	const char *title;
@@ -88,6 +130,8 @@ public:
 	MacMenuSubMenu *getSubmenu(MacMenuSubMenu *submenu, int index);
 
 	bool draw(ManagedSurface *g, bool forceRedraw = false) override;
+	void eventLoop();
+	bool mouseClick(int x, int y);
 	bool draw(bool forceRedraw = false) override { return false; }
 	void blit(ManagedSurface *g, Common::Rect &dest) override {}
 
@@ -121,10 +165,18 @@ public:
 	void setAction(MacMenuItem *menuItem, int actionId);
 	int getAction(MacMenuItem *menuItem);
 
+
+protected:
 	Common::Rect _bbox;
+	ManagedSurface _screen;
+	ItemArray _items;
+	bool _isVisible;
+	bool _dimensionsDirty;
+	Common::Array<MacMenuSubMenu *> _menustack;
+
+	void renderSubmenu(MacMenuSubMenu *menu, bool recursive = true);
 
 private:
-	ManagedSurface _screen;
 	ManagedSurface _tempSurface;
 	TextAlign _align;
 	int _menuDropdownItemHeight;
@@ -140,10 +192,8 @@ private:
 
 	int calcSubMenuWidth(MacMenuSubMenu *menu);
 	void calcSubMenuBounds(MacMenuSubMenu *menu, int x, int y);
-	void renderSubmenu(MacMenuSubMenu *menu, bool recursive = true);
 
 	bool keyEvent(Common::Event &event);
-	bool mouseClick(int x, int y);
 	bool mouseRelease(int x, int y);
 	bool mouseMove(int x, int y);
 
@@ -152,22 +202,14 @@ private:
 	void drawSubMenuArrow(ManagedSurface *dst, int x, int y, int color);
 	bool contains(int x, int y);
 
-	void eventLoop();
-
 	MacMenuItem *findMenuItem(const Common::String &menuId, const Common::String &itemId);
 	MacMenuItem *findMenuItem(int menuId, int itemId);
 
-	ItemArray _items;
 
 	const Font *_font;
 	Font *_loadedFont;
 
-	bool _isVisible;
-
-	bool _dimensionsDirty;
-
 	int _activeItem;
-	Common::Array<MacMenuSubMenu *> _menustack;
 	int _activeSubItem;
 
 	void (*_ccallback)(int action, Common::String &text, void *data);


Commit: 014712bbc5a2959b6ad86dc75d7031b6814f7000
    https://github.com/scummvm/scummvm/commit/014712bbc5a2959b6ad86dc75d7031b6814f7000
Author: Harishankar Kumar (hari01584 at gmail.com)
Date: 2023-05-28T13:50:18+02:00

Commit Message:
GRAPHICS: Add menu by id and support custom menu

Adds new function addMenu/getMenu with menu id to add custom menus.

Used when implementing macpopupmenu which reuses macmenu for theapartment.

Changed paths:
    graphics/macgui/macwindowmanager.cpp
    graphics/macgui/macwindowmanager.h


diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index 1742add7c47..555ef40e6ff 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -394,6 +394,10 @@ MacMenu *MacWindowManager::addMenu() {
 	return _menu;
 }
 
+void MacWindowManager::addMenu(int id, MacMenu *menu) {
+	_windows[id] = menu;
+}
+
 MacMenu *MacWindowManager::getMenu() {
 	if (_menu) {
 		return _menu;
@@ -401,6 +405,12 @@ MacMenu *MacWindowManager::getMenu() {
 	return nullptr;
 }
 
+MacMenu *MacWindowManager::getMenu(int id) {
+	if (_windows.contains(id))
+		return (MacMenu *)_windows[id];
+	return nullptr;
+}
+
 void MacWindowManager::removeMenu() {
 	if (_menu) {
 		_windows[_menu->getId()] = nullptr;
diff --git a/graphics/macgui/macwindowmanager.h b/graphics/macgui/macwindowmanager.h
index d88ceb5e992..7587149f9ea 100644
--- a/graphics/macgui/macwindowmanager.h
+++ b/graphics/macgui/macwindowmanager.h
@@ -203,6 +203,7 @@ public:
 	 * @return Pointer to a new empty menu.
 	 */
 	MacMenu *addMenu();
+	void addMenu(int id, MacMenu *menu);
 
 	void removeMenu();
 	void activateMenu();
@@ -371,6 +372,7 @@ public:
 	Common::String getMenuItemName(MacMenuItem *menuItem);
 	int getMenuItemAction(MacMenuItem *menuItem);
 	MacMenu *getMenu();
+	MacMenu *getMenu(int id);
 
 public:
 	MacFontManager *_fontMan;


Commit: e12d3053cc919da77e68bb98986477f428498c25
    https://github.com/scummvm/scummvm/commit/e12d3053cc919da77e68bb98986477f428498c25
Author: Harishankar Kumar (hari01584 at gmail.com)
Date: 2023-05-28T13:50:18+02:00

Commit Message:
GRAPHICS: Implement macpopupmenu while reusing macmenu

Added functions for menu drawing/selections, this uses the base functions of macmenu to implement mac-styled popupmenu's, also return selected item index/text.

Used by 'Popup Menu' in theapartment: With this changes the popupmenu is working with both item selectors, doesn't implement the icon selector.

Changed paths:
  A graphics/macgui/macpopupmenu.cpp
  A graphics/macgui/macpopupmenu.h
    graphics/macgui/macmenu.cpp
    graphics/macgui/macmenu.h
    graphics/module.mk


diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index c3369eed518..a9825fdb986 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -114,6 +114,8 @@ MacMenu::MacMenu(int id, const Common::Rect &bounds, MacWindowManager *wm)
 
 	_activeItem = -1;
 	_activeSubItem = -1;
+	_lastActiveItem = -1;
+	_lastActiveSubItem = -1;
 
 	_ccallback = NULL;
 	_unicodeccallback = NULL;
@@ -685,7 +687,7 @@ void MacMenu::createSubMenuFromString(int id, const char *str, int commandId) {
 		submenu = addSubMenu(nullptr, id);
 
 	for (uint i = 0; i < string.size(); i++) {
-		while (i < string.size() && string[i] != ';') // Read token
+		while (i < string.size() && (string[i] != ';' && string[i] != '\r')) // Read token, consume \r for popup menu (MacPopUp)
 			item += string[i++];
 
 		if (item.lastChar() == ']') { // we have command id
@@ -1455,6 +1457,10 @@ bool MacMenu::mouseRelease(int x, int y) {
 		}
 	}
 
+	// Set last active items and subitems before leaving!
+	_lastActiveItem = _activeItem;
+	_lastActiveSubItem = _activeSubItem;
+
 	// if the mode is not win95, or the click position is outside of the menu, then we close it
 	if (!(_wm->_mode & kWMModeWin95) || !contains(x, y) || haveCallBack)
 		closeMenu();
diff --git a/graphics/macgui/macmenu.h b/graphics/macgui/macmenu.h
index 5603ef2ec8f..24c18430638 100644
--- a/graphics/macgui/macmenu.h
+++ b/graphics/macgui/macmenu.h
@@ -165,6 +165,8 @@ public:
 	void setAction(MacMenuItem *menuItem, int actionId);
 	int getAction(MacMenuItem *menuItem);
 
+	int getLastSelectedMenuItem() { return _lastActiveItem; };
+	int getLastSelectedSubmenuItem() { return _lastActiveSubItem; };
 
 protected:
 	Common::Rect _bbox;
@@ -175,6 +177,7 @@ protected:
 	Common::Array<MacMenuSubMenu *> _menustack;
 
 	void renderSubmenu(MacMenuSubMenu *menu, bool recursive = true);
+	void calcSubMenuBounds(MacMenuSubMenu *menu, int x, int y);
 
 private:
 	ManagedSurface _tempSurface;
@@ -191,7 +194,6 @@ private:
 	void processSubmenuTabs(MacMenuSubMenu *submenu);
 
 	int calcSubMenuWidth(MacMenuSubMenu *menu);
-	void calcSubMenuBounds(MacMenuSubMenu *menu, int x, int y);
 
 	bool keyEvent(Common::Event &event);
 	bool mouseRelease(int x, int y);
@@ -212,6 +214,9 @@ private:
 	int _activeItem;
 	int _activeSubItem;
 
+	int _lastActiveItem;
+	int _lastActiveSubItem;
+
 	void (*_ccallback)(int action, Common::String &text, void *data);
 	void (*_unicodeccallback)(int action, Common::U32String &text, void *data);
 	void *_cdata;
diff --git a/graphics/macgui/macpopupmenu.cpp b/graphics/macgui/macpopupmenu.cpp
new file mode 100644
index 00000000000..5ee790ff100
--- /dev/null
+++ b/graphics/macgui/macpopupmenu.cpp
@@ -0,0 +1,95 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "graphics/macgui/macpopupmenu.h"
+#include "graphics/macgui/macwindowmanager.h"
+
+namespace Graphics {
+
+MacPopUp::MacPopUp(int id, const Common::Rect &bounds, MacWindowManager *wm, const char *string) : MacMenu(id, bounds, wm) {
+	_menuItemId = addMenuItem(nullptr, "");
+	createSubMenuFromString(0, string, 0);
+	wm->addMenu(id, this);
+	_menuId = id;
+}
+
+bool MacPopUp::draw(ManagedSurface *g, bool forceRedraw) {
+
+	if (!_isVisible)
+		return false;
+
+	if (_dimensionsDirty)
+		calcSubMenuBounds(_items[0]->submenu, _mouseX, _mouseY);
+
+	if (!_contentIsDirty && !forceRedraw)
+		return false;
+	_contentIsDirty = false;
+
+	_screen.clear(_wm->_colorGreen);
+	renderSubmenu(_items[0]->submenu, false);
+
+	if (g)
+		g->transBlitFrom(_screen, _wm->_colorGreen);
+
+	if (!(_wm->_mode & kWMModalMenuMode) && g)
+		g_system->copyRectToScreen(g->getPixels(), g->pitch, 0, 0, g->w, g->h);
+
+	return true;
+}
+
+uint32 MacPopUp::drawAndSelectMenu(int x, int y, int item) {
+	_mouseX = x;
+	_mouseY = y;
+
+	// If menu is not active, then activate it!
+	if (!_active)
+		_wm->activateMenu();
+	setActive(true);
+
+	_contentIsDirty = true; // Set true to force refresh menu open changes
+
+	// Push our submenu to stack
+	_menustack.clear();
+	_menustack.push_back(_items[0]->submenu);
+
+	// Display menu and update according to events
+	this->draw(_wm->_screen);
+	eventLoop();
+
+	// Close menu
+	closeMenu();
+
+	int activeSubItem = getLastSelectedSubmenuItem();
+	if (activeSubItem == -1)
+		return item;
+
+	// Return one indexed item!
+	return activeSubItem + 1;
+}
+
+Common::String MacPopUp::getItemText(int item) {
+	// Convert 1-indexed item to 0 indexed
+	item = item - 1;
+	MacMenuItem *menu = getMenuItem(_menuItemId);
+	MacMenuItem *submenu = getSubMenuItem(menu, item);
+	return getName(submenu);
+}
+} // end of namespace Graphics
diff --git a/graphics/macgui/macpopupmenu.h b/graphics/macgui/macpopupmenu.h
new file mode 100644
index 00000000000..68ff4da18a6
--- /dev/null
+++ b/graphics/macgui/macpopupmenu.h
@@ -0,0 +1,48 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef GRAPHICS_MACGUI_MACPOPUPMENU_H
+#define GRAPHICS_MACGUI_MACPOPUPMENU_H
+
+#include "graphics/macgui/macmenu.h"
+
+namespace Graphics {
+
+class MacMenu;
+class MacWindowManager;
+
+class MacPopUp : public MacMenu {
+public:
+	MacPopUp(int id, const Common::Rect &bounds, MacWindowManager *wm, const char *string);
+	uint32 drawAndSelectMenu(int x, int y, int item);
+	Common::String getItemText(int item);
+
+	bool draw(ManagedSurface *g, bool forceRedraw = false) override;
+private:
+	int _mouseX;
+	int _mouseY;
+	int _menuItemId;
+	int _menuId;
+
+	bool mouseClicked(int x, int y);
+};
+} // End of namespace Graphics
+#endif
diff --git a/graphics/module.mk b/graphics/module.mk
index f8528e1c923..0d12dc92c88 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -27,6 +27,7 @@ MODULE_OBJS := \
 	macgui/macdialog.o \
 	macgui/macfontmanager.o \
 	macgui/macmenu.o \
+	macgui/macpopupmenu.o \
 	macgui/mactext.o \
 	macgui/mactextwindow.o \
 	macgui/macwidget.o \


Commit: 8aa6ed21103e094bf24468f73554d42bfb4978fd
    https://github.com/scummvm/scummvm/commit/8aa6ed21103e094bf24468f73554d42bfb4978fd
Author: Harishankar Kumar (hari01584 at gmail.com)
Date: 2023-05-28T13:50:18+02:00

Commit Message:
DIRECTOR: Implement popupmenuxobj for macpopmenu

Implements xlib methods for popupmenu creation/item selection, uses macpopmenu internally.

Used for implementing 'Popup Menu'  in theapartment, with this popupmenu are working.

Changed paths:
    engines/director/lingo/xlibs/popupmenuxobj.cpp
    engines/director/lingo/xlibs/popupmenuxobj.h


diff --git a/engines/director/lingo/xlibs/popupmenuxobj.cpp b/engines/director/lingo/xlibs/popupmenuxobj.cpp
index 8585b8f2848..3911fcc0258 100644
--- a/engines/director/lingo/xlibs/popupmenuxobj.cpp
+++ b/engines/director/lingo/xlibs/popupmenuxobj.cpp
@@ -102,11 +102,14 @@
  */
 
 #include "director/director.h"
+#include "director/window.h"
+
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-object.h"
 #include "director/lingo/lingo-utils.h"
 #include "director/lingo/xlibs/popupmenuxobj.h"
 
+#include "graphics/macgui/macpopupmenu.h"
 
 namespace Director {
 
@@ -149,23 +152,64 @@ void PopUpMenuXObj::close(int type) {
 }
 
 
-PopUpMenuXObject::PopUpMenuXObject(ObjectType ObjectType) :Object<PopUpMenuXObject>("PopMenu") {
+PopUpMenuXObject::PopUpMenuXObject(ObjectType ObjectType) : Object<PopUpMenuXObject>("PopMenu") {
 	_objType = ObjectType;
 }
 
 void PopUpMenuXObj::m_new(int nargs) {
-	g_lingo->printSTUBWithArglist("PopUpMenuXObj::m_new", nargs);
-	g_lingo->dropStack(nargs);
+	PopUpMenuXObject *me = static_cast<PopUpMenuXObject *>(g_lingo->_state->me.u.obj);
+
+	int menuId = g_lingo->pop().asInt();
+	Common::String menuList = g_lingo->pop().asString();
+
+	new Graphics::MacPopUp(menuId, g_director->_wm->getScreenBounds(), g_director->_wm, menuList.c_str());
+	me->_menuId = menuId;
+
 	g_lingo->push(g_lingo->_state->me);
 }
 
+void PopUpMenuXObj::m_popNum(int nargs) {
+	PopUpMenuXObject *me = static_cast<PopUpMenuXObject *>(g_lingo->_state->me.u.obj);
+
+	int itemNum = g_lingo->pop().asInt();
+	int top = g_lingo->pop().asInt();
+	int left = g_lingo->pop().asInt();
+
+	// Convert window coordinates to screen coordinates
+	Common::Rect windowRect = g_director->getCurrentWindow()->getInnerDimensions();
+	int screenTop = top + windowRect.top;
+	int screenLeft = left + windowRect.left;
+
+	Graphics::MacPopUp *menu = static_cast<Graphics::MacPopUp *>(g_director->_wm->getMenu(me->_menuId));
+	int selected = menu->drawAndSelectMenu(screenLeft, screenTop, itemNum);
+	g_lingo->push(Datum(selected));
+}
+
+void PopUpMenuXObj::m_popText(int nargs) {
+	PopUpMenuXObject *me = static_cast<PopUpMenuXObject *>(g_lingo->_state->me.u.obj);
+
+	int itemNum = g_lingo->pop().asInt();
+	int top = g_lingo->pop().asInt();
+	int left = g_lingo->pop().asInt();
+
+	// Convert window coordinates to screen coordinates
+	Common::Rect windowRect = g_director->getCurrentWindow()->getInnerDimensions();
+	int screenTop = top + windowRect.top;
+	int screenLeft = left + windowRect.left;
+
+	Graphics::MacPopUp *menu = static_cast<Graphics::MacPopUp *>(g_director->_wm->getMenu(me->_menuId));
+	int selected = menu->drawAndSelectMenu(screenLeft, screenTop, itemNum);
+	Common::String selectedText = menu->getItemText(selected);
+
+	g_lingo->push(Datum(selectedText));
+}
+
+
 XOBJSTUBNR(PopUpMenuXObj::m_appendMenu)
 XOBJSTUBNR(PopUpMenuXObj::m_disableItem)
 XOBJSTUBNR(PopUpMenuXObj::m_enableItem)
 XOBJSTUB(PopUpMenuXObj::m_getItem, "")
 XOBJSTUB(PopUpMenuXObj::m_getMenuID, 0)
-XOBJSTUB(PopUpMenuXObj::m_popNum, 0)
-XOBJSTUB(PopUpMenuXObj::m_popText, "")
 XOBJSTUBNR(PopUpMenuXObj::m_setItem)
 XOBJSTUBNR(PopUpMenuXObj::m_setItemMark)
 XOBJSTUBNR(PopUpMenuXObj::m_smart)
diff --git a/engines/director/lingo/xlibs/popupmenuxobj.h b/engines/director/lingo/xlibs/popupmenuxobj.h
index 0f139042c29..418ad31ee18 100644
--- a/engines/director/lingo/xlibs/popupmenuxobj.h
+++ b/engines/director/lingo/xlibs/popupmenuxobj.h
@@ -26,6 +26,7 @@ namespace Director {
 
 class PopUpMenuXObject : public Object<PopUpMenuXObject> {
 public:
+	int _menuId;
 	PopUpMenuXObject(ObjectType objType);
 };
 


Commit: fd5977b911c024f60006bfcaa474f9a7a0d3fba0
    https://github.com/scummvm/scummvm/commit/fd5977b911c024f60006bfcaa474f9a7a0d3fba0
Author: Harishankar Kumar (hari01584 at gmail.com)
Date: 2023-05-28T13:50:18+02:00

Commit Message:
GRAPHICS: Add blinking animation when selecting item

Additional logic for drawing blinks when closing popup menu is added, closeMenu is overriden because it is called inside eventLoop and therefore need to be captured when closingMenu.

Add blinking animation support for macpopups, affects `Popup Menu` in theapartment, before this there was no animation when selecting item and the menu just used to immediately close, now however there is proper animation for item selection.

Changed paths:
    graphics/macgui/macmenu.h
    graphics/macgui/macpopupmenu.cpp
    graphics/macgui/macpopupmenu.h


diff --git a/graphics/macgui/macmenu.h b/graphics/macgui/macmenu.h
index 24c18430638..0f06c168ac6 100644
--- a/graphics/macgui/macmenu.h
+++ b/graphics/macgui/macmenu.h
@@ -148,7 +148,7 @@ public:
 
 	void printMenu(int level = 0, MacMenuSubMenu *submenu = nullptr);
 
-	void closeMenu();
+	virtual void closeMenu();
 
 	bool checkIntersects(Common::Rect &rect);
 
diff --git a/graphics/macgui/macpopupmenu.cpp b/graphics/macgui/macpopupmenu.cpp
index 5ee790ff100..f8d08855a9d 100644
--- a/graphics/macgui/macpopupmenu.cpp
+++ b/graphics/macgui/macpopupmenu.cpp
@@ -55,6 +55,29 @@ bool MacPopUp::draw(ManagedSurface *g, bool forceRedraw) {
 	return true;
 }
 
+void MacPopUp::closeMenu() {
+	// Special handling of popup closing (for example when displaying closing animation)
+	int activeSubItem = getLastSelectedSubmenuItem(); // Find selected item
+
+	if (activeSubItem != -1) {
+		// Do the blinking animation
+		for (int i = 0; i < kNumBlinks; i++) {
+			_items[0]->submenu->highlight = -1; // No selection
+			draw(_wm->_screen, true);
+			g_system->updateScreen();
+			g_system->delayMillis(kBlinkDelay);
+
+			_items[0]->submenu->highlight = activeSubItem; // Selection
+			draw(_wm->_screen, true);
+			g_system->updateScreen();
+			g_system->delayMillis(kBlinkDelay);
+		}
+	}
+
+	// Close now
+	MacMenu::closeMenu();
+}
+
 uint32 MacPopUp::drawAndSelectMenu(int x, int y, int item) {
 	_mouseX = x;
 	_mouseY = y;
@@ -74,9 +97,6 @@ uint32 MacPopUp::drawAndSelectMenu(int x, int y, int item) {
 	this->draw(_wm->_screen);
 	eventLoop();
 
-	// Close menu
-	closeMenu();
-
 	int activeSubItem = getLastSelectedSubmenuItem();
 	if (activeSubItem == -1)
 		return item;
diff --git a/graphics/macgui/macpopupmenu.h b/graphics/macgui/macpopupmenu.h
index 68ff4da18a6..c341451a895 100644
--- a/graphics/macgui/macpopupmenu.h
+++ b/graphics/macgui/macpopupmenu.h
@@ -36,7 +36,12 @@ public:
 	Common::String getItemText(int item);
 
 	bool draw(ManagedSurface *g, bool forceRedraw = false) override;
+	void closeMenu() override;
+
 private:
+	int kBlinkDelay = 15; // Blink delay for closing animation
+	int kNumBlinks = 3; // Number of blinks
+
 	int _mouseX;
 	int _mouseY;
 	int _menuItemId;


Commit: 76d1590ccc4d2f680cbbd0dd480084fb010536ba
    https://github.com/scummvm/scummvm/commit/76d1590ccc4d2f680cbbd0dd480084fb010536ba
Author: Harishankar Kumar (hari01584 at gmail.com)
Date: 2023-05-28T13:50:18+02:00

Commit Message:
GRAPHICS: Implement smartmenu for macpopups

Smartmenu implementation using offsetY to displace popup such that the previous selected item will fall onto cursor, includes checked item and highlighted.

For `Popup Menu` in theapartment, without this patch the second popmenu was not remembering the last selected item and was opening it from scratch, after this patch popupmenu will open from the last selected item already selected with checkbox.

Changed paths:
    engines/director/lingo/xlibs/popupmenuxobj.cpp
    graphics/macgui/macmenu.h
    graphics/macgui/macpopupmenu.cpp
    graphics/macgui/macpopupmenu.h


diff --git a/engines/director/lingo/xlibs/popupmenuxobj.cpp b/engines/director/lingo/xlibs/popupmenuxobj.cpp
index 3911fcc0258..afd3a911b3d 100644
--- a/engines/director/lingo/xlibs/popupmenuxobj.cpp
+++ b/engines/director/lingo/xlibs/popupmenuxobj.cpp
@@ -177,8 +177,8 @@ void PopUpMenuXObj::m_popNum(int nargs) {
 
 	// Convert window coordinates to screen coordinates
 	Common::Rect windowRect = g_director->getCurrentWindow()->getInnerDimensions();
-	int screenTop = top + windowRect.top;
-	int screenLeft = left + windowRect.left;
+	int screenTop = top + windowRect.top - 1;
+	int screenLeft = left + windowRect.left - 1;
 
 	Graphics::MacPopUp *menu = static_cast<Graphics::MacPopUp *>(g_director->_wm->getMenu(me->_menuId));
 	int selected = menu->drawAndSelectMenu(screenLeft, screenTop, itemNum);
@@ -194,8 +194,8 @@ void PopUpMenuXObj::m_popText(int nargs) {
 
 	// Convert window coordinates to screen coordinates
 	Common::Rect windowRect = g_director->getCurrentWindow()->getInnerDimensions();
-	int screenTop = top + windowRect.top;
-	int screenLeft = left + windowRect.left;
+	int screenTop = top + windowRect.top - 1;
+	int screenLeft = left + windowRect.left - 1;
 
 	Graphics::MacPopUp *menu = static_cast<Graphics::MacPopUp *>(g_director->_wm->getMenu(me->_menuId));
 	int selected = menu->drawAndSelectMenu(screenLeft, screenTop, itemNum);
@@ -204,6 +204,13 @@ void PopUpMenuXObj::m_popText(int nargs) {
 	g_lingo->push(Datum(selectedText));
 }
 
+void PopUpMenuXObj::m_smart(int nargs) {
+	PopUpMenuXObject *me = static_cast<PopUpMenuXObject *>(g_lingo->_state->me.u.obj);
+	bool isSmart = g_lingo->pop().asInt() != 0;
+
+	Graphics::MacPopUp *menu = static_cast<Graphics::MacPopUp *>(g_director->_wm->getMenu(me->_menuId));
+	menu->setSmart(isSmart);
+}
 
 XOBJSTUBNR(PopUpMenuXObj::m_appendMenu)
 XOBJSTUBNR(PopUpMenuXObj::m_disableItem)
@@ -212,7 +219,6 @@ XOBJSTUB(PopUpMenuXObj::m_getItem, "")
 XOBJSTUB(PopUpMenuXObj::m_getMenuID, 0)
 XOBJSTUBNR(PopUpMenuXObj::m_setItem)
 XOBJSTUBNR(PopUpMenuXObj::m_setItemMark)
-XOBJSTUBNR(PopUpMenuXObj::m_smart)
 XOBJSTUBNR(PopUpMenuXObj::m_setItemIcon)
 
 } // End of namespace Director
diff --git a/graphics/macgui/macmenu.h b/graphics/macgui/macmenu.h
index 0f06c168ac6..455ce5a1c33 100644
--- a/graphics/macgui/macmenu.h
+++ b/graphics/macgui/macmenu.h
@@ -174,15 +174,18 @@ protected:
 	ItemArray _items;
 	bool _isVisible;
 	bool _dimensionsDirty;
+	int _menuDropdownItemHeight;
 	Common::Array<MacMenuSubMenu *> _menustack;
 
+	int _activeItem;
+	int _activeSubItem;
+
 	void renderSubmenu(MacMenuSubMenu *menu, bool recursive = true);
 	void calcSubMenuBounds(MacMenuSubMenu *menu, int x, int y);
 
 private:
 	ManagedSurface _tempSurface;
 	TextAlign _align;
-	int _menuDropdownItemHeight;
 	int _menuLeftDropdownPadding;
 	int _menuRightDropdownPadding;
 
@@ -211,9 +214,6 @@ private:
 	const Font *_font;
 	Font *_loadedFont;
 
-	int _activeItem;
-	int _activeSubItem;
-
 	int _lastActiveItem;
 	int _lastActiveSubItem;
 
diff --git a/graphics/macgui/macpopupmenu.cpp b/graphics/macgui/macpopupmenu.cpp
index f8d08855a9d..bd042323963 100644
--- a/graphics/macgui/macpopupmenu.cpp
+++ b/graphics/macgui/macpopupmenu.cpp
@@ -37,7 +37,7 @@ bool MacPopUp::draw(ManagedSurface *g, bool forceRedraw) {
 		return false;
 
 	if (_dimensionsDirty)
-		calcSubMenuBounds(_items[0]->submenu, _mouseX, _mouseY);
+		calcSubMenuBounds(_items[0]->submenu, _mouseX, _mouseY + _offsetY);
 
 	if (!_contentIsDirty && !forceRedraw)
 		return false;
@@ -74,6 +74,22 @@ void MacPopUp::closeMenu() {
 		}
 	}
 
+	if (_isSmart && activeSubItem != -1) {
+		// Smart menu, open menu at offset position (so selected item under cursor)
+		int yDisplace = -activeSubItem * _menuDropdownItemHeight;
+		_offsetY = _mouseY + yDisplace > 0 ? yDisplace : -_mouseY; // If offset sum gets out of window, then position menu to 0 (ie below top of window)
+
+		// Checkmark handling
+		setCheckMark(_items[0]->submenu->items[activeSubItem], true);
+
+		// // Uncheck previous item if checked
+		if (_prevCheckedItem != -1 && _prevCheckedItem != activeSubItem) {
+			setCheckMark(_items[0]->submenu->items[_prevCheckedItem], false);
+		}
+
+		_prevCheckedItem = activeSubItem;
+	}
+
 	// Close now
 	MacMenu::closeMenu();
 }
@@ -93,6 +109,14 @@ uint32 MacPopUp::drawAndSelectMenu(int x, int y, int item) {
 	_menustack.clear();
 	_menustack.push_back(_items[0]->submenu);
 
+	// Highlight previous item if smart menu
+	if (_isSmart && getLastSelectedSubmenuItem() != -1) {
+		_activeItem = 0;
+		_activeSubItem = getLastSelectedSubmenuItem();
+		// Also select the item
+		_items[0]->submenu->highlight = getLastSelectedSubmenuItem();
+	}
+
 	// Display menu and update according to events
 	this->draw(_wm->_screen);
 	eventLoop();
diff --git a/graphics/macgui/macpopupmenu.h b/graphics/macgui/macpopupmenu.h
index c341451a895..3e7b67d2730 100644
--- a/graphics/macgui/macpopupmenu.h
+++ b/graphics/macgui/macpopupmenu.h
@@ -38,6 +38,10 @@ public:
 	bool draw(ManagedSurface *g, bool forceRedraw = false) override;
 	void closeMenu() override;
 
+	// Extra functions
+	void setSmart(bool smart) {
+		_isSmart = smart;
+	}
 private:
 	int kBlinkDelay = 15; // Blink delay for closing animation
 	int kNumBlinks = 3; // Number of blinks
@@ -47,6 +51,10 @@ private:
 	int _menuItemId;
 	int _menuId;
 
+	bool _isSmart = false;
+	int _offsetY = 0;
+	int _prevCheckedItem = -1;
+
 	bool mouseClicked(int x, int y);
 };
 } // End of namespace Graphics




More information about the Scummvm-git-logs mailing list