1-- Copyright (C) 2012 Jared Krinke. 2-- 3-- This is free software; you can redistribute it and/or 4-- modify it under the terms of the GNU General Public License 5-- as published by the Free Software Foundation; either version 2 6-- of the License, or (at your option) any later version. 7-- 8-- This program is distributed in the hope that it will be useful, 9-- but WITHOUT ANY WARRANTY; without even the implied warranty of 10-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11-- GNU General Public License for more details. 12-- 13-- You should have received a copy of the GNU General Public License 14-- along with this program; if not, write to the Free Software 15-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 17require("UI/Input.lua") 18require("UI/Label.lua") 19require("UI/Button.lua") 20require("UI/Form.lua") 21 22-- Helper layer for setting a new control 23local rawEventCaptureLayer = Layer.new(-1) 24 25rawEventCaptureLayer:addChild(Entity.new(0, 0, 0, Form.defaultTextWidth, Form.defaultTextHeight, 0, Color.new(1, 1, 1), ElementList.new(Element.Text.new("Press any key", 0, 0, 0, 1, 1, 0, Color.new(1, 1, 1), "center")))) 26 27-- TODO: Add some UI for binding (preferably without hiding lower layers) 28function rawEventCaptureLayer.rawEventReceived(self, rawEvent, pressed) 29 if isString(rawEvent) then 30 if pressed then 31 self.rawEvent = rawEvent 32 elseif not pressed and not isNil(self.rawEvent) then 33 Layers.pop() 34 35 if isFunction(self.rawEventCaptured) then 36 self.rawEventCaptured() 37 end 38 end 39 end 40end 41 42function rawEventCaptureLayer.keyPressed(self, key, pressed, character) 43 self:rawEventReceived(key, pressed) 44end 45 46function rawEventCaptureLayer.mouseButtonPressed(self, button, pressed, x, y) 47 self:rawEventReceived(button, pressed) 48end 49 50function rawEventCaptureLayer.joystickButtonPressed(self, joystick, button, pressed) 51 self:rawEventReceived(Input.translateJoystickButtonToRawEvent(joystick, button), pressed) 52end 53 54function rawEventCaptureLayer.joystickAxisMoved(self, joystick, axis, value) 55 local rawEventPressed 56 local rawEventReleased 57 58 rawEventPressed, rawEventReleased = Input.translateJoystickAxisMoveToRawEvent(self, joystick, axis, value) 59 60 self:rawEventReceived(rawEventPressed, true) 61 self:rawEventReceived(rawEventReleased, false) 62end 63 64function rawEventCaptureLayer.capture(self, rawEventCaptured) 65 self.rawEvent = nil 66 self.rawEventCaptured = rawEventCaptured 67 Layers.push(self) 68end 69 70function rawEventCaptureLayer.getRawEvent(self) 71 return self.rawEvent 72end 73 74local function writeRawEventsToStringBuffer(rawEvents, stringBuffer) 75 local first = true 76 77 stringBuffer:clear() 78 79 if isTable(rawEvents) then 80 rawEvents:forEach(function(rawEvent) 81 if first then 82 first = false 83 else 84 stringBuffer:append(" ") 85 end 86 87 stringBuffer:append(rawEvent) 88 end) 89 end 90end 91 92-- The actual control component 93Control = { } 94 95function Control.new(input, logicalEvent, name) 96 local labelText = logicalEvent 97 98 if isString(name) then 99 labelText = name 100 end 101 102 local rawEvents = Label.new("", "right") 103 local control = Form.newNestedBox({ left = Button.new(labelText), center = rawEvents }) 104 105 control.input = input 106 control.logicalEvent = logicalEvent 107 control.rawEvents = rawEvents 108 control.buffer = StringBuffer.new() 109 110 function control.notified(self) 111 writeRawEventsToStringBuffer(self.input:getRawEvents(self.logicalEvent), self.buffer) 112 self.rawEvents:setText(self.buffer.text) 113 self:layout() 114 end 115 116 function control.activated(self) 117 rawEventCaptureLayer:capture(function() 118 self.input:bind(rawEventCaptureLayer:getRawEvent(), self.logicalEvent) 119 end) 120 end 121 122 -- Treat as one component 123 control.mouseMoved = nil 124 125 -- Override inputReceived 126 control.inputReceivedBase = control.inputReceived 127 128 function control.inputReceived(self, event, pressed) 129 local handled = false 130 131 if event == "delete" and pressed then 132 -- Remove oldest binding 133 local rawEvents = self.input:getRawEvents(self.logicalEvent) 134 135 if rawEvents:getCount() > 0 then 136 self.input:unbind(rawEvents:get(1), self.logicalEvent) 137 end 138 139 handled = true 140 end 141 142 if not handled then 143 handled = self:inputReceivedBase(event, pressed) 144 end 145 146 return handled 147 end 148 149 input:addListener(function() control:notified() end) 150 control:notified() 151 152 return control 153end 154 155