Merge pull request #93 from argonui/optionpanel

Optionpanel: Part 1
This commit is contained in:
Chr1Z 2022-12-13 20:01:26 +01:00 committed by GitHub
commit 2c7a05db80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 368 additions and 94 deletions

View File

@ -22,7 +22,7 @@
}, },
"Lighting_path": "Lighting.json", "Lighting_path": "Lighting.json",
"LuaScript": "require(\"core/Global\")", "LuaScript": "require(\"core/Global\")",
"LuaScriptState": "", "LuaScriptState": "{\"optionPanel\":[false,false,false,false,false,false,false,false]}",
"MusicPlayer_path": "MusicPlayer.json", "MusicPlayer_path": "MusicPlayer.json",
"Note": "", "Note": "",
"ObjectStates_order": [ "ObjectStates_order": [
@ -265,5 +265,5 @@
"Tags": [], "Tags": [],
"Turns_path": "Turns.json", "Turns_path": "Turns.json",
"VersionNumber": "v13.2.2", "VersionNumber": "v13.2.2",
"XmlUI_path": "Root.xml" "XmlUI": "<Include src=\"Global.xml\"/>"
} }

View File

@ -43,5 +43,45 @@
"Name": "OverlaySmall", "Name": "OverlaySmall",
"Type": 0, "Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/1745699502804112719/CFFC89BF9FB8439204EE19CF94180EC99450CD38/" "URL": "http://cloud-3.steamusercontent.com/ugc/1745699502804112719/CFFC89BF9FB8439204EE19CF94180EC99450CD38/"
},
{
"Name": "option-gear",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/2026086584372569912/5CB461AEAE2E59D3064D90A776EB86C46081EC78/"
},
{
"Name": "font_birmingham",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118466443497/3CF9BB9AF968D245961494CC9A151774EB9BA638/"
},
{
"Name": "font_columbus",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118466515872/F473E4ACC75ACB6CE07457C45290B4912E0B3286/"
},
{
"Name": "font_oldremington",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118466515932/AFCE53F1E1D9580D166F53AD9EB0D77A331D4A26/"
},
{
"Name": "font_teutonic-arkham",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118467703445/89328E273B4C5180BF491516CE998DE3C604E162/"
},
{
"Name": "font_uglyqua",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118466516005/113C19D37CFFA9E554394FD5B11B32967F846A62/"
},
{
"Name": "option_image1",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118468280563/911BA319CD7502258D570B23BD51B3D8DA8B2AC3/"
},
{
"Name": "option_image2",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118470839572/FB133C41A6D8915A44C138BCF947ECFE3D111813/"
} }
] ]

View File

@ -1,65 +0,0 @@
<Defaults>
<Text color="white" fontSize="16"/>
</Defaults>
<VerticalLayout
visibility="Admin"
color="black" outlineSize="1 1" outline="#303030"
rectAlignment="LowerRight" width="40" height="200" offsetXY="0 100">
<Button icon="cthulhu" tooltipPosition="Left" tooltip="Campaigns"
onClick="onClick_toggleUi(Campaigns)"
color="black"/>
<Button icon="dark-cult" tooltipPosition="Left" tooltip="Standalone Scenarios"
onClick="onClick_toggleUi(Standalone Scenarios)"
color="black"/>
<Button icon="yog-sothoth" tooltipPosition="Left" tooltip="Extras"
onClick="onClick_toggleUi(Extras)"
color="black"/>
<Button icon="elder-sign" tooltipPosition="Left" tooltip="Investigators"
onClick="onClick_toggleUi(Investigators)"
color="black"/>
<Button icon="devourer" tooltipPosition="Left" tooltip="Community Content"
onClick="onClick_toggleUi(Community Content)"
color="black"/>
<?ignore
<Button icon="download" tooltipPosition="Left" tooltip="ArkhamDB Deck Importer"
onClick="onClick_toggleUi(Deck Importer)"
color="black"/>
?>
</VerticalLayout>
<!-- allowDragging="true" returnToOriginalPositionWhenReleased="false" -->
<VerticalLayout
id="load_ui"
active="false"
visibility="Admin"
width="800" height="780"
color="black" outlineSize="1 1" outline="#303030">
<HorizontalLayout minHeight="50" preferredHeight="50" flexibleHeight="0">
<Button icon="refresh"
tooltip="Refresh List" tooltipPosition="Right"
onClick="onClick_refreshList"
minWidth="50" preferredWidth="50" flexibleWidth="0" color="black"/>
<Text id="title" minWidth="200" flexibleWidth="100" fontSize="36">Loadable Items</Text>
<Button icon="close" tooltip="Close" tooltipPosition="Left"
onClick="onClick_toggleUi(Hidden)"
minWidth="50" preferredHeight="50" flexibleWidth="0" color="black"/>
</HorizontalLayout>
<VerticalScrollView
color="transparent" minHeight="100" flexibleHeight="100">
<Panel id="ui_update_height" height="24">
<VerticalLayout id="ui_update_point">
<Text>Please refresh to see available items.</Text>
</VerticalLayout>
</Panel>
</VerticalScrollView>
<Panel color="rgb(0,0,0)" minHeight="50" preferredHeight="50" flexibleHeight="0" active="true">
<Button id="load_buttion" active="false" onClick="onClick_load">Load:</Button>
<HorizontalLayout id="progress_display" active="true">
<ProgressBar id="download_progress" percentage="0" color="#000000" fillImageColor="#333333"/>
<Button onClick="onClick_cancel" active="false">Cancel</Button>
</HorizontalLayout>
</Panel>
</VerticalLayout>

