rubygame 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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