Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/usability/data/gui/scripts/GUISheet.lua @ 7925

Last change on this file since 7925 was 7925, checked in by landauf, 13 years ago

if a menu sheet was opened with the keyboard, preselect the first button

  • Property svn:eol-style set to native
File size: 8.4 KB
RevLine 
[6718]1-- GUISheet.lua
[5491]2
3local P = {}
[6718]4_G[_REQUIREDNAME or "GUISheet"] = P
5P.__index = P
[5491]6
[6718]7-- Don't use directly --> use HUDSheet.new or MenuSheet.new
8function P.new(_name)
9    local newSheet = { name = _name }
10    setmetatable(newSheet, P)
11    return newSheet
[5491]12end
13
[6718]14-- Override this function if you need to do work on load
[6720]15function P:onLoad()
[5523]16end
17
[7922]18-- Override this function if you need to do work on show
19function P:onShow()
20end
21
22-- Override this function if you need to do work on hide
23function P:onHide()
24end
25
26-- Override this function if you need to do work just after the sheet has been hidden
27function P:onAfterHide()
28end
29
[6747]30-- show function for the GUI
31function P:show()
32    self.window:show()
33    self.bVisible = true
34
[7922]35    -- set the selected button's state
36    if self.buttons and self:hasSelection() then
37        self:setButtonStateSelected()
38    end
39
[6747]40    self:onShow()
41end
42
[5491]43-- hide function for the GUI
[6595]44function P:hide()
[5491]45    self.window:hide()
[6718]46    self.bVisible = false
[6747]47
48    self:onHide()
[5491]49end
50
[7922]51function P:afterHide()
52    -- reset the selected button
53    if self.buttons then
54        self:resetSelection()
55    end
[5491]56
[7922]57    self:onAfterHide()
[7403]58end
59
[6595]60function P:load()
[6718]61    -- Load the layout that describes the sheet
[6704]62    self.window = winMgr:loadWindowLayout(self.name .. ".layout")
[6718]63    if self.window == nil then
64        error("Could not load layout file for GUI sheet '"..self.name.."'")
65    end
66    -- Hide it at first
67    self:hide()
68    -- Allow sheets to do some work upon loading
[6720]69    self:onLoad()
[6748]70
71    -- Also load additional sheets to avoid display lags
72    if self.loadAlong then
73        for k, sheet in pairs(self.loadAlong) do
74            loadSheet(sheet)
75        end
76    end
[5559]77    return self
[5491]78end
79
[7922]80-- Handles key pressed while the gui sheed is displayed
81function P:keyPressed()
82    if self.buttons then
83        if code == "208" then     -- key down
84            self:moveSelection(1, 0)
85        elseif code == "200" then -- key up
86            self:moveSelection(-1, 0)
87        elseif code == "205" then -- key right
88            self:moveSelection(0, 1)
89        elseif code == "203" then -- key left
90            self:moveSelection(0, -1)
91        elseif code == "28"  then -- key enter
92            self:pressSelectedButton()
93        end
94    end
95
96    self.onKeyPressed()
[7689]97end
98
[7922]99-- Override this function if you want to ract on keystrokes
100function P:onKeyPressed()
101end
102
103
104-------------------------------------------------------------------------------
105-- Keyboard control -----------------------------------------------------------
106-------------------------------------------------------------------------------
107
108-- Initializes the buttons table, used to control the menu with the keyboard
109function P:initButtons(rows, columns)
110    self.rows = rows
111    self.columns = columns
112    self.buttons = {}
113    self.selectedRow = 0
114    self.selectedColumn = 0
115end
116
117-- Defines the button for a given position in the table. The upper-left button is at position (1, 1)
118function P:setButton(row, column, button)
119    assert(self.rows ~= nil and self.columns ~= nil and self.buttons ~= nil, "You have to call initButtons() before using setButton()")
120    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 .. ")")
121
122    self.buttons[(row - 1) * self.columns + (column - 1)] = button
123end
124
125-- Returns the button at a given position in the table. The upper-left button is at position (1, 1)
126function P:getButton(row, column)
127    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 .. ")")
128
129    return self.buttons[(row - 1) * self.columns + (column - 1)]
130end
131
132-- Returns the selected button
133function P:getSelectedButton()
134    assert(self.selectedRow > 0 and self.selectedColumn > 0, "no button selected")
135
136    return self:getButton(self.selectedRow, self.selectedColumn)
137end
138
139-- Presses the selected button if any
140function P:pressSelectedButton()
141    if self:hasSelection() then
[7925]142        self.pressedEnter = true
[7922]143        self:getSelectedButton().callback()
[7925]144        self.pressedEnter = false
[7922]145    end
146end
147
148-- Sets the selection to a given row and column. The upper-left button is at position (1, 1)
149function P:setSelection(row, column)
150    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 .. ")")
151
152    if self:hasSelection() then
153        self:setButtonStateNormal()
154    end
155
156    self.selectedRow = row
157    self.selectedColumn = column
158
159    self:setButtonStateSelected()
160end
161
162-- Moves the selection by a given number of rows and columns (positive values mean increasing row/column, negative values mean decreasing row/column)
163function P:moveSelection(relRow, relColumn)
164    -- if there's no selection yet, prepare it such that the selection enters the table from the desired side
165    if self:hasSelection() == false then
166        -- note: we assume either relRow or relColumn is 0, thus no diagonal movement. therefore the following checks can be separated
167        if relRow > 0 then
168            self.selectedRow = 0
169            self.selectedColumn = 1
170        elseif relRow < 0 then
171            self.selectedRow = self.rows + 1
172            self.selectedColumn = 1
173        end
174
175        if relColumn > 0 then
176            self.selectedRow = 1
177            self.selectedColumn = 0
178        elseif relColumn < 0 then
179            self.selectedRow = 1
180            self.selectedColumn = self.columns + 1
181        end
182    else
183        self:setButtonStateNormal()
184    end
185
186    -- move the selection according to the parameters
187    self.selectedRow = self.selectedRow + relRow
188    self.selectedColumn = self.selectedColumn + relColumn
189
190    -- wrap around on overflow
191    while self.selectedRow > self.rows do
192        self.selectedRow = self.selectedRow - self.rows
193    end
194    while self.selectedColumn > self.columns do
195        self.selectedColumn = self.selectedColumn - self.columns
196    end
197
198    -- wrap around on underflow
199    while self.selectedRow <= 0 do
200        self.selectedRow = self.selectedRow + self.rows
201    end
202    while self.selectedColumn <= 0 do
203        self.selectedColumn = self.selectedColumn + self.columns
204    end
205
206    -- if the button is deactivated, call this function again
207    if self:getSelectedButton() == nil then
208        self:moveSelection(relRow, relColumn)
209    else
210        self:setButtonStateSelected()
211    end
212end
213
214-- Resets the selection
215function P:resetSelection()
216    if self:hasSelection() then
217        self:setButtonStateNormal()
218    end
219
220    self.selectedRow = 0
221    self.selectedColumn = 0
222end
223
224-- Determines if a button is selected
225function P:hasSelection()
226    if self.selectedRow == 0 or self.selectedColumn == 0 then
227        return false
228    else
229        return true
230    end
231end
232
233-- Sets the selected button's state to normal
234function P:setButtonStateNormal()
235    self:setButtonState("Normal")
236end
237
238-- Sets the selected button's state to selected
239function P:setButtonStateSelected()
240    self:setButtonState("Selected")
241end
242
243-- Sets the selected button's state to pushed
244function P:setButtonStatePushed()
245    self:setButtonState("Pushed")
246end
247
248-- Sets the selected button's state
249function P:setButtonState(state)
250    if self:getSelectedButton() then
251        local element = self:getSelectedButton().button
252        local offset = getElementStateOffset(element)
253
254        if offset then
255            element:setProperty("NormalImageRightEdge",  string.sub(element:getProperty("NormalImageRightEdge"),  1, offset) .. state)
256            element:setProperty("NormalImageLeftEdge",   string.sub(element:getProperty("NormalImageLeftEdge"),   1, offset) .. state)
257            element:setProperty("NormalImageBackground", string.sub(element:getProperty("NormalImageBackground"), 1, offset) .. state)
258        end
259    end
260end
261
262-- Gets the offset of the button's current state
263function getElementStateOffset(element)
264    local property = element:getProperty("NormalImageRightEdge")
265
266    if string.sub(property, string.len(property) - 5, string.len(property)) == "Normal" then
267        return -7
268    elseif string.sub(property, string.len(property) - 7, string.len(property)) == "Selected" then
269        return -9
270    elseif string.sub(property, string.len(property) - 5, string.len(property)) == "Pushed" then
271        return -7
272    else
273        return nil
274    end
275end
276
[5661]277return P
Note: See TracBrowser for help on using the repository browser.