View File

@ -5,6 +5,9 @@
ENCOUNTER_DECK_POS = {-3.93, 1, 5.76} ENCOUNTER_DECK_POS = {-3.93, 1, 5.76}
ENCOUNTER_DECK_DISCARD_POSITION = {-3.85, 1, 10.38} ENCOUNTER_DECK_DISCARD_POSITION = {-3.85, 1, 10.38}
-- optionPanel data
optionPanel = {}
-- GUID of data helper -- GUID of data helper
DATA_HELPER_GUID = "708279" DATA_HELPER_GUID = "708279"
@ -25,8 +28,8 @@ local NOT_INTERACTABLE = {
local chaosTokens = {} local chaosTokens = {}
local chaosTokensLastMat = nil local chaosTokensLastMat = nil
local IS_RESHUFFLING = false local IS_RESHUFFLING = false
local bagSearchers = {}
local bagSearchers = { } local playmatAPI = require("playermat/PlaymatApi")
--------------------------------------------------------- ---------------------------------------------------------
-- data for tokens -- data for tokens
@ -127,10 +130,22 @@ local overallStats = {
-- general code -- general code
--------------------------------------------------------- ---------------------------------------------------------
function onLoad() -- saving state of optionPanel to restore later
function onSave() return JSON.encode({ optionPanel = optionPanel }) end
function onLoad(savedData)
if savedData then
loadedData = JSON.decode(savedData)
optionPanel = loadedData.optionPanel
updateOptionPanelState()
else
print("Saved state could not be found!")
end
for _, guid in ipairs(NOT_INTERACTABLE) do for _, guid in ipairs(NOT_INTERACTABLE) do
getObjectFromGUID(guid).interactable = false getObjectFromGUID(guid).interactable = false
end end
math.randomseed(os.time()) math.randomseed(os.time())
end end
@ -600,14 +615,10 @@ local source_repo = 'https://raw.githubusercontent.com/seth-sced/loadable-object
local library = nil local library = nil
local request_obj local request_obj
function onClick_toggleUi(player, window)
toggle_ui(window)
end
function onClick_refreshList() function onClick_refreshList()
local request = WebRequest.get(source_repo .. '/library.json', completed_list_update) local request = WebRequest.get(source_repo .. '/library.json', completed_list_update)
request_obj = request request_obj = request
startLuaCoroutine(Global, 'my_coroutine') startLuaCoroutine(Global, 'downloadCoroutine')
end end
function onClick_select(player, params) function onClick_select(player, params)
@ -615,7 +626,7 @@ function onClick_select(player, params)
local url = source_repo .. '/' .. params.url local url = source_repo .. '/' .. params.url
local request = WebRequest.get(url, function (request) complete_obj_download(request, params) end ) local request = WebRequest.get(url, function (request) complete_obj_download(request, params) end )
request_obj = request request_obj = request
startLuaCoroutine(Global, 'my_coroutine') startLuaCoroutine(Global, 'downloadCoroutine')
end end
function onClick_load() function onClick_load()
@ -623,18 +634,70 @@ function onClick_load()
UI.hide('load_button') UI.hide('load_button')
end end
function toggle_ui(title) function onClick_defaultSettings()
UI.hide('load_ui') print("Dummy: Load default settings")
if UI.getValue('title') == title or title == 'Hidden' then end
UI.setValue('title', 'Hidden')
function onClick_toggleOption(_, id)
local state = self.UI.getAttribute("toggle" .. id, "isOn")
-- flip state (and handle stupid "False" value)
if state == "False" then
state = true
else else
UI.setValue('title', title) state = false
update_window_content(title) end
UI.show('load_ui')
self.UI.setAttribute("toggle" .. id, "isOn", state)
id = tonumber(id)
optionPanel[id] = state
applyOptionPanelChange(id, state)
end
-- sets the option panel to the correct state (corresponding to 'optionPanel')
function updateOptionPanelState()
for id, enabled in pairs(optionPanel) do
if enabled then self.UI.setAttribute("toggle" .. id, "isOn", true) end
end end
end end
function my_coroutine() function applyOptionPanelChange(id, state)
-- option 1: Snap tags
if id == 1 then
playmatAPI.setLimitSnapsByType(state, "All")
-- option 2: Draw 1 button
elseif id == 2 then
playmatAPI.showDrawButton(state, "All")
-- option 3: Clickable clue counters
elseif id == 3 then
playmatAPI.clickableClues(state, "All")
end
end
function onClick_toggleUi(_, title)
UI.hide('optionPanel')
UI.hide('load_ui')
-- when same button is clicked or close window button is pressed, don't open UI
if UI.getValue('title') ~= title and title ~= 'Hidden' then
UI.setValue('title', title)
if title == "Options" then
UI.show('optionPanel')
else
update_window_content(title)
UI.show('load_ui')
end
else
UI.setValue('title', "Hidden")
end
end
function downloadCoroutine()
while request_obj do while request_obj do
UI.setAttribute('download_progress', 'percentage', request_obj.download_progress * 100) UI.setAttribute('download_progress', 'percentage', request_obj.download_progress * 100)
coroutine.yield(0) coroutine.yield(0)

View File

@ -45,8 +45,16 @@ local RESOURCE_COUNTER
-- global variable so it can be reset by the Clean Up Helper -- global variable so it can be reset by the Clean Up Helper
activeInvestigatorId = "00000" activeInvestigatorId = "00000"
local isDrawButtonVisible = false
function onSave() return JSON.encode({zoneID = zoneID, playerColor = PLAYER_COLOR, activeInvestigatorId = activeInvestigatorId}) end function onSave()
return JSON.encode({
zoneID = zoneID,
playerColor = PLAYER_COLOR,
activeInvestigatorId = activeInvestigatorId,
isDrawButtonVisible = isDrawButtonVisible
})
end
function onLoad(save_state) function onLoad(save_state)
self.interactable = DEBUG self.interactable = DEBUG
@ -96,8 +104,11 @@ function onLoad(save_state)
zoneID = state.zoneID zoneID = state.zoneID
PLAYER_COLOR = state.playerColor PLAYER_COLOR = state.playerColor
activeInvestigatorId = state.activeInvestigatorId activeInvestigatorId = state.activeInvestigatorId
isDrawButtonVisible = state.isDrawButtonVisible
end end
showDrawButton(isDrawButtonVisible)
if getObjectFromGUID(zoneID) == nil then spawnDeckZone() end if getObjectFromGUID(zoneID) == nil then spawnDeckZone() end
COLLISION_ENABLED = true COLLISION_ENABLED = true
end end
@ -648,11 +659,46 @@ function spawnToken(position, tokenType)
Global.call('spawnToken', {position, tokenType, PLAY_ZONE_ROTATION}) Global.call('spawnToken', {position, tokenType, PLAY_ZONE_ROTATION})
end end
-- Sets this playermat's draw 1 button to visible
---@param visible Boolean. Whether the draw 1 button should be visible
function showDrawButton(visible)
isDrawButtonVisible = visible
-- create the "Draw 1" button
if isDrawButtonVisible then
self.createButton({
label = "Draw 1",
click_function = "doDrawOne",
function_owner = mat,
position = { 1.84, 0.1, -0.36 },
scale = { 0.12, 0.12, 0.12 },
width = 800,
height = 280,
font_size = 180
})
-- remove the "Draw 1" button
else
local buttons = self.getButtons()
for i = 1, #buttons do
if buttons[i].label == "Draw 1" then
self.removeButton(buttons[i].index)
end
end
end
end
-- Shows or hides the clickable clue counter for this playmat
---@param showCounters Boolean. Whether the clickable clue counter should be present
function clickableClues(showCounters)
print("dummy function for clue counters")
end
-- Sets this playermat's snap points to limit snapping to matching card types or not. If matchTypes -- Sets this playermat's snap points to limit snapping to matching card types or not. If matchTypes
-- is true, the main card slot snap points will only snap assets, while the investigator area point -- is true, the main card slot snap points will only snap assets, while the investigator area point
-- will only snap Investigators. If matchTypes is false, snap points will be reset to snap all -- will only snap Investigators. If matchTypes is false, snap points will be reset to snap all
-- cards. -- cards.
-- @param matchTypes Boolean. Whether snap points should only snap for the matching card types. ---@param matchTypes Boolean. Whether snap points should only snap for the matching card types.
function setLimitSnapsByType(matchTypes) function setLimitSnapsByType(matchTypes)
local snaps = self.getSnapPoints() local snaps = self.getSnapPoints()
for i, snap in ipairs(snaps) do for i, snap in ipairs(snaps) do
@ -686,10 +732,10 @@ function setLimitSnapsByType(matchTypes)
end end
-- Simple method to check if the given point is in a specified area. Local use only, -- Simple method to check if the given point is in a specified area. Local use only,
-- @param point Vector. Point to check, only x and z values are relevant ---@param point Vector. Point to check, only x and z values are relevant
-- @param bounds Table. Defined area to see if the point is within. See MAIN_PLAY_AREA for sample ---@param bounds Table. Defined area to see if the point is within. See MAIN_PLAY_AREA for sample
-- bounds definition. -- bounds definition.
-- @return Boolean. True if the point is in the area defined by bounds ---@return Boolean. True if the point is in the area defined by bounds
function inArea(point, bounds) function inArea(point, bounds)
return (point.x < bounds.upperLeft.x return (point.x < bounds.upperLeft.x
and point.x > bounds.lowerRight.x and point.x > bounds.lowerRight.x

View File

@ -13,9 +13,9 @@ do
-- matchTypes is true, the main card slot snap points will only snap assets, while the -- matchTypes is true, the main card slot snap points will only snap assets, while the
-- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- investigator area point will only snap Investigators. If matchTypes is false, snap points will
-- be reset to snap all cards. -- be reset to snap all cards.
-- @param matchCardTypes Boolean. Whether snap points should only snap for the matching card ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card
-- types. -- types.
-- @param matColor String for one of the active player colors - White, Orange, Green, Red. Also ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also
-- accepts "All" as a special value which will apply the setting to all four mats. -- accepts "All" as a special value which will apply the setting to all four mats.
PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor)
for _, mat in ipairs(internal.getMatForColor(matColor)) do for _, mat in ipairs(internal.getMatForColor(matColor)) do
@ -23,10 +23,30 @@ do
end end
end end
-- Sets the requested playermat's draw 1 button to visible
---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not
---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also
-- accepts "All" as a special value which will apply the setting to all four mats.
PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor)
for _, mat in ipairs(internal.getMatForColor(matColor)) do
mat.call("showDrawButton", isDrawButtonVisible)
end
end
-- Shows or hides the clickable clue counter for the requested playermat
---@param showCounter Boolean. Whether the clickable counter should be present or not
---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also
-- accepts "All" as a special value which will apply the setting to all four mats.
PlaymatApi.clickableClues = function(showCounter, matColor)
for _, mat in ipairs(internal.getMatForColor(matColor)) do
mat.call("clickableClues", showCounter)
end
end
-- Convenience function to look up a mat's object by color, or get all mats. -- Convenience function to look up a mat's object by color, or get all mats.
-- @param matColor String for one of the active player colors - White, Orange, Green, Red. Also ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also
-- accepts "All" as a special value which will return all four mats. -- accepts "All" as a special value which will return all four mats.
-- @return Array of playermat objects. If a single mat is requested, will return a single-element ---@return Array of playermat objects. If a single mat is requested, will return a single-element
-- array to simplify processing by consumers. -- array to simplify processing by consumers.
internal.getMatForColor = function(matColor) internal.getMatForColor = function(matColor)
local targetMatGuid = MAT_IDS[matColor] local targetMatGuid = MAT_IDS[matColor]

47
xml/Global.xml Normal file
View File

@ -0,0 +1,47 @@
<!-- Default formatting -->
<Defaults>
<!-- general Stuff -->
<Text color="white" fontSize="18"/>
<Button tooltipPosition="Left" color="clear"/>
<!-- Window -->
<HorizontalLayout class="headerLayout" height="75" padding="5"/>
<Button class="headerButton" minWidth="50" preferredWidth="50" flexibleWidth="0" color="clear"/>
<Text class="headerText" minWidth="200" flexibleWidth="100" fontSize="32" font="font_teutonic-arkham"/>
</Defaults>
<!-- Buttons in the bottom right of the screen -->
<VerticalLayout visibility="Admin" color="#000000" outlineSize="1 1" outline="#303030" rectAlignment="LowerRight" width="35" height="215" offsetXY="-1 60" spacing="1">
<Button icon="cthulhu" tooltip="Campaigns" onClick="onClick_toggleUi(Campaigns)"/>
<Button icon="dark-cult" tooltip="Standalone Scenarios" onClick="onClick_toggleUi(Standalone Scenarios)"/>
<Button icon="yog-sothoth" tooltip="Extras" onClick="onClick_toggleUi(Extras)"/>
<Button icon="elder-sign" tooltip="Investigators" onClick="onClick_toggleUi(Investigators)"/>
<Button icon="devourer" tooltip="Community Content" onClick="onClick_toggleUi(Community Content)"/>
<Button icon="option-gear" tooltip="Options" onClick="onClick_toggleUi(Options)" active="false"/>
<!--<Button icon="download" tooltip="ArkhamDB Deck Importer" onClick="onClick_toggleUi(Deck Importer)"/> -->
</VerticalLayout>
<!-- Basic UI that will be replaced based on title -->
<VerticalLayout id="load_ui" visibility="Admin" color="black" active="false" width="700" height="780" outlineSize="1 1" outline="#303030">
<HorizontalLayout class="headerLayout">
<Button class="headerButton" icon="refresh" tooltip="Refresh List" tooltipPosition="Right" onClick="onClick_refreshList"/>
<Text id="title" class="headerText">Loadable Items</Text>
<Button class="headerButton" icon="close" tooltip="Close" onClick="onClick_toggleUi(Hidden)"/>
</HorizontalLayout>
<VerticalScrollView color="transparent" minHeight="100" flexibleHeight="100">
<Panel id="ui_update_height" height="24">
<VerticalLayout id="ui_update_point" padding="10">
<Text>Please refresh to see available items.</Text>
</VerticalLayout>
</Panel>
</VerticalScrollView>
<Panel color="rgb(0,0,0)" minHeight="50" preferredHeight="50" flexibleHeight="0">
<Button id="load_button" active="false" onClick="onClick_load">Load:</Button>
<HorizontalLayout id="progress_display">
<ProgressBar id="download_progress" percentage="0" color="#000000" fillImageColor="#333333"/>
<Button onClick="onClick_cancel" active="false">Cancel</Button>
</HorizontalLayout>
</Panel>
</VerticalLayout>
<Include src="OptionPanel.xml"/>

123
xml/OptionPanel.xml Normal file
View File

@ -0,0 +1,123 @@
<!-- Default formatting -->
<Defaults>
<Text color="white" alignment="MiddleLeft"/>
<Toggle isOn="False" rectAlignment="MiddleRight"/>
<VerticalLayout class="window" active="false" color="black" visibility="Admin" outlineSize="1 1" outline="grey" allowDragging="true" returnToOriginalPositionWhenReleased="false" width="500" height="800"/>
<VerticalLayout class="group" outlineSize="1 1" outline="grey" color="#222222" padding="10" spacing="5"/>
<VerticalLayout class="text-column" padding="5 20 0 0"/>
<HorizontalLayout class="group-content" color="#444444" padding="5" spacing="5"/>
<Text class="group-header" fontSize="24" font="font_teutonic-arkham"/>
<Text class="option-header" fontSize="16" font="font_teutonic-arkham"/>
<Text class="description" fontSize="12"/>
<Button class="bottomButtons" hoverClass="hover" pressClass="press" selectClass="select" color="#888888" minHeight="35" fontSize="24" font="font_teutonic-arkham"/>
<Button class="hover" color="grey"/>
<Button class="press" color="white"/>
<Button class="select" color="white"/>
</Defaults>
<!-- Option Panel -->
<VerticalLayout id="optionPanel" class="window">
<Panel minHeight="45" flexibleHeight="0" padding="10 10 0 0">
<Text font="font_teutonic-arkham" fontSize="35">Options</Text>
</Panel>
<VerticalLayout>
<!-- Group 1 -->
<VerticalLayout class="group">
<Panel minHeight="44" image="option_image1" padding="5 0 0 0">
<Text class="group-header">PLAYERMAT SETTINGS</Text>
</Panel>
<!-- Option 1 -->
<HorizontalLayout class="group-content">
<VerticalLayout class="text-column">
<Text class="option-header">Enable snap tags</Text>
<Text class="description">Only cards with the tag "Asset" will snap (official cards are supported by default).&#xA;Disable this if you are having issues with custom content.</Text>
</VerticalLayout>
<Toggle id="toggle1" onValueChanged="onClick_toggleOption(1)" />
</HorizontalLayout>
<!-- Option 2 -->
<HorizontalLayout class="group-content">
<VerticalLayout class="text-column">
<Text class="option-header">Show "Draw 1" button</Text>
<Text class="description">Displays a button below the "Upkeep" button that draws a card from your deck. Useful for multi-handed solo play.</Text>
</VerticalLayout>
<Toggle id="toggle2" onValueChanged="onClick_toggleOption(2)"/>
</HorizontalLayout>
<!-- Option 3 -->
<HorizontalLayout class="group-content">
<VerticalLayout class="text-column">
<Text class="option-header">Use clickable clue-counters</Text>
<Text class="description">Instead of automatically counting clues in the respective area on your playermat, this displays a clickable counter for clues.&#xA;Take note of each player's clue count before changing this option!</Text>
</VerticalLayout>
<Toggle id="toggle3" onValueChanged="onClick_toggleOption(3)"/>
</HorizontalLayout>
</VerticalLayout>
<!-- Group 2 -->
<VerticalLayout class="group">
<Panel minHeight="44" image="option_image2" padding="5 0 0 0">
<Text class="group-header">FAN-MADE ACCESSORIES</Text>
</Panel>
<!-- Option 4 -->
<HorizontalLayout class="group-content">
<VerticalLayout class="text-column">
<Text class="option-header">Toggle Text 4</Text>
<Text class="description">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat...</Text>
</VerticalLayout>
<Toggle id="toggle4" onValueChanged="onClick_toggleOption(4)"/>
</HorizontalLayout>
<!-- Option 5 -->
<HorizontalLayout class="group-content">
<VerticalLayout class="text-column">
<Text class="option-header">Toggle Text 5</Text>
<Text class="description">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat...</Text>
</VerticalLayout>
<Toggle id="toggle5" onValueChanged="onClick_toggleOption(5)"/>
</HorizontalLayout>
<!-- Option 6 -->
<HorizontalLayout class="group-content">
<VerticalLayout class="text-column">
<Text class="option-header">Toggle Text 6</Text>
<Text class="description">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat...</Text>
</VerticalLayout>
<Toggle id="toggle6" onValueChanged="onClick_toggleOption(6)"/>
</HorizontalLayout>
</VerticalLayout>
<!-- Group 3 -->
<VerticalLayout class="group">
<Panel minHeight="30">
<Text class="group-header">Group 3</Text>
</Panel>
<!-- Option 7 -->
<HorizontalLayout class="group-content">
<VerticalLayout class="text-column">
<Text class="option-header">Toggle Text 7</Text>
<Text class="description">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat...</Text>
</VerticalLayout>
<Toggle id="toggle7" onValueChanged="onClick_toggleOption(7)"/>
</HorizontalLayout>
<!-- Option 8 -->
<HorizontalLayout class="group-content">
<VerticalLayout class="text-column">
<Text class="option-header">Toggle Text 8</Text>
<Text class="description">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat...</Text>
</VerticalLayout>
<Toggle id="toggle8" onValueChanged="onClick_toggleOption(8)"/>
</HorizontalLayout>
</VerticalLayout>
</VerticalLayout>
<HorizontalLayout minHeight="50" flexibleHeight="0" padding="5" spacing="5">
<Button class="bottomButtons" onClick="onClick_defaultSettings">Load defaults</Button>
<Button class="bottomButtons" onClick="onClick_toggleUi(Hidden)">Close</Button>
</HorizontalLayout>
</VerticalLayout>