fidgit 0.0.2alpha
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.
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/COPYING.txt +674 -0
- data/Gemfile +4 -0
- data/README.textile +138 -0
- data/Rakefile +38 -0
- data/config/default_schema.yml +180 -0
- data/examples/_all_examples.rb +9 -0
- data/examples/align_example.rb +56 -0
- data/examples/button_and_toggle_button_example.rb +27 -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 +17 -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 +30 -0
- data/examples/splash_example.rb +42 -0
- data/examples/text_area_example.rb +28 -0
- data/fidgit.gemspec +28 -0
- data/lib/fidgit.rb +4 -0
- data/lib/fidgit/chingu_ext/window.rb +6 -0
- data/lib/fidgit/clipboard.rb +23 -0
- data/lib/fidgit/cursor.rb +38 -0
- data/lib/fidgit/elements/button.rb +68 -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 +85 -0
- data/lib/fidgit/elements/composite.rb +17 -0
- data/lib/fidgit/elements/container.rb +187 -0
- data/lib/fidgit/elements/element.rb +252 -0
- data/lib/fidgit/elements/file_browser.rb +152 -0
- data/lib/fidgit/elements/grid_packer.rb +219 -0
- data/lib/fidgit/elements/group.rb +66 -0
- data/lib/fidgit/elements/horizontal_packer.rb +12 -0
- data/lib/fidgit/elements/label.rb +77 -0
- data/lib/fidgit/elements/list.rb +47 -0
- data/lib/fidgit/elements/menu_pane.rb +149 -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 +75 -0
- data/lib/fidgit/elements/scroll_bar.rb +114 -0
- data/lib/fidgit/elements/scroll_window.rb +92 -0
- data/lib/fidgit/elements/slider.rb +119 -0
- data/lib/fidgit/elements/text_area.rb +351 -0
- data/lib/fidgit/elements/toggle_button.rb +67 -0
- data/lib/fidgit/elements/tool_tip.rb +35 -0
- data/lib/fidgit/elements/vertical_packer.rb +12 -0
- data/lib/fidgit/event.rb +99 -0
- data/lib/fidgit/gosu_ext/color.rb +123 -0
- data/lib/fidgit/history.rb +85 -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 +42 -0
- data/lib/fidgit/states/file_dialog.rb +24 -0
- data/lib/fidgit/states/gui_state.rb +301 -0
- data/lib/fidgit/states/message_dialog.rb +61 -0
- data/lib/fidgit/thumbnail.rb +29 -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/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/label_spec.rb +49 -0
- data/spec/fidgit/event_spec.rb +149 -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/helpers/tex_play_helper.rb +9 -0
- data/spec/fidgit/history_spec.rb +144 -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
- data/spec/fidgit/thumbnail_spec.rb +50 -0
- metadata +177 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
# Container that auto-packs elements.
|
5
|
+
#
|
6
|
+
# @abstract
|
7
|
+
class Packer < Container
|
8
|
+
attr_reader :spacing_h, :spacing_v
|
9
|
+
|
10
|
+
# @param (see Container#initialize)
|
11
|
+
#
|
12
|
+
# @option (see Container#initialize)
|
13
|
+
def initialize(options = {})
|
14
|
+
options = {
|
15
|
+
}.merge! options
|
16
|
+
|
17
|
+
@spacing_h = options[:spacing_h] || options[:spacing] || default(:spacing_h)
|
18
|
+
@spacing_v = options[:spacing_v] || options[:spacing] || default(:spacing_v)
|
19
|
+
|
20
|
+
super(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
# Recalculate the size of the container.
|
25
|
+
# Should be overridden by any descendant that manages the positions of its children.
|
26
|
+
def layout
|
27
|
+
# This assumes that the container overlaps all the children.
|
28
|
+
|
29
|
+
# Move all children if we have moved.
|
30
|
+
@children.each.with_index do |child, index|
|
31
|
+
child.x = padding_left + x
|
32
|
+
child.y = padding_top + y
|
33
|
+
end
|
34
|
+
|
35
|
+
# Make us as wrap around the largest child.
|
36
|
+
rect.width = (@children.map {|c| c.width }.max || 0) + padding_left + padding_right
|
37
|
+
rect.height = (@children.map {|c| c.height }.max || 0) + padding_top + padding_bottom
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class RadioButton < Button
|
5
|
+
attr_reader :group, :value
|
6
|
+
|
7
|
+
event :changed
|
8
|
+
|
9
|
+
def checked?; @checked; end
|
10
|
+
|
11
|
+
# @param (see Button#initialize)
|
12
|
+
# @param [Object] value
|
13
|
+
#
|
14
|
+
# @option (see Button#initialize)
|
15
|
+
# @option options [Boolean] :checked
|
16
|
+
def initialize(text, value, options = {}, &block)
|
17
|
+
options = {
|
18
|
+
checked: false,
|
19
|
+
checked_border_color: default(:checked, :border_color),
|
20
|
+
}.merge! options
|
21
|
+
|
22
|
+
@checked = options[:checked]
|
23
|
+
@value = value
|
24
|
+
|
25
|
+
super(text, options)
|
26
|
+
|
27
|
+
@checked_border_color = options[:checked_border_color].dup
|
28
|
+
@unchecked_border_color = border_color
|
29
|
+
add_to_group
|
30
|
+
|
31
|
+
@border_color = (checked? ? @checked_border_color : @unchecked_border_color).dup
|
32
|
+
end
|
33
|
+
|
34
|
+
def clicked_left_mouse_button(sender, x, y)
|
35
|
+
super
|
36
|
+
check
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
# Check the button and update its group. This may uncheck another button in the group if one is selected.
|
41
|
+
def check
|
42
|
+
return if checked?
|
43
|
+
|
44
|
+
@checked = true
|
45
|
+
@group.value = value
|
46
|
+
@border_color = @checked_border_color.dup
|
47
|
+
publish :changed, @checked
|
48
|
+
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
# Uncheck the button and update its group.
|
53
|
+
def uncheck
|
54
|
+
return unless checked?
|
55
|
+
|
56
|
+
@checked = false
|
57
|
+
@group.value = value
|
58
|
+
@border_color = @unchecked_border_color.dup
|
59
|
+
publish :changed, @checked
|
60
|
+
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
def parent=(parent)
|
66
|
+
@group.remove_button self if @parent
|
67
|
+
super(parent)
|
68
|
+
add_to_group if parent
|
69
|
+
parent
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
def add_to_group
|
74
|
+
container = parent
|
75
|
+
while container and not container.is_a? Group
|
76
|
+
container = container.parent
|
77
|
+
end
|
78
|
+
|
79
|
+
raise "#{self.class.name} must be placed inside a group element" unless container
|
80
|
+
|
81
|
+
@group = container
|
82
|
+
@group.add_button self
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
# A basic scrolling area. It is not managed in any way (use ScrollWindow for that).
|
5
|
+
class ScrollArea < Container
|
6
|
+
# @return [VerticalPacker] The content shown within this ScrollArea
|
7
|
+
attr_reader :content
|
8
|
+
|
9
|
+
def offset_x; x - @content.x; end
|
10
|
+
def offset_y; y - @content.y; end
|
11
|
+
|
12
|
+
def offset_x=(value)
|
13
|
+
@content.x = x - [[@content.width - width, value].min, 0].max
|
14
|
+
end
|
15
|
+
|
16
|
+
def offset_y=(value)
|
17
|
+
@content.y = y - [[@content.height - height, value].min, 0].max
|
18
|
+
end
|
19
|
+
|
20
|
+
# @option options [Number] :offset (0)
|
21
|
+
# @option options [Number] :offset_x (value of :offset option)
|
22
|
+
# @option options [Number] :offset_y (value of :offset option)
|
23
|
+
# @option options [Element] :owner The owner of the content, such as the scroll-window containing the content.
|
24
|
+
def initialize(options = {})
|
25
|
+
options = {
|
26
|
+
offset: 0,
|
27
|
+
owner: nil,
|
28
|
+
}.merge! options
|
29
|
+
|
30
|
+
@owner = options[:owner]
|
31
|
+
|
32
|
+
super(options)
|
33
|
+
|
34
|
+
@content = VerticalPacker.new(parent: self, padding: 0)
|
35
|
+
|
36
|
+
self.offset_x = options[:offset_x] || options[:offset]
|
37
|
+
self.offset_y = options[:offset_y] || options[:offset]
|
38
|
+
end
|
39
|
+
|
40
|
+
def hit_element(x, y)
|
41
|
+
# Only pass on mouse events if they are inside the window.
|
42
|
+
if hit?(x, y)
|
43
|
+
@content.hit_element(x, y) || self
|
44
|
+
else
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def recalc
|
50
|
+
super
|
51
|
+
# Always recalc our owner if our content resizes, even though our size can't change even if the content changes
|
52
|
+
# (may encourage ScrollWindow to show/hide scroll-bars, for example)
|
53
|
+
@owner.recalc if @owner
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
def draw_foreground
|
58
|
+
$window.clip_to(*rect) do
|
59
|
+
@content.draw
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
def post_init_block(&block)
|
65
|
+
case block.arity
|
66
|
+
when 1
|
67
|
+
yield @content
|
68
|
+
when 0
|
69
|
+
@content.instance_methods_eval &block
|
70
|
+
else
|
71
|
+
raise "block arity must be 0 or 1"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
# @abstract
|
5
|
+
class ScrollBar < Composite
|
6
|
+
class Handle < Element
|
7
|
+
event :begin_drag
|
8
|
+
event :update_drag
|
9
|
+
event :end_drag
|
10
|
+
|
11
|
+
def drag?(button); button == :left; end
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
super options
|
15
|
+
|
16
|
+
subscribe :begin_drag do |sender, x, y|
|
17
|
+
# Store position of the handle when it starts to drag.
|
18
|
+
@drag_start_pos = [x - self.x, y - self.y]
|
19
|
+
end
|
20
|
+
|
21
|
+
subscribe :update_drag do |sender, x, y|
|
22
|
+
parent.parent.handle_dragged_to x - @drag_start_pos[0], y - @drag_start_pos[1]
|
23
|
+
end
|
24
|
+
|
25
|
+
subscribe :end_drag do
|
26
|
+
@drag_start_pos = nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(options = {})
|
32
|
+
options = {
|
33
|
+
background_color: default(:background_color),
|
34
|
+
border_color: default(:border_color),
|
35
|
+
rail_width: default(:rail_width),
|
36
|
+
rail_color: default(:rail_color),
|
37
|
+
handle_color: default(:handle_color),
|
38
|
+
owner: nil,
|
39
|
+
}.merge! options
|
40
|
+
|
41
|
+
@owner = options[:owner]
|
42
|
+
@rail_thickness = options[:rail_width]
|
43
|
+
@rail_color = options[:rail_color]
|
44
|
+
|
45
|
+
super options
|
46
|
+
|
47
|
+
@handle_container = Container.new(parent: self, width: options[:width], height: options[:height]) do
|
48
|
+
@handle = Handle.new(parent: self, x: x, y: y, background_color: options[:handle_color])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class HorizontalScrollBar < ScrollBar
|
54
|
+
attr_reader :owner
|
55
|
+
|
56
|
+
def initialize(options = {})
|
57
|
+
super options
|
58
|
+
|
59
|
+
@handle.height = height
|
60
|
+
|
61
|
+
@handle_container.subscribe :left_mouse_button do |sender, x, y|
|
62
|
+
distance = @owner.view_width
|
63
|
+
@owner.offset_x += (x > @handle.x)? +distance : -distance
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def update
|
68
|
+
window = parent.parent
|
69
|
+
|
70
|
+
# Resize and re-locate the handles based on changes to the scroll-window.
|
71
|
+
content_width = window.content_width.to_f
|
72
|
+
@handle.width = (window.view_width * width) / content_width
|
73
|
+
@handle.x = x + (window.offset_x * width) / content_width
|
74
|
+
end
|
75
|
+
|
76
|
+
def draw_foreground
|
77
|
+
draw_rect x + padding_left, y + (height - @rail_thickness) / 2, width, @rail_thickness, z, @rail_color
|
78
|
+
super
|
79
|
+
end
|
80
|
+
|
81
|
+
def handle_dragged_to(x, y)
|
82
|
+
@owner.offset_x = @owner.content_width * ((x - self.x) / width.to_f)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class VerticalScrollBar < ScrollBar
|
87
|
+
def initialize(options = {})
|
88
|
+
super options
|
89
|
+
|
90
|
+
@handle.width = width
|
91
|
+
|
92
|
+
@handle_container.subscribe :left_mouse_button do |sender, x, y|
|
93
|
+
distance = @owner.view_height
|
94
|
+
@owner.offset_y += (y > @handle.y)? +distance : -distance
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def update
|
99
|
+
window = parent.parent
|
100
|
+
content_height = window.content_height.to_f
|
101
|
+
@handle.height = (window.view_height * height) / content_height
|
102
|
+
@handle.y = y + (window.offset_y * height) / content_height
|
103
|
+
end
|
104
|
+
|
105
|
+
def draw_foreground
|
106
|
+
draw_rect x + (width - @rail_thickness) / 2, y + padding_top, @rail_thickness, height, z, @rail_color
|
107
|
+
super
|
108
|
+
end
|
109
|
+
|
110
|
+
def handle_dragged_to(x, y)
|
111
|
+
@owner.offset_y = @owner.content_height * ((y - self.y) / height.to_f)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class ScrollWindow < Composite
|
5
|
+
def content; @view.content; end
|
6
|
+
|
7
|
+
def offset_x; @view.offset_x; end
|
8
|
+
def offset_x=(value); @view.offset_x = value; end
|
9
|
+
def offset_y; @view.offset_y; end
|
10
|
+
def offset_y=(value); @view.offset_y = value; end
|
11
|
+
|
12
|
+
def view_width; @view.width; end
|
13
|
+
def view_height; @view.height; end
|
14
|
+
def content_width; @view.content.width; end
|
15
|
+
def content_height; @view.content.height; end
|
16
|
+
|
17
|
+
def width=(value); super(value); end
|
18
|
+
def height=(value); super(value); end
|
19
|
+
|
20
|
+
def initialize(options = {})
|
21
|
+
options = {
|
22
|
+
scroll_bar_thickness: default(:scroll_bar_thickness),
|
23
|
+
}.merge! options
|
24
|
+
|
25
|
+
super(options)
|
26
|
+
|
27
|
+
@grid = pack :grid, num_columns: 2, padding: 0, spacing: 0 do
|
28
|
+
@view = scroll_area(owner: self, width: options[:width], height: options[:height])
|
29
|
+
@spacer = label '', padding: 0, width: 0, height: 0
|
30
|
+
end
|
31
|
+
|
32
|
+
@scroll_bar_v = VerticalScrollBar.new(owner: self, width: options[:scroll_bar_thickness], align_v: :fill)
|
33
|
+
@scroll_bar_h = HorizontalScrollBar.new(owner: self, height: options[:scroll_bar_thickness], align_h: :fill)
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
def layout
|
38
|
+
# Prevent recursive layouts.
|
39
|
+
return if @in_layout
|
40
|
+
|
41
|
+
@in_layout = true
|
42
|
+
|
43
|
+
if @view
|
44
|
+
# Constrain the values of the offsets.
|
45
|
+
@view.offset_x = @view.offset_x
|
46
|
+
@view.offset_y = @view.offset_y
|
47
|
+
|
48
|
+
if content_height > view_height
|
49
|
+
unless @scroll_bar_v.parent
|
50
|
+
@view.send(:rect).width -= @scroll_bar_v.width
|
51
|
+
@grid.remove @spacer
|
52
|
+
@grid.insert 1, @scroll_bar_v
|
53
|
+
end
|
54
|
+
else
|
55
|
+
if @scroll_bar_v.parent
|
56
|
+
@view.send(:rect).width += @scroll_bar_v.width
|
57
|
+
@grid.remove @scroll_bar_v
|
58
|
+
@grid.insert 1, @spacer
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if content_width > view_width
|
63
|
+
unless @scroll_bar_h.parent
|
64
|
+
@view.send(:rect).height -= @scroll_bar_h.height
|
65
|
+
@grid.add @scroll_bar_h
|
66
|
+
end
|
67
|
+
else
|
68
|
+
if @scroll_bar_h.parent
|
69
|
+
@view.send(:rect).height += @scroll_bar_h.height
|
70
|
+
@grid.remove @scroll_bar_h
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
super
|
76
|
+
|
77
|
+
@in_layout = false
|
78
|
+
end
|
79
|
+
|
80
|
+
protected
|
81
|
+
def post_init_block(&block)
|
82
|
+
case block.arity
|
83
|
+
when 1
|
84
|
+
yield @view.content
|
85
|
+
when 0
|
86
|
+
@view.content.instance_methods_eval &block
|
87
|
+
else
|
88
|
+
raise "block arity must be 0 or 1"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class Slider < Composite
|
5
|
+
# @private
|
6
|
+
class Handle < Element
|
7
|
+
event :begin_drag
|
8
|
+
event :end_drag
|
9
|
+
event :update_drag
|
10
|
+
|
11
|
+
def drag?(button); button == :left; end
|
12
|
+
|
13
|
+
# @param (see Element#initialize)
|
14
|
+
#
|
15
|
+
# @option (see Element#initialize)
|
16
|
+
def initialize(options = {}, &block)
|
17
|
+
options = {
|
18
|
+
background_color: default(:background_color),
|
19
|
+
border_color: default(:border_color),
|
20
|
+
}.merge! options
|
21
|
+
|
22
|
+
super options
|
23
|
+
|
24
|
+
subscribe :begin_drag do |sender, x, y|
|
25
|
+
# Store position of the handle when it starts to drag.
|
26
|
+
@drag_start_pos = [x - self.x, y - self.y]
|
27
|
+
end
|
28
|
+
|
29
|
+
subscribe :update_drag do |sender, x, y|
|
30
|
+
parent.handle_dragged_to x - @drag_start_pos[0], y - @drag_start_pos[1]
|
31
|
+
end
|
32
|
+
|
33
|
+
subscribe :end_drag do
|
34
|
+
@drag_start_pos = nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
event :changed
|
40
|
+
|
41
|
+
attr_reader :value, :range
|
42
|
+
|
43
|
+
# @param (see Composite#initialize)
|
44
|
+
#
|
45
|
+
# @option (see Composite#initialize)
|
46
|
+
# @option options [Range] :range (0.0..1.0)
|
47
|
+
# @option options [Range] :value (minimum of :range)
|
48
|
+
def initialize(options = {}, &block)
|
49
|
+
options = {
|
50
|
+
range: 0.0..1.0,
|
51
|
+
height: 25,
|
52
|
+
background_color: default(:background_color),
|
53
|
+
border_color: default(:border_color),
|
54
|
+
groove_color: default(:groove_color),
|
55
|
+
handle_color: default(:handle_color),
|
56
|
+
groove_thickness: 5,
|
57
|
+
}.merge! options
|
58
|
+
|
59
|
+
@range = options[:range].dup
|
60
|
+
@groove_color = options[:groove_color].dup
|
61
|
+
@groove_thickness = options[:groove_thickness]
|
62
|
+
@continuous = @range.min.is_a?(Float) or @range.max.is_a?(Float)
|
63
|
+
|
64
|
+
super(options)
|
65
|
+
|
66
|
+
@handle = Handle.new(parent: self, width: (height / 2 - padding_left), height: height - padding_top + padding_bottom,
|
67
|
+
background_color: options[:handle_color])
|
68
|
+
|
69
|
+
self.value = options.has_key?(:value) ? options[:value] : @range.min
|
70
|
+
end
|
71
|
+
|
72
|
+
def value=(value)
|
73
|
+
@value = @continuous ? value.to_f : value.round
|
74
|
+
@value = [[@value, @range.min].max, @range.max].min
|
75
|
+
@handle.x = x + padding_left + ((width - @handle.width) * (@value - @range.min) / (@range.max - @range.min).to_f)
|
76
|
+
publish :changed, @value
|
77
|
+
|
78
|
+
@value
|
79
|
+
end
|
80
|
+
|
81
|
+
def tip
|
82
|
+
tip = super
|
83
|
+
tip.empty? ? @value.to_s : "#{tip}: #{@value}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def left_mouse_button(sender, x, y)
|
87
|
+
# In this case, x should be the centre of the handle after it has moved.
|
88
|
+
self.value = ((x - (@handle.width / 2) - self.x) / (width - @handle.width)) * (@range.max - @range.min) + @range.min
|
89
|
+
@mouse_down = true
|
90
|
+
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def handle_dragged_to(x, y)
|
95
|
+
# In this case, x is the left-hand side fo the handle.
|
96
|
+
self.value = ((x - self.x) / (width - @handle.width)) * (@range.max - @range.min) + @range.min
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
# Prevent standard packing layout change.
|
101
|
+
def layout
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
|
105
|
+
protected
|
106
|
+
def draw_background
|
107
|
+
super
|
108
|
+
# Draw a groove for the handle to move along.
|
109
|
+
draw_rect x + (@handle.width / 2), y + (height - @groove_thickness) / 2, width - @handle.width, @groove_thickness, z, @groove_color
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
|
113
|
+
protected
|
114
|
+
# Use block as an event handler.
|
115
|
+
def post_init_block(&block)
|
116
|
+
subscribe :changed, &block
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|