Skip to content

Instantly share code, notes, and snippets.

@nico-abram
Created September 11, 2018 02:19
Show Gist options
  • Save nico-abram/c8b96b6058e0e322ed8623f858a15e92 to your computer and use it in GitHub Desktop.
Save nico-abram/c8b96b6058e0e322ed8623f858a15e92 to your computer and use it in GitHub Desktop.
function resizeX(x) return x*SCREEN_WIDTH/854 end
function resizeY(y) return y*SCREEN_HEIGHT/480 end
function resize(point)
return {resizeX(point[1]), resizeY(point[2])}
end
function fillNilTableFieldsFrom(table1, defaultTable)
for key,value in pairs(defaultTable) do
if table1[key] == nil then
table1[key] = defaultTable[key]
end
end
end
local defaultLabel = {
x=0,
y=0,
scale=1.0,
text="",
alpha=1,
centered=false,
width=nil,
color=color("#FFFFFF"),
init=nil
}
Def.Label = function(params)
if params==nil then params={} end
fillNilTableFieldsFrom(params, defaultLabel)
return LoadFont("Common Normal") .. {
InitCommand=function(self)
self:xy(resizeX(params.x), resizeY(params.y)):zoom(params.scale)
if centered then
self:halign(0.5)
end
if params.width then
self:maxwidth(params.width)
end
if params.init then params.init(self) end
end,
BeginCommand=function(self)
self:settext(params.text):diffuse(params.color):diffusealpha(params.alpha)
end
}
end
local defaultRectangle = {
x=0,
y=0,
z=1,
centered=false,
width=100,
height=100,
color=color("#FFFFFF"),
onClick=nil,
init=nil,
alpha=1,
messages = {}
}
Def.Rectangle = function(params)
if params==nil then params={} end
fillNilTableFieldsFrom(params, defaultRectangle)
local topName
local rect = Def.Quad {
InitCommand=function(self)
self:xy(resizeX(params.x + (params.centered and 0 or params.width/2)),resizeY(params.y + (params.centered and 0 or params.height/2))):zoomto(resizeX(params.width),resizeY(params.height)):z(params.z)
if params.init then params.init(self) end
end;
OnCommand=function(self)
self:diffuse(params.color):diffusealpha(params.alpha)
local top = SCREENMAN:GetTopScreen()
topName = top:GetName()
end;
LeftClickPressMessageCommand=function(self)
if params.onClick and self:isOver() then
BUTTON:addPressedActors(self, topName, "DeviceButton_left mouse button")
end
end,
TopPressedCommand = params.onClick
}
for k,v in pairs(params.messages) do
rect[k] = v
end
return rect
end
local defaultBorders = {
x=0,
y=0,
alpha=1,
color=color("#FFFFFF"),
width=100,
height=100,
centered=false,
borderWidth=10,
init=nil,
messages={},
}
Def.Borders = function(params)
if params==nil then params={} end
fillNilTableFieldsFrom(params, defaultBorders)
return Def.ActorFrame {
InitCommand=function(self)
self:xy(resizeX(params.x),resizeY(params.y))
if params.init then params.init(self) end
end,
--4 border quads
Def.Rectangle(setmetatable({width=params.borderWidth,x=0,y=0}, {__index=params})), --left
Def.Rectangle(setmetatable({height=params.borderWidth,x=0,y=0}, {__index=params})), --top
Def.Rectangle(setmetatable({x=params.width-params.borderWidth,y=0, width=params.borderWidth}, {__index=params})), --right
Def.Rectangle(setmetatable({y=params.height-params.borderWidth,x=0, height=params.borderWidth}, {__index=params})), --bottom
}
end
local defaultBordereredRectangle = {
x=0,
y=0,
z=1,
width=100,
height=100,
centered=false,
color=color("#FFFFFF"),
alpha=1,
onClick=nil,
init=nil,
borderWidth=10,
borderColor=color("#999999"),
messages = {}
}
Def.BorderedRectangle = function(params)
if params==nil then params={} end
fillNilTableFieldsFrom(params, defaultBordereredRectangle)
local borderParams = setmetatable({color=params.borderColor}, {__index=params})
return Def.ActorFrame {
Def.Rectangle(params),
Def.Borders(borderParams)
}
end
local defaultButton = {
x=0,
y=0,
z=1,
width=100,
height=100,
bgColor=color("#FFFFFF"),
fontScale=0.5,
fontColor=color("#000000"),
borderWidth=nil,
borderColor=color("#888888"),
text="",
centered=false,
onClick=nil,
init=nil,
alpha=1,
messages = {}
}
Def.Button = function(params)
if params==nil then params={} end
fillNilTableFieldsFrom(params, defaultButton)
local labelParams = setmetatable({color=params.bgColor, width=params.width*0.9,y=params.height/2, x=params.width/2}, {__index=params})
local rectangleParams = setmetatable({}, {__index=params})
local t = Def.ActorFrame {
InitCommand=function(self)
self:xy(resizeX(params.x),resizeY(params.y))
if params.init then params.init(self) end
end,
Def.Rectangle(rectangleParams),
Def.Label(labelParams),
}
if params.borderWidth and params.borderWidth > 0 then
t[#t+1] = Def.Borders(setmetatable({color=params.borderColor,}, {__index=params}))
end
return t
end
function insertCircleVerts(t, rx, ry, chords, start_angle, end_angle, color, x, y)
if start_angle == end_angle then
end_angle= start_angle + (math.pi*2)
end
local chord_angle= (end_angle - start_angle) / chords
local verts= {}
for c= 0, chords do
local angle= start_angle + (chord_angle * c)
table.insert(t,{{resizeX(x+rx * math.cos(angle)), resizeY(y+ry * math.sin(angle)), 0}, color})
end
return verts
end
function calcRoundedRectVerts(params)
local verts={}
local top = -params.height/2
local bot = params.height/2
local left = -params.width/2
local right = params.width/2
local r = params.r
table.insert(verts, {{resizeX(left+r), resizeY(top), 0}, params.color}) -- top, left+r
insertCircleVerts(verts, r, r, r*6, math.pi*3/2, math.pi, params.color, left+r, top+r)
table.insert(verts, {{resizeX(left), resizeY(bot-r), 0}, params.color})
insertCircleVerts(verts, r, r, r*6, math.pi, math.pi/2, params.color, left+r, bot-r)
table.insert(verts, {{resizeX(right-r), resizeY(bot), 0}, params.color})
insertCircleVerts(verts, r, r, r*6, math.pi/2, 0, params.color, right-r, bot-r)
table.insert(verts, {{resizeX(right), resizeY(top+r), 0}, params.color})
insertCircleVerts(verts, r, r, r*6, 0, -math.pi/2, params.color, right-r, top+r)
table.insert(verts, {{resizeX(left+r), resizeY(top), 0}, params.color})
return verts
end
local defaultRoundedRectangle = {
x=0,
y=0,
z=1,
r=5,
width=100,
height=100,
alpha=1,
color=color("#FFFFFF"),
borderWidth=nil,
borderColor=nil,
onClick=nil,
init=nil
}
Def.RoundedRectangle = function(params)
if params==nil then params={} end
fillNilTableFieldsFrom(params, defaultRoundedRectangle)
local clickable = quadButton(params.z)
clickable.TopPressedCommand = params.onClick
local t = Def.ActorFrame {
Def.ActorMultiVertex{
InitCommand= function(self)
self:xy(resizeX(params.x), resizeY(params.y)):
SetDrawState{Mode="DrawMode_Fan"}:SetDrawState{First= 1, Num= -1}:
SetVertices(calcRoundedRectVerts(params)):diffusealpha(params.alpha):finishtweening()
end,
},
clickable,
}
if params.borderColor~=nil and params.borderWidth~=nil then
local borderParams = {}
setmetatable(borderParams, {__index = params})
borderParams.color = params.borderColor
t[#t+1] = Def.ActorMultiVertex{
InitCommand= function(self)
self:xy(resizeX(params.x), resizeY(params.y)):
SetDrawState({Mode="DrawMode_LineStrip"}):SetDrawState{First= 1, Num= -1}:
SetVertices(calcRoundedRectVerts(borderParams)):SetLineWidth(params.borderWidth):finishtweening()
end,
}
end
return t
end
function calcOvalRectVerts(params)
ry = params.height/2
local verts={}
table.insert(verts, {{resizeX(-params.width/2+params.r), resizeY(-params.height/2), 0}, params.color})
insertCircleVerts(verts, params.r, ry, params.r*6, math.pi*3/2, math.pi/2, params.color, -params.width/2+params.r, 0)
table.insert(verts, {{resizeX(-params.width/2+params.r), resizeY(params.height/2), 0}, params.color})
table.insert(verts, {{resizeX(params.width/2-params.r), resizeY(params.height/2), 0}, params.color})
insertCircleVerts(verts, params.r, ry, params.r*6, math.pi*5/2, math.pi*3/2, params.color, params.width/2-params.r, 0)
table.insert(verts, {{resizeX(params.width/2-params.r), resizeY(-params.height/2), 0}, params.color})
table.insert(verts, {{resizeX(-params.width/2+params.r), resizeY(-params.height/2), 0}, params.color})
return verts
end
local defaultOvalRectangle = {
x=0,
y=0,
r=5,
width=100,
height=100,
color=color("#FFFFFF"),
borderWidth=nil,
borderColor=nil,
alpha=1,
onClick=nil,
z=1,
init=nil
}
Def.OvalRectangle = function(params)
if params==nil then params={} end
fillNilTableFieldsFrom(params, defaultOvalRectangle)
local clickableParams = setmetatable({alpha=0}, {__index=params})
local clickable = Def.Rectangle(clickableParams)
clickable.TopPressedCommand = params.onClick
local t = Def.ActorFrame {
Def.ActorMultiVertex{
InitCommand= function(self)
self:xy(resizeX(params.x), resizeY(params.y)):
SetDrawState{Mode="DrawMode_Fan"}:SetDrawState{First= 1, Num= -1}:
SetVertices(calcOvalRectVerts(params)):finishtweening()
end,
},
clickable,
}
if params.borderColor~=nil and params.borderWidth~=nil then
local borderParams = {}
setmetatable(borderParams, {__index = params})
borderParams.color = params.borderColor
t[#t+1] = Def.ActorMultiVertex{
InitCommand= function(self)
self:xy(resizeX(params.x), resizeY(params.y)):
SetDrawState({Mode="DrawMode_LineStrip"}):SetDrawState{First= 1, Num= -1}:
SetVertices(calcOvalRectVerts(borderParams)):SetLineWidth(params.borderWidth):finishtweening()
end,
}
end
return t
end
local function gen_arrow_verts(size, point_vert, leg_width, leg_len, stem_width)
return {
point_vert,
{point_vert[1]-leg_len, point_vert[2]+leg_len, 0},
{point_vert[1]+leg_width, point_vert[2]+leg_width, 0},
{point_vert[1]-leg_len, point_vert[2]+leg_len, 0},
{point_vert[1]-leg_len+leg_width, point_vert[2]+leg_len+leg_width, 0},
{point_vert[1]+leg_width, point_vert[2]+leg_width, 0},
{point_vert[1]-leg_len, point_vert[2]+leg_len, 0},
{point_vert[1]-leg_len, point_vert[2]+leg_len+leg_width, 0},
{point_vert[1]-leg_len+leg_width, point_vert[2]+leg_len+leg_width, 0},
point_vert,
{point_vert[1]+leg_len, point_vert[2]+leg_len, 0},
{point_vert[1]-leg_width, point_vert[2]+leg_width, 0},
{point_vert[1]+leg_len, point_vert[2]+leg_len, 0},
{point_vert[1]+leg_len-leg_width, point_vert[2]+leg_len+leg_width, 0},
{point_vert[1]-leg_width, point_vert[2]+leg_width, 0},
{point_vert[1]+leg_len, point_vert[2]+leg_len, 0},
{point_vert[1]+leg_len, point_vert[2]+leg_len+leg_width, 0},
{point_vert[1]+leg_len-leg_width, point_vert[2]+leg_len+leg_width, 0},
}
end
function arrow_actor(x, y, r, size, out_color, in_color)
x= x or 0
y= y or 0
r= r or 0
size= size or 8
local point_vert= {0, -size/2, 0}
local leg_width= 8
local leg_len= size/2 - leg_width^.5
local stem_width= 4 * 2^.5
local insize= size-8
local in_point_vert= {0, -insize/2, 0}
local inlw= leg_width-4
local inll= leg_len-2
local insw= stem_width-2
return Def.ActorMultiVertex{
InitCommand= function(self)
local out_verts= gen_arrow_verts(size, point_vert, leg_width, leg_len, stem_width)
local in_verts= gen_arrow_verts(insize, in_point_vert, inlw, inll, insw)
local verts= {}
for i, v in ipairs(out_verts) do
verts[#verts+1]= {v, out_color}
end
for i, v in ipairs(in_verts) do
verts[#verts+1]= {v, in_color}
end
self:xy(x, y):rotationz(r):SetDrawState{Mode="DrawMode_Triangles"}
:SetVertices(verts)
end
}
end
local defaultDragAndDroppable = {
minX=0,
maxX=SCREEN_WIDTH,
minY=0,
maxY=SCREEN_HEIGHT,
}
function makeDragAndDroppable(actor, params)
if params==nil then params={} end
fillNilTableFieldsFrom(params, defaultDragAndDroppable)
actor.relativeClickPos = nil
--Press (Store selfX-PressMouseX)
actor.LeftClickPressMessageCommand=function(self)
if (actor.isOver and actor.isOver(self)) or isOver(self) then
actor.relativeClickPos = {self:GetX()-INPUTFILTER:GetMouseX(), self:GetY()-INPUTFILTER:GetMouseY()}
end
end
--Release
actor.LeftClickPressReleaseMessageCommand=function(self)
if actor.relativeClickPos then
actor.relativeClickPos = nil
end
end
--Move (Set selfX+(currentMouseX-PressmouseX) = selfX+deltaMouseX)
actor.MouseMoveMessageCommand=function(self)
if actor.relativeClickPos then
local x =math.min(math.max(INPUTFILTER:GetMouseX()+actor.relativeClickPos[1], params.minX), params.maxX)
local y = math.min(math.max(INPUTFILTER:GetMouseY()+actor.relativeClickPos[2], 0), SCREEN_HEIGHT)
self:xy(x, y)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment