290 lines
7.4 KiB
Lua
290 lines
7.4 KiB
Lua
|
|
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{}
|
|
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{ keypressed = keypressed }
|
|
local currentMode
|
|
|
|
button.new{ name = "NEW CITY",
|
|
group = t,
|
|
icon = lg.newImage("icons/city-new.png"),
|
|
x = 615,
|
|
y = 0,
|
|
callback = function()
|
|
city = map.cities.newCity()
|
|
city:add()
|
|
return editModal:start()
|
|
end
|
|
}
|
|
|
|
moveModal.button = button.new{ name = "MOVE CITY",
|
|
group = t,
|
|
icon = lg.newImage("icons/city-move.png"),
|
|
x = 615,
|
|
y = button.h + 4,
|
|
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 = (button.h + 4) * 2,
|
|
callback = function( self )
|
|
self.lit = true
|
|
selectModal.mode = editModal
|
|
return selectModal:start()
|
|
end,
|
|
}
|
|
|
|
deleteModal.button = button.new{ name = "DELETE CITY",
|
|
group = t,
|
|
icon = lg.newImage("icons/city-delete.png"),
|
|
x = 615,
|
|
y = (button.h + 4) * 3,
|
|
callback = function( self )
|
|
self.lit = true
|
|
return deleteModal:start()
|
|
end,
|
|
}
|
|
|
|
--editButtons
|
|
local function editText( self )
|
|
print( "editing: ", self.field, city.name )
|
|
self.lit = true
|
|
return textModal:start( self.field )
|
|
end
|
|
|
|
local function editNumber( self )
|
|
print( "editing: ", self.field, city.name )
|
|
self.lit = true
|
|
return numberModal:start( self.field )
|
|
end
|
|
|
|
local editButtons = {
|
|
|
|
save = button.new{
|
|
icon = lg.newImage( "icons/check.png" ),
|
|
callback = function() 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( self )
|
|
if city then
|
|
self.name = tostring( not( city.capital ) )
|
|
return city:toggleCapital()
|
|
end
|
|
end },
|
|
}
|
|
|
|
do
|
|
local i = 0
|
|
for _, key in ipairs{ "save", "name", "country", "x", "y", "capital" } do
|
|
local b = assert( editButtons[ key ] )
|
|
b.align = "right"
|
|
b.field = key
|
|
b.name = tostring( key ) --bools must be cast to string before getting passed to printf
|
|
b.group = editModal
|
|
b.x = lg.getWidth() / 2 - button.w / 2
|
|
b.y = (button.h + 4) * 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 = tostring( city[k] or b.name )
|
|
end
|
|
if city.capital == false then editButtons.capital.name = "false" end
|
|
end
|
|
|
|
function editModal:stop()
|
|
return modal.stop( self )
|
|
end
|
|
|
|
function editModal.draw()
|
|
lg.setColor( 1, 1, 1, 0.5 )
|
|
return button:draw()
|
|
end
|
|
|
|
function editModal.resize( w, h )
|
|
local i = 0
|
|
local high = h / 6
|
|
for key, b in pairs( editButtons ) do
|
|
b.x = w / 2 - button.w / 2
|
|
b.y = ( high + 4 ) * i
|
|
b.h = high
|
|
i = i + 1
|
|
end
|
|
end
|
|
|
|
function moveModal.update( dt )
|
|
local x, y = love.mouse.getPosition()
|
|
if y > t.menuHeight 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 < t.menuHeight 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 deleteModal.mousepressed( x, y, mouseButton, istouch, presses )
|
|
if map.selected then
|
|
map.selected:delete()
|
|
end
|
|
if y < t.menuHeight then
|
|
deleteModal.button.lit = false
|
|
deleteModal:stop()
|
|
return button.mousepressed( x, y, mouseButton, istouch, presses )
|
|
end
|
|
end
|
|
|
|
|
|
function numberModal:start( field )
|
|
self.field = field
|
|
return modal.start( self )
|
|
end
|
|
|
|
function numberModal.keypressed( key, code, isrepeat )
|
|
if code == "backspace" then
|
|
local text = tostring( city[numberModal.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).
|
|
local newstr = text:sub( 1, byteoffset - 1)
|
|
if newstr == "" then newstr = 0 end
|
|
city[numberModal.field] = tonumber( newstr ) or city[numberModal.field]
|
|
editButtons[numberModal.field].name = city[numberModal.field]
|
|
end
|
|
end
|
|
if code == "escape" or code == "return" then
|
|
return numberModal:stop()
|
|
end
|
|
end
|
|
|
|
function numberModal.textinput( char )
|
|
local str = tostring( city[ numberModal.field ] )
|
|
local plus = str..char
|
|
print( "text input: ", 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" or code == "return" 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 < t.menuHeight 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
|
|
|
|
function t.setMenuHeight( h )
|
|
t.menuHeight = h
|
|
end
|
|
|
|
return t |