cyberarm_engine 0.13.1 → 0.17.1
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/Gemfile +1 -1
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/assets/textures/default.png +0 -0
- data/cyberarm_engine.gemspec +12 -9
- data/lib/cyberarm_engine.rb +20 -5
- data/lib/cyberarm_engine/animator.rb +6 -4
- data/lib/cyberarm_engine/background.rb +19 -15
- data/lib/cyberarm_engine/background_nine_slice.rb +125 -0
- data/lib/cyberarm_engine/bounding_box.rb +18 -18
- data/lib/cyberarm_engine/cache.rb +4 -0
- data/lib/cyberarm_engine/cache/download_manager.rb +121 -0
- data/lib/cyberarm_engine/common.rb +16 -16
- data/lib/cyberarm_engine/config_file.rb +2 -2
- data/lib/cyberarm_engine/game_object.rb +63 -72
- data/lib/cyberarm_engine/game_state.rb +6 -3
- data/lib/cyberarm_engine/model.rb +207 -0
- data/lib/cyberarm_engine/model/material.rb +21 -0
- data/lib/cyberarm_engine/model/model_object.rb +131 -0
- data/lib/cyberarm_engine/model/parser.rb +74 -0
- data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -0
- data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -0
- data/lib/cyberarm_engine/model_cache.rb +31 -0
- data/lib/cyberarm_engine/opengl.rb +28 -0
- data/lib/cyberarm_engine/opengl/light.rb +50 -0
- data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -0
- data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -0
- data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -0
- data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -0
- data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +289 -0
- data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -0
- data/lib/cyberarm_engine/{shader.rb → opengl/shader.rb} +51 -43
- data/lib/cyberarm_engine/opengl/texture.rb +69 -0
- data/lib/cyberarm_engine/ray.rb +5 -5
- data/lib/cyberarm_engine/stats.rb +21 -0
- data/lib/cyberarm_engine/text.rb +45 -31
- data/lib/cyberarm_engine/timer.rb +1 -1
- data/lib/cyberarm_engine/transform.rb +43 -20
- data/lib/cyberarm_engine/ui/border_canvas.rb +4 -3
- data/lib/cyberarm_engine/ui/dsl.rb +49 -10
- data/lib/cyberarm_engine/ui/element.rb +73 -21
- data/lib/cyberarm_engine/ui/elements/button.rb +121 -28
- data/lib/cyberarm_engine/ui/elements/check_box.rb +25 -33
- data/lib/cyberarm_engine/ui/elements/container.rb +113 -33
- data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -0
- data/lib/cyberarm_engine/ui/elements/edit_line.rb +145 -45
- data/lib/cyberarm_engine/ui/elements/flow.rb +1 -3
- data/lib/cyberarm_engine/ui/elements/image.rb +32 -12
- data/lib/cyberarm_engine/ui/elements/label.rb +122 -16
- data/lib/cyberarm_engine/ui/elements/list_box.rb +82 -0
- data/lib/cyberarm_engine/ui/elements/progress.rb +6 -5
- data/lib/cyberarm_engine/ui/elements/radio.rb +6 -0
- data/lib/cyberarm_engine/ui/elements/slider.rb +104 -0
- data/lib/cyberarm_engine/ui/elements/stack.rb +1 -3
- data/lib/cyberarm_engine/ui/elements/text_block.rb +156 -0
- data/lib/cyberarm_engine/ui/elements/toggle_button.rb +40 -31
- data/lib/cyberarm_engine/ui/event.rb +7 -7
- data/lib/cyberarm_engine/ui/gui_state.rb +118 -6
- data/lib/cyberarm_engine/ui/style.rb +10 -9
- data/lib/cyberarm_engine/ui/theme.rb +84 -22
- data/lib/cyberarm_engine/vector.rb +33 -30
- data/lib/cyberarm_engine/version.rb +2 -2
- data/lib/cyberarm_engine/{engine.rb → window.rb} +32 -19
- metadata +87 -18
- data/lib/cyberarm_engine/gosu_ext/circle.rb +0 -9
@@ -2,13 +2,32 @@ module CyberarmEngine
|
|
2
2
|
class Element
|
3
3
|
class CheckBox < Flow
|
4
4
|
def initialize(text, options, block = nil)
|
5
|
-
super(
|
5
|
+
super(options, block)
|
6
6
|
options[:toggled] = options[:checked]
|
7
7
|
|
8
8
|
@toggle_button = ToggleButton.new(options)
|
9
|
-
@label =
|
9
|
+
@label = TextBlock.new(text, options)
|
10
10
|
|
11
|
-
|
11
|
+
@label.subscribe(:holding_left_mouse_button) do |sender, x, y|
|
12
|
+
@toggle_button.left_mouse_button(sender, x, y)
|
13
|
+
end
|
14
|
+
|
15
|
+
@label.subscribe(:released_left_mouse_button) do |sender, x, y|
|
16
|
+
@toggle_button.released_left_mouse_button(sender, x, y)
|
17
|
+
end
|
18
|
+
|
19
|
+
@label.subscribe(:clicked_left_mouse_button) do |sender, x, y|
|
20
|
+
@toggle_button.clicked_left_mouse_button(sender, x, y)
|
21
|
+
publish(:changed, @toggle_button.value)
|
22
|
+
end
|
23
|
+
|
24
|
+
@label.subscribe(:enter) do |sender|
|
25
|
+
@toggle_button.enter(sender)
|
26
|
+
end
|
27
|
+
|
28
|
+
@label.subscribe(:leave) do |sender|
|
29
|
+
@toggle_button.leave(sender)
|
30
|
+
end
|
12
31
|
|
13
32
|
add(@toggle_button)
|
14
33
|
add(@label)
|
@@ -24,36 +43,9 @@ module CyberarmEngine
|
|
24
43
|
end
|
25
44
|
|
26
45
|
def value=(bool)
|
27
|
-
@toggle_button.
|
28
|
-
|
29
|
-
|
30
|
-
def define_label_singletons
|
31
|
-
@label.define_singleton_method(:_toggle_button) do |button|
|
32
|
-
@_toggle_button = button
|
33
|
-
end
|
34
|
-
|
35
|
-
@label._toggle_button(@toggle_button)
|
36
|
-
|
37
|
-
@label.define_singleton_method(:holding_left_mouse_button) do |sender, x, y|
|
38
|
-
@_toggle_button.left_mouse_button(sender, x, y)
|
39
|
-
end
|
40
|
-
|
41
|
-
@label.define_singleton_method(:released_left_mouse_button) do |sender, x, y|
|
42
|
-
@_toggle_button.released_left_mouse_button(sender, x, y)
|
43
|
-
end
|
44
|
-
|
45
|
-
@label.define_singleton_method(:clicked_left_mouse_button) do |sender, x, y|
|
46
|
-
@_toggle_button.clicked_left_mouse_button(sender, x, y)
|
47
|
-
end
|
48
|
-
|
49
|
-
@label.define_singleton_method(:enter) do |sender|
|
50
|
-
@_toggle_button.enter(sender)
|
51
|
-
end
|
52
|
-
|
53
|
-
@label.define_singleton_method(:leave) do |sender|
|
54
|
-
@_toggle_button.leave(sender)
|
55
|
-
end
|
46
|
+
@toggle_button.value = bool
|
47
|
+
publish(:changed, @toggle_button.value)
|
56
48
|
end
|
57
49
|
end
|
58
50
|
end
|
59
|
-
end
|
51
|
+
end
|
@@ -4,31 +4,32 @@ module CyberarmEngine
|
|
4
4
|
include Common
|
5
5
|
|
6
6
|
attr_accessor :stroke_color, :fill_color
|
7
|
-
attr_reader :children, :gui_state
|
8
|
-
attr_reader :scroll_x, :scroll_y
|
7
|
+
attr_reader :children, :gui_state, :scroll_position
|
9
8
|
|
10
9
|
def initialize(options = {}, block = nil)
|
11
10
|
@gui_state = options.delete(:gui_state)
|
12
11
|
super
|
13
12
|
|
14
|
-
@
|
15
|
-
@scroll_speed =
|
13
|
+
@scroll_position = Vector.new(0, 0)
|
14
|
+
@scroll_speed = 40
|
16
15
|
|
17
16
|
@text_color = options[:color]
|
18
17
|
|
19
18
|
@children = []
|
19
|
+
|
20
|
+
event(:window_size_changed)
|
20
21
|
end
|
21
22
|
|
22
23
|
def build
|
23
24
|
@block.call(self) if @block
|
24
25
|
|
25
|
-
|
26
|
+
root.gui_state.request_recalculate
|
26
27
|
end
|
27
28
|
|
28
29
|
def add(element)
|
29
30
|
@children << element
|
30
31
|
|
31
|
-
|
32
|
+
root.gui_state.request_recalculate
|
32
33
|
end
|
33
34
|
|
34
35
|
def clear(&block)
|
@@ -41,7 +42,17 @@ module CyberarmEngine
|
|
41
42
|
|
42
43
|
$__current_container__ = old_container
|
43
44
|
|
44
|
-
|
45
|
+
root.gui_state.request_recalculate
|
46
|
+
end
|
47
|
+
|
48
|
+
def apend(&block)
|
49
|
+
old_container = $__current_container__
|
50
|
+
|
51
|
+
$__current_container__ = self
|
52
|
+
block.call(self) if block
|
53
|
+
|
54
|
+
$__current_container__ = old_container
|
55
|
+
|
45
56
|
root.gui_state.request_recalculate
|
46
57
|
end
|
47
58
|
|
@@ -49,6 +60,31 @@ module CyberarmEngine
|
|
49
60
|
Gosu.clip_to(@x, @y, width, height) do
|
50
61
|
@children.each(&:draw)
|
51
62
|
end
|
63
|
+
|
64
|
+
if false # DEBUG
|
65
|
+
Gosu.flush
|
66
|
+
|
67
|
+
Gosu.draw_line(
|
68
|
+
x, y, Gosu::Color::RED,
|
69
|
+
x + outer_width, y, Gosu::Color::RED,
|
70
|
+
Float::INFINITY
|
71
|
+
)
|
72
|
+
Gosu.draw_line(
|
73
|
+
x + outer_width, y, Gosu::Color::RED,
|
74
|
+
x + outer_width, y + outer_height, Gosu::Color::RED,
|
75
|
+
Float::INFINITY
|
76
|
+
)
|
77
|
+
Gosu.draw_line(
|
78
|
+
x + outer_width, y + outer_height, Gosu::Color::RED,
|
79
|
+
x, y + outer_height, Gosu::Color::RED,
|
80
|
+
Float::INFINITY
|
81
|
+
)
|
82
|
+
Gosu.draw_line(
|
83
|
+
x, outer_height, Gosu::Color::RED,
|
84
|
+
x, y, Gosu::Color::RED,
|
85
|
+
Float::INFINITY
|
86
|
+
)
|
87
|
+
end
|
52
88
|
end
|
53
89
|
|
54
90
|
def update
|
@@ -57,6 +93,8 @@ module CyberarmEngine
|
|
57
93
|
|
58
94
|
def hit_element?(x, y)
|
59
95
|
@children.reverse_each do |child|
|
96
|
+
next unless child.visible?
|
97
|
+
|
60
98
|
case child
|
61
99
|
when Container
|
62
100
|
if element = child.hit_element?(x, y)
|
@@ -72,7 +110,12 @@ module CyberarmEngine
|
|
72
110
|
|
73
111
|
def recalculate
|
74
112
|
@current_position = Vector.new(@style.margin_left + @style.padding_left, @style.margin_top + @style.padding_top)
|
113
|
+
@current_position += @scroll_position
|
114
|
+
|
75
115
|
return unless visible?
|
116
|
+
|
117
|
+
Stats.increment(:gui_recalculations_last_frame, 1)
|
118
|
+
|
76
119
|
stylize
|
77
120
|
|
78
121
|
layout
|
@@ -81,24 +124,26 @@ module CyberarmEngine
|
|
81
124
|
@width = @style.width = window.width
|
82
125
|
@height = @style.height = window.height
|
83
126
|
else
|
84
|
-
@width
|
127
|
+
@width = 0
|
128
|
+
@height = 0
|
85
129
|
|
86
130
|
_width = dimensional_size(@style.width, :width)
|
87
|
-
_height= dimensional_size(@style.height
|
131
|
+
_height = dimensional_size(@style.height, :height)
|
88
132
|
|
89
|
-
@width = _width
|
90
|
-
@height = _height
|
133
|
+
@width = _width || (@children.map { |c| c.x + c.outer_width }.max || 0).round
|
134
|
+
@height = _height || (@children.map { |c| c.y + c.outer_height }.max || 0).round
|
91
135
|
end
|
92
136
|
|
93
|
-
|
94
137
|
# Move child to parent after positioning
|
95
138
|
@children.each do |child|
|
96
|
-
child.x += @x
|
97
|
-
child.y += @y
|
139
|
+
child.x += (@x + @style.border_thickness_left) - style.margin_left
|
140
|
+
child.y += (@y + @style.border_thickness_top) - style.margin_top
|
98
141
|
|
99
142
|
child.stylize
|
100
143
|
child.recalculate
|
101
144
|
child.reposition # TODO: Implement top,bottom,left,center, and right positioning
|
145
|
+
|
146
|
+
Stats.increment(:gui_recalculations_last_frame, 1)
|
102
147
|
end
|
103
148
|
|
104
149
|
update_background
|
@@ -109,32 +154,36 @@ module CyberarmEngine
|
|
109
154
|
end
|
110
155
|
|
111
156
|
def max_width
|
112
|
-
|
157
|
+
_width = dimensional_size(@style.width, :width)
|
158
|
+
if _width
|
159
|
+
outer_width
|
160
|
+
else
|
161
|
+
window.width - (@parent ? @parent.style.margin_right + @style.margin_right : @style.margin_right)
|
162
|
+
end
|
113
163
|
end
|
114
164
|
|
115
165
|
def fits_on_line?(element) # Flow
|
166
|
+
p [@options[:id], @width] if @options[:id]
|
116
167
|
@current_position.x + element.outer_width <= max_width &&
|
117
|
-
|
168
|
+
@current_position.x + element.outer_width <= window.width
|
118
169
|
end
|
119
170
|
|
120
171
|
def position_on_current_line(element) # Flow
|
121
172
|
element.x = element.style.margin_left + @current_position.x
|
122
173
|
element.y = element.style.margin_top + @current_position.y
|
123
174
|
|
124
|
-
element.recalculate
|
125
|
-
|
126
175
|
@current_position.x += element.outer_width
|
127
176
|
@current_position.x = @style.margin_left if @current_position.x >= max_width
|
128
177
|
end
|
129
178
|
|
130
|
-
def tallest_neighbor(querier,
|
179
|
+
def tallest_neighbor(querier, _y_position) # Flow
|
131
180
|
response = querier
|
132
181
|
@children.each do |child|
|
133
182
|
response = child if child.outer_height > response.outer_height
|
134
183
|
break if child == querier
|
135
184
|
end
|
136
185
|
|
137
|
-
|
186
|
+
response
|
138
187
|
end
|
139
188
|
|
140
189
|
def position_on_next_line(child) # Flow
|
@@ -144,8 +193,6 @@ module CyberarmEngine
|
|
144
193
|
child.x = child.style.margin_left + @current_position.x
|
145
194
|
child.y = child.style.margin_top + @current_position.y
|
146
195
|
|
147
|
-
child.recalculate
|
148
|
-
|
149
196
|
@current_position.x += child.outer_width
|
150
197
|
end
|
151
198
|
|
@@ -153,23 +200,56 @@ module CyberarmEngine
|
|
153
200
|
element.x = element.style.margin_left + @current_position.x
|
154
201
|
element.y = element.style.margin_top + @current_position.y
|
155
202
|
|
156
|
-
element.recalculate
|
157
|
-
|
158
203
|
@current_position.y += element.outer_height
|
159
204
|
end
|
160
205
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
# end
|
206
|
+
def mouse_wheel_up(sender, x, y)
|
207
|
+
return unless @style.scroll
|
208
|
+
return if height < max_scroll_height
|
165
209
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
210
|
+
if @scroll_position.y < 0
|
211
|
+
@scroll_position.y += @scroll_speed
|
212
|
+
@scroll_position.y = 0 if @scroll_position.y > 0
|
213
|
+
recalculate
|
214
|
+
|
215
|
+
return :handled
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def mouse_wheel_down(sender, x, y)
|
220
|
+
return unless @style.scroll
|
221
|
+
return if height < max_scroll_height
|
222
|
+
|
223
|
+
if @scroll_position.y.abs < max_scroll_height
|
224
|
+
@scroll_position.y -= @scroll_speed
|
225
|
+
@scroll_position.y = -max_scroll_height if @scroll_position.y.abs > max_scroll_height
|
226
|
+
recalculate
|
227
|
+
|
228
|
+
return :handled
|
229
|
+
end
|
230
|
+
end
|
170
231
|
|
171
232
|
def value
|
172
|
-
@children.map {|c| c.class}.join(", ")
|
233
|
+
@children.map { |c| c.class }.join(", ")
|
234
|
+
end
|
235
|
+
|
236
|
+
def to_s
|
237
|
+
"#{self.class} x=#{x} y=#{y} width=#{width} height=#{height} children=#{@children.size}"
|
238
|
+
end
|
239
|
+
|
240
|
+
def write_tree(indent = "", _index = 0)
|
241
|
+
puts self
|
242
|
+
|
243
|
+
indent += " "
|
244
|
+
@children.each_with_index do |child, i|
|
245
|
+
print "#{indent}#{i}: "
|
246
|
+
|
247
|
+
if child.is_a?(Container)
|
248
|
+
child.write_tree(indent)
|
249
|
+
else
|
250
|
+
puts child
|
251
|
+
end
|
252
|
+
end
|
173
253
|
end
|
174
254
|
end
|
175
255
|
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module CyberarmEngine
|
2
|
+
class Element
|
3
|
+
class EditBox < EditLine
|
4
|
+
def initialize(*args)
|
5
|
+
super(*args)
|
6
|
+
|
7
|
+
@active_line = 0
|
8
|
+
|
9
|
+
@repeatable_keys = [
|
10
|
+
{
|
11
|
+
key: Gosu::KB_UP,
|
12
|
+
down: false,
|
13
|
+
repeat_delay: 50,
|
14
|
+
last_repeat: 0,
|
15
|
+
action: proc { move(:up) }
|
16
|
+
},
|
17
|
+
{
|
18
|
+
key: Gosu::KB_DOWN,
|
19
|
+
down: false,
|
20
|
+
repeat_delay: 50,
|
21
|
+
last_repeat: 0,
|
22
|
+
action: proc { move(:down) }
|
23
|
+
}
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
def update
|
28
|
+
super
|
29
|
+
|
30
|
+
caret_stay_left_of_last_newline
|
31
|
+
calculate_active_line
|
32
|
+
|
33
|
+
@repeatable_keys.each do |key|
|
34
|
+
if key[:down] && (Gosu.milliseconds > key[:last_repeat] + key[:repeat_delay])
|
35
|
+
key[:action].call
|
36
|
+
key[:last_repeat] = Gosu.milliseconds
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def draw_caret
|
42
|
+
Gosu.draw_rect(caret_position, @text.y + @active_line * @text.textobject.height, @caret_width, @caret_height,
|
43
|
+
@caret_color, @z)
|
44
|
+
end
|
45
|
+
|
46
|
+
def draw_selection
|
47
|
+
selection_width = caret_position - selection_start_position
|
48
|
+
|
49
|
+
Gosu.draw_rect(selection_start_position, @text.y, selection_width, @text.textobject.height,
|
50
|
+
default(:selection_color), @z)
|
51
|
+
end
|
52
|
+
|
53
|
+
def text_input_position_for(_method)
|
54
|
+
line = @text_input.text[0...@text_input.caret_pos].lines.last
|
55
|
+
_x = @text.x + @offset_x
|
56
|
+
|
57
|
+
if @type == :password
|
58
|
+
_x + @text.width(default(:password_character) * line.length)
|
59
|
+
else
|
60
|
+
_x + @text.width(line)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_position(int)
|
65
|
+
int = 0 if int < 0
|
66
|
+
@text_input.selection_start = @text_input.caret_pos = int
|
67
|
+
end
|
68
|
+
|
69
|
+
def calculate_active_line
|
70
|
+
sub_text = @text_input.text[0...@text_input.caret_pos]
|
71
|
+
@active_line = sub_text.lines.size - 1
|
72
|
+
end
|
73
|
+
|
74
|
+
def caret_stay_left_of_last_newline
|
75
|
+
@text_input.text += "\n" unless @text_input.text.end_with?("\n")
|
76
|
+
|
77
|
+
eof = @text_input.text.chomp.length
|
78
|
+
set_position(eof) if @text_input.caret_pos > eof
|
79
|
+
end
|
80
|
+
|
81
|
+
def caret_position_under_mouse(mouse_x, mouse_y)
|
82
|
+
active_line = row_at(mouse_y)
|
83
|
+
right_offset = column_at(mouse_x, mouse_y)
|
84
|
+
|
85
|
+
buffer = @text_input.text.lines[0..active_line].join if active_line != 0
|
86
|
+
buffer = @text_input.text.lines.first if active_line == 0
|
87
|
+
line = buffer.lines.last
|
88
|
+
|
89
|
+
if buffer.chars.last == "\n"
|
90
|
+
(buffer.length - line.length) + right_offset - 1
|
91
|
+
else
|
92
|
+
(buffer.length - line.length) + right_offset
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def move_caret_to_mouse(mouse_x, mouse_y)
|
97
|
+
set_position(caret_position_under_mouse(mouse_x, mouse_y))
|
98
|
+
end
|
99
|
+
|
100
|
+
def row_at(y)
|
101
|
+
((y - @text.y) / @text.textobject.height).round
|
102
|
+
end
|
103
|
+
|
104
|
+
def column_at(x, y)
|
105
|
+
row = row_at(y)
|
106
|
+
|
107
|
+
buffer = @text_input.text.lines[0..row].join if row != 0
|
108
|
+
buffer = @text_input.text.lines.first if row == 0
|
109
|
+
|
110
|
+
line = @text_input.text.lines[row]
|
111
|
+
line ||= ""
|
112
|
+
column = 0
|
113
|
+
|
114
|
+
line.length.times do |_i|
|
115
|
+
break if @text.textobject.text_width(line[0...column]) >= (x - @text.x).clamp(0.0, Float::INFINITY)
|
116
|
+
|
117
|
+
column += 1
|
118
|
+
end
|
119
|
+
|
120
|
+
column
|
121
|
+
end
|
122
|
+
|
123
|
+
def button_down(id)
|
124
|
+
super
|
125
|
+
|
126
|
+
@repeatable_keys.detect do |key|
|
127
|
+
next unless key[:key] == id
|
128
|
+
|
129
|
+
key[:down] = true
|
130
|
+
key[:last_repeat] = Gosu.milliseconds + key[:repeat_delay]
|
131
|
+
return true
|
132
|
+
end
|
133
|
+
|
134
|
+
case id
|
135
|
+
when Gosu::KB_ENTER, Gosu::KB_RETURN
|
136
|
+
caret_pos = @text_input.caret_pos
|
137
|
+
@text_input.text = @text_input.text.insert(@text_input.caret_pos, "\n")
|
138
|
+
@text_input.caret_pos = @text_input.selection_start = caret_pos + 1
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def button_up(id)
|
143
|
+
super
|
144
|
+
|
145
|
+
@repeatable_keys.detect do |key|
|
146
|
+
if key[:key] == id
|
147
|
+
key[:down] = false
|
148
|
+
return true
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def move(direction)
|
154
|
+
pos = @text_input.caret_pos
|
155
|
+
line = nil
|
156
|
+
|
157
|
+
case direction
|
158
|
+
when :up
|
159
|
+
return if @active_line == 0
|
160
|
+
when :down
|
161
|
+
return if @active_line == @text_input.text.chomp.lines
|
162
|
+
|
163
|
+
text = @text_input.text.chomp.lines[0..@active_line].join("\n")
|
164
|
+
pos = text.length
|
165
|
+
end
|
166
|
+
|
167
|
+
set_position(pos)
|
168
|
+
end
|
169
|
+
|
170
|
+
def drag_update(_sender, x, y, _button)
|
171
|
+
int = caret_position_under_mouse(x, y)
|
172
|
+
int = 0 if int < 0
|
173
|
+
@text_input.caret_pos = int
|
174
|
+
|
175
|
+
:handled
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|