Drop Down Menus for Simple Window Manager (SWM)

Share your scripts and packages with other Mudlet users.
Jor'Mox
Posts: 1101
Joined: Wed Apr 03, 2013 2:19 am

Re: Drop Down Menus for Simple Window Manager (SWM)

Post by Jor'Mox »

So, I have been trying to think of any functions I missed. So far I have, setBackgroundColor, setFontSize, setOnEnter, and setOnLeave (so that you can essentially mimic any of the key functionalities you might reasonably want to have available for the menu items, the main button is the label with the same name as the menu, so it can in theory be accessed that way as well). Can anyone else think of something that they might want that isn't available?

User avatar
chris
Posts: 493
Joined: Fri Jun 17, 2011 5:39 am

Re: Drop Down Menus for Simple Window Manager (SWM)

Post by chris »

Might want to check out this page:

http://wiki.mudlet.org/w/Manual:Geyser#Nestable_Labels

And check out the code for how you can make labels that flyout when hovered on.

Jor'Mox
Posts: 1101
Joined: Wed Apr 03, 2013 2:19 am

Re: Drop Down Menus for Simple Window Manager (SWM)

Post by Jor'Mox »

Will do chris, thanks for pointing it out. At the very least, I think I'll add in a "setMenuOpenOnHover" function, and a "createSubMenu" function, to make stuff like that a little bit easier to emulate. Though, submenus are going to require some rewriting of things, to be a bit more flexible in how menu items are named. Shouldn't be too big a deal though.

icesteruk
Posts: 287
Joined: Sun Jan 20, 2013 9:16 pm

Re: Drop Down Menus for Simple Window Manager (SWM)

Post by icesteruk »

Unsure if this is already in it or not but,

this part
Code: [show] | [select all] lua
function clickMenu(menu, button)
        echo("You clicked button number: " .. button .. " in menu number: " .. menu .. ".\n")
        hideMenu(menu)
end
Anyway to change it so, If I have 3 'menus' I can do 3 different clickmenu functions? Instead of having them all in the first one with something like

if menu == 1 then
if button == 1 then echo("\nhii") end
end
if menu == 2 then
end
etc etc ?

Jor'Mox
Posts: 1101
Joined: Wed Apr 03, 2013 2:19 am

Re: Drop Down Menus for Simple Window Manager (SWM)

Post by Jor'Mox »

If you look at my second posted script, you will notice that it is completely different from the first. The first was basically just a simple script thrown together that could be used to manage menus, but it wasn't very sophisticated. My second script is a (mostly) complete set of functions to create, position, and otherwise manage any number of menus in much the same way that you would use base functions to create and manage labels. Using the second script, you would use the setMenuClickCallback function to specify a function and any arguments it is to receive when a particular button in a particular menu is clicked. This lets you easily specify which function works with what menu buttons. However, as I have not yet integrated these new "menu objects" into the Simple Window Manager script, you can't have it manage their size and position as you can in the first example. It is on my to do list, but I, as always, a bit busy.

If you are generally okay with the solution presented in the first post, but just want to split up which functions are called by different menus, then you can find this line in the script:
Code: [show] | [select all] lua
setLabelClickCallback(v2, "clickMenu",k,k2)
and change it to something like this:
Code: [show] | [select all] lua
setLabelClickCallback(v2, menuFunctions[k],k2)
, where the table menuFunctions is defined in this way:
Code: [show] | [select all] lua
menuFunctions = {"functionForMenu1", "functionForMenu2", "functionForMenu3"}
or change it like this:
Code: [show] | [select all] lua
setLabelClickCallback(v2, menuFunctions[k][k2])
where the table menuFunctions is defined in this way:
Code: [show] | [select all] lua
menuFunctions = {{"functionForMenu1Button1","functionForMenu1Button2","functionForMenu1Button3"}, {"functionForMenu2Button1","functionForMenu2Button2","functionForMenu2Button3"}}

Jor'Mox
Posts: 1101
Joined: Wed Apr 03, 2013 2:19 am

Re: Drop Down Menus for Simple Window Manager (SWM)

Post by Jor'Mox »

Here is an update to the Menu functions I have been working on.

