(solved)Help with keeping a contextual menu on screen

flyinian

Member
I am trying to create a contextual menu and so, far so good besides the fact that I can't figure out how to keep the sub menu open(active?).

Menu 1 > sub menu 1 > item 1 , item 2, and so forth. The sub menu is the list of item 1, item 2 and so forth.
Mouse Hover on Menu 1 > Should open the sub menu > with its menu options that are clickable to activate their code.

When I hover over Menu 1 it opens the sub menu as it should and I am able to drag my cursor over to it to keep it open but all of the items within the sub menu besides the first item which is where my cursor is currently located closes/disappears/etc.

I am following a video tutorial for this and here is that video. In the video the first menu will be destroyed for that the second menu can be created and I have stopped that from happening and want all menu to still show while I am still interacting with it until the mouse leaves the buttons.

Below is the step event that creates the menu.
Code:
 //step event
if (point_in_rectangle(mouse_x, mouse_y, x - Width, y - Height, x + Width, y + Height))
{
Hover = 1; //set hover to 1
HoverColor = c_yellow;

if (mouse_check_button(mb_left))
{
Hover = 2;
HoverColor = c_red;
}
}


else 
{
    Hover = 0; 
    HoverColor = c_white;
}

if (Hover == 1) 
{
    
    if(mouse_check_button_released(mb_left)) 
    {
    switch(BUTTON_TYPE) 
    {
        case 1: //menu 1
        with(obj_buttonspawner)
        {
        event_user(0);
        }
        break;
        
        case 2: //menu 2
        with(obj_buttonspawner)
        {
        event_user(1);
        }
        break;
        
        case 3: //menu 3
        with(obj_buttonspawner)
        {
        event_user(2);
        }
        
        break;
        
        case 4: //menu 4
        with(obj_buttonspawner)
        {
        event_user(3);
        }
        break;
        
        default:
        
        break;
        
    }}}
Here is this code. This code belongs in the object that spawns the buttons.

Code:
//User-Event(0)
//The creates the popup menus when mouse hover
with(obj_button)
{
    
There was an "instance_destroy()" in here and I removed it so it would't destroy my menu 1 with mouse click/hover.

}


var Button_1 = instance_create_depth(view_xport[0] + 249, view_yport[0] + 23, 1,obj_subbutton);
Button_1.BUTTON_TYPE = 1;
Button_1.HoverValue = 1;

var Button_2 = instance_create_depth(view_xport[0] + 249, view_yport[0] + 83, -5000,obj_subbutton);
Button_2.BUTTON_TYPE = 2;
Button_2.HoverValue = 2;

var Button_3 = instance_create_depth(view_xport[0] + 249, view_yport[0] + 143, -5000,obj_subbutton);
Button_3.BUTTON_TYPE = 3;
Button_3.HoverValue = 3;

var Button_4 = instance_create_depth(view_xport[0] + 249, view_yport[0] + 206, -5000,obj_subbutton);
Button_4.BUTTON_TYPE = 4;
Button_4.HoverValue = 4;

Let me know if you need any clarification and I hope the code I provided will suffice. I believe I am just missing a simple line of code in one of these events.

Thank you.
 

TheouAegis

Member
If you move the mouse to where the other Submenus should be, do they appear? Or is the first submenu the only one that is ever visible?
 

flyinian

Member
If you move the mouse to where the other Submenus should be, do they appear? Or is the first submenu the only one that is ever visible?
The entire sub menu will a pear when I hover over the Menu button but, once I leave the menu button and go to the first sub menu item the rest of the sub menu items disappears besides the current sub menu item that I am on.
 

TheouAegis

Member
What's in obj_subbitton's code? Syep? Draw?

Is obj_subbutton a child of anyone?

Run in debug mode. Are the submenus still in the room or are they gone? If in the room, are they visible?
 

flyinian

Member
What's in obj_subbitton's code? Syep? Draw?
Code:
//obj_subbutton create event:

/// @description Insert description here
BUTTON_TYPE = 0;
String = "";
Hover = 1;   
Width =    80;     
Height = 20;  
HoverValue = 0;
HoverColor = c_white;

alarm[0] = 1;
Code:
//obj_subbutton step event:
//Check to see if a mouse hover exists;
if (point_in_rectangle(mouse_x, mouse_y, x - Width, y - Height, x + Width, y + Height))
{
Hover = 1;
HoverColor = c_yellow;
//instance_activate_object(obj_subbutton);
if (mouse_check_button(mb_left))
{
Hover = 2; //set the hover to 2
HoverColor = c_red;
}
}


else
{
    Hover = 0; // set hover to 0. (no hover)
    HoverColor = c_white;
    instance_destroy();

}
{
}
if (Hover == 1)
{
  
    if(mouse_check_button_released(mb_left))
    {
    switch(BUTTON_TYPE)
    {
        case 1: //item 1
        with(obj_buttonspawner)
        {
        room_goto(rm_1);
        }
        break;
//case 1 works as it should. below cases not set yet.
        case 2: //menu 2
        with(obj_buttonspawner)
        {
        //code goes here
        }
        break;
      
        case 3: //menu 3
        with(obj_buttonspawner)
        {
        //code goes here
        }
      
        break;
      
        case 4: //menu 4
        with(obj_buttonspawner)
        {
        //code goes here
        }
        break;
      
        default:
      
        break;
      
    }}}



