fidgit 0.1.10 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +11 -0
- data/LICENSE.txt +20 -0
- data/README.textile +1 -1
- data/examples/text_area_example.rb +10 -5
- data/fidgit.gemspec +3 -2
- data/lib/fidgit/elements/element.rb +9 -1
- data/lib/fidgit/elements/text_area.rb +97 -32
- data/lib/fidgit/event.rb +79 -19
- data/lib/fidgit/gosu_ext/color.rb +6 -0
- data/lib/fidgit/version.rb +1 -1
- data/spec/fidgit/event_spec.rb +61 -0
- metadata +26 -24
- data/COPYING.txt +0 -674
data/CHANGELOG.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Fidgit changelog
|
2
|
+
================
|
3
|
+
|
4
|
+
v0.2.0
|
5
|
+
------
|
6
|
+
|
7
|
+
* Added editable attribute to TextArea (Allows selection, but not alteration).
|
8
|
+
* Added Element#font= and :font option.
|
9
|
+
* Added Gosu::Color#colorize to use when using in-line text styling.
|
10
|
+
* Managed layout of entities and XML tags (Used by Gosu) in TextArea text better (tags still don't like newlines inside them).
|
11
|
+
* Changed license from LGPL to MIT.
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Bil Bas (Spooner)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
CHANGED
@@ -4,22 +4,27 @@ class ExampleState < Fidgit::GuiState
|
|
4
4
|
def initialize
|
5
5
|
super
|
6
6
|
|
7
|
+
Gosu.register_entity(:entity, Gosu::Image["head_icon.png"])
|
8
|
+
|
9
|
+
string = "<c=3333ff>Hello, my name</c> is <c=ff0000>Brian</c> the&entity;&entity;snail<c=00ff00>!\nHi\nHello!</c>"
|
7
10
|
horizontal do
|
8
11
|
vertical do
|
9
|
-
label '
|
10
|
-
text_area(width: 200)
|
12
|
+
label 'disabled'
|
13
|
+
text_area(text: "Can't even select this text", width: 200, enabled: false)
|
11
14
|
end
|
12
15
|
|
13
16
|
vertical do
|
14
17
|
label 'mirrors to right'
|
15
|
-
text_area(width: 200, text:
|
18
|
+
text_area(width: 200, text: string) do |_, text|
|
16
19
|
@mirror.text = text
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
20
23
|
vertical do
|
21
|
-
label 'not editable'
|
22
|
-
|
24
|
+
my_label = label 'not editable'
|
25
|
+
font = Gosu::Font.new($window, "", my_label.font.height)
|
26
|
+
font["a"] = Gosu::Image["head_icon.png"]
|
27
|
+
@mirror = text_area(text: string, width: 200, editable: false, font: font)
|
23
28
|
end
|
24
29
|
end
|
25
30
|
end
|
data/fidgit.gemspec
CHANGED
@@ -20,12 +20,13 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
21
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
22
|
s.require_paths = ["lib"]
|
23
|
+
s.license = "MIT"
|
23
24
|
|
24
|
-
s.add_dependency('gosu', '~> 0.7.
|
25
|
+
s.add_dependency('gosu', '~> 0.7.41')
|
25
26
|
s.add_dependency('chingu', '~> 0.9rc7')
|
26
27
|
s.add_dependency('clipboard', '~> 0.9.9')
|
27
28
|
s.add_dependency('ffi', '= 1.0.9') # 1.0.10 is borked :(
|
28
|
-
s.add_development_dependency('rspec', '~> 2.
|
29
|
+
s.add_development_dependency('rspec', '~> 2.8.0')
|
29
30
|
s.add_development_dependency('texplay', '~> 0.3.5')
|
30
31
|
s.add_development_dependency('rake')
|
31
32
|
s.add_development_dependency('yard')
|
@@ -121,6 +121,7 @@ module Fidgit
|
|
121
121
|
# @option options [String] :tip ('') Tool-tip text
|
122
122
|
# @option options [String, :default] :font_name (:default, which resolves as the default Gosu font)
|
123
123
|
# @option options [String] :font_height (30)
|
124
|
+
# @option options [Gosu::Font] :font Use this instead of :font_name and :font_height
|
124
125
|
#
|
125
126
|
# @option options [Gosu::Color] :background_color (transparent)
|
126
127
|
# @option options [Gosu::Color] :border_color (transparent)
|
@@ -191,11 +192,18 @@ module Fidgit
|
|
191
192
|
options[:font_name].dup
|
192
193
|
end
|
193
194
|
|
194
|
-
@font = Gosu::Font[font_name, options[:font_height]]
|
195
|
+
@font = options[:font] || Gosu::Font[font_name, options[:font_height]]
|
195
196
|
|
196
197
|
@rect = Chingu::Rect.new(options[:x], options[:y], options[:width] || 0, options[:height] || 0)
|
197
198
|
end
|
198
199
|
|
200
|
+
def font=(font)
|
201
|
+
raise TypeError unless font.is_a? Gosu::Font
|
202
|
+
@font = font
|
203
|
+
recalc
|
204
|
+
font
|
205
|
+
end
|
206
|
+
|
199
207
|
def recalc
|
200
208
|
old_width, old_height = width, height
|
201
209
|
layout
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Fidgit
|
4
4
|
class TextArea < Element
|
5
|
+
ENTITY_PLACEHOLDER = "*"
|
6
|
+
|
5
7
|
# @return [Number]
|
6
8
|
attr_reader :min_height
|
7
9
|
# @return [Number]
|
@@ -14,13 +16,16 @@ module Fidgit
|
|
14
16
|
# @return [Boolean]
|
15
17
|
attr_writer :editable
|
16
18
|
|
19
|
+
# @return [String] Text, but stripped of tags.
|
20
|
+
attr_reader :stripped_text
|
21
|
+
|
17
22
|
event :changed
|
18
23
|
event :focus
|
19
24
|
event :blur
|
20
25
|
|
21
|
-
# Is the area editable?
|
26
|
+
# Is the area editable? This will always be false if the Element is disabled.
|
22
27
|
def editable?
|
23
|
-
enabled?
|
28
|
+
enabled? and @editable
|
24
29
|
end
|
25
30
|
|
26
31
|
# Text within the element.
|
@@ -43,7 +48,7 @@ module Fidgit
|
|
43
48
|
#
|
44
49
|
# @return [String]
|
45
50
|
def selection_text
|
46
|
-
|
51
|
+
stripped_text[selection_range]
|
47
52
|
end
|
48
53
|
|
49
54
|
# Sets the text within the selection. The caret will be placed at the end of the inserted text.
|
@@ -52,10 +57,14 @@ module Fidgit
|
|
52
57
|
# @return [String] The new selection text.
|
53
58
|
def selection_text=(str)
|
54
59
|
from = [@text_input.selection_start, @text_input.caret_pos].min
|
60
|
+
to = [@text_input.selection_start, @text_input.caret_pos].max
|
55
61
|
new_length = str.length
|
56
62
|
|
57
63
|
full_text = text
|
58
|
-
|
64
|
+
tags_length_before = (0...from).inject(0) {|m, i| m + @tags[i].length }
|
65
|
+
tags_length_inside = (from...to).inject(0) {|m, i| m + @tags[i].length }
|
66
|
+
range = (selection_range.first + tags_length_before)...(selection_range.last + tags_length_before + tags_length_inside)
|
67
|
+
full_text[range] = str.encode('UTF-8', undef: :replace)
|
59
68
|
@text_input.text = full_text
|
60
69
|
|
61
70
|
@text_input.selection_start = @text_input.caret_pos = from + new_length
|
@@ -79,7 +88,7 @@ module Fidgit
|
|
79
88
|
# @param [Integer] pos Position of caret in the text.
|
80
89
|
# @return [Integer] New position of caret.
|
81
90
|
def caret_position=(position)
|
82
|
-
raise ArgumentError, "Caret position must be in the range 0 to the length of the text (inclusive)" unless position.between?(0,
|
91
|
+
raise ArgumentError, "Caret position must be in the range 0 to the length of the text (inclusive)" unless position.between?(0, stripped_text.length)
|
83
92
|
@text_input.caret_pos = position
|
84
93
|
|
85
94
|
position
|
@@ -105,6 +114,7 @@ module Fidgit
|
|
105
114
|
# @option options [Integer] :min_height
|
106
115
|
# @option options [Integer] :max_height (Infinite)
|
107
116
|
# @option options [Number] :line_spacing (0)
|
117
|
+
# @option options [Boolean] :editable (true)
|
108
118
|
def initialize(options = {}, &block)
|
109
119
|
options = {
|
110
120
|
text: '',
|
@@ -116,6 +126,7 @@ module Fidgit
|
|
116
126
|
caret_period: default(:caret_period),
|
117
127
|
focused_border_color: default(:focused, :border_color),
|
118
128
|
selection_color: default(:selection_color),
|
129
|
+
editable: true,
|
119
130
|
}.merge! options
|
120
131
|
|
121
132
|
@line_spacing = options[:line_spacing]
|
@@ -123,6 +134,7 @@ module Fidgit
|
|
123
134
|
@caret_period = options[:caret_period]
|
124
135
|
@focused_border_color = options[:focused_border_color].dup
|
125
136
|
@selection_color = options[:selection_color].dup
|
137
|
+
@editable = options[:editable]
|
126
138
|
|
127
139
|
@lines = [''] # List of lines of wrapped text.
|
128
140
|
@caret_positions = [[0, 0]] # [x, y] of each position the caret can be in.
|
@@ -131,8 +143,10 @@ module Fidgit
|
|
131
143
|
@old_text = ''
|
132
144
|
@old_caret_position = 0
|
133
145
|
@old_selection_start = 0
|
146
|
+
@tags = Hash.new("") # Hash of tags embedded in the text.
|
134
147
|
|
135
148
|
@text_input.text = options[:text].dup
|
149
|
+
@stripped_text = '' # Text stripped of xml tags.
|
136
150
|
|
137
151
|
super(options)
|
138
152
|
|
@@ -195,14 +209,20 @@ module Fidgit
|
|
195
209
|
# @return [nil]
|
196
210
|
def draw_foreground
|
197
211
|
# Always roll back changes made by the user unless the text is editable.
|
198
|
-
if
|
199
|
-
@text_input.text = @old_text
|
200
|
-
@text_input.selection_start = @old_selection_start
|
201
|
-
self.caret_position = @old_caret_position
|
202
|
-
else
|
212
|
+
if editable? or text == @old_text
|
203
213
|
recalc if focused? # Workaround for Windows draw/update bug.
|
204
214
|
@old_caret_position = caret_position
|
205
215
|
@old_selection_start = @text_input.selection_start
|
216
|
+
else
|
217
|
+
roll_back
|
218
|
+
end
|
219
|
+
|
220
|
+
if caret_position > stripped_text.length
|
221
|
+
self.caret_position = stripped_text.length
|
222
|
+
end
|
223
|
+
|
224
|
+
if @text_input.selection_start >= stripped_text.length
|
225
|
+
@text_input.selection_start = stripped_text.length
|
206
226
|
end
|
207
227
|
|
208
228
|
# Draw the selection.
|
@@ -236,7 +256,8 @@ module Fidgit
|
|
236
256
|
# Helper for #recalc
|
237
257
|
# @return [Integer]
|
238
258
|
def position_letters_in_word(word, line_width)
|
239
|
-
word.
|
259
|
+
# Strip tags before measuring word.
|
260
|
+
word.gsub(/<[^>]*>|&[^;];/, '').each_char do |c|
|
240
261
|
char_width = font.text_width(c)
|
241
262
|
line_width += char_width
|
242
263
|
@caret_positions.push [line_width, y_at_line(@lines.size)]
|
@@ -271,8 +292,23 @@ module Fidgit
|
|
271
292
|
word = ''
|
272
293
|
word_width = 0
|
273
294
|
|
274
|
-
|
275
|
-
|
295
|
+
strip_tags
|
296
|
+
|
297
|
+
stripped_text.each_char.with_index do |char, i|
|
298
|
+
tag = @tags[i]
|
299
|
+
|
300
|
+
# \x0 is just a place-holder for an entity: &entity;
|
301
|
+
if char == ENTITY_PLACEHOLDER
|
302
|
+
char = tag
|
303
|
+
tag = ""
|
304
|
+
end
|
305
|
+
|
306
|
+
case char
|
307
|
+
when "\n"
|
308
|
+
char_width = 0
|
309
|
+
else
|
310
|
+
char_width = font.text_width char
|
311
|
+
end
|
276
312
|
|
277
313
|
overall_width = line_width + (line_width == 0 ? 0 : space_width) + word_width + char_width
|
278
314
|
if overall_width > max_width and not (char == ' ' and not word.empty?)
|
@@ -282,7 +318,7 @@ module Fidgit
|
|
282
318
|
position_letters_in_word(word, line_width)
|
283
319
|
|
284
320
|
# Push as much of the current word as possible as a complete line.
|
285
|
-
@lines.push word + (char == ' ' ? '' : '-')
|
321
|
+
@lines.push word + tag + (char == ' ' ? '' : '-')
|
286
322
|
line_width = font.text_width(word)
|
287
323
|
|
288
324
|
word = ''
|
@@ -294,18 +330,18 @@ module Fidgit
|
|
294
330
|
line = ''
|
295
331
|
end
|
296
332
|
|
297
|
-
|
333
|
+
widen_last_character line_width
|
298
334
|
line_width = 0
|
299
335
|
end
|
300
336
|
|
301
337
|
case char
|
302
338
|
when "\n"
|
303
339
|
# A new-line ends the word and puts it on the line.
|
304
|
-
line += word
|
340
|
+
line += word + tag
|
305
341
|
line_width = position_letters_in_word(word, line_width)
|
306
342
|
@caret_positions.push [line_width, y_at_line(@lines.size)]
|
307
|
-
@char_widths[-1] += (width - line_width - (padding_left + padding_right)) unless @char_widths.empty?
|
308
343
|
@char_widths.push 0
|
344
|
+
widen_last_character line_width
|
309
345
|
@lines.push line
|
310
346
|
word = ''
|
311
347
|
word_width = 0
|
@@ -314,7 +350,7 @@ module Fidgit
|
|
314
350
|
|
315
351
|
when ' '
|
316
352
|
# A space ends a word and puts it on the line.
|
317
|
-
line += word + char
|
353
|
+
line += word + tag + char
|
318
354
|
line_width = position_letters_in_word(word, line_width)
|
319
355
|
line_width += space_width
|
320
356
|
@caret_positions.push [line_width, y_at_line(@lines.size)]
|
@@ -330,14 +366,15 @@ module Fidgit
|
|
330
366
|
end
|
331
367
|
|
332
368
|
# Start building up a new word.
|
333
|
-
word += char
|
369
|
+
word += tag + char
|
334
370
|
word_width += char_width
|
335
371
|
end
|
336
372
|
end
|
337
373
|
|
338
374
|
# Add any remaining word on the last line.
|
339
375
|
unless word.empty?
|
340
|
-
position_letters_in_word(word, line_width)
|
376
|
+
line_width = position_letters_in_word(word, line_width)
|
377
|
+
@char_widths << width - line_width - padding_left - padding_right
|
341
378
|
line += word
|
342
379
|
end
|
343
380
|
|
@@ -351,25 +388,32 @@ module Fidgit
|
|
351
388
|
@old_caret_position = caret_position
|
352
389
|
@old_selection_start = @text_input.selection_start
|
353
390
|
else
|
354
|
-
|
355
|
-
@lines = old_lines
|
356
|
-
@caret_positions = old_caret_positions
|
357
|
-
@char_widths = old_char_widths
|
358
|
-
@text_input.text = @old_text
|
359
|
-
self.caret_position = @old_caret_position
|
360
|
-
@text_input.selection_start = @old_selection_start
|
391
|
+
roll_back
|
361
392
|
end
|
362
393
|
|
363
394
|
nil
|
364
395
|
end
|
365
396
|
|
397
|
+
protected
|
398
|
+
def roll_back
|
399
|
+
@text_input.text = @old_text
|
400
|
+
self.caret_position = @old_caret_position
|
401
|
+
@text_input.selection_start = @old_selection_start
|
402
|
+
recalc
|
403
|
+
end
|
404
|
+
|
405
|
+
protected
|
406
|
+
def widen_last_character(line_width)
|
407
|
+
@char_widths[-1] += (width - line_width - padding_left - padding_right) unless @char_widths.empty?
|
408
|
+
end
|
409
|
+
|
366
410
|
public
|
367
411
|
# Cut the selection and copy it to the clipboard.
|
368
412
|
def cut
|
369
413
|
str = selection_text
|
370
|
-
unless
|
414
|
+
unless str.empty?
|
371
415
|
Clipboard.copy str
|
372
|
-
self.selection_text = ''
|
416
|
+
self.selection_text = '' if editable?
|
373
417
|
end
|
374
418
|
end
|
375
419
|
|
@@ -377,9 +421,7 @@ module Fidgit
|
|
377
421
|
# Copy the selection to the clipboard.
|
378
422
|
def copy
|
379
423
|
str = selection_text
|
380
|
-
unless
|
381
|
-
Clipboard.copy str
|
382
|
-
end
|
424
|
+
Clipboard.copy str unless str.empty?
|
383
425
|
end
|
384
426
|
|
385
427
|
public
|
@@ -393,5 +435,28 @@ module Fidgit
|
|
393
435
|
def post_init_block(&block)
|
394
436
|
subscribe :changed, &block
|
395
437
|
end
|
438
|
+
|
439
|
+
protected
|
440
|
+
# Strip XML tags and entities ("<c=000000></c>" and "&entity;")
|
441
|
+
# @note Entities will mess up the system because we don't know how wide they are.
|
442
|
+
def strip_tags
|
443
|
+
tags_length = 0
|
444
|
+
@tags = Hash.new('')
|
445
|
+
|
446
|
+
@stripped_text = text.gsub(%r[(<[^>]*?>|&[^;]+;)]) do |tag|
|
447
|
+
pos = $`.length - tags_length
|
448
|
+
tags_length += tag.length
|
449
|
+
@tags[pos] += tag
|
450
|
+
|
451
|
+
# Entities need to have a non-printing character that can represent them.
|
452
|
+
# Still not right, but does mean there are the right number of characters.
|
453
|
+
if tag[0] == '&'
|
454
|
+
tags_length -= 1
|
455
|
+
ENTITY_PLACEHOLDER # Will be expanded later.
|
456
|
+
else
|
457
|
+
'' # Tags don't use up space, so ignore them.
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
396
461
|
end
|
397
462
|
end
|
data/lib/fidgit/event.rb
CHANGED
@@ -23,23 +23,87 @@ module Fidgit
|
|
23
23
|
# # JumpingBean jumped 4 metres up
|
24
24
|
#
|
25
25
|
module Event
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
# Created and returned by {Event#subscribe} and can be used to unsubscribe from the event.
|
27
|
+
class Subscription
|
28
|
+
attr_reader :publisher, :event, :handler
|
29
|
+
|
30
|
+
def initialize(publisher, event, handler)
|
31
|
+
raise TypeError unless publisher.is_a? Event
|
32
|
+
raise TypeError unless event.is_a? Symbol
|
33
|
+
raise TypeError unless handler.is_a? Proc or handler.is_a? Method
|
34
|
+
|
35
|
+
@publisher, @event, @handler = publisher, event, handler
|
36
|
+
end
|
37
|
+
|
38
|
+
def unsubscribe
|
39
|
+
@publisher.unsubscribe self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class << self
|
44
|
+
def new_event_handlers
|
45
|
+
# Don't use Set, since it is not guaranteed to be ordered.
|
46
|
+
Hash.new {|h, k| h[k] = [] }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Subscription] Definition of this the handler created by this subscription, to be used with {#unsubscribe}
|
33
51
|
def subscribe(event, method = nil, &block)
|
34
52
|
raise ArgumentError, "Expected method or block for event handler" unless !block.nil? ^ !method.nil?
|
35
53
|
raise ArgumentError, "#{self.class} does not handle #{event.inspect}" unless events.include? event
|
36
54
|
|
37
|
-
@_event_handlers ||=
|
38
|
-
|
55
|
+
@_event_handlers ||= Event.new_event_handlers
|
56
|
+
handler = method || block
|
57
|
+
@_event_handlers[event] << handler
|
39
58
|
|
40
|
-
|
59
|
+
Subscription.new self, event, handler
|
41
60
|
end
|
42
61
|
|
62
|
+
# @overload unsubscribe(subscription)
|
63
|
+
# Unsubscribe from a #{Subscription}, as returned from {#subscribe}
|
64
|
+
# @param subscription [Subscription]
|
65
|
+
# @return [Boolean] true if the handler was able to be deleted.
|
66
|
+
#
|
67
|
+
# @overload unsubscribe(handler)
|
68
|
+
# Unsubscribe from first event this handler has been used to subscribe to..
|
69
|
+
# @param handler [Block, Method] Event handler used.
|
70
|
+
# @return [Boolean] true if the handler was able to be deleted.
|
71
|
+
#
|
72
|
+
# @overload unsubscribe(event, handler)
|
73
|
+
# Unsubscribe from specific handler on particular event.
|
74
|
+
# @param event [Symbol] Name of event originally subscribed to.
|
75
|
+
# @param handler [Block, Method] Event handler used.
|
76
|
+
# @return [Boolean] true if the handler was able to be deleted.
|
77
|
+
#
|
78
|
+
def unsubscribe(*args)
|
79
|
+
@_event_handlers ||= Event.new_event_handlers
|
80
|
+
|
81
|
+
case args.size
|
82
|
+
when 1
|
83
|
+
case args.first
|
84
|
+
when Subscription
|
85
|
+
# Delete specific event handler.
|
86
|
+
subscription = args.first
|
87
|
+
raise ArgumentError, "Incorrect publisher for #{Subscription}: #{subscription.publisher}" unless subscription.publisher == self
|
88
|
+
unsubscribe subscription.event, subscription.handler
|
89
|
+
when Proc, Method
|
90
|
+
# Delete first events that use the handler.
|
91
|
+
handler = args.first
|
92
|
+
!!@_event_handlers.find {|_, handlers| handlers.delete handler }
|
93
|
+
else
|
94
|
+
raise TypeError, "handler must be a #{Subscription}, Block or Method: #{args.first}"
|
95
|
+
end
|
96
|
+
when 2
|
97
|
+
event, handler = args
|
98
|
+
raise TypeError, "event name must be a Symbol: #{event}" unless event.is_a? Symbol
|
99
|
+
raise TypeError, "handler name must be a Proc/Method: #{handler}" unless handler.is_a? Proc or handler.is_a? Method
|
100
|
+
!!@_event_handlers[event].delete(handler)
|
101
|
+
else
|
102
|
+
raise ArgumentError, "Requires 1..2 arguments, but received #{args.size} arguments"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
43
107
|
# Publish an event to all previously added handlers in the order they were added.
|
44
108
|
# It will automatically call the publishing object with the method named after the event if it is defined
|
45
109
|
# (this will be done before the manually added handlers are called).
|
@@ -78,15 +142,11 @@ module Fidgit
|
|
78
142
|
class << base
|
79
143
|
def events
|
80
144
|
# Copy the events already set up for your parent.
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
@events
|
145
|
+
@events ||= if superclass.respond_to? :events
|
146
|
+
superclass.events.dup
|
147
|
+
else
|
148
|
+
[]
|
149
|
+
end
|
90
150
|
end
|
91
151
|
|
92
152
|
def event(event)
|