Recently Added Functions:
setMenuBackgroundColor(menuName, (optional) buttonNumber, r, g, b, t) -- sets the color of the whole menu, or the button specified by buttonNumber
setMenuFontSize(menuName, (optional) buttonNumber, fontSize) -- sets the font size for the whole menu, or for the button specified by buttonNumber
setMenuOnEnter(menuName, buttonNumber, luaFunctionName, (optional) any number of arguments) -- passes function and arguments to setLabelOnEnter for button specified by buttonNumber
setMenuOnLeave(menuName, buttonNumber, luaFunctionName, (optional) any number of arguments) -- passes function and arguments to setLabelOnLeave for button specified by buttonNumber

I'm still working on a setMenuOpenOnHover and a creatSubMenu function. If you can think of other functions or functionalities that you would like to see added, please chime in.
Code: [show] | [select all] lua
-- Menu GUI Objects Script --
--	Zachary Hiland
--	9/01/2013

-- To Do List:

-- setMenuOpenOnHover
-- createSubMenu

menusTable = menusTable or {}

function createMenu(menuName, x, y, width, height, menuText, numButtons, buttonPosition, buttonDirection)
	menuText = menuText or ""
	numButtons = numButtons or 1
	buttonPosition = buttonPosition or "bottom"
	buttonDirection = buttonDirecton or "down"
	
	assert(table.contains({"bottom","top","left","right"},buttonPosition), "createMenu: buttonPosition must be bottom, top, left, or right")
	assert(table.contains({"up","down","left","right"},buttonDirection), "createMenu: buttonDirection must be up, down, left, or right")
	
	local tbl = {open = false, width = width, height = height, x = x, y = y, text = menuText, numButtons = numButtons, buttonPos = buttonPosition, buttonDir = buttonDirection}
	-- save new values in table
	menusTable[menuName] = tbl
	
	createLabel(menuName,0,0,0,0,1)
	setBackgroundColor(menuName,0,0,0,255)
	setLabelClickCallback(menuName, "openMenu", menuName, "true")
	for k = 1,numButtons do
		createLabel(menuName.."_menubutton_"..k,0,0,0,0,1)
		setBackgroundColor(menuName.."_menubutton_"..k,0,0,0,255)
		setMenuText(menuName, "Button " .. k, k, "white")
		setLabelClickCallback(menuName.."_menubutton_"..k, "closeMenu", menuName)
		hideWindow(menuName.."_menubutton_"..k)
	end
	
	-- resize and move menu to desired position
	resizeMenu(menuName, tbl.width, tbl.height)
	moveMenu(menuName, tbl.x, tbl.y)
	-- write text on main menu button
	setMenuText(menuName, menuText, "white")
	showMenu(menuName)
end

function setMenuPosition(menuName, position)
	assert(menusTable[menuName], "setMenuPosition: no such menu exists.")
	assert(table.contains({"bottom","top","left","right"},position), "setMenuPosition: Position must be bottom, top, left, or right")
	menusTable[menuName].buttonPos = position
end

function setMenuDirection(menuName, direction)
	assert(menusTable[menuName], "setMenuDirection: no such menu exists.")
	assert(table.contains({"up","down","left","right"},direction), "setMenuDirection: Direction must be up, down, left, or right")
	menusTable[menuName].buttonDir = direction
end

function setMenuBackgroundColor(menuName, buttonNumber, r, g, b, t)
	assert(menusTable[menuName], "setMenuBackgroundColor: no such menu exists.")
	if not t then
		r,g,b,t = buttonNumber,r,g,b
		setBackgroundColor(menuName,r,g,b,t)
		for k = 1, menusTable[menuName].numButtons do
			setBackgroundColor(menuName.."_menubutton_"..k, r,g,b,t)
		end
	else
		assert(tonumber(buttonNumber) and buttonNumber <= menusTable[menuName].numButtons, "setMenuBackgroundColor: buttonNumber higher than number of buttons in menu.")
		setBackgroundColor(menuName.."_menubutton_"..buttonNumber, r,g,b,t)
	end
end

