fidgit 0.2.4 → 0.2.5
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 +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
|