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