function setMenuNumberButtons(menuName, numButtons)
	assert(menusTable[menuName], "setMenuNumberButtons: no such menu exists.")
	local curButtons = menusTable[menuName].numButtons
	menusTable[menuName].numButtons = numButtons
	if curButtons < numButtons then
		for k = curButtons + 1,numButtons do
			createLabel(menuName.."_menubutton_"..k,0,0,0,0,1)
			setBackgroundColor(menuName.."_menubutton_"..k,0,0,0,255)
			setMenuText(menuName, "Button " .. k, k, "white")
			setLabelClickCallback(menuName.."_menubutton_"..k, "closeMenu", menuName)
			hideWindow(menuName.."_menubutton_"..k)
		end
	elseif curButtons > numButtons then
		for k = numButtons + 1, curButtons do
			hideWindow(menuName.."_menubutton_"..k)
		end
	end
end

function setMenuStyleSheet(menuName, buttonNumber, buttonCSS)
	assert(menusTable[menuName], "setMenuStyleSheet: no such menu exists.")
	if tonumber(buttonNumber) then
		assert(buttonNumber <= menusTable[menuName].numButtons, "setMenuStyleSheet: buttonNumber higher than number of buttons in menu.")
		setLabelStyleSheet(menuName.."_menubutton_"..buttonNumber, buttonCSS)
	else
		buttonCSS = buttonCSS or buttonNumber
		setLabelStyleSheet(menuName, buttonNumber)
		for k = 1, menusTable[menuName].numButtons do
			setLabelStyleSheet(menuName.."_menubutton_"..k, buttonCSS)
		end
	end
end

function setMenuClickCallback(menuName, buttonNumber, ...)
	assert(menusTable[menuName], "setMenuClickCallback: no such menu exists.")
	assert(tonumber(buttonNumber) and buttonNumber <= menusTable[menuName].numButtons, "setMenuClickCallback: buttonNumber higher than number of buttons in menu.")
	setLabelClickCallback(menuName.."_menubutton_"..buttonNumber, ...)
end

function setMenuOnEnter(menuName, buttonNumber, ...)
	assert(menusTable[menuName], "setMenuOnEnter: no such menu exists.")
	assert(tonumber(buttonNumber) and buttonNumber <= menusTable[menuName].numButtons, "setMenuOnEnter: buttonNumber higher than number of buttons in menu.")
	setLabelOnEnter(menuName.."_menubutton_"..buttonNumber, ...)
end

function setMenuOnLeave(menuName, buttonNumber, ...)
	assert(menusTable[menuName], "setMenuOnLeave: no such menu exists.")
	assert(tonumber(buttonNumber) and buttonNumber <= menusTable[menuName].numButtons, "setMenuOnLeave: buttonNumber higher than number of buttons in menu.")
	setLabelOnLeave(menuName.."_menubutton_"..buttonNumber, ...)
end

function setMenuText(menuName, text, buttonNumber, r, g, b)
	assert(menusTable[menuName], "setMenuText: no such menu exists.")
	if r ~= nil then
		if g == nil then
			r,g,b = getRGB(r)
		elseif b == nil then
			r,g,b = buttonNumber,r,g
			buttonNumber = nil
		end
	elseif buttonNumber and not tonumber(buttonNumber) then
		r,g,b = getRGB(buttonNumber)
		buttonNumber = nil
	else
		r,g,b = 255,255,255
	end
	local echoString = [[<font color ="#]] .. RGB2Hex(r,g,b) .. [[">]] .. text .. [[</font>]]
	local labelName = menuName
	if buttonNumber then
		assert(menusTable[menuName].numButtons >= buttonNumber, "setMenuText: buttonNumber higher than number of buttons in menu.")
		labelName = labelName .. "_menubutton_" .. buttonNumber
		if menusTable[menuName].buttonFontSize[buttonNumber] then
			echoString = [[<span style="font-size: ]] .. menusTable[menuName].buttonFontSize[buttonNumber] .. [[px">]] .. echoString .. [[</style>]]
		elseif menusTable[menuName].fontSize then
			echoString = [[<span style="font-size: ]] .. menusTable[menuName].fontSize .. [[px">]] .. echoString .. [[</style>]]
		end
		menusTable[menuName].buttonText = menusTable[menuName].buttonText or {}
		menusTable[menuName].buttonText[buttonNumber] = echoString
	else
		if menusTable[menuName].fontSize then
			echoString = [[<span style="font-size: ]] .. menusTable[menuName].fontSize .. [[px">]] .. echoString .. [[</style>]]
		end
		menusTable[menuName].text = echoString
	end
	echo(labelName, echoString)
