Last active
October 28, 2025 13:59
-
-
Save SofieBrink/5829fff6c04a2dd9de37b93a5b46f292 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // !runscript c6989efbfa4a6abb323f66ac631ae3be | |
| // Sofie's Universal Display Bootfile Version | |
| //------------------------------------------------------------------------------------------------- | |
| // Usage Description. Parameters with {OPT} infront can be left out. | |
| // FormatTime(input) - Function to format a time in seconds to a 24 hour human-readable clock format | |
| //------------------------------------------------------------------------------------------------- | |
| // Variables | |
| global UD_Widgets is lexicon(). | |
| global UD_DecimalString is "". | |
| set UD_Path to "1:/UniversalDisplay/". | |
| set UD_Active to true. | |
| set UD_Reboot to false. | |
| set UD_HelperIndex to 0. | |
| set UD_RefreshRate to 20. | |
| set UD_HideOnInactive to true. | |
| set UD_TrainingWheels to true. | |
| set UD_WidgetIndex to 0. | |
| set EmptyList to ship:partsnamed("THIS PART WILL NEVER EXIST, I JUST NEED AN EMPTY LIST"). | |
| EmptyList:clear(). | |
| // datastructure: | |
| // UD_Widgets | |
| // lex { | |
| // key: 0, value: | |
| // lex { | |
| // key: x, value: 200 | |
| // key: y, value: 200 | |
| // key: width, value: 250 | |
| // key: background, value: "" | |
| // key: displayname, value: "Left Widget" | |
| // key: fontsize, value: 16 | |
| // key: gui, value: | |
| // lex { | |
| // key: gui, value: guiElement | |
| // key: contents, value: | |
| // list { | |
| // lex { | |
| // key: layout, value: layoutElement | |
| // key: contents, value: | |
| // list { | |
| // labelElement, | |
| // labelElement | |
| // } | |
| // }, | |
| // lex { | |
| // key: layout, value layoutElement | |
| // key: contents, value: | |
| // list { | |
| // someElement | |
| // } | |
| // }, | |
| // lex { | |
| // key: layout, value: layoutElement | |
| // key: contents, value: | |
| // list { | |
| // labelElement, | |
| // labelElement | |
| // } | |
| // }, | |
| // lex { | |
| // key: layout, value layoutElement | |
| // key: contents, value: | |
| // list { | |
| // someElement | |
| // } | |
| // }, | |
| // lex { | |
| // key: layout, value: layoutElement | |
| // key: contents, value: | |
| // list { | |
| // labelElement, | |
| // labelElement | |
| // } | |
| // } | |
| // } | |
| // } | |
| // key: contents, value: | |
| // list { | |
| // lex { | |
| // key: type, value: "item" | |
| // key: label, value: "Vessel" | |
| // key: prefix, value: "", | |
| // key: postfix, value: "", | |
| // key: decimaldigits, value: 0, | |
| // key: value, value: {return ship:name.}, | |
| // key: stringvalue, value: "{return ship:name.}" | |
| // }, | |
| // lex { | |
| // key: type, value: "seperator" | |
| // }, | |
| // lex { | |
| // key: type, value: "item" | |
| // key: label, value: "Apoapsis" | |
| // key: prefix, value: "", | |
| // key: postfix, value: "Km", | |
| // key: decimaldigits, value: 2, | |
| // key: value, value: {return ship:apoapsis.}, | |
| // key: stringvalue, value: "{return ship:apoapsis.}" | |
| // }, | |
| // lex { | |
| // key: type, value: "spacer" | |
| // }, | |
| // lex { | |
| // key: type, value: "item" | |
| // key: label, value: "Periapsis" | |
| // key: prefix, value: "", | |
| // key: postfix, value: "Km", | |
| // key: decimaldigits, value: 2, | |
| // key: value, value: {return ship:periapsis.}, | |
| // key: stringvalue, value: "{return ship:periapsis.}" | |
| // } | |
| // } | |
| // } | |
| // } | |
| // TODO | |
| // Colours low prio | |
| // Allow hiding and showing specific widgets, maybe via delegate so a widget can be dynamically shown or hidden. | |
| // same as above but for lines, such ETA transition if the orbit has a transition | |
| // Auto shutdown on low power | |
| // Bugs | |
| // widgets get garbage collected on docking? | |
| //------------------------------------------------------------------------------------------------- | |
| // Helper Functions | |
| global function FormatTime { | |
| // Function to format a time in seconds to a 24 hour human-readable clock format | |
| parameter input. | |
| if (not input:typename = "scalar") return. | |
| local result is choose "-" if input < 0 else "". | |
| set input to abs(input). | |
| local years is floor(input / (3600 * 24 * 365)). | |
| local days is floor(mod(input / (3600 * 24), 365)). | |
| local hours is floor(mod(input / 3600, 24)). | |
| local minutes is floor((mod(input, 3600)) / 60). | |
| local seconds is round(mod(input, 60), 1). | |
| if (years > 1e3) return result + "Infinity". | |
| if (years <> 0) { | |
| set result to result + years + "y ". | |
| } | |
| if (days <> 0 OR years <> 0) { | |
| set result to result + days + "d ". | |
| } | |
| if ((hours <> 0 OR days <> 0) AND years = 0) { | |
| set result to result + hours + "h ". | |
| } | |
| if ((minutes <> 0 OR hours <> 0) AND days = 0) AND years = 0 { | |
| set result to result + minutes + "m ". | |
| } | |
| if (hours = 0 AND days = 0 AND years = 0 AND minutes <> 0) { | |
| set result to result + round(seconds) + "s". | |
| } | |
| else if (hours = 0 AND days = 0 AND minutes = 0 AND years = 0) { | |
| set result to result + (seconds + ".0"):substring(0, choose 3 if seconds < 10 else 4) + "s". | |
| } | |
| return result. | |
| } | |
| global function FormatSI { | |
| // Function to format an SI unit depending on its size. | |
| parameter input, unit, decimalDigits is 2, fullPrefix is false. | |
| if (not input:typename = "scalar") return. | |
| if (not unit:typename = "string") return. | |
| if (not decimalDigits:typename = "scalar" OR decimalDigits < 0) return. | |
| if (not fullPrefix:typename = "boolean") return. | |
| if (decimalDigits > UD_DecimalString:length) { local decimals is "". for i in range(decimalDigits) set decimals to decimals + "0". set UD_DecimalString to decimals.} | |
| local result is "". | |
| local postfix is "</color>". | |
| set result to result + (choose "-" if input < 0 else ""). | |
| set input to abs(input). | |
| local prefixes is lex( | |
| "Tera", input * 1e-12, | |
| "Giga", input * 1e-9, | |
| "Mega", input * 1e-6, | |
| "Kilo", input * 1e-3, | |
| "", input, | |
| "centi", input * 1e2, | |
| "milli", input * 1e3). | |
| for key in prefixes:keys { | |
| //print key + " val " + prefixes[key]. | |
| if (prefixes[key] >= 1 OR key = prefixes:keys[prefixes:keys:length - 1]) { | |
| local value is round(prefixes[key], decimalDigits):tostring(). | |
| local decimals is (choose "" if value:contains(".") OR decimalDigits = 0 else ".") + UD_DecimalString. | |
| set value to (value + decimals):substring(0, value:split(".")[0]:length + decimalDigits + (choose 1 if decimalDigits > 0 else 0)). | |
| return result + value + "<color=white> " + (choose key:substring(0, 1) if (key:length > 0 AND not(fullPrefix)) else key) + (choose unit:substring(0, 1) if (unit:length > 0 AND not(fullPrefix)) else unit) + postfix. | |
| } | |
| } | |
| } | |
| //------------------------------------------------------------------------------------------------- | |
| // Internal Helper Functions | |
| function UD_Print { | |
| // Function to allow printing of messages to the HUD for display with a closed terminal. | |
| parameter message. | |
| parameter type is "Info". | |
| parameter short is true. | |
| //print (choose "UD " if (short) else "Universal Display ") + type + ": " + message. | |
| HUDTEXT((choose "UD " if (short) else "Universal Display ") + type + ": " + message | |
| , 15 // Show for 5 seconds | |
| , 2 // Upper right hand corner | |
| , 24 // Font Size | |
| , WHITE // Print in white | |
| , true // Also print to the terminal for good measure | |
| ). | |
| } | |
| function UD_TestErrors { | |
| // Function to test if there's any errors present and to print them. | |
| parameter listing, type is "Error". | |
| if (listing:length > 0) { | |
| for li in listing { | |
| UD_Print(li, type). | |
| } | |
| return false. | |
| } | |
| return true. | |
| } | |
| function UD_ValidateWidget { | |
| // Function to test if a given widgetLex is valid. | |
| parameter widget. | |
| local errors is EmptyList:copy. | |
| if (not(widget:haskey("DisplayName"))) errors:add("Item:DisplayName is empty"). | |
| else if (widget["DisplayName"]:typename <> "string") errors:add("Item:DisplayName is not a string."). | |
| if (not(widget:haskey("Background"))) set widget["Background"] to "". | |
| else if (widget["Background"]:typename <> "string") errors:add("Item:Background is not a string."). | |
| if (not(widget:haskey("Width"))) set widget["Width"] to 250. | |
| else if (widget["Width"]:typename <> "scalar") errors:add("Item:Width is not a scalar."). | |
| if (not(widget:haskey("X"))) set widget["X"] to -60. | |
| else if (widget["X"]:typename <> "scalar") errors:add("Item:X is not a scalar."). | |
| if (not(widget:haskey("Y"))) set widget["Y"] to 550. | |
| else if (widget["Y"]:typename <> "scalar") errors:add("Item:Y is not a scalar."). | |
| if (not(widget:haskey("FontSize"))) set widget["FontSize"] to 16. | |
| else if (widget["FontSize"]:typename <> "scalar") errors:add("Item:FontSize is not a scalar."). | |
| if (widget:haskey("Contents") AND widget["Contents"]:typename <> "list") errors:add("Item:Contents is not a list."). | |
| return lex("widget", widget, "errors", errors). | |
| } | |
| function UD_ValidateLine { | |
| // Function to test if a given lineLex is valid. | |
| parameter line. | |
| local errors is EmptyList:copy. | |
| if (not(line:haskey("Type"))) set line["Type"] to "item". | |
| else if (line["Type"]:typename <> "string") errors:add("Item:Type is not a string."). | |
| if (line["Type"] = "item") { | |
| if (not(line:haskey("Label"))) errors:add("Item:Label is empty"). | |
| else if (line["Label"]:typename <> "string") errors:add("Item:Label is not a string."). | |
| if (not(line:haskey("Prefix"))) set line["Prefix"] to "". | |
| else if (line["Prefix"]:typename <> "string") errors:add("Item:Prefix is not a string."). | |
| if (not(line:haskey("Postfix"))) set line["Postfix"] to "". | |
| else if (line["Postfix"]:typename <> "string") errors:add("Item:Postfix is not a string."). | |
| if (not(line:haskey("DecimalDigits"))) set line["DecimalDigits"] to 0. | |
| else if (line["DecimalDigits"]:typename <> "scalar") errors:add("Item:DecimalDigits is not a scalar."). | |
| // Validate delegate as much as possible. | |
| if (line:haskey("Value") | |
| AND line["Value"]:typename = "string" | |
| AND line["Value"]:length >= 2 | |
| AND line["Value"][0] = "{" | |
| AND line["Value"][line["Value"]:length - 1] = "}" | |
| AND UD_TrainingWheels | |
| ) { | |
| // Split delegate into components. | |
| local knownDirectives is EmptyList:copy. | |
| knownDirectives:add("set"). | |
| knownDirectives:add("lock"). | |
| knownDirectives:add("local"). | |
| knownDirectives:add("global"). | |
| knownDirectives:add("return"). | |
| knownDirectives:add("for"). | |
| knownDirectives:add("if"). | |
| local statements is EmptyList:copy. | |
| statements:add(""). | |
| local inString is false. | |
| for char in line["Value"]:substring(1, line["Value"]:length - 2) { | |
| set statements[statements:length-1] to statements[statements:length-1] + char. | |
| if (char = char(34)) toggle inString. | |
| if (not(inString) AND char = char(46)) { | |
| set statements[statements:length-1] to statements[statements:length-1]:trim(). | |
| statements:add(""). | |
| } | |
| } | |
| if (statements[statements:length-1]:length = 0) | |
| statements:remove(statements:length-1). | |
| for statement in statements { | |
| if (not(statement:endswith("."))) | |
| errors:add("Item:Value does not end with a period"). | |
| if (statement:contains("{") OR statement:contains("}")) { | |
| errors:add("Item:Value statement contains a nested delegate"). | |
| // Nested Delegates are currently unsupported | |
| } | |
| if not(knownDirectives:contains(statement:split(" ")[0])) { | |
| errors:add("Item:Value statement has an unknown or disallowed directive."). | |
| } | |
| } | |
| if (not(statements[statements:length-1]:startswith("return "))) { | |
| errors:add("Item:Value does not end with a return statement."). | |
| } | |
| } | |
| else if (UD_TrainingWheels) { | |
| if (line:haskey("Value")) errors:add("Item:Value is not a stringified delegate."). | |
| else errors:add("Item:Value is empty."). | |
| } | |
| } | |
| else if (line["Type"] <> "spacer" AND line["Type"] <> "seperator") errors:add("Item:Type " + line["Type"] + " is unkown."). | |
| return lex("line", line, "errors", errors). | |
| } | |
| function UD_FindWidget { | |
| // Function to find the widget that matches the provided index or display name, returns false if no or multiple matches exist. | |
| parameter dub. | |
| local matchingItems is EmptyList:copy. | |
| for w in UD_Widgets:keys { | |
| if (dub:typename = "scalar" AND w = dub) { | |
| matchingItems:add(w). | |
| } | |
| else if (dub:typename = "string" and UD_Widgets[w]["DisplayName"] = dub) { | |
| matchingItems:add(w). | |
| } | |
| } | |
| if (matchingItems:length = 1) { | |
| return matchingItems[0]. | |
| } | |
| else { | |
| return false. | |
| } | |
| } | |
| function UD_ListWidgets { | |
| // Function to display all the existing widgets in a hud message. | |
| UD_Print("Active Widgets:"). | |
| for key in UD_Widgets:keys { | |
| HUDTEXT(key + ": " + UD_Widgets[key]["DisplayName"] | |
| , 15 // Show for 5 seconds | |
| , 2 // Upper right hand corner | |
| , 24 // Font Size | |
| , WHITE // Print in white | |
| , true // Also print to the terminal for good measure | |
| ). | |
| } | |
| } | |
| function UD_RunHelper { | |
| // Function to write to and run the helper file. | |
| parameter command. | |
| log command to UD_Path + "UniversalDisplayHelper" + UD_HelperIndex + ".ks". | |
| runpath(UD_Path + "UniversalDisplayHelper" + UD_HelperIndex + ".ks"). | |
| deletePath(UD_Path + "UniversalDisplayHelper" + UD_HelperIndex + ".ks"). | |
| set UD_HelperIndex to UD_HelperIndex + 1. | |
| } | |
| function UD_DeleteData { | |
| // Function to help remove data from the saved file and the active list. | |
| parameter widgetIndex, lineIndexes is EmptyList:copy, deleteWidget is false. | |
| local widgetDub is "UD_Widgets:add(" + widgetIndex + ", ". | |
| local lineDub is "UD_Widgets[" + widgetIndex + "][" + char(34) + "Contents" + char(34) + "]:add(". | |
| local file is open(UD_Path + "UniversalDisplayValues.ks"). | |
| local fileContents is file:readall(). | |
| local index is 0. | |
| file:clear(). | |
| for line in fileContents { | |
| if (line:contains(widgetDub) AND deleteWidget) { | |
| // don't save. | |
| } | |
| else if (line:contains(lineDub)) { | |
| if (deleteWidget OR lineIndexes:contains(index)) { | |
| // don't save. | |
| } | |
| else { | |
| file:writeln(line). | |
| } | |
| set index to index + 1. | |
| } | |
| else { | |
| file:writeln(line). | |
| } | |
| } | |
| if (deleteWidget) { | |
| UD_Widgets[widgetIndex]["GUI"]["GUI"]:dispose(). | |
| UD_Widgets:remove(widgetIndex). | |
| } | |
| else { | |
| for i in lineIndexes { | |
| UD_Widgets[widgetIndex]["GUI"]["Contents"][i]["Layout"]:dispose(). | |
| UD_Widgets[widgetIndex]["GUI"]["Contents"]:remove(i). | |
| UD_Widgets[widgetIndex]["Contents"]:remove(i). | |
| } | |
| } | |
| } | |
| function UD_EditData { | |
| // function to edit one line of the saved file | |
| parameter dub, newline. | |
| local file is open(UD_Path + "UniversalDisplayValues.ks"). | |
| local fileContents is file:readall(). | |
| local index is 0. | |
| file:clear(). | |
| for line in fileContents { | |
| if (line:contains(dub)) { | |
| file:writeln(newline). | |
| } | |
| else { | |
| file:writeln(line). | |
| } | |
| } | |
| } | |
| function UD_ConstructWidgetCommand { | |
| // function to make a command to save the widget. | |
| parameter index, commandLex. | |
| local command is "". | |
| set command to "UD_Widgets:add(" + index + ", lex(". | |
| set command to command + char(34) + "DisplayName" + char(34) + ", " + char(34) + commandLex["DisplayName"] + char(34) + ", ". | |
| set command to command + char(34) + "Background" + char(34) + ", " + char(34) + commandLex["Background"] + char(34) + ", ". | |
| set command to command + char(34) + "Width" + char(34) + ", " + commandLex["Width"] + ", ". | |
| set command to command + char(34) + "X" + char(34) + ", " + commandLex["X"] + ", ". | |
| set command to command + char(34) + "Y" + char(34) + ", " + commandLex["Y"] + ", ". | |
| set command to command + char(34) + "FontSize" + char(34) + ", " + commandLex["FontSize"] + ", ". | |
| set command to command + char(34) + "Contents" + char(34) + ", " + "list()". | |
| set command to command + ")).". | |
| return command. | |
| } | |
| function UD_GenerateSeperatorString { | |
| // function to generate a seperator string of the right length. | |
| parameter width, fontSize. | |
| local seperatorText is "<color=white>". | |
| for d in range(floor(width / (fontSize * 0.825))) { | |
| set seperatorText to seperatorText + char(8213). | |
| } | |
| return seperatorText + "</color>". | |
| } | |
| //------------------------------------------------------------------------------------------------- | |
| // Internal Functions | |
| function UD_Loop { | |
| // Function to start the internal loop to that will call functions to continually update the widgets. | |
| on floor(time:seconds * UD_RefreshRate) { | |
| UD_HandleMessages(). | |
| UD_UpdateWidgets(). | |
| return UD_Active. | |
| } | |
| wait until (not(UD_Active)). | |
| UD_Save(). | |
| clearGuis(). | |
| if (UD_Reboot) reboot. | |
| } | |
| function UD_Save { | |
| // Function to save the settings to a json file for loading on the next reboot. | |
| local settingsLex is lexicon( | |
| "UD_WidgetIndex", UD_WidgetIndex, | |
| "UD_RefreshRate", UD_RefreshRate, | |
| "UD_HideOnInactive", UD_HideOnInactive, | |
| "UD_TrainingWheels", UD_TrainingWheels | |
| ). | |
| writeJson(settingsLex, UD_Path + "UniversalDisplaySettings.json"). | |
| } | |
| function UD_Load { | |
| // Function to load the settings from the json file, validate the exit state and load the widgets from storage. | |
| if (homeConnection:isconnected) { | |
| if (core:bootfilename = "boot/UniversalDisplay.ks" AND exists("0:/UniversalDisplay.ks")) copypath("0:/UniversalDisplay.ks", "1:/boot/UniversalDisplay.ks"). | |
| else if (exists("0:/UniversalDisplay.ksm")) { | |
| copypath("0:/UniversalDisplay.ksm", "1:/boot/UniversalDisplay.ksm"). | |
| if (not(core:bootfilename = "boot/UniversalDisplay.ksm")) set core:bootfilename to "boot/UniversalDisplay.ksm". | |
| } | |
| else { | |
| UD_Print("Archive is accessible but source files were not found!", "Warning"). | |
| } | |
| } | |
| if (exists(UD_Path)) { | |
| cd(UD_Path). | |
| list files in fileList. | |
| for file in fileList { | |
| if file:name:contains("UniversalDisplayHelper") and file:extension = "ks" { | |
| UD_Print("Helper file detected indicating a possible syntax error on previous run!", "Warning"). | |
| deletepath(UD_Path + file:name). | |
| } | |
| else if (file:name = "UniversalDisplaySettings.json") { | |
| local settingsLex is readJson(UD_Path + "UniversalDisplaySettings.json"). | |
| if (settingsLex:haskey("UD_WidgetIndex")) set UD_WidgetIndex to settingsLex["UD_WidgetIndex"]. | |
| if (settingsLex:haskey("UD_RefreshRate")) set UD_RefreshRate to settingsLex["UD_RefreshRate"]. | |
| if (settingsLex:haskey("UD_HideOnInactive")) set UD_HideOnInactive to settingsLex["UD_HideOnInactive"]. | |
| if (settingsLex:haskey("UD_TrainingWheels")) set UD_TrainingWheels to settingsLex["UD_TrainingWheels"]. | |
| UD_Print("Loaded settings from disk"). | |
| } | |
| else if (file:name = "UniversalDisplayValues.ks") { | |
| runPath(UD_Path + "UniversalDisplayValues.ks"). | |
| } | |
| } | |
| if (not(exists(UD_Path + "UniversalDisplayValues.ks")) AND exists(UD_Path + "UniversalDisplayValues_Backup.ks")) | |
| { | |
| UD_Print("Backup file found without main file. Recovering from backup."). | |
| runPath(UD_Path + "UniversalDisplayValues_Backup.ks"). | |
| } | |
| cd("1:/"). | |
| } | |
| } | |
| function UD_Backup { | |
| // Function to create a backup of the current UniversalDisplayValues, incase something goes terribly wrong. | |
| if (exists(UD_Path + "UniversalDisplayValues.ks")) { | |
| copyPath(UD_Path + "UniversalDisplayValues.ks", UD_Path + "UniversalDisplayValues_Backup.ks"). | |
| } | |
| } | |
| function UD_HandleMessages { | |
| // Function to handle incomming messages from other cores to update various things. | |
| if (core:messages:empty) return. | |
| local msg is core:messages:pop. | |
| local errors is EmptyList:copy. | |
| UD_Backup(). | |
| if (msg:content:typename = "string") { | |
| if (msg:content = "exit") { | |
| UD_Print("Exiting"). | |
| UD_Active off. | |
| } | |
| else if (msg:content = "reboot") { | |
| UD_Print("Rebooting"). | |
| UD_Reboot on. | |
| UD_Active off. | |
| } | |
| else if (msg:content = "refresh") { | |
| UD_Print("Refresing"). | |
| for key in UD_Widgets:keys { | |
| UD_Widgets[key]["GUI"]["GUI"]:dispose(). | |
| UD_Widgets[key]:remove("GUI"). | |
| } | |
| } | |
| else if (msg:content = "show") { | |
| core:doevent("open terminal"). | |
| } | |
| else if (msg:content = "hide") { | |
| core:doevent("close terminal"). | |
| } | |
| else if (msg:content = "ListWidgets") { | |
| UD_ListWidgets(). | |
| } | |
| else if (msg:content = "reset") { | |
| UD_Print("Resetting"). | |
| if (exists(UD_Path + "UniversalDisplaySettings.json")) deletePath(UD_Path + "UniversalDisplaySettings.json"). | |
| if (exists(UD_Path + "UniversalDisplayValues.ks")) deletePath(UD_Path + "UniversalDisplayValues.ks"). | |
| if (exists(UD_Path + "UniversalDisplayValues_Backup.ks")) deletePath(UD_Path + "UniversalDisplayValues_Backup.ks"). | |
| clearguis(). | |
| reboot. | |
| } | |
| } | |
| else if (msg:content:typename = "lexicon") { | |
| local receivedLex is msg:content. | |
| if (receivedLex:haskey("RefreshRate")) { | |
| if (receivedLex["RefreshRate"]:typename = "scalar") { | |
| set UD_RefreshRate to receivedLex["RefreshRate"]. | |
| UD_Print("Updating RefreshRate to " + UD_RefreshRate). | |
| } | |
| else { | |
| UD_Print("Received RefreshRate is not a scalar.", "Warning"). | |
| } | |
| } | |
| if (receivedLex:haskey("HideOnInactive")) { | |
| if (receivedLex["HideOnInactive"]:typename = "boolean") { | |
| set UD_HideOnInactive to receivedLex["HideOnInactive"]. | |
| UD_Print("Updating HideOnInactive to " + UD_HideOnInactive). | |
| } | |
| else { | |
| UD_Print("Received HideOnInactive is not a boolean.", "Warning"). | |
| } | |
| } | |
| if (receivedLex:haskey("TrainingWheels")) { | |
| if (receivedLex["TrainingWheels"]:typename = "boolean") { | |
| set UD_TrainingWheels to receivedLex["TrainingWheels"]. | |
| UD_Print("Updating TrainingWheels to " + UD_TrainingWheels). | |
| } | |
| else { | |
| UD_Print("Received TrainingWheels is not a boolean.", "Warning"). | |
| } | |
| } | |
| if (receivedLex:haskey("AddWidget")) { | |
| if (receivedLex["AddWidget"]:typename = "lexicon") { | |
| UD_AddWidget(receivedLex["AddWidget"]). | |
| } | |
| else { | |
| UD_Print("Received AddWidget is not a lexicon.", "Warning"). | |
| } | |
| } | |
| else if (receivedLex:haskey("RemoveWidget")) { | |
| if (receivedLex["RemoveWidget"]:typename = "scalar" OR receivedLex["RemoveWidget"]:typename = "string") { | |
| UD_Print("Removing widget"). | |
| UD_RemoveWidget(receivedLex["RemoveWidget"]). | |
| } | |
| else { | |
| UD_Print("Received RemoveWidget is not a string or scalar.", "Warning"). | |
| } | |
| } | |
| else if (receivedLex:haskey("EditWidget")) { | |
| if (receivedLex["EditWidget"]:typename = "lexicon") { | |
| UD_Print("Editing widget"). | |
| UD_EditWidget(receivedLex["EditWidget"]). | |
| } | |
| else { | |
| UD_Print("Received EditWidget is not a lexicon.", "Warning"). | |
| } | |
| } | |
| else if (receivedLex:haskey("AddLine")) { | |
| if (receivedLex["AddLine"]:typename = "lexicon") { | |
| if (not(receivedLex["AddLine"]:haskey("Widget"))) errors:add("Item:Widget is empty"). | |
| else if (not(receivedLex["AddLine"]["Widget"]:typename = "string" OR receivedLex["AddLine"]["Widget"]:typename = "scalar")) errors:add("Item:Widget is not a string or scalar."). | |
| if (not(receivedLex["AddLine"]:haskey("Line"))) errors:add("Item:Line is empty"). | |
| else if (receivedLex["AddLine"]["Line"]:typename <> "lexicon") errors:add("Item:Line is not a lexicon."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| if (not(receivedLex["AddLine"]:haskey("Index"))) set receivedLex["AddLine"]["Index"] to -1. | |
| else if (receivedLex["AddLine"]["Index"]:typename <> "scalar") errors:add("Item:Index is not a scalar."). | |
| local widgetIndex is UD_FindWidget(receivedLex["AddLine"]["Widget"]). | |
| if (widgetIndex:typename <> "scalar" AND receivedLex["AddLine"]["Widget"]:typename = "scalar") errors:add("Item:Widget at index " + receivedLex["AddLine"]["Widget"] + " does not exist."). | |
| else if (widgetIndex:typename <> "scalar") errors:add("Item:Widget with DisplayName " + receivedLex["AddLine"]["Widget"] + " does not exist, or there are multiple."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| set receivedLex["AddLine"]["Index"] to choose receivedLex["AddLine"]["Index"] if UD_Widgets[widgetIndex]["Contents"]:length <> receivedLex["AddLine"]["Index"] else -1. | |
| if (receivedLex["AddLine"]["Index"] > UD_Widgets[widgetIndex]["Contents"]:length OR receivedLex["AddLine"]["Index"] < -1) errors:add("Item:Index is out of range."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| if (receivedLex["AddLine"]["Index"] <> -1) { | |
| UD_Widgets[widgetIndex]["GUI"]["GUI"]:dispose(). | |
| UD_Widgets[widgetIndex]:remove("GUI"). | |
| } | |
| local line is UD_AddLine(widgetIndex, receivedLex["AddLine"]["Line"], receivedLex["AddLine"]["Index"]). | |
| if (line:typename <> "lexicon") { | |
| errors:add("Failed to add line to widget"). | |
| } | |
| else { | |
| if (line:haskey("command") AND line:haskey("checksum")) { | |
| UD_RunHelper(line["checksum"]). | |
| UD_Print("Checksum passed."). | |
| UD_RunHelper(line["command"]). | |
| UD_Print("Command Executed."). | |
| } | |
| else errors:add("Internal Error when adding line"). | |
| } | |
| if (not(UD_TestErrors(errors))) return false. | |
| } | |
| else { | |
| UD_Print("Received AddWidget is not a lexicon.", "Warning"). | |
| } | |
| } | |
| else if (receivedLex:haskey("RemoveLine")) { | |
| UD_Print("Removing line"). | |
| UD_RemoveLine(receivedLex["RemoveLine"]). | |
| } | |
| else if (receivedLex:haskey("EditLine")) { | |
| if (receivedLex["EditLine"]:typename = "lexicon") { | |
| UD_Print("Editing line"). | |
| UD_EditLine(receivedLex["EditLine"]). | |
| } | |
| else { | |
| UD_Print("Received EditLine is not a lexicon.", "Warning"). | |
| } | |
| } | |
| } | |
| } | |
| function UD_AddWidget { | |
| // Function to add a widget to the list | |
| parameter addLex. | |
| local errors is EmptyList:copy. | |
| local widget is lex(). | |
| local commands is EmptyList:copy. | |
| commands:add(""). | |
| local checksums is EmptyList:copy. | |
| if (addLex:typename <> "lexicon") errors:add("Item is not a lexicon."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| local validation is UD_ValidateWidget(addLex). | |
| for e in validation["errors"] errors:add(e). | |
| set addLex to validation["widget"]. | |
| if (not(UD_TestErrors(errors))) return false. | |
| set commands[0] to UD_ConstructWidgetCommand(UD_WidgetIndex, addLex). | |
| widget:add("DisplayName", addLex["DisplayName"]). | |
| widget:add("Background", addLex["Background"]). | |
| widget:add("Width", addLex["Width"]). | |
| widget:add("X", addLex["X"]). | |
| widget:add("Y", addLex["Y"]). | |
| widget:add("FontSize", addLex["FontSize"]). | |
| widget:add("Contents", EmptyList:copy). | |
| if (addLex:haskey("Contents")) { | |
| for listItem in addLex["Contents"] { | |
| local line is UD_addLine(UD_WidgetIndex, listItem). | |
| if (line:typename <> "lexicon") { | |
| errors:add("Failed to add line to widget"). | |
| } | |
| else { | |
| if (line:haskey("command")) commands:add(line["command"]). else errors:add("Internal Error when adding line"). | |
| if (line:haskey("checksum")) checksums:add(line["checksum"]). else errors:add("Internal Error when adding line"). | |
| } | |
| } | |
| } | |
| if (not(UD_TestErrors(errors))) return false. | |
| log commands[0] to UD_Path + "UniversalDisplayValues.ks". | |
| UD_Widgets:add(UD_WidgetIndex, widget). | |
| if (checksums:length > 0) { | |
| UD_RunHelper(checksums:join(" ")). | |
| UD_Print(checksums:length + " Checksums passed."). | |
| } | |
| if (commands:length >= 2) { | |
| local tmpcommand is "". | |
| for i in range(1, commands:length) { | |
| set tmpcommand to tmpcommand + commands[i] + " ". | |
| } | |
| UD_RunHelper(tmpcommand). | |
| UD_Print("Commands Executed."). | |
| } | |
| set UD_WidgetIndex to UD_WidgetIndex + 1. | |
| return true. | |
| } | |
| function UD_RemoveWidget { | |
| // Function to remove a widget from the list. | |
| parameter removeIndex. | |
| local errors is EmptyList:copy. | |
| local widgetIndex is UD_FindWidget(removeIndex). | |
| if (widgetIndex:typename <> "scalar" AND removeIndex:typename = "scalar") errors:add("Item:Widget at index " + removeIndex + " does not exist."). | |
| else if (widgetIndex:typename <> "scalar") errors:add("Item:Widget with DisplayName " + removeIndex + " does not exist, or there are multiple."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| UD_DeleteData(widgetIndex, EmptyList:copy, true). | |
| } | |
| function UD_EditWidget { | |
| // Function to edit an existing widget. | |
| parameter editLex. | |
| local errors is EmptyList:copy. | |
| local replacementLex is lex(). | |
| local command is "". | |
| if (not(editLex:haskey("Index"))) errors:add("Item:Index is empty"). | |
| else if (editLex["Index"]:typename <> "scalar" AND editLex["Index"]:typename <> "string") errors:add("Item:Index is not a string or scalar."). | |
| if (not(editLex:haskey("Widget"))) errors:add("Item:Widget is empty"). | |
| else if (editLex["Widget"]:typename <> "lexicon") errors:add("Item:Widget is not a lexicon."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| local widgetIndex is UD_FindWidget(editLex["Index"]). | |
| if (widgetIndex:typename <> "scalar" AND editLex["Index"]:typename = "scalar") errors:add("Widget at index " + editLex["Index"] + " does not exist."). | |
| else if (widgetIndex:typename <> "scalar") errors:add("Widget with DisplayName " + editLex["Index"] + " does not exist, or there are multiple."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| if (editLex["Widget"]:haskey("DisplayName")) { | |
| if (editLex["Widget"]["DisplayName"]:typename <> "string") errors:add("Item:DisplayName is not a string."). | |
| set replacementLex["DisplayName"] to editLex["Widget"]["DisplayName"]. | |
| } | |
| else { | |
| set replacementLex["DisplayName"] to UD_Widgets[widgetIndex]["DisplayName"]. | |
| } | |
| if (editLex["Widget"]:haskey("Background")) { | |
| if (editLex["Widget"]["Background"]:typename <> "string") errors:add("Item:Background is not a string."). | |
| set replacementLex["Background"] to editLex["Widget"]["Background"]. | |
| } | |
| else { | |
| set replacementLex["Background"] to UD_Widgets[widgetIndex]["Background"]. | |
| } | |
| if (editLex["Widget"]:haskey("Width")) { | |
| if (editLex["Widget"]["Width"]:typename <> "scalar") errors:add("Item:Width is not a string."). | |
| set replacementLex["Width"] to editLex["Widget"]["Width"]. | |
| } | |
| else { | |
| set replacementLex["Width"] to UD_Widgets[widgetIndex]["Width"]. | |
| } | |
| if (editLex["Widget"]:haskey("X")) { | |
| if (editLex["Widget"]["X"]:typename <> "scalar") errors:add("Item:X is not a string."). | |
| set replacementLex["X"] to editLex["Widget"]["X"]. | |
| } | |
| else { | |
| set replacementLex["X"] to UD_Widgets[widgetIndex]["X"]. | |
| } | |
| if (editLex["Widget"]:haskey("Y")) { | |
| if (editLex["Widget"]["Y"]:typename <> "scalar") errors:add("Item:Y is not a string."). | |
| set replacementLex["Y"] to editLex["Widget"]["Y"]. | |
| } | |
| else { | |
| set replacementLex["Y"] to UD_Widgets[widgetIndex]["Y"]. | |
| } | |
| if (editLex["Widget"]:haskey("FontSize")) { | |
| if (editLex["Widget"]["FontSize"]:typename <> "scalar") errors:add("Item:FontSize is not a string."). | |
| set replacementLex["FontSize"] to editLex["Widget"]["FontSize"]. | |
| } | |
| else { | |
| set replacementLex["FontSize"] to UD_Widgets[widgetIndex]["FontSize"]. | |
| } | |
| if (not(UD_TestErrors(errors))) return false. | |
| local isDifferent is false. | |
| for key in replacementLex:keys { | |
| if (not(replacementLex[key] = UD_Widgets[widgetIndex][key])) isDifferent on. | |
| } | |
| if (not(isDifferent)) errors:add("New widget is not different from existing widget"). | |
| if (not(UD_TestErrors(errors))) return false. | |
| local validation is UD_ValidateWidget(replacementLex). | |
| for e in validation["errors"] errors:add(e). | |
| set replacementLex to validation["widget"]. | |
| if (not(UD_TestErrors(errors))) return false. | |
| set command to UD_ConstructWidgetCommand(widgetIndex, replacementLex). | |
| UD_EditData("UD_Widgets:add(" + widgetIndex + ", ", command). | |
| for key in replacementLex:keys { | |
| set UD_Widgets[widgetIndex][key] to replacementLex[key]. | |
| } | |
| } | |
| function UD_AddLine { | |
| // function to add a line to a widget. | |
| parameter widgetIndex, addLex, lineIndex is -1. | |
| local errors is EmptyList:copy. | |
| local preCommand is "". | |
| local lineLex is "". | |
| local command is "". | |
| local checksum is "". | |
| if (widgetIndex:typename <> "scalar") errors:add("WidgetIndex is not a scalar."). | |
| if (addLex:typename <> "lexicon") errors:add("Item is not a lexicon."). | |
| if (lineIndex:typename <> "scalar") errors:add("LineIndex is not a scalar."). | |
| local validation is UD_ValidateLine(addLex). | |
| for e in validation["errors"] errors:add(e). | |
| set addLex to validation["line"]. | |
| if (not(UD_TestErrors(errors))) return false. | |
| set preCommand to "UD_Widgets[" + widgetIndex + "][" + char(34) + "Contents" + char(34) + "]". | |
| if (addLex["Type"] = "item") { | |
| set checksum to "(" + addLex["value"] + "):call().". | |
| set lineLex to "lex(". | |
| set lineLex to lineLex + char(34) + "Type" + char(34) + ", " + char(34) + addLex["Type"] + char(34) + ", ". | |
| set lineLex to lineLex + char(34) + "Label" + char(34) + ", " + char(34) + addLex["Label"] + char(34) + ", ". | |
| set lineLex to lineLex + char(34) + "Prefix" + char(34) + ", " + char(34) + addLex["Prefix"] + char(34) + ", ". | |
| set lineLex to lineLex + char(34) + "Postfix" + char(34) + ", " + char(34) + addLex["Postfix"] + char(34) + ", ". | |
| set lineLex to lineLex + char(34) + "DecimalDigits" + char(34) + ", " + addLex["DecimalDigits"] + ", ". | |
| set lineLex to lineLex + char(34) + "Value" + char(34) + ", " + addLex["Value"] + ", ". | |
| set lineLex to lineLex + char(34) + "StringValue" + char(34) + ", " + char(34) + addLex["Value"]:replace(char(34), char(34) + " + char(34) + " + char(34)) + char(34). | |
| set lineLex to lineLex + ")". | |
| } | |
| else { | |
| set lineLex to "lex(" + char(34) + "Type" + char(34) + ", " + char(34) + addLex["Type"] + char(34) + ")". | |
| } | |
| set command to "if (not(exists(" + char(34) + UD_Path + "UniversalDisplayValues.ks" + char(34) + "))) create(" + char(34) + UD_Path + "UniversalDisplayValues.ks" + char(34) + ").". | |
| set command to command + "local index is 0. local file is open(" + char(34) + UD_Path + "UniversalDisplayValues.ks" + char(34) + "). local fileContents is file:readall().". | |
| set command to command + "set addLine to {file:writeln(" + char(34) + (preCommand + ":add(" + lineLex + ")."):replace(char(34), char(34) + " + char(34) + " + char(34)) + char(34) + ").}.". | |
| set command to command + "if (fileContents:length = 0) addLine(). else {". | |
| if (lineIndex <> -1) { | |
| set command to command + "local lines is list().". | |
| set command to command + "for line in fileContents { if line:contains(" + char(34) + "UD_Widgets[" + widgetIndex + "][" + char(34) + " + char(34) + " + char(34) + "Contents" + char(34) + " + char(34) +" + char(34) + "]:add(" + char(34) + ") {". | |
| set command to command + "lines:add(list(line, index)). set index to index + 1.}else lines:add(list(line)).} file:clear().". | |
| set command to command + "for i in range(lines:length) { if (lines[i]:length = 2 AND lines[i][1] = " + lineIndex + ") addLine(). file:writeln(lines[i][0]).} }". | |
| } | |
| else { | |
| set command to command + " addLine(). }". | |
| } | |
| set command to command + preCommand + (choose ":insert(" + lineIndex + ", " if lineIndex <> -1 else ":add(") + lineLex + ").". | |
| return lex("command", command, "checksum", checksum). | |
| } | |
| function UD_RemoveLine { | |
| // Function to remove a line from a widget. | |
| parameter removeLex. | |
| local errors is EmptyList:copy. | |
| if (not(removeLex:haskey("Widget"))) errors:add("Item:Widget is empty"). | |
| else if (not(removeLex["Widget"]:typename = "string" OR removeLex["Widget"]:typename = "scalar")) errors:add("Item:Widget is not a string or scalar."). | |
| if (not(removeLex:haskey("Index"))) errors:add("Item:Index is empty"). | |
| else if (not(removeLex["Index"]:typename = "scalar")) errors:add("Item:Index is not a scalar."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| local widgetIndex is UD_FindWidget(removeLex["Widget"]). | |
| if (widgetIndex:typename <> "scalar" AND removeLex["Widget"]:typename = "scalar") errors:add("Item:Widget at index " + removeLex["Widget"] + " does not exist."). | |
| else if (widgetIndex:typename <> "scalar") errors:add("Item:Widget with DisplayName " + removeLex["Widget"] + " does not exist, or there are multiple."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| If (removeLex["Index"] < 0 OR removeLex["Index"] >= UD_Widgets[widgetIndex]["Contents"]:length) errors:add("Item:Index is out of range."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| local tmplist is EmptyList:copy. | |
| tmplist:add(removeLex["Index"]). | |
| UD_DeleteData(widgetIndex, tmplist, false). | |
| } | |
| function UD_EditLine { | |
| // Function to edit an existing line. | |
| parameter editLex. | |
| local errors is EmptyList:copy. | |
| local replacementLex is lex(). | |
| local command is "". | |
| if (not(editLex:haskey("Widget"))) errors:add("Item:Widget is empty"). | |
| else if (editLex["Widget"]:typename <> "scalar" AND editLex["Widget"]:typename <> "string") errors:add("Item:Widget is not a string or scalar."). | |
| if (not(editLex:haskey("Index"))) errors:add("Item:Index is empty"). | |
| else if (editLex["Index"]:typename <> "scalar") errors:add("Item:Index is not a scalar."). | |
| if (not(editLex:haskey("Line"))) errors:add("Item:Line is empty"). | |
| else if (editLex["Line"]:typename <> "Lexicon") errors:add("Item:Line is not a lexicon."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| local widgetIndex is UD_FindWidget(editLex["Widget"]). | |
| if (widgetIndex:typename <> "scalar" AND editLex["Widget"]:typename = "scalar") errors:add("Widget at index " + editLex["Widget"] + " does not exist."). | |
| else if (widgetIndex:typename <> "scalar") errors:add("Widget with DisplayName " + editLex["Widget"] + " does not exist, or there are multiple."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| if (editLex["Index"] < 0 OR editLex["Index"] >= UD_Widgets[widgetIndex]["Contents"]:length) errors:add("Item:Index is out of range."). | |
| if (not(UD_TestErrors(errors))) return false. | |
| if (editLex["Line"]:haskey("Type")) { | |
| if (editLex["Line"]["Type"]:typename <> "string") errors:add("Item:Type is not a string."). | |
| set replacementLex["Type"] to editLex["Line"]["Type"]. | |
| } | |
| else { | |
| set replacementLex["Type"] to UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]["Type"]. | |
| } | |
| if (editLex["Line"]:haskey("Label")) { | |
| if (editLex["Line"]["Label"]:typename <> "string") errors:add("Item:Label is not a string."). | |
| set replacementLex["Label"] to editLex["Line"]["Label"]. | |
| } | |
| else { | |
| if (UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]:haskey("Label")) | |
| set replacementLex["Label"] to UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]["Label"]. | |
| else errors:add("Item:Label is empty"). | |
| } | |
| if (editLex["Line"]:haskey("Prefix")) { | |
| if (editLex["Line"]["Prefix"]:typename <> "string") errors:add("Item:Prefix is not a string."). | |
| set replacementLex["Prefix"] to editLex["Line"]["Prefix"]. | |
| } | |
| else { | |
| if (UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]:haskey("Prefix")) | |
| set replacementLex["Prefix"] to UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]["Prefix"]. | |
| else errors:add("Item:Prefix is empty"). | |
| } | |
| if (editLex["Line"]:haskey("Postfix")) { | |
| if (editLex["Line"]["Postfix"]:typename <> "string") errors:add("Item:Postfix is not a string."). | |
| set replacementLex["Postfix"] to editLex["Line"]["Postfix"]. | |
| } | |
| else { | |
| if (UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]:haskey("Postfix")) | |
| set replacementLex["Postfix"] to UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]["Postfix"]. | |
| else errors:add("Item:Postfix is empty"). | |
| } | |
| if (editLex["Line"]:haskey("DecimalDigits")) { | |
| if (editLex["Line"]["DecimalDigits"]:typename <> "scalar") errors:add("Item:DecimalDigits is not a scalar."). | |
| set replacementLex["DecimalDigits"] to editLex["Line"]["DecimalDigits"]. | |
| } | |
| else { | |
| if (UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]:haskey("DecimalDigits")) | |
| set replacementLex["DecimalDigits"] to UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]["DecimalDigits"]. | |
| else errors:add("Item:DecimalDigits is empty"). | |
| } | |
| if (editLex["Line"]:haskey("Value")) { | |
| if (editLex["Line"]["Value"]:typename <> "string") errors:add("Item:Value is not a stringified delegate."). | |
| set replacementLex["Value"] to editLex["Line"]["Value"]. | |
| } | |
| else { | |
| if (UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]:haskey("StringValue")) | |
| set replacementLex["Value"] to UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]["StringValue"]. | |
| else errors:add("Item:Value is empty"). | |
| } | |
| if (not(UD_TestErrors(errors))) return false. | |
| local isDifferent is false. | |
| for key in replacementLex:keys { | |
| if (key = "Value") { | |
| if (not(UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]:haskey("StringValue")) | |
| OR not(replacementLex[key] = UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]["StringValue"])) isDifferent on. | |
| } | |
| else { | |
| if (not(UD_Widgets[widgetIndex]["Contents"][editLex["Index"]]:haskey(key)) | |
| OR not(replacementLex[key] = UD_Widgets[widgetIndex]["Contents"][editLex["Index"]][key])) isDifferent on. | |
| } | |
| } | |
| if (not(isDifferent)) errors:add("New line is not different from existing line"). | |
| if (not(UD_TestErrors(errors))) return false. | |
| local newLine is UD_AddLine(widgetIndex, replacementLex, choose -1 if editLex["Index"] = UD_Widgets[widgetIndex]["Contents"]:length - 1 else editLex["Index"]). | |
| if (newLine:typename <> "lexicon") { | |
| errors:add("Failed to edit line on widget"). | |
| } | |
| else { | |
| if (newLine:haskey("command") AND newLine:haskey("checksum")) { | |
| local tmplist is EmptyList:copy. | |
| tmplist:add(editLex["Index"]). | |
| UD_DeleteData(widgetIndex, tmplist, false). | |
| UD_RunHelper(newLine["checksum"]). | |
| UD_Print("Checksum passed."). | |
| UD_RunHelper(newLine["command"]). | |
| UD_Print("Command Executed."). | |
| } | |
| else errors:add("Internal Error when editing line"). | |
| } | |
| if (not(UD_TestErrors(errors))) return false. | |
| } | |
| function UD_UpdateWidgets { | |
| // Function to draw and update the widgets | |
| for key in UD_Widgets:keys { | |
| local widget is UD_Widgets[key]. | |
| if (not(widget:haskey("GUI"))) set widget["GUI"] to lex(). | |
| if (not(widget["GUI"]:haskey("GUI"))) { | |
| set widget["GUI"]["GUI"] to gui(widget["Width"]). | |
| widget["GUI"]["GUI"]:show(). | |
| if widget["Background"] = "" set widget["GUI"]["GUI"]:Style:bg to "". | |
| } | |
| if (not(widget["GUI"]:haskey("SeperatorString"))) set widget["GUI"]["SeperatorString"] to "". | |
| // Update the direct elements of the widget. | |
| if (not(widget["GUI"]["GUI"]:Style:bg = widget["Background"])) set widget["GUI"]["GUI"]:Style:bg to widget["Background"]. | |
| if (not(widget["GUI"]["GUI"]:X = widget["X"])) set widget["GUI"]["GUI"]:X to widget["X"]. | |
| if (not(widget["GUI"]["GUI"]:Y = widget["Y"])) set widget["GUI"]["GUI"]:Y to widget["Y"]. | |
| if (not(widget["GUI"]["GUI"]:Style:Width = widget["Width"])) { set widget["GUI"]["GUI"]:Style:Width to widget["Width"]. set widget["GUI"]["SeperatorString"] to UD_GenerateSeperatorString(widget["Width"], widget["FontSize"]). } | |
| if (not(widget["GUI"]["GUI"]:Style:FontSize = widget["FontSize"])) { set widget["GUI"]["GUI"]:Style:FontSize to widget["FontSize"]. set widget["GUI"]["SeperatorString"] to UD_GenerateSeperatorString(widget["Width"], widget["FontSize"]). } | |
| if (not(widget["GUI"]["GUI"]:visible) and kuniverse:activevessel = ship) widget["GUI"]["GUI"]:show(). | |
| else if (widget["GUI"]["GUI"]:visible and UD_HideOnInactive and kuniverse:activevessel <> ship) widget["GUI"]["GUI"]:hide(). | |
| if (widget["GUI"]["GUI"]:visible) { // Don't need to tick the lines if the widget isn't visible. | |
| local index is 0. | |
| for line in widget["Contents"] { | |
| if (not(widget["GUI"]:haskey("Contents"))) set widget["GUI"]["Contents"] to EmptyList:copy. | |
| if (not(widget["GUI"]["Contents"]:length > index)) widget["GUI"]["Contents"]:add(lex()). | |
| if (not(widget["GUI"]["Contents"][index]:haskey("Layout"))) set widget["GUI"]["Contents"][index]["Layout"] to widget["GUI"]["GUI"]:addhlayout(). | |
| if (not(widget["GUI"]["Contents"][index]:haskey("Contents"))) set widget["GUI"]["Contents"][index]["Contents"] to EmptyList:copy. | |
| if (line["Type"] = "item") { | |
| local labeltxt is "<color=white>" + line["Label"] + (choose ":" if line["Label"]:length <> 0 else "") + "</color>". | |
| local prefixtxt is "<color=white>" + line["Prefix"] + "</color>". | |
| local postfixtxt is "<color=white>" + (choose "" if line["Postfix"]:length = 0 else " ") + line["Postfix"] + "</color>". | |
| local value is line["Value"]:call(). | |
| local valuetxt is prefixtxt + "<color=yellow>" + (choose round(value, line["DecimalDigits"]) if value:typename = "scalar" else value) + "</color>" + postfixtxt. | |
| if (not(widget["GUI"]["Contents"][index]["Contents"]:length > 0)) widget["GUI"]["Contents"][index]["Contents"]:add(widget["GUI"]["Contents"][index]["Layout"]:addlabel()). | |
| if (not(widget["GUI"]["Contents"][index]["Contents"]:length > 1)) widget["GUI"]["Contents"][index]["Contents"]:add(widget["GUI"]["Contents"][index]["Layout"]:addlabel()). | |
| // specifics for the two labels in an item | |
| if (not(widget["GUI"]["Contents"][index]["Contents"][0]:text = labeltxt)) set widget["GUI"]["Contents"][index]["Contents"][0]:text to labeltxt. | |
| if (not(widget["GUI"]["Contents"][index]["Contents"][1]:text = valuetxt)) set widget["GUI"]["Contents"][index]["Contents"][1]:text to valuetxt. | |
| if (not(widget["GUI"]["Contents"][index]["Contents"][1]:style:align = "RIGHT")) set widget["GUI"]["Contents"][index]["Contents"][1]:style:align to "RIGHT". | |
| } | |
| else if (line["Type"] = "spacer") { | |
| if (not(widget["GUI"]["Contents"][index]["Contents"]:length > 0)) widget["GUI"]["Contents"][index]["Contents"]:add(widget["GUI"]["Contents"][index]["Layout"]:addlabel()). | |
| if (not(widget["GUI"]["Contents"][index]["Contents"][0]:text = " ")) set widget["GUI"]["Contents"][index]["Contents"][0]:text to " ". | |
| } | |
| else if (line["Type"] = "seperator") { | |
| if (not(widget["GUI"]["Contents"][index]["Contents"]:length > 0)) widget["GUI"]["Contents"][index]["Contents"]:add(widget["GUI"]["Contents"][index]["Layout"]:addlabel()). | |
| if (not(widget["GUI"]["Contents"][index]["Contents"][0]:text = widget["GUI"]["SeperatorString"])) set widget["GUI"]["Contents"][index]["Contents"][0]:text to widget["GUI"]["SeperatorString"]. | |
| if (not(widget["GUI"]["Contents"][index]["Contents"][0]:style:align = "CENTER")) set widget["GUI"]["Contents"][index]["Contents"][0]:style:align to "CENTER". | |
| if (not(widget["GUI"]["Contents"][index]["Contents"][0]:style:font = "MS Gothic")) set widget["GUI"]["Contents"][index]["Contents"][0]:style:font to "MS Gothic". | |
| } | |
| // basic markup for all labels | |
| for label in widget["GUI"]["Contents"][index]["Contents"] { | |
| if (not(label:style:margin:top = 0)) set label:style:margin:top to 0. | |
| if (not(label:style:margin:bottom = 0)) set label:style:margin:bottom to 0. | |
| if (not(label:style:margin:left = 0)) set label:style:margin:left to 0. | |
| if (not(label:style:margin:right = 0)) set label:style:margin:right to 0. | |
| if (not(label:style:padding:top = round(Widget["FontSize"] / 12, 1))) set label:style:padding:top to round(Widget["FontSize"] / 12, 1). | |
| if (not(label:style:padding:bottom = round(Widget["FontSize"] / 12, 1))) set label:style:padding:bottom to round(Widget["FontSize"] / 12, 1). | |
| if (not(label:style:padding:left = round(Widget["FontSize"] / 12, 1))) set label:style:padding:left to round(Widget["FontSize"] / 12, 1). | |
| if (not(label:style:padding:right = round(Widget["FontSize"] / 12, 1))) set label:style:padding:right to round(Widget["FontSize"] / 12, 1). | |
| if (not(label:style:fontsize = Widget["FontSize"] * 0.8125)) set label:style:fontsize to Widget["FontSize"] * 0.8125. | |
| if (not(label:style:wordwrap = false)) set label:style:wordwrap to false. | |
| } | |
| set index to index + 1. | |
| } | |
| } | |
| } | |
| } | |
| //------------------------------------------------------------------------------------------------- | |
| // Function Calls Post-Loading | |
| clearGuis(). | |
| UD_Load(). | |
| UD_Loop(). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment