Compare commits
No commits in common. "1f2899077c7ae4d553ea982cd364b10b28b803e1" and "97f21e192f2c4b533bfd1e1bf21b6549216749ee" have entirely different histories.
1f2899077c
...
97f21e192f
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 = 1024 -- The window width (number)
|
t.window.width = 1000 -- 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)
|
||||||
|
|
BIN
icons/check.png
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 341 B |
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 300 B |
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 301 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.menu.mainmenu'
|
local mainmenu = require 'ui.mainmenu'
|
||||||
local Camera = require 'ui.camera'
|
local Camera = require 'ui.camera'
|
||||||
|
|
||||||
function love.load()
|
function love.load()
|
||||||
|
@ -58,7 +58,10 @@ 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 )
|
||||||
|
|
||||||
return button.mousepressed( x, y )
|
if button.selected and button.selected:contains( x, y ) then
|
||||||
|
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 )
|
||||||
|
@ -86,6 +89,9 @@ function love.keypressed(key, code, isRepeat)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.textinput()
|
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -53,48 +53,6 @@ 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. ===" )
|
||||||
|
@ -114,8 +72,7 @@ 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
|
||||||
Length: %d]]):format( self.x, self.y, self.X, self.Y, #self / 4 )
|
N: %d]]):format( self.x, self.y, self.X, self.Y, #self )
|
||||||
end
|
end
|
||||||
|
|
||||||
function polygon:drawDirection()
|
function polygon:drawDirection()
|
||||||
|
@ -73,9 +73,8 @@ 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 - 3, 4 do
|
for k = 1, #poly, 2 do
|
||||||
--find the midpoint of each line segment
|
local x, y = poly[k], poly[k + 1]
|
||||||
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,5 +1 @@
|
||||||
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,13 +4,12 @@ local t = {
|
||||||
name = "",
|
name = "",
|
||||||
tooltip = "",
|
tooltip = "",
|
||||||
icon = false,
|
icon = false,
|
||||||
lit = false,
|
|
||||||
x = 8,
|
x = 8,
|
||||||
y = 250,
|
y = 250,
|
||||||
w = 13 * 28 - 4,
|
w = 176,
|
||||||
h = 24,
|
h = 24,
|
||||||
group = false,
|
group = "",
|
||||||
visible = false,
|
visible = true,
|
||||||
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
|
||||||
|
@ -53,7 +52,7 @@ function t.draw( b )
|
||||||
0,
|
0,
|
||||||
b.h / h )
|
b.h / h )
|
||||||
end
|
end
|
||||||
if b.lit or t.selected == b then
|
if t.selected == b then
|
||||||
b:highlight()
|
b:highlight()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -93,27 +92,15 @@ function t.selectPrevInGroup()
|
||||||
repeat t.selectPrev() until group == t.selected.group
|
repeat t.selectPrev() until group == t.selected.group
|
||||||
end
|
end
|
||||||
|
|
||||||
--show/hide all buttons in a group
|
function t.displayGroup( group, show )
|
||||||
--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
|
||||||
local inGroup = (group == b.group)
|
b.visible = ( b.group == 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 = t,
|
group = "loadModal",
|
||||||
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 = t,
|
group = "loadModal",
|
||||||
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( t, true )
|
button.displayGroup( "loadModal", true )
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.draw()
|
function t.draw()
|
||||||
|
|
|
@ -5,44 +5,40 @@ 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,
|
||||||
group = t,
|
w = 28 * 13,
|
||||||
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,
|
||||||
group = t,
|
w = 28 * 13,
|
||||||
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,
|
||||||
group = t,
|
w = 28 * 13,
|
||||||
callback = map.undo,
|
callback = map.undo,
|
||||||
icon = love.graphics.newImage( "icons/undo.bmp" ) }
|
icon = love.graphics.newImage( "icons/undo.bmp" ) }
|
||||||
|
|
||||||
|
|
||||||
local editButtons = {}
|
local layers = {
|
||||||
local layerButtons = {}
|
{ name = "AF", layer = "africa" },
|
||||||
|
{ 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()
|
||||||
|
@ -61,17 +57,9 @@ end
|
||||||
|
|
||||||
local activeLayerButton
|
local activeLayerButton
|
||||||
local function back( self )
|
local function back( self )
|
||||||
activeLayerButton.lit = false
|
|
||||||
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
|
self.visible = false
|
||||||
|
map.setEditLayer()
|
||||||
|
activeLayerButton = nil
|
||||||
return updateVisibilityIcons()
|
return updateVisibilityIcons()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -80,18 +68,13 @@ 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
|
||||||
|
@ -103,15 +86,18 @@ local function copy( i, target )
|
||||||
return target
|
return target
|
||||||
end
|
end
|
||||||
|
|
||||||
local x = 250
|
|
||||||
for i = 1, #layers do
|
|
||||||
|
|
||||||
|
local layerButtons = {}
|
||||||
|
local x = 250
|
||||||
|
local soloButtons = {}
|
||||||
|
local editButtons = {}
|
||||||
|
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 = editButtons,
|
group = "edit",
|
||||||
tooltip = "edit "..layers[i].layer
|
tooltip = "edit "..layers[i].layer
|
||||||
}))
|
}))
|
||||||
layerButtons[ 2 * i - 2 ] = editButtons[i]
|
layerButtons[ 2 * i - 2 ] = editButtons[i]
|
||||||
|
@ -123,13 +109,14 @@ for i = 1, #layers do
|
||||||
name = "",
|
name = "",
|
||||||
callback = toggleVisibleLayer,
|
callback = toggleVisibleLayer,
|
||||||
icon = visibilityIcon,
|
icon = visibilityIcon,
|
||||||
group = showButtons,
|
group = "show",
|
||||||
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.
|
||||||
|
@ -156,22 +143,16 @@ 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( 250, 0, love.graphics.getWidth() - 250, 200 )
|
love.graphics.setScissor( 0, 0, love.graphics.getWidth(), 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 )
|
|
||||||
end
|
|
||||||
|
|
||||||
do --button visibility
|
love.graphics.setColor( 1, 0, 0, 0.4 )
|
||||||
button.displayGroup( t, false, true )
|
if activeLayerButton then activeLayerButton:highlight() end
|
||||||
button.displayGroup( editButtons, false, false )
|
|
||||||
button.displayGroup( layerButtons, false, false )
|
|
||||||
button.displayGroup( showButtons, false, false )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return t
|
return t
|
|
@ -1,231 +0,0 @@
|
||||||
|
|
||||||
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
|
|
20
ui/modal.lua
|
@ -5,17 +5,10 @@ t.__index = t
|
||||||
|
|
||||||
local i = 0
|
local i = 0
|
||||||
function t.start( self )
|
function t.start( self )
|
||||||
print( "starting modal:", i + 1)
|
love.graphics.setScissor( 0, 0, love.graphics.getDimensions() )
|
||||||
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] = { modal = self }
|
t[i] = t[i] or {}
|
||||||
t.previous = t[i]
|
|
||||||
t.current = self
|
|
||||||
|
|
||||||
--store callbacks
|
--store callbacks
|
||||||
for name in pairs( self ) do
|
for name in pairs( self ) do
|
||||||
|
@ -34,11 +27,10 @@ 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] or love[name]
|
love[name] = t[i][name]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -47,16 +39,12 @@ function t.stop( self )
|
||||||
button.deselect()
|
button.deselect()
|
||||||
repeat
|
repeat
|
||||||
b = b.next
|
b = b.next
|
||||||
b.visible = t[i][b] or false
|
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
|
||||||
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 = t,
|
group = "saveModal",
|
||||||
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 = t,
|
group = "saveModal",
|
||||||
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( t, false, true )
|
button.displayGroup( "saveModal", true )
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.draw()
|
function t.draw()
|
||||||
|
|
|
@ -47,17 +47,16 @@ 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).
|
||||||
t.currentModal.currentField = text:sub( 1, byteoffset - 1)
|
text = string.sub(text, 1, byteoffset - 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if code == "escape" then
|
if key == "escape" then
|
||||||
return t:stop()
|
return t:stop()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|