end

function setMenuFontSize(menuName, buttonNumber, fontSize)
	assert(menusTable[menuName], "setMenuFontSize: no such menu exists.")
	if not fontSize then
		fontSize = buttonNumber
		buttonNumber = nil
	end
	if buttonNumber then
		assert(tonumber(buttonNumber) and buttonNumber <= menusTable[menuName].numButtons, "setMenuFontSize: buttonNumber higher than number of buttons in menu.")
		buttonNumber = tonummber(buttonNumber)
		menusTable[menuName].buttonFontSize[buttonNumber] = fontSize
	else
		menusTable[menuName].fontSize = fontSize
	end
end

function setMenuButtonSize(menuName, width, height)
	assert(menusTable[menuName], "setMenuButtonSize: no such menu exists.")
	assert(width and height, "setMenuButtonSize: need to have both width and height.")
	menusTable[menuName].bsize = {width = width, height = height}
	for k = 1, menusTable[menuName].numButtons do
		resizeWindow(menuName.."_menubutton_"..k, width, height)
	end
	if menusTable[menuName].open then
		openMenu()
	end
end

function resizeMenu(menuName, width, height)
	assert(menusTable[menuName], "resizeMenu: no such menu exists.")
	assert(width and height, "resizeMenu: need to have both width and height.")
	resizeWindow(menuName, width, height)
	if not menusTable[menuName].bsize then
		for k = 1,menusTable[menuName].numButtons do
			resizeWindow(menuName.."_menubutton_"..k, width, height)
		end
	end
	if menusTable[menuName].open then
		openMenu()
	end
	menusTable[menuName].width, menusTable[menuName].height = width, height
end

function moveMenu(menuName, x, y)
	assert(menusTable[menuName], "moveMenu: no such menu exists.")
	assert(x and y, "moveMenu: need to have both X and Y positions.")
	moveWindow(menuName, x, y)
	if menusTable[menuName].open then
		openMenu()
	end
	menusTable[menuName].x, menusTable[menuName].y = x, y
end

function openMenu(menuName, toggle)
	assert(menusTable[menuName], "openMenu: no such menu exists.")
	if toggle and menusTable[menuName].open then
		closeMenu(menuName)
	else
		menusTable[menuName].open = true
		local width, height = menusTable[menuName].width, menusTable[menuName].height
		local bwidth, bheight = width, height
		local x,y = menusTable[menuName].x, menusTable[menuName].y
		local pos, dir = menusTable[menuName].buttonPos, menusTable[menuName].buttonDir
		if menusTable[menuName].bsize then
			bwidth = menusTable[menuName].bsize.width
			bheight = menusTable[menuName].bsize.height
		end
		if pos == "left" then
			x = x - bwidth
		elseif pos == "right" then
			x = x + width
		elseif pos == "top" then
			y = y - bheight
		elseif pos == "bottom" then
			y = y + height
		end
		for k = 1, menusTable[menuName].numButtons do
			moveWindow(menuName.."_menubutton_"..k,x,y)
			resizeWindow(menuName.."_menubutton_"..k,bwidth,bheight)
			showWindow(menuName.."_menubutton_"..k)
			if dir == "left" then
				x = x - bwidth
			elseif dir == "right" then
				x = x + bwidth
			elseif dir == "up" then
				y = y - bheight
			elseif dir == "down" then
				y = y + bheight
			end
		end
	end
end

function closeMenu(menuName)
	assert(menusTable[menuName], "closeMenu: no such menu exists.")
	menusTable[menuName].open = false
	for k = 1, menusTable[menuName].numButtons do
		hideWindow(menuName.."_menubutton_"..k)
	end
end

function hideMenu(menuName)
	assert(menusTable[menuName], "hideMenu: no such menu exists.")
	hideWindow(menuName)
	for k = 1, menusTable[menuName].numButtons do
		hideWindow(menuName.."_menubutton_"..k)
	end
end

function showMenu(menuName)
	assert(menusTable[menuName], "showMenu: no such menu exists.")
	showWindow(menuName)
	if menusTable[menuName].open then
		for k = 1, menusTable[menuName].numButtons do
			showWindow(menuName.."_menubutton_"..k)
		end
	end
end

Post Reply