Changeset 8079 for code/trunk/data/gui/scripts/GUISheet.lua
- Timestamp:
- Mar 15, 2011, 9:47:11 PM (14 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/data/gui/scripts/GUISheet.lua
r7689 r8079 16 16 end 17 17 18 -- Override this function if you need to do work on show 19 function P:onShow() 20 end 21 22 -- Override this function if you need to do work on hide 23 function P:onHide() 24 end 25 26 -- Override this function if you need to do work on quit 27 function P:onQuit() 28 end 29 30 -- Override this function if you want to react on keystrokes 31 function P:onKeyPressed() 32 end 33 34 -- Override this function if you want to update the gui after the window was resized 35 function P:onWindowResized() 36 end 37 18 38 -- show function for the GUI 19 39 function P:show() … … 21 41 self.bVisible = true 22 42 43 -- set the selected button's state 44 self:setSelectedButtonsStateToSelected() 45 23 46 self:onShow() 24 end25 26 -- Override this function if you need to do work on show27 function P:onShow()28 47 end 29 48 … … 36 55 end 37 56 38 -- Override this function if you need to do work on hide 39 function P:onHide() 40 end 41 42 -- Override this function if you need to do work just after the sheet has been hidden 43 function P:afterHide() 57 function P:quit() 58 -- reset the selected button 59 if self.buttons then 60 self:resetSelection() 61 end 62 63 self:onQuit() 44 64 end 45 65 … … 64 84 end 65 85 66 function P:onKeyPressed(e) 86 -- Handles key pressed while the gui sheed is displayed 87 function P:keyPressed() 88 if self.buttons then 89 if code == "208" then -- key down 90 self:moveSelectionRow(1) 91 elseif code == "200" then -- key up 92 self:moveSelectionRow(-1) 93 elseif code == "205" then -- key right 94 self:moveSelectionColumn(1) 95 elseif code == "203" then -- key left 96 self:moveSelectionColumn(-1) 97 elseif code == "28" or code == "156" then -- key enter or key numpad enter 98 self:pressSelectedButton() 99 end 100 end 101 102 self:onKeyPressed() 103 end 104 105 function P:windowResized() 106 self:onWindowResized() 107 end 108 109 110 ------------------------------------------------------------------------------- 111 -- Keyboard control ----------------------------------------------------------- 112 ------------------------------------------------------------------------------- 113 114 -- Initializes the buttons table, used to control the menu with the keyboard 115 function P:initButtons(rows, columns) 116 self.rows = rows 117 self.columns = columns 118 self.buttons = {} 119 self.selectedRow = 0 120 self.selectedColumn = 0 121 self.ratio = 1 122 end 123 124 -- ratio: the button's with divided by the button's height (used to calculate distance between buttons - adjust this until you get the desired behavior) 125 function P:setRatio(ratio) 126 self.ratio = ratio 127 end 128 129 -- Defines the button for a given position in the table. The upper-left button is at position (1, 1) 130 function P:setButton(row, column, button) 131 if not self.buttons then 132 -- init the table 133 self:initButtons(row, column) 134 elseif row > self.rows or column > self.columns then 135 -- rearrange the table 136 local maxRows = math.max(self.rows, row) 137 local maxColumns = math.max(self.columns, column) 138 139 for r = self.rows, 1, -1 do 140 for c = self.columns, 1, -1 do 141 local b = self:getButton(r, c) 142 if b then 143 self.buttons[(r - 1) * self.columns + (c - 1)] = nil 144 self.buttons[(r - 1) * maxColumns + (c - 1)] = b 145 end 146 end 147 end 148 149 self.rows = maxRows 150 self.columns = maxColumns 151 end 152 153 self.buttons[(row - 1) * self.columns + (column - 1)] = button 154 end 155 156 -- Returns the button at a given position in the table. The upper-left button is at position (1, 1) 157 function P:getButton(row, column) 158 if self.buttons then 159 return self.buttons[(row - 1) * self.columns + (column - 1)] 160 else 161 return nil 162 end 163 end 164 165 -- Returns the selected button 166 function P:getSelectedButton() 167 if self:hasSelection() then 168 return self:getButton(self.selectedRow, self.selectedColumn) 169 else 170 return nil 171 end 172 end 173 174 -- Presses the selected button if any 175 function P:pressSelectedButton() 176 if self:getSelectedButton() then 177 self.pressedEnter = true 178 self:getSelectedButton().callback() 179 self.pressedEnter = false 180 end 181 end 182 183 -- Sets the selection to a given row and column. The upper-left button is at position (1, 1) 184 function P:setSelection(row, column) 185 if not self.buttons then 186 return 187 end 188 189 assert(row > 0 and column > 0 and row <= self.rows and column <= self.columns, "(" .. row .. "/" .. column .. ") is not in the valid bounds of the table (1/1)-(" .. self.rows .. "/" .. self.columns .. ")") 190 191 self:setSelectedButtonsStateToNormal() 192 193 self.selectedRow = row 194 self.selectedColumn = column 195 196 self:setSelectedButtonsStateToSelected() 197 end 198 199 -- Sets the selection to the button closest to the given row and column. The upper-left button is at position (1, 1) 200 function P:setSelectionNear(row, column) 201 if not self.buttons then 202 return 203 end 204 205 assert(row > 0 and column > 0 and row <= self.rows and column <= self.columns, "(" .. row .. "/" .. column .. ") is not in the valid bounds of the table (1/1)-(" .. self.rows .. "/" .. self.columns .. ")") 206 207 if self:getButton(row, column) then 208 self:setSelection(row, column) 209 else 210 local min = 1000000 211 local minRow, minColumn 212 213 for r = 1, self.rows do 214 for c = 1, self.columns do 215 if self:getButton(r, c) then 216 local distance = math.sqrt((row - r)^2 + ((column - c) * self.ratio)^2) 217 if distance < min then 218 min = distance; minRow = r; minColumn = c 219 end 220 end 221 end 222 end 223 224 if minRow and minColumn then 225 self:setSelection(minRow, minColumn) 226 else 227 self:resetSelection() 228 end 229 end 230 end 231 232 -- Moves the selection by a given number of rows (a positive value means down, a negative value means up) 233 function P:moveSelectionRow(relRow) 234 self:moveSelection(relRow, "selectedRow", "selectedColumn", "rows", "columns", true) 235 end 236 237 -- Moves the selection by a given number of columns (a positive value means right, a negative value means left) 238 function P:moveSelectionColumn(relColumn) 239 self:moveSelection(relColumn, "selectedColumn", "selectedRow", "columns", "rows", false) 240 end 241 242 -- Generic move function, the values are determined at runtime depending on the arguments 243 function P:moveSelection(relMove, selectedThis, selectedOther, limitThis, limitOther, isRow) 244 if not self.buttons then 245 return 246 end 247 248 -- if there's no selection yet, prepare it such that the selection enters the table from the desired side 249 if self.selectedRow > 0 or self.selectedColumn > 0 then 250 self:setSelectedButtonsStateToNormal() 251 else 252 if relMove > 0 then 253 self[selectedThis] = 0 254 self[selectedOther] = 1 255 elseif relMove < 0 then 256 self[selectedThis] = self[limitThis] + 1 257 self[selectedOther] = 1 258 else 259 return 260 end 261 end 262 263 -- move the selection according to the parameters 264 self[selectedThis] = self[selectedThis] + relMove 265 266 -- wrap around on overflow or underflow 267 while self[selectedThis] > self[limitThis] do self[selectedThis] = self[selectedThis] - self[limitThis] end 268 while self[selectedThis] <= 0 do self[selectedThis] = self[selectedThis] + self[limitThis] end 269 270 -- if the button is deactivated, search the button closest to the desired location 271 if self:getSelectedButton() == nil then 272 local min = 1000000 273 local minV1, minV2 274 local limit, step 275 276 if relMove > 0 then 277 limit = self[limitThis] 278 step = 1 279 else 280 limit = 1 281 step = -1 282 end 283 284 for v1 = self[selectedThis], limit, step do 285 for v2 = 1, self[limitOther] do 286 local button 287 if isRow == true then 288 button = self:getButton(v1, v2) 289 else 290 button = self:getButton(v2, v1) 291 end 292 if button then 293 local distance 294 if isRow == true then 295 distance = math.sqrt((self[selectedThis] - v1)^2 + ((self[selectedOther] - v2) * self.ratio)^2) 296 else 297 distance = math.sqrt(((self[selectedThis] - v1) * self.ratio)^2 + (self[selectedOther] - v2)^2) 298 end 299 if distance < min then 300 min = distance; minV1 = v1; minV2 = v2 301 end 302 end 303 end 304 end 305 306 if minV1 and minV2 then 307 self[selectedThis] = minV1 308 self[selectedOther] = minV2 309 elseif self:hasButtons() then 310 -- no suitable button found - wrap around and search again 311 if relMove > 0 then 312 self[selectedThis] = 0 313 else 314 self[selectedThis] = self[limitThis] + 1 315 end 316 self:moveSelection(relMove, selectedThis, selectedOther, limitThis, limitOther, isRow) 317 end 318 end 319 320 self:setSelectedButtonsStateToSelected() 321 end 322 323 -- Resets the selection 324 function P:resetSelection() 325 self:setSelectedButtonsStateToNormal() 326 327 self.selectedRow = 0 328 self.selectedColumn = 0 329 end 330 331 -- Checks if there's at least one button in the table 332 function P:hasButtons() 333 local count = 0 334 for r = 1, self.rows do 335 for c = 1, self.columns do 336 if self:getButton(r, c) then 337 count = count + 1 338 end 339 end 340 end 341 342 return (count > 0) 343 end 344 345 -- Determines if a button is selected 346 function P:hasSelection() 347 if self.selectedRow and self.selectedRow > 0 and self.selectedColumn and self.selectedColumn > 0 then 348 return true 349 else 350 return false 351 end 352 end 353 354 -- Sets the selected button's state to normal 355 function P:setSelectedButtonsStateToNormal() 356 self:setSelectedButtonsState("Normal") 357 end 358 359 -- Sets the selected button's state to selected 360 function P:setSelectedButtonsStateToSelected() 361 self:setSelectedButtonsState("Selected") 362 end 363 364 -- Sets the selected button's state to pushed 365 function P:setSelectedButtonsStateToPushed() 366 self:setSelectedButtonsState("Pushed") 367 end 368 369 -- Sets the selected button's state 370 function P:setSelectedButtonsState(state) 371 if self:getSelectedButton() then 372 local element = self:getSelectedButton().button 373 local offset = getElementStateOffset(element) 374 375 if offset then 376 element:setProperty("NormalImageRightEdge", string.sub(element:getProperty("NormalImageRightEdge"), 1, offset) .. state) 377 element:setProperty("NormalImageLeftEdge", string.sub(element:getProperty("NormalImageLeftEdge"), 1, offset) .. state) 378 element:setProperty("NormalImageBackground", string.sub(element:getProperty("NormalImageBackground"), 1, offset) .. state) 379 end 380 end 381 end 382 383 -- Gets the offset of the button's current state 384 function getElementStateOffset(element) 385 local property = element:getProperty("NormalImageRightEdge") 386 387 if string.sub(property, string.len(property) - 5, string.len(property)) == "Normal" then 388 return -7 389 elseif string.sub(property, string.len(property) - 7, string.len(property)) == "Selected" then 390 return -9 391 elseif string.sub(property, string.len(property) - 5, string.len(property)) == "Pushed" then 392 return -7 393 else 394 return nil 395 end 67 396 end 68 397
Note: See TracChangeset
for help on using the changeset viewer.