/*
//The below code is the original code before I started making my edits and testing.

if (point_in_rectangle(mouse_x, mouse_y, x - Width, y - Height, x + Width, y + Height))
{
Hover = 1; //set hover to 1
HoverColor = c_yellow; //set over color to yellow

if (mouse_check_button(mb_left))
{
Hover = 2; //set the hover to 2
HoverColor = c_red; //set the hover color to red
}
}
else
{
    Hover = 0; // set hover to 0. (no hover)
    HoverColor = c_white; // set hover color to white.
}

if (Hover == 1)
{
   
    if(mouse_check_button_released(mb_left))
    {
    switch(BUTTON_TYPE)
    {
        case 1: //menu 1
        with(obj_buttonspawner)
        {
        event_user(0);
        }
        break;
       
        case 2: //menu 2
        with(obj_buttonspawner)
        {
        event_user(1);
        }
        break;
       
        case 3: //menu 3
        with(obj_buttonspawner)
        {
        event_user(2);
        }
       
        break;
       
        case 4: //menu 4
        with(obj_buttonspawner)
        {
        event_user(3);
        }
        break;
       
        default:
       
        break;
       
    }}}

Code:
//sub_button Alarm event:

//creates the text on the buttons.
//The text doesn't show when the buttons are created. I have to hover over the buttons to have the text to //show. I am not as concerned about his as I am with the buttons disappearing.
    switch(BUTTON_TYPE)
    {
        case 1: //Item 1
        String = "Item 1";
        break;
       
        case 2: //Item 2
        String = "Item 2";
        break;
       
        case 3: //Item 3
        String = "Item 3";
        break;
       
        case 4: //Item 4
        String = "Item 4";
        break;
       
        default: //default button.(no text)
        String = "";
        break;
       
    }
Code:
//sub_button Draw event:

//set the button's bounding box color;
draw_set_color(HoverColor); // Sets the hover color overlay.

//Draw button bounding box
draw_rectangle(x - Width, y - Height, x + Width, y + Height, false); //Creates the rectangle for the button.

//Text draw settings
draw_set_color(c_black); //color of the text
draw_set_halign(fa_center); //text's horizontal alignment
draw_set_valign(fa_middle); //text's vertical alignent

//draw text
draw_text(x,y,String); //draws the text on the button

//revert drawing settings
draw_set_color(-1); //
draw_set_halign(fa_left);
draw_set_valign(fa_top);
Is obj_subbutton a child of anyone?
No, There are no parents to any objects.

Run in debug mode. Are the submenus still in the room or are they gone? If in the room, are they visible?
As far as my knowledge goes for the debugger, The call count for the code in the obj_subbutton of the profiling increases if I hover over the menu item list. If I am not hovering it stops the count. so, they are not in the room if I am not activating them(hovering over what creates them) and when they are active(when I hover over what creates them) they are visible.
The below listed were all listed in the profiler
obj_subbutton(DRAW) is listed.
obj_subbutton(ALARM) is listed.
obj_subbutton(STEP) is listed.

In the "Instances" page of the debugger it shows the obj_subbutton listed if I activate the sub menu with the hovering. I get additional obj_subbuttons if I have the entire submenu show.


I hope the above has helped and is clear.

Thank you.
 

TheouAegis

Member
if (Hover == 1) { if(mouse_check_button_released(mb_left)) {
One thing I noticed is your code says if the mouse button is pressed while over the submenu, set its Hover to 2. BUT your code then goes on to say if the mouse button is released while Hover is 1, go to the next room or whatever. ...Hover should never be 1 when you release the mouse button.

else { Hover = 0; // set hover to 0. (no hover) HoverColor = c_white; instance_destroy(); }
Also your code says when the mouse is NOT over the area defined, then set Hover to 0 AND destroy the instance. So all your subbuttons are destroying themselves because of that.
 

TheouAegis

Member
I'm not sure what the standard for menus in GMS2 is. There was functionality for them in GM8, which sadly was removed for cross-platform functionality, although I couldn't get sub-menus to work properly.

Personally if we're going to stick with an instance-based menu, I'd do something like using global variables to keep track of things. I'd have an array to keep track of which menus are open; probably only need to go 3 deep:

global.openMenu[2] = -1

For each of your main menus, make an enumerator.

enum Menu{
File,
Edit,
Help,
Recent
}

Also make another variable to keep track of the menu depth.

global.MenuDepth = 0

When you click on a menu, set global.openMenu[global.MenuDepth] to whatever enum based on what you clicked on, then increase the depth.

global.openMenu[global.MenuDepth++]=Menu.File;

When you close all the menus, loop through the array while decreasing MenuDepth.

while global.MenuDepth>0 { global.openMenu[global.MenuDepth--]=-1;

In your Draw Event of your controller object, check if any of the values in global.openMenu[] are not -1. For each one that's not -1, draw the proper menu baased on the enum that's assigned to that spot in the array.You could use a switch or some kind of data structure to sort that out.
 

flyinian

Member
I'm not sure what the standard for menus in GMS2 is. There was functionality for them in GM8, which sadly was removed for cross-platform functionality, although I couldn't get sub-menus to work properly.

Personally if we're going to stick with an instance-based menu, I'd do something like using global variables to keep track of things. I'd have an array to keep track of which menus are open; probably only need to go 3 deep:

global.openMenu[2] = -1

For each of your main menus, make an enumerator.

enum Menu{
File,
Edit,
Help,
Recent
}

Also make another variable to keep track of the menu depth.

global.MenuDepth = 0

When you click on a menu, set global.openMenu[global.MenuDepth] to whatever enum based on what you clicked on, then increase the depth.

global.openMenu[global.MenuDepth++]=Menu.File;

When you close all the menus, loop through the array while decreasing MenuDepth.

while global.MenuDepth>0 { global.openMenu[global.MenuDepth--]=-1;

In your Draw Event of your controller object, check if any of the values in global.openMenu[] are not -1. For each one that's not -1, draw the proper menu baased on the enum that's assigned to that spot in the array.You could use a switch or some kind of data structure to sort that out.
Thanks for replying. I didn't get anywhere with it. I think I'm done with this.
 
Top