fidgit 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -7
- data/.rspec +2 -2
- data/CHANGELOG.md +30 -30
- data/Gemfile +3 -3
- data/LICENSE.txt +19 -19
- data/README.textile +139 -139
- data/Rakefile +37 -37
- data/config/default_schema.yml +216 -216
- data/examples/_all_examples.rb +9 -9
- data/examples/align_example.rb +55 -55
- data/examples/button_and_toggle_button_example.rb +37 -37
- data/examples/color_picker_example.rb +16 -16
- data/examples/color_well_example.rb +24 -24
- data/examples/combo_box_example.rb +23 -23
- data/examples/file_dialog_example.rb +41 -41
- data/examples/grid_packer_example.rb +28 -28
- data/examples/helpers/example_window.rb +16 -16
- data/examples/label_example.rb +22 -22
- data/examples/list_example.rb +22 -22
- data/examples/menu_pane_example.rb +26 -26
- data/examples/message_dialog_example.rb +64 -64
- data/examples/radio_button_example.rb +36 -36
- data/examples/readme_example.rb +31 -31
- data/examples/scroll_window_example.rb +48 -48
- data/examples/slider_example.rb +33 -33
- data/examples/splash_example.rb +41 -41
- data/examples/text_area_example.rb +32 -32
- data/fidgit.gemspec +35 -35
- data/lib/fidgit.rb +50 -50
- data/lib/fidgit/chingu_ext/window.rb +5 -5
- data/lib/fidgit/cursor.rb +37 -37
- data/lib/fidgit/elements/button.rb +112 -112
- data/lib/fidgit/elements/color_picker.rb +62 -62
- data/lib/fidgit/elements/color_well.rb +38 -38
- data/lib/fidgit/elements/combo_box.rb +113 -113
- data/lib/fidgit/elements/composite.rb +16 -16
- data/lib/fidgit/elements/container.rb +208 -208
- data/lib/fidgit/elements/element.rb +297 -297
- data/lib/fidgit/elements/file_browser.rb +151 -151
- data/lib/fidgit/elements/grid.rb +226 -226
- data/lib/fidgit/elements/group.rb +64 -64
- data/lib/fidgit/elements/horizontal.rb +11 -11
- data/lib/fidgit/elements/image_frame.rb +64 -64
- data/lib/fidgit/elements/label.rb +84 -84
- data/lib/fidgit/elements/list.rb +46 -46
- data/lib/fidgit/elements/main_packer.rb +24 -24
- data/lib/fidgit/elements/menu_pane.rb +160 -160
- data/lib/fidgit/elements/packer.rb +41 -41
- data/lib/fidgit/elements/radio_button.rb +85 -85
- data/lib/fidgit/elements/scroll_area.rb +67 -67
- data/lib/fidgit/elements/scroll_bar.rb +127 -127
- data/lib/fidgit/elements/scroll_window.rb +82 -82
- data/lib/fidgit/elements/slider.rb +124 -124
- data/lib/fidgit/elements/text_area.rb +493 -493
- data/lib/fidgit/elements/text_line.rb +91 -91
- data/lib/fidgit/elements/toggle_button.rb +66 -66
- data/lib/fidgit/elements/tool_tip.rb +34 -34
- data/lib/fidgit/elements/vertical.rb +11 -11
- data/lib/fidgit/event.rb +158 -158
- data/lib/fidgit/gosu_ext/color.rb +135 -135
- data/lib/fidgit/gosu_ext/gosu_module.rb +24 -24
- data/lib/fidgit/history.rb +90 -90
- data/lib/fidgit/redirector.rb +82 -82
- data/lib/fidgit/schema.rb +123 -123
- data/lib/fidgit/selection.rb +105 -105
- data/lib/fidgit/standard_ext/hash.rb +20 -20
- data/lib/fidgit/states/dialog_state.rb +51 -51
- data/lib/fidgit/states/file_dialog.rb +24 -24
- data/lib/fidgit/states/gui_state.rb +329 -329
- data/lib/fidgit/states/message_dialog.rb +60 -60
- data/lib/fidgit/version.rb +4 -4
- data/lib/fidgit/window.rb +19 -19
- data/spec/fidgit/elements/helpers/helper.rb +2 -2
- data/spec/fidgit/elements/helpers/tex_play_helper.rb +8 -8
- data/spec/fidgit/elements/image_frame_spec.rb +68 -68
- data/spec/fidgit/elements/label_spec.rb +36 -36
- data/spec/fidgit/event_spec.rb +209 -209
- data/spec/fidgit/gosu_ext/color_spec.rb +129 -129
- data/spec/fidgit/gosu_ext/helpers/helper.rb +2 -2
- data/spec/fidgit/helpers/helper.rb +3 -3
- data/spec/fidgit/history_spec.rb +153 -153
- data/spec/fidgit/redirector_spec.rb +77 -77
- data/spec/fidgit/schema_spec.rb +66 -66
- data/spec/fidgit/schema_test.yml +32 -32
- metadata +67 -22
@@ -1,42 +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
|
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
42
|
end
|
@@ -1,86 +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
|
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
86
|
end
|
@@ -1,68 +1,68 @@
|
|
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 [Vertical] 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 = Vertical.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
|
-
with(&block)
|
66
|
-
end
|
67
|
-
end
|
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 [Vertical] 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 = Vertical.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
|
+
with(&block)
|
66
|
+
end
|
67
|
+
end
|
68
68
|
end
|
@@ -1,128 +1,128 @@
|
|
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
|
-
|
51
|
-
subscribe :left_mouse_button do |sender, x, y|
|
52
|
-
clicked_to_move x, y
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class HorizontalScrollBar < ScrollBar
|
58
|
-
attr_reader :owner
|
59
|
-
|
60
|
-
def initialize(options = {})
|
61
|
-
super options
|
62
|
-
|
63
|
-
@handle.height = height
|
64
|
-
|
65
|
-
@handle_container.subscribe :left_mouse_button do |sender, x, y|
|
66
|
-
distance = @owner.view_width
|
67
|
-
@owner.offset_x += (x > @handle.x)? +distance : -distance
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def update
|
72
|
-
window = parent.parent
|
73
|
-
|
74
|
-
# Resize and re-locate the handles based on changes to the scroll-window.
|
75
|
-
content_width = window.content_width.to_f
|
76
|
-
@handle.width = (window.view_width * width) / content_width
|
77
|
-
@handle.x = x + (window.offset_x * width) / content_width
|
78
|
-
end
|
79
|
-
|
80
|
-
def draw_foreground
|
81
|
-
draw_rect x + padding_left, y + (height - @rail_thickness) / 2, width, @rail_thickness, z, @rail_color
|
82
|
-
super
|
83
|
-
end
|
84
|
-
|
85
|
-
def handle_dragged_to(x, y)
|
86
|
-
@owner.offset_x = @owner.content_width * ((x - self.x) / width.to_f)
|
87
|
-
end
|
88
|
-
|
89
|
-
def clicked_to_move(x, y)
|
90
|
-
new_x = x < @handle.x ? @handle.x - @handle.width : @handle.x + @handle.width
|
91
|
-
handle_dragged_to new_x, @handle.y
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
class VerticalScrollBar < ScrollBar
|
96
|
-
def initialize(options = {})
|
97
|
-
super options
|
98
|
-
|
99
|
-
@handle.width = width
|
100
|
-
|
101
|
-
@handle_container.subscribe :left_mouse_button do |sender, x, y|
|
102
|
-
distance = @owner.view_height
|
103
|
-
@owner.offset_y += (y > @handle.y)? +distance : -distance
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def update
|
108
|
-
window = parent.parent
|
109
|
-
content_height = window.content_height.to_f
|
110
|
-
@handle.height = (window.view_height * height) / content_height
|
111
|
-
@handle.y = y + (window.offset_y * height) / content_height
|
112
|
-
end
|
113
|
-
|
114
|
-
def draw_foreground
|
115
|
-
draw_rect x + (width - @rail_thickness) / 2, y + padding_top, @rail_thickness, height, z, @rail_color
|
116
|
-
super
|
117
|
-
end
|
118
|
-
|
119
|
-
def handle_dragged_to(x, y)
|
120
|
-
@owner.offset_y = @owner.content_height * ((y - self.y) / height.to_f)
|
121
|
-
end
|
122
|
-
|
123
|
-
def clicked_to_move(x, y)
|
124
|
-
new_y = y < @handle.y ? @handle.y - @handle.height : @handle.y + @handle.height
|
125
|
-
handle_dragged_to @handle.x, new_y
|
126
|
-
end
|
127
|
-
end
|
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
|
+
|
51
|
+
subscribe :left_mouse_button do |sender, x, y|
|
52
|
+
clicked_to_move x, y
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class HorizontalScrollBar < ScrollBar
|
58
|
+
attr_reader :owner
|
59
|
+
|
60
|
+
def initialize(options = {})
|
61
|
+
super options
|
62
|
+
|
63
|
+
@handle.height = height
|
64
|
+
|
65
|
+
@handle_container.subscribe :left_mouse_button do |sender, x, y|
|
66
|
+
distance = @owner.view_width
|
67
|
+
@owner.offset_x += (x > @handle.x)? +distance : -distance
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def update
|
72
|
+
window = parent.parent
|
73
|
+
|
74
|
+
# Resize and re-locate the handles based on changes to the scroll-window.
|
75
|
+
content_width = window.content_width.to_f
|
76
|
+
@handle.width = (window.view_width * width) / content_width
|
77
|
+
@handle.x = x + (window.offset_x * width) / content_width
|
78
|
+
end
|
79
|
+
|
80
|
+
def draw_foreground
|
81
|
+
draw_rect x + padding_left, y + (height - @rail_thickness) / 2, width, @rail_thickness, z, @rail_color
|
82
|
+
super
|
83
|
+
end
|
84
|
+
|
85
|
+
def handle_dragged_to(x, y)
|
86
|
+
@owner.offset_x = @owner.content_width * ((x - self.x) / width.to_f)
|
87
|
+
end
|
88
|
+
|
89
|
+
def clicked_to_move(x, y)
|
90
|
+
new_x = x < @handle.x ? @handle.x - @handle.width : @handle.x + @handle.width
|
91
|
+
handle_dragged_to new_x, @handle.y
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class VerticalScrollBar < ScrollBar
|
96
|
+
def initialize(options = {})
|
97
|
+
super options
|
98
|
+
|
99
|
+
@handle.width = width
|
100
|
+
|
101
|
+
@handle_container.subscribe :left_mouse_button do |sender, x, y|
|
102
|
+
distance = @owner.view_height
|
103
|
+
@owner.offset_y += (y > @handle.y)? +distance : -distance
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def update
|
108
|
+
window = parent.parent
|
109
|
+
content_height = window.content_height.to_f
|
110
|
+
@handle.height = (window.view_height * height) / content_height
|
111
|
+
@handle.y = y + (window.offset_y * height) / content_height
|
112
|
+
end
|
113
|
+
|
114
|
+
def draw_foreground
|
115
|
+
draw_rect x + (width - @rail_thickness) / 2, y + padding_top, @rail_thickness, height, z, @rail_color
|
116
|
+
super
|
117
|
+
end
|
118
|
+
|
119
|
+
def handle_dragged_to(x, y)
|
120
|
+
@owner.offset_y = @owner.content_height * ((y - self.y) / height.to_f)
|
121
|
+
end
|
122
|
+
|
123
|
+
def clicked_to_move(x, y)
|
124
|
+
new_y = y < @handle.y ? @handle.y - @handle.height : @handle.y + @handle.height
|
125
|
+
handle_dragged_to @handle.x, new_y
|
126
|
+
end
|
127
|
+
end
|
128
128
|
end
|