Class: GlimR::TextInput
- Inherits:
-
Label
show all
- Defined in:
- lib/glimr/widgets/text_editor.rb
Overview
TextInput is a single-line text input widget.
Constant Summary
collapse
- @@xsel =
false
Constants included
from Layoutable
Layoutable::DIMENSIONS
Instance Attribute Summary collapse
Attributes inherited from Image
#bound, #image
Attributes inherited from Widget
#focused, #hover
Attributes included from Layoutable
#align, #valign
Attributes inherited from Model
#geometry, #material, #shader, #texture, #transform
Attributes inherited from SceneObject
#children, #drawables, #mtime, #parent, #viewport
#event_listeners, #listener_count
Instance Method Summary
collapse
-
#as_alpha(pixels, alpha) ⇒ Object
-
#change! ⇒ Object
-
#clear_selection(new_cursor_position = [@selection_start, @selection_end].min) ⇒ Object
-
#click(o, e) ⇒ Object
-
#cursor_position_closest_to(cx, cy) ⇒ Object
-
#default_config ⇒ Object
-
#draw_text(x_offset = @scroll_x, y_offset = @scroll_y) ⇒ Object
-
#initialize(*a, &b) ⇒ TextInput
constructor
A new instance of TextInput.
-
#key_up(o, e) ⇒ Object
-
#layout ⇒ Object
-
#mouse_down(o, e) ⇒ Object
-
#mouse_move(o, e) ⇒ Object
-
#mouse_up(o, e) ⇒ Object
-
#replace_selection_with(str) ⇒ Object
-
#selection ⇒ Object
-
#selection_range ⇒ Object
-
#submit ⇒ Object
-
#text=(text) ⇒ Object
-
#update_on_frame ⇒ Object
-
#update_selection ⇒ Object
-
#update_text(o, e) ⇒ Object
-
#update_text_offsets ⇒ Object
Methods inherited from Image
#create_colors, #create_normals, #create_texcoords, #create_vertices, #load, load, load_theme, #load_theme, #texture=, #update_geometry
Methods inherited from Widget
#activate, #blur, #focus, for, #key_down, #lock, #mouse_out, #mouse_over, #unlock
Methods included from Layoutable
#attach, #children_change, #constant_size?, #detach, #expand!, #expand?, #expand_height, #expand_to_max_height!, #expand_to_max_width!, #expand_width, #fit_height!, #fit_to_children!, #fit_width!, #free_height, #free_width, #full_depth, #full_height, #full_width, #inner_depth, #inner_height, #inner_width, #inspect, #layoutable_children, #margin, #margin=, #max_height=, #max_width=, #min_height=, #min_width=, #padding, #padding=, #parent=, #size_changing, size_changing_accessor, #tell_children_of_size_change, #x=, #y=
Methods inherited from Model
#absolute_transform, #apply, #inspect, #pop_state, #push_state
Methods inherited from SceneObject
#<<, #absolute_geometry, #absolute_material, #absolute_shader, #absolute_texture, #absolute_transform, #absolute_transform_for_drawing, #add_drawables, #apply, #attach, #clone, #detach, #detach_self, #inspect, #pop_state, #push_state, #remove_drawables, #render, #replace_node, #root, #touch!, #visible
#add_event_listener, #decrement_listener_count, #dispatch_event, #event_root, #increment_listener_count, #method_missing, #multicast_event, #process_event, #remove_event_listener
Constructor Details
#initialize(*a, &b) ⇒ TextInput
Returns a new instance of TextInput.
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# File 'lib/glimr/widgets/text_editor.rb', line 68
def initialize(*a,&b)
if a[0]
txt = a[0][:text]
a[0].delete(:text)
end
super(*a, &nil)
@texture.pixels = "\000" * (@width*@height*4)
@texture.width = @width
@texture.height = @height
@bound = @texture.bound
update_geometry
if a[0]
self.text = txt if txt
end
@cursor.height = @height - 2
@cursor.y = 1
@cursor.z = -0.1
attach @cursor
@background.set_dimensions(@width, @height)
@background.z = -0.2
attach @background
if block_given?
self.submit_handler = b
end
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
in the class GlimR::EventListener
Instance Attribute Details
#cursor_position ⇒ Object
Returns the value of attribute cursor_position.
48
49
50
|
# File 'lib/glimr/widgets/text_editor.rb', line 48
def cursor_position
@cursor_position
end
|
Returns the value of attribute scroll_x.
46
47
48
|
# File 'lib/glimr/widgets/text_editor.rb', line 46
def scroll_x
@scroll_x
end
|
Returns the value of attribute scroll_y.
46
47
48
|
# File 'lib/glimr/widgets/text_editor.rb', line 46
def scroll_y
@scroll_y
end
|
#selection_end ⇒ Object
Returns the value of attribute selection_end.
48
49
50
|
# File 'lib/glimr/widgets/text_editor.rb', line 48
def selection_end
@selection_end
end
|
#selection_start ⇒ Object
Returns the value of attribute selection_start.
48
49
50
|
# File 'lib/glimr/widgets/text_editor.rb', line 48
def selection_start
@selection_start
end
|
#submit_handler ⇒ Object
Returns the value of attribute submit_handler.
49
50
51
|
# File 'lib/glimr/widgets/text_editor.rb', line 49
def submit_handler
@submit_handler
end
|
Instance Method Details
#as_alpha(pixels, alpha) ⇒ Object
330
331
332
333
334
335
336
337
|
# File 'lib/glimr/widgets/text_editor.rb', line 330
def as_alpha(pixels, alpha)
i = 3
while i < pixels.size
pixels[i] = alpha[i-1]
i += 4
end
pixels
end
|
251
252
253
254
|
# File 'lib/glimr/widgets/text_editor.rb', line 251
def change!
dispatch_event(Event.new(:change, :text => @text))
update_on_frame
end
|
#clear_selection(new_cursor_position = [@selection_start, @selection_end].min) ⇒ Object
226
227
228
229
230
231
|
# File 'lib/glimr/widgets/text_editor.rb', line 226
def clear_selection(new_cursor_position=[@selection_start, @selection_end].min)
@selecting = false
@text_selected = false
@cursor.use_normal
self.cursor_position = new_cursor_position
end
|
#click(o, e) ⇒ Object
161
162
163
164
165
166
167
168
169
170
|
# File 'lib/glimr/widgets/text_editor.rb', line 161
def click(o,e)
if e.button == :left
clear_selection if @text_selected
self.cursor_position = cursor_position_closest_to(e.rx, e.ry)
elsif e.button == :middle and @@xsel
x_sel = IO.popen("#@@xsel -o", "r"){|f| f.read }
replace_selection_with x_sel
@cursor_position += x_sel.size
end
end
|
#cursor_position_closest_to(cx, cy) ⇒ Object
233
234
235
236
237
238
239
240
241
242
243
|
# File 'lib/glimr/widgets/text_editor.rb', line 233
def cursor_position_closest_to(cx,cy)
index = nil
@text_offsets.each_with_index{|(x,y), i|
if x + scroll_x > cx
index = [i-1, 0].max
break
end
}
index ||= @text.size
index
end
|
#default_config ⇒ Object
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# File 'lib/glimr/widgets/text_editor.rb', line 51
def default_config
super.merge(
:fit_children => false,
:align => :left,
:text => "",
:width => 150,
:height => 16,
:scroll_x => 0,
:scroll_y => 0,
:background => StretchableImage.load_theme("text_input_bg.png"),
:cursor => TextCursor.new,
:cursor_position => 0,
:selection_start => 0,
:selection_end => 0
)
end
|
#draw_text(x_offset = @scroll_x, y_offset = @scroll_y) ⇒ Object
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
|
# File 'lib/glimr/widgets/text_editor.rb', line 304
def draw_text x_offset=@scroll_x, y_offset=@scroll_y
GC.disable
w,h = @width, @height
rmask = 0xff000000
gmask = 0x00ff0000
bmask = 0x0000ff00
amask = 0x000000ff
mask = SDL::Surface.new(
SDL::SWSURFACE|SDL::SRCALPHA,
w, h, 32,
amask,bmask,gmask,rmask)
mask.fill_rect(0,0, w,h, [0,0,0,255])
@sdl_font.draw_blended_utf8(
mask, text,
x_offset, y_offset,
255, 255, 255
)
image = SDL::Surface.new(
SDL::SWSURFACE|SDL::SRCALPHA,
w, h, 32,
amask,bmask,gmask,rmask)
image.fill_rect(0,0, w,h, color.map{|i|(i*255).to_i})
texture.pixels = as_alpha(image.pixels, mask.pixels)
GC.enable
end
|
#key_up(o, e) ⇒ Object
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/glimr/widgets/text_editor.rb', line 100
def key_up(o,e)
return unless focused
case e.key
when :left
clear_selection if @text_selected
self.cursor_position -= 1
when :right
clear_selection if @text_selected
self.cursor_position += 1
when 8 if @text_selected
replace_selection_with ""
elsif self.cursor_position > 0
@text[self.cursor_position-1] = ""
self.text = @text
@cursor_position -= 1
end
when 127 if @text_selected
replace_selection_with ""
elsif self.cursor_position < @text.size
@text[self.cursor_position] = ""
self.text = @text
end
when 13 submit
else
if @text_selected
replace_selection_with e.key.chr
cp = [@selection_start, @selection_end].min
else
cp = self.cursor_position
@text.insert(cp, e.key.chr)
self.text = @text
end
@cursor_position = cp + 1
end
end
|
280
281
|
# File 'lib/glimr/widgets/text_editor.rb', line 280
def layout
end
|
#mouse_down(o, e) ⇒ Object
172
173
174
175
176
177
178
|
# File 'lib/glimr/widgets/text_editor.rb', line 172
def mouse_down(o,e)
if e.button == :left
@sx, @sy = e.rx, e.ry
@selection_start = @selection_end = cursor_position_closest_to(@sx, @sy)
end
super
end
|
#mouse_move(o, e) ⇒ Object
190
191
192
193
194
195
196
197
198
|
# File 'lib/glimr/widgets/text_editor.rb', line 190
def mouse_move(o,e)
if @sx and @sy
@selecting = true
@sx += e.dx
@sy += e.dy
@selection_end = cursor_position_closest_to(@sx, @sy)
update_selection
end
end
|
#mouse_up(o, e) ⇒ Object
180
181
182
183
184
185
186
187
188
|
# File 'lib/glimr/widgets/text_editor.rb', line 180
def mouse_up(o,e)
super unless @selecting
if e.button == :left and @selecting
@selecting = false
@selection_end = cursor_position_closest_to(@sx, @sy)
update_selection
end
@sx = @sy = false
end
|
#replace_selection_with(str) ⇒ Object
143
144
145
146
147
|
# File 'lib/glimr/widgets/text_editor.rb', line 143
def replace_selection_with str
@text[selection_range] = str
clear_selection
self.text = @text
end
|
#selection ⇒ Object
157
158
159
|
# File 'lib/glimr/widgets/text_editor.rb', line 157
def selection
@text[selection_range]
end
|
#selection_range ⇒ Object
149
150
151
152
153
154
155
|
# File 'lib/glimr/widgets/text_editor.rb', line 149
def selection_range
if @selection_start > @selection_end
(@selection_end...@selection_start) else
(@selection_start..@selection_end)
end
end
|
139
140
141
|
# File 'lib/glimr/widgets/text_editor.rb', line 139
def submit
dispatch_event(Event.new(:submit, :text => @text))
end
|
#text=(text) ⇒ Object
245
246
247
248
249
|
# File 'lib/glimr/widgets/text_editor.rb', line 245
def text= text
@text = text
@text_changed = true
change!
end
|
#update_on_frame ⇒ Object
256
257
258
259
260
|
# File 'lib/glimr/widgets/text_editor.rb', line 256
def update_on_frame
if not @updater
@updater = on_frame(:update_text)
end
end
|
#update_selection ⇒ Object
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
# File 'lib/glimr/widgets/text_editor.rb', line 200
def update_selection
if @@xsel
IO.popen("#@@xsel -i", "w"){|f| f.write selection }
end
ss = @text_offsets[@selection_start][0]
se = @text_offsets[@selection_end][0]
d = se - ss
self.cursor_position = @selection_end
ex = @cursor.x
ew = @cursor.width
if d > 0 @cursor.x = [0, ex - d].max @cursor.width = ex + ew - @cursor.x else @cursor.x = ex
@cursor.width = [@width - ex, -d].min
end
@cursor.use_insert
@text_selected = true
dispatch_event(
Event.new(
:select, :selection => selection,
:start => @selection_start, :end => @selection_end))
end
|
#update_text(o, e) ⇒ Object
283
284
285
286
287
288
289
290
291
292
293
294
295
|
# File 'lib/glimr/widgets/text_editor.rb', line 283
def update_text(o,e)
if @text_changed
@text_offsets = false
@text_changed = false
end
update_text_offsets
self.cursor_position = self.cursor_position
update_selection if @selecting
draw_text
touch!
remove_event_listener(:frame, @updater)
@updater = false
end
|
#update_text_offsets ⇒ Object
297
298
299
300
301
302
|
# File 'lib/glimr/widgets/text_editor.rb', line 297
def update_text_offsets
@sdl_font = SDL::TTF.open(font, size)
@text_offsets ||= (0..text.size).map{|i|
@sdl_font.text_size(text[0,i])
}
end
|