HomeForumSourceResearchGuide
Sign in to contribute to source. how it works
Component ui.ContextMenu by barry
expand copy to clipboardexpand
const int ITEM_SEP = 5
const int FONT_HEIGHT = 15

const int PAD_LEFT = 3
const int PAD_RIGHT = 3

component provides ContextMenu requires ui.Font, os.SystemInfo sysInfo, io.Output out {
	
	Font labelFont
	
	int width = 2
	int height = 2
	
	MenuItem menuItems[]
	
	Color borderColor = new Color(180, 180, 200, 255)
	Color shadowColor = new Color(180, 180, 180, 255)
	Color bgColor = new Color(195, 195, 215, 255)
	Color textColor = new Color(0, 0, 0, 255)
	Color hlColor = new Color(180, 188, 220, 255)
	
	int hoverIndex = INT_MAX
	
	ContextMenu:ContextMenu()
		{
		labelFont = new Font(sysInfo.getSystemFont(false), FONT_HEIGHT)
		}
	
	void ContextMenu:paint(Canvas c)
		{
		c.rect(new Rect2D(xPosition+2, yPosition+2, width, height, shadowColor))
		c.rect(new Rect2D(xPosition, yPosition, width, height, bgColor))
		
		int ryPos = yPosition
		for (int i = 0; i < menuItems.arrayLength; i++)
			{
			if (i == hoverIndex)
				{
				c.rect(new Rect2D(xPosition, ryPos, width, FONT_HEIGHT + ITEM_SEP, hlColor))
				}
			
			c.text(new Point2D(xPosition+PAD_LEFT, ryPos, textColor), labelFont, menuItems[i].name)
			ryPos += FONT_HEIGHT + ITEM_SEP
			}
		
		c.rectOutline(new Rect2D(xPosition, yPosition, width, height, borderColor))
		}
	
	void ContextMenu:addItem(store MenuItem item)
		{
		menuItems = new MenuItem[](menuItems, item)
		height += FONT_HEIGHT + ITEM_SEP
		
		int textWidth = labelFont.getTextWidth(item.name)
		
		if ((textWidth + PAD_LEFT + PAD_RIGHT) > width)
			{
			width = textWidth + PAD_LEFT + PAD_RIGHT
			}
		}
	
	void ContextMenu:remItem(MenuItem item)
		{
		
		}
	
	void ContextMenu:setItems(store MenuItem items[])
		{
		menuItems = items
		
		for (int i = 0; i < items.arrayLength; i++)
			{
			int textWidth = labelFont.getTextWidth(items[i].name)
			
			if ((textWidth + PAD_LEFT + PAD_RIGHT) > width)
				{
				width = textWidth + PAD_LEFT + PAD_RIGHT
				}
			}
		
		height = (FONT_HEIGHT + ITEM_SEP) * items.arrayLength
		}
	
	void ContextMenu:setPosition(int x, int y)
		{
		xPosition = x
		yPosition = y
		}
	
	void ContextMenu:click(int x, int y, int button)
		{
		if (button == MouseButtons.BUTTON_LEFT)
			{
			int ryPos = 0
			for (int i = 0; i < menuItems.arrayLength; i++)
				{
				if (y > ryPos && y < ryPos + FONT_HEIGHT)
					{
					emitevent menuClick(menuItems[i])
					
					break
					}
				
				ryPos += FONT_HEIGHT + ITEM_SEP
				}
			}
		}
	
	void ContextMenu:postRepaint()
		{
		emitevent repaint()
		}
	
	void ContextMenu:setFocus()
		{
		emitevent requestFocus()
		}
	
	void ContextMenu:setDisabled(bool d)
		{
		disabled = d
		postRepaint()
		}
	
	Rect ContextMenu:getBounds()
		{
		return new Rect(xPosition, yPosition, width, height)
		}
	
	WH ContextMenu:getPreferredSize()
		{
		return new WH(width, height)
		}
	
	Point ContextMenu:getPosition()
		{
		return new Point(xPosition, yPosition)
		}
	
	void ContextMenu:mouseMove(int x, int y)
		{
		int ryPos = 0
		
		for (int i = 0; i < menuItems.arrayLength; i++)
			{
			if (y > ryPos && y < ryPos + FONT_HEIGHT)
				{
				if (i != hoverIndex)
					{
					hoverIndex = i
					postRepaint()
					}
				
				break
				}
			
			ryPos += FONT_HEIGHT + ITEM_SEP
			}
		}
	
	void ContextMenu:mouseOut()
		{
		hoverIndex = INT_MAX
		postRepaint()
		}
	
	}
Revision history
To propose a new revision to this entity, use dana source put -uc your/new/version.dn -n ui.ContextMenu -m "reason for update" -u yourUsername
Version 1 (this version) by barry
Notes for this version: Standard Library Initialisation