rubygoo 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +5 -0
- data/Manifest.txt +2 -0
- data/TODO +1 -4
- data/lib/rubygoo.rb +14 -13
- data/lib/rubygoo/adapters/adapter_factory.rb +12 -9
- data/lib/rubygoo/adapters/gosu_app_adapter.rb +510 -7
- data/lib/rubygoo/adapters/gosu_render_adapter.rb +52 -38
- data/lib/rubygoo/adapters/rubygame_app_adapter.rb +36 -29
- data/lib/rubygoo/adapters/rubygame_render_adapter.rb +39 -37
- data/lib/rubygoo/app.rb +77 -64
- data/lib/rubygoo/button.rb +43 -41
- data/lib/rubygoo/check_box.rb +58 -56
- data/lib/rubygoo/container.rb +106 -96
- data/lib/rubygoo/css_colors.rb +152 -150
- data/lib/rubygoo/dialog.rb +35 -36
- data/lib/rubygoo/goo_color.rb +14 -6
- data/lib/rubygoo/goo_event.rb +10 -8
- data/lib/rubygoo/label.rb +36 -34
- data/lib/rubygoo/mouse_cursor.rb +21 -0
- data/lib/rubygoo/rect.rb +602 -0
- data/lib/rubygoo/text_field.rb +244 -243
- data/lib/rubygoo/widget.rb +122 -114
- data/samples/gosu_app.rb +11 -4
- data/samples/rubygame_app.rb +2 -0
- data/themes/default/config.yml +8 -5
- metadata +4 -2
data/lib/rubygoo/text_field.rb
CHANGED
@@ -1,301 +1,302 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Rubygoo
|
2
|
+
class TextField < Widget
|
3
|
+
SPACE = " "
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# TODO make widget respect these?
|
9
|
-
@max_length = opts[:max_length]
|
10
|
-
@min_length = opts[:min_length]
|
5
|
+
def initialize(text, opts={})
|
6
|
+
super opts
|
7
|
+
@text = text
|
11
8
|
|
12
|
-
|
13
|
-
|
9
|
+
# TODO make widget respect these?
|
10
|
+
@max_length = opts[:max_length]
|
11
|
+
@min_length = opts[:min_length]
|
14
12
|
|
15
|
-
|
16
|
-
# note: this will override default behavior such as K_RIGHT and
|
17
|
-
# such
|
18
|
-
# Example:
|
19
|
-
# text_field.on_key K_RETURN, K_KP_ENTER do |evt|
|
20
|
-
# puts "BOO-YAH"
|
21
|
-
# end
|
22
|
-
def on_key(*keys, &block)
|
23
|
-
for key in keys
|
24
|
-
@key_handlers[key] ||= []
|
25
|
-
@key_handlers[key] << block
|
13
|
+
@key_handlers = {}
|
26
14
|
end
|
27
|
-
end
|
28
15
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
if @w == 1
|
43
|
-
# we have the default from widget, we want to set the
|
44
|
-
# default to 6 chars wide and 1 char tall
|
45
|
-
size = @app.renderer.size_text "MMMMMM", @font_file, @font_size
|
46
|
-
@min_w = size[0]
|
47
|
-
@min_h = size[1]
|
16
|
+
# Allows for registering callbacks for various key presses.
|
17
|
+
# note: this will override default behavior such as K_RIGHT and
|
18
|
+
# such
|
19
|
+
# Example:
|
20
|
+
# text_field.on_key K_RETURN, K_KP_ENTER do |evt|
|
21
|
+
# puts "BOO-YAH"
|
22
|
+
# end
|
23
|
+
def on_key(*keys, &block)
|
24
|
+
for key in keys
|
25
|
+
@key_handlers[key] ||= []
|
26
|
+
@key_handlers[key] << block
|
27
|
+
end
|
48
28
|
end
|
49
29
|
|
50
|
-
|
51
|
-
|
30
|
+
def added()
|
31
|
+
font = theme_property :font
|
32
|
+
@font_size = theme_property :font_size
|
33
|
+
@color = theme_property :color
|
34
|
+
@fg_color = theme_property :fg_color
|
35
|
+
@bg_color = theme_property :bg_color
|
36
|
+
@bg_select_color = theme_property :bg_select_color
|
37
|
+
@fg_select_color = theme_property :fg_select_color
|
38
|
+
@focus_color = theme_property :focus_color
|
39
|
+
@border_color = theme_property :border_color
|
40
|
+
|
41
|
+
@font_file = File.join(@app.theme_dir,font)
|
42
|
+
|
43
|
+
if @w == 1
|
44
|
+
# we have the default from widget, we want to set the
|
45
|
+
# default to 6 chars wide and 1 char tall
|
46
|
+
size = @app.renderer.size_text "MMMMMM", @font_file, @font_size
|
47
|
+
@min_w = size[0]
|
48
|
+
@min_h = size[1]
|
49
|
+
end
|
52
50
|
|
53
|
-
|
54
|
-
if @text.empty?
|
55
|
-
w = [@w,@min_w].max + @x_pad
|
56
|
-
h = [@h,@min_h].max + @y_pad
|
57
|
-
@rendered_text = nil
|
58
|
-
@rect = Rect.new [@x,@y,w,h]
|
59
|
-
else
|
60
|
-
@rendered_text = @app.renderer.render_text @text, @font_file, @font_size, @color
|
61
|
-
w = [@rendered_text.width,@min_w].max + @x_pad
|
62
|
-
h = [@rendered_text.height,@min_h].max + @y_pad
|
63
|
-
@rect = Rect.new [@x,@y,w,h]
|
51
|
+
set_text @text
|
64
52
|
end
|
65
|
-
end
|
66
53
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
54
|
+
def render()
|
55
|
+
if @text.empty?
|
56
|
+
w = [@w,@min_w].max + @x_pad
|
57
|
+
h = [@h,@min_h].max + @y_pad
|
58
|
+
@rendered_text = nil
|
59
|
+
@rect = Rect.new [@x,@y,w,h]
|
60
|
+
else
|
61
|
+
@rendered_text = @app.renderer.render_text @text, @font_file, @font_size, @color
|
62
|
+
w = [@rendered_text.width,@min_w].max + @x_pad
|
63
|
+
h = [@rendered_text.height,@min_h].max + @y_pad
|
64
|
+
@rect = Rect.new [@x,@y,w,h]
|
65
|
+
end
|
76
66
|
end
|
77
67
|
|
78
|
-
|
68
|
+
def set_text(text)
|
69
|
+
if text.nil?
|
70
|
+
@text = ""
|
71
|
+
@caret_pos = 0
|
72
|
+
@select_pos = 0
|
73
|
+
else
|
74
|
+
@text = text
|
75
|
+
@caret_pos = text.length
|
76
|
+
@select_pos = @caret_pos
|
77
|
+
end
|
79
78
|
|
80
|
-
|
79
|
+
render
|
81
80
|
|
82
|
-
def draw(screen)
|
83
|
-
screen.fill @fg_color, @rect
|
84
|
-
screen.fill @bg_color, [@rect[0]-2,@rect[1]-2,@rect[2]+4,@rect[3]+4]
|
85
|
-
if @border_color
|
86
|
-
x1 = @rect[0] - 2
|
87
|
-
y1 = @rect[1] - 2
|
88
|
-
x2 = @rect[2] + x1 + 4
|
89
|
-
y2 = @rect[3] + y1 + 4
|
90
|
-
screen.draw_box x1, y1, x2, y2, @border_color
|
91
81
|
end
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
82
|
+
|
83
|
+
def draw(screen)
|
84
|
+
screen.fill @fg_color, @rect
|
85
|
+
screen.fill @bg_color, [@rect[0]-2,@rect[1]-2,@rect[2]+4,@rect[3]+4]
|
86
|
+
if @border_color
|
87
|
+
x1 = @rect[0] - 2
|
88
|
+
y1 = @rect[1] - 2
|
89
|
+
x2 = @rect[2] + x1 + 4
|
90
|
+
y2 = @rect[3] + y1 + 4
|
91
|
+
screen.draw_box x1, y1, x2, y2, @border_color
|
92
|
+
end
|
93
|
+
defaultY = @app.renderer.size_text(@text.slice(0,1),@font_file,@font_size)[1]
|
94
|
+
x,y,w,h = @rect
|
95
|
+
if @focussed
|
96
|
+
caretX = @app.renderer.size_text(@text.slice(0,@caret_pos),@font_file,@font_size)[0]
|
97
|
+
unless @select_pos.nil?
|
98
|
+
# draw selection highlight
|
99
|
+
selectX = @app.renderer.size_text(@text.slice(0,@select_pos),@font_file,@font_size)[0]
|
100
|
+
selectX0 = [caretX, selectX].min
|
101
|
+
selectX1 = [caretX, selectX].max
|
102
|
+
if selectX0 < selectX1
|
103
|
+
# TODO cache this height
|
104
|
+
screen.fill(@bg_select_color, [x+1+selectX0, y+1, selectX1-selectX0, defaultY])
|
105
|
+
end
|
104
106
|
end
|
105
107
|
end
|
106
|
-
end
|
107
108
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
unless @text.nil? or @text.empty?
|
110
|
+
@rendered_text = @app.renderer.render_text @text, @font_file, @font_size, @color
|
111
|
+
screen.draw_image @rendered_text, x+1, y+1, @color
|
112
|
+
end
|
112
113
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
114
|
+
# draw caret
|
115
|
+
if @focussed
|
116
|
+
screen.fill(@fg_select_color, [x+1+caretX, y+1, 1, defaultY])
|
117
|
+
end
|
117
118
|
|
118
|
-
|
119
|
-
|
120
|
-
|
119
|
+
# don't really need this??
|
120
|
+
return @rect
|
121
|
+
end
|
121
122
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
123
|
+
def on_unfocus()
|
124
|
+
@caret_pos = 0
|
125
|
+
@select_pos = 0
|
126
|
+
end
|
126
127
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
128
|
+
def on_focus()
|
129
|
+
@select_pos = @text.length
|
130
|
+
@caret_pos = @text.length
|
131
|
+
end
|
131
132
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
133
|
+
def find_mouse_position(pos)
|
134
|
+
# put hit position in window relative coords
|
135
|
+
x = pos[0] - @rect[0]
|
136
|
+
y = pos[1] - @rect[1]
|
137
|
+
|
138
|
+
# find the horizontal position within the text by binary search
|
139
|
+
l,r = 0, @text.length
|
140
|
+
c = 0
|
141
|
+
while l < r
|
142
|
+
c = (l + r + 1) / 2
|
143
|
+
w = @app.renderer.size_text(@text.slice(l,c-l), @font_file, @font_size)[0]
|
144
|
+
if x >= w
|
145
|
+
l = c
|
146
|
+
x -= w
|
147
|
+
else
|
148
|
+
if r == c
|
149
|
+
if x > w / 2
|
150
|
+
l = l + 1
|
151
|
+
end
|
152
|
+
break
|
150
153
|
end
|
151
|
-
break
|
152
|
-
end
|
153
154
|
|
154
|
-
|
155
|
+
r = c
|
156
|
+
end
|
155
157
|
end
|
158
|
+
return l
|
156
159
|
end
|
157
|
-
return l
|
158
|
-
end
|
159
|
-
|
160
|
-
def mouse_down(event)
|
161
|
-
x = event.data[:x]
|
162
|
-
y = event.data[:y]
|
163
|
-
return 0 unless contains?([x,y])
|
164
|
-
|
165
|
-
# TODO rework focus and mouse events
|
166
|
-
# getFocus()
|
167
|
-
@caret_pos = find_mouse_position([x,y])
|
168
|
-
@select_pos = @caret_pos
|
169
|
-
@dragging = true
|
170
|
-
render
|
171
|
-
end
|
172
160
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
@caret_pos = find_mouse_position([x,y])
|
178
|
-
render
|
179
|
-
end
|
161
|
+
def mouse_down(event)
|
162
|
+
x = event.data[:x]
|
163
|
+
y = event.data[:y]
|
164
|
+
return 0 unless contains?([x,y])
|
180
165
|
|
181
|
-
|
182
|
-
|
183
|
-
|
166
|
+
# TODO rework focus and mouse events
|
167
|
+
# getFocus()
|
168
|
+
@caret_pos = find_mouse_position([x,y])
|
169
|
+
@select_pos = @caret_pos
|
170
|
+
@dragging = true
|
171
|
+
render
|
184
172
|
end
|
185
|
-
x = event.data[:x]
|
186
|
-
y = event.data[:y]
|
187
|
-
@caret_pos = find_mouse_position([x,y])
|
188
|
-
@dragging = false
|
189
|
-
render
|
190
|
-
end
|
191
173
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
174
|
+
def mouse_motion(event)
|
175
|
+
return 0 unless @dragging
|
176
|
+
x = event.data[:x]
|
177
|
+
y = event.data[:y]
|
178
|
+
@caret_pos = find_mouse_position([x,y])
|
179
|
+
render
|
196
180
|
end
|
197
181
|
|
198
|
-
|
199
|
-
@
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
182
|
+
def mouse_up(event)
|
183
|
+
if not @dragging
|
184
|
+
return 0
|
185
|
+
end
|
186
|
+
x = event.data[:x]
|
187
|
+
y = event.data[:y]
|
188
|
+
@caret_pos = find_mouse_position([x,y])
|
189
|
+
@dragging = false
|
190
|
+
render
|
191
|
+
end
|
207
192
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
handler.call event
|
193
|
+
def delete_selected()
|
194
|
+
return if @select_pos == @caret_pos
|
195
|
+
if @caret_pos > @select_pos
|
196
|
+
@caret_pos, @select_pos = @select_pos, @caret_pos
|
213
197
|
end
|
214
198
|
|
199
|
+
@text = @text.slice(0, @caret_pos) +
|
200
|
+
@text.slice(@select_pos,@text.length-@select_pos)
|
215
201
|
render
|
216
|
-
|
202
|
+
@select_pos = @caret_pos
|
217
203
|
end
|
218
204
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
205
|
+
def key_pressed(event)
|
206
|
+
return if not @focussed
|
207
|
+
@dragging = false
|
208
|
+
|
209
|
+
mods = event.data[:mods]
|
210
|
+
handlers = @key_handlers[event.data[:key]]
|
211
|
+
unless handlers.nil?
|
212
|
+
for handler in handlers
|
213
|
+
handler.call event
|
214
|
+
end
|
215
|
+
|
216
|
+
render
|
217
|
+
return
|
223
218
|
end
|
224
|
-
|
225
|
-
|
219
|
+
|
220
|
+
case event.data[:key]
|
221
|
+
when K_LEFT
|
222
|
+
if @caret_pos > 0
|
226
223
|
@caret_pos -= 1
|
227
224
|
end
|
228
|
-
|
229
|
-
@caret_pos
|
225
|
+
if mods.include? K_LCTRL or mods.include? K_RCTRL
|
226
|
+
while @caret_pos > 0 and @text.slice(@caret_pos - 1,1) == SPACE
|
227
|
+
@caret_pos -= 1
|
228
|
+
end
|
229
|
+
while @caret_pos > 0 and not @text.slice(@caret_pos - 1,1) == SPACE
|
230
|
+
@caret_pos -= 1
|
231
|
+
end
|
230
232
|
end
|
231
|
-
end
|
232
233
|
|
233
|
-
|
234
|
-
|
235
|
-
|
234
|
+
unless mods.include? K_LSHIFT or mods.include? K_RSHIFT
|
235
|
+
@select_pos = @caret_pos
|
236
|
+
end
|
236
237
|
|
237
|
-
|
238
|
-
|
239
|
-
@caret_pos += 1
|
240
|
-
end
|
241
|
-
if mods.include? K_LCTRL or mods.include? K_RCTRL
|
242
|
-
while @caret_pos < @text.length and not @text.slice(@caret_pos,1) == SPACE
|
238
|
+
when K_RIGHT
|
239
|
+
if @caret_pos < @text.length
|
243
240
|
@caret_pos += 1
|
244
241
|
end
|
245
|
-
|
246
|
-
@caret_pos
|
242
|
+
if mods.include? K_LCTRL or mods.include? K_RCTRL
|
243
|
+
while @caret_pos < @text.length and not @text.slice(@caret_pos,1) == SPACE
|
244
|
+
@caret_pos += 1
|
245
|
+
end
|
246
|
+
while @caret_pos < @text.length and @text.slice(@caret_pos,1) == SPACE
|
247
|
+
@caret_pos += 1
|
248
|
+
end
|
249
|
+
end
|
250
|
+
unless mods.include? K_LSHIFT or mods.include? K_RSHIFT
|
251
|
+
@select_pos = @caret_pos
|
247
252
|
end
|
248
|
-
end
|
249
|
-
unless mods.include? K_LSHIFT or mods.include? K_RSHIFT
|
250
|
-
@select_pos = @caret_pos
|
251
|
-
end
|
252
253
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
254
|
+
when K_HOME
|
255
|
+
@caret_pos = 0
|
256
|
+
unless mods.include? K_LSHIFT or mods.include? K_RSHIFT
|
257
|
+
@select_pos = @caret_pos
|
258
|
+
end
|
258
259
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
260
|
+
when K_END
|
261
|
+
@caret_pos = @text.length
|
262
|
+
unless mods.include? K_LSHIFT or mods.include? K_RSHIFT
|
263
|
+
@select_pos = @caret_pos
|
264
|
+
end
|
264
265
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
266
|
+
when K_BACKSPACE
|
267
|
+
if @select_pos != @caret_pos
|
268
|
+
delete_selected()
|
269
|
+
elsif @caret_pos > 0
|
270
|
+
@text = @text.slice(0,@caret_pos-1) + @text.slice(@caret_pos,@text.length-@caret_pos)
|
271
|
+
@caret_pos -= 1
|
272
|
+
@select_pos = @caret_pos
|
273
|
+
end
|
273
274
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
275
|
+
when K_DELETE
|
276
|
+
if @select_pos != @caret_pos:
|
277
|
+
delete_selected()
|
278
|
+
elsif @caret_pos < @text.length:
|
279
|
+
@text = @text.slice(0,@caret_pos) + @text.slice(@caret_pos+1,@text.length-@caret_pos-1)
|
280
|
+
@select_pos = @caret_pos
|
281
|
+
end
|
281
282
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
283
|
+
when *KEY2ASCII.keys
|
284
|
+
# add regular text to the box
|
285
|
+
if @caret_pos == @select_pos
|
286
|
+
@text = @text.slice(0,@caret_pos) + event.data[:string] + @text.slice(@caret_pos,@text.length-@caret_pos)
|
287
|
+
@caret_pos += 1
|
288
|
+
else
|
289
|
+
positions = [@caret_pos,@select_pos]
|
290
|
+
min = positions.min
|
291
|
+
max = positions.max
|
292
|
+
@text = @text.slice(0,min) + event.data[:string] + @text.slice(max,@text.length-max)
|
293
|
+
@caret_pos = min + 1
|
294
|
+
end
|
295
|
+
|
296
|
+
@select_pos = @caret_pos
|
294
297
|
end
|
295
298
|
|
296
|
-
|
299
|
+
render
|
297
300
|
end
|
298
|
-
|
299
|
-
render
|
300
301
|
end
|
301
302
|
end
|