dcs-scratchpad/Scripts/Hooks/scratchpad-hook.lua
2019-08-13 22:49:16 +02:00

380 lines
12 KiB
Lua

function scratchpad_load()
package.path = package.path .. ";.\\Scripts\\?.lua;.\\Scripts\\UI\\?.lua;"
local lfs = require("lfs")
local U = require("me_utilities")
local Skin = require("Skin")
local DialogLoader = require("DialogLoader")
local Tools = require("tools")
local Input = require("Input")
local isHidden = true
local keyboardLocked = false
local window = nil
local windowDefaultSkin = nil
local windowSkinHidden = Skin.windowSkinChatMin()
local panel = nil
local textarea = nil
local getCoordsLua =
[[
-- thanks MIST! https://github.com/mrSkortch/MissionScriptingTools/blob/master/mist.lua
local round = function (num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
local tostringLL = function (lat, lon, acc, DMS)
local latHemi, lonHemi
if lat > 0 then
latHemi = 'N'
else
latHemi = 'S'
end
if lon > 0 then
lonHemi = 'E'
else
lonHemi = 'W'
end
lat = math.abs(lat)
lon = math.abs(lon)
local latDeg = math.floor(lat)
local latMin = (lat - latDeg)*60
local lonDeg = math.floor(lon)
local lonMin = (lon - lonDeg)*60
if DMS then -- degrees, minutes, and seconds.
local oldLatMin = latMin
latMin = math.floor(latMin)
local latSec = round((oldLatMin - latMin)*60, acc)
local oldLonMin = lonMin
lonMin = math.floor(lonMin)
local lonSec = round((oldLonMin - lonMin)*60, acc)
if latSec == 60 then
latSec = 0
latMin = latMin + 1
end
if lonSec == 60 then
lonSec = 0
lonMin = lonMin + 1
end
local secFrmtStr -- create the formatting string for the seconds place
if acc <= 0 then -- no decimal place.
secFrmtStr = '%02d'
else
local width = 3 + acc -- 01.310 - that's a width of 6, for example.
secFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
end
return string.format('%02d', latDeg) .. ' ' .. string.format('%02d', latMin) .. '\' ' .. string.format(secFrmtStr, latSec) .. '"' .. latHemi .. ' '
.. string.format('%02d', lonDeg) .. ' ' .. string.format('%02d', lonMin) .. '\' ' .. string.format(secFrmtStr, lonSec) .. '"' .. lonHemi
else -- degrees, decimal minutes.
latMin = round(latMin, acc)
lonMin = round(lonMin, acc)
if latMin == 60 then
latMin = 0
latDeg = latDeg + 1
end
if lonMin == 60 then
lonMin = 0
lonDeg = lonDeg + 1
end
local minFrmtStr -- create the formatting string for the minutes place
if acc <= 0 then -- no decimal place.
minFrmtStr = '%02d'
else
local width = 3 + acc -- 01.310 - that's a width of 6, for example.
minFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
end
return string.format('%02d', latDeg) .. ' ' .. string.format(minFrmtStr, latMin) .. '\'' .. latHemi .. ' '
.. string.format('%02d', lonDeg) .. ' ' .. string.format(minFrmtStr, lonMin) .. '\'' .. lonHemi
end
end
local marks = world.getMarkPanels()
local result = ""
for _, mark in pairs(marks) do
local lat, lon = coord.LOtoLL({
x = mark.pos.z,
y = 0,
z = mark.pos.x
})
local alt = round(land.getHeight({
x = mark.pos.z,
y = mark.pos.x
}), 0)
result = result .. "\n" .. tostringLL(lat, lon, 2, true) .. "\n" .. tostring(alt) .. "m, " .. mark.text .. "\n"
end
return result
]]
local scratchpad = {
logFile = io.open(lfs.writedir() .. [[Logs\Scratchpad.log]], "w")
}
function scratchpad.loadConfiguration()
scratchpad.log("Loading config file...")
local tbl = Tools.safeDoFile(lfs.writedir() .. "Config/ScratchpadConfig.lua", false)
if (tbl and tbl.config) then
scratchpad.log("Configuration exists...")
scratchpad.config = tbl.config
-- config migration
-- add default fontSize config
if scratchpad.config.fontSize == nil then
scratchpad.config.fontSize = 14
scratchpad.saveConfiguration()
end
-- move content into text file
if scratchpad.config.content ~= nil then
scratchpad.saveContent("0000", scratchpad.config.content, false)
scratchpad.config.content = nil
scratchpad.saveConfiguration()
end
else
scratchpad.log("Configuration not found, creating defaults...")
scratchpad.config = {
hotkey = "Ctrl+Shift+x",
windowPosition = {x = 200, y = 200},
windowSize = {w = 350, h = 150},
fontSize = 14
}
scratchpad.saveConfiguration()
end
end
function scratchpad.getContent(name)
local path = lfs.writedir() .. [[Scratchpad\]] .. name .. [[.txt]]
file, err = io.open(path, "r")
if err then
scratchpad.log("Error reading file: " .. path)
return ""
else
local content = file:read("*all")
file:close()
return content
end
end
function scratchpad.saveContent(name, content, override)
lfs.mkdir(lfs.writedir() .. [[Scratchpad\]])
local path = lfs.writedir() .. [[Scratchpad\]] .. name .. [[.txt]]
local mode = "a"
if override then
mode = "w"
end
file, err = io.open(path, mode)
if err then
scratchpad.log("Error writing file: " .. path)
else
file:write(content)
file:flush()
file:close()
end
end
function scratchpad.saveConfiguration()
U.saveInFile(scratchpad.config, "config", lfs.writedir() .. "Config/ScratchpadConfig.lua")
end
function scratchpad.log(str)
if not str then
return
end
if scratchpad.logFile then
scratchpad.logFile:write("[" .. os.date("%H:%M:%S") .. "] " .. str .. "\r\n")
scratchpad.logFile:flush()
end
end
local function unlockKeyboardInput(releaseKeyboardKeys)
if keyboardLocked then
DCS.unlockKeyboardInput(releaseKeyboardKeys)
keyboardLocked = false
end
end
local function lockKeyboardInput()
if keyboardLocked then
return
end
local keyboardEvents = Input.getDeviceKeys(Input.getKeyboardDeviceName())
DCS.lockKeyboardInput(keyboardEvents)
keyboardLocked = true
end
local function insertCoordinates()
local coords = net.dostring_in("server", getCoordsLua)
local lineCountBefore = textarea:getLineCount()
if coords == "" then
textarea:setText(textarea:getText() .. "\nNo marks found\n")
else
textarea:setText(textarea:getText() .. coords .. "\n")
end
-- scroll to the bottom of the textarea
local lastLine = textarea:getLineCount() - 1
local lastLineChar = textarea:getLineTextLength(lastLine)
textarea:setSelectionNew(lastLine, 0, lastLine, lastLineLen)
scratchpad.saveContent("0000", textarea:getText(), true)
end
function scratchpad.createWindow()
window = DialogLoader.spawnDialogFromFile(lfs.writedir() .. "Scripts\\Scratchpad\\ScratchpadWindow.dlg", cdata)
windowDefaultSkin = window:getSkin()
panel = window.Box
textarea = panel.ScratchpadEditBox
insertCoordsBtn = panel.ScratchpadInsertCoordsButton
-- setup textarea
local skin = textarea:getSkin()
skin.skinData.states.released[1].text.fontSize = scratchpad.config.fontSize
textarea:setSkin(skin)
textarea:setText(scratchpad.getContent("0000"))
textarea:addChangeCallback(
function(self)
scratchpad.saveContent("0000", self:getText(), true)
end
)
textarea:addFocusCallback(
function(self)
if self:getFocused() then
lockKeyboardInput()
else
unlockKeyboardInput(true)
end
end
)
textarea:addKeyDownCallback(
function(self, keyName, unicode)
if keyName == "escape" then
self:setFocused(false)
unlockKeyboardInput(true)
end
end
)
-- setup insert coords button
insertCoordsBtn:addMouseDownCallback(
function(self)
insertCoordinates()
end
)
-- setup window
window:setBounds(
scratchpad.config.windowPosition.x,
scratchpad.config.windowPosition.y,
scratchpad.config.windowSize.w,
scratchpad.config.windowSize.h
)
scratchpad.handleResize(window)
window:addHotKeyCallback(
scratchpad.config.hotkey,
function()
if isHidden == true then
scratchpad.show()
else
scratchpad.hide()
end
end
)
window:addSizeCallback(scratchpad.handleResize)
window:addPositionCallback(scratchpad.handleMove)
window:setVisible(true)
scratchpad.hide()
scratchpad.log("Scratchpad Window created")
end
function scratchpad.setVisible(b)
window:setVisible(b)
end
function scratchpad.handleResize(self)
local w, h = self:getSize()
panel:setBounds(0, 0, w, h - 20)
textarea:setBounds(0, 0, w, h - 20 - 20)
insertCoordsBtn:setBounds(0, h - 40, 50, 20)
scratchpad.config.windowSize = {w = w, h = h}
scratchpad.saveConfiguration()
end
function scratchpad.handleMove(self)
local x, y = self:getPosition()
scratchpad.config.windowPosition = {x = x, y = y}
scratchpad.saveConfiguration()
end
function scratchpad.show()
if window == nil then
local status, err = pcall(scratchpad.createWindow)
if not status then
net.log("[Scratchpad] Error creating window: " .. tostring(err))
end
end
window:setVisible(true)
window:setSkin(windowDefaultSkin)
panel:setVisible(true)
window:setHasCursor(true)
isHidden = false
end
function scratchpad.hide()
window:setSkin(windowSkinHidden)
panel:setVisible(false)
textarea:setFocused(false)
window:setHasCursor(false)
-- window.setVisible(false) -- if you make the window invisible, its destroyed
unlockKeyboardInput(true)
isHidden = true
end
function scratchpad.onSimulationFrame()
if scratchpad.config == nil then
scratchpad.loadConfiguration()
end
if not window then
scratchpad.log("Creating Scratchpad window hidden...")
scratchpad.createWindow()
end
end
DCS.setUserCallbacks(scratchpad)
net.log("[Scratchpad] Loaded ...")
end
local status, err = pcall(scratchpad_load)
if not status then
net.log("[Scratchpad] Load Error: " .. tostring(err))
end