/ld27

To get this branch, use:
bzr branch http://9ix.org/bzr/ld27
1 by Josh C
zoetrope 1.4
1
-- Class: TextInput
2
-- This is like a <Text> object, only it listens to user input and
3
-- adjusts its text property accordingly.
4
--
5
-- Extends:
6
--		<Text>
7
--
8
-- Events:
9
--		onChange - Occurs when the input's text has changed, either by a
10
--				   user's input or programmtically.
11
--		onType - Occurs when the input is about to accept input from a key.
12
--				 This event handler is passed the key about to be inserted.
13
--				 If the handler returns false, *not* nil or any other value,
14
--				 then the key is ignored.
15
16
TextInput = Text:extend{
17
	text = '',
18
19
	-- Property: listening
20
	-- Whether the input is currently listening to input.
21
	listening = true,
22
23
	-- Property: caret
24
	-- This shows the current insert position.
25
	caret = 0,
26
27
	-- Property: blinkRate
28
	-- How quickly the caret blinks, in seconds.
29
	blinkRate = 0.5,
30
31
	-- internal property: _blinkTimer
32
	-- Used to keep track of caret blinking.
33
	_blinkTimer = 0,
34
35
	-- internal property: _repeatKey
36
	-- Used to keep track of what movement key is being held down.
37
	
38
	-- internal property: _repeatTimer
39
	-- Used to keep track of how quickly movement keys repeat.
40
41
	-- internal property: _caretHeight
42
	-- How tall the caret is onscreen, based on the font.
43
44
	-- internal property: _caretX
45
	-- Where to draw the caret, relative to the sprite's x position.
46
47
	update = function (self, elapsed)
48
		if self.listening then
49
			-- listen to normal keys
50
51
			if the.keys.typed ~= '' then
52
				if (self.onType and self:onType(the.keys.typed)) or not self.onType then
53
					self.text = string.sub(self.text, 1, self.caret) .. the.keys.typed
54
								.. string.sub(self.text, self.caret + 1)
55
					self.caret = self.caret + string.len(the.keys.typed)
56
				end
57
			end
58
59
			if the.keys:justPressed('home') then
60
				self.caret = 0
61
			end
62
63
			if the.keys:justPressed('end') then
64
				self.caret = string.len(self.text)
65
			end
66
67
			-- handle movement keys that repeat
68
69
			local frameAction
70
71
			for _, key in pairs{'backspace', 'delete', 'left', 'right'} do
72
				if the.keys:pressed(key) then
35 by Josh C
cluke009 zoetrope + my spritebatch changes
73
					frameAction = key
74
					if the.keys:alreadyHandled(key) then
75
						frameAction = nil
1 by Josh C
zoetrope 1.4
76
					end
77
				end
78
			end
79
35 by Josh C
cluke009 zoetrope + my spritebatch changes
80
1 by Josh C
zoetrope 1.4
81
			if frameAction == 'backspace' and self.caret > 0 then
82
				self.text = string.sub(self.text, 1, self.caret - 1) .. string.sub(self.text, self.caret + 1)
83
				self.caret = self.caret - 1
84
			end
85
86
			if frameAction == 'delete' and self.caret < string.len(self.text) then
87
				self.text = string.sub(self.text, 1, self.caret) .. string.sub(self.text, self.caret + 2)
88
			end
89
90
			if frameAction == 'left' and self.caret > 0 then
91
				self.caret = self.caret - 1
92
			end
93
94
			if frameAction == 'right' and self.caret < string.len(self.text) then
95
				self.caret = self.caret + 1
96
			end
97
		end
98
99
		-- update caret position
100
101
		if self._set.caret ~= self.caret and self._fontObj then
102
			self._caretX = self._fontObj:getWidth(string.sub(self.text, 1, self.caret))
103
			self._caretHeight = self._fontObj:getHeight()
104
			self._set.caret = self.caret
105
		end
106
107
		-- update caret timer
108
109
		self._blinkTimer = self._blinkTimer + elapsed
110
		if self._blinkTimer > self.blinkRate * 2 then self._blinkTimer = 0 end
111
112
		-- call onChange handler as needed
113
114
		if self.text ~= self._set.text then
115
			if self.onChange then self:onChange() end
116
			self._set.text = self.text
117
		end
118
119
		Text.update(self, elapsed)
120
	end,
121
122
	draw = function (self, x, y)
123
		if self.visible then
124
			x = x or self.x
125
			y = y or self.y
126
127
			Text.draw(self, x, y)
128
129
			-- draw caret
130
			
131
			if (self._repeatKey or self._blinkTimer < self.blinkRate) and
132
			   (self._caretX and self._caretHeight) then
133
				love.graphics.setLineWidth(1)
134
				love.graphics.line(x + self._caretX, y, x + self._caretX, y + self._caretHeight)
135
			end
136
		end
137
	end
138
}