Simple Menu

Написан простенькое меню.

Класс меню, наследует базовый класс GuiElement

/// @description CHECK BOX
//Site:   MidaDev.ru
//Author: Dimusikus
enum MENU_TYPE
{	
	GO_SUB_MENU,	//тип переход в другое меню
	CALL_BACK,		//тип вызов функции
	RETURN			//возврат в предыдущее меню
};

enum MENU_ITEM
{	
	name,	
	type,	
	callback
};

function GUI_Menu_Text() : GUIElement() constructor 
{	
	#region Constructor
	my_name_is	= other.my_name_is;		
	menu		= ds_map_create(); //карта менюшек	
	index		= ds_map_create(); //индексы где хранится позиция курсора для данного меню
	curr_parent = "General"; //текущий родитель страницы меню
	back_parent = []; //история, предыдущий блок меню, используется что бы туда вернуцться по клавише эскапэ
	//index		= 0;  //выбранный индекс меню, т.е. куда курсор стоит	
	menu[? curr_parent] = ds_list_create();
	index[? curr_parent] = 0;
	
	//GUI_Elements.add_element(my_name_is, self);
	#endregion	
	//*******************************************************************
	static add_menu = function(_parent, _name, _type, _callback=pointer_null)
	{ 
		//если такого списка меню еще не существует то создаём его
		if menu[? _parent] == undefined then menu[? _parent] = ds_list_create();
		//если индекса текущего пункта данного меню не существует то инициилизируем его на 0
		if index[? _parent] == undefined then index[? _parent] = 0;
		
		var item=[];
		item[MENU_ITEM.name] = _name;		
		item[MENU_ITEM.type] = _type;
		item[MENU_ITEM.callback] = _callback;
		
		ds_list_add(menu[? _parent], item);
	}
	//*******************************************************************
	static set_return = function()
	{
		var par = array_pop(back_parent);
		if !is_undefined(par) then curr_parent = par;
	}
	static set = function()
	{
		//trace("set=", _type);
		var item = ds_list_find_value(menu[? curr_parent], index[? curr_parent]);
		//var item_name		= item[MENU_ITEM.name];		
		var item_type		= item[MENU_ITEM.type];		
		var item_callback	= item[MENU_ITEM.callback];
		
		//если это каллбак то вызываем функцию
		if item_type == MENU_TYPE.CALL_BACK then if item_callback!=pointer_null then item_callback();
		
		//если это переход в другое меню то меняем менюшку
		if item_type == MENU_TYPE.GO_SUB_MENU then
		{	array_push(back_parent, curr_parent);
			curr_parent = item_callback;
		}
		
		//возврат в предыдущее меню
		if item_type == MENU_TYPE.RETURN then	set_return();				
	}
	//*******************************************************************
	static step = function() 
	{ 
		//ждём клика мышкой
		if (mouse_check_button_pressed(mb_left)) then
		{	mouse_clear(mb_any); 		
			//тогда высчитываем куда ана кликнула
			for(var i = 0; i<=ds_list_size(menu[? curr_parent]); i++) 
			{	if ( !point_in_rectangle(mouse_x, mouse_y,	_xo, _yo + (char_height * i), _xo + width, _yo + (char_height * (i+1))) ) then continue;				
				index[? curr_parent] = i; //поймали клик на элементе i
				set(true);
				return;
			}	
		};
		
		var to_key = keyboard_check_pressed(vk_down) - keyboard_check_pressed(vk_up);
		index[? curr_parent] = clamp(index[? curr_parent]+to_key, 0 , ds_list_size(menu[? curr_parent])-1);
		
		to_key = mouse_wheel_down() - mouse_wheel_up();
		index[? curr_parent] = clamp(index[? curr_parent]+to_key, 0 , ds_list_size(menu[? curr_parent])-1);
		
		var space_key = keyboard_check_pressed(vk_space);
		var enter_key = keyboard_check_pressed(vk_enter);
		if (space_key+enter_key)>=1 then set(true);		
		
		var esc_key = keyboard_check_pressed(vk_escape);
		var bs_key = keyboard_check_pressed(vk_backspace);
		if (esc_key+bs_key)>=1 then set_back();
		
		/*if mouse_released then
		{	mouse_clear(mb_any);  
			trace("полноценное нажатиэ");
			EVENTGUI.publish(my_name_is, true);
			//if callback!=pointer_null then callback();
			GUI_Elements.element_callback(my_name_is);
		};*/
	}
	//*******************************************************************
	static draw = function() 
	{	
		draw_focus();				
		draw_set_color(color_text);				
		draw_set_hv(other.text_halign);		
		var size = ds_list_size(menu[? curr_parent]);		
		for (var i = 0; i < size; i++;)
		{
			var _item = ds_list_find_value(menu[? curr_parent], i);			
			var ku = i == index[? curr_parent] ? ">" : " ";
			//if i == index then draw_text(x - char_width,y + i * char_height , ">");
			draw_text(x - string_width(ku),y + i * char_height ,ku + _item[0]);
		}		
	}	
	//*******************************************************************
	//инициализируем значение
	//set(value);	
	//*******************************************************************
}

Пункты меню создаются следующим кодом:

/// @description
//Site:   MidaDev.ru
//Author: Dimusikus

menu = new GUI_Menu_Text();

function fexit(){ game_end();};
function frestart(){ game_restart() ;};

menu.add_menu("General", "New Game", MENU_TYPE.CALL_BACK,	frestart);
menu.add_menu("General", "Settings", MENU_TYPE.GO_SUB_MENU, "Settings");
menu.add_menu("General", "Exit",	 MENU_TYPE.CALL_BACK,	fexit);

menu.add_menu("Settings", "Volume",	 MENU_TYPE.CALL_BACK);
menu.add_menu("Settings", "Difficulty",	 MENU_TYPE.CALL_BACK);
menu.add_menu("Settings", "Return",	 MENU_TYPE.RETURN, "General");