Compare commits
2 Commits
97f21e192f
...
1f2899077c
Author | SHA1 | Date |
---|---|---|
wan-may | 1f2899077c | |
wan-may | 6483f42c80 |
2
conf.lua
|
@ -12,7 +12,7 @@ function love.conf(t)
|
||||||
|
|
||||||
t.window.title = "dcEarth" -- The window title (string)
|
t.window.title = "dcEarth" -- The window title (string)
|
||||||
t.window.icon = "icons/favicon.png" -- Filepath to an image to use as the window's icon (string)
|
t.window.icon = "icons/favicon.png" -- Filepath to an image to use as the window's icon (string)
|
||||||
t.window.width = 1000 -- The window width (number)
|
t.window.width = 1024 -- The window width (number)
|
||||||
t.window.height = 640 -- The window height (number)
|
t.window.height = 640 -- The window height (number)
|
||||||
t.window.borderless = false -- Remove all border visuals from the window (boolean)
|
t.window.borderless = false -- Remove all border visuals from the window (boolean)
|
||||||
t.window.resizable = true -- Let the window be user-resizable (boolean)
|
t.window.resizable = true -- Let the window be user-resizable (boolean)
|
||||||
|
|
After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 357 B |
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 301 B After Width: | Height: | Size: 381 B |
12
main.lua
|
@ -2,7 +2,7 @@ local love = assert( love, "This tool requires LOVE: love2d.org" )
|
||||||
--assert( require('mobdebug') ).start() --remote debugger
|
--assert( require('mobdebug') ).start() --remote debugger
|
||||||
local map = require 'map.map'
|
local map = require 'map.map'
|
||||||
local button = require 'ui.button'
|
local button = require 'ui.button'
|
||||||
local mainmenu = require 'ui.mainmenu'
|
local mainmenu = require 'ui.menu.mainmenu'
|
||||||
local Camera = require 'ui.camera'
|
local Camera = require 'ui.camera'
|
||||||
|
|
||||||
function love.load()
|
function love.load()
|
||||||
|
@ -58,10 +58,7 @@ end
|
||||||
function love.mousepressed( x, y, mouseButton, istouch, presses )
|
function love.mousepressed( x, y, mouseButton, istouch, presses )
|
||||||
local wx, wy = Camera.GetWorldCoordinate( x, y )
|
local wx, wy = Camera.GetWorldCoordinate( x, y )
|
||||||
|
|
||||||
if button.selected and button.selected:contains( x, y ) then
|
return button.mousepressed( x, y )
|
||||||
button.callback( button.selected )
|
|
||||||
return button.selected:callback()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.mousemoved( x, y, dx, dy, istouch )
|
function love.mousemoved( x, y, dx, dy, istouch )
|
||||||
|
@ -89,9 +86,6 @@ function love.keypressed(key, code, isRepeat)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function love.textinput()
|
||||||
|
|
||||||
do
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,48 @@ function city:formatDisplayInfo()
|
||||||
CAPITAL: %s]]):format( self.name, self.country, self.x, self.y, self.pop, tostring(self.capital) )
|
CAPITAL: %s]]):format( self.name, self.country, self.x, self.y, self.pop, tostring(self.capital) )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function city:delete()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function city:add()
|
||||||
|
local n = #cities + 1
|
||||||
|
cities[ n ] = self
|
||||||
|
self.n = n
|
||||||
|
|
||||||
|
local idxPoints = #points + 1
|
||||||
|
self.points = idxPoints
|
||||||
|
points[ idxPoints ], points[ idxPoints + 1 ] = self.x, self.y
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function city:moveTo(x, y)
|
||||||
|
self.x, self.y = x, y
|
||||||
|
if self.points then
|
||||||
|
points[ self.points ] = x
|
||||||
|
points[ self.points + 1 ] = y
|
||||||
|
end
|
||||||
|
if self.capital then
|
||||||
|
caps[ self.caps ] = x
|
||||||
|
caps[ self.caps + 1 ] = y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function city:toggleCapital()
|
||||||
|
self.capital = not( self.capital )
|
||||||
|
end
|
||||||
|
|
||||||
|
function t.newCity( tbl )
|
||||||
|
return setmetatable({
|
||||||
|
name = "",
|
||||||
|
country = "",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
pop = 0,
|
||||||
|
capital = false,
|
||||||
|
}, citymt )
|
||||||
|
end
|
||||||
|
|
||||||
function t.load( filename )
|
function t.load( filename )
|
||||||
|
|
||||||
print( "=== LOADING CITIES. ===" )
|
print( "=== LOADING CITIES. ===" )
|
||||||
|
@ -72,7 +114,8 @@ function t.load( filename )
|
||||||
local city = setmetatable({
|
local city = setmetatable({
|
||||||
name = line:sub( 1, 39 ):gsub("%s+$",""),
|
name = line:sub( 1, 39 ):gsub("%s+$",""),
|
||||||
country = line:sub( 42, 82 ):gsub("%s+$",""),
|
country = line:sub( 42, 82 ):gsub("%s+$",""),
|
||||||
x = x, y = y, pop = pop, capital = capital
|
x = x, y = y, pop = pop, capital = capital,
|
||||||
|
n = n, points = idxPts, caps = capital and idxCaps
|
||||||
}, citymt )
|
}, citymt )
|
||||||
cities[n] = city
|
cities[n] = city
|
||||||
n = n + 1
|
n = n + 1
|
||||||
|
|
|
@ -12,7 +12,7 @@ function polygon:formatDisplayInfo()
|
||||||
y: %f
|
y: %f
|
||||||
X: %f
|
X: %f
|
||||||
Y: %f
|
Y: %f
|
||||||
N: %d]]):format( self.x, self.y, self.X, self.Y, #self )
|
Length: %d]]):format( self.x, self.y, self.X, self.Y, #self / 4 )
|
||||||
end
|
end
|
||||||
|
|
||||||
function polygon:drawDirection()
|
function polygon:drawDirection()
|
||||||
|
@ -73,8 +73,9 @@ function t.selectNearest( lines, wx, wy )
|
||||||
poly.X + 5 > wx and
|
poly.X + 5 > wx and
|
||||||
poly.y - 5 < wy and
|
poly.y - 5 < wy and
|
||||||
poly.Y + 5 > wy then
|
poly.Y + 5 > wy then
|
||||||
for k = 1, #poly, 2 do
|
for k = 1, #poly - 3, 4 do
|
||||||
local x, y = poly[k], poly[k + 1]
|
--find the midpoint of each line segment
|
||||||
|
local x, y = 0.5 * (poly[k] + poly[k + 2]), 0.5 * (poly[k + 1] + poly[k + 3])
|
||||||
local r = ( x - wx ) * ( x - wx ) + ( y - wy ) * ( y - wy )
|
local r = ( x - wx ) * ( x - wx ) + ( y - wy ) * ( y - wy )
|
||||||
if r < d then
|
if r < d then
|
||||||
d = r
|
d = r
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
Map editor for DEFCON, the strategy game, written in LOVE2D, the engine.
|
Map editor for DEFCON, the strategy game, written in LOVE2D, the engine.
|
||||||
|
|
||||||
|
Currently does not do anything besides read the files and write them back out.
|
||||||
|
|
||||||
|
Need to make a more structured UI, rewriting menu.lua and button.lua for this purpose.
|
|
@ -4,12 +4,13 @@ local t = {
|
||||||
name = "",
|
name = "",
|
||||||
tooltip = "",
|
tooltip = "",
|
||||||
icon = false,
|
icon = false,
|
||||||
|
lit = false,
|
||||||
x = 8,
|
x = 8,
|
||||||
y = 250,
|
y = 250,
|
||||||
w = 176,
|
w = 13 * 28 - 4,
|
||||||
h = 24,
|
h = 24,
|
||||||
group = "",
|
group = false,
|
||||||
visible = true,
|
visible = false,
|
||||||
callback = function( self ) return print( "clicked button: ", self.name, self.x, self.y, self.w, self.h, self.visible ) end
|
callback = function( self ) return print( "clicked button: ", self.name, self.x, self.y, self.w, self.h, self.visible ) end
|
||||||
}
|
}
|
||||||
t.selected, t.next, t.prev = t, t, t
|
t.selected, t.next, t.prev = t, t, t
|
||||||
|
@ -52,7 +53,7 @@ function t.draw( b )
|
||||||
0,
|
0,
|
||||||
b.h / h )
|
b.h / h )
|
||||||
end
|
end
|
||||||
if t.selected == b then
|
if b.lit or t.selected == b then
|
||||||
b:highlight()
|
b:highlight()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -92,15 +93,27 @@ function t.selectPrevInGroup()
|
||||||
repeat t.selectPrev() until group == t.selected.group
|
repeat t.selectPrev() until group == t.selected.group
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.displayGroup( group, show )
|
--show/hide all buttons in a group
|
||||||
|
--passing hide=true will hide the group, hide=false or nil will show the group
|
||||||
|
--solo=true will hide all buttons outside the group
|
||||||
|
function t.displayGroup( group, hide, solo )
|
||||||
local b = t
|
local b = t
|
||||||
repeat
|
repeat
|
||||||
b = b.next
|
b = b.next
|
||||||
b.visible = ( b.group == group )
|
local inGroup = (group == b.group)
|
||||||
|
if solo or inGroup then
|
||||||
|
b.visible = not(hide) and inGroup
|
||||||
|
end
|
||||||
until b == t
|
until b == t
|
||||||
t.visible = true
|
t.visible = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function t.mousepressed( x, y )
|
||||||
|
if t.selected and t.selected:contains( x, y ) then
|
||||||
|
return t.selected:callback()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function t.deselect( b )
|
function t.deselect( b )
|
||||||
t.selected = t
|
t.selected = t
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,7 @@ local loadLocation = false
|
||||||
local folder = love.graphics.newImage( "icons/load.png" )
|
local folder = love.graphics.newImage( "icons/load.png" )
|
||||||
folder:setFilter( "nearest", "nearest" )
|
folder:setFilter( "nearest", "nearest" )
|
||||||
local loadButton = button.new{
|
local loadButton = button.new{
|
||||||
group = "loadModal",
|
group = t,
|
||||||
name = "load",
|
name = "load",
|
||||||
callback = function()
|
callback = function()
|
||||||
if not loadLocation then return end
|
if not loadLocation then return end
|
||||||
|
@ -25,7 +25,7 @@ local loadButton = button.new{
|
||||||
local xIcon = love.graphics.newImage( "icons/x.png" )
|
local xIcon = love.graphics.newImage( "icons/x.png" )
|
||||||
xIcon:setFilter( "nearest", "nearest" )
|
xIcon:setFilter( "nearest", "nearest" )
|
||||||
local cancelButton = button.new{
|
local cancelButton = button.new{
|
||||||
group = "loadModal",
|
group = t,
|
||||||
name = "cancel load",
|
name = "cancel load",
|
||||||
visible = false,
|
visible = false,
|
||||||
icon = xIcon,
|
icon = xIcon,
|
||||||
|
@ -41,7 +41,7 @@ function t.start()
|
||||||
loadLocation = loadLocation or map.path
|
loadLocation = loadLocation or map.path
|
||||||
button.selected = loadButton
|
button.selected = loadButton
|
||||||
loadButton.name = "save to "..loadLocation
|
loadButton.name = "save to "..loadLocation
|
||||||
button.displayGroup( "loadModal", true )
|
button.displayGroup( t, true )
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.draw()
|
function t.draw()
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
|
||||||
|
local love = assert( love )
|
||||||
|
local lg = assert( love ).graphics
|
||||||
|
local utf8 = require 'utf8'
|
||||||
|
|
||||||
|
local button = require 'ui.button'
|
||||||
|
local textinput = require 'ui.textinput'
|
||||||
|
local modal = require 'ui.modal'
|
||||||
|
local map = require 'map.map'
|
||||||
|
local camera = require 'ui.camera'
|
||||||
|
|
||||||
|
local t = {}
|
||||||
|
local city
|
||||||
|
|
||||||
|
|
||||||
|
local function keypressed( key, code, isRepeat )
|
||||||
|
if code == 'escape' then return modal.current:stop() end
|
||||||
|
if modal.previous then return modal.previous.keypressed( key, code, isRepeat ) end
|
||||||
|
end
|
||||||
|
|
||||||
|
--select modal: as normal, but clicking a city will proceed to the previously selected mode,
|
||||||
|
--and clicking escape will clear the previously selected mode
|
||||||
|
local selectModal = modal.new{}
|
||||||
|
local textModal = modal.new{}
|
||||||
|
local numberModal = modal.new{ cursor = 1 }
|
||||||
|
local editModal = modal.new{ mousepressed = button.mousepressed, keypressed = keypressed, }
|
||||||
|
local moveModal = modal.new{ mousepressed = button.mousepressed, keypressed = keypressed, mousemoved = button.selectIn }
|
||||||
|
local deleteModal = modal.new{ mousepressed = button.mousepressed, keypressed = keypressed }
|
||||||
|
local currentMode
|
||||||
|
|
||||||
|
button.new{ name = "NEW CITY",
|
||||||
|
group = t,
|
||||||
|
icon = lg.newImage("icons/layer-cities.png"),
|
||||||
|
x = 615,
|
||||||
|
y = 0,
|
||||||
|
callback = function()
|
||||||
|
city = map.cities.newCity()
|
||||||
|
return editModal:start()
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
moveModal.button = button.new{ name = "MOVE CITY",
|
||||||
|
group = t,
|
||||||
|
x = 615,
|
||||||
|
y = 28,
|
||||||
|
callback = function( self )
|
||||||
|
self.lit = true
|
||||||
|
selectModal.mode = moveModal
|
||||||
|
return selectModal:start()
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
editModal.button = button.new{ name = "EDIT CITY",
|
||||||
|
group = t,
|
||||||
|
x = 615,
|
||||||
|
y = 28 * 2,
|
||||||
|
callback = function( self )
|
||||||
|
self.lit = true
|
||||||
|
selectModal.mode = editModal
|
||||||
|
return selectModal:start()
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteModal.button = button.new{ name = "DELETE CITY",
|
||||||
|
group = t,
|
||||||
|
x = 615,
|
||||||
|
y = 28 * 3,
|
||||||
|
icon = lg.newImage("icons/x.png"),
|
||||||
|
callback = function( self )
|
||||||
|
self.lit = true
|
||||||
|
selectModal.mode = deleteModal
|
||||||
|
return selectModal:start()
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
--editButtons
|
||||||
|
local function editText( self )
|
||||||
|
print( "editing: ", self.field, city.name )
|
||||||
|
return textModal:start( self.field )
|
||||||
|
end
|
||||||
|
|
||||||
|
local function editNumber( self )
|
||||||
|
local field = self.field
|
||||||
|
end
|
||||||
|
|
||||||
|
local editButtons = {
|
||||||
|
|
||||||
|
save = button.new{
|
||||||
|
icon = lg.newImage( "icons/save.png" ),
|
||||||
|
callback = function() print( "stop editing city" ) return editModal:stop() end,},
|
||||||
|
|
||||||
|
|
||||||
|
name = button.new{ callback = editText },
|
||||||
|
country = button.new{ callback = editText },
|
||||||
|
x = button.new{ callback = editNumber },
|
||||||
|
y = button.new{ callback = editNumber },
|
||||||
|
capital = button.new{ callback = function() if city then return city:toggleCapital() end end },
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
local i = 0
|
||||||
|
for key, b in pairs( editButtons ) do
|
||||||
|
b.field = key
|
||||||
|
b.name = key
|
||||||
|
b.group = editModal
|
||||||
|
b.x = 0
|
||||||
|
b.y = 28 * i
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function editModal:start()
|
||||||
|
modal.start( self )
|
||||||
|
button.displayGroup( self, false, true )
|
||||||
|
for k, b in pairs( editButtons ) do
|
||||||
|
b.name = city[k] or b.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function editModal.draw()
|
||||||
|
return button:draw()
|
||||||
|
end
|
||||||
|
|
||||||
|
function moveModal.update( dt )
|
||||||
|
local x, y = love.mouse.getPosition()
|
||||||
|
if y > 200 and love.mouse.isDown( 1 ) then
|
||||||
|
local wx, wy = camera.GetWorldCoordinate( x, y )
|
||||||
|
city:moveTo( wx, wy )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function moveModal.mousemoved( x, y, dx, dy, istouch )
|
||||||
|
return button.selectIn( x, y )
|
||||||
|
end
|
||||||
|
|
||||||
|
function moveModal.mousepressed( x, y, mouseButton, istouch, presses )
|
||||||
|
if y < 200 then
|
||||||
|
moveModal:stop()
|
||||||
|
return button.mousepressed( x, y, mouseButton, istouch, presses )
|
||||||
|
end
|
||||||
|
if map.selected and mouseButton == 2 then
|
||||||
|
city = map.selected
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function numberModal:start( field )
|
||||||
|
self.field = field
|
||||||
|
return modal.start( self )
|
||||||
|
end
|
||||||
|
|
||||||
|
function numberModal.keypressed( key, code, isrepeat )
|
||||||
|
if code == 'backspace' then end
|
||||||
|
if code == 'escape' then return numberModal:stop() end
|
||||||
|
end
|
||||||
|
|
||||||
|
function numberModal.textinput( char )
|
||||||
|
local str = tostring( city[ numberModal.field ] )
|
||||||
|
local plus = str..char
|
||||||
|
if tonumber( plus ) then
|
||||||
|
city[ numberModal.field ] = plus
|
||||||
|
editButtons[ numberModal.field ].name = plus
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function textModal.textinput( char )
|
||||||
|
print( "text input: ", char )
|
||||||
|
city[textModal.field] = city[textModal.field] .. char
|
||||||
|
editButtons[textModal.field].name = city[textModal.field]
|
||||||
|
end
|
||||||
|
|
||||||
|
function textModal.mousepressed()
|
||||||
|
end
|
||||||
|
|
||||||
|
function textModal:stop()
|
||||||
|
self.field = nil
|
||||||
|
return modal.stop( self )
|
||||||
|
end
|
||||||
|
|
||||||
|
function textModal:start( field )
|
||||||
|
self.field = field
|
||||||
|
return modal.start( self )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function textModal.keypressed( key, code, isRepeat )
|
||||||
|
if code == "backspace" then
|
||||||
|
local text = city[textModal.field]
|
||||||
|
-- get the byte offset to the last UTF-8 character in the string.
|
||||||
|
local byteoffset = utf8.offset(text, -1)
|
||||||
|
print( "textmodal: backspace", byteoffset )
|
||||||
|
|
||||||
|
if byteoffset then
|
||||||
|
-- remove the last UTF-8 character.
|
||||||
|
-- string.sub operates on bytes rather than UTF-8 characters, so we couldn't do string.sub(text, 1, -2).
|
||||||
|
city[textModal.field] = text:sub( 1, byteoffset - 1)
|
||||||
|
editButtons[textModal.field].name = city[textModal.field]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if code == "escape" then
|
||||||
|
return textModal:stop()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function selectModal.keypressed( key, code, isRepeat )
|
||||||
|
if code == 'escape' then return selectModal:stop() end
|
||||||
|
if modal.previous then return modal.previous.keypressed( key, code, isRepeat ) end
|
||||||
|
end
|
||||||
|
|
||||||
|
function selectModal:stop()
|
||||||
|
local mode = selectModal.mode
|
||||||
|
if mode then
|
||||||
|
mode.button.lit = false
|
||||||
|
end
|
||||||
|
return modal.stop( self )
|
||||||
|
end
|
||||||
|
|
||||||
|
function selectModal.mousepressed( x, y, mouseButton, istouch, presses )
|
||||||
|
if y < 200 then
|
||||||
|
selectModal:stop()
|
||||||
|
return button.mousepressed( x, y, mouseButton, istouch, presses )
|
||||||
|
end
|
||||||
|
|
||||||
|
if map.selected then
|
||||||
|
city = map.selected
|
||||||
|
return selectModal.mode:start()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return t
|
|
@ -5,40 +5,44 @@ local savemodal = require 'ui.savemodal'
|
||||||
local loadmodal = require 'ui.loadmodal'
|
local loadmodal = require 'ui.loadmodal'
|
||||||
local Camera = require 'ui.camera'
|
local Camera = require 'ui.camera'
|
||||||
local map = require 'map.map'
|
local map = require 'map.map'
|
||||||
|
local t = {}
|
||||||
|
|
||||||
|
local loadImg = love.graphics.newImage
|
||||||
|
local layers = {
|
||||||
|
{ name = "AF", layer = "africa" , menu = require 'ui.menu.territory' },
|
||||||
|
{ name = "EU", layer = "europe" , menu = require 'ui.menu.territory' },
|
||||||
|
{ name = "NA", layer = "northamerica" , menu = require 'ui.menu.territory' },
|
||||||
|
{ name = "SA", layer = "southamerica" , menu = require 'ui.menu.territory' },
|
||||||
|
{ name = "AS", layer = "southasia" , menu = require 'ui.menu.territory' },
|
||||||
|
{ name = "RU", layer = "russia" , menu = require 'ui.menu.territory' },
|
||||||
|
{ name = "PATH", layer = "travelnodes" , menu = require 'ui.menu.travelnodes', icon = loadImg( "icons/layer-travelnodes.png" )},
|
||||||
|
{ name = "AI", layer = "ainodes" , menu = require 'ui.menu.ainodes', icon = loadImg( "icons/layer-ainodes.png" )},
|
||||||
|
{ name = "CITY", layer = "cities" , menu = require 'ui.menu.cities', icon = loadImg( "icons/layer-cities.png" )},
|
||||||
|
{ name = "COAST", layer = "coastlines" , menu = require 'ui.menu.lines', icon = loadImg( "icons/layer-coastlines.png" )},
|
||||||
|
{ name = "LOW", layer = "coastlinesLow", menu = require 'ui.menu.lines', icon = loadImg( "icons/layer-coastlines-low.png" )},
|
||||||
|
{ name = "INT", layer = "international", menu = require 'ui.menu.lines', icon = loadImg( "icons/layer-international.png" )},
|
||||||
|
{ name = "SAIL", layer = "sailable" , menu = require 'ui.menu.territory', icon = loadImg( "icons/layer-sailable.png" )},
|
||||||
|
}
|
||||||
|
|
||||||
button.new{
|
button.new{
|
||||||
name = "LOAD", x = 250, y = 0,
|
name = "LOAD", x = 250, y = 0,
|
||||||
w = 28 * 13,
|
group = t,
|
||||||
callback = loadmodal.start,
|
callback = loadmodal.start,
|
||||||
icon = love.graphics.newImage( "icons/load.png" )}
|
icon = love.graphics.newImage( "icons/load.png" )}
|
||||||
button.new{
|
button.new{
|
||||||
name = "SAVE", x = 250, y = 28,
|
name = "SAVE", x = 250, y = 28,
|
||||||
w = 28 * 13,
|
group = t,
|
||||||
callback = savemodal.start,
|
callback = savemodal.start,
|
||||||
icon = love.graphics.newImage( "icons/save.png" )}
|
icon = love.graphics.newImage( "icons/save.png" )}
|
||||||
button.new{
|
button.new{
|
||||||
name = "UNDO", x = 250, y = 2 * 28,
|
name = "UNDO", x = 250, y = 2 * 28,
|
||||||
w = 28 * 13,
|
group = t,
|
||||||
callback = map.undo,
|
callback = map.undo,
|
||||||
icon = love.graphics.newImage( "icons/undo.bmp" ) }
|
icon = love.graphics.newImage( "icons/undo.bmp" ) }
|
||||||
|
|
||||||
|
|
||||||
local layers = {
|
local editButtons = {}
|
||||||
{ name = "AF", layer = "africa" },
|
local layerButtons = {}
|
||||||
{ name = "EU", layer = "europe" },
|
|
||||||
{ name = "NA", layer = "northamerica" },
|
|
||||||
{ name = "SA", layer = "southamerica" },
|
|
||||||
{ name = "AS", layer = "southasia" },
|
|
||||||
{ name = "RU", layer = "russia" },
|
|
||||||
{ name = "PATH", layer = "travelnodes" , icon = love.graphics.newImage( "icons/layer-travelnodes.png" )},
|
|
||||||
{ name = "AI", layer = "ainodes" , icon = love.graphics.newImage( "icons/layer-ainodes.png" )},
|
|
||||||
{ name = "CITY", layer = "cities" , icon = love.graphics.newImage( "icons/layer-cities.png" )},
|
|
||||||
{ name = "COAST", layer = "coastlines" , icon = love.graphics.newImage( "icons/layer-coastlines.png" )},
|
|
||||||
{ name = "LOW", layer = "coastlinesLow", icon = love.graphics.newImage( "icons/layer-coastlines-low.png" )},
|
|
||||||
{ name = "INT", layer = "international", icon = love.graphics.newImage( "icons/layer-international.png" )},
|
|
||||||
{ name = "SAIL", layer = "sailable" , icon = love.graphics.newImage( "icons/layer-sailable.png" )},
|
|
||||||
}
|
|
||||||
|
|
||||||
local showButtons = {}
|
local showButtons = {}
|
||||||
local visibilityIcon = love.graphics.newImage( "icons/eye.bmp" )
|
local visibilityIcon = love.graphics.newImage( "icons/eye.bmp" )
|
||||||
local function updateVisibilityIcons()
|
local function updateVisibilityIcons()
|
||||||
|
@ -57,9 +61,17 @@ end
|
||||||
|
|
||||||
local activeLayerButton
|
local activeLayerButton
|
||||||
local function back( self )
|
local function back( self )
|
||||||
self.visible = false
|
activeLayerButton.lit = false
|
||||||
map.setEditLayer()
|
|
||||||
activeLayerButton = nil
|
activeLayerButton = nil
|
||||||
|
map.setEditLayer()
|
||||||
|
button.displayGroup( t, false, true )
|
||||||
|
for i, b in ipairs( editButtons ) do
|
||||||
|
b.visible = true
|
||||||
|
end
|
||||||
|
for i, b in ipairs( showButtons ) do
|
||||||
|
b.visible = true
|
||||||
|
end
|
||||||
|
self.visible = false
|
||||||
return updateVisibilityIcons()
|
return updateVisibilityIcons()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -68,13 +80,18 @@ local backButton = button.new{
|
||||||
visible = false,
|
visible = false,
|
||||||
y = 5 * 28,
|
y = 5 * 28,
|
||||||
x = 250,
|
x = 250,
|
||||||
|
group = false,
|
||||||
icon = love.graphics.newImage( "icons/up.bmp" ),
|
icon = love.graphics.newImage( "icons/up.bmp" ),
|
||||||
callback = back,
|
callback = back,
|
||||||
}
|
}
|
||||||
|
|
||||||
local function editLayer( self )
|
local function editLayer( self )
|
||||||
|
self.lit = true
|
||||||
map.setEditLayer( self.layer )
|
map.setEditLayer( self.layer )
|
||||||
activeLayerButton = self
|
activeLayerButton = self
|
||||||
|
if self.menu then
|
||||||
|
button.displayGroup( self.menu )
|
||||||
|
end
|
||||||
backButton.visible = true
|
backButton.visible = true
|
||||||
return updateVisibilityIcons()
|
return updateVisibilityIcons()
|
||||||
end
|
end
|
||||||
|
@ -86,18 +103,15 @@ local function copy( i, target )
|
||||||
return target
|
return target
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local layerButtons = {}
|
|
||||||
local x = 250
|
local x = 250
|
||||||
local soloButtons = {}
|
|
||||||
local editButtons = {}
|
|
||||||
for i = 1, #layers do
|
for i = 1, #layers do
|
||||||
|
|
||||||
editButtons[i] = button.new( copy( i, {
|
editButtons[i] = button.new( copy( i, {
|
||||||
y = 3 * 28,
|
y = 3 * 28,
|
||||||
x = x + (button.h + 4) * ( i - 1 ),
|
x = x + (button.h + 4) * ( i - 1 ),
|
||||||
w = 24,
|
w = 24,
|
||||||
callback = editLayer,
|
callback = editLayer,
|
||||||
group = "edit",
|
group = editButtons,
|
||||||
tooltip = "edit "..layers[i].layer
|
tooltip = "edit "..layers[i].layer
|
||||||
}))
|
}))
|
||||||
layerButtons[ 2 * i - 2 ] = editButtons[i]
|
layerButtons[ 2 * i - 2 ] = editButtons[i]
|
||||||
|
@ -109,14 +123,13 @@ for i = 1, #layers do
|
||||||
name = "",
|
name = "",
|
||||||
callback = toggleVisibleLayer,
|
callback = toggleVisibleLayer,
|
||||||
icon = visibilityIcon,
|
icon = visibilityIcon,
|
||||||
group = "show",
|
group = showButtons,
|
||||||
tooltip = "show "..layers[i].layer
|
tooltip = "show "..layers[i].layer
|
||||||
}))
|
}))
|
||||||
layerButtons[ 2 * i - 1 ] = showButtons[i]
|
layerButtons[ 2 * i - 1 ] = showButtons[i]
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local t = {}
|
|
||||||
|
|
||||||
function t.draw()
|
function t.draw()
|
||||||
--Status bar.
|
--Status bar.
|
||||||
|
@ -143,16 +156,22 @@ function t.draw()
|
||||||
if map.selected then love.graphics.print( map.selected:formatDisplayInfo(), 0, 80 ) end
|
if map.selected then love.graphics.print( map.selected:formatDisplayInfo(), 0, 80 ) end
|
||||||
if map.selectionLocked then end
|
if map.selectionLocked then end
|
||||||
|
|
||||||
love.graphics.setScissor( 0, 0, love.graphics.getWidth(), 200 )
|
love.graphics.setScissor( 250, 0, love.graphics.getWidth() - 250, 200 )
|
||||||
love.graphics.rectangle( "line", 0, 0 , 250, 200 )
|
love.graphics.rectangle( "line", 0, 0 , 250, 200 )
|
||||||
love.graphics.rectangle( "line", 250, 0, love.graphics.getWidth() - 250, 200 )
|
love.graphics.rectangle( "line", 250, 0, love.graphics.getWidth() - 250, 200 )
|
||||||
|
love.graphics.rectangle( "line", 250, 0, button.w, 200 )
|
||||||
|
|
||||||
|
|
||||||
love.graphics.setColor( 1, 1, 1, 0.8 )
|
love.graphics.setColor( 1, 1, 1, 0.8 )
|
||||||
button:draw()
|
button:draw()
|
||||||
|
|
||||||
love.graphics.setColor( 1, 0, 0, 0.4 )
|
love.graphics.setColor( 1, 0, 0, 0.4 )
|
||||||
if activeLayerButton then activeLayerButton:highlight() end
|
end
|
||||||
|
|
||||||
|
do --button visibility
|
||||||
|
button.displayGroup( t, false, true )
|
||||||
|
button.displayGroup( editButtons, false, false )
|
||||||
|
button.displayGroup( layerButtons, false, false )
|
||||||
|
button.displayGroup( showButtons, false, false )
|
||||||
end
|
end
|
||||||
|
|
||||||
return t
|
return t
|
20
ui/modal.lua
|
@ -5,10 +5,17 @@ t.__index = t
|
||||||
|
|
||||||
local i = 0
|
local i = 0
|
||||||
function t.start( self )
|
function t.start( self )
|
||||||
love.graphics.setScissor( 0, 0, love.graphics.getDimensions() )
|
print( "starting modal:", i + 1)
|
||||||
|
love.graphics.setScissor(
|
||||||
|
self.x or 0,
|
||||||
|
self.y or 0,
|
||||||
|
self.w or love.graphics.getWidth(),
|
||||||
|
self.h or love.graphics.getHeight())
|
||||||
|
|
||||||
i = i + 1
|
i = i + 1
|
||||||
t[i] = t[i] or {}
|
t[i] = { modal = self }
|
||||||
|
t.previous = t[i]
|
||||||
|
t.current = self
|
||||||
|
|
||||||
--store callbacks
|
--store callbacks
|
||||||
for name in pairs( self ) do
|
for name in pairs( self ) do
|
||||||
|
@ -27,10 +34,11 @@ function t.start( self )
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.stop( self )
|
function t.stop( self )
|
||||||
|
print( "stopping modal:", i )
|
||||||
--restore callbacks
|
--restore callbacks
|
||||||
for name in pairs( self ) do
|
for name in pairs( self ) do
|
||||||
if love[name] then
|
if love[name] then
|
||||||
love[name] = t[i][name]
|
love[name] = t[i][name] or love[name]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -39,12 +47,16 @@ function t.stop( self )
|
||||||
button.deselect()
|
button.deselect()
|
||||||
repeat
|
repeat
|
||||||
b = b.next
|
b = b.next
|
||||||
b.visible = t[i][b] or false --accessing a button's nil field is an error, so make sure that b.visible is a boolean
|
b.visible = t[i][b] or false
|
||||||
until b == button
|
until b == button
|
||||||
|
|
||||||
|
|
||||||
|
t.current = t[i].modal
|
||||||
t[i] = nil
|
t[i] = nil
|
||||||
i = i - 1
|
i = i - 1
|
||||||
|
t.previous = t[i - 1]
|
||||||
|
|
||||||
|
love.graphics.setScissor(0, 0, love.graphics.getDimensions())
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.new( modal )
|
function t.new( modal )
|
||||||
|
|
|
@ -8,7 +8,7 @@ local saveLocation = false
|
||||||
local floppy = love.graphics.newImage( "icons/save.png" )
|
local floppy = love.graphics.newImage( "icons/save.png" )
|
||||||
floppy:setFilter( "nearest", "nearest" )
|
floppy:setFilter( "nearest", "nearest" )
|
||||||
local saveButton = button.new{
|
local saveButton = button.new{
|
||||||
group = "saveModal",
|
group = t,
|
||||||
name = "save",
|
name = "save",
|
||||||
callback = function() map.save(); return t:stop() end,
|
callback = function() map.save(); return t:stop() end,
|
||||||
visible = false,
|
visible = false,
|
||||||
|
@ -22,7 +22,7 @@ local saveButton = button.new{
|
||||||
local xIcon = love.graphics.newImage( "icons/x.png" )
|
local xIcon = love.graphics.newImage( "icons/x.png" )
|
||||||
xIcon:setFilter( "nearest", "nearest" )
|
xIcon:setFilter( "nearest", "nearest" )
|
||||||
local cancelButton = button.new{
|
local cancelButton = button.new{
|
||||||
group = "saveModal",
|
group = t,
|
||||||
name = "cancel",
|
name = "cancel",
|
||||||
visible = false,
|
visible = false,
|
||||||
icon = xIcon,
|
icon = xIcon,
|
||||||
|
@ -38,7 +38,7 @@ function t.start()
|
||||||
saveLocation = saveLocation or map.path
|
saveLocation = saveLocation or map.path
|
||||||
button.selected = saveButton
|
button.selected = saveButton
|
||||||
saveButton.name = "save to "..saveLocation
|
saveButton.name = "save to "..saveLocation
|
||||||
button.displayGroup( "saveModal", true )
|
button.displayGroup( t, false, true )
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.draw()
|
function t.draw()
|
||||||
|
|
|
@ -47,16 +47,17 @@ function t.keypressed(key, code, isRepeat)
|
||||||
end
|
end
|
||||||
|
|
||||||
if key == "backspace" then
|
if key == "backspace" then
|
||||||
|
local text = t.currentModal.currentField
|
||||||
-- get the byte offset to the last UTF-8 character in the string.
|
-- get the byte offset to the last UTF-8 character in the string.
|
||||||
local byteoffset = utf8.offset(text, -1)
|
local byteoffset = utf8.offset(text, -1)
|
||||||
|
|
||||||
if byteoffset then
|
if byteoffset then
|
||||||
-- remove the last UTF-8 character.
|
-- remove the last UTF-8 character.
|
||||||
-- string.sub operates on bytes rather than UTF-8 characters, so we couldn't do string.sub(text, 1, -2).
|
-- string.sub operates on bytes rather than UTF-8 characters, so we couldn't do string.sub(text, 1, -2).
|
||||||
text = string.sub(text, 1, byteoffset - 1)
|
t.currentModal.currentField = text:sub( 1, byteoffset - 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if key == "escape" then
|
if code == "escape" then
|
||||||
return t:stop()
|
return t:stop()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|