colstrom-fidgit 0.2.7
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 +7 -0
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +31 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +20 -0
- data/README.md +154 -0
- data/Rakefile +38 -0
- data/config/default_schema.yml +216 -0
- data/examples/_all_examples.rb +9 -0
- data/examples/align_example.rb +56 -0
- data/examples/button_and_toggle_button_example.rb +38 -0
- data/examples/color_picker_example.rb +17 -0
- data/examples/color_well_example.rb +25 -0
- data/examples/combo_box_example.rb +24 -0
- data/examples/file_dialog_example.rb +42 -0
- data/examples/grid_packer_example.rb +29 -0
- data/examples/helpers/example_window.rb +17 -0
- data/examples/label_example.rb +23 -0
- data/examples/list_example.rb +23 -0
- data/examples/media/images/head_icon.png +0 -0
- data/examples/menu_pane_example.rb +27 -0
- data/examples/message_dialog_example.rb +65 -0
- data/examples/radio_button_example.rb +37 -0
- data/examples/readme_example.rb +32 -0
- data/examples/scroll_window_example.rb +49 -0
- data/examples/slider_example.rb +34 -0
- data/examples/splash_example.rb +42 -0
- data/examples/text_area_example.rb +33 -0
- data/fidgit.gemspec +35 -0
- data/lib/fidgit.rb +51 -0
- data/lib/fidgit/chingu_ext/window.rb +6 -0
- data/lib/fidgit/cursor.rb +38 -0
- data/lib/fidgit/elements/button.rb +113 -0
- data/lib/fidgit/elements/color_picker.rb +63 -0
- data/lib/fidgit/elements/color_well.rb +39 -0
- data/lib/fidgit/elements/combo_box.rb +115 -0
- data/lib/fidgit/elements/composite.rb +17 -0
- data/lib/fidgit/elements/container.rb +210 -0
- data/lib/fidgit/elements/element.rb +298 -0
- data/lib/fidgit/elements/file_browser.rb +152 -0
- data/lib/fidgit/elements/grid.rb +227 -0
- data/lib/fidgit/elements/group.rb +64 -0
- data/lib/fidgit/elements/horizontal.rb +12 -0
- data/lib/fidgit/elements/image_frame.rb +65 -0
- data/lib/fidgit/elements/label.rb +85 -0
- data/lib/fidgit/elements/list.rb +47 -0
- data/lib/fidgit/elements/main_packer.rb +25 -0
- data/lib/fidgit/elements/menu_pane.rb +163 -0
- data/lib/fidgit/elements/packer.rb +42 -0
- data/lib/fidgit/elements/radio_button.rb +86 -0
- data/lib/fidgit/elements/scroll_area.rb +68 -0
- data/lib/fidgit/elements/scroll_bar.rb +128 -0
- data/lib/fidgit/elements/scroll_window.rb +83 -0
- data/lib/fidgit/elements/slider.rb +125 -0
- data/lib/fidgit/elements/text_area.rb +494 -0
- data/lib/fidgit/elements/text_line.rb +92 -0
- data/lib/fidgit/elements/toggle_button.rb +67 -0
- data/lib/fidgit/elements/tool_tip.rb +35 -0
- data/lib/fidgit/elements/vertical.rb +12 -0
- data/lib/fidgit/event.rb +159 -0
- data/lib/fidgit/gosu_ext/color.rb +136 -0
- data/lib/fidgit/gosu_ext/gosu_module.rb +25 -0
- data/lib/fidgit/history.rb +91 -0
- data/lib/fidgit/redirector.rb +83 -0
- data/lib/fidgit/schema.rb +123 -0
- data/lib/fidgit/selection.rb +106 -0
- data/lib/fidgit/standard_ext/hash.rb +21 -0
- data/lib/fidgit/states/dialog_state.rb +52 -0
- data/lib/fidgit/states/file_dialog.rb +24 -0
- data/lib/fidgit/states/gui_state.rb +331 -0
- data/lib/fidgit/states/message_dialog.rb +61 -0
- data/lib/fidgit/version.rb +5 -0
- data/lib/fidgit/window.rb +19 -0
- data/media/images/arrow.png +0 -0
- data/media/images/combo_arrow.png +0 -0
- data/media/images/file_directory.png +0 -0
- data/media/images/file_file.png +0 -0
- data/media/images/pixel.png +0 -0
- data/spec/fidgit/elements/helpers/helper.rb +3 -0
- data/spec/fidgit/elements/helpers/tex_play_helper.rb +9 -0
- data/spec/fidgit/elements/image_frame_spec.rb +69 -0
- data/spec/fidgit/elements/label_spec.rb +37 -0
- data/spec/fidgit/event_spec.rb +210 -0
- data/spec/fidgit/gosu_ext/color_spec.rb +130 -0
- data/spec/fidgit/gosu_ext/helpers/helper.rb +3 -0
- data/spec/fidgit/helpers/helper.rb +4 -0
- data/spec/fidgit/history_spec.rb +153 -0
- data/spec/fidgit/redirector_spec.rb +78 -0
- data/spec/fidgit/schema_spec.rb +67 -0
- data/spec/fidgit/schema_test.yml +32 -0
- metadata +320 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
module Fidgit
|
2
|
+
# Used internally by the label.
|
3
|
+
class TextLine < Element
|
4
|
+
VALID_JUSTIFICATION = [:left, :right, :center]
|
5
|
+
|
6
|
+
attr_reader :color, :justify
|
7
|
+
|
8
|
+
def color=(color)
|
9
|
+
raise ArgumentError.new("Text must be a Gosu::Color") unless color.is_a? Gosu::Color
|
10
|
+
|
11
|
+
@color = color.dup
|
12
|
+
|
13
|
+
color
|
14
|
+
end
|
15
|
+
|
16
|
+
def text; @text.dup; end
|
17
|
+
|
18
|
+
def text=(text)
|
19
|
+
raise ArgumentError.new("Text must be a String") unless text.respond_to? :to_s
|
20
|
+
|
21
|
+
@text = text.to_s.dup
|
22
|
+
|
23
|
+
recalc
|
24
|
+
text
|
25
|
+
end
|
26
|
+
|
27
|
+
def justify=(justify)
|
28
|
+
raise ArgumentError.new("Justify must be one of #{VALID_JUSTIFICATION.inspect}") unless VALID_JUSTIFICATION.include? justify
|
29
|
+
@justify = justify
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param (see Element#initialize)
|
33
|
+
# @param [String] text The string to display in the line of text.
|
34
|
+
#
|
35
|
+
# @option (see Element#initialize)
|
36
|
+
# @option options [:left, :right, :center] :justify (:left) Text justification.
|
37
|
+
def initialize(text, options = {})
|
38
|
+
options = {
|
39
|
+
color: default(:color),
|
40
|
+
justify: default(:justify),
|
41
|
+
}.merge! options
|
42
|
+
|
43
|
+
super(options)
|
44
|
+
|
45
|
+
self.justify = options[:justify]
|
46
|
+
self.color = options[:color]
|
47
|
+
self.text = text
|
48
|
+
end
|
49
|
+
|
50
|
+
def draw_foreground
|
51
|
+
case @justify
|
52
|
+
when :left
|
53
|
+
rel_x = 0.0
|
54
|
+
draw_x = x + padding_left
|
55
|
+
|
56
|
+
when :right
|
57
|
+
rel_x = 1.0
|
58
|
+
draw_x = x + rect.width - padding_right
|
59
|
+
|
60
|
+
when :center
|
61
|
+
rel_x = 0.5
|
62
|
+
draw_x = (x + padding_left) + (rect.width - padding_right - padding_left) / 2.0
|
63
|
+
end
|
64
|
+
|
65
|
+
font.draw_rel(@text, draw_x, y + padding_top, z, rel_x, 0, 1, 1, color)
|
66
|
+
end
|
67
|
+
|
68
|
+
def min_width
|
69
|
+
if @text.empty?
|
70
|
+
[padding_left + padding_right, super].max
|
71
|
+
else
|
72
|
+
[padding_left + font.text_width(@text) + padding_right, super].max
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
def layout
|
78
|
+
rect.width = [min_width, max_width].min
|
79
|
+
|
80
|
+
if @text.empty?
|
81
|
+
rect.height = [[padding_top + padding_bottom, min_height].max, max_height].min
|
82
|
+
else
|
83
|
+
rect.height = [[padding_top + font.height + padding_bottom, min_height].max, max_height].min
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
public
|
88
|
+
def to_s
|
89
|
+
"#{super} '#{@text}'"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
# A button that toggles its value from false<->true when clicked.
|
5
|
+
class ToggleButton < Button
|
6
|
+
event :changed
|
7
|
+
|
8
|
+
attr_reader :value
|
9
|
+
def value=(value); @value = value; update_status; end
|
10
|
+
|
11
|
+
# @param (see Button#initialize)
|
12
|
+
#
|
13
|
+
# @option (see Button#initialize)
|
14
|
+
def initialize(text, options = {}, &block)
|
15
|
+
options = {
|
16
|
+
value: false
|
17
|
+
}.merge! options
|
18
|
+
|
19
|
+
@value = options[:value]
|
20
|
+
|
21
|
+
super(text, options)
|
22
|
+
|
23
|
+
@text_on = (options[:text_on] || text).dup
|
24
|
+
@icon_on = options[:icon_on] || icon
|
25
|
+
@tip_on = (options[:tip_on] || tip).dup
|
26
|
+
@border_color_on = (options[:border_color_on] || options[:border_color] || default(:toggled, :border_color)).dup
|
27
|
+
|
28
|
+
@text_off = (options[:text_off] || text).dup
|
29
|
+
@icon_off = options[:icon_off] || icon
|
30
|
+
@tip_off = (options[:tip_off] || tip).dup
|
31
|
+
@border_color_off = (options[:border_color_off] || options[:border_color] || default(:border_color)).dup
|
32
|
+
|
33
|
+
update_status
|
34
|
+
|
35
|
+
subscribe :clicked_left_mouse_button do |sender, x, y|
|
36
|
+
@value = (not @value)
|
37
|
+
update_status
|
38
|
+
publish :changed, @value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
# The block for a toggle-button is connected to :changed event.
|
44
|
+
def post_init_block(&block)
|
45
|
+
subscribe :changed, &block
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
def update_status
|
50
|
+
if @value
|
51
|
+
self.text = @text_on.dup
|
52
|
+
@icon = @icon_on ? @icon_on.dup : nil
|
53
|
+
@tip = @tip_on.dup
|
54
|
+
@border_color = @border_color_on.dup
|
55
|
+
else
|
56
|
+
self.text = @text_off.dup
|
57
|
+
@icon = @icon_off ? @icon_off.dup : nil
|
58
|
+
@tip = @tip_off.dup
|
59
|
+
@border_color = @border_color_off.dup
|
60
|
+
end
|
61
|
+
|
62
|
+
recalc
|
63
|
+
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class ToolTip < TextLine
|
5
|
+
def x=(value); super(value); recalc; value; end
|
6
|
+
def y=(value); super(value); recalc; value; end
|
7
|
+
def hit?(x, y); false; end
|
8
|
+
|
9
|
+
|
10
|
+
# @param (see Label#initialize)
|
11
|
+
#
|
12
|
+
# @option (see Label#initialize)
|
13
|
+
def initialize(options = {}, &block)
|
14
|
+
options = {
|
15
|
+
z: Float::INFINITY,
|
16
|
+
background_color: default(:background_color),
|
17
|
+
border_color: default(:border_color),
|
18
|
+
text: '',
|
19
|
+
}.merge! options
|
20
|
+
|
21
|
+
super(options[:text], options)
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
def layout
|
26
|
+
super
|
27
|
+
|
28
|
+
# Ensure the tip can't go over the edge of the screen. If it can't be avoided, align with left edge of screen.
|
29
|
+
rect.x = [[x, $window.width - width - padding_right].min, 0].max
|
30
|
+
rect.y = [[y, $window.height - height - padding_bottom].min, 0].max
|
31
|
+
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/fidgit/event.rb
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
# Adds simple event handling methods to an object (subscribe/publish pattern).
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# class JumpingBean
|
8
|
+
# include Event
|
9
|
+
# event :jump
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# bean = JumpingBean.new
|
13
|
+
# bean.subscribe :jump do
|
14
|
+
# puts "Whee!"
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# bean.subscribe :jump do |object, direction, distance|
|
18
|
+
# puts "#{object.class.name} jumped #{distance} metres #{direction}"
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# bean.publish :jump, :up, 4
|
22
|
+
# # Whee!
|
23
|
+
# # JumpingBean jumped 4 metres up
|
24
|
+
#
|
25
|
+
module Event
|
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}
|
51
|
+
def subscribe(event, method = nil, &block)
|
52
|
+
raise ArgumentError, "Expected method or block for event handler" unless !block.nil? ^ !method.nil?
|
53
|
+
raise ArgumentError, "#{self.class} does not handle #{event.inspect}" unless events.include? event
|
54
|
+
|
55
|
+
@_event_handlers ||= Event.new_event_handlers
|
56
|
+
handler = method || block
|
57
|
+
@_event_handlers[event] << handler
|
58
|
+
|
59
|
+
Subscription.new self, event, handler
|
60
|
+
end
|
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
|
+
|
107
|
+
# Publish an event to all previously added handlers in the order they were added.
|
108
|
+
# It will automatically call the publishing object with the method named after the event if it is defined
|
109
|
+
# (this will be done before the manually added handlers are called).
|
110
|
+
#
|
111
|
+
# If any handler returns :handled, then no further handlers will be called.
|
112
|
+
#
|
113
|
+
# @param [Symbol] event Name of the event to publish.
|
114
|
+
# @param [Array] args Arguments to pass to the event handlers.
|
115
|
+
# @return [Symbol, nil] :handled if any handler handled the event or nil if none did.
|
116
|
+
def publish(event, *args)
|
117
|
+
raise ArgumentError, "#{self.class} does not handle #{event.inspect}" unless events.include? event
|
118
|
+
|
119
|
+
# Do nothing if the object is disabled.
|
120
|
+
return if respond_to?(:enabled?) and not enabled?
|
121
|
+
|
122
|
+
if respond_to? event
|
123
|
+
return :handled if send(event, self, *args) == :handled
|
124
|
+
end
|
125
|
+
|
126
|
+
if defined? @_event_handlers
|
127
|
+
@_event_handlers[event].reverse_each do |handler|
|
128
|
+
return :handled if handler.call(self, *args) == :handled
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
|
135
|
+
# The list of events that this object can publish/subscribe.
|
136
|
+
def events
|
137
|
+
self.class.events
|
138
|
+
end
|
139
|
+
|
140
|
+
# Add singleton methods to the class that includes Event.
|
141
|
+
def self.included(base)
|
142
|
+
class << base
|
143
|
+
def events
|
144
|
+
# Copy the events already set up for your parent.
|
145
|
+
@events ||= if superclass.respond_to? :events
|
146
|
+
superclass.events.dup
|
147
|
+
else
|
148
|
+
[]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def event(event)
|
153
|
+
events.push event.to_sym unless events.include? event
|
154
|
+
event
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Gosu
|
4
|
+
class Color
|
5
|
+
# Is the color completely transparent?
|
6
|
+
def transparent?; alpha == 0; end
|
7
|
+
# Is the color completely opaque?
|
8
|
+
def opaque?; alpha == 255; end
|
9
|
+
|
10
|
+
# RGB in 0..255 format (Alpha assumed 255)
|
11
|
+
#
|
12
|
+
# @param [Integer] red
|
13
|
+
# @param [Integer] green
|
14
|
+
# @param [Integer] blue
|
15
|
+
# @return [Color]
|
16
|
+
def self.rgb(red, green, blue)
|
17
|
+
new(255, red, green, blue)
|
18
|
+
end
|
19
|
+
|
20
|
+
# RGBA in 0..255 format
|
21
|
+
#
|
22
|
+
# @param [Integer] red
|
23
|
+
# @param [Integer] green
|
24
|
+
# @param [Integer] blue
|
25
|
+
# @param [Integer] alpha
|
26
|
+
# @return [Color]
|
27
|
+
def self.rgba(red, green, blue, alpha)
|
28
|
+
new(alpha, red, green, blue)
|
29
|
+
end
|
30
|
+
|
31
|
+
# ARGB in 0..255 format (equivalent to Color.new, but explicit)
|
32
|
+
#
|
33
|
+
# @param [Integer] alpha
|
34
|
+
# @param (see Color.rgb)
|
35
|
+
# @return [Color]
|
36
|
+
def self.argb(alpha, red, green, blue)
|
37
|
+
new(alpha, red, green, blue)
|
38
|
+
end
|
39
|
+
|
40
|
+
# HSV format (alpha assumed to be 255)
|
41
|
+
#
|
42
|
+
# @param [Float] hue 0.0..360.0
|
43
|
+
# @param [Float] saturation 0.0..1.0
|
44
|
+
# @param [Float] value 0.0..1.0
|
45
|
+
# @return [Color]
|
46
|
+
def self.hsv(hue, saturation, value)
|
47
|
+
from_hsv(hue, saturation, value)
|
48
|
+
end
|
49
|
+
|
50
|
+
# HSVA format
|
51
|
+
#
|
52
|
+
# @param [Float] hue 0.0..360.0
|
53
|
+
# @param [Float] saturation 0.0..1.0
|
54
|
+
# @param [Float] value 0.0..1.0
|
55
|
+
# @param [Integer] alpha 1..255
|
56
|
+
# @return [Color]
|
57
|
+
def self.hsva(hue, saturation, value, alpha)
|
58
|
+
from_ahsv(alpha, hue, saturation, value)
|
59
|
+
end
|
60
|
+
|
61
|
+
class << self
|
62
|
+
alias_method :ahsv, :from_ahsv
|
63
|
+
end
|
64
|
+
|
65
|
+
# Convert from an RGBA array, as used by TexPlay.
|
66
|
+
#
|
67
|
+
# @param [Array<Float>] color TexPlay color [r, g, b, a] in range 0.0..1.0
|
68
|
+
# @return [Color]
|
69
|
+
def self.from_tex_play(color)
|
70
|
+
rgba(*color.map {|c| (c * 255).to_i })
|
71
|
+
end
|
72
|
+
|
73
|
+
# Convert to an RGBA array, as used by TexPlay.
|
74
|
+
#
|
75
|
+
# @return [Array<Float>] TexPlay color array [r, g, b, a] in range 0.0..1.0
|
76
|
+
def to_tex_play
|
77
|
+
[red / 255.0, green / 255.0, blue / 255.0, alpha / 255.0]
|
78
|
+
end
|
79
|
+
|
80
|
+
# Convert to a 6-digit hexadecimal value, appropriate for passing to the Gosu +<c>+ tag. The alpha channel is ignored.
|
81
|
+
#
|
82
|
+
# @return [String] RGB hexadecimal string, such as "AABB00"
|
83
|
+
def to_hex
|
84
|
+
"%02x%02x%02x" % [red, green, blue]
|
85
|
+
end
|
86
|
+
|
87
|
+
# Colorize text for in-line rendering by Gosu.
|
88
|
+
# e.g. "frog" => "<c=00ff9a>frog</c>"
|
89
|
+
def colorize(text)
|
90
|
+
"<c=#{to_hex}>#{text}</c>"
|
91
|
+
end
|
92
|
+
|
93
|
+
# Show the Color as <RGBA [0, 0, 0, 0]> or, if opaque, <RGB [0, 0, 0]> (Gosu default is '(ARGB:0/0/0/0)')
|
94
|
+
def to_s
|
95
|
+
if opaque?
|
96
|
+
"<RGB [#{red}, #{green}, #{blue}]>"
|
97
|
+
else
|
98
|
+
"<RGBA [#{red}, #{green}, #{blue}, #{alpha}]>"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def +(other)
|
103
|
+
raise ArgumentError, "Can only add another #{self.class}" unless other.is_a? Color
|
104
|
+
|
105
|
+
copy = Color.new(0)
|
106
|
+
|
107
|
+
copy.red = [red + other.red, 255].min
|
108
|
+
copy.green = [green + other.green, 255].min
|
109
|
+
copy.blue = [blue + other.blue, 255].min
|
110
|
+
copy.alpha = [alpha + other.alpha, 255].min
|
111
|
+
|
112
|
+
copy
|
113
|
+
end
|
114
|
+
|
115
|
+
def -(other)
|
116
|
+
raise ArgumentError, "Can only take away another #{self.class}" unless other.is_a? Color
|
117
|
+
|
118
|
+
copy = Color.new(0)
|
119
|
+
|
120
|
+
copy.red = [red - other.red, 0].max
|
121
|
+
copy.green = [green - other.green, 0].max
|
122
|
+
copy.blue = [blue - other.blue, 0].max
|
123
|
+
copy.alpha = [alpha - other.alpha, 0].max
|
124
|
+
|
125
|
+
copy
|
126
|
+
end
|
127
|
+
|
128
|
+
def ==(other)
|
129
|
+
if other.is_a? Color
|
130
|
+
red == other.red and green == other.green and blue == other.blue and alpha == other.alpha
|
131
|
+
else
|
132
|
+
false
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|