I’ve now got what’s shaping up to be a pretty good UI system:
- The UI styling is defined via data in space-format (JSONish)
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576{fonts: [{ name: "label1", filename: "../../Assets/KoshgarianRegular.ttf", size: 18 },],rects: [{ name: "buttonUp", x: 567, y: 71, w: 84, h: 31},{ name: "buttonDown", x: 662, y: 71, w: 84, h: 31 },{ name: "border1TopLeft", x: 547, y: 25, w: 9, h: 9 },{ name: "border1TopRight", x: 630, y: 25, w: 9, h: 9},{ name: "border1BottomLeft", x: 547, y: 55, w: 9, h: 9},{ name: "border1BottomRight", x: 630, y: 55, w: 9, h: 9},{ name: "border1Top", x: 560, y: 25, w: 1, h: 9},{ name: "border1Bottom", x: 561, y: 55, w: 1, h: 9},{ name: "border1Left", x: 547, y: 39, w: 9, h: 1},{ name: "border1Right", x: 630, y: 44, w: 9, h: 1},{ name: "border2TopLeft", x: 640, y: 2, w: 9, h: 9},{ name: "border2TopRight", x: 723, y: 2, w: 9, h: 9},{ name: "border2BottomLeft", x: 640, y: 32, w: 9, h: 9},{ name: "border2BottomRight", x: 723, y: 32, w: 9, h: 9},{ name: "border2Top", x: 654, y: 2, w: 1, h: 9},{ name: "border2Bottom", x: 653, y: 32, w: 1, h: 9},{ name: "border2Left", x: 640, y: 19, w: 9, h: 1},{ name: "border2Right", x: 723, y: 16, w: 9, h: 1},{ name: "redRect", r: 130, g: 13, b: 30, a: 255 }],borders: [{name: "border1",topLeft: "border1TopLeft",topRight: "border1TopRight",bottomLeft: "border1BottomLeft",bottomRight: "border1BottomRight",top: "border1Top",bottom: "border1Bottom",left: "border1Left",right: "border1Right",edgeRepeatX: "stretch",edgeRepeatY: "stretch"},{name: "border2",topLeft: "border2TopLeft",topRight: "border2TopRight",bottomLeft: "border2BottomLeft",bottomRight: "border2BottomRight",top: "border2Top",bottom: "border2Bottom",left: "border2Left",right: "border2Right",edgeRepeatX: "stretch",edgeRepeatY: "stretch"}],labels:[{name: "mainButtonLabel",textColor: { r: 255, g: 255, b: 255, a: 255 },textFont: "label1",textPadding: { left: 0, top: 0, right: 0, bottom: 0 }}],buttons:[{name: "mainButton",label: "mainButtonLabel",backgroundMargins: { left: 5, top: 5, right: 5, bottom: 5 },up: "buttonUp",down: "redRect",upBorder: "border1",downBorder: "border2"}]} - The layout of the UI is then defined by a second space-format file:
123456789101112131415161718{type: "Box",class: "mainBox",orientation: "HORIZONTAL",alignmentOptions: "CENTER_H|CENTER_V",size: (1600,900),position: (0,0),widgets: [{type: "Button",class: "mainButton",text: "Click to set random number",action: "SeedButton",position:(650,425),size:(300,50)}]} - Then the “actions”, in the case above the single button, are defined in a space-script file:
12345678910void OutputNum(){engine.Output("sd");}void SeedButton(){engine.CreateButton("id1","","New Button","mainButton",0,0,0,0,"OutputNum");}
Basically, the UI Layout says the button will execute the function named “SeedButton”. That function creates a new button that will execute the function named “OutputNum”.
This all works well, surprisingly. The only gap is that every “execution” of the script, or execution of a function in the script, is completely independent of any other execution. Meaning that I can’t store information between button presses, at least not in the script.
To get around this, I’ll likely implement a key-store as a regular Engine Function so that scripts can store information for later use, even when it’s only ever needed by the script.
I didn’t think of this before because I only ever imagined scripting things like enemy behaviour, which would just access and set what it needed to.