move UI for horizontal aspect ratio, add load modal and new icons, tweak camera
2
conf.lua
|
@ -12,7 +12,7 @@ function love.conf(t)
|
|||
|
||||
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.width = 800 -- The window width (number)
|
||||
t.window.width = 1000 -- The window width (number)
|
||||
t.window.height = 640 -- The window height (number)
|
||||
t.window.borderless = false -- Remove all border visuals from the window (boolean)
|
||||
t.window.resizable = true -- Let the window be user-resizable (boolean)
|
||||
|
|
BIN
icons/eye.bmp
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 341 B |
After Width: | Height: | Size: 341 B |
After Width: | Height: | Size: 424 B |
After Width: | Height: | Size: 383 B |
After Width: | Height: | Size: 300 B |
After Width: | Height: | Size: 301 B |
After Width: | Height: | Size: 3.1 KiB |
BIN
icons/undo.bmp
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
@ -17,14 +17,7 @@ local exists, mkdir, PATH_SEPARATOR
|
|||
if ffi.os == "Windows" then
|
||||
ffi.cdef[[
|
||||
bool CreateDirectoryA(const char *path, void *lpSecurityAttributes);
|
||||
int _access(const char *path, int mode);
|
||||
]]
|
||||
function exists(path)
|
||||
assert(type(path) == "string", "path isn't a string")
|
||||
local result = C._access(path, 0) -- Check existence
|
||||
return result == 0
|
||||
end
|
||||
|
||||
function mkdir(path, _)
|
||||
assert(type(path) == "string", "path isn't a string")
|
||||
if not C.CreateDirectoryA(path, nil) then
|
||||
|
@ -36,13 +29,7 @@ if ffi.os == "Windows" then
|
|||
elseif ffi.os == "Linux" or ffi.os == "OSX" then
|
||||
ffi.cdef[[
|
||||
int mkdir(const char *path, int mode);
|
||||
int access(const char *path, int amode);
|
||||
]]
|
||||
function exists(path)
|
||||
assert(type(path) == "string", "path isn't a string")
|
||||
local result = C.access(path, 0) -- Check existence
|
||||
return result == 0
|
||||
end
|
||||
function mkdir(path, mode)
|
||||
assert(type(path) == "string", "path isn't a string")
|
||||
local mode = tonumber(mode or "755", 8)
|
||||
|
@ -94,6 +81,18 @@ local function mkdirs(path)
|
|||
end
|
||||
end
|
||||
|
||||
--- Check if a file or directory exists in this path
|
||||
function exists(file)
|
||||
local ok, err, code = os.rename(file, file)
|
||||
if not ok then
|
||||
if code == 13 then
|
||||
-- Permission denied, but it exists
|
||||
return true
|
||||
end
|
||||
end
|
||||
return ok, err
|
||||
end
|
||||
|
||||
return {
|
||||
exists = exists,
|
||||
join = join,
|
||||
|
|
43
main.lua
|
@ -1,9 +1,9 @@
|
|||
local love = assert( love, "This tool requires LOVE: love2d.org" )
|
||||
--assert( require('mobdebug') ).start() --remote debugger
|
||||
local map = require 'map'
|
||||
local button = require 'button'
|
||||
require 'mainmenu'
|
||||
local Camera = require 'camera'
|
||||
local map = require 'map.map'
|
||||
local button = require 'ui.button'
|
||||
local mainmenu = require 'ui.mainmenu'
|
||||
local Camera = require 'ui.camera'
|
||||
|
||||
function love.load()
|
||||
love.filesystem.setIdentity( "dcearth", false )
|
||||
|
@ -44,29 +44,7 @@ function love.draw()
|
|||
map.draw()
|
||||
love.graphics.pop()
|
||||
|
||||
--Status bar.
|
||||
local x, y = love.mouse.getPosition()
|
||||
local wx, wy = Camera.GetWorldCoordinate( x, y )
|
||||
local bx, by = Camera.GetBitmapCoordinate( x, y )
|
||||
local h = love.graphics.getHeight() - 60
|
||||
love.graphics.setColor( 0, 0, 0, 0.9 )
|
||||
love.graphics.rectangle( "fill", 0, 0, 250, love.graphics.getHeight() )
|
||||
love.graphics.setColor( 1, 1, 1, 1 )
|
||||
love.graphics.print(([[
|
||||
SCREEN %-12d %-12d
|
||||
WORLD %-12.2f%-12.2f
|
||||
BITMAP %-12d %-12d
|
||||
%s]]):format(x, y, wx, wy, bx, by, map.editLayer and map.editLayer.filename or ""), 0, 0)
|
||||
|
||||
if map.selected then love.graphics.print( map.selected:formatDisplayInfo(), 0, 80 ) end
|
||||
if map.selectionLocked then end
|
||||
|
||||
|
||||
love.graphics.rectangle( "line", 0, 0 , 250, 218 )
|
||||
love.graphics.rectangle( "line", 0, 218, 250, love.graphics.getHeight() )
|
||||
|
||||
love.graphics.setColor( 1, 1, 1, 0.6 )
|
||||
button:draw()
|
||||
mainmenu.draw()
|
||||
end
|
||||
|
||||
function love.resize(w, h)
|
||||
|
@ -80,8 +58,7 @@ end
|
|||
function love.mousepressed( x, y, mouseButton, istouch, presses )
|
||||
local wx, wy = Camera.GetWorldCoordinate( x, y )
|
||||
|
||||
if button.selected and button.selected:contains( x, y ) then
|
||||
print( ("MOUSE\tx %f\ty %f\twx %f\twy %f"):format(x, y, wx, wy) )
|
||||
if button.selected and button.selected:contains( x, y ) then
|
||||
button.callback( button.selected )
|
||||
return button.selected:callback()
|
||||
end
|
||||
|
@ -101,10 +78,10 @@ end
|
|||
|
||||
function love.keypressed(key, code, isRepeat)
|
||||
|
||||
if code == "left" then return button.selectPrev() end
|
||||
if code == "right" then return button.selectNext() end
|
||||
if code == "down" then return button.selectNextInGroup() end
|
||||
if code == "up" then return button.selectPrevInGroup() end
|
||||
if code == "up" then return button.selectPrev() end
|
||||
if code == "down" then return button.selectNext() end
|
||||
if code == "right" then return button.selectNextInGroup() end
|
||||
if code == "left" then return button.selectPrevInGroup() end
|
||||
if code == "return" then return button.selected:callback() end
|
||||
|
||||
if key == "c" then
|
||||
|
|
142
mainmenu.lua
|
@ -1,142 +0,0 @@
|
|||
|
||||
local love = assert( love )
|
||||
local button = require 'button'
|
||||
local savemodal = require 'savemodal'
|
||||
local map = require 'map'
|
||||
|
||||
button.new{ name = "SAVE", y = 222, callback = savemodal.start, icon = love.graphics.newImage( "icons/save.png" )}
|
||||
button.new{ name = "UNDO", y = 250, callback = map.undo, icon = love.graphics.newImage( "icons/undo.bmp" ) }
|
||||
|
||||
local tools
|
||||
local layerButtons = {}
|
||||
local function back( self )
|
||||
for k, button in pairs( tools ) do button.visible = false end
|
||||
for k, button in pairs( layerButtons ) do button.visible = true end
|
||||
self.visible = false
|
||||
map.editLayer = false
|
||||
end
|
||||
|
||||
local backButton = button.new{
|
||||
name = "UP",
|
||||
visible = false,
|
||||
y = 250 + button.h + 4,
|
||||
icon = love.graphics.newImage( "icons/up.bmp" ),
|
||||
callback = back,
|
||||
}
|
||||
|
||||
local function toolCallback( self )
|
||||
local f = (map.layers[self.layer])[self.name]
|
||||
if f then return f(self) end
|
||||
end
|
||||
|
||||
tools = {
|
||||
button.new{ name = "SELECT"},
|
||||
button.new{ name = "ERASE",},
|
||||
button.new{ name = "MOVE", },
|
||||
button.new{ name = "ADD", },
|
||||
button.new{ name = "EDIT", },
|
||||
button.new{ name = "DRAW", },
|
||||
}
|
||||
for i, v in ipairs( tools ) do
|
||||
v.callback = toolCallback
|
||||
v.y = 250 + (v.h + 4) * ( i + 1 )
|
||||
v.visible = false
|
||||
end
|
||||
|
||||
local layers = {
|
||||
{ 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" },
|
||||
{ name = "AI", layer = "ainodes" },
|
||||
{ name = "CITY", layer = "cities" },
|
||||
{ name = "COAST", layer = "coastlines" },
|
||||
{ name = "LOW", layer = "coastlinesLow"},
|
||||
{ name = "INT", layer = "international"},
|
||||
{ name = "SAIL", layer = "sailable" },
|
||||
}
|
||||
|
||||
local showButtons = {}
|
||||
local visibilityIcon = love.graphics.newImage( "icons/eye.bmp" )
|
||||
local function updateVisibilityIcons()
|
||||
for i = 1, #showButtons do
|
||||
showButtons[i].icon = map.layers[ showButtons[i].layer ].visible and visibilityIcon
|
||||
end
|
||||
end
|
||||
|
||||
local function toggleVisibleLayer( self )
|
||||
if not (self and self.layer) then return end
|
||||
local ml = map.layers[ self.layer ]
|
||||
ml.visible = not( ml.visible )
|
||||
return updateVisibilityIcons()
|
||||
end
|
||||
|
||||
local soloIcon = false--love.graphics.newImage( "icons/eye.bmp" )
|
||||
local function soloVisibleLayer( self )
|
||||
for k, layer in pairs( map.layers ) do
|
||||
print( "invisible layer, map:", k, layer)
|
||||
layer.visible = false
|
||||
end
|
||||
map.layers[ self.layer ].visible = true
|
||||
return updateVisibilityIcons()
|
||||
end
|
||||
|
||||
local function editLayer( self )
|
||||
map.editLayer = map.layers[ self.layer ]
|
||||
map.editLayer.visible = true
|
||||
for k, button in pairs( layerButtons ) do button.visible = false end
|
||||
for k, button in pairs( tools ) do
|
||||
button.visible = true
|
||||
button.layer = self.layer
|
||||
end
|
||||
backButton.visible = true
|
||||
print( "EDITING LAYER", self.layer )
|
||||
return updateVisibilityIcons()
|
||||
end
|
||||
|
||||
local function copy( i, target )
|
||||
for k, v in pairs( layers[i] ) do
|
||||
target[k] = target[k] or v
|
||||
end
|
||||
return target
|
||||
end
|
||||
|
||||
|
||||
local y = 250
|
||||
local soloButtons = {}
|
||||
local editButtons = {}
|
||||
for i = 1, #layers do
|
||||
editButtons[i] = button.new( copy( i, {
|
||||
x = 8,
|
||||
y = y + (button.h + 4) * i,
|
||||
w = 112,
|
||||
callback = editLayer,
|
||||
group = "edit",
|
||||
}))
|
||||
layerButtons[ 3 * i - 2 ] = editButtons[i]
|
||||
|
||||
showButtons[i] = button.new( copy( i, {
|
||||
x = 128,
|
||||
y = y + (button.h + 4) * i,
|
||||
w = 24,
|
||||
name = "",
|
||||
callback = toggleVisibleLayer,
|
||||
icon = visibilityIcon,
|
||||
group = "show",
|
||||
}))
|
||||
layerButtons[ 3 * i - 1 ] = showButtons[i]
|
||||
|
||||
soloButtons[i] = button.new( copy( i, {
|
||||
x = 160,
|
||||
y = y + (button.h + 4) * i,
|
||||
w = 24,
|
||||
name = "S",
|
||||
callback = soloVisibleLayer,
|
||||
icon = soloIcon,
|
||||
group = "solo",
|
||||
}))
|
||||
layerButtons[ 3 * i ] = soloButtons[i]
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
--Manage the AI nodes used by DEFCON.
|
||||
local bmp = require 'bmp'
|
||||
local bmp = require 'map.bmp'
|
||||
local lg = assert( love.graphics )
|
||||
local locationQuery = require 'locationQuery'
|
||||
local locationQuery = require 'map.locationQuery'
|
||||
|
||||
local t = setmetatable( {}, {__index = locationQuery } )
|
||||
local print = print
|
|
@ -6,7 +6,7 @@ local table = table
|
|||
local tonumber = tonumber
|
||||
local lfs = love.filesystem
|
||||
local lg = love.graphics
|
||||
local locationQuery = require 'locationQuery'
|
||||
local locationQuery = require 'map.locationQuery'
|
||||
local cities
|
||||
local points = {}
|
||||
local caps = {}
|
|
@ -87,11 +87,14 @@ function t.selectNearest( lines, wx, wy )
|
|||
end
|
||||
|
||||
function t.save( lines )
|
||||
local str = { "b" }
|
||||
local str = { "b" } --initial B
|
||||
for i, poly in ipairs( lines ) do
|
||||
str[i + 1] = table.concat( poly, " " )
|
||||
end
|
||||
str = table.concat( str, "\nb\n" ):gsub("(%S+) (%S+) ", "%1 %2\n")
|
||||
--concatenate into one big string, one line per polygon
|
||||
--then put each pair of numbers on their own line (without concatenating)
|
||||
--we use CRLF line breaks here because that's what's in the original game files
|
||||
str = table.concat( str, "\13\nb\13\n" ):gsub("(%S+) (%S+) ", "%1 %2\13\n")
|
||||
return str
|
||||
end
|
||||
|
|
@ -2,12 +2,12 @@ local love = assert( love )
|
|||
local io = io
|
||||
local mkdir = assert( require 'lib.mkdir' )
|
||||
local lg = love.graphics
|
||||
local AI = require 'ai'
|
||||
local Cities = require 'cities'
|
||||
local Lines = require 'lines'
|
||||
local Nodes = require 'travelNodes'
|
||||
local Camera = require 'camera'
|
||||
local Territory = require 'territory'
|
||||
local AI = require 'map.ai'
|
||||
local Cities = require 'map.cities'
|
||||
local Lines = require 'map.lines'
|
||||
local Nodes = require 'map.travelNodes'
|
||||
local Camera = require 'ui.camera'
|
||||
local Territory = require 'map.territory'
|
||||
|
||||
--flat list of editable layers for convenience
|
||||
local layers = {
|
||||
|
@ -33,7 +33,7 @@ local map = {
|
|||
selected = false,
|
||||
selectionLocked = false,
|
||||
editLayer = false,
|
||||
|
||||
|
||||
territory = {
|
||||
africa = false,
|
||||
europe = false,
|
||||
|
@ -42,7 +42,7 @@ local map = {
|
|||
southamerica = false,
|
||||
southasia = false
|
||||
},
|
||||
|
||||
|
||||
background = false,
|
||||
coastlines = false,
|
||||
coastlinesLow = false,
|
||||
|
@ -67,7 +67,7 @@ function map.load( path )
|
|||
end
|
||||
map.loaded = true
|
||||
map.path = path
|
||||
|
||||
|
||||
--update references
|
||||
for k, v in pairs( layers ) do
|
||||
layers[k] = map[k] or map.territory[k]
|
||||
|
@ -75,6 +75,7 @@ function map.load( path )
|
|||
end
|
||||
|
||||
function map.draw()
|
||||
love.graphics.setScissor( 0, 200, love.graphics.getWidth(), love.graphics.getHeight() - 200 )
|
||||
lg.clear( 0, 0, 0, 1 )
|
||||
if not map.loaded then return end
|
||||
|
||||
|
@ -192,7 +193,8 @@ end
|
|||
function map.save()
|
||||
--should be cross platform-ish
|
||||
for _, folder in ipairs{ "/data/", "/data/earth/", "/data/graphics/" } do
|
||||
assert( mkdir.exists( map.path ) )
|
||||
--getInfo checks if a directory exists
|
||||
assert( mkdir.exists( map.path ), map.path )
|
||||
local path = map.path..folder
|
||||
if not mkdir.exists( path ) then mkdir.mkdir( path ) end
|
||||
end
|
||||
|
@ -211,4 +213,17 @@ function map.undo()
|
|||
print( "=== UNDO ===" )
|
||||
end
|
||||
|
||||
function map.setEditLayer( layerName )
|
||||
if not layerName then
|
||||
map.editLayer = nil
|
||||
for name, layer in pairs( layers ) do layer.visible = true end
|
||||
else
|
||||
for name, layer in pairs( layers ) do
|
||||
layer.visible = false
|
||||
end
|
||||
map.editLayer = layers[ layerName ]
|
||||
if map.editLayer then map.editLayer.visible = true end
|
||||
end
|
||||
end
|
||||
|
||||
return map
|
|
@ -1,5 +1,5 @@
|
|||
local t = {}
|
||||
local bmp = require 'bmp'
|
||||
local bmp = require 'map.bmp'
|
||||
local lg = assert( love.graphics )
|
||||
|
||||
local colours = {
|
|
@ -2,8 +2,8 @@
|
|||
--This is important for a mapping tool because the DEFCON client will not load a map unless
|
||||
--the pathfinding nodes form a connected graph.
|
||||
|
||||
local bmp = require 'bmp'
|
||||
local locationQuery = require 'locationQuery'
|
||||
local bmp = require 'map.bmp'
|
||||
local locationQuery = require 'map.locationQuery'
|
||||
local lg = assert( love.graphics )
|
||||
|
||||
|
|
@ -2,13 +2,13 @@ local lg = love.graphics
|
|||
|
||||
local t = {
|
||||
name = "",
|
||||
tooltip = "button",
|
||||
tooltip = "",
|
||||
icon = false,
|
||||
x = 8,
|
||||
y = 250,
|
||||
w = 176,
|
||||
h = 24,
|
||||
group = false,
|
||||
group = "",
|
||||
visible = true,
|
||||
callback = function( self ) return print( "clicked button: ", self.name, self.x, self.y, self.w, self.h, self.visible ) end
|
||||
}
|
||||
|
@ -29,13 +29,17 @@ function t.new( b )
|
|||
return b
|
||||
end
|
||||
|
||||
function t.highlight( b )
|
||||
lg.rectangle( "fill", b.x, b.y, b.w, b.h )
|
||||
end
|
||||
|
||||
local drawPassOngoing = false
|
||||
function t.draw( b )
|
||||
if b == t then
|
||||
drawPassOngoing = not( drawPassOngoing )
|
||||
if not drawPassOngoing then return end
|
||||
elseif b.visible then
|
||||
lg.rectangle( "line", b.x, b.y, b.w, b.h, 6 )
|
||||
lg.rectangle( "line", b.x, b.y, b.w, b.h )
|
||||
lg.printf( b.name,
|
||||
b.x + (b.icon and b.h or 0),
|
||||
b.y + 0.5 * ( b.h - lg.getFont():getHeight() ),
|
||||
|
@ -49,7 +53,7 @@ function t.draw( b )
|
|||
b.h / h )
|
||||
end
|
||||
if t.selected == b then
|
||||
lg.rectangle( "fill", b.x, b.y, b.w, b.h, 6 )
|
||||
b:highlight()
|
||||
end
|
||||
end
|
||||
return t.draw( b.next )
|
||||
|
@ -74,7 +78,9 @@ end
|
|||
|
||||
function t.selectNextInGroup()
|
||||
--make sure our group is visible, otherwise the loop doesn't end
|
||||
local group = t.selected and t.selected.visible and t.selected.group
|
||||
local group = t.selected
|
||||
group = group and t.selected.visible
|
||||
group = group and t.selected.group
|
||||
if not group then return t.selectNext() end
|
||||
repeat t.selectNext() until group == t.selected.group
|
||||
end
|
|
@ -3,7 +3,7 @@ local tfTerritory = love.math.newTransform()
|
|||
local tfNodes = love.math.newTransform()
|
||||
local lg = assert( love.graphics )
|
||||
local Camera = {
|
||||
x = -90, y = 45,
|
||||
x = 0, y = 70,
|
||||
w = 360, h = 200,
|
||||
zoom = 1, tf = tf,
|
||||
tfTerritory = tfTerritory, tfNodes = tfNodes }
|
||||
|
@ -37,7 +37,9 @@ end
|
|||
function Camera.Translate( x, y )
|
||||
x = x or 0
|
||||
y = y or 0
|
||||
return Camera.Set( math.max(-180, math.min(360, Camera.x + x)), math.min(100, Camera.y + y), Camera.w, Camera.h)
|
||||
return Camera.Set(
|
||||
math.max(-360, math.min(360, Camera.x + x)),
|
||||
math.max(-140, math.min(140, Camera.y + y)), Camera.w, Camera.h)
|
||||
end
|
||||
|
||||
--In world coordinates: top left corner at x, y, extent of 1/w, 1/h.
|
||||
|
@ -48,14 +50,17 @@ function Camera.Set( x, y, w, h )
|
|||
tf:scale( w / 360, -h / 200 )
|
||||
tf:translate( 180 - x, -y - 100 )
|
||||
|
||||
|
||||
tfTerritory:reset()
|
||||
tfTerritory:scale( w / 512, h / 285 )
|
||||
tfTerritory:translate( -x * 512 / 360, y * 512 / 360 )
|
||||
|
||||
|
||||
tfNodes:reset()
|
||||
tfNodes:scale( w / 360, -h / 200 )
|
||||
tfNodes:translate( 180 - x , -y - 100 )
|
||||
--tfNodes:translate( -x * 800 / 360, y * 400 / 200 )
|
||||
|
||||
end
|
||||
|
||||
function Camera.Resize( w, h )
|
|
@ -0,0 +1,61 @@
|
|||
local love = assert( love )
|
||||
local modal = require( "ui.modal" )
|
||||
local button = require( "ui.button" )
|
||||
local map = require( "map.map" )
|
||||
local t = {}
|
||||
|
||||
local loadLocation = false
|
||||
local folder = love.graphics.newImage( "icons/load.png" )
|
||||
folder:setFilter( "nearest", "nearest" )
|
||||
local loadButton = button.new{
|
||||
group = "loadModal",
|
||||
name = "load",
|
||||
callback = function()
|
||||
if not loadLocation then return end
|
||||
map.load( loadLocation )
|
||||
return t:stop() end,
|
||||
visible = false,
|
||||
icon = folder,
|
||||
x = love.graphics.getWidth() / 2 - 300,
|
||||
y = love.graphics.getHeight() / 2 - 150,
|
||||
w = 600,
|
||||
h = 100,
|
||||
}
|
||||
|
||||
local xIcon = love.graphics.newImage( "icons/x.png" )
|
||||
xIcon:setFilter( "nearest", "nearest" )
|
||||
local cancelButton = button.new{
|
||||
group = "loadModal",
|
||||
name = "cancel load",
|
||||
visible = false,
|
||||
icon = xIcon,
|
||||
callback = function() return t:stop() end,
|
||||
x = love.graphics.getWidth() / 2 - 300,
|
||||
y = love.graphics.getHeight() / 2,
|
||||
w = 600,
|
||||
h = 100
|
||||
}
|
||||
|
||||
function t.start()
|
||||
modal.start( t )
|
||||
loadLocation = loadLocation or map.path
|
||||
button.selected = loadButton
|
||||
loadButton.name = "save to "..loadLocation
|
||||
button.displayGroup( "loadModal", true )
|
||||
end
|
||||
|
||||
function t.draw()
|
||||
love.graphics.clear( 0,0,0,1 )
|
||||
love.graphics.setColor( 0, 0, 1, 0.4 )
|
||||
button:draw()
|
||||
end
|
||||
|
||||
function t.directorydropped( path )
|
||||
loadLocation = path
|
||||
map.path = path
|
||||
loadButton.name = "load from "..map.path
|
||||
return love.filesystem.mount( path, "" )
|
||||
end
|
||||
|
||||
|
||||
return modal.new( t )
|
|
@ -0,0 +1,158 @@
|
|||
|
||||
local love = assert( love )
|
||||
local button = require 'ui.button'
|
||||
local savemodal = require 'ui.savemodal'
|
||||
local loadmodal = require 'ui.loadmodal'
|
||||
local Camera = require 'ui.camera'
|
||||
local map = require 'map.map'
|
||||
|
||||
button.new{
|
||||
name = "LOAD", x = 250, y = 0,
|
||||
w = 28 * 13,
|
||||
callback = loadmodal.start,
|
||||
icon = love.graphics.newImage( "icons/load.png" )}
|
||||
button.new{
|
||||
name = "SAVE", x = 250, y = 28,
|
||||
w = 28 * 13,
|
||||
callback = savemodal.start,
|
||||
icon = love.graphics.newImage( "icons/save.png" )}
|
||||
button.new{
|
||||
name = "UNDO", x = 250, y = 2 * 28,
|
||||
w = 28 * 13,
|
||||
callback = map.undo,
|
||||
icon = love.graphics.newImage( "icons/undo.bmp" ) }
|
||||
|
||||
|
||||
local layers = {
|
||||
{ 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 visibilityIcon = love.graphics.newImage( "icons/eye.bmp" )
|
||||
local function updateVisibilityIcons()
|
||||
for i = 1, #showButtons do
|
||||
showButtons[i].icon = map.layers[ showButtons[i].layer ].visible and visibilityIcon
|
||||
end
|
||||
end
|
||||
|
||||
local function toggleVisibleLayer( self )
|
||||
if not (self and self.layer) then return end
|
||||
local ml = map.layers[ self.layer ]
|
||||
ml.visible = not( ml.visible )
|
||||
return updateVisibilityIcons()
|
||||
end
|
||||
|
||||
|
||||
local activeLayerButton
|
||||
local function back( self )
|
||||
self.visible = false
|
||||
map.setEditLayer()
|
||||
activeLayerButton = nil
|
||||
return updateVisibilityIcons()
|
||||
end
|
||||
|
||||
local backButton = button.new{
|
||||
name = "UP",
|
||||
visible = false,
|
||||
y = 5 * 28,
|
||||
x = 250,
|
||||
icon = love.graphics.newImage( "icons/up.bmp" ),
|
||||
callback = back,
|
||||
}
|
||||
|
||||
local function editLayer( self )
|
||||
map.setEditLayer( self.layer )
|
||||
activeLayerButton = self
|
||||
backButton.visible = true
|
||||
return updateVisibilityIcons()
|
||||
end
|
||||
|
||||
local function copy( i, target )
|
||||
for k, v in pairs( layers[i] ) do
|
||||
target[k] = target[k] or v
|
||||
end
|
||||
return target
|
||||
end
|
||||
|
||||
|
||||
local layerButtons = {}
|
||||
local x = 250
|
||||
local soloButtons = {}
|
||||
local editButtons = {}
|
||||
for i = 1, #layers do
|
||||
editButtons[i] = button.new( copy( i, {
|
||||
y = 3 * 28,
|
||||
x = x + (button.h + 4) * ( i - 1 ),
|
||||
w = 24,
|
||||
callback = editLayer,
|
||||
group = "edit",
|
||||
tooltip = "edit "..layers[i].layer
|
||||
}))
|
||||
layerButtons[ 2 * i - 2 ] = editButtons[i]
|
||||
|
||||
showButtons[i] = button.new( copy( i, {
|
||||
y = 4 * 28,
|
||||
x = x + (button.h + 4) * ( i - 1 ),
|
||||
w = 24,
|
||||
name = "",
|
||||
callback = toggleVisibleLayer,
|
||||
icon = visibilityIcon,
|
||||
group = "show",
|
||||
tooltip = "show "..layers[i].layer
|
||||
}))
|
||||
layerButtons[ 2 * i - 1 ] = showButtons[i]
|
||||
|
||||
end
|
||||
|
||||
local t = {}
|
||||
|
||||
function t.draw()
|
||||
--Status bar.
|
||||
love.graphics.setScissor( 0, 0, 250, 200 )
|
||||
local x, y = love.mouse.getPosition()
|
||||
local wx, wy = Camera.GetWorldCoordinate( x, y )
|
||||
local bx, by = Camera.GetBitmapCoordinate( x, y )
|
||||
local h = love.graphics.getHeight() - 60
|
||||
love.graphics.setColor( 0, 0, 0, 1 )
|
||||
love.graphics.rectangle( "fill", 0, 0, 250, love.graphics.getHeight() )
|
||||
love.graphics.setColor( 1, 1, 1, 1 )
|
||||
love.graphics.print(([[
|
||||
SCREEN %-12d %-12d
|
||||
WORLD %-12.2f%-12.2f
|
||||
BITMAP %-12d %-12d
|
||||
%s
|
||||
%s]]):format(
|
||||
x, y,
|
||||
wx, wy,
|
||||
bx, by,
|
||||
button.selected and button.selected.tooltip or "",
|
||||
map.editLayer and map.editLayer.filename or ""), 0, 0)
|
||||
|
||||
if map.selected then love.graphics.print( map.selected:formatDisplayInfo(), 0, 80 ) end
|
||||
if map.selectionLocked then end
|
||||
|
||||
love.graphics.setScissor( 0, 0, love.graphics.getWidth(), 200 )
|
||||
love.graphics.rectangle( "line", 0, 0 , 250, 200 )
|
||||
love.graphics.rectangle( "line", 250, 0, love.graphics.getWidth() - 250, 200 )
|
||||
|
||||
|
||||
love.graphics.setColor( 1, 1, 1, 0.8 )
|
||||
button:draw()
|
||||
|
||||
love.graphics.setColor( 1, 0, 0, 0.4 )
|
||||
if activeLayerButton then activeLayerButton:highlight() end
|
||||
end
|
||||
|
||||
return t
|
|
@ -1,10 +1,12 @@
|
|||
local love = assert( love )
|
||||
local button = require( "button" )
|
||||
local button = require( "ui.button" )
|
||||
local t = {}
|
||||
t.__index = t
|
||||
|
||||
local i = 0
|
||||
function t.start( self )
|
||||
love.graphics.setScissor( 0, 0, love.graphics.getDimensions() )
|
||||
|
||||
i = i + 1
|
||||
t[i] = t[i] or {}
|
||||
|
||||
|
@ -34,10 +36,10 @@ function t.stop( self )
|
|||
|
||||
--restore menus
|
||||
local b = button
|
||||
button.selected = button
|
||||
button.deselect()
|
||||
repeat
|
||||
b = b.next
|
||||
b.visible = t[i][b]
|
||||
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
|
||||
|
||||
t[i] = nil
|
|
@ -1,7 +1,7 @@
|
|||
local love = assert( love )
|
||||
local modal = require( "modal" )
|
||||
local button = require( "button" )
|
||||
local map = require( "map" )
|
||||
local modal = require( "ui.modal" )
|
||||
local button = require( "ui.button" )
|
||||
local map = require( "map.map" )
|
||||
local t = {}
|
||||
|
||||
local saveLocation = false
|
|
@ -1,6 +1,6 @@
|
|||
local love = assert( love )
|
||||
local utf8 = require("utf8")
|
||||
local modal = require( "modal" )
|
||||
local modal = require( "ui.modal" )
|
||||
local t = modal.new{ }
|
||||
|
||||
function t.setCurrentModal( fields )
|