-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- -- file: gui_commandring.lua -- brief: A proof of concept for a fast mouse driven circular menu -- author: Michiel Van den Berghe, Dave "Trepan" Rodgers -- -- Copyright (C) 2007. -- Licensed under the terms of the GNU GPL, v2 or later. -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- function widget:GetInfo() return { name = "Command Ring", desc = "A proof of concept for a fast mouse driven circular menu", author = 'Michiel "Michilus" Van den Berghe', date = "Jul 10, 2008", license = "GNU GPL, v2 or later", layer = 0, enabled = true -- loaded by default? } end -------------------------------------------------------------------------------- -- GLOBALS -------------------------------------------------------------------------------- local gl = gl -- use a local copy for faster access local commandersFound = false local alliedCommanders = {} local commander -------------------------------------------------------------------------------- -- BUTTON STUFF -------------------------------------------------------------------------------- local buttons = {} function AddButton(button) table.insert(buttons, button) end function ClearButtons() buttons = {} end function InButton(button, x, y) return button.posx < x and x < button.posx + button.width and button.posy < y and y < button.posy + button.height end function CheckButtons(x, y) for index, button in ipairs(buttons) do if InButton(button, x, y) then button.onClick() end end end function SetButtons(b) buttons = b end function DrawButton(button) gl.Color(button.color) gl.Rect(button.posx, button.posy, button.posx + button.width, button.posy + button.height) gl.Color(button.textColor) w = gl.GetTextWidth(button.text) local size = (button.width - 6) / w if size > button.height then size = button.height - 6 end textX = button.posx + button.width / 2 textY = button.posy + button.height / 2 - size / 2 gl.Text(button.text, textX, textY, size, "cno") gl.Color(1,1,1,1) end function DrawButtons() for index, button in ipairs(buttons) do DrawButton(button) end end -- Buttons for testing function OnAttack() Spring.SetActiveCommand(CMD[CMD.ATTACK]) end function OnGuard() Spring.SetActiveCommand(CMD[CMD.GUARD]) end function OnCloak() Spring.SetActiveCommand(CMD[CMD.CLOAK]) end function OnToggleMode() Spring.Echo("Mode") end function OnRepair() Spring.SetActiveCommand(CMD[CMD.REPAIR]) end local testButton = { text = "Button Test", height = 60, width = 100, posx = 100, posy = 200, color = {1, 1, 1, 0.5}, textColor = {1, 0, 0, 1}, onClick = TestButtonClick } local attackButton = { text = "Attack", height = 40, width = 60, posx = 0, posy = 0, color = {1, 1, 1, 0.5}, textColor = {1, 0, 0, 1}, onClick = OnAttack } local guardButton = { text = "Guard", height = 40, width = 60, posx = 0, posy = 0, color = {1, 1, 1, 0.5}, textColor = {1, 0, 0, 1}, onClick = OnGuard } local cloakButton = { text = "Cloak", height = 40, width = 60, posx = 0, posy = 0, color = {1, 1, 1, 0.5}, textColor = {1, 0, 0, 1}, onClick = OnCloak } local toggleModeButton = { text = "Mode", height = 40, width = 60, posx = 0, posy = 0, color = {1, 1, 1, 0.5}, textColor = {1, 0, 0, 1}, onClick = OnToggleMode } local repairButton = { text = "Repair", height = 40, width = 60, posx = 0, posy = 0, color = {1, 1, 1, 0.5}, textColor = {1, 0, 0, 1}, onClick = OnRepair } -- Buildpic functions function DrawBuildPic(unit, posx, posy, w, h) texture = '#' .. Spring.GetUnitDefID(unit) gl.Texture(true) gl.Texture(texture) gl.TexRect(posx, posy, posx + w, posy + h) gl.Texture(false) end -------------------------------------------------------------------------------- -- DRAG MODE -------------------------------------------------------------------------------- local dragMode = false local circleLineList local function MakeCircleList(type) local radius = 80 local divs = 64 local x, y, l, m, r = Spring.GetMouseState() local elements = {} for i = 0,divs-1 do local r = 2.0 * math.pi * (i / divs) table.insert(elements, { v = { x + math.cos(r) * radius, y + math.sin(r) * radius }, t = { x + math.cos(r) * radius, y + math.sin(r) * radius} }) end gl.Shape(type, elements) end function EnterDragMode(x, y) radius = 80 dragMode = true gl.LineWidth(50.0) circleLineList = gl.CreateList(MakeCircleList, GL.LINE_LOOP) SetButtons({attackButton, guardButton, toggleModeButton, cloakButton, repairButton}) n = # buttons if n <= 0 then return false end angle = 2 * math.pi / n for i = 1, n do posx = x + math.sin(angle * (i - 1)) * radius posy = y + math.cos(angle * (i - 1)) * radius buttons[i].posx = posx - buttons[i].width / 2 buttons[i].posy = posy - buttons[i].height / 2 end end function ExitDragMode(x, y) dragMode = false CheckButtons(x, y) ClearButtons() end -------------------------------------------------------------------------------- -- CALL INS -------------------------------------------------------------------------------- function widget:DrawScreen() size = 60 DrawButtons() if dragMode then gl.Color(1,1,1,0.3) gl.CallList(circleLineList) gl.Color(1,1,1,1) end -- count = Spring.GetSelectedUnitsCount() -- if count > 0 then -- units = Spring.GetSelectedUnits() -- for i = 1, count do -- DrawBuildPic(units[i], size * (i - 1), 0, size, size) -- end end end function widget:MousePress(x, y, button) if button == 1 and InButton(testButton, x, y) then testButton.onClick() end if button == 1 or button == 3 then x, y, l, m, r = Spring.GetMouseState() if l and r and not dragMode then EnterDragMode(x, y) --Spring.Echo("Dragmode!") return true -- Don't block the event, we need it for MouseRelease end end end function widget:MouseRelease(x, y, button) x, y, l, m, r = Spring.GetMouseState() if dragMode and (l or r) then ExitDragMode(x, y) --Spring.Echo("No more Dragmode!") return -1 -- Don't issue any commands end end function widget:UnitCreated(unitID, unitDefID, unitTeam) teams = Spring.GetTeamList(Spring.GetMyTeamID()) if not commandersFound then if unitTeam == Spring.GetMyTeamID() then commander = unitID else table.insert(alliedCommanders,unitID) end end end