
-----------------------------------------------------------
-- CONTEXT MENU 
-----------------------------------------------------------
function editor.updateContextMenu()

	contextMenu.fontSize =LOVR and 11 or 9
	pushPost()
	gfx.setFont(fonts.inconsolata,contextMenu.fontSize)

	-- if LOVR then gfx.setFont(fonts.inconsolata,16) end
	contextMenu.hovered = false	
	contextMenu.split = 0

	if #contextMenu.items>0 and not contextMenu.open then 
		editor.updateContextMenuItems(contextMenu)

	else

		unlockMouse() 

		lmouse.setCursor(defaultCursor)

		if editor.pickingColor then 
			editor.colorPickerPreview() 
			mouse.set(function() 
				editor.pickColor (contextMenu.colorTarget) 
				editor.pickingColor=false
				lmouse.setPosition(editor.storedMouse.x,editor.storedMouse.y)
			end)
		else 
			if editor.colorTip.open then 
				lockMouse() 
			end

			editor.updateContextMenuItems(contextMenu)
			unlockMouse() 
			editor.updateColorTip()

			if keypressed("escape") then  
				editor.closeContextMenu()
				popPost()
				return
			end
			if not contextMenu.hovered and not editor.colorTip.open then 
				mouse.pushDown(function()
					editor.closeContextMenu()
					return 
				end)
			else
				stageHovered=false
			end
		end

		lockMouse() 
	end
	popPost()
end


function editor.updateContextMenuItems(context,offset)
	if not context.items then return end
	
	-- gfx.push("all")
	gfx.setBlendMode("alpha")
	local h = 0
	for i,item in ipairs(context.items) do 
		h=h+(item.height or contextMenu.itemHeight)
	end
	h=offset and offset.h or h
	if offset then
		offset.y=mc(8,offset.y,screenHeight-h-8)
	end
	local back = lume.merge(offset or context,{height=h,shadow=0,padding=4,color={r=0,g=0,b=0,a=0.4}})
	if mouseIn(back) then 
		contextMenu.hovered =true 
		lmouse.setVisible(true) 
	end
	editor.drawContextBack(back)

	pushPost()
	local offset = offset or {}
	context.selected = context.selected or {split=0,item=0}
	local newItems
	local yoff = 0

	if offset.scroll then
		--offset.scroll = context.scroll+mouseScroll.y*5
	end
	context.listLevel = 0
	--offset.scroll=offset.scroll and offset.scroll+mouseScroll.y*5 or 0
	--trace("context.scro",offset.scroll)
	local listOffset 

	local contextSplit = function(item,i,splitx)
		local bx,by,bw,bh= gfx.getScissor()
		local inbox 	= mouseIn({x=bx or 0,y=by or 0,w=bw or screenWidth,h=bh or screenHeight})
		
		item.scale 		= item.scale 	or 1
		item.width  	= (offset.width or contextMenu.width)
		item.height 	= item.height 	or contextMenu.itemHeight 
		--item.w 		= item.width  	
		--item.h 		= item.height 	
		item.y 			= (offset.y 	or context.y)+yoff+contextMenu.spacing
		
		local indent  = (item.indent and (16-item.indent)/16 or 1)
		local indent2 = ( 1-indent )*(context.subWidth or context.width)

		item.x 			  = (offset.x 	or context.x)+(splitx or 0)*item.width*indent+indent2
		item.width 		= item.width 	*  item.scale * indent
		item.context 	= context
		item.wasHovered = item.hovered
		item.hovered 	= (inbox and not item.static and mouseIn(lume.merge(item,{y=item.y+2,w=item.width,h=item.height-1})))

		if not inbox then 
			item.hovered = false
		end
		
		item.col 		  = lume.merge( {r=0,g=0,b=0,a=0} , item.col or {})
		item.text  		= item.text or item.name
		item.funcR 		= item.funcR or function()return true end
		yoff  			  = splitx and yoff or  yoff + item.height;

		(item.update or nothing)(item)

		if (context.subbed==nil or contextMenu.refresh) and context.sub then 
			local header,head = lume.match(context.items[1],function(x) return x.name == context.sub end ) or context.items[1][1]
			if header.subitems then 
				context.subbed  = context.sub
				local subitems =  lume.map(header.subitems, function(x) x.header = item; return x end)
				print("bef",(#context.items))
				context.items 	= lume.concat({context.items[1]}, subitems)
				print("aft",(#context.items))
				contextMenu.refresh = false
			end
		end

		item.subhead = (context and context.subbed == item.text) 
		if (item.hovered ) then 
			(item.rollOn or nothing)(item)
			if item.subhead then 
				mouseScroll.y = 0
			end
			-- namer:close()
			if item.subitems then 
				context.subbed 	= item.text
				item.subitems = lume.map(item.subitems, function(x) x.header = item; return x end)
				context.items = {context.items[1]}
				for i=1,#item.subitems,1 do 
					if i<=#item.subitems then 
						table.insert(context.items,item.subitems[i])
					end
				end
			end
		end
		
		if item.subhead and offset and offset.yoff  then 
			if item.scroll and context.yoff then 
				local lim = -zero(context.yoff-item.scroll-h)
				local hh = h-item.height
				if lim<0 then 
					item.scroll = mc(lim,item.scroll+mouseScroll.y*5,0,2)
					gfx.setColor(0,0,0,0.7)
					gfx.rectangle("fill",offset.x+(context.subWidth or 0),offset.y+item.height,3,hh,2)
					gfx.setColor(1,1,1,0.5)
					gfx.rectangle("fill",offset.x+(context.subWidth or 0),offset.y+item.height-item.scroll,2,(hh^2)/(hh-lim)-6,2)
				end
			else
				item.scroll = 0
			end
		end

		if not item.header and item.scroll then
			--gfx.setScissor()
		end

		if not item.hovered and item.wasHovered then 
			(item.rollOff or nothing)(item)
			mouse.set(function()end)
		end



		if item.list then 
			local ii = i
			local makeList = true
			if item.toggle and not item.toggle.targ[item.toggle.prop] then 	
				makeList = false
			end
			if context.items[ii+1] and context.items[ii+1].head==ii then 
				if not makeList  then 
					local base,rems = item.indent or 0,0
					for j=ii+1,#context.items do 
						if (context.items[j].indent or 0) > base then 
							rems=rems+1
						end
					end
					for r=1,rems do 
						table.remove(context.items,ii+1)
					end
					-- ii=ii-rems
				else
					makeList=false
				end
			end
			if makeList then 
				context.listLevel = context.listLevel+1
				for l,li in lume.ripairs(item.list) do 
					li.indent = (item.indent or 0)+1
					for s,split in ipairs(li) do 
						split.indent=li.indent
					end
					li.head = ii
					table.insert(context.items,ii+1,li)
				end
			end
		end

		if item.hovered and contextMenu.open and  (contextMenu.sliding==0 or contextMenu.sliding==nil) then 
			if item.tip and not editor.colorTip.open then 
				editor.setToolTip(item.tip)
			end
			(item.hover or nothing)(item)
			if mouse.moved then 
				(item.moved or nothing)(item)
			end
			if context.selected ~= contextMenu.split then 
				-- temp
				--editor.deselectContext(context)
			end

			context.selected = {split=contextMenu.split,item=i}

			
			
			if not item.slider and item.items == nil then 
				for b=1,2,1 do
					(b==1 and mouse.set or mouse.setR)( function ()
						unlockMouse()
						if item.slide then 
							item.slide()
						end
						local preWarn = lume.clone(context.items[i])
						local click 	= function()
							local rval 
							if b==1  then 
								if item.func then 
									if editingLevel then 
										editor.pushUndoState("Context Click")
									end
									rval= item.func(item)
									if item.toggle then 
										item.toggle.targ[item.toggle.prop]=not item.toggle.targ[item.toggle.prop]
										rval = "toggle"
									end
								end
							else 
								rval = item.funcR(item)
							end

							if rval == nil then 
								editor.closeContextMenu()
							else
								if  rval=="remove" then
									local _,s = lume.match(context.items[1],function(x) return x.name == context.subbed end)
									if context.subbed then 
										table.remove(context.items[1][s].subitems,i-1)
									end
									newItems = table.remove(context.items,i)
								else
									
								end
							end
						end
						if item.warning then 
							local rval = item.warning=="open" and item.warning or nil
							context.items[i]={
								{	name="Confirm",		col={r=0.4,g=1,b=0.4,a=0.25}, func=function() click() return rval end},
								{	name="Cancel",		col={r=1,g=0.4,b=0.4,a=0.25}, func=function() context.items[i]=preWarn return item.warning end}
							}
						else
							click()
						end
					end)
				end
			end
		end

		if item.items ~= nil  then 
			local expand 
			if item.hoverOnly then 
				if context.selected.item == i  then 
					expand=item.expand 
				else
					item.expand = false
				end
			else 
				expand = context.selected.item == i 
			end
			if expand then 
				local width = item.subWidth or (context.subWidth or context.width)
				local height = lume.count(item.items)*(contextMenu.itemHeight+contextMenu.spacing)
				local sub = (item.items[1][1] and item.items[1][1].subitems)

				editor.updateContextMenuItems(item,{
					col 	= contextMenu.col,
					x 		= (offset.x or context.x)+((contextMenu.direction<0 and width or context.width)+8)*contextMenu.direction,
					y 		= (context.up and -height+item.height or 0)+(sub and context.y or item.y),
					height  = height,
					width 	= width,
					sub 	= item.sub or nil,
					subWidth= width,
					h 		= item.subHeight or nil,
					scroll 	= item.scroll,
					yoff 	= yoff,
					up = context.up
				})
				pushPost()
			else
				-- temp
				--context.selected = 0
			end
		end

		if item.slider then 
			item.align = item.align or "left"
			if mouseIn(item) then 
				mouse.click(function()
					contextMenu.sliding = item.hovered and i or contextMenu.sliding 
					contextMenu.prop = item.slider.prop
				end)
			end
			if item.slider.min and item.slider.max and item.slider.target[item.slider.prop] then 
				item.slider.target[item.slider.prop]  = mc(item.slider.min, item.slider.target[item.slider.prop], item.slider.max )
			end
			if mouse.down.L and contextMenu.sliding==i and contextMenu.prop ==item.slider.prop and contextMenu.open then 
				item.slider.target[item.slider.prop] = lerp(item.slider.min,item.slider.max,math.pow(mc(0, (mouse.x-item.x)/item.width, 1), (item.slider.pow or 1) ) )
				if item.slide and mouse.moved then 	
					-- print("slideee",time)
					item.slide()
				end
				if item.slider.update then 
					item.slider.update(item.slider.target)
				end
			end
			if item.slider.target[item.slider.prop] and item.round then 
				item.slider.target[item.slider.prop] = lume.round(item.slider.target[item.slider.prop],item.round)
			end
			local prop = item.slider.target[item.slider.prop]  or 0
			item.text 	= (item.name=="" and "" or (item.name..": "))..tostring(lume.round(prop,item.slider.round or 0) or "")
			item.text 	= item.slider.noval and item.name or item.text

			item[item.slider.style or "pos"] 	= math.pow((prop-item.slider.min)/(item.slider.max-item.slider.min),1/(item.slider.pow or 1))
			
			editor.drawContextItem(lume.merge(item,{name=""})) 
			editor.drawButton(lume.merge(item,{y=item.y+(item.gradient and 3 or 0)})) 

			mouse.pushRelease(function() contextMenu.sliding=0 end)
		else 
			if item.button then 
				editor.drawButton(item) 
			else
				editor.drawContextItem(item) 
			end
		end
	end

	listOffset = 1
	local sciss = false
	for i,item in ipairs(context.items) do 
		contextMenu.split = contextMenu.split+1
		local scroll = 0
		if i==2 then
			if context.subbed and not (context and context.subbed == item.text)  and not item.subitems and item.header then 
				yoff=yoff+(item.header.scroll or 0)
				gfx.setScissor()
				gfx.setScissor(0,(offset and offset.y or context.y) +20,screenWidth,h-20)
				sciss = true
			end
		end
		if #item>0 then 
			local splitx = 0
			local sumSizes = 0
			local absWidth = 0
			for j,jtem in ipairs (item) do 
				if type(jtem)=="table" then
					jtem.size = (jtem.size or 1)
					if jtem.size>0 then 
						sumSizes=sumSizes+jtem.size
					else
						jtem.size = jtem.size==-1 and -contextMenu.itemHeight or jtem.size
						absWidth = absWidth - jtem.size
					end
				end
			end

			local cw      = context.subWidth or context.width or 180
			local indent  = (item[1].indent and (16-item[1].indent)/16 or 1)
			cw = cw*indent

			for s,split in ipairs(item) do  
				if type(split)=="table" then
					split.size = (split.size or 1)
					split.scale 	= split.size>0 and (split.size/sumSizes)*((cw-absWidth)/cw) or math.abs(split.size)/cw
					split.parent  	= item
					contextSplit	(split,i,splitx)
					splitx 			= splitx + split.scale
				end
			end
			yoff  		= yoff + (item.height or contextMenu.itemHeight)
		else
			contextSplit(item,i)
		end
		if i==#context.items and sciss then
			gfx.setScissor()
		end
	end
	context.yoff = yoff
	context.items = newItems or context.items
	popPost()
	-- gfx.pop()
end


function editor.deselectContext(context)
	context.selected = {split=0,item=0}
	for i,item in ipairs(context.items) do 
		if item.items ~= nil  then 
			editor.deselectContext(item)
		end
	end
end

function editor.makeToggle(targ,prop,over,list,slide)
	local t = {}
	local over = over or {}
	local slide = type(prop)=="table" and "slideToggle" or slide or "toggle"
	local tclick = over.click or nothing
	local sclick = slide=="toggle" and over.click or (over.slide or nothing)

	local prop1 = type(prop)=="table" and prop[1] or prop
	local prop2 = type(prop)=="table" and prop[2] or prop
	local prop3 = type(prop)=="table" and prop[3] or prop

	

	t= {{	
			name = type(over.name)=="function" and over.name or (over.nocap and tostring or capFirst)(over.name or prop3), 
			align="center",size=10, col = {r=0,g=0,b=0,a=0},
			hover= hover,
			tip=over.tip,
			align="left",
			toggle = slide=="toggle" and {targ=targ,prop=prop1} or nil,
			func = sclick,
			slide = over.slide,
			update =over.namef and function (item)  
				over.namef(item) 
			end or nil,
			round = over.round,
			list = slide =="toggle" and list or nil,
			slider= slide~="toggle" and {noval=over and over.noval or false,target=targ,  style="pct", prop=prop1, min=over.min or 0, pow=over.pow or 1, max=over.max or 1,	round=over.round or 0.01}  or nil 
		},slide~="slide" and {	
			name = "", 
			align="center",size=-1, col = {r=0,g=0,b=0,a=0.6},
			hover= hover,
			func = tclick,
			list = list,
			toggle = {targ=targ,prop=prop2},
			update 	= function(item)
				item.toggle.targ = item.toggle.targ or {}
				item.text = item.toggle.targ[prop2] and "ticked" or "unticked"
			end
		} or nil 
	}

	if over.colors then 
		for i,color in lume.ripairs(over.colors)do
			table.insert(t,2,editor.colorSquare(targ,color,over.parent,{targ,"enabled"}))
		end
	end

	return t
end


function editor.makeCheckbox(targ,prop,tip)
	return {	
		name = "", align="center",size=-1, col = {r=0,g=0,b=0,a=0.6},
		hover= nothing,
		func = nothing,
		list = list,
		tip  = tip,
		toggle = {targ=targ,prop=prop},
		update 	= function(x)
			x.text = targ[prop] and "ticked" or "unticked"
		end
	}
end

function editor.makeSlider(targ,prop,over,list)
	return editor.makeToggle(targ,prop,over,list,"slide")
end

function editor.makeModes(targ,prop,modes,options)
	local out = {}
	for m,mode in ipairs(modes) do 
		local name,tip
		if type(mode)=="table" then 
			name = mode.name 
			tip  = mode.tip
		else
			name = mode
		end
		table.insert(out,{
			name=name,
			align=options and options.align or "center",
			tip = tip ,
			open = true,
			func=function(item) 
				targ[prop] = name
				return item.open
			end,
			update=function(item)
				item.selectedMode = (targ[prop] == name)
				item.col = {a=item.selectedMode and 0.7 or 0}
			end
		})
	end
	return out
end

function editor.openContextMenu(contextItems, props)
	editor.closeColorTip()
	if #contextItems == 0 then return end
	for i,item in lume.ripairs(contextItems) do 
		if type(item)~="table"  then 
			table.remove(contextItems,i)
		end
	end
	if #contextItems == 0 then return end

	local props 	= props or {}
	props.width 	= props.width 		or 180
	props.subWidth 	= props.subWidth 	or 180
	props.x 		= mc(16, props.x or mouse.x/game.resolution+4, screenWidth-props.width-16)
	props.y 		= props.y 		or mouse.y/game.resolution

	editState 	=  "Context Menu"
	contextMenu = 	{	
		open 		= true,
		alpha 		= 0,
		selected	= {split=0,item=0},
		x 			= props.x,
		y 			= props.y,
		width 		= props.width,
		subWidth 	= props.subWidth,
		items 		= contextItems,
		itemHeight  = 20,
		spacing 	= 0,
		hovered 	= true,
		col 		= {a=130},
		up 		= props.up,
		direction = (props.x>screenWidth-(props.width+(props.subWidth or props.width))-16) and -1 or 1
	}	
	contextMenu.height 	= #contextMenu.items*(contextMenu.itemHeight+contextMenu.spacing)+contextMenu.spacing
	contextMenu.y 		= mc(16, contextMenu.y+16+(props.up and -contextMenu.height or 0), screenHeight-contextMenu.height) 


	for t,tween in ipairs(tweens) do
		if tween.thing == contextMenu then 
			table.remove(tweens,t)
		end
	end
	effects.tween(contextMenu,{y=contextMenu.y-16,alpha=1},0.15,"easeOut",1)
end

function editor.closeContextMenu()
	editState 			= "Normal"
	contextMenu.open 	= false
	mouse.down.L 			= true
	effects.tween(contextMenu,{y=contextMenu.y+16,alpha=0},0.06,"easeIn",1,function() 
		contextMenu.items 	= {}
		contextMenu.x=screenWidth
		contextMenu.y=screenHeight
		unlockMouse 		()
	end)
	
	editor.closeColorTip()
end

---------------------------------
-- CONTEXT ITEMS
---------------------------------
function editor.openContextColor(color,props,a)
	editor.openContextMenu(editor.contextColor(color,a),props)
end

function editor.openContextRGB(color,props,a)
	editor.openContextMenu(editor.contextRGB(color,a),props)
end

function editor.openContextHSV(color,props,a)
	editor.openContextMenu(editor.contextHSV(color,a),props)
end

function editor.openContextHue(color,props,a)
	editor.openContextMenu(editor.contextHue(color),props)
end

function editor.openColorTip(targ,prop)
	editor.colorTip = editor.colorTip or {}
	editor.colorTip.open  = true
	editor.colorTip.a 		= 0
	editor.colorTip.targ  = targ
	editor.colorTip.prop  = prop
	editor.colorTip.x = mouse.x
	editor.colorTip.y = mouse.y 
	
	editor.colorTip.h = 210
	editor.colorTip.expandLimit=editor.colorTip.y-210
	editor.colorTip.shape = "quad" 
	editor.colorTip.dragging = ""
	editor.colorTip.scrollSpeed=0
	editor.colorTip.scrollLimit=200
	editor.colorTip.mode = editor.colorTip.targ[editor.colorTip.prop].pattern and "patterns" or "colors"
	editor.colorTip.scroll = editor.colorTip.mode=="patterns" and editor.colorTip.scrollLimit or 0
	editor.colorTip.sliders = {}
	editor.colorTip.tri = gfx.newMesh(zformat3,{{0,0,0,1},{0,0,0,1},{0,0,0,1}},"fan")
	editor.colorTip.quad = gfx.newMesh(zformat3,600,"strip")
	-- editor.colorTip.palettes 
	effects.tween(editor.colorTip,{a=1},0.2,"easeOut",1)
end

function editor.hueWheel(inner,outer)
	local segs = 54
	local inner = inner or 0
	local outer = outer or 1
	local verts = {}
	local r,g,b
	for i=1,segs+1,1 do 
		r,g,b = hsvToRgb(i*(1/segs),1,1)
		verts[i*2-1] = {inner*math.cos((i/segs)*pi*2),inner*math.sin((i/segs)*pi*2),0,1, r,g,b,1}
		verts[i*2]   = {outer*math.cos((i/segs)*pi*2),outer*math.sin((i/segs)*pi*2),0,1, r,g,b,1}
	end
	-- table.insert(verts,verts[#verts])
	table.insert(verts,verts[3])
	return gfx.newMesh(zformat3,verts,"strip")
end

function editor.updateColorTip()
	if not editor.colorTip.open then  return end
	local cross = vec2(0,0)
	lmouse.setCursor(defaultCursor)
	editor.colorTip.w = 150--+math.clamp(0,editor.colorTip.expandLimit,editor.colorTip.scroll)/2
	local patternMode = editor.colorTip.mode=="patterns"
	local col=editor.colorTip.targ[editor.colorTip.prop]

	editor.colorTip.inner = editor.colorTip.w/2-18
	editor.colorTip.outer = editor.colorTip.w/2-8
	editor.colorTip.wheel =  editor.hueWheel(editor.colorTip.inner,editor.colorTip.outer)

	gfx.setBlendMode("alpha")
	local tip=editor.drawTip(lume.merge(editor.colorTip,{h=editor.colorTip.h+math.clamp(0,editor.colorTip.expandLimit,editor.colorTip.scroll),temp=true,noshadow=true,dome=patternMode and 118 or true}))

	pushPost()

	local third, pt, tri, verts, vOff, vLine, quad, c
	if editor.colorTip.shape == "tri" then
		third = (pi*2)/3
		pt = vec2.from_cartesian(54,third)
		tri = {l=pt.x,r=54,t=pt.y,b=-pt.y}
		verts = {{tri.l,tri.b,0,1, 1,1,1,1},{tri.r,0,0,1,hsvToRgb(col.h,1,1) },{tri.l,tri.t,0,1,0,0,0,1}}
		vOff  = vec2.from_cartesian((1-col.v)*80.35,math.angle(verts[1][1],verts[1][2],verts[2][1],verts[2][2])+pi/2)
		vLine = { vec2(verts[1][1],verts[1][2])+vOff,vec2(verts[2][1],verts[2][2])+vOff }
		c     = vec3(math.clamp(tri.l,tri.r,m2[1]) , math.clamp(tri.b,tri.t,m2[2]), m2[3])
		local hit,crosspos = math.intersect ( vec2(cx,tri.b),vec2(cx,tri.t), vLine[1], vLine[2])
		if hit then 
			cross = vec2(crosspos.x,crosspos.y)
		end
	else 
		size  = editor.colorTip.inner/1.5
		quad  = {x=-size,y=-size,w=size*2.15,h=size*2}
		verts = {}
		local r,g,b,h,s,v,x,y1,y2
		local n = 1
		local num = 16
		for i=1,num,1 do 
			for j=1,num,1 do 
				x     				= quad.x+(j-1)*(quad.w)/num

				r,g,b 				= hsvToRgb(col.h,j/num,(i-1)/num)
				verts[n*2-1] 	= {x,quad.y+(i-1)*(quad.h/num),0,1, r,g,b,1}
				
				r,g,b 				= hsvToRgb(col.h,j/num,(i)/num)
				verts[n*2] 		= {x,quad.y+(i)*(quad.h/num),0,1, r,g,b,1}

				n 						= n+1
			end
			verts[n*2-1] 	= {x,quad.y+(i)*(quad.h/num),0,1, r,g,b,1}
			verts[n*2] 		= {x,quad.y+(i)*(quad.h/num),0,1, r,g,b,1}
			n= n+1
		end
		cross = {
			x=utils.map(col.s,0,1,quad.x,quad.x+quad.w),
			y=utils.map(col.v,1,0,quad.y,quad.y+quad.h)
		}
	end
	

	local ang 	= col.h*pi*2+pi/2
	local m 		= {x=mouse.x,y=mouse.y}
	local m2 		= {m.x-tip.x-tip.w/2,m.y-tip.y-tip.w/2,0}

	if not tip.hovered then 
		mouse.set(editor.closeColorTip)
	else
		mouse.set(nothing)

		editor.colorTip.scrollSpeed = easeTo(editor.colorTip.scrollSpeed,editor.colorTip.scrollSpeed - mouseScroll.y*8,4)
		

		if 		 editor.colorTip.shape == "tri"  and point_in_triangle(verts[1],verts[2],verts[3],m2) then 
			mouse.set(function() 	editor.colorTip.dragging = "tri" end)
		elseif editor.colorTip.shape == "quad" and mouseIn(quad,vec2(m2)) then 
			mouse.set(function() 	editor.colorTip.dragging = "quad" end)
		end

		local dist = math.dist(0,0,m2[1],m2[2])
		if dist>editor.colorTip.inner and dist<editor.colorTip.outer then 
			mouse.set(function() 	editor.colorTip.dragging = "wheel" end)
		end
	end

	editor.colorTip.scroll = editor.colorTip.scroll + editor.colorTip.scrollSpeed
		editor.colorTip.scroll = 
			easeTo(editor.colorTip.scroll,editor.colorTip.scroll<0 and 0 or (editor.colorTip.scroll>editor.colorTip.scrollLimit and editor.colorTip.scrollLimit or editor.colorTip.scroll))
		editor.colorTip.scrollSpeed = editor.colorTip.scrollSpeed*0.5


	gfx.setScissor(tip.x,tip.y+2,tip.w,tip.h-4)

	gfx.push("all")
		gfx.translate(tip.x,tip.y)
		

		-- Pattern toggle
		if not level.isAnim then 
			local pat = math.dist(tip.x+15.5,tip.y+tip.w-15.5,mouse.x,mouse.y) <12
			if pat then 
				mouse.set(function() 
					editor.colorTip.mode = cycleTable({"patterns","colors"},editor.colorTip.mode)
					if editor.colorTip.mode == "patterns" then 
						editor.colorTip.scroll=editor.colorTip.scrollLimit
						editor.colorTip.targ[editor.colorTip.prop].pattern = editor.colorTip.targ[editor.colorTip.prop].pattern or 1
					else
						editor.colorTip.targ[editor.colorTip.prop].pattern = nil
					end
				end)
			end

			gfx.setColor(setAll(pat and 0.6 or 0.2))
			gfx.circle("line",15.5,tip.w-15.5,12)
			gfx.setColor(1,1,1,1)
			img = getImage("checkersRounded")
			if LOVE then img:setFilter("linear","linear") end
			gfx.draw(img,15.5,tip.w-15.5,0,1/4,1/4,32,32)
		end


		if editor.colorTip.mode == "colors" then 
			-- Color Cube
			gfx.setColor(1,1,1,1)
			gfx.push("all")
				
				gfx.setShader(shaders.noGamma)
				if 		 editor.colorTip.shape == "tri" then 
					editor.colorTip.tri:setVertices(verts)
					gfx.draw(editor.colorTip.tri,tip.w/2,tip.w/2)
				elseif 		 editor.colorTip.shape == "quad" then 
					editor.colorTip.quad:setVertices(verts)
					gfx.draw(editor.colorTip.quad,tip.w/2,tip.w/2,0,1,LOVR and -1 or -1)
				end

			gfx.pop()
			gfx.setColor(1,1,1,1)
			gfx.setMeshCullMode("none")
			gfx.draw(editor.colorTip.wheel,tip.w/2,tip.w/2)
			gfx.setColor(0,0,0,1)
			gfx.setLineWidth(2)
			gfx.circle("line",tip.w/2,tip.w/2,editor.colorTip.inner,64)
			gfx.circle("line",tip.w/2,tip.w/2,editor.colorTip.outer,64)

			gfx.push()
			gfx.setColor(1,1,1,1)
				gfx.translate(tip.w/2,tip.w/2)
					if editor.colorTip.shape == "tri" then 
						gfx.line(vLine[1].x,vLine[1].y,vLine[2].x,vLine[2].y)
					end
					gfx.rotate(ang)
					gfx.line(0,-57,0,-69)
					gfx.rotate(-ang)
				gfx.translate(cross.x,cross.y)
				gfx.setColor(1,1,1,1)
					gfx.line(0,-3,0,3)
					gfx.line(-3,0,3,0)
					gfx.setColor(col.r,col.g,col.b,1)
					gfx.rectangle("fill",-1,-1,2,2)
			gfx.pop()
			
			-- Eyedrop tool
			local pick = math.dist(tip.x+tip.w-16.5,tip.y+tip.w-16.5,mouse.x,mouse.y) <12
			if pick then 
				mouse.set(function() 
					editor.contextColorPicker(editor.colorTip.targ[editor.colorTip.prop]) 
				end)
			end
			gfx.setColor(setAll(pick and 0.6 or 0.2))
			gfx.circle("line",tip.w-16.5,tip.w-16.5,12)
			gfx.setColor(1,1,1,1)
			img = getImage("eyedrop")
			if LOVE then img:setFilter("linear","linear") end
			gfx.draw(img,tip.w-16.5,tip.w-16.5,0,1,1,10,10)
		end

		-- Sliders
		gfx.translate(4,tip.w)
			
		local paddedWidth = editor.colorTip.w-8
		local m3 = vec2(m)+vec2(-tip.x-4,-tip.y-tip.w)

		if editor.colorTip.mode == "colors" then 
			for i,v in ipairs({"r","g","b"}) do		
				local gradient 
				if i<=3 then 
					gradient = {
						{v=="r" and 0 or col.r,v=="g" and 0 or col.g,v=="b" and 0 or col.b},
						{v=="r" and 1 or col.r,v=="g" and 1 or col.g,v=="b" and 1 or col.b}
					}
				else
					local h,s,v = rgbToHsv(col.r,col.g,col.b)
					local r1,g1,b1 = hsvToRgb(v=="h" and 0 or h,v=="s" and 0 or s,v=="v" and 0 or v)
					local r2,g2,b2 = hsvToRgb(v=="h" and 1 or h,v=="s" and 1 or s,v=="v" and 1 or v)
					gradient = {{r1,g1,b1,1},{r2,g2,b2,1}}
				end
				gfx.setColor(1,1,1,1)
				editor.colorTip.sliders[v] = editor.colorTip.sliders[v] or {}

				local slider = editor.colorTip.sliders[v]
				slider.name=v
				slider.x=0
				slider.y=(i-1)*13
				slider.width=paddedWidth
				slider.height=10
				slider.slider=slider.slider or 
					{target=editor.colorTip.targ[editor.colorTip.prop] ,round=0.01, prop=v ,min=0 ,max=1}
				slider.slider.pos=col[v]
				slider.alpha =0
				slider.func = slider.func or function() editor.colorTip.sliding = v end
				local dat = gradientMesh("horizontal",gradient[1],gradient[2])
				-- table.insert(dat,{0,0,0,0, 0,0,0,0})
				-- table.insert(dat,dat[])
				table.insert(dat,dat[3])
				table.insert(dat,dat[2])
				popPost()
				slider.gradient=gfx.newMesh(zformat3,dat,"triangles")
				pushPost()
				gfx.setMeshCullMode("none")
				gfx.draw(slider.gradient,0,slider.y,0,slider.width,slider.height)
				-- gfx.rectangle("fill",0,0,100,100)
				-- print("slider.gradient",slider.gradient)
				local val = editor.colorTip.targ[editor.colorTip.prop][v]*slider.width
				gfx.line(val,slider.y,val,slider.y+slider.height)
				editor.drawButton(slider,m3)

				if editor.colorTip.sliding==v then 
					editor.colorTip.targ[editor.colorTip.prop][v]=math.clamp(0,1,utils.map(m3.x,0,paddedWidth,0,1))
				end

				calcHSV(editor.colorTip.targ[editor.colorTip.prop])
				
				local c = (slider.hovered or editor.colorTip.sliding==v) and 0.8 or 0
				gfx.setColor(c,c,c,0.3)
				gfx.setLineWidth(2)
				gfx.rectangle("line",0,mf((i-1)*13),editor.colorTip.w-8,10,2)
				-- gfx.setColor(1,1,1,1)
				-- gfx.line(mf(col[v]*paddedWidth),slider.y,mf(col[v]*paddedWidth),slider.y+10)

			end
			gfx.translate(-1,41)
		else 
			gfx.push()
			gfx.translate(0,-30)
			gfx.setColor(1,1,1,1)
			-- gfx.rectangle("fill",0,0,100,100)
			local slider = {
				 name="scale"
				,x=28
				,y=0
				,width=paddedWidth
				,height=20
				,pct = 0.5
				,slider={target=editor.colorTip.targ[editor.colorTip.prop],round=0.01 , prop="scale" ,	min=0 ,max=1,pct=1}
				,func = function() editor.colorTip.sliding = "scale" end
			}
			editor.drawButton(slider,m3)
			gfx.pop()
		end

		-- Recent colors/patterns
		if editor.colorTip.mode == "patterns" then 
			local w = 28
			local w2 = w-1
			local n = mu((editor.colorTip.w-12)/w)
			for i=1,#patterns.dims,1 do 
				local pattern 		   = patterns.size[i]
				local x,y = ((i-1)%n)*(w+1),mf((i-1)/n)*(w+1)
				gfx.setColor(1,1,1,1)
				gfx.draw(
					patterns.atlas,
					gfx_copy.newQuad( pattern.x, pattern.y, pattern.w, pattern.w, patterns.w, patterns.h),
					x,y,0,w/pattern.w,w/pattern.w
				)

				if editor.colorTip.targ[editor.colorTip.prop].pattern 
					and editor.colorTip.targ[editor.colorTip.prop].pattern == i then 
					gfx.setColor(0,0,0,1)
					gfx.rectangle("line",x+0.5,y+0.5,w2,w2)	
				end
				if mouseIn(tip) and mouseIn(x,y,w2,w2, mouse.x-tip.x-4,mouse.y-tip.y-tip.w) then 
					gfx.setColor(1,1,1,0.5)
					gfx.rectangle("line",x,y,w2,w2)
					mouse.set(function()
						editor.colorTip.targ[editor.colorTip.prop].pattern = i
					end)
				end
			end
		else
			local recent = editor.recentColors
			if recent then 
				local w = 16
				local w2 = w-1
				local n = (editor.colorTip.w-12)/w
				for i=1,mu(n),1 do 
					local col 		= recent[i]
					if col and col.r then 
						gfx.setColor(col.r, col.g, col.b,1)
						gfx.rectangle("fill",(i-1)*w,0,w2,w2)
						if mouseIn((i-1)*w,0,w2,w2, mouse.x-tip.x-4,mouse.y-tip.y-tip.w-41) then 
							gfx.setColor(1,1,1,0.5)
							gfx.rectangle("line",(i-1)*w,0,w2,w2)
							mouse.set(function()
								editor.colorTip.targ[editor.colorTip.prop].r = col.r
								editor.colorTip.targ[editor.colorTip.prop].g = col.g
								editor.colorTip.targ[editor.colorTip.prop].b = col.b
							end)
						end
					end
				end
			end

			if editor.colorTip.dragging == "tri" then 
				local c     = vec3(math.clamp(tri.l,tri.r,m2[1]) , m2[2], m2[3])
				local cols  = {vec3(1),vec3(hsvToRgb(col.h,1,1)),vec3(0)}
				local pts		= {vec3(verts[1]),vec3(verts[2]),vec3(verts[3])}
				local u = pts[2] - pts[1]
				local v = pts[3] - pts[1]
				local w = c  - pts[1]
				local vw = v:cross(w)
				local vu = v:cross(u)
				local uw = u:cross(w)
				local uv = u:cross(v)
				local d = uv:len()
				local r = vw:len() / d
				local t = uw:len() / d

				local result = cols[1]*(1-(r+t)) + cols[2]*r + cols[3]*t
				if col.h then 
					--local r,g,b = result.x,result.y,result.z
					--local h,s,v = rgbToHsv(r,g,b)
					--local s = utils.map(m2[1],tri.l,tri.r,0,1)
					local s = 1-distPointToLineSegment({c.x,c.y},verts[2],verts[3])/80.35
					local v = 1-distPointToLineSegment({c.x,c.y},verts[1],verts[2])/80.35
					local r,g,b = hsvToRgb(col.h,s,v)
					trace("result",result.x,result.y,result.z)
					trace("result",r,g,b)
					editor.colorTip.targ[editor.colorTip.prop] = {r=r,g=g,b=b,h=col.h,s=s,v=v}
				end
			end

			if editor.colorTip.dragging == "quad" then 
				if col.h then 
					local s = math.clamp(0,1,utils.map(m2[1],quad.x,quad.x+quad.w,0,1))
					local v = math.clamp(0,1,utils.map(m2[2],quad.y,quad.y+quad.h,1,0))
					local r,g,b = hsvToRgb(col.h,s,v)
					editor.colorTip.targ[editor.colorTip.prop] = {r=r,g=g,b=b,h=col.h,s=s,v=v}
				end
			end

			if editor.colorTip.dragging == "wheel" then 
				local h = (math.angle(0,0,m2[1],m2[2]))/(pi*2)
				local r,g,b = hsvToRgb(h,col.s,col.v)
				editor.colorTip.targ[editor.colorTip.prop] = {r=r,g=g,b=b,h=h,s=col.s,v=col.v}
			end
		end

	 gfx.pop()
	

	 gfx.setScissor()



	mouse.pushUp(function() 
		editor.colorTip.dragging=""
		editor.colorTip.sliding=nil
	end)
	popPost()
end

function editor.closeColorTip()
	effects.tween(editor.colorTip,{a=0},0.06,"easeIn",1,function() 
		editor.colorTip.open=false
		if editor.colorTip.targ and editor.colorTip.targ[editor.colorTip.prop] then 
			editor.pushColor(editor,editor.colorTip.targ[editor.colorTip.prop])
		end
		if not contextMenu.open then 
			unlockMouse() 
			mouse.down.L 			= true
		end
	end)

end

function editor.colorSquare(targ,prop,parent,enable)
	return {
		name="",size=-1,tip=prop,col={},
		func=function(x)
			editor.openColorTip(targ,prop)
			return ""
		end,
		update=function(x) 
			if enable then 
				x.active = enable[1][enable[2]]
			else 
				x.active=true
			end
			x.col = {
				r=targ[prop] and targ[prop].r or 1,
				g=targ[prop] and targ[prop].g or 1,
				b=targ[prop] and targ[prop].b or 1,
				a=1--x.active and 1 or 0.5
			}
			x.ocol={r=1,g=1,b=1,a=x.hovered and 1 or 0.3}
			calcHSV(targ[prop])
		end
	}
end

function editor.contextColor(color,prop)
	
	editor.colorMode = "HSVRGB2"

	if prop and not color[prop] then 
		--color[prop] = {r=1,g=1,b=1,h=1,s=0,v=1}
	end

	local rval = {}

	if editor.colorMode == "HSV" then 
		rval= editor.contextHSV(prop and color[prop] or color,a)
	elseif editor.colorMode == "RGB" then 
		rval= editor.contextRGB(prop and color[prop] or color,a)
	elseif editor.colorMode == "HSVRGB1" then 
		rval= {editor.contextHSV(prop and color[prop] or color,a),editor.contextRGB(prop and color[prop] or color,a)}
	elseif editor.colorMode == "HSVRGB2" then 
		rval= classicConcat(editor.contextHSV(prop and color[prop] or color,a,{noval=true}),editor.contextRGB(prop and color[prop] or color,a,{noval=true}))
	end

	classicConcat(rval,{{ tip="pick color", name="+", align="center",size =1,func = function() editor.contextColorPicker(prop and color[prop] or color) return " " end}})
	classicConcat(rval,{{ tip="palettes", name=">", align="center",size =1,func = function() editor.contextPalettes(prop and color[prop] or color) return " " end}})
	
	return rval
end

function editor.contextRGB(color,a,prop)
	local prop = prop or {}
	--calcRGB(color,a)

	local update = function(x)
		calcHSV(x,a)
	end
	local update2 = function(x)
		x.gradient = {
			{x.slider.prop=="r" and 0 or x.slider.target.r,x.slider.prop=="g" and 0 or x.slider.target.g,x.slider.prop=="b" and 0 or x.slider.target.b},
			{x.slider.prop=="r" and 1 or x.slider.target.r,x.slider.prop=="g" and 1 or x.slider.target.g,x.slider.prop=="b" and 1 or x.slider.target.b}
		}
	end

	return {
		{ name= "R",gradient = {{0,0,0},{1,1,1}}, size=2,slider={noval=prop.noval,target=color,round=0.01, prop="r" ,min=0,max=1,update = update },update = update2},
		{ name= "G", size=2,slider={noval=prop.noval,target=color,round=0.01, prop="g" ,min=0,max=1,update = update},update = update2 },
		{ name= "B", size=2,slider={noval=prop.noval,target=color,round=0.01, prop="b" ,min=0,max=1,update = update},update = update2 }
		,
	}

end


function editor.contextHSV(color,a,prop)
	local prop = prop or {}
	color = color or colors.white
	color.h,color.s,color.v = rgbToHsv(color.r, color.g, color.b, a or color.a or 1)
	local update = function(x)
		calcRGB(x,a)
	end
	local update2 = function(x)
		x.gradient = {
			{hsvToRgb(x.slider.prop=="h" and 0 or x.slider.target.h,x.slider.prop=="s" and 0 or x.slider.target.s,x.slider.prop=="v" and 0 or x.slider.target.v)},
			{hsvToRgb(x.slider.prop=="h" and 1 or x.slider.target.h,x.slider.prop=="s" and 1 or x.slider.target.s,x.slider.prop=="v" and 1 or x.slider.target.v)}
		}
	end


	return {
		{ name= "H", size =2,  slider={noval=prop.noval,target=color,round=0.01, prop="h" ,	min=0,max=1,update = update},update=update2 },
		{ name= "S", size =2,	 slider={noval=prop.noval,target=color,round=0.01, prop="s" ,min=0,max=1,update = update}, update=update2 },
		{ name= "V", size =2,  slider={noval=prop.noval,target=color,round=0.01, prop="v" ,	min=0,max=1,update = update},update=update2 },
	}
end

function editor.contextHue(color)
	color.h,color.s,color.v = rgbToHsv(color.r, color.g, color.b, a or color.a or 1)
	calcRGB(color,a)
	return {
		{ name= "Hue",   		col  = color.hued, 		slider={target=color,round=0.01, prop="h" ,min=0,max=1,update = function(x) calcRGB(x,a)	end} }
	}
end

function calcRGB(color,a)
	color.hued 				= color.hued 		or {r=0,g=0,b=0,a=1}
	color.saturated 		= color.saturated  	or {r=0,g=0,b=0,a=1}
	color.valued 			= color.valued 	 	or {r=0,g=0,b=0,a=1}
	
	color.r,color.g,color.b,color.a = hsvToRgb(color.h, color.s, color.v, (a or color.a or 1))

	color.hued.r,		color.hued.g,		color.hued.b, 		color.hued.a 		= hsvToRgb(color.h, 	0.5, 	 	0.5, 		(a or color.a or 1))
	color.saturated.r,	color.saturated.g,	color.saturated.b, 	color.saturated.a	= hsvToRgb(color.h, 	color.s, 	0.5, 		(a or color.a or 1))
	color.valued.r,		color.valued.g,		color.valued.b, 	color.valued.a		= hsvToRgb(color.h, 	0.5, 	color.v, 		(a or color.a or 1))
end

function calcHSV(color,a)
	color.h,color.s,color.v = rgbToHsv(color.r, color.g, color.b, a or color.a)

end


---------------------------------
-- DRAW 
---------------------------------
function editor.drawContextBack(cm)
	if  not bboxCollide2(cm,{x=0,y=0,w=screenWidth,h=screenHeight}) then return end
	frostCalled 	= true
	cm.shadow 		= cm.shadow or 0.5
	cm.col 			= lume.merge({r=0,g=0,b=0,a=0},cm.col or {})
	local alpha 		= cm.backTex and 1 or (cm.alpha or 1)
	cm.w = cm.w or cm.width 
	cm.h = cm.h or cm.height

	if cm.padding then 
		cm.x = cm.x - cm.padding
		cm.y = cm.y - cm.padding
		cm.w = cm.w + cm.padding*2
		cm.h = cm.h + cm.padding*2
	end

	local shadowless = cm.shadowless==nil and true or cm.shadowless

	pushPost()
	if LOVR or config.flatUI then 
		gfx.push("all")
		gfx.setBlendMode("alpha")
		if cm.color then 
			gfx.setColor(cm.color.r,cm.color.g,cm.color.b,(cm.color.a )*alpha)
		end
		gfx.setColor(0.13,0.13,0.13,0.999*alpha)
		gfx.rectangle("fill",	mf(cm.x),	mf(cm.y),	mf(cm.w),	mf(cm.h),cm.sharp and 0 or 6)  
		gfx.pop()
		popPost()
		return 
	end
	
	gfx.push("all")
	gfx.setCanvas({stencil=true})
	
	-- if game.state~="Load" then 
	-- 	local shadow = cm.h> 30 and getImage("ContextShadow") or getImage("ContextShadowShort")
	-- 	gfx.setColor(1,1,1,cm.shadow*1*alpha)
	-- 	if not cm.shadowless then 
	-- 		gfx.draw(
	-- 			shadow
	-- 			, cm.x+cm.w/2
	-- 			, cm.y+cm.h/1.8
	-- 			, 0
	-- 			, (cm.w/512)*1.4
	-- 			, (cm.h/shadow:getHeight())*1.6
	-- 			, shadow:getWidth()/2
	-- 			, shadow:getHeight()/2
	-- 		)      
	-- 	end
	-- end

	if hiSpec then 
		shaders.frosty:send('image_size',{renderWidth/frostScale,renderHeight/frostScale})
		
		local res = game.resolution or 1
		gfx.setShader()
		gfx.stencil(function()
			gfx.setColor(1,1,1,1)
			gfx.rectangle("fill",	mf(cm.x),	mf(cm.y),	mf(cm.w),	mf(cm.h),4) 
		end, "replace", 1)
		gfx.setStencilTest("greater", 0)
		gfx.setColor(1,1,1,1)
		gfx.setShader(shaders.frosty)
		shaders.frosty:send("alpha",1)
		gfx.setBlendMode("alpha")
		gfx.draw(
			canvasFrost,
			gfx_copy.newQuad( 
			cm.x/frostScale*res,
			cm.y/frostScale*res,	
			cm.w/frostScale*res,
			cm.h/frostScale*res, 
			renderWidth/frostScale, 
			renderHeight/frostScale),
			cm.x,cm.y,0,frostScale/res 	       ,frostScale/res        
		)
		gfx.setShader()

		gfx.setColor(0.1,0.1,0.1,0.5)
		gfx.rectangle("fill",	cm.x,	cm.y,	cm.w,	cm.h,	4) 
	else 

		gfx.setColor(0.1,0.1,0.1,1)
		gfx.rectangle("fill",	cm.x,	cm.y,	cm.w,	cm.h,	4) 
	end
	
	gfx.pop()
	popPost()
end
local gradient
function editor.drawContextItem(cmi)
	-- if LOVR then rl.BeginBlendMode() end
	local round = 2
	cmi = lume.map(cmi,mf)
	cmi.col = lume.merge({r=0,g=0,b=0,a=0},cmi.col or {})
	cmi.tcol = lume.merge({r=1,g=1,b=1,a=1},cmi.tcol or {})
	cmi.w = cmi.width or cmi.w
	cmi.h = cmi.height or cmi.h
	local cut = (cmi.name == "×" or cmi.name == "-") and 2 or 1
	if cmi.hovered then 
		gfx.setColor(0,0,0,0.5) 
		gfx.rectangle("fill", cmi.x+cut, cmi.y+cut, cmi.width-cut*2, cmi.h-cut*2,round) 
	end 
	local mult = cmi.hovered and 1.5 or 1
	--gfx.setColor(cmi.col.r*mult,cmi.col.g*mult,cmi.col.b*mult,cmi.subhead and 0.8 or cmi.col.a) 
	if cmi.ocol then 
		gfx.setLineWidth(2)
		gfx.setColor(cmi.ocol.r,cmi.ocol.g,cmi.ocol.b,cmi.ocol.a)
		gfx.rectangle("line", cmi.x+cut+0.5, cmi.y+cut+0.5, cmi.width-cut*2-1, cmi.h-cut*2-1,round) 
	end
	gfx.setColor(cmi.col.r,cmi.col.g,cmi.col.b,cmi.col.a)
	gfx.rectangle("fill", cmi.x+cut, cmi.y+cut, cmi.width-cut*2, cmi.h-cut*2,round) 
	if cmi.img then 
		cmi.imgScaleOverride = 1
		buttonImages(cmi)
	end
	if cmi.gradient then 
		print("cm grad")
		-- gradient = gradientMesh("horizontal",cmi.gradient[1],cmi.gradient[2])
		-- gfx.setColor(1,1,1,1)
		-- gfx.draw(gradient,cmi.x+cut,cmi.y+cut,0,cmi.width-cut*2, cmi.fullGrad and cmi.h or cmi.h/4)
	end
	gfx.setColor(1,1,1,1);
	-- (cmi.draw or nothing)(cmi);
	gfx.setColor(cmi.tcol.r,cmi.tcol.g,cmi.tcol.b,(cmi.subitems and not cmi.subhead) and 0.4 or cmi.tcol.a*contextMenu.alpha)
	if cmi.name or cmi.text then 
		if cmi.toggle and cmi.toggle.targ[cmi.toggle.prop] then 

		end
		if cmi.name == "ticked" or cmi.text == "ticked" then 
			gfx.setColor(1,1,1,1)
			gfx.setLineWidth(2)
			gfx.line	(	
				cmi.x+4,cmi.y+cmi.height/1.7,
				cmi.x+cmi.width/2.5,cmi.y+cmi.height-4,
				cmi.x+cmi.width-4,cmi.y+4
			)
			-- gfx.circle("line",cmi.x+cmi.w/2,cmi.y+cmi.h/2,cmi.w/4)
		end
		local name = cmi.name or cmi.text  
		if #name>3 then 	
			name = ellipses(cmi.name,(cmi.width-cmi.width/8),(cmi.items),cmi.items)
		end
		cmi.align = name=="···" and "center" or cmi.align
		local dotOff = name=="···" and 3 or 0

		gfx.printf(tostring(name) ,	mf(cmi.x+(cmi.align=="center" and 0 or 4))-dotOff,	cmi.y+4, cmi.width+dotOff*2, cmi.align or (cmi.width<64 and "center" or "left"))

		if cmi.selectedMode then 
			gfx.setColor	(1,1,1,.6)  	
			gfx.rectangle	("fill",cmi.x+2,cmi.y+cmi.h-4,(cmi.w-4),2, 2 )
		end
	end
	
end

function editor.drawContextOutline(cm)
	--- OUTLINE
	gfx.setLineWidth(2)
	gfx.setColor(0,0,0,1)
	gfx.rectangle("line",	cm.x,	cm.y,	cm.width,	cm.height,	5) 
end
