GuiElement#alignmentX | string [optional] Horizontal alignment of the layout, defaults to "left". Valid values are "left", "right" and "center". |
GuiElement#alignmentY | string [optional] Vertical alignment of the layout, defaults to "top". Valid values are "top", "bottom" and "middle". |
GuiElement#flowDirection | string [optional] Flow direction of the layout, defaults to "vertical". A vertical layout is column-based while a horizontal one is row-based. Valid values are "vertical" and "horizontal". |
GuiElement#focusDirection | string [optional] If set, overrides focus input to use the given direction instead. Defaults to the flow direction. This may be required for layouts which contain elements that handle input in the flow direction, e.g. MultiOptionElements. Valid values are "vertical", "horizontal" or "none" for no focus linking. |
GuiElement#numFlows | int [optional] Number of rows or columns depending on the flow direction, defaults to 1. |
GuiElement#lateralFlowSize | string [optional] Pixel size of row height or column width in reference resolution. Format: "[size]px" |
GuiElement#flowMargin | string [optional] Pixel sizes of margin around rows or columns in reference resolution. Format: see GuiElement#margin |
GuiElement#fitFlowToElements | bool [optional] If true, will ignore #lateralFlowSize and use the size of the largest element per row or column instead. |
GuiElement#autoValidateLayout | bool [optional] If true, will re-layout each time after adding or removing a new element. |
GuiElement#wrapAround | bool [optional] If true, will make focus navigation on child elements wrap around within the layout. Use this only for top-level layouts like the main menu. |
GuiElement#rememberLastFocus | bool [optional] If true, remembers the last focused child element when the layout box loses focus and reactivates that element when focus is reacquired. Otherwise, default focus navigation logic is used. |
204 | function BoxLayoutElement:copyAttributes(src) |
205 | BoxLayoutElement:superClass().copyAttributes(self, src); |
206 | |
207 | self.alignmentX = src.alignmentX; |
208 | self.alignmentY = src.alignmentY; |
209 | self.autoValidateLayout = src.autoValidateLayout; |
210 | self.useFullVisibility = src.useFullVisibility; |
211 | |
212 | self.layoutToleranceX, self.layoutToleranceY = src.layoutToleranceX, src.layoutToleranceY |
213 | |
214 | self.flowDirection = src.flowDirection; |
215 | self.focusDirection = src.focusDirection; |
216 | self.numFlows = src.numFlows; |
217 | self.lateralFlowSize = src.lateralFlowSize; |
218 | self.flowMargin = src.flowMargin; |
219 | self.fitFlowToElements = src.fitFlowToElements; |
220 | |
221 | self.wrapAround = src.wrapAround; |
222 | self.rememberLastFocus = src.rememberLastFocus; |
223 | end |
110 | function BoxLayoutElement:loadFromXML(xmlFile, key) |
111 | BoxLayoutElement:superClass().loadFromXML(self, xmlFile, key); |
112 | |
113 | local alignmentX = getXMLString(xmlFile, key.."#alignmentX"); |
114 | if alignmentX ~= nil then |
115 | alignmentX = alignmentX:lower(); |
116 | if alignmentX == "right" then |
117 | self.alignmentX = BoxLayoutElement.ALIGN_RIGHT; |
118 | elseif alignmentX == "center" then |
119 | self.alignmentX = BoxLayoutElement.ALIGN_CENTER; |
120 | else |
121 | self.alignmentX = BoxLayoutElement.ALIGN_LEFT; |
122 | end; |
123 | end; |
124 | |
125 | local alignmentY = getXMLString(xmlFile, key.."#alignmentY"); |
126 | if alignmentY ~= nil then |
127 | alignmentY = alignmentY:lower(); |
128 | if alignmentY == "bottom" then |
129 | self.alignmentY = BoxLayoutElement.ALIGN_BOTTOM; |
130 | elseif alignmentY == "middle" then |
131 | self.alignmentY = BoxLayoutElement.ALIGN_MIDDLE; |
132 | else |
133 | self.alignmentY = BoxLayoutElement.ALIGN_TOP; |
134 | end; |
135 | end; |
136 | |
137 | self.flowDirection = Utils.getNoNil(getXMLString(xmlFile, key.."#flowDirection"), self.flowDirection); |
138 | self.focusDirection = getXMLString(xmlFile, key.."#focusDirection") or self.flowDirection; -- use flow direction as default |
139 | |
140 | self.numFlows = Utils.getNoNil(tonumber(getXMLString(xmlFile, key.."#numFlows")), self.numFlows); |
141 | self.lateralFlowSize = Utils.getNoNil(GuiUtils.getNormalizedValues(getXMLString(xmlFile, key.."#lateralFlowSize"), self.outputSize, {self.lateralFlowSize})[1], self.lateralFlowSize); |
142 | self.flowMargin = GuiUtils.getNormalizedValues(getXMLString(xmlFile, key.."#flowMargin"), self.outputSize, self.flowMargin); |
143 | self.fitFlowToElements = Utils.getNoNil(getXMLBool(xmlFile, key.."#fitFlowToElements"), self.fitFlowToElements); |
144 | |
145 | self.autoValidateLayout = Utils.getNoNil(getXMLBool(xmlFile, key.."#autoValidateLayout"), self.autoValidateLayout); |
146 | self.useFullVisibility = Utils.getNoNil(getXMLBool(xmlFile, key.."#useFullVisibility"), self.useFullVisibility); |
147 | |
148 | self.wrapAround = Utils.getNoNil(getXMLBool(xmlFile, key.."#wrapAround"), self.wrapAround); |
149 | self.rememberLastFocus = Utils.getNoNil(getXMLBool(xmlFile, key.."#rememberLastFocus"), self.rememberLastFocus); |
150 | end |
154 | function BoxLayoutElement:loadProfile(profile, applyProfile) |
155 | BoxLayoutElement:superClass().loadProfile(self, profile, applyProfile); |
156 | |
157 | local alignmentX = profile:getValue("alignmentX"); |
158 | if alignmentX ~= nil then |
159 | alignmentX = alignmentX:lower(); |
160 | if alignmentX == "right" then |
161 | self.alignmentX = BoxLayoutElement.ALIGN_RIGHT; |
162 | elseif alignmentX == "center" then |
163 | self.alignmentX = BoxLayoutElement.ALIGN_CENTER; |
164 | else |
165 | self.alignmentX = BoxLayoutElement.ALIGN_LEFT; |
166 | end; |
167 | end; |
168 | |
169 | local alignmentY = profile:getValue("alignmentY"); |
170 | if alignmentY ~= nil then |
171 | alignmentY = alignmentY:lower(); |
172 | if alignmentY == "bottom" then |
173 | self.alignmentY = BoxLayoutElement.ALIGN_BOTTOM; |
174 | elseif alignmentY == "middle" then |
175 | self.alignmentY = BoxLayoutElement.ALIGN_MIDDLE; |
176 | else |
177 | self.alignmentY = BoxLayoutElement.ALIGN_TOP; |
178 | end; |
179 | end; |
180 | |
181 | local autoValidateLayout = profile:getBool("autoValidateLayout") |
182 | if autoValidateLayout ~= nil then |
183 | self.autoValidateLayout = autoValidateLayout |
184 | end |
185 | local useFullVisibility = profile:getBool("useFullVisibility") |
186 | if useFullVisibility ~= nil then |
187 | self.useFullVisibility = useFullVisibility |
188 | end |
189 | |
190 | self.flowDirection = Utils.getNoNil(profile:getValue("flowDirection"), self.flowDirection); |
191 | self.focusDirection = profile:getValue("focusDirection") or self.flowDirection; |
192 | self.numFlows = profile:getNumber("numFlows", self.numFlows); |
193 | |
194 | self.lateralFlowSize = GuiUtils.getNormalizedValues(profile:getValue("lateralFlowSize", "0px"), self.outputSize, {self.lateralFlowSize})[1] |
195 | self.flowMargin = GuiUtils.getNormalizedValues(profile:getValue("flowMargin", "0px 0px 0px 0px"), self.outputSize, self.flowMargin); |
196 | self.fitFlowToElements = profile:getBool("fitFlowToElements", self.fitFlowToElements); |
197 | |
198 | self.wrapAround = profile:getBool("wrapAround", self.wrapAround); |
199 | self.rememberLastFocus = profile:getBool("rememberLastFocus", self.rememberLastFocus); |
200 | end |
76 | function BoxLayoutElement:new(target, custom_mt) |
77 | if custom_mt == nil then |
78 | custom_mt = BoxLayoutElement_mt; |
79 | end; |
80 | local self = BitmapElement:new(target, custom_mt); |
81 | self.alignmentX = BoxLayoutElement.ALIGN_LEFT |
82 | self.alignmentY = BoxLayoutElement.ALIGN_TOP |
83 | |
84 | self.autoValidateLayout = false |
85 | self.useFullVisibility = true |
86 | |
87 | self.wrapAround = false; |
88 | self.flowDirection = BoxLayoutElement.FLOW_VERTICAL; |
89 | self.numFlows = 1; -- number of flows (columns or rows, depending on flow direction) |
90 | self.lateralFlowSize = 0.5; -- lateral size of flow (column width or row height, depending on flow direction) |
91 | self.fitFlowToElements = false; -- ignore lateral flow size and fit flows to element dimensions |
92 | self.flowMargin = {0, 0, 0, 0}; -- outward offset between flows, no effect at numFlows == 1 |
93 | self.layoutToleranceX, self.layoutToleranceY = 0, 0 |
94 | |
95 | self.rememberLastFocus = false; |
96 | self.lastFocusElement = nil; |
97 | self.incomingFocusTargets = {}; |
98 | self.defaultFocusTarget = nil; -- first focusable element of the current layout state |
99 | return self; |
100 | end |