Class: AuthorEngine::CodeEditor::Cursor
- Inherits:
-
Object
- Object
- AuthorEngine::CodeEditor::Cursor
show all
- Includes:
- Part::Colors, Support
- Defined in:
- lib/author_engine/code_editor/cursor.rb
Constant Summary
Part::Colors::COLORS
Instance Attribute Summary collapse
Instance Method Summary
collapse
#black, #blue, #brown, #dark_blue, #dark_gray, #dark_green, #dark_purple, #green, #indigo, #light_gray, #orange, #peach, #pink, #red, #rgb, #white, #xml_color, #yellow
Methods included from Support
#code_editor, #mouse_over?, #sprite_editor, #window
Constructor Details
#initialize(view:, text_input:, text:) ⇒ Cursor
Returns a new instance of Cursor.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
# File 'lib/author_engine/code_editor/cursor.rb', line 8
def initialize(view:, text_input:, text:)
@view = view
@text_input = text_input
@text = text
@x, @y = 0, 0
@last_blink = Gosu.milliseconds
@blink_interval = 250
@show = false
@newline_data = {}
@active_line = 0
@active_line_history_size = 2
@active_line_history_index = 0
@active_line_history = []
@highlight_color = Gosu::Color.rgba(dark_gray.red, dark_gray.green, dark_gray.blue, 100)
@selection_color = window.lighten(Gosu::Color.rgba(@view.background.red, @view.background.green, @view.background.blue, 100), 100)
@repeatable_keys = [
{
key: Gosu::KbUp,
down: false,
repeat_delay: 50,
last_repeat: 0,
action: proc {move(:up)}
},
{
key: Gosu::KbDown,
down: false,
repeat_delay: 50,
last_repeat: 0,
action: proc {move(:down)}
}
]
caret_stay_left_of_last_newline
end
|
Instance Attribute Details
#active_line ⇒ Object
Returns the value of attribute active_line.
7
8
9
|
# File 'lib/author_engine/code_editor/cursor.rb', line 7
def active_line
@active_line
end
|
#line_x ⇒ Object
Returns the value of attribute line_x.
7
8
9
|
# File 'lib/author_engine/code_editor/cursor.rb', line 7
def line_x
@line_x
end
|
Instance Method Details
#build_newline_data ⇒ Object
159
160
161
162
163
164
165
166
167
168
169
170
|
# File 'lib/author_engine/code_editor/cursor.rb', line 159
def build_newline_data
i = 0
virt_caret = 0
@text_input.text.each_line do |line|
virt_caret += line.length
@newline_data[i] = {position_end_of_line: virt_caret-1, text: line.chomp, text_length: line.chomp.length}
i+=1
end
end
|
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/author_engine/code_editor/cursor.rb', line 74
def button_down(id)
@repeatable_keys.detect do |key|
if key[:key] == id
key[:down] = true
key[:last_repeat] = Gosu.milliseconds + key[:repeat_delay]
return true
end
end
case id
when Gosu::KbA
select_all if window.control_button_down?
end
end
|
89
90
91
92
93
94
95
96
97
98
99
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
|
# File 'lib/author_engine/code_editor/cursor.rb', line 89
def button_up(id)
@repeatable_keys.detect do |key|
if key[:key] == id
key[:down] = false
return true
end
end
caret_stay_left_of_last_newline
case id
when Gosu::MsLeft
return unless @view.mouse_inside_view?
index = row_at(window.mouse_y)
line = @newline_data.dig(index)
return unless line right_offset = column_at((window.mouse_x + @view.x_offset.abs) - @text.x, window.mouse_y)
pos = (line[:position_end_of_line] - line[:text_length]) + right_offset
set_position(pos)
when Gosu::KbHome
line = @newline_data[last_active_line(0)]
pos = line[:position_end_of_line] - line[:text_length]
set_position(pos)
when Gosu::KbEnd
line = @newline_data[last_active_line(@newline_data.size-1)]
pos = line[:position_end_of_line]
set_position(pos)
end
end
|
#calculate_active_line ⇒ Object
172
173
174
175
|
# File 'lib/author_engine/code_editor/cursor.rb', line 172
def calculate_active_line
sub_text = @text_input.text[0..position]
@active_line = sub_text.lines.size-1
end
|
#calculate_x_and_y ⇒ Object
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
# File 'lib/author_engine/code_editor/cursor.rb', line 177
def calculate_x_and_y
@y = @text.y + (@active_line * @text.height)
if position == 0
@x = 0
return
end
line = @text_input.text[0..position-1].lines[@active_line]
sub_text = ""
if line
sub_text = line[0..position-1]
end
@x = @text.font.markup_width(sub_text)
end
|
#calculate_x_offset ⇒ Object
194
195
196
197
198
199
200
201
|
# File 'lib/author_engine/code_editor/cursor.rb', line 194
def calculate_x_offset
two_zeros = @text.font.text_width("00")
if @x + two_zeros > @view.width - @text.x
@view.x_offset = (@view.width - @text.x) - (@x + two_zeros)
else
@view.x_offset = 0
end
end
|
#calculate_y_offset ⇒ Object
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
# File 'lib/author_engine/code_editor/cursor.rb', line 219
def calculate_y_offset
y_offset = @view.height - ((@text.y - (window.container. - (@text.height*2))) + (@active_line * @text.height))
if y_offset > 0 y_offset = 0
else
top = (@text.y + @view.y_offset.abs) + @text.height
bottom = (@text.y + @view.y_offset.abs + @view.height) - @text.height * 2
if (@y).between?(top, bottom) y_offset = @view.y_offset
elsif @y < top && y_offset <= 0
y_offset = @view.y_offset + @text.height
end
end
@view.y_offset = y_offset
end
|
#caret_stay_left_of_last_newline ⇒ Object
212
213
214
215
216
217
|
# File 'lib/author_engine/code_editor/cursor.rb', line 212
def caret_stay_left_of_last_newline
@text_input.text+="\n" unless @text_input.text.end_with?("\n")
eof = @text_input.text.chomp.length
set_position(eof) if position > eof
end
|
#column_at(x, y, y_is_line = false) ⇒ Object
returns the column for x on line y
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/author_engine/code_editor/cursor.rb', line 137
def column_at(x, y, y_is_line = false)
x = @text.x if x < x-@text.x
line = @newline_data.dig(row_at(y)) unless y_is_line
line = @newline_data.dig(y) if y_is_line
column= 0
return unless line
text = line[:text]
buffer= ""
local_x=0
text.size.times do |i|
local_x = @text.font.text_width(buffer)
break if local_x >= x
column+=1
buffer+=text.chars[i]
end
return column
end
|
#draw ⇒ Object
48
49
50
51
52
|
# File 'lib/author_engine/code_editor/cursor.rb', line 48
def draw
highlight_activeline
highlight_selection
Gosu.draw_rect(@text.x + @x, @y, 1, @text.height, light_gray) if @show
end
|
#highlight_activeline ⇒ Object
265
266
267
|
# File 'lib/author_engine/code_editor/cursor.rb', line 265
def highlight_activeline
Gosu.draw_rect(0 - @view.x_offset, @y, @view.width, @text.height, @highlight_color)
end
|
#highlight_selection ⇒ Object
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
|
# File 'lib/author_engine/code_editor/cursor.rb', line 269
def highlight_selection
return if @text_input.selection_start == position
line = @newline_data[@active_line]
selection_x = 0
if @text_input.selection_start < position
selection_x = @text.font.text_width(@text_input.text[@text_input.selection_start..position-1])
Gosu.draw_rect((@x + @text.x) - selection_x, @text.y + (@active_line * @text.height), selection_x, @text.height, @selection_color)
else
selection_x = @text.font.text_width(@text_input.text[position..@text_input.selection_start-1])
Gosu.draw_rect((@x + @text.x), @text.y + (@active_line * @text.height), selection_x, @text.height, @selection_color)
end
end
|
#last_active_line(poison) ⇒ Object
poison: line index at which home is 0 and end is @newline_data.size-1
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
# File 'lib/author_engine/code_editor/cursor.rb', line 250
def last_active_line(poison)
candidate = @active_line
list = @active_line_history.reject{|l| l == poison}
return candidate unless list
candidate = list.reverse.first if list.size > 0
return candidate
end
|
#move(direction) ⇒ Object
300
301
302
303
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
329
330
331
332
333
334
335
336
|
# File 'lib/author_engine/code_editor/cursor.rb', line 300
def move(direction)
pos = @text_input.caret_pos
line = nil
if direction == :up
return if @active_line == 0
line = @newline_data.dig(@active_line-1)
return unless line above_offset = column_at(@x, (@active_line-1), true)
right_offset = above_offset
pos = (line[:position_end_of_line] - line[:text_length]) + right_offset
elsif direction == :down
return if @text_input.caret_pos == @text_input.text.size
return unless @newline_data[@active_line+1]
line = @newline_data.dig(@active_line+1)
return unless line below_offset = column_at(@x, (@active_line+1), true)
right_offset = below_offset
pos = (line[:position_end_of_line] - line[:text_length]) + right_offset
else
raise ":up or :down please."
end
set_position(pos)
end
|
#position ⇒ Object
286
287
288
|
# File 'lib/author_engine/code_editor/cursor.rb', line 286
def position
@text_input.caret_pos
end
|
#row_at(y) ⇒ Object
returns the line of lines from the top that y is at
132
133
134
|
# File 'lib/author_engine/code_editor/cursor.rb', line 132
def row_at(y)
return (((y.to_f - window.container..to_f) - @view.y_offset.to_f) / @text.height).floor
end
|
#select_all ⇒ Object
295
296
297
298
|
# File 'lib/author_engine/code_editor/cursor.rb', line 295
def select_all
@text_input.selection_start = 0
@text_input.caret_pos = @text_input.text.length-1
end
|
#set_position(int) ⇒ Object
290
291
292
293
|
# File 'lib/author_engine/code_editor/cursor.rb', line 290
def set_position(int)
@text_input.caret_pos = int
@text_input.selection_start = int end
|
#update ⇒ Object
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/author_engine/code_editor/cursor.rb', line 54
def update
if (Gosu.milliseconds - @last_blink) > @blink_interval
@last_blink = Gosu.milliseconds
@show = !@show
end
update_caret
update_active_line_history
@repeatable_keys.each do |key|
if key[:down]
if Gosu.milliseconds > key[:last_repeat] + key[:repeat_delay]
key[:action].call
key[:last_repeat] = Gosu.milliseconds
end
end
end
end
|
#update_active_line_history ⇒ Object
239
240
241
242
243
244
245
246
247
|
# File 'lib/author_engine/code_editor/cursor.rb', line 239
def update_active_line_history
@active_line_history_index = 0 unless @active_line_history_index < @active_line_history_size
unless @active_line_history[@active_line_history_index-1] == @active_line
@active_line_history[@active_line_history_index] = @active_line
@active_line_history_index+=1
end
end
|
#update_caret ⇒ Object
203
204
205
206
207
208
209
210
|
# File 'lib/author_engine/code_editor/cursor.rb', line 203
def update_caret
build_newline_data
calculate_active_line
calculate_x_and_y
calculate_x_offset
calculate_y_offset
end
|