function menu(...) --ЕСЛИ ЧИСЛО АРУМЕНТОВ < 3 И ТИП ТРЕТЬЕГО АРГУМЕНТА НЕ TABLE, ТО ВЫДАТЬ ОШИБКУ ПО ИСПОЛЬЗОВАНИЮ API if #arg < 3 or type(arg[3]) ~= "table" then error("Usage: menu(number x,number y,table Element1,table Element2, table Element3...) \nReturns: string Action \n structure: {string Name[, boolean isElementHidden][,number colorOfText]}") end --ПОЛУЧЕНИЕ РАЗМЕРА МОНИТОРА local xSize, ySize = term.getSize() --ПРОСТОЕ ОТОБРАЖЕНИЕ ТЕКСТА В УКАЗАННЫХ КООРДИНАТАХ С УКАЗАННЫМ ЦВЕТОМ local function text(x,y,text1,color) term.setTextColor(color) term.setCursorPos(x,y) term.write(text1) end --СОЗДАНИЕ ОБЪЕКТОВ В ПАМЯТИ (В НАШЕМ СЛУЧАЕ КНОПОК, ОТВЕЧАЮЩИХ ЗА ВЫБОР ЭЛЕМЕНТА МЕНЮ) local Objects = {} local function newObj(name,isHidden,xStart,xEnd,y) Objects[name]={} Objects[name]["isHidden"] = isHidden Objects[name]["xStart"] = xStart Objects[name]["xEnd"] = xEnd Objects[name]["y"] = y end --ОПРЕДЕЛЕНИЕ САМОГО ДЛИННОГО ПО КОЛ-ВУ СИМВОЛОВ ЭЛЕМЕНТА МЕНЮ local theLongestElement = #arg[3][1] for i=3,#arg do if arg[i] ~= "-" and theLongestElement < #arg[i][1] then theLongestElement = #arg[i][1] end end --ОПРЕДЕЛЕНИЕ РАЗМЕРА МЕНЮ local xSizeOfMenu = theLongestElement + 4 local ySizeOfMenu = #arg-2 local xStartToDisplay = nil local yStartToDisplay = nil --РИСОВАНИЕ КВАДРАТА С ЗАЛИВКОЙ local function square(x1,y1,width,height,color) local string = string.rep(" ",width) term.setBackgroundColor(color) for y=y1,(y1+height-1) do term.setCursorPos(x1,y) term.write(string) end end --ОТРИСОВКА РАЗДЕЛИТЕЛЯ В МЕНЮ local function drawSeparator(x,y,size) term.setTextColor(colors.lightGray) term.setCursorPos(x,y) term.write(string.rep("-",size)) end --ФУНКЦИЯ ОТРИСОВКИ ВСЕГО МЕНЮ local function drawMenu(xMenu,yMenu) --КОРРЕКЦИЯ КООРДИНАТЫ МЕНЮ, ЧТОБ ЗА КРАЯ ЭКРАНА НЕ ЗАЛЕЗАЛО if yMenu+ySizeOfMenu - 1 >= ySize then yMenu = yMenu - (yMenu+ySizeOfMenu - 1 - ySize) - 1 end if xMenu+xSizeOfMenu - 1 >= xSize then xMenu = xMenu - (xMenu+xSizeOfMenu - 1 - xSize) - 1 end --ОПРЕДЕЛЕНИЕ ТОЧЕК СТАРТА ОТОБРАЖЕНИЯ ТЕКСТА В МЕНЮ xStartToDisplay = xMenu + 2 yStartToDisplay = yMenu --ОТРИСОВКА ТЕНИ МЕНЮ square(xMenu+1,yMenu+1,xSizeOfMenu,ySizeOfMenu,colors.gray) --ОТРИСОВКА БЕЛОЙ ПОДЛОЖКИ МЕНЮ square(xMenu,yMenu,xSizeOfMenu,ySizeOfMenu,colors.white) --ЦИКЛ ПЕРЕБОРА ВСЕХ ЭЛЕМЕНТОВ МЕНЮ, РАССМАТРИВАЕМ ДАННЫЕ О КАЖДОМ for i=3,#arg do --ЕСЛИ ВЫБРАННЫХ ЭЛЕМЕНТ НЕ ЯВЛЯЕТСЯ РАЗДЕЛИТЕЛЕМ, ТО if arg[i] ~= "-" then --ЗАДАНИЕ СТАНДАРТНОГО ЦВЕТА ТЕКСТА ДЛЯ ЭЛЕМЕНТА МЕНЮ local contextColor = colors.black --ЕСЛИ АРГУМЕНТ_2 (СКРЫТЫЙ/НЕ СКРЫТЫЙ) И АРУМЕНТ_3 (ЦВЕТ ТЕКСТА ЭЛЕМЕНТА) ДЛЯ РАССМАТРИВАЕМОГО ЭЛЕМЕНТА НЕ УКАЗАНЫ, ТО if arg[i][2] == nil and arg[i][3] == nil then contextColor = colors.black --ЕСЛИ АРГУМЕНТ 2 = FALSE И АРГУМЕНТ 3 НЕ УКАЗАН, ТО elseif arg[i][2] == false and arg[i][3] == nil then contextColor = colors.black --ЕСЛИ АРГУМЕНТ 2 = FALSE И АРГУМЕНТ 3 УКАЗАН, ТО elseif arg[i][2] == false and arg[i][3] ~= nil then contextColor = arg[i][3] --ЕСЛИ АРГУМЕНТ 2 = TRUE, ТО ЭЛЕМЕНТ СКРЫТ elseif arg[i][2] == true then contextColor = colors.lightGray end --ОТОБРАЖЕНИЕ ТЕКСТА ЭЛЕМЕНТА В САМОМ МЕНЮ text(xStartToDisplay,yStartToDisplay+i-3,arg[i][1],contextColor) --СОЗДАНИЕ ОБЪЕКТА ЭЛЕМЕНТА В ПАМЯТИ, ЧТОБЫ ПОТОМ ИМЕТЬ К НЕМУ ДОСТУП newObj(arg[i][1],arg[i][2],xMenu,xMenu+xSizeOfMenu-1,yStartToDisplay+i-3) --А ЕСЛИ ВСЕ-ТАКИ ЯВЛЯЕТСЯ, ТО else drawSeparator(xMenu,yStartToDisplay+i-3,xSizeOfMenu) end end end --СТАРТ ПРОГРАММЫ, РИСУЕМ МЕНЮ drawMenu(arg[1],arg[2]) --ОТСЛЕЖИВАНИЕ КЛИКА МЫШИ local event,side,xClick,yClick = os.pullEvent() if event == "monitor_touch" then side = 1 end if event == "mouse_click" or event == "monitor_touch" then --ПЕРЕБОР ВСЕХ ЭЛЕМЕНТОВ МАССИВА ОБЪЕКТОВ В ПАРЕ СО ЗНАЧЕНИЕМ ЭЛЕМЕНТА (КЛЮЧ = ЗНАЧЕНИЕ, KEY = VAL) for key,val in pairs(Objects) do --ЕСЛИ МЫ КЛИКНУЛИ НА ОБЪЕКТ, И ЭТОТ ОБЪЕКТ НЕ ЯВЛЯЕТСЯ СКРЫТЫМ, ТО if xClick >= Objects[key]["xStart"] and xClick <= Objects[key]["xEnd"] and yClick == Objects[key]["y"] and Objects[key]["isHidden"] == false or xClick >= Objects[key]["xStart"] and xClick <= Objects[key]["xEnd"] and yClick == Objects[key]["y"] and Objects[key]["isHidden"] == nil then --НАРИСОВАТЬ ГОЛУБОЕ ВЫДЕЛЕНИЕ ЭЛЕМЕНТА МЕНЮ for i=Objects[key]["xStart"],Objects[key]["xEnd"] do paintutils.drawPixel(i,Objects[key]["y"],colors.blue) end --ОТОБРАЗИТЬ ТОТ ЖЕ ТЕКСТ, ТОЛЬКО БЕЛЫМ ЦВЕТОМ text(xStartToDisplay,Objects[key]["y"],key,colors.white) --ЖДАТЬ НЕКОТОРОЕ ВРЕМЯ sleep(0.3) --ВЕРНУТЬ ЗНАЧЕНИЕ KEY (ТО ЕСТЬ ЗНАЧЕНИЕ ВЫБРАННОГО ЭЛЕМЕНТА МЕНЮ) И ЗАВЕШИТЬ ПРОГРАММУ МЕНЮ return key end --А ЕСЛИ НИКАКОЙ ЭЛЕМЕНТ МЕНЮ НЕ БЫЛ ВЫБРАН, ТО ФУНКЦИЯ ВЕРНЕТ NIL end end end