[Scummvm-git-logs] scummvm master -> ae8fc03e3a1800eef97bd1a45b282e107a4baf95
dreammaster
noreply at scummvm.org
Thu Feb 13 06:44:07 UTC 2025
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d5313f37f9 M4: RIDDLE: Move msg methods to menuItemMsg
01da5fd1cf M4: RIDDLE: Move slider methods to slider classes
ae8fc03e3a M4: RIDDLE: Move text field methods to menuItemTextField
Commit: d5313f37f95210d0de729594626d0a0d679e33da
https://github.com/scummvm/scummvm/commit/d5313f37f95210d0de729594626d0a0d679e33da
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2025-02-12T21:51:07-08:00
Commit Message:
M4: RIDDLE: Move msg methods to menuItemMsg
Changed paths:
engines/m4/burger/gui/game_menu.cpp
engines/m4/burger/gui/game_menu.h
engines/m4/gui/gui_menu.cpp
engines/m4/gui/gui_menu.h
diff --git a/engines/m4/burger/gui/game_menu.cpp b/engines/m4/burger/gui/game_menu.cpp
index a8455c4761f..2f2af9d904d 100644
--- a/engines/m4/burger/gui/game_menu.cpp
+++ b/engines/m4/burger/gui/game_menu.cpp
@@ -235,127 +235,6 @@ Sprite *menu_CreateThumbnail(int32 *spriteSize) {
return thumbNailSprite;
}
-//------------------------------- MESSAGE MENU ITEM ---------------------------------//
-
-
-void menu_DrawMsg(menuItemMsg *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32) {
- Buffer *myBuff = nullptr;
- Buffer *backgroundBuff = nullptr;
- Sprite *mySprite = nullptr;
-
- // Verify params
- if (!myItem || !myMenu) {
- return;
- }
-
- // If the item is marked transparent, get the background buffer
- if (myItem->transparent) {
- if (!myItem->background) {
- return;
- }
- backgroundBuff = myItem->background->get_buffer();
- if (!backgroundBuff) {
- return;
- }
- }
-
- // Get the button info and select the sprite
- //myMsg = (menuItemMsg *)myItem->itemInfo;
- switch (myItem->tag) {
- case SL_TAG_SAVE_LABEL:
- mySprite = _GM(menuSprites)[Burger::GUI::SL_SAVE_LABEL];
- break;
- case SL_TAG_LOAD_LABEL:
- mySprite = _GM(menuSprites)[Burger::GUI::SL_LOAD_LABEL];
- break;
- case SL_TAG_THUMBNAIL:
- mySprite = _GM(saveLoadThumbNail);
- break;
- }
-
- // Get the menu buffer and draw the sprite to it
- myBuff = myMenu->menuBuffer->get_buffer();
- if (!myBuff) {
- return;
- }
-
- // If the item is tagged as transparent, we need to fill in it's background behind it
- if (backgroundBuff) {
- gr_buffer_rect_copy_2(backgroundBuff, myBuff, 0, 0, x, y, backgroundBuff->w, backgroundBuff->h);
- myItem->background->release();
- } else if (myItem->tag == SL_TAG_THUMBNAIL && mySprite->w == 160) {
- // Hack for handling smaller ScummVM thumbnails
- for (int yp = y; yp < (y + SL_THUMBNAIL_H); ++yp) {
- byte *line = myBuff->data + myBuff->stride * yp + x;
- Common::fill(line, line + SL_THUMBNAIL_W, 0);
- }
-
- x += 25;
- y += 25;
- }
-
- // Draw the sprite in
- gui_DrawSprite(mySprite, myBuff, x, y);
-
- // Release the menu buffer
- myMenu->menuBuffer->release();
-}
-
-
-menuItemMsg *menu_MsgAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, bool transparent) {
- menuItemMsg *newItem;
- ScreenContext *myScreen;
- int32 status;
-
- // Verify params
- if (!myMenu) {
- return nullptr;
- }
-
- // Allocate a new one
- newItem = new menuItemMsg();
-
- // Initialize the struct
- newItem->next = myMenu->itemList;
- newItem->prev = nullptr;
- if (myMenu->itemList) {
- myMenu->itemList->prev = newItem;
- }
- myMenu->itemList = newItem;
-
- newItem->myMenu = myMenu;
- newItem->tag = tag;
- newItem->x1 = x;
- newItem->y1 = y;
- newItem->x2 = x + w - 1;
- newItem->y2 = y + h - 1;
- newItem->callback = nullptr;
-
- if (!transparent) {
- newItem->transparent = false;
- newItem->background = nullptr;
- } else {
- newItem->transparent = true;
- newItem->background = guiMenu::copyBackground(myMenu, x, y, w, h);
- }
-
- newItem->redraw = (DrawFunction)menu_DrawMsg;
- newItem->destroy = (DestroyFunction)menuItem::destroyItem;
- newItem->itemEventHandler = nullptr;
-
- // Draw the message in now
- (newItem->redraw)(newItem, myMenu, x, y, 0, 0);
-
- // See if the screen is currently visible
- myScreen = vmng_screen_find(myMenu, &status);
- if (myScreen && (status == SCRN_ACTIVE)) {
- RestoreScreens(myScreen->x1 + newItem->x1, myScreen->y1 + newItem->y1,
- myScreen->x1 + newItem->x2, myScreen->y1 + newItem->y2);
- }
-
- return newItem;
-}
-
//------------------------------- HSLIDER MENU ITEM ---------------------------------//
enum {
@@ -2236,11 +2115,11 @@ void CreateSaveLoadMenu(RGB8 *myPalette, bool saveMenu) {
}
if (_GM(currMenuIsSave)) {
- menu_MsgAdd(_GM(slMenu), SL_TAG_SAVE_LABEL, SL_SAVE_LABEL_X, SL_SAVE_LABEL_Y, SL_SAVE_LABEL_W, SL_SAVE_LABEL_H);
+ menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_SAVE_LABEL, SL_SAVE_LABEL_X, SL_SAVE_LABEL_Y, SL_SAVE_LABEL_W, SL_SAVE_LABEL_H);
menuItemButton::buttonAdd(_GM(slMenu), SL_TAG_SAVE, SL_SAVE_X, SL_SAVE_Y, SL_SAVE_W, SL_SAVE_H,
(CALLBACK)cb_SaveLoad_Save, menuItemButton::BTN_TYPE_SL_SAVE, true);
} else {
- menu_MsgAdd(_GM(slMenu), SL_TAG_LOAD_LABEL, SL_LOAD_LABEL_X, SL_LOAD_LABEL_Y, SL_LOAD_LABEL_W, SL_LOAD_LABEL_H);
+ menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_LOAD_LABEL, SL_LOAD_LABEL_X, SL_LOAD_LABEL_Y, SL_LOAD_LABEL_W, SL_LOAD_LABEL_H);
menuItemButton::buttonAdd(_GM(slMenu), SL_TAG_LOAD, SL_LOAD_X, SL_LOAD_Y, SL_LOAD_W, SL_LOAD_H,
(CALLBACK)cb_SaveLoad_Load, menuItemButton::BTN_TYPE_SL_LOAD, true);
}
@@ -2281,7 +2160,7 @@ void CreateSaveLoadMenu(RGB8 *myPalette, bool saveMenu) {
_GM(saveLoadThumbNail) = _GM(menuSprites)[Burger::GUI::SL_EMPTY_THUMB];
}
- menu_MsgAdd(_GM(slMenu), SL_TAG_THUMBNAIL, SL_THUMBNAIL_X, SL_THUMBNAIL_Y, SL_THUMBNAIL_W, SL_THUMBNAIL_H, false);
+ menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_THUMBNAIL, SL_THUMBNAIL_X, SL_THUMBNAIL_Y, SL_THUMBNAIL_W, SL_THUMBNAIL_H, false);
if (_GM(currMenuIsSave)) {
//<return> - if a slot has been selected, saves the game
diff --git a/engines/m4/burger/gui/game_menu.h b/engines/m4/burger/gui/game_menu.h
index 7a8ae6df6f6..506dbe000eb 100644
--- a/engines/m4/burger/gui/game_menu.h
+++ b/engines/m4/burger/gui/game_menu.h
@@ -45,11 +45,6 @@ using M4::GUI::ItemHandlerFunction;
// SPECIFIC ITEM FUNCTIONS
-// Messages
-extern menuItemMsg *menu_MsgAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, bool transparent = false);
-extern void menu_DisableMsg(menuItemMsg *myItem, int32 tag, guiMenu *myMenu);
-extern void menu_EnableMsg(menuItemMsg *myItem, int32 tag, guiMenu *myMenu);
-
// Horizontal sliders
menuItemHSlider *menu_HSliderAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h,
int32 initPercent = 0, CALLBACK callback = nullptr, bool transparent = false);
@@ -98,16 +93,6 @@ enum game_menu_button_tags {
#define SAVE_LOAD_MENU_W 344
#define SAVE_LOAD_MENU_H 460
-enum save_load_menu_item_tags {
- SL_TAG_SAVE = 100,
- SL_TAG_SAVE_LABEL,
- SL_TAG_LOAD,
- SL_TAG_LOAD_LABEL,
- SL_TAG_CANCEL,
- SL_TAG_VSLIDER,
- SL_TAG_THUMBNAIL
-};
-
#define SL_SAVE_X 214
#define SL_SAVE_Y 384
#define SL_SAVE_W 74
diff --git a/engines/m4/gui/gui_menu.cpp b/engines/m4/gui/gui_menu.cpp
index 7ae72e61400..3527e9e7d23 100644
--- a/engines/m4/gui/gui_menu.cpp
+++ b/engines/m4/gui/gui_menu.cpp
@@ -1132,5 +1132,125 @@ void menuItemButton::enableButton(menuItemButton *myItem, int32 tag, guiMenu *my
myItem->itemFlags = BTN_STATE_NORM;
}
+
+//----------------------------- MSG FUNCTIONS ---------------------------------//
+
+menuItemMsg *menuItemMsg::msgAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, bool transparent) {
+ menuItemMsg *newItem;
+ ScreenContext *myScreen;
+ int32 status;
+
+ // Verify params
+ if (!myMenu) {
+ return nullptr;
+ }
+
+ // Allocate a new one
+ newItem = new menuItemMsg();
+
+ // Initialize the struct
+ newItem->next = myMenu->itemList;
+ newItem->prev = nullptr;
+ if (myMenu->itemList) {
+ myMenu->itemList->prev = newItem;
+ }
+ myMenu->itemList = newItem;
+
+ newItem->myMenu = myMenu;
+ newItem->tag = tag;
+ newItem->x1 = x;
+ newItem->y1 = y;
+ newItem->x2 = x + w - 1;
+ newItem->y2 = y + h - 1;
+ newItem->callback = nullptr;
+
+ if (!transparent) {
+ newItem->transparent = false;
+ newItem->background = nullptr;
+ } else {
+ newItem->transparent = true;
+ newItem->background = guiMenu::copyBackground(myMenu, x, y, w, h);
+ }
+
+ newItem->redraw = (DrawFunction)menuItemMsg::drawMsg;
+ newItem->destroy = (DestroyFunction)menuItem::destroyItem;
+ newItem->itemEventHandler = nullptr;
+
+ // Draw the message in now
+ (newItem->redraw)(newItem, myMenu, x, y, 0, 0);
+
+ // See if the screen is currently visible
+ myScreen = vmng_screen_find(myMenu, &status);
+ if (myScreen && (status == SCRN_ACTIVE)) {
+ RestoreScreens(myScreen->x1 + newItem->x1, myScreen->y1 + newItem->y1,
+ myScreen->x1 + newItem->x2, myScreen->y1 + newItem->y2);
+ }
+
+ return newItem;
+}
+
+void menuItemMsg::drawMsg(menuItemMsg *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32) {
+ Buffer *myBuff = nullptr;
+ Buffer *backgroundBuff = nullptr;
+ Sprite *mySprite = nullptr;
+
+ // Verify params
+ if (!myItem || !myMenu) {
+ return;
+ }
+
+ // If the item is marked transparent, get the background buffer
+ if (myItem->transparent) {
+ if (!myItem->background) {
+ return;
+ }
+ backgroundBuff = myItem->background->get_buffer();
+ if (!backgroundBuff) {
+ return;
+ }
+ }
+
+ // Get the button info and select the sprite
+ //myMsg = (menuItemMsg *)myItem->itemInfo;
+ switch (myItem->tag) {
+ case SL_TAG_SAVE_LABEL:
+ mySprite = _GM(menuSprites)[Burger::GUI::SL_SAVE_LABEL];
+ break;
+ case SL_TAG_LOAD_LABEL:
+ mySprite = _GM(menuSprites)[Burger::GUI::SL_LOAD_LABEL];
+ break;
+ case SL_TAG_THUMBNAIL:
+ mySprite = _GM(saveLoadThumbNail);
+ break;
+ }
+
+ // Get the menu buffer and draw the sprite to it
+ myBuff = myMenu->menuBuffer->get_buffer();
+ if (!myBuff) {
+ return;
+ }
+
+ // If the item is tagged as transparent, we need to fill in it's background behind it
+ if (backgroundBuff) {
+ gr_buffer_rect_copy_2(backgroundBuff, myBuff, 0, 0, x, y, backgroundBuff->w, backgroundBuff->h);
+ myItem->background->release();
+ } else if (myItem->tag == SL_TAG_THUMBNAIL && mySprite->w == 160) {
+ // Hack for handling smaller ScummVM thumbnails
+ for (int yp = y; yp < (y + SL_THUMBNAIL_H); ++yp) {
+ byte *line = myBuff->data + myBuff->stride * yp + x;
+ Common::fill(line, line + SL_THUMBNAIL_W, 0);
+ }
+
+ x += 25;
+ y += 25;
+ }
+
+ // Draw the sprite in
+ gui_DrawSprite(mySprite, myBuff, x, y);
+
+ // Release the menu buffer
+ myMenu->menuBuffer->release();
+}
+
} // namespace GUI
} // namespace M4
diff --git a/engines/m4/gui/gui_menu.h b/engines/m4/gui/gui_menu.h
index 9b938eefae8..571b7396fb7 100644
--- a/engines/m4/gui/gui_menu.h
+++ b/engines/m4/gui/gui_menu.h
@@ -98,6 +98,16 @@ enum options_menu_sprites {
OM_TOTAL_SPRITES
};
+enum save_load_menu_item_tags {
+ SL_TAG_SAVE = 100,
+ SL_TAG_SAVE_LABEL,
+ SL_TAG_LOAD,
+ SL_TAG_LOAD_LABEL,
+ SL_TAG_CANCEL,
+ SL_TAG_VSLIDER,
+ SL_TAG_THUMBNAIL
+};
+
} // namespace GUI
} // namespace Burger
@@ -173,7 +183,15 @@ struct menuItem {
struct menuItemMsg : public menuItem {
+private:
+ static void drawMsg(menuItemMsg *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32);
+
+public:
int32 itemFlags = 0;
+
+ static menuItemMsg *msgAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, bool transparent = false);
+ static void disableMsg(menuItemMsg *myItem, int32 tag, guiMenu *myMenu);
+ static void enableMsg(menuItemMsg *myItem, int32 tag, guiMenu *myMenu);
};
struct menuItemButton : public menuItem {
Commit: 01da5fd1cffc2ce0a440681975ced14d3d778d69
https://github.com/scummvm/scummvm/commit/01da5fd1cffc2ce0a440681975ced14d3d778d69
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2025-02-12T22:32:47-08:00
Commit Message:
M4: RIDDLE: Move slider methods to slider classes
Changed paths:
engines/m4/burger/gui/game_menu.cpp
engines/m4/burger/gui/game_menu.h
engines/m4/gui/gui_menu.cpp
engines/m4/gui/gui_menu.h
engines/m4/riddle/gui/game_menu.cpp
diff --git a/engines/m4/burger/gui/game_menu.cpp b/engines/m4/burger/gui/game_menu.cpp
index 2f2af9d904d..97c198d86f8 100644
--- a/engines/m4/burger/gui/game_menu.cpp
+++ b/engines/m4/burger/gui/game_menu.cpp
@@ -45,10 +45,6 @@ namespace M4 {
namespace Burger {
namespace GUI {
-static bool buttonClosesDialog;
-
-void UpdateThumbNails(int32 firstSlot, guiMenu *myMenu);
-
Sprite *menu_CreateThumbnail(int32 *spriteSize) {
Sprite *thumbNailSprite;
GrBuff *thumbNail;
@@ -235,678 +231,6 @@ Sprite *menu_CreateThumbnail(int32 *spriteSize) {
return thumbNailSprite;
}
-//------------------------------- HSLIDER MENU ITEM ---------------------------------//
-
-enum {
- H_THUMB_NORM = 0,
- H_THUMB_OVER = 1,
- H_THUMB_PRESS = 2
-};
-
-
-void menu_DrawHSlider(menuItemHSlider *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32) {
- Buffer *myBuff = nullptr;
- Buffer *backgroundBuff = nullptr;
- Sprite *mySprite = nullptr;
-
- // Verify params
- if (!myItem || !myMenu)
- return;
-
- // If the item is marked transparent, get the background buffer
- if (myItem->transparent) {
- if (!myItem->background) {
- return;
- }
- backgroundBuff = myItem->background->get_buffer();
- if (!backgroundBuff) {
- return;
- }
- }
-
- // Get the menu buffer and draw the sprite to it
- myBuff = myMenu->menuBuffer->get_buffer();
- if (!myBuff) {
- return;
- }
-
- // If the item is tagged as transparent, we need to fill in it's background behind it
- if (backgroundBuff) {
- gr_buffer_rect_copy_2(backgroundBuff, myBuff, 0, 0, x, y, backgroundBuff->w, backgroundBuff->h);
- myItem->background->release();
- }
-
- // Get the slider info and select the thumb sprite
- switch (myItem->itemFlags) {
- case H_THUMB_OVER:
- mySprite = _GM(menuSprites)[OM_SLIDER_BTN_OVER];
- break;
- case H_THUMB_PRESS:
- mySprite = _GM(menuSprites)[OM_SLIDER_BTN_PRESS];
- break;
- default:
- case H_THUMB_NORM:
- mySprite = _GM(menuSprites)[OM_SLIDER_BTN_NORM];
- break;
- }
-
- // Fill in everything left of the thumb with a hilite color
- if (myItem->thumbX > 2) {
- gr_color_set(menuItem::SLIDER_BAR_COLOR);
- gr_buffer_rect_fill(myBuff, myItem->x1 + 3, myItem->y1 + 9, myItem->thumbX, myItem->thumbH - 18);
- }
-
- // Draw in the thumb
- gui_DrawSprite(mySprite, myBuff, myItem->x1 + myItem->thumbX, myItem->y1);
-
- // Release the menu buffer
- myMenu->menuBuffer->release();
-}
-
-
-bool hslider_Handler(menuItemHSlider *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem) {
- bool redrawItem, execCallback, handled;
- ScreenContext *myScreen;
- int32 status;
- int32 deltaSlide;
- static bool movingFlag;
- static int32 movingX;
-
- // Verify params
- if (!myItem)
- return false;
-
- if (!(eventType == EVENT_MOUSE)) {
- return false;
- }
-
- redrawItem = false;
- handled = true;
- execCallback = false;
-
- switch (event) {
- case _ME_L_click:
- case _ME_doubleclick:
- if (menuItem::cursorInsideItem(myItem, x, y) && (x - myItem->x1 >= myItem->thumbX) &&
- (x - myItem->x1 <= myItem->thumbX + myItem->thumbW - 1)) {
- myItem->itemFlags = H_THUMB_PRESS;
- movingFlag = true;
- movingX = x;
- *currItem = myItem;
- redrawItem = true;
- } else {
- *currItem = nullptr;
- myItem->itemFlags = 0;
- redrawItem = true;
- }
- break;
-
- case _ME_L_drag:
- case _ME_doubleclick_drag:
- if (!*currItem) {
- return true;
- }
- if (movingFlag) {
- if (x < movingX) {
- deltaSlide = imath_min(myItem->thumbX, movingX - x);
- if (deltaSlide > 0) {
- myItem->thumbX -= deltaSlide;
- redrawItem = true;
- myItem->percent = myItem->thumbX * 100 / myItem->maxThumbX;
- execCallback = true;
- }
- } else if (x > movingX) {
- deltaSlide = imath_min(myItem->maxThumbX - myItem->thumbX, x - movingX);
- if (deltaSlide > 0) {
- myItem->thumbX += deltaSlide;
- redrawItem = true;
- myItem->percent = myItem->thumbX * 100 / myItem->maxThumbX;
- execCallback = true;
- }
- }
- movingX = x;
- if (movingX < (myItem->thumbX + myItem->x1)) {
- movingX = myItem->thumbX + myItem->x1;
- } else if (movingX > (myItem->thumbX + myItem->thumbW - 1 + myItem->x1)) {
- movingX = myItem->thumbX + myItem->thumbW - 1 + myItem->x1;
- }
- } else {
- *currItem = nullptr;
- }
- break;
-
- case _ME_L_release:
- case _ME_doubleclick_release:
- if (!*currItem) {
- return true;
- }
- movingFlag = false;
- if (menuItem::cursorInsideItem(myItem, x, y) && (x - myItem->x1 >= myItem->thumbX) &&
- (x - myItem->x1 <= myItem->thumbX + myItem->thumbW - 1)) {
- myItem->itemFlags = H_THUMB_OVER;
- *currItem = myItem;
- } else {
- myItem->itemFlags = H_THUMB_NORM;
- *currItem = nullptr;
- }
- redrawItem = true;
- execCallback = true;
- break;
-
- case _ME_move:
- if (menuItem::cursorInsideItem(myItem, x, y) && (x - myItem->x1 >= myItem->thumbX) &&
- (x - myItem->x1 <= myItem->thumbX + myItem->thumbW - 1)) {
- if (myItem->itemFlags != H_THUMB_OVER) {
- myItem->itemFlags = H_THUMB_OVER;
- *currItem = myItem;
- redrawItem = true;
- }
- } else {
- if (myItem->itemFlags != H_THUMB_NORM) {
- myItem->itemFlags = H_THUMB_NORM;
- *currItem = nullptr;
- redrawItem = true;
- handled = false;
- }
- }
- break;
-
- case _ME_L_hold:
- case _ME_doubleclick_hold:
- break;
- }
-
- // See if we need to redraw the hslider
- if (redrawItem) {
- (myItem->redraw)(myItem, myItem->myMenu, myItem->x1, myItem->y1, 0, 0);
- myScreen = vmng_screen_find(myItem->myMenu, &status);
- if (myScreen && (status == SCRN_ACTIVE)) {
- RestoreScreens(myScreen->x1 + myItem->x1, myScreen->y1 + myItem->y1,
- myScreen->x1 + myItem->x2, myScreen->y1 + myItem->y2);
- }
- }
-
- // See if we need to call the callback function
- if (execCallback && myItem->callback) {
- (myItem->callback)((void *)myItem, myItem->myMenu);
- myScreen = vmng_screen_find(myItem->myMenu, &status);
- if ((!myScreen) || (status != SCRN_ACTIVE)) {
- *currItem = nullptr;
- }
- }
-
- return handled;
-}
-
-
-menuItemHSlider *menu_HSliderAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h,
- int32 initPercent, CALLBACK callback, bool transparent) {
- menuItemHSlider *newItem;
- ScreenContext *myScreen;
- int32 status;
-
- // Verify params
- if (!myMenu) {
- return nullptr;
- }
-
- // Allocate a new one
- newItem = new menuItemHSlider();
-
- // Initialize the struct
- newItem->next = myMenu->itemList;
- newItem->prev = nullptr;
- if (myMenu->itemList) {
- myMenu->itemList->prev = newItem;
- }
- myMenu->itemList = newItem;
-
- newItem->myMenu = myMenu;
- newItem->tag = tag;
- newItem->x1 = x;
- newItem->y1 = y;
- newItem->x2 = x + w - 1;
- newItem->y2 = y + h - 1;
- newItem->callback = callback;
-
- if (!transparent) {
- newItem->transparent = false;
- newItem->background = nullptr;
- } else {
- newItem->transparent = true;
- newItem->background = guiMenu::copyBackground(myMenu, x, y, w, h);
- }
-
- // Intialize the new slider
- newItem->itemFlags = H_THUMB_NORM;
- newItem->thumbW = _GM(menuSprites)[OM_SLIDER_BTN_NORM]->w;
- newItem->thumbH = _GM(menuSprites)[OM_SLIDER_BTN_NORM]->h;
- newItem->maxThumbX = w - _GM(menuSprites)[OM_SLIDER_BTN_NORM]->w;
-
- if (initPercent < 0) {
- initPercent = 0;
- } else if (initPercent > 100) {
- initPercent = 100;
- }
-
- // Calculate the initial thumbX
- newItem->percent = initPercent;
- newItem->thumbX = initPercent * newItem->maxThumbX / 100;
-
- newItem->redraw = (DrawFunction)menu_DrawHSlider;
- newItem->destroy = (DestroyFunction)menuItem::destroyItem;
- newItem->itemEventHandler = (ItemHandlerFunction)hslider_Handler;
-
- // Draw the slider in now
- (newItem->redraw)(newItem, myMenu, x, y, 0, 0);
-
- // See if the screen is currently visible
- myScreen = vmng_screen_find(myMenu, &status);
- if (myScreen && (status == SCRN_ACTIVE)) {
- RestoreScreens(myScreen->x1 + newItem->x1, myScreen->y1 + newItem->y1,
- myScreen->x1 + newItem->x2, myScreen->y1 + newItem->y2);
- }
-
- return newItem;
-}
-
-
-//------------------------------- VSLIDER MENU ITEM ---------------------------------//
-
-enum {
- VS_NORM = 0x0000,
- VS_OVER = 0x0001,
- VS_PRESS = 0x0002,
- VS_GREY = 0x0003,
- VS_STATUS = 0x000f,
- VS_UP = 0x0010,
- VS_PAGE_UP = 0x0020,
- VS_THUMB = 0x0030,
- VS_PAGE_DOWN = 0x0040,
- VS_DOWN = 0x0050,
- VS_COMPONENT = 0x00f0
-};
-
-
-void menu_DrawVSlider(menuItemVSlider *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32) {
- Buffer *myBuff = nullptr;
- Buffer *backgroundBuff = nullptr;
- Sprite *upSprite = nullptr;
- Sprite *thumbSprite = nullptr;
- Sprite *downSprite = nullptr;
- Sprite *vbarSprite = nullptr;
-
- // Verify params
- if (!myItem || !myMenu)
- return;
-
- // If the item is marked transparent, get the background buffer
- if (myItem->transparent) {
- if (!myItem->background) {
- return;
- }
- backgroundBuff = myItem->background->get_buffer();
- if (!backgroundBuff) {
- return;
- }
- }
-
- // Get the menu buffer
- myBuff = myMenu->menuBuffer->get_buffer();
- if (!myBuff) {
- return;
- }
-
- // If the item is tagged as transparent, we need to fill in it's background behind it
- if (backgroundBuff) {
- gr_buffer_rect_copy_2(backgroundBuff, myBuff, 0, 0, x, y, backgroundBuff->w, backgroundBuff->h);
- myItem->background->release();
- }
-
- // Set the different sprite components
- vbarSprite = _GM(menuSprites)[Burger::GUI::SL_SCROLL_BAR];
- upSprite = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_NORM];
- thumbSprite = _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_NORM];
- downSprite = _GM(menuSprites)[Burger::GUI::SL_DOWN_BTN_NORM];
-
- if ((myItem->itemFlags & VS_STATUS) == VS_GREY) {
- upSprite = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_GREY];
- thumbSprite = nullptr;
- downSprite = _GM(menuSprites)[Burger::GUI::SL_DOWN_BTN_GREY];
- } else if ((myItem->itemFlags & VS_STATUS) == VS_OVER) {
- if ((myItem->itemFlags & VS_COMPONENT) == VS_UP) {
- upSprite = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_OVER];
- } else if ((myItem->itemFlags & VS_COMPONENT) == VS_THUMB) {
- thumbSprite = _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_OVER];
- } else if ((myItem->itemFlags & VS_COMPONENT) == VS_DOWN) {
- downSprite = _GM(menuSprites)[Burger::GUI::SL_DOWN_BTN_OVER];
- }
- } else if ((myItem->itemFlags & VS_STATUS) == VS_PRESS) {
- if ((myItem->itemFlags & VS_COMPONENT) == VS_UP) {
- upSprite = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_PRESS];
- } else if ((myItem->itemFlags & VS_COMPONENT) == VS_THUMB) {
- thumbSprite = _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_PRESS];
- } else if ((myItem->itemFlags & VS_COMPONENT) == VS_DOWN) {
- downSprite = _GM(menuSprites)[Burger::GUI::SL_DOWN_BTN_PRESS];
- }
- }
-
- // Draw the sprite comonents
- gui_DrawSprite(vbarSprite, myBuff, x, y + upSprite->h);
- gui_DrawSprite(upSprite, myBuff, x, y);
- gui_DrawSprite(thumbSprite, myBuff, x, y + myItem->thumbY);
- gui_DrawSprite(downSprite, myBuff, x, y + upSprite->h + vbarSprite->h);
-
- // Release the menu buffer
- myMenu->menuBuffer->release();
-}
-
-int32 vslider_WhereIsCursor(menuItemVSlider *myVSlider, int32 y) {
- if (y < myVSlider->minThumbY) {
- return VS_UP;
- } else if (y < myVSlider->thumbY) {
- return VS_PAGE_UP;
- } else if (y < myVSlider->thumbY + myVSlider->thumbH) {
- return VS_THUMB;
- } else if (y < myVSlider->maxThumbY + myVSlider->thumbH) {
- return VS_PAGE_DOWN;
- } else {
- return VS_DOWN;
- }
-}
-
-bool vslider_Handler(menuItemVSlider *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem) {
- bool redrawItem, execCallback, handled;
- int32 tempFlags;
- ScreenContext *myScreen;
- int32 status;
- int32 deltaSlide;
- int32 currTime;
- static bool movingFlag;
- static int32 movingY;
- static int32 callbackTime;
-
- // Verify params
- if (!myItem)
- return false;
-
- if (!(eventType == EVENT_MOUSE))
- return false;
-
- if ((myItem->itemFlags & VS_STATUS) == VS_GREY) {
- *currItem = nullptr;
- return false;
- }
-
- currTime = timer_read_60();
- redrawItem = false;
- handled = true;
- execCallback = false;
-
- switch (event) {
- case _ME_L_click:
- case _ME_doubleclick:
- if (menuItem::cursorInsideItem(myItem, x, y)) {
- // digi_play(inv_click_snd, 2, 255, -1, inv_click_snd_room_lock);
- *currItem = myItem;
- tempFlags = vslider_WhereIsCursor(myItem, y - myItem->y1);
- if (tempFlags == VS_THUMB) {
- movingFlag = true;
- movingY = y;
- }
- if ((tempFlags == VS_PAGE_UP) || (tempFlags == VS_PAGE_DOWN)) {
- myItem->itemFlags = tempFlags + VS_NORM;
- } else {
- myItem->itemFlags = tempFlags + VS_PRESS;
- redrawItem = true;
- }
- execCallback = true;
- } else {
- *currItem = nullptr;
- myItem->itemFlags = VS_NORM;
- redrawItem = true;
- }
- break;
-
- case _ME_L_drag:
- case _ME_doubleclick_drag:
- if (!*currItem) {
- return true;
- }
- if (movingFlag) {
- if (y < movingY) {
- deltaSlide = imath_min(myItem->thumbY - myItem->minThumbY, movingY - y);
- if (deltaSlide > 0) {
- myItem->thumbY -= deltaSlide;
- myItem->percent = ((myItem->thumbY - myItem->minThumbY) * 100) /
- (myItem->maxThumbY - myItem->minThumbY);
- redrawItem = true;
- execCallback = true;
- }
- } else if (y > movingY) {
- deltaSlide = imath_min(myItem->maxThumbY - myItem->thumbY, y - movingY);
- if (deltaSlide > 0) {
- myItem->thumbY += deltaSlide;
- myItem->percent = ((myItem->thumbY - myItem->minThumbY) * 100) /
- (myItem->maxThumbY - myItem->minThumbY);
- redrawItem = true;
- execCallback = true;
- }
- }
- movingY = y;
- if (movingY < (myItem->thumbY + myItem->y1)) {
- movingY = myItem->thumbY + myItem->y1;
- } else if (movingY > (myItem->thumbY + myItem->thumbH - 1 + myItem->y1)) {
- movingY = myItem->thumbY + myItem->thumbH - 1 + myItem->y1;
- }
- } else {
- if (menuItem::cursorInsideItem(myItem, x, y)) {
- tempFlags = vslider_WhereIsCursor(myItem, y - myItem->y1);
- if ((myItem->itemFlags & VS_COMPONENT) == tempFlags) {
- if ((tempFlags != VS_PAGE_UP) && (tempFlags != VS_PAGE_DOWN) &&
- ((myItem->itemFlags & VS_STATUS) != VS_PRESS)) {
- myItem->itemFlags = tempFlags + VS_PRESS;
- redrawItem = true;
- }
- if (currTime - callbackTime > 6) {
- execCallback = true;
- }
- } else {
- if ((myItem->itemFlags & VS_STATUS) != VS_OVER) {
- myItem->itemFlags = (myItem->itemFlags & VS_COMPONENT) + VS_OVER;
- redrawItem = true;
- }
- }
- execCallback = true;
- } else {
- if ((myItem->itemFlags & VS_STATUS) != VS_OVER) {
- myItem->itemFlags = (myItem->itemFlags & VS_COMPONENT) + VS_OVER;
- redrawItem = true;
- }
- }
- }
- break;
-
- case _ME_L_release:
- case _ME_doubleclick_release:
- movingFlag = false;
- if (menuItem::cursorInsideItem(myItem, x, y)) {
- tempFlags = vslider_WhereIsCursor(myItem, y - myItem->y1);
- if ((tempFlags == VS_PAGE_UP) || (tempFlags == VS_PAGE_DOWN)) {
- myItem->itemFlags = VS_NORM;
- } else {
- myItem->itemFlags = tempFlags + VS_OVER;
- *currItem = myItem;
- }
- } else {
- myItem->itemFlags = VS_NORM;
- *currItem = nullptr;
- }
- redrawItem = true;
- if (!_GM(currMenuIsSave)) {
- UpdateThumbNails(_GM(firstSlotIndex), (guiMenu *)myItem->myMenu);
- }
- break;
-
- case _ME_move:
- if (menuItem::cursorInsideItem(myItem, x, y)) {
- *currItem = myItem;
- tempFlags = vslider_WhereIsCursor(myItem, y - myItem->y1);
- if ((myItem->itemFlags & VS_COMPONENT) != tempFlags) {
- if ((tempFlags == VS_PAGE_UP) || (tempFlags == VS_PAGE_DOWN)) {
- myItem->itemFlags = VS_NORM;
- } else {
- myItem->itemFlags = tempFlags + VS_OVER;
- }
- redrawItem = true;
- }
- } else {
- *currItem = nullptr;
- if (myItem->itemFlags != VS_NORM) {
- myItem->itemFlags = VS_NORM;
- redrawItem = true;
- handled = false;
- }
- }
- break;
-
- case _ME_L_hold:
- case _ME_doubleclick_hold:
- if (!*currItem) {
- return true;
- }
- if (menuItem::cursorInsideItem(myItem, x, y)) {
- tempFlags = vslider_WhereIsCursor(myItem, y - myItem->y1);
- if ((myItem->itemFlags & VS_COMPONENT) == tempFlags) {
- if (currTime - callbackTime > 6) {
- execCallback = true;
- }
- }
- }
- break;
- }
-
- // See if we need to redraw the vslider
- if (redrawItem) {
- (myItem->redraw)(myItem, myItem->myMenu, myItem->x1, myItem->y1, 0, 0);
- myScreen = vmng_screen_find(myItem->myMenu, &status);
- if (myScreen && (status == SCRN_ACTIVE)) {
- RestoreScreens(myScreen->x1 + myItem->x1, myScreen->y1 + myItem->y1,
- myScreen->x1 + myItem->x2, myScreen->y1 + myItem->y2);
- }
- }
-
- // See if we need to call the callback function
- if (execCallback && myItem->callback) {
- callbackTime = currTime;
- (myItem->callback)((void *)myItem, myItem->myMenu);
- myScreen = vmng_screen_find(myItem->myMenu, &status);
- if ((!myScreen) || (status != SCRN_ACTIVE)) {
- *currItem = nullptr;
- }
- }
-
- return handled;
-}
-
-
-menuItemVSlider *menu_VSliderAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h,
- int32 initPercent, CALLBACK callback, bool transparent) {
- menuItemVSlider *newItem;
- ScreenContext *myScreen;
- int32 status;
-
- // Verify params
- if (!myMenu)
- return nullptr;
-
- // Allocate a new one
- newItem = new menuItemVSlider();
-
- // Initialize the struct
- newItem->next = myMenu->itemList;
- newItem->prev = nullptr;
- if (myMenu->itemList) {
- myMenu->itemList->prev = newItem;
- }
- myMenu->itemList = newItem;
-
- newItem->myMenu = myMenu;
- newItem->tag = tag;
- newItem->x1 = x;
- newItem->y1 = y;
- newItem->x2 = x + w - 1;
- newItem->y2 = y + h - 1;
- newItem->callback = callback;
-
- if (!transparent) {
- newItem->transparent = false;
- newItem->background = nullptr;
- } else {
- newItem->transparent = true;
- newItem->background = guiMenu::copyBackground(myMenu, x, y, w, h);
- }
-
- newItem->itemFlags = VS_NORM;
-
- newItem->thumbW = _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_NORM]->w;
- newItem->thumbH = _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_NORM]->h;
-
- newItem->minThumbY = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_NORM]->h + 1;
- newItem->maxThumbY = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_NORM]->h + _GM(menuSprites)[Burger::GUI::SL_SCROLL_BAR]->h
- - _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_NORM]->h - 1;
-
- // Calculate the initial thumbY
- newItem->percent = imath_max(imath_min(initPercent, 100), 0);
- newItem->thumbY = newItem->minThumbY +
- ((newItem->percent * (newItem->maxThumbY - newItem->minThumbY)) / 100);
-
- newItem->redraw = (DrawFunction)menu_DrawVSlider;
- newItem->destroy = (DestroyFunction)menuItem::destroyItem;
- newItem->itemEventHandler = (ItemHandlerFunction)vslider_Handler;
-
- // Draw the vslider in now
- (newItem->redraw)(newItem, myMenu, x, y, 0, 0);
-
- // See if the screen is currently visible
- myScreen = vmng_screen_find(myMenu, &status);
- if (myScreen && (status == SCRN_ACTIVE)) {
- RestoreScreens(myScreen->x1 + newItem->x1, myScreen->y1 + newItem->y1,
- myScreen->x1 + newItem->x2, myScreen->y1 + newItem->y2);
- }
-
- return newItem;
-}
-
-
-void menu_DisableVSlider(menuItemVSlider *myItem, int32 tag, guiMenu *myMenu) {
- // Verify params
- if (!myMenu)
- return;
-
- if (!myItem)
- myItem = (menuItemVSlider *)guiMenu::getItem(tag, myMenu);
- if (!myItem)
- return;
-
- myItem->itemFlags = VS_GREY;
-}
-
-
-void menu_EnableVSlider(menuItemVSlider *myItem, int32 tag, guiMenu *myMenu) {
- // Verify params
- if (!myMenu)
- return;
-
- if (!myItem)
- myItem = (menuItemVSlider *)guiMenu::getItem(tag, myMenu);
- if (!myItem)
- return;
-
- myItem->itemFlags = VS_NORM;
-}
-
-
//----------------------------- TEXTFIELD MENU ITEM ---------------------------------//
enum {
@@ -1306,7 +630,7 @@ void cb_Game_Save(void *, void *) {
// Destroy the game menu
DestroyGameMenu();
guiMenu::shutdown(true);
- buttonClosesDialog = true;
+ _GM(buttonClosesDialog) = true;
// Create the save game menu
g_engine->showSaveScreen();
@@ -1316,7 +640,7 @@ void cb_Game_Load(void *, void *) {
// Destroy the game menu
DestroyGameMenu();
guiMenu::shutdown(true);
- buttonClosesDialog = true;
+ _GM(buttonClosesDialog) = true;
// Create the save game menu
g_engine->showLoadScreen(M4Engine::kLoadFromGameDialog);
@@ -1348,7 +672,7 @@ void cb_Game_Main(void *, void *) {
void cb_Game_Options(void *, void *) {
// Destroy the game menu
DestroyGameMenu();
- buttonClosesDialog = true;
+ _GM(buttonClosesDialog) = true;
// Create the options menu
CreateOptionsMenu(nullptr);
@@ -1388,22 +712,22 @@ void CreateGameMenuMain(RGB8 *myPalette) {
return;
}
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_MAIN, GM_MAIN_X, GM_MAIN_Y, GM_MAIN_W, GM_MAIN_H, cb_Game_Main);
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_OPTIONS, GM_OPTIONS_X, GM_OPTIONS_Y, GM_OPTIONS_W, GM_OPTIONS_H, cb_Game_Options);
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_RESUME, GM_RESUME_X, GM_RESUME_Y, GM_RESUME_W, GM_RESUME_H, cb_Game_Resume);
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_QUIT, GM_QUIT_X, GM_QUIT_Y, GM_QUIT_W, GM_QUIT_H, cb_Game_Quit);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_MAIN, GM_MAIN_X, GM_MAIN_Y, GM_MAIN_W, GM_MAIN_H, cb_Game_Main);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_OPTIONS, GM_OPTIONS_X, GM_OPTIONS_Y, GM_OPTIONS_W, GM_OPTIONS_H, cb_Game_Options);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_RESUME, GM_RESUME_X, GM_RESUME_Y, GM_RESUME_W, GM_RESUME_H, cb_Game_Resume);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_QUIT, GM_QUIT_X, GM_QUIT_Y, GM_QUIT_W, GM_QUIT_H, cb_Game_Quit);
if (!_GM(gameMenuFromMain)) {
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_SAVE, GM_SAVE_X, GM_SAVE_Y, GM_SAVE_W, GM_SAVE_H, cb_Game_Save);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_SAVE, GM_SAVE_X, GM_SAVE_Y, GM_SAVE_W, GM_SAVE_H, cb_Game_Save);
} else {
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_SAVE, GM_SAVE_X, GM_SAVE_Y, GM_SAVE_W, GM_SAVE_H, cb_Game_Save, menuItemButton::BTN_TYPE_GM_GENERIC, true);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_SAVE, GM_SAVE_X, GM_SAVE_Y, GM_SAVE_W, GM_SAVE_H, cb_Game_Save, menuItemButton::BTN_TYPE_GM_GENERIC, true);
}
// See if there are any games to load
if (g_engine->savesExist()) {
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_LOAD, GM_LOAD_X, GM_LOAD_Y, GM_LOAD_W, GM_LOAD_H, cb_Game_Load);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_LOAD, GM_LOAD_X, GM_LOAD_Y, GM_LOAD_W, GM_LOAD_H, cb_Game_Load);
} else {
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_LOAD, GM_LOAD_X, GM_LOAD_Y, GM_LOAD_W, GM_LOAD_H, cb_Game_Load, menuItemButton::BTN_TYPE_GM_GENERIC, true);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_LOAD, GM_LOAD_X, GM_LOAD_Y, GM_LOAD_W, GM_LOAD_H, cb_Game_Load, menuItemButton::BTN_TYPE_GM_GENERIC, true);
}
// Configure the game so pressing <esc> will cause the menu to disappear and the game to resume
@@ -1426,7 +750,7 @@ void cb_Options_Game_Cancel(void *, void *) {
// Destroy the options menu
DestroyOptionsMenu();
- buttonClosesDialog = true;
+ _GM(buttonClosesDialog) = true;
// Create the options menu
CreateGameMenuMain(nullptr);
@@ -1435,7 +759,7 @@ void cb_Options_Game_Cancel(void *, void *) {
void cb_Options_Game_Done(void *, void *) {
// Destroy the options menu
DestroyOptionsMenu();
- buttonClosesDialog = true;
+ _GM(buttonClosesDialog) = true;
// Create the options menu
CreateGameMenuMain(nullptr);
@@ -1495,11 +819,11 @@ void CreateOptionsMenu(RGB8 *myPalette) {
return;
}
- menuItemButton::buttonAdd(_GM(opMenu), OM_TAG_CANCEL, OM_CANCEL_X, OM_CANCEL_Y, OM_CANCEL_W, OM_CANCEL_H, cb_Options_Game_Cancel, menuItemButton::BTN_TYPE_OM_CANCEL);
- menuItemButton::buttonAdd(_GM(opMenu), OM_TAG_DONE, OM_DONE_X, OM_DONE_Y, OM_DONE_W, OM_DONE_H, cb_Options_Game_Done, menuItemButton::BTN_TYPE_OM_DONE, true);
- menu_HSliderAdd(_GM(opMenu), OM_TAG_DIGI, OM_DIGI_X, OM_DIGI_Y, OM_DIGI_W, OM_DIGI_H, digi_get_overall_volume(),
+ menuItemButton::add(_GM(opMenu), OM_TAG_CANCEL, OM_CANCEL_X, OM_CANCEL_Y, OM_CANCEL_W, OM_CANCEL_H, cb_Options_Game_Cancel, menuItemButton::BTN_TYPE_OM_CANCEL);
+ menuItemButton::add(_GM(opMenu), OM_TAG_DONE, OM_DONE_X, OM_DONE_Y, OM_DONE_W, OM_DONE_H, cb_Options_Game_Done, menuItemButton::BTN_TYPE_OM_DONE, true);
+ menuItemHSlider::add(_GM(opMenu), OM_TAG_DIGI, OM_DIGI_X, OM_DIGI_Y, OM_DIGI_W, OM_DIGI_H, digi_get_overall_volume(),
(CALLBACK)cb_Options_Digi, true);
- menu_HSliderAdd(_GM(opMenu), OM_TAG_DIGESTABILITY, OM_DIGESTABILITY_X, OM_DIGESTABILITY_Y,
+ menuItemHSlider::add(_GM(opMenu), OM_TAG_DIGESTABILITY, OM_DIGESTABILITY_X, OM_DIGESTABILITY_Y,
OM_DIGESTABILITY_W, OM_DIGESTABILITY_H, _G(flags)[digestability],
(CALLBACK)cb_Options_Digestability, true);
@@ -1587,7 +911,7 @@ void CreateErrMenu(RGB8 *myPalette) {
_GM(errMenu)->menuBuffer->release();
// Add the done button
- menuItemButton::buttonAdd(_GM(errMenu), EM_TAG_RETURN, EM_RETURN_X, EM_RETURN_Y, EM_RETURN_W, EM_RETURN_H, cb_Err_Done);
+ menuItemButton::add(_GM(errMenu), EM_TAG_RETURN, EM_RETURN_X, EM_RETURN_Y, EM_RETURN_W, EM_RETURN_H, cb_Err_Done);
// Configure the game so pressing <esc> will cause the menu to disappear and the gamemenu to reappear
guiMenu::configure(_GM(errMenu), cb_Err_Done, cb_Err_Done);
@@ -1603,142 +927,37 @@ void DestroySaveLoadMenu(bool saveMenu);
void cb_SaveLoad_Slot(menuItemButton *theItem, guiMenu *myMenu);
bool load_Handler(menuItemButton *theItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem);
-
-bool LoadThumbNail(int32 slotNum) {
- Sprite *&thumbNailSprite = _GM(thumbNails)[slotNum];
- return g_engine->loadSaveThumbnail(slotNum + 1, thumbNailSprite);
-}
-
-
-void UnloadThumbNail(int32 slotNum) {
- if (_GM(thumbNails)[slotNum]->sourceHandle) {
- HUnLock(_GM(thumbNails)[slotNum]->sourceHandle);
- DisposeHandle(_GM(thumbNails)[slotNum]->sourceHandle);
- _GM(thumbNails)[slotNum]->sourceHandle = nullptr;
- }
-}
-
-
-void UpdateThumbNails(int32 firstSlot, guiMenu *myMenu) {
- int32 i, startIndex, endIndex;
-
- // Make sure there is something to update
- if (firstSlot == _GM(thumbIndex)) {
- return;
- }
-
- // Ensure firstSlot is in a valid range
- firstSlot = imath_max(imath_min(firstSlot, 89), 0);
-
- if (firstSlot > _GM(thumbIndex)) {
- // Dump Out all thumbnails in slots which don't overlap
- startIndex = _GM(thumbIndex);
- endIndex = imath_min(_GM(thumbIndex) + 9, firstSlot - 1);
- for (i = startIndex; i <= endIndex; i++) {
- UnloadThumbNail(i);
- }
-
- // Load in all thumbnails missing thumbnails
- startIndex = imath_max(_GM(thumbIndex) + 10, firstSlot);
- endIndex = imath_min(firstSlot + 9, 98);
- for (i = startIndex; i <= endIndex; i++) {
- if (_GM(slotInUse)[i]) {
- if (!LoadThumbNail(i)) {
- _GM(slotInUse)[i] = false;
- menuItemButton::disableButton(nullptr, 1001 + i - firstSlot, myMenu);
- guiMenu::itemRefresh(nullptr, 1001 + i - firstSlot, myMenu);
- }
- }
- }
- } else {
- // Else firstSlot < _GM(thumbIndex)
- // Dump Out all thumbnails in slots which don't overlap
- startIndex = imath_max(firstSlot + 10, _GM(thumbIndex));
- endIndex = imath_min(_GM(thumbIndex) + 9, 98);
- for (i = startIndex; i <= endIndex; i++) {
- UnloadThumbNail(i);
- }
-
- // Load in all thumbnails missing thumbnails
- startIndex = firstSlot;
- endIndex = imath_min(firstSlot + 9, _GM(thumbIndex) - 1);
- for (i = startIndex; i <= endIndex; i++) {
- if (_GM(slotInUse)[i]) {
- if (!LoadThumbNail(i)) {
- _GM(slotInUse)[i] = false;
- menuItemButton::disableButton(nullptr, 1001 + i - firstSlot, myMenu);
- guiMenu::itemRefresh(nullptr, 1001 + i - firstSlot, myMenu);
- }
- }
- }
- }
-
- // Set the var
- _GM(thumbIndex) = firstSlot;
-}
-
-
-void SetFirstSlot(int32 firstSlot, guiMenu *myMenu) {
- menuItemButton *myButton;
- int32 i;
-
- if (!myMenu) {
- return;
- }
-
- // Ensure firstSlot is in a valid range
- firstSlot = imath_max(imath_min(firstSlot, 89), 0);
-
- // Change the prompt and special tag of each of the slot buttons
- for (i = 0; i < MAX_SLOTS_SHOWN; i++) {
- myButton = (menuItemButton *)guiMenu::getItem(i + 1001, myMenu);
-
- myButton->prompt = _GM(slotTitles)[firstSlot + i];
- if (_GM(currMenuIsSave) || _GM(slotInUse)[firstSlot + i]) {
- myButton->itemFlags = menuItemButton::BTN_STATE_NORM;
- } else {
- myButton->itemFlags = menuItemButton::BTN_STATE_GREY;
- }
-
- myButton->specialTag = firstSlot + i + 1;
- guiMenu::itemRefresh(myButton, i + 1001, myMenu);
- }
-}
-
-
void cb_SaveLoad_VSlider(menuItemVSlider *myItem, guiMenu *myMenu) {
bool redraw;
if (!myMenu || !myItem)
return;
- if ((myItem->itemFlags & VS_COMPONENT) != VS_THUMB) {
-
+ if ((myItem->itemFlags & menuItemVSlider::VS_COMPONENT) != menuItemVSlider::VS_THUMB) {
redraw = (DrawFunction)false;
- switch (myItem->itemFlags & VS_COMPONENT) {
-
- case VS_UP:
+ switch (myItem->itemFlags & menuItemVSlider::VS_COMPONENT) {
+ case menuItemVSlider::VS_UP:
if (_GM(firstSlotIndex) > 0) {
_GM(firstSlotIndex)--;
redraw = (DrawFunction)true;
}
break;
- case VS_PAGE_UP:
+ case menuItemVSlider::VS_PAGE_UP:
if (_GM(firstSlotIndex) > 0) {
_GM(firstSlotIndex) = imath_max(_GM(firstSlotIndex) - 10, 0);
redraw = (DrawFunction)true;
}
break;
- case VS_PAGE_DOWN:
+ case menuItemVSlider::VS_PAGE_DOWN:
if (_GM(firstSlotIndex) < 89) {
_GM(firstSlotIndex) = imath_min(_GM(firstSlotIndex) + 10, 89);
redraw = (DrawFunction)true;
}
break;
- case VS_DOWN:
+ case menuItemVSlider::VS_DOWN:
if (_GM(firstSlotIndex) < 89) {
_GM(firstSlotIndex)++;
redraw = (DrawFunction)true;
@@ -1871,10 +1090,10 @@ void cb_SaveLoad_Cancel(menuItemButton *, guiMenu *myMenu) {
// Add the button back in
if (_GM(currMenuIsSave)) {
- menuItemButton::buttonAdd(myMenu, 1000 + _GM(slotSelected) - _GM(firstSlotIndex), x, y, w, h,
+ menuItemButton::add(myMenu, 1000 + _GM(slotSelected) - _GM(firstSlotIndex), x, y, w, h,
(CALLBACK)cb_SaveLoad_Slot, menuItemButton::BTN_TYPE_SL_TEXT, false, true, _GM(slotTitles)[_GM(slotSelected) - 1]);
} else {
- menuItemButton::buttonAdd(myMenu, 1000 + _GM(slotSelected) - _GM(firstSlotIndex), x, y, w, h,
+ menuItemButton::add(myMenu, 1000 + _GM(slotSelected) - _GM(firstSlotIndex), x, y, w, h,
(CALLBACK)cb_SaveLoad_Slot, menuItemButton::BTN_TYPE_SL_TEXT, false, true, _GM(slotTitles)[_GM(slotSelected) - 1],
(ItemHandlerFunction)load_Handler);
@@ -1887,7 +1106,7 @@ void cb_SaveLoad_Cancel(menuItemButton *, guiMenu *myMenu) {
SetFirstSlot(_GM(firstSlotIndex), myMenu);
// Enable the slider
- menu_EnableVSlider(nullptr, SL_TAG_VSLIDER, myMenu);
+ menuItemVSlider::enableVSlider(nullptr, SL_TAG_VSLIDER, myMenu);
guiMenu::itemRefresh(nullptr, SL_TAG_VSLIDER, myMenu);
// Disable the save/load button
@@ -1917,7 +1136,7 @@ void cb_SaveLoad_Cancel(menuItemButton *, guiMenu *myMenu) {
}
}
- buttonClosesDialog = true;
+ _GM(buttonClosesDialog) = true;
}
@@ -1968,7 +1187,7 @@ void cb_SaveLoad_Slot(menuItemButton *myButton, guiMenu *myMenu) {
}
// Disable the slider
- menu_DisableVSlider(nullptr, SL_TAG_VSLIDER, myMenu);
+ menuItemVSlider::disableVSlider(nullptr, SL_TAG_VSLIDER, myMenu);
guiMenu::itemRefresh(nullptr, SL_TAG_VSLIDER, myMenu);
// Enable the save/load button
@@ -2116,18 +1335,18 @@ void CreateSaveLoadMenu(RGB8 *myPalette, bool saveMenu) {
if (_GM(currMenuIsSave)) {
menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_SAVE_LABEL, SL_SAVE_LABEL_X, SL_SAVE_LABEL_Y, SL_SAVE_LABEL_W, SL_SAVE_LABEL_H);
- menuItemButton::buttonAdd(_GM(slMenu), SL_TAG_SAVE, SL_SAVE_X, SL_SAVE_Y, SL_SAVE_W, SL_SAVE_H,
+ menuItemButton::add(_GM(slMenu), SL_TAG_SAVE, SL_SAVE_X, SL_SAVE_Y, SL_SAVE_W, SL_SAVE_H,
(CALLBACK)cb_SaveLoad_Save, menuItemButton::BTN_TYPE_SL_SAVE, true);
} else {
menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_LOAD_LABEL, SL_LOAD_LABEL_X, SL_LOAD_LABEL_Y, SL_LOAD_LABEL_W, SL_LOAD_LABEL_H);
- menuItemButton::buttonAdd(_GM(slMenu), SL_TAG_LOAD, SL_LOAD_X, SL_LOAD_Y, SL_LOAD_W, SL_LOAD_H,
+ menuItemButton::add(_GM(slMenu), SL_TAG_LOAD, SL_LOAD_X, SL_LOAD_Y, SL_LOAD_W, SL_LOAD_H,
(CALLBACK)cb_SaveLoad_Load, menuItemButton::BTN_TYPE_SL_LOAD, true);
}
- menuItemButton::buttonAdd(_GM(slMenu), SL_TAG_CANCEL, SL_CANCEL_X, SL_CANCEL_Y, SL_CANCEL_W, SL_CANCEL_H,
+ menuItemButton::add(_GM(slMenu), SL_TAG_CANCEL, SL_CANCEL_X, SL_CANCEL_Y, SL_CANCEL_W, SL_CANCEL_H,
(CALLBACK)cb_SaveLoad_Cancel, menuItemButton::BTN_TYPE_SL_CANCEL);
- menu_VSliderAdd(_GM(slMenu), SL_TAG_VSLIDER, SL_SLIDER_X, SL_SLIDER_Y, SL_SLIDER_W, SL_SLIDER_H,
+ menuItemVSlider::add(_GM(slMenu), SL_TAG_VSLIDER, SL_SLIDER_X, SL_SLIDER_Y, SL_SLIDER_W, SL_SLIDER_H,
0, (CALLBACK)cb_SaveLoad_VSlider);
InitializeSlotTables();
@@ -2141,7 +1360,7 @@ void CreateSaveLoadMenu(RGB8 *myPalette, bool saveMenu) {
}
for (int32 i = 0; i < MAX_SLOTS_SHOWN; i++) {
- menuItemButton::buttonAdd(_GM(slMenu), 1001 + i,
+ menuItemButton::add(_GM(slMenu), 1001 + i,
SL_SCROLL_FIELD_X, SL_SCROLL_FIELD_Y + i * SL_SCROLL_LINE_H,
SL_SCROLL_LINE_W, SL_SCROLL_LINE_H,
(CALLBACK)cb_SaveLoad_Slot, menuItemButton::BTN_TYPE_SL_TEXT,
diff --git a/engines/m4/burger/gui/game_menu.h b/engines/m4/burger/gui/game_menu.h
index 506dbe000eb..6a17d82060b 100644
--- a/engines/m4/burger/gui/game_menu.h
+++ b/engines/m4/burger/gui/game_menu.h
@@ -43,18 +43,6 @@ using M4::GUI::Sprite;
using M4::GUI::CALLBACK;
using M4::GUI::ItemHandlerFunction;
-// SPECIFIC ITEM FUNCTIONS
-
-// Horizontal sliders
-menuItemHSlider *menu_HSliderAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h,
- int32 initPercent = 0, CALLBACK callback = nullptr, bool transparent = false);
-
-// Vertical sliders
-menuItemVSlider *menu_VSliderAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h,
- int32 initPercent = 0, CALLBACK callback = nullptr, bool transparent = false);
-void menu_DisableVSlider(menuItemVSlider *myItem, int32 tag, guiMenu *myMenu);
-void menu_EnableVSlider(menuItemVSlider *myItem, int32 tag, guiMenu *myMenu);
-
// Textfields
menuItemTextField *menu_TextFieldAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, int32 initFlags,
const char *prompt = nullptr, int32 specialtag = 0, CALLBACK callback = nullptr, bool transparent = false);
@@ -143,8 +131,6 @@ enum game_menu_button_tags {
#define SL_THUMBNAIL_X 66
#define SL_THUMBNAIL_Y 28
-#define SL_THUMBNAIL_W 215
-#define SL_THUMBNAIL_H 162
/**
* Options menu defines
diff --git a/engines/m4/gui/gui_menu.cpp b/engines/m4/gui/gui_menu.cpp
index 3527e9e7d23..3268e477b8c 100644
--- a/engines/m4/gui/gui_menu.cpp
+++ b/engines/m4/gui/gui_menu.cpp
@@ -78,6 +78,106 @@ void gui_DrawSprite(Sprite *mySprite, Buffer *myBuff, int32 x, int32 y) {
}
}
+bool LoadThumbNail(int32 slotNum) {
+ Sprite *&thumbNailSprite = _GM(thumbNails)[slotNum];
+ return g_engine->loadSaveThumbnail(slotNum + 1, thumbNailSprite);
+}
+
+void UnloadThumbNail(int32 slotNum) {
+ if (_GM(thumbNails)[slotNum]->sourceHandle) {
+ HUnLock(_GM(thumbNails)[slotNum]->sourceHandle);
+ DisposeHandle(_GM(thumbNails)[slotNum]->sourceHandle);
+ _GM(thumbNails)[slotNum]->sourceHandle = nullptr;
+ }
+}
+
+void UpdateThumbNails(int32 firstSlot, guiMenu *myMenu) {
+ int32 i, startIndex, endIndex;
+
+ // Make sure there is something to update
+ if (firstSlot == _GM(thumbIndex)) {
+ return;
+ }
+
+ // Ensure firstSlot is in a valid range
+ firstSlot = imath_max(imath_min(firstSlot, 89), 0);
+
+ if (firstSlot > _GM(thumbIndex)) {
+ // Dump Out all thumbnails in slots which don't overlap
+ startIndex = _GM(thumbIndex);
+ endIndex = imath_min(_GM(thumbIndex) + 9, firstSlot - 1);
+ for (i = startIndex; i <= endIndex; i++) {
+ UnloadThumbNail(i);
+ }
+
+ // Load in all thumbnails missing thumbnails
+ startIndex = imath_max(_GM(thumbIndex) + 10, firstSlot);
+ endIndex = imath_min(firstSlot + 9, 98);
+ for (i = startIndex; i <= endIndex; i++) {
+ if (_GM(slotInUse)[i]) {
+ if (!LoadThumbNail(i)) {
+ _GM(slotInUse)[i] = false;
+ menuItemButton::disableButton(nullptr, 1001 + i - firstSlot, myMenu);
+ guiMenu::itemRefresh(nullptr, 1001 + i - firstSlot, myMenu);
+ }
+ }
+ }
+ } else {
+ // Else firstSlot < _GM(thumbIndex)
+ // Dump Out all thumbnails in slots which don't overlap
+ startIndex = imath_max(firstSlot + 10, _GM(thumbIndex));
+ endIndex = imath_min(_GM(thumbIndex) + 9, 98);
+ for (i = startIndex; i <= endIndex; i++) {
+ UnloadThumbNail(i);
+ }
+
+ // Load in all thumbnails missing thumbnails
+ startIndex = firstSlot;
+ endIndex = imath_min(firstSlot + 9, _GM(thumbIndex) - 1);
+ for (i = startIndex; i <= endIndex; i++) {
+ if (_GM(slotInUse)[i]) {
+ if (!LoadThumbNail(i)) {
+ _GM(slotInUse)[i] = false;
+ menuItemButton::disableButton(nullptr, 1001 + i - firstSlot, myMenu);
+ guiMenu::itemRefresh(nullptr, 1001 + i - firstSlot, myMenu);
+ }
+ }
+ }
+ }
+
+ // Set the var
+ _GM(thumbIndex) = firstSlot;
+}
+
+void SetFirstSlot(int32 firstSlot, guiMenu *myMenu) {
+ menuItemButton *myButton;
+ int32 i;
+
+ if (!myMenu) {
+ return;
+ }
+
+ // Ensure firstSlot is in a valid range
+ firstSlot = imath_max(imath_min(firstSlot, 89), 0);
+
+ // Change the prompt and special tag of each of the slot buttons
+ for (i = 0; i < MAX_SLOTS_SHOWN; i++) {
+ myButton = (menuItemButton *)guiMenu::getItem(i + 1001, myMenu);
+
+ myButton->prompt = _GM(slotTitles)[firstSlot + i];
+ if (_GM(currMenuIsSave) || _GM(slotInUse)[firstSlot + i]) {
+ myButton->itemFlags = menuItemButton::BTN_STATE_NORM;
+ } else {
+ myButton->itemFlags = menuItemButton::BTN_STATE_GREY;
+ }
+
+ myButton->specialTag = firstSlot + i + 1;
+ guiMenu::itemRefresh(myButton, i + 1001, myMenu);
+ }
+}
+
+//----------------------------- MENU DIALOG FUNCTIONS ---------------------------------//
+
bool guiMenu::initialize(RGB8 *myPalette) {
int32 i, memAvail;
@@ -1040,7 +1140,7 @@ bool menuItemButton::handler(menuItemButton *myItem, int32 eventType, int32 even
return handled;
}
-menuItemButton *menuItemButton::buttonAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, CALLBACK callback, int32 buttonType,
+menuItemButton *menuItemButton::add(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, CALLBACK callback, int32 buttonType,
bool greyed, bool transparent, const char *prompt, ItemHandlerFunction i_handler) {
menuItemButton *newItem;
ScreenContext *myScreen;
@@ -1210,16 +1310,15 @@ void menuItemMsg::drawMsg(menuItemMsg *myItem, guiMenu *myMenu, int32 x, int32 y
}
}
- // Get the button info and select the sprite
- //myMsg = (menuItemMsg *)myItem->itemInfo;
+ // Select the sprite
switch (myItem->tag) {
- case SL_TAG_SAVE_LABEL:
+ case Burger::GUI::SL_TAG_SAVE_LABEL:
mySprite = _GM(menuSprites)[Burger::GUI::SL_SAVE_LABEL];
break;
- case SL_TAG_LOAD_LABEL:
+ case Burger::GUI::SL_TAG_LOAD_LABEL:
mySprite = _GM(menuSprites)[Burger::GUI::SL_LOAD_LABEL];
break;
- case SL_TAG_THUMBNAIL:
+ case Burger::GUI::SL_TAG_THUMBNAIL:
mySprite = _GM(saveLoadThumbNail);
break;
}
@@ -1234,11 +1333,11 @@ void menuItemMsg::drawMsg(menuItemMsg *myItem, guiMenu *myMenu, int32 x, int32 y
if (backgroundBuff) {
gr_buffer_rect_copy_2(backgroundBuff, myBuff, 0, 0, x, y, backgroundBuff->w, backgroundBuff->h);
myItem->background->release();
- } else if (myItem->tag == SL_TAG_THUMBNAIL && mySprite->w == 160) {
+ } else if (myItem->tag == Burger::GUI::SL_TAG_THUMBNAIL && mySprite->w == 160) {
// Hack for handling smaller ScummVM thumbnails
- for (int yp = y; yp < (y + SL_THUMBNAIL_H); ++yp) {
+ for (int yp = y; yp < (y + Burger::GUI::SL_THUMBNAIL_H); ++yp) {
byte *line = myBuff->data + myBuff->stride * yp + x;
- Common::fill(line, line + SL_THUMBNAIL_W, 0);
+ Common::fill(line, line + Burger::GUI::SL_THUMBNAIL_W, 0);
}
x += 25;
@@ -1252,5 +1351,653 @@ void menuItemMsg::drawMsg(menuItemMsg *myItem, guiMenu *myMenu, int32 x, int32 y
myMenu->menuBuffer->release();
}
+
+//------------------------------- HSLIDER MENU ITEM ---------------------------------//
+
+void menuItemHSlider::drawHSlider(menuItemHSlider *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32) {
+ Buffer *myBuff = nullptr;
+ Buffer *backgroundBuff = nullptr;
+ Sprite *mySprite = nullptr;
+
+ // Verify params
+ if (!myItem || !myMenu)
+ return;
+
+ // If the item is marked transparent, get the background buffer
+ if (myItem->transparent) {
+ if (!myItem->background) {
+ return;
+ }
+ backgroundBuff = myItem->background->get_buffer();
+ if (!backgroundBuff) {
+ return;
+ }
+ }
+
+ // Get the menu buffer and draw the sprite to it
+ myBuff = myMenu->menuBuffer->get_buffer();
+ if (!myBuff) {
+ return;
+ }
+
+ // If the item is tagged as transparent, we need to fill in it's background behind it
+ if (backgroundBuff) {
+ gr_buffer_rect_copy_2(backgroundBuff, myBuff, 0, 0, x, y, backgroundBuff->w, backgroundBuff->h);
+ myItem->background->release();
+ }
+
+ // Get the slider info and select the thumb sprite
+ switch (myItem->itemFlags) {
+ case H_THUMB_OVER:
+ mySprite = _GM(menuSprites)[Burger::GUI::OM_SLIDER_BTN_OVER];
+ break;
+ case H_THUMB_PRESS:
+ mySprite = _GM(menuSprites)[Burger::GUI::OM_SLIDER_BTN_PRESS];
+ break;
+ default:
+ case H_THUMB_NORM:
+ mySprite = _GM(menuSprites)[Burger::GUI::OM_SLIDER_BTN_NORM];
+ break;
+ }
+
+ // Fill in everything left of the thumb with a hilite color
+ if (myItem->thumbX > 2) {
+ gr_color_set(menuItem::SLIDER_BAR_COLOR);
+ gr_buffer_rect_fill(myBuff, myItem->x1 + 3, myItem->y1 + 9, myItem->thumbX, myItem->thumbH - 18);
+ }
+
+ // Draw in the thumb
+ gui_DrawSprite(mySprite, myBuff, myItem->x1 + myItem->thumbX, myItem->y1);
+
+ // Release the menu buffer
+ myMenu->menuBuffer->release();
+}
+
+bool menuItemHSlider::handler(menuItemHSlider *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem) {
+ bool redrawItem, execCallback, handled;
+ ScreenContext *myScreen;
+ int32 status;
+ int32 deltaSlide;
+ static bool movingFlag;
+ static int32 movingX;
+
+ // Verify params
+ if (!myItem)
+ return false;
+
+ if (!(eventType == EVENT_MOUSE)) {
+ return false;
+ }
+
+ redrawItem = false;
+ handled = true;
+ execCallback = false;
+
+ switch (event) {
+ case _ME_L_click:
+ case _ME_doubleclick:
+ if (menuItem::cursorInsideItem(myItem, x, y) && (x - myItem->x1 >= myItem->thumbX) &&
+ (x - myItem->x1 <= myItem->thumbX + myItem->thumbW - 1)) {
+ myItem->itemFlags = H_THUMB_PRESS;
+ movingFlag = true;
+ movingX = x;
+ *currItem = myItem;
+ redrawItem = true;
+ } else {
+ *currItem = nullptr;
+ myItem->itemFlags = 0;
+ redrawItem = true;
+ }
+ break;
+
+ case _ME_L_drag:
+ case _ME_doubleclick_drag:
+ if (!*currItem) {
+ return true;
+ }
+ if (movingFlag) {
+ if (x < movingX) {
+ deltaSlide = imath_min(myItem->thumbX, movingX - x);
+ if (deltaSlide > 0) {
+ myItem->thumbX -= deltaSlide;
+ redrawItem = true;
+ myItem->percent = myItem->thumbX * 100 / myItem->maxThumbX;
+ execCallback = true;
+ }
+ } else if (x > movingX) {
+ deltaSlide = imath_min(myItem->maxThumbX - myItem->thumbX, x - movingX);
+ if (deltaSlide > 0) {
+ myItem->thumbX += deltaSlide;
+ redrawItem = true;
+ myItem->percent = myItem->thumbX * 100 / myItem->maxThumbX;
+ execCallback = true;
+ }
+ }
+ movingX = x;
+ if (movingX < (myItem->thumbX + myItem->x1)) {
+ movingX = myItem->thumbX + myItem->x1;
+ } else if (movingX > (myItem->thumbX + myItem->thumbW - 1 + myItem->x1)) {
+ movingX = myItem->thumbX + myItem->thumbW - 1 + myItem->x1;
+ }
+ } else {
+ *currItem = nullptr;
+ }
+ break;
+
+ case _ME_L_release:
+ case _ME_doubleclick_release:
+ if (!*currItem) {
+ return true;
+ }
+ movingFlag = false;
+ if (menuItem::cursorInsideItem(myItem, x, y) && (x - myItem->x1 >= myItem->thumbX) &&
+ (x - myItem->x1 <= myItem->thumbX + myItem->thumbW - 1)) {
+ myItem->itemFlags = H_THUMB_OVER;
+ *currItem = myItem;
+ } else {
+ myItem->itemFlags = H_THUMB_NORM;
+ *currItem = nullptr;
+ }
+ redrawItem = true;
+ execCallback = true;
+ break;
+
+ case _ME_move:
+ if (menuItem::cursorInsideItem(myItem, x, y) && (x - myItem->x1 >= myItem->thumbX) &&
+ (x - myItem->x1 <= myItem->thumbX + myItem->thumbW - 1)) {
+ if (myItem->itemFlags != H_THUMB_OVER) {
+ myItem->itemFlags = H_THUMB_OVER;
+ *currItem = myItem;
+ redrawItem = true;
+ }
+ } else {
+ if (myItem->itemFlags != H_THUMB_NORM) {
+ myItem->itemFlags = H_THUMB_NORM;
+ *currItem = nullptr;
+ redrawItem = true;
+ handled = false;
+ }
+ }
+ break;
+
+ case _ME_L_hold:
+ case _ME_doubleclick_hold:
+ break;
+ }
+
+ // See if we need to redraw the hslider
+ if (redrawItem) {
+ (myItem->redraw)(myItem, myItem->myMenu, myItem->x1, myItem->y1, 0, 0);
+ myScreen = vmng_screen_find(myItem->myMenu, &status);
+ if (myScreen && (status == SCRN_ACTIVE)) {
+ RestoreScreens(myScreen->x1 + myItem->x1, myScreen->y1 + myItem->y1,
+ myScreen->x1 + myItem->x2, myScreen->y1 + myItem->y2);
+ }
+ }
+
+ // See if we need to call the callback function
+ if (execCallback && myItem->callback) {
+ (myItem->callback)((void *)myItem, myItem->myMenu);
+ myScreen = vmng_screen_find(myItem->myMenu, &status);
+ if ((!myScreen) || (status != SCRN_ACTIVE)) {
+ *currItem = nullptr;
+ }
+ }
+
+ return handled;
+}
+
+menuItemHSlider *menuItemHSlider::add(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h,
+ int32 initPercent, CALLBACK callback, bool transparent) {
+ menuItemHSlider *newItem;
+ ScreenContext *myScreen;
+ int32 status;
+
+ // Verify params
+ if (!myMenu) {
+ return nullptr;
+ }
+
+ // Allocate a new one
+ newItem = new menuItemHSlider();
+
+ // Initialize the struct
+ newItem->next = myMenu->itemList;
+ newItem->prev = nullptr;
+ if (myMenu->itemList) {
+ myMenu->itemList->prev = newItem;
+ }
+ myMenu->itemList = newItem;
+
+ newItem->myMenu = myMenu;
+ newItem->tag = tag;
+ newItem->x1 = x;
+ newItem->y1 = y;
+ newItem->x2 = x + w - 1;
+ newItem->y2 = y + h - 1;
+ newItem->callback = callback;
+
+ if (!transparent) {
+ newItem->transparent = false;
+ newItem->background = nullptr;
+ } else {
+ newItem->transparent = true;
+ newItem->background = guiMenu::copyBackground(myMenu, x, y, w, h);
+ }
+
+ // Intialize the new slider
+ newItem->itemFlags = H_THUMB_NORM;
+ newItem->thumbW = _GM(menuSprites)[Burger::GUI::OM_SLIDER_BTN_NORM]->w;
+ newItem->thumbH = _GM(menuSprites)[Burger::GUI::OM_SLIDER_BTN_NORM]->h;
+ newItem->maxThumbX = w - _GM(menuSprites)[Burger::GUI::OM_SLIDER_BTN_NORM]->w;
+
+ if (initPercent < 0) {
+ initPercent = 0;
+ } else if (initPercent > 100) {
+ initPercent = 100;
+ }
+
+ // Calculate the initial thumbX
+ newItem->percent = initPercent;
+ newItem->thumbX = initPercent * newItem->maxThumbX / 100;
+
+ newItem->redraw = (DrawFunction)menuItemHSlider::drawHSlider;
+ newItem->destroy = (DestroyFunction)menuItem::destroyItem;
+ newItem->itemEventHandler = (ItemHandlerFunction)menuItemHSlider::handler;
+
+ // Draw the slider in now
+ (newItem->redraw)(newItem, myMenu, x, y, 0, 0);
+
+ // See if the screen is currently visible
+ myScreen = vmng_screen_find(myMenu, &status);
+ if (myScreen && (status == SCRN_ACTIVE)) {
+ RestoreScreens(myScreen->x1 + newItem->x1, myScreen->y1 + newItem->y1,
+ myScreen->x1 + newItem->x2, myScreen->y1 + newItem->y2);
+ }
+
+ return newItem;
+}
+
+
+//------------------------------- VSLIDER MENU ITEM ---------------------------------//
+
+void menuItemVSlider::drawVSlider(menuItemVSlider *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32) {
+ Buffer *myBuff = nullptr;
+ Buffer *backgroundBuff = nullptr;
+ Sprite *upSprite = nullptr;
+ Sprite *thumbSprite = nullptr;
+ Sprite *downSprite = nullptr;
+ Sprite *vbarSprite = nullptr;
+
+ // Verify params
+ if (!myItem || !myMenu)
+ return;
+
+ // If the item is marked transparent, get the background buffer
+ if (myItem->transparent) {
+ if (!myItem->background) {
+ return;
+ }
+ backgroundBuff = myItem->background->get_buffer();
+ if (!backgroundBuff) {
+ return;
+ }
+ }
+
+ // Get the menu buffer
+ myBuff = myMenu->menuBuffer->get_buffer();
+ if (!myBuff) {
+ return;
+ }
+
+ // If the item is tagged as transparent, we need to fill in it's background behind it
+ if (backgroundBuff) {
+ gr_buffer_rect_copy_2(backgroundBuff, myBuff, 0, 0, x, y, backgroundBuff->w, backgroundBuff->h);
+ myItem->background->release();
+ }
+
+ // Set the different sprite components
+ vbarSprite = _GM(menuSprites)[Burger::GUI::SL_SCROLL_BAR];
+ upSprite = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_NORM];
+ thumbSprite = _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_NORM];
+ downSprite = _GM(menuSprites)[Burger::GUI::SL_DOWN_BTN_NORM];
+
+ if ((myItem->itemFlags & VS_STATUS) == VS_GREY) {
+ upSprite = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_GREY];
+ thumbSprite = nullptr;
+ downSprite = _GM(menuSprites)[Burger::GUI::SL_DOWN_BTN_GREY];
+ } else if ((myItem->itemFlags & VS_STATUS) == VS_OVER) {
+ if ((myItem->itemFlags & VS_COMPONENT) == VS_UP) {
+ upSprite = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_OVER];
+ } else if ((myItem->itemFlags & VS_COMPONENT) == VS_THUMB) {
+ thumbSprite = _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_OVER];
+ } else if ((myItem->itemFlags & VS_COMPONENT) == VS_DOWN) {
+ downSprite = _GM(menuSprites)[Burger::GUI::SL_DOWN_BTN_OVER];
+ }
+ } else if ((myItem->itemFlags & VS_STATUS) == VS_PRESS) {
+ if ((myItem->itemFlags & VS_COMPONENT) == VS_UP) {
+ upSprite = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_PRESS];
+ } else if ((myItem->itemFlags & VS_COMPONENT) == VS_THUMB) {
+ thumbSprite = _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_PRESS];
+ } else if ((myItem->itemFlags & VS_COMPONENT) == VS_DOWN) {
+ downSprite = _GM(menuSprites)[Burger::GUI::SL_DOWN_BTN_PRESS];
+ }
+ }
+
+ // Draw the sprite comonents
+ gui_DrawSprite(vbarSprite, myBuff, x, y + upSprite->h);
+ gui_DrawSprite(upSprite, myBuff, x, y);
+ gui_DrawSprite(thumbSprite, myBuff, x, y + myItem->thumbY);
+ gui_DrawSprite(downSprite, myBuff, x, y + upSprite->h + vbarSprite->h);
+
+ // Release the menu buffer
+ myMenu->menuBuffer->release();
+}
+
+int32 menuItemVSlider::whereIsCursor(menuItemVSlider *myVSlider, int32 y) {
+ if (y < myVSlider->minThumbY) {
+ return VS_UP;
+ } else if (y < myVSlider->thumbY) {
+ return VS_PAGE_UP;
+ } else if (y < myVSlider->thumbY + myVSlider->thumbH) {
+ return VS_THUMB;
+ } else if (y < myVSlider->maxThumbY + myVSlider->thumbH) {
+ return VS_PAGE_DOWN;
+ } else {
+ return VS_DOWN;
+ }
+}
+
+bool menuItemVSlider::handler(menuItemVSlider *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem) {
+ bool redrawItem, execCallback, handled;
+ int32 tempFlags;
+ ScreenContext *myScreen;
+ int32 status;
+ int32 deltaSlide;
+ int32 currTime;
+ static bool movingFlag;
+ static int32 movingY;
+ static int32 callbackTime;
+
+ // Verify params
+ if (!myItem)
+ return false;
+
+ if (!(eventType == EVENT_MOUSE))
+ return false;
+
+ if ((myItem->itemFlags & VS_STATUS) == VS_GREY) {
+ *currItem = nullptr;
+ return false;
+ }
+
+ currTime = timer_read_60();
+ redrawItem = false;
+ handled = true;
+ execCallback = false;
+
+ switch (event) {
+ case _ME_L_click:
+ case _ME_doubleclick:
+ if (menuItem::cursorInsideItem(myItem, x, y)) {
+ // digi_play(inv_click_snd, 2, 255, -1, inv_click_snd_room_lock);
+ *currItem = myItem;
+ tempFlags = menuItemVSlider::whereIsCursor(myItem, y - myItem->y1);
+ if (tempFlags == VS_THUMB) {
+ movingFlag = true;
+ movingY = y;
+ }
+ if ((tempFlags == VS_PAGE_UP) || (tempFlags == VS_PAGE_DOWN)) {
+ myItem->itemFlags = tempFlags + VS_NORM;
+ } else {
+ myItem->itemFlags = tempFlags + VS_PRESS;
+ redrawItem = true;
+ }
+ execCallback = true;
+ } else {
+ *currItem = nullptr;
+ myItem->itemFlags = VS_NORM;
+ redrawItem = true;
+ }
+ break;
+
+ case _ME_L_drag:
+ case _ME_doubleclick_drag:
+ if (!*currItem) {
+ return true;
+ }
+ if (movingFlag) {
+ if (y < movingY) {
+ deltaSlide = imath_min(myItem->thumbY - myItem->minThumbY, movingY - y);
+ if (deltaSlide > 0) {
+ myItem->thumbY -= deltaSlide;
+ myItem->percent = ((myItem->thumbY - myItem->minThumbY) * 100) /
+ (myItem->maxThumbY - myItem->minThumbY);
+ redrawItem = true;
+ execCallback = true;
+ }
+ } else if (y > movingY) {
+ deltaSlide = imath_min(myItem->maxThumbY - myItem->thumbY, y - movingY);
+ if (deltaSlide > 0) {
+ myItem->thumbY += deltaSlide;
+ myItem->percent = ((myItem->thumbY - myItem->minThumbY) * 100) /
+ (myItem->maxThumbY - myItem->minThumbY);
+ redrawItem = true;
+ execCallback = true;
+ }
+ }
+ movingY = y;
+ if (movingY < (myItem->thumbY + myItem->y1)) {
+ movingY = myItem->thumbY + myItem->y1;
+ } else if (movingY > (myItem->thumbY + myItem->thumbH - 1 + myItem->y1)) {
+ movingY = myItem->thumbY + myItem->thumbH - 1 + myItem->y1;
+ }
+ } else {
+ if (menuItem::cursorInsideItem(myItem, x, y)) {
+ tempFlags = menuItemVSlider::whereIsCursor(myItem, y - myItem->y1);
+ if ((myItem->itemFlags & VS_COMPONENT) == tempFlags) {
+ if ((tempFlags != VS_PAGE_UP) && (tempFlags != VS_PAGE_DOWN) &&
+ ((myItem->itemFlags & VS_STATUS) != VS_PRESS)) {
+ myItem->itemFlags = tempFlags + VS_PRESS;
+ redrawItem = true;
+ }
+ if (currTime - callbackTime > 6) {
+ execCallback = true;
+ }
+ } else {
+ if ((myItem->itemFlags & VS_STATUS) != VS_OVER) {
+ myItem->itemFlags = (myItem->itemFlags & VS_COMPONENT) + VS_OVER;
+ redrawItem = true;
+ }
+ }
+ execCallback = true;
+ } else {
+ if ((myItem->itemFlags & VS_STATUS) != VS_OVER) {
+ myItem->itemFlags = (myItem->itemFlags & VS_COMPONENT) + VS_OVER;
+ redrawItem = true;
+ }
+ }
+ }
+ break;
+
+ case _ME_L_release:
+ case _ME_doubleclick_release:
+ movingFlag = false;
+ if (menuItem::cursorInsideItem(myItem, x, y)) {
+ tempFlags = menuItemVSlider::whereIsCursor(myItem, y - myItem->y1);
+ if ((tempFlags == VS_PAGE_UP) || (tempFlags == VS_PAGE_DOWN)) {
+ myItem->itemFlags = VS_NORM;
+ } else {
+ myItem->itemFlags = tempFlags + VS_OVER;
+ *currItem = myItem;
+ }
+ } else {
+ myItem->itemFlags = VS_NORM;
+ *currItem = nullptr;
+ }
+ redrawItem = true;
+ if (!_GM(currMenuIsSave)) {
+ UpdateThumbNails(_GM(firstSlotIndex), (guiMenu *)myItem->myMenu);
+ }
+ break;
+
+ case _ME_move:
+ if (menuItem::cursorInsideItem(myItem, x, y)) {
+ *currItem = myItem;
+ tempFlags = menuItemVSlider::whereIsCursor(myItem, y - myItem->y1);
+ if ((myItem->itemFlags & VS_COMPONENT) != tempFlags) {
+ if ((tempFlags == VS_PAGE_UP) || (tempFlags == VS_PAGE_DOWN)) {
+ myItem->itemFlags = VS_NORM;
+ } else {
+ myItem->itemFlags = tempFlags + VS_OVER;
+ }
+ redrawItem = true;
+ }
+ } else {
+ *currItem = nullptr;
+ if (myItem->itemFlags != VS_NORM) {
+ myItem->itemFlags = VS_NORM;
+ redrawItem = true;
+ handled = false;
+ }
+ }
+ break;
+
+ case _ME_L_hold:
+ case _ME_doubleclick_hold:
+ if (!*currItem) {
+ return true;
+ }
+ if (menuItem::cursorInsideItem(myItem, x, y)) {
+ tempFlags = menuItemVSlider::whereIsCursor(myItem, y - myItem->y1);
+ if ((myItem->itemFlags & VS_COMPONENT) == tempFlags) {
+ if (currTime - callbackTime > 6) {
+ execCallback = true;
+ }
+ }
+ }
+ break;
+ }
+
+ // See if we need to redraw the vslider
+ if (redrawItem) {
+ (myItem->redraw)(myItem, myItem->myMenu, myItem->x1, myItem->y1, 0, 0);
+ myScreen = vmng_screen_find(myItem->myMenu, &status);
+ if (myScreen && (status == SCRN_ACTIVE)) {
+ RestoreScreens(myScreen->x1 + myItem->x1, myScreen->y1 + myItem->y1,
+ myScreen->x1 + myItem->x2, myScreen->y1 + myItem->y2);
+ }
+ }
+
+ // See if we need to call the callback function
+ if (execCallback && myItem->callback) {
+ callbackTime = currTime;
+ (myItem->callback)((void *)myItem, myItem->myMenu);
+ myScreen = vmng_screen_find(myItem->myMenu, &status);
+ if ((!myScreen) || (status != SCRN_ACTIVE)) {
+ *currItem = nullptr;
+ }
+ }
+
+ return handled;
+}
+
+
+menuItemVSlider *menuItemVSlider::add(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h,
+ int32 initPercent, CALLBACK callback, bool transparent) {
+ menuItemVSlider *newItem;
+ ScreenContext *myScreen;
+ int32 status;
+
+ // Verify params
+ if (!myMenu)
+ return nullptr;
+
+ // Allocate a new one
+ newItem = new menuItemVSlider();
+
+ // Initialize the struct
+ newItem->next = myMenu->itemList;
+ newItem->prev = nullptr;
+ if (myMenu->itemList) {
+ myMenu->itemList->prev = newItem;
+ }
+ myMenu->itemList = newItem;
+
+ newItem->myMenu = myMenu;
+ newItem->tag = tag;
+ newItem->x1 = x;
+ newItem->y1 = y;
+ newItem->x2 = x + w - 1;
+ newItem->y2 = y + h - 1;
+ newItem->callback = callback;
+
+ if (!transparent) {
+ newItem->transparent = false;
+ newItem->background = nullptr;
+ } else {
+ newItem->transparent = true;
+ newItem->background = guiMenu::copyBackground(myMenu, x, y, w, h);
+ }
+
+ newItem->itemFlags = menuItemVSlider::VS_NORM;
+
+ newItem->thumbW = _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_NORM]->w;
+ newItem->thumbH = _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_NORM]->h;
+
+ newItem->minThumbY = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_NORM]->h + 1;
+ newItem->maxThumbY = _GM(menuSprites)[Burger::GUI::SL_UP_BTN_NORM]->h + _GM(menuSprites)[Burger::GUI::SL_SCROLL_BAR]->h
+ - _GM(menuSprites)[Burger::GUI::SL_SLIDER_BTN_NORM]->h - 1;
+
+ // Calculate the initial thumbY
+ newItem->percent = imath_max(imath_min(initPercent, 100), 0);
+ newItem->thumbY = newItem->minThumbY +
+ ((newItem->percent * (newItem->maxThumbY - newItem->minThumbY)) / 100);
+
+ newItem->redraw = (DrawFunction)menuItemVSlider::drawVSlider;
+ newItem->destroy = (DestroyFunction)menuItem::destroyItem;
+ newItem->itemEventHandler = (ItemHandlerFunction)menuItemVSlider::handler;
+
+ // Draw the vslider in now
+ (newItem->redraw)(newItem, myMenu, x, y, 0, 0);
+
+ // See if the screen is currently visible
+ myScreen = vmng_screen_find(myMenu, &status);
+ if (myScreen && (status == SCRN_ACTIVE)) {
+ RestoreScreens(myScreen->x1 + newItem->x1, myScreen->y1 + newItem->y1,
+ myScreen->x1 + newItem->x2, myScreen->y1 + newItem->y2);
+ }
+
+ return newItem;
+}
+
+void menuItemVSlider::disableVSlider(menuItemVSlider *myItem, int32 tag, guiMenu *myMenu) {
+ // Verify params
+ if (!myMenu)
+ return;
+
+ if (!myItem)
+ myItem = (menuItemVSlider *)guiMenu::getItem(tag, myMenu);
+ if (!myItem)
+ return;
+
+ myItem->itemFlags = menuItemVSlider::VS_GREY;
+}
+
+void menuItemVSlider::enableVSlider(menuItemVSlider *myItem, int32 tag, guiMenu *myMenu) {
+ // Verify params
+ if (!myMenu)
+ return;
+
+ if (!myItem)
+ myItem = (menuItemVSlider *)guiMenu::getItem(tag, myMenu);
+ if (!myItem)
+ return;
+
+ myItem->itemFlags = menuItemVSlider::VS_NORM;
+}
+
+
+
} // namespace GUI
} // namespace M4
diff --git a/engines/m4/gui/gui_menu.h b/engines/m4/gui/gui_menu.h
index 571b7396fb7..48eefee03c7 100644
--- a/engines/m4/gui/gui_menu.h
+++ b/engines/m4/gui/gui_menu.h
@@ -108,6 +108,9 @@ enum save_load_menu_item_tags {
SL_TAG_THUMBNAIL
};
+constexpr int SL_THUMBNAIL_W = 215;
+constexpr int SL_THUMBNAIL_H = 162;
+
} // namespace GUI
} // namespace Burger
@@ -181,7 +184,6 @@ struct menuItem {
static bool cursorInsideItem(menuItem *myItem, int32 cursorX, int32 cursorY);
};
-
struct menuItemMsg : public menuItem {
private:
static void drawMsg(menuItemMsg *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32);
@@ -225,7 +227,7 @@ public:
menuItem *assocItem = nullptr;
int32 specialTag = 0;
- static menuItemButton *buttonAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, CALLBACK callback = nullptr,
+ static menuItemButton *add(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, CALLBACK callback = nullptr,
int32 buttonType = 0, bool ghosted = false, bool transparent = false,
const char *prompt = nullptr, ItemHandlerFunction i_handler = (ItemHandlerFunction)handler);
static void disableButton(menuItemButton *myItem, int32 tag, guiMenu *myMenu);
@@ -235,21 +237,61 @@ public:
};
struct menuItemHSlider : public menuItem {
+private:
+ static void drawHSlider(menuItemHSlider *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32);
+ static bool handler(menuItemHSlider *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem);
+
+public:
int32 itemFlags = 0;
int32 thumbW = 0, thumbH = 0;
int32 thumbX = 0, maxThumbX = 0;
int32 percent = 0;
+
+ enum {
+ H_THUMB_NORM = 0,
+ H_THUMB_OVER = 1,
+ H_THUMB_PRESS = 2
+ };
+
+ static menuItemHSlider *add(guiMenu *myMenu, int32 tag,
+ int32 x, int32 y, int32 w, int32 h, int32 initPercent = 0,
+ CALLBACK callback = nullptr, bool transparent = false);
};
struct menuItemVSlider : public menuItem {
+private:
+ static int32 whereIsCursor(menuItemVSlider *myVSlider, int32 y);
+
+public:
int32 itemFlags = 0;
int32 thumbW = 0, thumbH = 0;
int32 thumbY = 0, minThumbY = 0, maxThumbY = 0;
int32 percent = 0;
+
+ enum {
+ VS_NORM = 0x0000,
+ VS_OVER = 0x0001,
+ VS_PRESS = 0x0002,
+ VS_GREY = 0x0003,
+ VS_STATUS = 0x000f,
+ VS_UP = 0x0010,
+ VS_PAGE_UP = 0x0020,
+ VS_THUMB = 0x0030,
+ VS_PAGE_DOWN = 0x0040,
+ VS_DOWN = 0x0050,
+ VS_COMPONENT = 0x00f0
+ };
+
+ static menuItemVSlider *add(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h,
+ int32 initPercent = 0, CALLBACK callback = nullptr, bool transparent = false);
+ static void disableVSlider(menuItemVSlider *myItem, int32 tag, guiMenu *myMenu);
+ static void enableVSlider(menuItemVSlider *myItem, int32 tag, guiMenu *myMenu);
+ static void drawVSlider(menuItemVSlider *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32);
+ static bool handler(menuItemVSlider *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem);
};
struct menuItemTextField : public menuItem {
@@ -345,6 +387,10 @@ struct MenuGlobals {
};
extern void gui_DrawSprite(Sprite *mySprite, Buffer *myBuff, int32 x, int32 y);
+extern bool LoadThumbNail(int32 slotNum);
+extern void UnloadThumbNail(int32 slotNum);
+extern void UpdateThumbNails(int32 firstSlot, guiMenu *myMenu);
+extern void SetFirstSlot(int32 firstSlot, guiMenu *myMenu);
//======================================
//
diff --git a/engines/m4/riddle/gui/game_menu.cpp b/engines/m4/riddle/gui/game_menu.cpp
index 338dd927afe..847c4cf9f85 100644
--- a/engines/m4/riddle/gui/game_menu.cpp
+++ b/engines/m4/riddle/gui/game_menu.cpp
@@ -104,24 +104,24 @@ void GameMenu::show(RGB8 *myPalette) {
GAME_MENU_X, GAME_MENU_Y, MENU_DEPTH | SF_GET_ALL | SF_BLOCK_ALL | SF_IMMOVABLE);
assert(_GM(gameMenu));
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_QUIT,
+ menuItemButton::add(_GM(gameMenu), GM_TAG_QUIT,
GM_QUIT_X, GM_QUIT_Y, GM_QUIT_W, GM_QUIT_H, cbQuitGame);
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_MAIN,
+ menuItemButton::add(_GM(gameMenu), GM_TAG_MAIN,
GM_MAIN_X, GM_MAIN_Y, GM_MAIN_W, GM_MAIN_H, cbMainMenu);
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_OPTIONS, GM_OPTIONS_X, GM_OPTIONS_Y, GM_OPTIONS_W, GM_OPTIONS_H, cbOptions);
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_RESUME, GM_RESUME_X, GM_RESUME_Y, GM_RESUME_W, GM_RESUME_H, cbResume);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_OPTIONS, GM_OPTIONS_X, GM_OPTIONS_Y, GM_OPTIONS_W, GM_OPTIONS_H, cbOptions);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_RESUME, GM_RESUME_X, GM_RESUME_Y, GM_RESUME_W, GM_RESUME_H, cbResume);
if (!_GM(gameMenuFromMain)) {
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_SAVE, GM_SAVE_X, GM_SAVE_Y, GM_SAVE_W, GM_SAVE_H, cbSave);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_SAVE, GM_SAVE_X, GM_SAVE_Y, GM_SAVE_W, GM_SAVE_H, cbSave);
} else {
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_SAVE, GM_SAVE_X, GM_SAVE_Y, GM_SAVE_W, GM_SAVE_H, cbSave, menuItemButton::BTN_TYPE_GM_GENERIC, true);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_SAVE, GM_SAVE_X, GM_SAVE_Y, GM_SAVE_W, GM_SAVE_H, cbSave, menuItemButton::BTN_TYPE_GM_GENERIC, true);
}
// See if there are any games to load
if (g_engine->savesExist()) {
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_LOAD, GM_LOAD_X, GM_LOAD_Y, GM_LOAD_W, GM_LOAD_H, cbLoad);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_LOAD, GM_LOAD_X, GM_LOAD_Y, GM_LOAD_W, GM_LOAD_H, cbLoad);
} else {
- menuItemButton::buttonAdd(_GM(gameMenu), GM_TAG_LOAD, GM_LOAD_X, GM_LOAD_Y, GM_LOAD_W, GM_LOAD_H, cbLoad, menuItemButton::BTN_TYPE_GM_GENERIC, true);
+ menuItemButton::add(_GM(gameMenu), GM_TAG_LOAD, GM_LOAD_X, GM_LOAD_Y, GM_LOAD_W, GM_LOAD_H, cbLoad, menuItemButton::BTN_TYPE_GM_GENERIC, true);
}
// Configure the game so pressing <esc> will cause the menu to disappear and the game to resume
Commit: ae8fc03e3a1800eef97bd1a45b282e107a4baf95
https://github.com/scummvm/scummvm/commit/ae8fc03e3a1800eef97bd1a45b282e107a4baf95
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2025-02-12T22:43:58-08:00
Commit Message:
M4: RIDDLE: Move text field methods to menuItemTextField
Changed paths:
engines/m4/burger/gui/game_menu.cpp
engines/m4/burger/gui/game_menu.h
engines/m4/gui/gui_menu.cpp
engines/m4/gui/gui_menu.h
diff --git a/engines/m4/burger/gui/game_menu.cpp b/engines/m4/burger/gui/game_menu.cpp
index 97c198d86f8..40cb8b82b00 100644
--- a/engines/m4/burger/gui/game_menu.cpp
+++ b/engines/m4/burger/gui/game_menu.cpp
@@ -231,342 +231,6 @@ Sprite *menu_CreateThumbnail(int32 *spriteSize) {
return thumbNailSprite;
}
-//----------------------------- TEXTFIELD MENU ITEM ---------------------------------//
-
-enum {
- TF_NORM = 0,
- TF_OVER = 1,
- TF_GREY = 2
-};
-
-void menu_DrawTextField(menuItemTextField *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32) {
- menuItemTextField *myText = nullptr;
- Buffer *myBuff = nullptr;
- Buffer *backgroundBuff = nullptr;
- Sprite *mySprite = nullptr;
- char tempStr[64], tempChar;
- int32 cursorX;
-
- // Verify params
- if (!myItem || !myMenu)
- return;
-
- // If the item is marked transparent, get the background buffer
- if (myItem->transparent) {
- if (!myItem->background) {
- return;
- }
- backgroundBuff = myItem->background->get_buffer();
- if (!backgroundBuff) {
- return;
- }
- }
-
- // Select the sprite
- switch (myText->itemFlags) {
- case TF_GREY:
- mySprite = _GM(menuSprites)[Burger::GUI::SL_LINE_NORM];
- break;
-
- case TF_OVER:
- mySprite = _GM(menuSprites)[Burger::GUI::SL_LINE_OVER];
- break;
-
- case TF_NORM:
- default:
- mySprite = _GM(menuSprites)[Burger::GUI::SL_LINE_OVER];
- break;
- }
-
- // Get the menu buffer and draw the sprite to it
- myBuff = myMenu->menuBuffer->get_buffer();
- if (!myBuff) {
- return;
- }
-
- // If the item is tagged as transparent, we need to fill in it's background behind it
- if (backgroundBuff) {
- gr_buffer_rect_copy_2(backgroundBuff, myBuff, 0, 0, x, y, backgroundBuff->w, backgroundBuff->h);
- myItem->background->release();
- }
-
- // Draw the item sprite in
- gui_DrawSprite(mySprite, myBuff, x, y);
-
- //write in the special tag
- gr_font_set_color(menuItem::TEXT_COLOR_NORM_FOREGROUND);
- Common::sprintf_s(tempStr, 64, "%02d", myText->specialTag);
- gr_font_set(_GM(menuFont));
- gr_font_write(myBuff, tempStr, x + 4, y + 1, 0, -1);
-
- //write in the text
- gr_font_write(myBuff, &myText->prompt[0], x + 26, y + 1, 0, -1);
-
- if (myText->itemFlags == TF_OVER) {
- // Draw in the cursor
- if (myText->cursor) {
- tempChar = *myText->cursor;
- *myText->cursor = '\0';
- cursorX = gr_font_string_width(&myText->prompt[0], -1);
- *myText->cursor = tempChar;
-
- gr_color_set(menuItem::TEXT_COLOR_OVER_FOREGROUND);
- gr_vline(myBuff, x + cursorX + 26, y + 1, y + 12);
- }
- }
-
- // Release the menu buffer
- myMenu->menuBuffer->release();
-}
-
-
-bool textfield_Handler(menuItemTextField *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem) {
- bool redrawItem, execCallback, handled;
- ScreenContext *myScreen;
- int32 status, temp;
- char tempStr[80], *tempPtr;
-
- // Verify params
- if (!myItem)
- return false;
-
- if (myItem->itemFlags == TF_GREY) {
- return false;
- }
-
- redrawItem = false;
- execCallback = false;
- handled = true;
-
- if (eventType == EVENT_MOUSE) {
- switch (event) {
- case _ME_L_click:
- case _ME_doubleclick:
- _GM(deleteSaveDesc) = false;
- if (menuItem::cursorInsideItem(myItem, x, y)) {
- *currItem = myItem;
- }
- break;
-
- case _ME_L_drag:
- case _ME_doubleclick_drag:
- break;
-
- case _ME_L_release:
- case _ME_doubleclick_release:
- if (!*currItem) {
- return true;
- }
- *currItem = nullptr;
- if (menuItem::cursorInsideItem(myItem, x, y)) {
- if (myItem->itemFlags == TF_OVER) {
- temp = strlen(myItem->prompt);
- if (temp > 0) {
- Common::strcpy_s(tempStr, myItem->prompt);
- tempPtr = &tempStr[temp];
- gr_font_set(_GM(menuFont));
- temp = gr_font_string_width(tempStr, -1);
- while ((tempPtr != &tempStr[0]) && (temp > x - myItem->x1 - 26)) {
- *--tempPtr = '\0';
- temp = gr_font_string_width(tempStr, -1);
- }
- myItem->cursor = &myItem->prompt[tempPtr - &tempStr[0]];
- redrawItem = true;
- }
- } else if (event == _ME_doubleclick_release) {
- execCallback = true;
- }
- }
- break;
-
- case _ME_move:
- case _ME_L_hold:
- case _ME_doubleclick_hold:
- break;
- }
- } else if ((eventType == EVENT_KEY) && (myItem->itemFlags == TF_OVER)) {
- switch (event) {
- case KEY_RETURN:
- _GM(deleteSaveDesc) = false;
- execCallback = true;
- break;
-
- case KEY_HOME:
- _GM(deleteSaveDesc) = false;
- myItem->cursor = &myItem->prompt[0];
- redrawItem = true;
- break;
-
- case KEY_END:
- _GM(deleteSaveDesc) = false;
- myItem->cursor = myItem->promptEnd;
- redrawItem = true;
- break;
-
- case KEY_LEFT:
- _GM(deleteSaveDesc) = false;
- if (myItem->cursor > &myItem->prompt[0]) {
- myItem->cursor--;
- redrawItem = true;
- }
- break;
-
- case KEY_RIGHT:
- _GM(deleteSaveDesc) = false;
- if (myItem->cursor < myItem->promptEnd) {
- myItem->cursor++;
- redrawItem = true;
- }
- break;
-
- case KEY_DELETE:
- if (_GM(deleteSaveDesc)) {
- myItem->prompt[0] = '\0';
- myItem->promptEnd = &myItem->prompt[0];
- myItem->cursor = myItem->promptEnd;
- redrawItem = true;
- } else if (myItem->cursor < myItem->promptEnd) {
- Common::strcpy_s(tempStr, (char *)(myItem->cursor + 1));
- Common::strcpy_s(myItem->cursor, 80, tempStr);
- myItem->promptEnd--;
- redrawItem = true;
- }
- break;
-
- case KEY_BACKSP:
- _GM(deleteSaveDesc) = false;
- if (myItem->cursor > &myItem->prompt[0]) {
- Common::strcpy_s(tempStr, myItem->cursor);
- myItem->promptEnd--;
- myItem->cursor--;
- Common::strcpy_s(myItem->cursor, 80, tempStr);
- redrawItem = true;
- }
- break;
-
- default:
- _GM(deleteSaveDesc) = false;
- gr_font_set(_GM(menuFont));
- temp = gr_font_string_width(&myItem->prompt[0], -1);
- if ((strlen(&myItem->prompt[0]) < 79) && (temp < myItem->pixWidth - 12) && (event >= 32) && (event <= 127)) {
- if (myItem->cursor < myItem->promptEnd) {
- Common::strcpy_s(tempStr, (char *)myItem->cursor);
- Common::sprintf_s(myItem->cursor, 80, "%c%s", (char)event, tempStr);
- } else {
- *myItem->cursor = (char)event;
- *(myItem->cursor + 1) = '\0';
- }
- myItem->cursor++;
- myItem->promptEnd++;
-
- redrawItem = true;
- }
- break;
- }
- } else if ((eventType == EVENT_KEY) && (event == KEY_RETURN)) {
- // The only events a NORM textfield can respond to are doubleclick_release and <return> keypress
- execCallback = true;
- } else {
- // Otherwise the event will not be handled
- return false;
- }
-
- // See if we need to redraw the button
- if (redrawItem) {
- (myItem->redraw)(myItem, myItem->myMenu, myItem->x1, myItem->y1, 0, 0);
- myScreen = vmng_screen_find(myItem->myMenu, &status);
- if (myScreen && (status == SCRN_ACTIVE)) {
- RestoreScreens(myScreen->x1 + myItem->x1, myScreen->y1 + myItem->y1,
- myScreen->x1 + myItem->x2, myScreen->y1 + myItem->y2);
- }
- }
-
- // See if we need to call the callback function
- if (execCallback && myItem->callback) {
- (myItem->callback)((void *)myItem, myItem->myMenu);
- myScreen = vmng_screen_find(myItem->myMenu, &status);
-
- if ((!myScreen) || (status != SCRN_ACTIVE)) {
- *currItem = nullptr;
- }
- }
-
- return handled;
-}
-
-
-menuItemTextField *menu_TextFieldAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, int32 initFlags,
- const char *prompt, int32 specialTag, CALLBACK callback, bool transparent) {
- menuItemTextField *newItem;
- menuItemTextField *textInfo;
- ScreenContext *myScreen;
- int32 status;
-
- // Verify params
- if (!myMenu)
- return nullptr;
-
- // Allocate a new one
- newItem = new menuItemTextField();
-
- // Initialize the struct
- newItem->next = myMenu->itemList;
- newItem->prev = nullptr;
- if (myMenu->itemList) {
- myMenu->itemList->prev = newItem;
- }
- myMenu->itemList = newItem;
-
- newItem->myMenu = myMenu;
- newItem->tag = tag;
- newItem->x1 = x;
- newItem->y1 = y;
- newItem->x2 = x + w - 1;
- newItem->y2 = y + h - 1;
- newItem->callback = callback;
-
- if (!transparent) {
- newItem->transparent = false;
- newItem->background = nullptr;
- } else {
- newItem->transparent = true;
- newItem->background = guiMenu::copyBackground(myMenu, x, y, w, h);
- }
-
- if ((textInfo = (menuItemTextField *)mem_alloc(sizeof(menuItemTextField), "menu item textfield")) == nullptr) {
- return nullptr;
- }
- textInfo->itemFlags = initFlags;
-
- textInfo->specialTag = specialTag;
- textInfo->pixWidth = w - 27;
- if (prompt) {
- Common::strcpy_s(&textInfo->prompt[0], 80, prompt);
- textInfo->promptEnd = &textInfo->prompt[strlen(prompt)];
- } else {
- textInfo->prompt[0] = '\0';
- textInfo->promptEnd = &textInfo->prompt[0];
- }
- textInfo->cursor = textInfo->promptEnd;
-
- newItem->redraw = (DrawFunction)menu_DrawTextField;
- newItem->destroy = (DestroyFunction)menuItem::destroyItem;
- newItem->itemEventHandler = (ItemHandlerFunction)textfield_Handler;
-
- // Draw the vslider in now
- (newItem->redraw)(newItem, myMenu, x, y, 0, 0);
-
- // See if the screen is currently visible
- myScreen = vmng_screen_find(myMenu, &status);
- if (myScreen && (status == SCRN_ACTIVE)) {
- RestoreScreens(myScreen->x1 + newItem->x1, myScreen->y1 + newItem->y1,
- myScreen->x1 + newItem->x2, myScreen->y1 + newItem->y2);
- }
-
- return newItem;
-}
-
-
//------------------------------------- GAME MENU -------------------------------------//
@@ -1003,7 +667,7 @@ void cb_SaveLoad_Save(void *, guiMenu *myMenu) {
if (myText)
return;
- myText->itemFlags = TF_NORM;
+ myText->itemFlags = menuItemTextField::TF_NORM;
// Set the vars
_GM(slotInUse)[_GM(slotSelected) - 1] = true;
@@ -1175,14 +839,14 @@ void cb_SaveLoad_Slot(menuItemButton *myButton, guiMenu *myMenu) {
if (_GM(currMenuIsSave)) {
// Replace the current button with a textfield
if (!strcmp(prompt, "<empty>")) {
- menu_TextFieldAdd(myMenu, 2000, x, y, w, h, TF_OVER,
+ menuItemTextField::add(myMenu, 2000, x, y, w, h, menuItemTextField::TF_OVER,
nullptr, specialTag, (CALLBACK)cb_SaveLoad_Save, true);
} else {
- menu_TextFieldAdd(myMenu, 2000, x, y, w, h, TF_OVER,
+ menuItemTextField::add(myMenu, 2000, x, y, w, h, menuItemTextField::TF_OVER,
prompt, specialTag, (CALLBACK)cb_SaveLoad_Save, true);
}
} else {
- menu_TextFieldAdd(myMenu, 2000, x, y, w, h, TF_NORM,
+ menuItemTextField::add(myMenu, 2000, x, y, w, h, menuItemTextField::TF_NORM,
prompt, specialTag, (CALLBACK)cb_SaveLoad_Load, true);
}
diff --git a/engines/m4/burger/gui/game_menu.h b/engines/m4/burger/gui/game_menu.h
index 6a17d82060b..47f1c55cf31 100644
--- a/engines/m4/burger/gui/game_menu.h
+++ b/engines/m4/burger/gui/game_menu.h
@@ -43,10 +43,6 @@ using M4::GUI::Sprite;
using M4::GUI::CALLBACK;
using M4::GUI::ItemHandlerFunction;
-// Textfields
-menuItemTextField *menu_TextFieldAdd(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, int32 initFlags,
- const char *prompt = nullptr, int32 specialtag = 0, CALLBACK callback = nullptr, bool transparent = false);
-
//GAME MENU FUNCTIONS
extern void CreateGameMenu(RGB8 *myPalette);
extern void CreateOptionsMenu(RGB8 *myPalette);
diff --git a/engines/m4/gui/gui_menu.cpp b/engines/m4/gui/gui_menu.cpp
index 3268e477b8c..c8df5004594 100644
--- a/engines/m4/gui/gui_menu.cpp
+++ b/engines/m4/gui/gui_menu.cpp
@@ -1998,6 +1998,332 @@ void menuItemVSlider::enableVSlider(menuItemVSlider *myItem, int32 tag, guiMenu
}
+//----------------------------- TEXTFIELD MENU ITEM ---------------------------------//
+
+void menuItemTextField::drawTextField(menuItemTextField *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32) {
+ menuItemTextField *myText = nullptr;
+ Buffer *myBuff = nullptr;
+ Buffer *backgroundBuff = nullptr;
+ Sprite *mySprite = nullptr;
+ char tempStr[64], tempChar;
+ int32 cursorX;
+
+ // Verify params
+ if (!myItem || !myMenu)
+ return;
+
+ // If the item is marked transparent, get the background buffer
+ if (myItem->transparent) {
+ if (!myItem->background) {
+ return;
+ }
+ backgroundBuff = myItem->background->get_buffer();
+ if (!backgroundBuff) {
+ return;
+ }
+ }
+
+ // Select the sprite
+ switch (myText->itemFlags) {
+ case TF_GREY:
+ mySprite = _GM(menuSprites)[Burger::GUI::SL_LINE_NORM];
+ break;
+
+ case TF_OVER:
+ mySprite = _GM(menuSprites)[Burger::GUI::SL_LINE_OVER];
+ break;
+
+ case TF_NORM:
+ default:
+ mySprite = _GM(menuSprites)[Burger::GUI::SL_LINE_OVER];
+ break;
+ }
+
+ // Get the menu buffer and draw the sprite to it
+ myBuff = myMenu->menuBuffer->get_buffer();
+ if (!myBuff) {
+ return;
+ }
+
+ // If the item is tagged as transparent, we need to fill in it's background behind it
+ if (backgroundBuff) {
+ gr_buffer_rect_copy_2(backgroundBuff, myBuff, 0, 0, x, y, backgroundBuff->w, backgroundBuff->h);
+ myItem->background->release();
+ }
+
+ // Draw the item sprite in
+ gui_DrawSprite(mySprite, myBuff, x, y);
+
+ //write in the special tag
+ gr_font_set_color(menuItem::TEXT_COLOR_NORM_FOREGROUND);
+ Common::sprintf_s(tempStr, 64, "%02d", myText->specialTag);
+ gr_font_set(_GM(menuFont));
+ gr_font_write(myBuff, tempStr, x + 4, y + 1, 0, -1);
+
+ //write in the text
+ gr_font_write(myBuff, &myText->prompt[0], x + 26, y + 1, 0, -1);
+
+ if (myText->itemFlags == TF_OVER) {
+ // Draw in the cursor
+ if (myText->cursor) {
+ tempChar = *myText->cursor;
+ *myText->cursor = '\0';
+ cursorX = gr_font_string_width(&myText->prompt[0], -1);
+ *myText->cursor = tempChar;
+
+ gr_color_set(menuItem::TEXT_COLOR_OVER_FOREGROUND);
+ gr_vline(myBuff, x + cursorX + 26, y + 1, y + 12);
+ }
+ }
+
+ // Release the menu buffer
+ myMenu->menuBuffer->release();
+}
+
+bool menuItemTextField::handler(menuItemTextField *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem) {
+ bool redrawItem, execCallback, handled;
+ ScreenContext *myScreen;
+ int32 status, temp;
+ char tempStr[80], *tempPtr;
+
+ // Verify params
+ if (!myItem)
+ return false;
+
+ if (myItem->itemFlags == TF_GREY) {
+ return false;
+ }
+
+ redrawItem = false;
+ execCallback = false;
+ handled = true;
+
+ if (eventType == EVENT_MOUSE) {
+ switch (event) {
+ case _ME_L_click:
+ case _ME_doubleclick:
+ _GM(deleteSaveDesc) = false;
+ if (menuItem::cursorInsideItem(myItem, x, y)) {
+ *currItem = myItem;
+ }
+ break;
+
+ case _ME_L_drag:
+ case _ME_doubleclick_drag:
+ break;
+
+ case _ME_L_release:
+ case _ME_doubleclick_release:
+ if (!*currItem) {
+ return true;
+ }
+ *currItem = nullptr;
+ if (menuItem::cursorInsideItem(myItem, x, y)) {
+ if (myItem->itemFlags == TF_OVER) {
+ temp = strlen(myItem->prompt);
+ if (temp > 0) {
+ Common::strcpy_s(tempStr, myItem->prompt);
+ tempPtr = &tempStr[temp];
+ gr_font_set(_GM(menuFont));
+ temp = gr_font_string_width(tempStr, -1);
+ while ((tempPtr != &tempStr[0]) && (temp > x - myItem->x1 - 26)) {
+ *--tempPtr = '\0';
+ temp = gr_font_string_width(tempStr, -1);
+ }
+ myItem->cursor = &myItem->prompt[tempPtr - &tempStr[0]];
+ redrawItem = true;
+ }
+ } else if (event == _ME_doubleclick_release) {
+ execCallback = true;
+ }
+ }
+ break;
+
+ case _ME_move:
+ case _ME_L_hold:
+ case _ME_doubleclick_hold:
+ break;
+ }
+ } else if ((eventType == EVENT_KEY) && (myItem->itemFlags == TF_OVER)) {
+ switch (event) {
+ case KEY_RETURN:
+ _GM(deleteSaveDesc) = false;
+ execCallback = true;
+ break;
+
+ case KEY_HOME:
+ _GM(deleteSaveDesc) = false;
+ myItem->cursor = &myItem->prompt[0];
+ redrawItem = true;
+ break;
+
+ case KEY_END:
+ _GM(deleteSaveDesc) = false;
+ myItem->cursor = myItem->promptEnd;
+ redrawItem = true;
+ break;
+
+ case KEY_LEFT:
+ _GM(deleteSaveDesc) = false;
+ if (myItem->cursor > &myItem->prompt[0]) {
+ myItem->cursor--;
+ redrawItem = true;
+ }
+ break;
+
+ case KEY_RIGHT:
+ _GM(deleteSaveDesc) = false;
+ if (myItem->cursor < myItem->promptEnd) {
+ myItem->cursor++;
+ redrawItem = true;
+ }
+ break;
+
+ case KEY_DELETE:
+ if (_GM(deleteSaveDesc)) {
+ myItem->prompt[0] = '\0';
+ myItem->promptEnd = &myItem->prompt[0];
+ myItem->cursor = myItem->promptEnd;
+ redrawItem = true;
+ } else if (myItem->cursor < myItem->promptEnd) {
+ Common::strcpy_s(tempStr, (char *)(myItem->cursor + 1));
+ Common::strcpy_s(myItem->cursor, 80, tempStr);
+ myItem->promptEnd--;
+ redrawItem = true;
+ }
+ break;
+
+ case KEY_BACKSP:
+ _GM(deleteSaveDesc) = false;
+ if (myItem->cursor > &myItem->prompt[0]) {
+ Common::strcpy_s(tempStr, myItem->cursor);
+ myItem->promptEnd--;
+ myItem->cursor--;
+ Common::strcpy_s(myItem->cursor, 80, tempStr);
+ redrawItem = true;
+ }
+ break;
+
+ default:
+ _GM(deleteSaveDesc) = false;
+ gr_font_set(_GM(menuFont));
+ temp = gr_font_string_width(&myItem->prompt[0], -1);
+ if ((strlen(&myItem->prompt[0]) < 79) && (temp < myItem->pixWidth - 12) && (event >= 32) && (event <= 127)) {
+ if (myItem->cursor < myItem->promptEnd) {
+ Common::strcpy_s(tempStr, (char *)myItem->cursor);
+ Common::sprintf_s(myItem->cursor, 80, "%c%s", (char)event, tempStr);
+ } else {
+ *myItem->cursor = (char)event;
+ *(myItem->cursor + 1) = '\0';
+ }
+ myItem->cursor++;
+ myItem->promptEnd++;
+
+ redrawItem = true;
+ }
+ break;
+ }
+ } else if ((eventType == EVENT_KEY) && (event == KEY_RETURN)) {
+ // The only events a NORM textfield can respond to are doubleclick_release and <return> keypress
+ execCallback = true;
+ } else {
+ // Otherwise the event will not be handled
+ return false;
+ }
+
+ // See if we need to redraw the button
+ if (redrawItem) {
+ (myItem->redraw)(myItem, myItem->myMenu, myItem->x1, myItem->y1, 0, 0);
+ myScreen = vmng_screen_find(myItem->myMenu, &status);
+ if (myScreen && (status == SCRN_ACTIVE)) {
+ RestoreScreens(myScreen->x1 + myItem->x1, myScreen->y1 + myItem->y1,
+ myScreen->x1 + myItem->x2, myScreen->y1 + myItem->y2);
+ }
+ }
+
+ // See if we need to call the callback function
+ if (execCallback && myItem->callback) {
+ (myItem->callback)((void *)myItem, myItem->myMenu);
+ myScreen = vmng_screen_find(myItem->myMenu, &status);
+
+ if ((!myScreen) || (status != SCRN_ACTIVE)) {
+ *currItem = nullptr;
+ }
+ }
+
+ return handled;
+}
+
+menuItemTextField *menuItemTextField::add(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, int32 initFlags,
+ const char *prompt, int32 specialTag, CALLBACK callback, bool transparent) {
+ menuItemTextField *newItem;
+ menuItemTextField *textInfo;
+ ScreenContext *myScreen;
+ int32 status;
+
+ // Verify params
+ if (!myMenu)
+ return nullptr;
+
+ // Allocate a new one
+ newItem = new menuItemTextField();
+
+ // Initialize the struct
+ newItem->next = myMenu->itemList;
+ newItem->prev = nullptr;
+ if (myMenu->itemList) {
+ myMenu->itemList->prev = newItem;
+ }
+ myMenu->itemList = newItem;
+
+ newItem->myMenu = myMenu;
+ newItem->tag = tag;
+ newItem->x1 = x;
+ newItem->y1 = y;
+ newItem->x2 = x + w - 1;
+ newItem->y2 = y + h - 1;
+ newItem->callback = callback;
+
+ if (!transparent) {
+ newItem->transparent = false;
+ newItem->background = nullptr;
+ } else {
+ newItem->transparent = true;
+ newItem->background = guiMenu::copyBackground(myMenu, x, y, w, h);
+ }
+
+ if ((textInfo = (menuItemTextField *)mem_alloc(sizeof(menuItemTextField), "menu item textfield")) == nullptr) {
+ return nullptr;
+ }
+ textInfo->itemFlags = initFlags;
+
+ textInfo->specialTag = specialTag;
+ textInfo->pixWidth = w - 27;
+ if (prompt) {
+ Common::strcpy_s(&textInfo->prompt[0], 80, prompt);
+ textInfo->promptEnd = &textInfo->prompt[strlen(prompt)];
+ } else {
+ textInfo->prompt[0] = '\0';
+ textInfo->promptEnd = &textInfo->prompt[0];
+ }
+ textInfo->cursor = textInfo->promptEnd;
+
+ newItem->redraw = (DrawFunction)menuItemTextField::drawTextField;
+ newItem->destroy = (DestroyFunction)menuItem::destroyItem;
+ newItem->itemEventHandler = (ItemHandlerFunction)menuItemTextField::handler;
+
+ // Draw the vslider in now
+ (newItem->redraw)(newItem, myMenu, x, y, 0, 0);
+
+ // See if the screen is currently visible
+ myScreen = vmng_screen_find(myMenu, &status);
+ if (myScreen && (status == SCRN_ACTIVE)) {
+ RestoreScreens(myScreen->x1 + newItem->x1, myScreen->y1 + newItem->y1,
+ myScreen->x1 + newItem->x2, myScreen->y1 + newItem->y2);
+ }
+
+ return newItem;
+}
} // namespace GUI
} // namespace M4
diff --git a/engines/m4/gui/gui_menu.h b/engines/m4/gui/gui_menu.h
index 48eefee03c7..89a24b61d70 100644
--- a/engines/m4/gui/gui_menu.h
+++ b/engines/m4/gui/gui_menu.h
@@ -304,6 +304,17 @@ struct menuItemTextField : public menuItem {
char *promptEnd = nullptr;
char *cursor = nullptr;
+
+ enum {
+ TF_NORM = 0,
+ TF_OVER = 1,
+ TF_GREY = 2
+ };
+
+ static menuItemTextField *add(guiMenu *myMenu, int32 tag, int32 x, int32 y, int32 w, int32 h, int32 initFlags,
+ const char *prompt = nullptr, int32 specialtag = 0, CALLBACK callback = nullptr, bool transparent = false);
+ static bool handler(menuItemTextField *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem);
+ static void drawTextField(menuItemTextField *myItem, guiMenu *myMenu, int32 x, int32 y, int32, int32);
};
struct guiMenu {
More information about the Scummvm-git-logs
mailing list