rubygame 2.3.0 → 2.4.0

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.
@@ -0,0 +1,112 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 2004-2008 John Croisant
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ #++
19
+
20
+ require 'rubygame/event_triggers'
21
+ require 'rubygame/event_actions'
22
+
23
+ module Rubygame
24
+
25
+ # The EventHook class provides the bare framework for event hooks
26
+ # used by EventHandler. Each hook has a trigger, which controls what
27
+ # types of events cause the hook to engage, and an action, which
28
+ # controls what should happen when the hook engages.
29
+ #
30
+ # An instance of EventHook has these attributes:
31
+ #
32
+ # owner:: the object that this hook applies to. This value will
33
+ # be provided to the action when the hook engages.
34
+ #
35
+ # trigger:: an instance of a trigger class, used to test every
36
+ # event to check whether the hook should engage.
37
+ # A valid trigger must have a #match? method which
38
+ # accepts an event and returns either true or false.
39
+ #
40
+ # action:: an instance of an action class, which is performed
41
+ # when the trigger matches an event. A valid action
42
+ # must have a #perform method which accepts two values:
43
+ # the hook's owner and the matching event.
44
+ #
45
+ # consumes:: if true, the event hook "eats" every event that it
46
+ # matches, so that hooks that come after it will not
47
+ # see the event. Has no effect on non-matching events.
48
+ #
49
+ # active:: if false, the event hook is disabled, and will not
50
+ # match any event until it is set to true again. You can
51
+ # use this to temporarily disable the hook.
52
+ #
53
+ class EventHook
54
+ attr_accessor :owner, :trigger, :action, :consumes, :active
55
+
56
+ # Create a new instance of EventHook. Description is a Hash with
57
+ # the following keys. See the class documentation for EventHook for
58
+ # more information about what these mean.
59
+ #
60
+ # :owner:: the hook's owner. (any object, required)
61
+ # :trigger:: an event trigger which matches certain events.
62
+ # (Object with +#match?(event)+, required)
63
+ # :action:: an event action to do when an event matches.
64
+ # (Object with +#perform(owner,event)+, required)
65
+ # :consumes:: if true, the hook will "eat" matching so
66
+ # later hooks won't see them. Default: false.
67
+ # (true or false, optional)
68
+ # :active:: if false, the hook will ignore all events.
69
+ # Default: true. (true or false, optional)
70
+ #
71
+ # NOTE: None of the attributes are truly required to create a hook.
72
+ # But, the hook will do nothing unless both @trigger and @action are
73
+ # set. Setting @owner is also highly recommended, because some types
74
+ # of actions use the owner, and may raise an error if it is nil.
75
+ #
76
+ # TIP: It's possible to set these attributes at any time using the
77
+ # accessors. For example, You could change keyboard controls on the
78
+ # fly, or temporarily deactivate a hook to stop it from engaging.
79
+ #
80
+ # Example:
81
+ #
82
+ # # Call player1.jump() when the space bar is pressed.
83
+ # EventHook.new( :owner => player1,
84
+ # :trigger => KeyPressTrigger.new(:space)
85
+ # :action => MethodAction.new(:jump) )
86
+ #
87
+ def initialize( description={} )
88
+ @owner = description[:owner]
89
+ @trigger = description[:trigger]
90
+ @action = description[:action]
91
+ @consumes = (description[:consumes] or false)
92
+ @active = (description[:active].nil? ? true : description[:active])
93
+ end
94
+
95
+ # Passes the event to @trigger's #match? method, and returns the
96
+ # result. If there is no @trigger or if @active is false, returns
97
+ # nil immediately.
98
+ def match?( event )
99
+ if (@trigger and @active)
100
+ @trigger.match?( event )
101
+ else
102
+ false
103
+ end
104
+ end
105
+
106
+ # Passes @owner and event to the @action's #perform method.
107
+ def perform( event )
108
+ @action.perform( owner, event ) if @action
109
+ end
110
+ end
111
+
112
+ end
@@ -0,0 +1,692 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 2004-2008 John Croisant
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ #++
19
+
20
+ require 'rubygame'
21
+
22
+ # This module contains all the event trigger classes that
23
+ # come with Rubygame.
24
+ #
25
+ # An event trigger class is simply a class which can be
26
+ # used as a trigger an EventHook. The trigger is used to
27
+ # determine whether the EventHook matches a particular
28
+ # event that occurs.
29
+ #
30
+ # The only requirement for an event trigger is this:
31
+ #
32
+ # * It must have a #match? method which takes exactly one
33
+ # argument (an event) and always returns either true or
34
+ # false.
35
+ #
36
+ # You can make your own custom event trigger classes and
37
+ # use them in an EventHook if they meet that requirement.
38
+ #
39
+ # NOTE: The #match? method may be called many times every
40
+ # second, even if there is no matching event. So, you should
41
+ # try to keep the method simple and fast, to have the least
42
+ # impact on your game's framerate.
43
+ #
44
+ # Here is an overview of the event trigger classes that
45
+ # come with Rubygame as of version 2.4:
46
+ #
47
+ #
48
+ # AndTrigger:: Holds multiple other triggers, and
49
+ # matches if ALL of the triggers
50
+ # match the event.
51
+ #
52
+ # OrTrigger:: Holds multiple other triggers, and
53
+ # matches if ONE OR MORE of the
54
+ # triggers match the event.
55
+ #
56
+ # AttrTrigger:: Matches if the event's attributes
57
+ # have the expected values.
58
+ #
59
+ # BlockTrigger:: Passes the event to a custom code
60
+ # block to check whether it matches.
61
+ #
62
+ # InstanceOfTrigger:: Matches if the event is an
63
+ # instance of a particular class.
64
+ #
65
+ # KeyPressTrigger:: Matches certain KeyPressed events.
66
+ #
67
+ # KeyReleaseTrigger:: Matches certain KeyReleased events.
68
+ #
69
+ # KindOfTrigger:: Matches if the event is #kind_of? a
70
+ # particular class or module.
71
+ #
72
+ # MousePressTrigger:: Matches certain MousePressed events.
73
+ #
74
+ # MouseMoveTrigger:: Matches certain MouseMoved events.
75
+ #
76
+ # MouseReleaseTrigger:: Matches certain MouseReleased events.
77
+ #
78
+ # YesTrigger:: Matches every event, no matter what.
79
+ #
80
+ module Rubygame::EventTriggers
81
+
82
+ #
83
+ # AndTrigger is an event trigger which contains one or
84
+ # more other triggers, and fires when an event matches
85
+ # all of its triggers. You can use this to create more
86
+ # complex logic than is possible with a single trigger.
87
+ #
88
+ # Contrast with OrTrigger.
89
+ #
90
+ class AndTrigger
91
+
92
+ # Initialize a new instance of AndTrigger, containing
93
+ # the given triggers.
94
+ #
95
+ # \*triggers:: The triggers to contain.
96
+ # (Array of triggers, required)
97
+ #
98
+ # Example:
99
+ #
100
+ # gameover_trigger = InstanceOfTrigger.new( GameOver )
101
+ # won_trigger = AttrTrigger.new( :won_game => true )
102
+ #
103
+ # # Matches only an event which is BOTH:
104
+ # # 1. an instance of class GameOver, AND
105
+ # # 2. returns true when #won_game is called
106
+ # AndTrigger.new( gameover_trigger, won_trigger )
107
+ #
108
+ def initialize( *triggers )
109
+ @triggers = triggers
110
+ end
111
+
112
+ # Returns true if the event matches all the triggers
113
+ # that the AndTrigger contains.
114
+ #
115
+ def match?( event )
116
+ @triggers.all? { |trigger| trigger.match? event }
117
+ end
118
+ end
119
+
120
+
121
+
122
+ #
123
+ # OrTrigger is an event trigger which contains one or
124
+ # more other triggers, and fires when an event matches
125
+ # one or more of its triggers.
126
+ #
127
+ # Contrast with AndTrigger.
128
+ #
129
+ class OrTrigger
130
+
131
+ # Initialize a new instance of OrTrigger, containing
132
+ # the given triggers.
133
+ #
134
+ # \*triggers:: The triggers to contain.
135
+ # (Array of triggers, required)
136
+ #
137
+ # Example:
138
+ #
139
+ # is_red = AttrTrigger.new( :color => :red )
140
+ # is_blue = AttrTrigger.new( :color => :blue )
141
+ #
142
+ # # Matches only an event which has EITHER:
143
+ # # 1. #color == :red, OR
144
+ # # 2. #color == :blue
145
+ # is_red_or_blue = OrTrigger.new( is_red, is_blue )
146
+ #
147
+ #
148
+ # # More complex example with nested logic triggers:
149
+ #
150
+ # changed = InstanceOfTrigger.new( ColorChanged )
151
+ #
152
+ # changed_to_red_or_blue =
153
+ # AndTrigger.new( changed, is_red_or_blue )
154
+ #
155
+ def initialize( *triggers )
156
+ @triggers = triggers
157
+ end
158
+
159
+ # Returns true if the event matches one or more of
160
+ # the triggers that the OrTrigger contains.
161
+ #
162
+ def match?( event )
163
+ @triggers.any? { |trigger| trigger.match? event }
164
+ end
165
+ end
166
+
167
+
168
+
169
+ #
170
+ # AttrTrigger is an event trigger which fires when an event
171
+ # has the expected value(s) for one or more attributes.
172
+ #
173
+ # AttrTrigger stores a Hash of :attr => value pairs, and
174
+ # checks each event to see if event.attr returns value.
175
+ # If all attributes have the expected value, the trigger fires.
176
+ #
177
+ class AttrTrigger
178
+
179
+ # Initialize a new instance of AttrTrigger with a
180
+ # Hash of one or more :attr => value pairs.
181
+ #
182
+ # attributes:: The attributes / value pairs to check.
183
+ # (Hash, required)
184
+ #
185
+ # Example:
186
+ #
187
+ # # Matches if event.color returns :red and
188
+ # # event.size returns :big
189
+ # AttrTrigger.new( :color => :red, :size => :big )
190
+ #
191
+ def initialize( attributes )
192
+ @attributes = attributes
193
+ end
194
+
195
+ # Returns true if, for every :attr => value pair, the event
196
+ # responds to :attr and calling event.attr returns value.
197
+ #
198
+ # Returns false if any of the attributes is not the expected value.
199
+ #
200
+ def match?( event )
201
+ @attributes.all? { |key, value|
202
+ event.respond_to?(key) and (event.send(key) == value)
203
+ }
204
+ end
205
+ end
206
+
207
+
208
+
209
+ #
210
+ # BlockTrigger is an event trigger which calls a block
211
+ # to check events. The trigger fires if the block returns
212
+ # true when called with the event as the only parameter.
213
+ #
214
+ class BlockTrigger
215
+
216
+ # Initialize a new instance of BlockTrigger with the given
217
+ # block. The block should take only 1 parameter, the event,
218
+ # and return true for matching events.
219
+ #
220
+ # &block:: The block to pass events to. (Proc, required)
221
+ #
222
+ def initialize( &block )
223
+ raise ArgumentError, "BlockTrigger needs a block" unless block_given?
224
+ @block = block
225
+ end
226
+
227
+ # Returns true if the block returns true when called
228
+ # with the event as the only parameter.
229
+ #
230
+ def match?( event )
231
+ @block.call( event ) == true
232
+ end
233
+ end
234
+
235
+
236
+
237
+ # class CollisionTrigger
238
+ #
239
+ # # type can be :start, :hold, :end, or :any
240
+ # def initialize( a=:any, b=:any, type=:any )
241
+ # @a, @b, @type = a, b, type
242
+ # end
243
+ #
244
+ # def match?( event )
245
+ # matching_types =
246
+ # case( event )
247
+ # when CollisionStartEvent
248
+ # [:start, :any]
249
+ # when CollisionEvent
250
+ # [:hold, :any]
251
+ # when CollisionEndEvent
252
+ # [:end, :any]
253
+ # else
254
+ # []
255
+ # end
256
+ #
257
+ # matching_types.include?(@type) and _has_objects?( event )
258
+ # end
259
+ #
260
+ # private
261
+ #
262
+ # # True if the event concerns the object(s) this trigger
263
+ # # is watching. It's not important that the event's pair order
264
+ # # matches the trigger's pair order.
265
+ # def _has_objects?( event )
266
+ # obs = [event.a, event.a.sprite, event.b, event.b.sprite]
267
+ #
268
+ # (@a == :any or obs.include?(@a)) and \
269
+ # (@b == :any or obs.include?(@b))
270
+ # end
271
+ #end
272
+
273
+
274
+
275
+ #
276
+ # InstanceOfTrigger is an event trigger which fires when
277
+ # the event is an instance of the given class. (In other
278
+ # words, when event.instance_of?( klass ) is true.)
279
+ #
280
+ # Contrast with KindOfTrigger.
281
+ #
282
+ class InstanceOfTrigger
283
+
284
+ # Initialize a new instance of InstanceOfTrigger with the
285
+ # given class.
286
+ #
287
+ # klass:: The class to check for. (Class, required)
288
+ #
289
+ def initialize( klass )
290
+ @klass = klass
291
+ end
292
+
293
+ # Returns true if the event is an instance of the class.
294
+ #
295
+ def match?( event )
296
+ event.instance_of?( @klass )
297
+ end
298
+ end
299
+
300
+
301
+
302
+ #
303
+ # KeyPressTrigger is an event trigger which fires when
304
+ # a key on the keyboard is pressed down (i.e. KeyPressed).
305
+ # See also KeyReleaseTrigger.
306
+ #
307
+ # This trigger can be configured to fire for any key,
308
+ # or a specific key. It can also fire depending on which
309
+ # modifier keys are held (ctrl, shift, alt, etc.).
310
+ #
311
+ # NOTE: This trigger only works with the new-style KeyPressed
312
+ # event class, not with the older KeyDownEvent.
313
+ # See EventQueue#enable_new_style_events
314
+ #
315
+ class KeyPressTrigger
316
+
317
+ # Initialize a new instance of KeyPressTrigger with the
318
+ # given key and modifier keys.
319
+ #
320
+ # key:: the key symbol to detect, or :any (default)
321
+ # to detect any key. (Symbol, optional)
322
+ #
323
+ # mods:: an Array of one or more modifier key symbols, or
324
+ # :none to detect key presses with exactly no modifiers,
325
+ # or :any (default) to detect any key modifiers.
326
+ #
327
+ # Valid modifiers are:
328
+ # * :alt, :left_alt, :right_alt,
329
+ # * :ctrl, :left_ctrl, :right_ctrl,
330
+ # * :shift, :left_shift, :right_shift,
331
+ # * :meta, :left_meta, :right_meta,
332
+ # * :numlock
333
+ # * :capslock
334
+ # * :mode
335
+ #
336
+ # :alt, :ctrl, :shift, and :meta will match either the
337
+ # left version or right version (e.g. :left_alt or
338
+ # :right_alt).
339
+ #
340
+ # Example:
341
+ #
342
+ # # Matches any key press, regardless of the key or modifiers.
343
+ # KeyPressTrigger.new
344
+ #
345
+ # # Matches the 'A' key with any (or no) modifiers.
346
+ # KeyPressTrigger.new( :a )
347
+ #
348
+ # # Matches the 'A' with both Ctrl and Shift modifiers.
349
+ # KeyPressTrigger.new( :a, [:ctrl, :shift] )
350
+ #
351
+ # # Matches the 'A' with both Left Ctrl and Left Shift modifiers.
352
+ # KeyPressTrigger.new( :a, [:left_ctrl, :left_shift] )
353
+ #
354
+ #
355
+ def initialize( key=:any, mods=:any )
356
+ @key = key
357
+ @mods = mods
358
+ end
359
+
360
+ # Returns true if the event is a KeyPressed event and the event's
361
+ # key and mods BOTH match the trigger's expectations.
362
+ #
363
+ # Key matches if either of these is true:
364
+ # * the trigger's key is the symbol :any
365
+ # * the event's key is the same as the trigger's key
366
+ #
367
+ # Modifiers matches if any of these is true:
368
+ # * the trigger's @mods is the symbol :any
369
+ # * the event has no modifiers and the trigger's @mods is
370
+ # the symbol :none
371
+ # * every one of the trigger's @mods matches one of the event's
372
+ # modifiers. "Matches" means either it is the same symbol,
373
+ # or it is a more general version. For example, :alt will
374
+ # match either :left_alt or :right_alt.
375
+ #
376
+ def match?( event )
377
+ if event.kind_of?( Events::KeyPressed )
378
+ ((@key == :any) or (event.key == @key)) and \
379
+ ((@mods == :any) or (@mods == :none and event.modifiers == [])\
380
+ or (_mods_match?(event.modifiers)))
381
+ end
382
+ end
383
+
384
+
385
+ private
386
+
387
+ # True if every modifier in @mods matches a modifier in
388
+ # evmods. :alt, :ctrl, :meta, and :shift match either
389
+ # the left or right versions (e.g. :left_alt, :right_alt).
390
+ # All other symbols match themselves.
391
+ #
392
+ def _mods_match?( evmods ) # :nodoc:
393
+ @mods.all? { |mod|
394
+ case mod
395
+ when :alt, :ctrl, :meta, :shift
396
+ evmods.include?("left_#{mod}".intern) or
397
+ evmods.include?("right_#{mod}".intern)
398
+ else
399
+ evmods.include?(mod)
400
+ end
401
+ }
402
+ end
403
+
404
+ end
405
+
406
+
407
+
408
+ #
409
+ # KeyReleaseTrigger is an event trigger which fires when
410
+ # a key on the keyboard is released (i.e. KeyReleased).
411
+ #
412
+ # NOTE: This trigger is identical to KeyPressTrigger, except that
413
+ # it fires for KeyReleased instead of KeyPressed. Please
414
+ # see the documentation for KeyPressTrigger for info about
415
+ # the parameters and behavior of the trigger.
416
+ #
417
+ # NOTE: This trigger only works with the new-style KeyReleased
418
+ # event class, not with the older KeyUpEvent.
419
+ # See EventQueue#enable_new_style_events
420
+ #
421
+ class KeyReleaseTrigger
422
+
423
+ # Initialize a new instance of KeyReleaseTrigger with the
424
+ # given key and modifier keys.
425
+ #
426
+ # See KeyPressTrigger#new for more information and examples.
427
+ #
428
+ def initialize( key=:any, mods=:any )
429
+ @key = key
430
+ @mods = mods
431
+ end
432
+
433
+ # Returns true if the event is a KeyReleased event and the event's
434
+ # key and mods BOTH match the trigger's expectations.
435
+ #
436
+ # See KeyPressTrigger#match? for more information.
437
+ #
438
+ def match?( event )
439
+ if event.kind_of?( Events::KeyReleased )
440
+ ((@key == :any) or (event.key == @key)) and \
441
+ ((@mods == :any) or (@mods == :none and event.modifiers == [])\
442
+ or (_mods_match?(event.modifiers)))
443
+ end
444
+ end
445
+
446
+
447
+ private
448
+
449
+ # True if every modifier in @mods matches a modifier in
450
+ # evmods. :alt, :ctrl, :meta, and :shift match either
451
+ # the left or right versions (e.g. :left_alt, :right_alt).
452
+ # All other symbols match themselves.
453
+ #
454
+ def _mods_match?( evmods ) # :nodoc:
455
+ @mods.all? { |mod|
456
+ case mod
457
+ when :alt, :ctrl, :meta, :shift
458
+ evmods.include?("left_#{mod}".intern) or
459
+ evmods.include?("right_#{mod}".intern)
460
+ else
461
+ evmods.include?(mod)
462
+ end
463
+ }
464
+ end
465
+
466
+
467
+ end
468
+
469
+
470
+
471
+ #
472
+ # KindOfTrigger is an event trigger which fires when
473
+ # the event is kind of the given class or module.
474
+ # (In other words, when event.kind_of?( kind ) is
475
+ # true.)
476
+ #
477
+ # Contrast with InstanceOfTrigger.
478
+ #
479
+ class KindOfTrigger
480
+
481
+ # Initialize a new instance of KindOfTrigger with the
482
+ # given class or module.
483
+ #
484
+ # kind:: The class/module to check for.
485
+ # (Class or Module, required)
486
+ #
487
+ def initialize( kind )
488
+ @kind = kind
489
+ end
490
+
491
+ # Returns true if the event is kind of the class/module.
492
+ #
493
+ def match?( event )
494
+ event.kind_of?( @kind )
495
+ end
496
+ end
497
+
498
+
499
+
500
+ #
501
+ # MousePressTrigger is an event trigger which fires when
502
+ # a mouse button is pressed down (i.e. MousePressed).
503
+ #
504
+ # By default, this trigger fires for any mouse press, but
505
+ # it can be configured to fire for only a specific mouse
506
+ # button by passing a button symbol to #new.
507
+ #
508
+ # See also MousReleaseTrigger.
509
+ #
510
+ class MousePressTrigger
511
+
512
+
513
+ # Initialize a new instance of MousePressTrigger with
514
+ # the given mouse button.
515
+ #
516
+ # button:: The mouse button symbol to detect, or :any
517
+ # to detect any button press.
518
+ #
519
+ # Valid mouse button symbols are: :mouse_left,
520
+ # :mouse_middle, :mouse_right, :mouse_wheel_up,
521
+ # and :mouse_wheel_down.
522
+ #
523
+ def initialize( button=:any )
524
+ @button = button
525
+ end
526
+
527
+ # Returns true if the event is a MousePressed event and
528
+ # the event's button is the same as the trigger's button
529
+ # (or the trigger's button is :any).
530
+ #
531
+ def match?( event )
532
+ if event.kind_of?( Events::MousePressed )
533
+ ((@button == :any) or (event.button == @button))
534
+ else
535
+ false
536
+ end
537
+ end
538
+ end
539
+
540
+
541
+
542
+ #
543
+ # MouseMoveTrigger is an event trigger which fires when the
544
+ # mouse cursor is moved (MouseMoved). If buttons are given,
545
+ # it only matches events with those buttons. See #new for details.
546
+ #
547
+ class MouseMoveTrigger
548
+
549
+ #
550
+ # Create a new instance of MouseMoveTrigger.
551
+ #
552
+ # The buttons parameter determines which mouse buttons can
553
+ # be held down and still match this trigger. It can be one of:
554
+ #
555
+ # 1. +:any+. Matches if zero or more buttons are held.
556
+ # 2. +:none+. Matches when zero buttons are being held.
557
+ # 3. +:mouse_left+, etc. Matches when at least the given
558
+ # button is being held.
559
+ # 4. An array of +:mouse_*+ symbols. Matches when exactly all
560
+ # buttons in the Array are being held, and nothing else.
561
+ #
562
+ #
563
+ # Example:
564
+ #
565
+ # # Matches all MouseMoved events, regardless of buttons:
566
+ # MouseMoveTrigger.new()
567
+ # MouseMoveTrigger.new( :any )
568
+ #
569
+ #
570
+ # # Matches only if no buttons pressed:
571
+ # MouseMoveTrigger.new( :none )
572
+ # MouseMoveTrigger.new( [] )
573
+ #
574
+ #
575
+ # # Matches if left mouse is held down, maybe with others:
576
+ # MouseMoveTrigger.new( :mouse_left )
577
+ #
578
+ #
579
+ # # Matches if ONLY left mouse held down, nothing else:
580
+ # MouseMoveTrigger.new( [:mouse_left] )
581
+ #
582
+ #
583
+ # # Matches if BOTH left AND right mouse are held down, nothing else:
584
+ # MouseMoveTrigger.new( [:mouse_left, :mouse_right] )
585
+ #
586
+ #
587
+ # # Matches if EITHER left OR right mouse are held down:
588
+ # OrTrigger.new( MouseMoveTrigger.new(:mouse_left),
589
+ # MouseMoveTrigger.new(:mouse_right) )
590
+ #
591
+ #
592
+ def initialize( buttons=:any )
593
+ @buttons = buttons
594
+ end
595
+
596
+ #
597
+ # Returns true if the given event matches this trigger.
598
+ # See #new for information about how events match.
599
+ #
600
+ def match?( event )
601
+ if event.kind_of?( Events::MouseMoved )
602
+ ((@buttons == :any) or
603
+ (@buttons == :none and event.buttons == []) or
604
+ (_buttons_match?(event.buttons)) or
605
+ (event.buttons.include?(@buttons)))
606
+ else
607
+ false
608
+ end
609
+ end
610
+
611
+ private
612
+
613
+ # Returns true if evbuttons is the same as @buttons,
614
+ # ignoring the order of the symbols.
615
+ #
616
+ def _buttons_match?( evbuttons )
617
+ if( @buttons.kind_of? Symbol )
618
+ return false
619
+ end
620
+
621
+ e = evbuttons.sort_by { |button| button.to_s }
622
+ t = @buttons.sort_by { |button| button.to_s }
623
+ return (e == t)
624
+ end
625
+
626
+ end
627
+
628
+
629
+
630
+ #
631
+ # MouseReleaseTrigger is an event trigger which fires when
632
+ # a mouse button is released (i.e. MouseReleased).
633
+ #
634
+ # By default, this trigger fires for any mouse release, but
635
+ # it can be configured to fire for only a specific mouse
636
+ # button by passing a button symbol to #new.
637
+ #
638
+ # See also MousePressTrigger.
639
+ #
640
+ class MouseReleaseTrigger
641
+
642
+ # Initialize a new instance of MouseReleaseTrigger with
643
+ # the given mouse button.
644
+ #
645
+ # button:: The mouse button symbol to detect, or :any
646
+ # to detect any button press.
647
+ #
648
+ # Valid mouse button symbols are: :mouse_left,
649
+ # :mouse_middle, :mouse_right, :mouse_wheel_up,
650
+ # and :mouse_wheel_down.
651
+ #
652
+ def initialize( button=:any )
653
+ @button = button
654
+ end
655
+
656
+ # Returns true if the event is a MouseReleased event and
657
+ # the event's button is the same as the trigger's button
658
+ # (or the trigger's button is :any).
659
+ #
660
+ def match?( event )
661
+ if event.kind_of?( Events::MouseReleased )
662
+ ((@button == :any) or (event.button == @button))
663
+ else
664
+ false
665
+ end
666
+ end
667
+ end
668
+
669
+
670
+
671
+ # class TickTrigger
672
+ # def match?( event )
673
+ # event.kind_of?( Events::ClockTicked )
674
+ # end
675
+ # end
676
+
677
+
678
+
679
+ #
680
+ # YesTrigger is an event trigger which will fire
681
+ # when any event occurs, regardless of the event
682
+ # type or details.
683
+ #
684
+ class YesTrigger
685
+
686
+ # Returns true every time.
687
+ def match?( event )
688
+ true
689
+ end
690
+ end
691
+
692
+ end