glimr 0.1.0
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/lib/glimr.rb +2 -0
- data/lib/glimr/configurable.rb +37 -0
- data/lib/glimr/default_theme/button_bg.png +0 -0
- data/lib/glimr/default_theme/button_bg_down.png +0 -0
- data/lib/glimr/default_theme/button_cover.png +0 -0
- data/lib/glimr/default_theme/button_cover_down.png +0 -0
- data/lib/glimr/default_theme/button_focus.png +0 -0
- data/lib/glimr/default_theme/checkbox_bg.png +0 -0
- data/lib/glimr/default_theme/checkbox_checked_bg.png +0 -0
- data/lib/glimr/default_theme/font.ttf +0 -0
- data/lib/glimr/default_theme/hscroller_bg.png +0 -0
- data/lib/glimr/default_theme/radiobutton_bg.png +0 -0
- data/lib/glimr/default_theme/radiobutton_checked_bg.png +0 -0
- data/lib/glimr/default_theme/resizer_down.png +0 -0
- data/lib/glimr/default_theme/resizer_up.png +0 -0
- data/lib/glimr/default_theme/scroll_down_down.png +0 -0
- data/lib/glimr/default_theme/scroll_down_up.png +0 -0
- data/lib/glimr/default_theme/scroll_hknob_down.png +0 -0
- data/lib/glimr/default_theme/scroll_hknob_up.png +0 -0
- data/lib/glimr/default_theme/scroll_left_down.png +0 -0
- data/lib/glimr/default_theme/scroll_left_up.png +0 -0
- data/lib/glimr/default_theme/scroll_right_down.png +0 -0
- data/lib/glimr/default_theme/scroll_right_up.png +0 -0
- data/lib/glimr/default_theme/scroll_up_down.png +0 -0
- data/lib/glimr/default_theme/scroll_up_up.png +0 -0
- data/lib/glimr/default_theme/scroll_vknob_down.png +0 -0
- data/lib/glimr/default_theme/scroll_vknob_up.png +0 -0
- data/lib/glimr/default_theme/text_cursor.png +0 -0
- data/lib/glimr/default_theme/text_cursor_insert.png +0 -0
- data/lib/glimr/default_theme/text_input_bg.png +0 -0
- data/lib/glimr/default_theme/vscroller_bg.png +0 -0
- data/lib/glimr/event.rb +41 -0
- data/lib/glimr/eventlistener.rb +209 -0
- data/lib/glimr/layoutable.rb +520 -0
- data/lib/glimr/renderer.rb +2 -0
- data/lib/glimr/renderer/camera.rb +63 -0
- data/lib/glimr/renderer/geometry.rb +194 -0
- data/lib/glimr/renderer/glutwindow.rb +387 -0
- data/lib/glimr/renderer/light.rb +43 -0
- data/lib/glimr/renderer/material.rb +66 -0
- data/lib/glimr/renderer/model.rb +103 -0
- data/lib/glimr/renderer/orthoprojection.rb +21 -0
- data/lib/glimr/renderer/raw.rb +34 -0
- data/lib/glimr/renderer/sceneobject.rb +279 -0
- data/lib/glimr/renderer/shader.rb +14 -0
- data/lib/glimr/renderer/texture.rb +280 -0
- data/lib/glimr/renderer/transform.rb +322 -0
- data/lib/glimr/renderer/viewport.rb +349 -0
- data/lib/glimr/renderer_core.rb +10 -0
- data/lib/glimr/util.rb +247 -0
- data/lib/glimr/widget.rb +87 -0
- data/lib/glimr/widgets.rb +37 -0
- data/lib/glimr/widgets/button.rb +277 -0
- data/lib/glimr/widgets/checkbox.rb +82 -0
- data/lib/glimr/widgets/container.rb +84 -0
- data/lib/glimr/widgets/image.rb +82 -0
- data/lib/glimr/widgets/label.rb +91 -0
- data/lib/glimr/widgets/layout.rb +227 -0
- data/lib/glimr/widgets/list.rb +28 -0
- data/lib/glimr/widgets/radiogroup.rb +118 -0
- data/lib/glimr/widgets/resizer.rb +31 -0
- data/lib/glimr/widgets/scrollable_container.rb +67 -0
- data/lib/glimr/widgets/scrollbar.rb +496 -0
- data/lib/glimr/widgets/stretchable_image.rb +135 -0
- data/lib/glimr/widgets/text_editor.rb +349 -0
- data/tests/assets/datatowers_crop.jpg +0 -0
- data/tests/assets/download_progress_meter.png +0 -0
- data/tests/assets/metalwing2.png +0 -0
- data/tests/assets/redhairgreeneyes3.jpg +0 -0
- data/tests/demo_apps/spinning_ruby.rb +37 -0
- data/tests/integration_tests/run_all.rb +8 -0
- data/tests/integration_tests/test_button.rb +22 -0
- data/tests/integration_tests/test_checkbox.rb +21 -0
- data/tests/integration_tests/test_container.rb +22 -0
- data/tests/integration_tests/test_label.rb +12 -0
- data/tests/integration_tests/test_layout.rb +43 -0
- data/tests/integration_tests/test_radiogroup.rb +16 -0
- data/tests/integration_tests/test_renderer.rb +44 -0
- data/tests/integration_tests/test_renderer2.rb +36 -0
- data/tests/integration_tests/test_scrollable_container.rb +34 -0
- data/tests/integration_tests/test_scrollbar.rb +20 -0
- data/tests/integration_tests/test_stretchable_image.rb +34 -0
- data/tests/integration_tests/test_text_input.rb +20 -0
- data/tests/integration_tests/test_zsort.rb +18 -0
- data/tests/unit_tests/test_button.rb +93 -0
- data/tests/unit_tests/test_checkbox.rb +35 -0
- data/tests/unit_tests/test_label.rb +36 -0
- data/tests/unit_tests/test_layout.rb +229 -0
- data/tests/unit_tests/test_widget.rb +3 -0
- metadata +139 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'glimr/widgets/scrollable_container'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module GlimR
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# A List is a Scrollable with a VLayout as its content.
|
|
8
|
+
#
|
|
9
|
+
class List < ScrollableContainer
|
|
10
|
+
|
|
11
|
+
def default_config
|
|
12
|
+
super.merge(
|
|
13
|
+
:width => 200,
|
|
14
|
+
:height => 100,
|
|
15
|
+
:content => VLayout.new
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(*args, &b)
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
require 'glimr/widgets/checkbox'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module GlimR
|
|
5
|
+
|
|
6
|
+
class RadioGroup < VLayout
|
|
7
|
+
|
|
8
|
+
attr_accessor :selected_index, :options
|
|
9
|
+
|
|
10
|
+
def default_config
|
|
11
|
+
super.merge(
|
|
12
|
+
:selected_index => 0,
|
|
13
|
+
:options => ["Default", "Options"]
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def initialize(*a, &b)
|
|
18
|
+
super
|
|
19
|
+
self.label = @label if @label
|
|
20
|
+
@option_models = []
|
|
21
|
+
self.options = @options
|
|
22
|
+
self.selected_index = @selected_index
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def label= l
|
|
26
|
+
if @label_model
|
|
27
|
+
@label_model.text = l
|
|
28
|
+
else
|
|
29
|
+
@label_model = Label.new(:text => @label)
|
|
30
|
+
attach @label_model
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def options=(opts)
|
|
35
|
+
@options = opts
|
|
36
|
+
@option_models.each{|m| m.detach_self }
|
|
37
|
+
@option_models.clear
|
|
38
|
+
@options.each_with_index{|opt, i|
|
|
39
|
+
rb = RadioOption.new(:label => opt)
|
|
40
|
+
rb.on_change{|o,e|
|
|
41
|
+
self.selected_index = i
|
|
42
|
+
dispatch_event(
|
|
43
|
+
Event.new(
|
|
44
|
+
:select,
|
|
45
|
+
{
|
|
46
|
+
:source => self,
|
|
47
|
+
:selected_index => i,
|
|
48
|
+
:option => selection
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
@option_models << rb
|
|
54
|
+
}
|
|
55
|
+
attach *@option_models
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def selected_index=(index)
|
|
59
|
+
@option_models[@selected_index].state = false
|
|
60
|
+
@selected_index = index
|
|
61
|
+
@option_models[@selected_index].state = true
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def selected_model
|
|
65
|
+
@option_models[@selected_index]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def selected_model= s
|
|
69
|
+
@option_models.each_with_index{|e,i|
|
|
70
|
+
if e == s
|
|
71
|
+
self.selected_index = i
|
|
72
|
+
break
|
|
73
|
+
end
|
|
74
|
+
}
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def selection
|
|
78
|
+
@option_models[@selected_index].label
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def selection= s
|
|
82
|
+
@option_models.each_with_index{|e,i|
|
|
83
|
+
if e.label == s
|
|
84
|
+
self.selected_index = i
|
|
85
|
+
break
|
|
86
|
+
end
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class RadioOption < Checkbox
|
|
94
|
+
|
|
95
|
+
def default_config
|
|
96
|
+
super.merge(
|
|
97
|
+
:button => RadioOptionButton.new
|
|
98
|
+
)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class RadioOptionButton < CheckboxButton
|
|
104
|
+
|
|
105
|
+
def default_config
|
|
106
|
+
super.merge(
|
|
107
|
+
:up_background => "radiobutton_bg.png",
|
|
108
|
+
:down_background => "radiobutton_checked_bg.png"
|
|
109
|
+
)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def activate o,e
|
|
113
|
+
super unless parent.state
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'glimr/widgets/button'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module GlimR
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Resizer < EmptyButton
|
|
8
|
+
|
|
9
|
+
attr_accessor :target
|
|
10
|
+
|
|
11
|
+
def default_config
|
|
12
|
+
super.merge(
|
|
13
|
+
:up_background => "resizer_up.png",
|
|
14
|
+
:down_background => "resizer_down.png"
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def mouse_move(o,e)
|
|
19
|
+
super
|
|
20
|
+
if down and target and e.buttons[:left]
|
|
21
|
+
target.size_changing{
|
|
22
|
+
target.width += e.dx
|
|
23
|
+
target.height += e.dy
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'glimr/widgets/layout'
|
|
2
|
+
require 'glimr/widgets/container'
|
|
3
|
+
require 'glimr/widgets/scrollbar'
|
|
4
|
+
require 'glimr/widgets/resizer'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module GlimR
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ScrollableContainer < Widget
|
|
11
|
+
|
|
12
|
+
ivar_accessor_delegate :@container, :content, :content_view
|
|
13
|
+
attr_accessor :container, :horizontal_scrollbar, :vertical_scrollbar, :resizer
|
|
14
|
+
|
|
15
|
+
def default_config
|
|
16
|
+
super.merge(
|
|
17
|
+
:width => 200,
|
|
18
|
+
:height => 200,
|
|
19
|
+
:content => nil
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize(*a, &b)
|
|
24
|
+
super
|
|
25
|
+
@resizer = Resizer.new(:target => self)
|
|
26
|
+
vsplit = VLayout.new(
|
|
27
|
+
:item_spacing => 0,
|
|
28
|
+
:expand_width => true, :expand_height => true
|
|
29
|
+
)
|
|
30
|
+
hsplit = HLayout.new(
|
|
31
|
+
:item_spacing => 0,
|
|
32
|
+
:expand_width => true, :expand_height => true
|
|
33
|
+
)
|
|
34
|
+
@container = Container.new(
|
|
35
|
+
:content => @content,
|
|
36
|
+
:expand_width => true, :expand_height => true
|
|
37
|
+
)
|
|
38
|
+
@vertical_scrollbar = VScrollBar.new(:container => @container)
|
|
39
|
+
@horizontal_scrollbar = HScrollBar.new(:container => @container)
|
|
40
|
+
@vertical_scrollbar.on_scroll{|o,e|
|
|
41
|
+
@container.scroll_y = e.y
|
|
42
|
+
}
|
|
43
|
+
@horizontal_scrollbar.on_scroll{|o,e|
|
|
44
|
+
@container.scroll_x = e.x
|
|
45
|
+
}
|
|
46
|
+
bottom_scroller = HLayout.new(:expand_width => true, :item_spacing => 0)
|
|
47
|
+
bottom_scroller << @horizontal_scrollbar << @resizer
|
|
48
|
+
hsplit << @container << @vertical_scrollbar
|
|
49
|
+
vsplit << hsplit << bottom_scroller
|
|
50
|
+
attach vsplit
|
|
51
|
+
@container.on_mouse_down{|o,e|
|
|
52
|
+
case e.button
|
|
53
|
+
when :wheel_up
|
|
54
|
+
@vertical_scrollbar.scroll_up
|
|
55
|
+
when :wheel_down
|
|
56
|
+
@vertical_scrollbar.scroll_down
|
|
57
|
+
end
|
|
58
|
+
}
|
|
59
|
+
self.min_width = @horizontal_scrollbar.min_width + @resizer.width
|
|
60
|
+
self.min_height = @vertical_scrollbar.min_height + @resizer.height
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
require 'glimr/widgets/layout'
|
|
2
|
+
require 'glimr/widgets/stretchable_image'
|
|
3
|
+
require 'glimr/widgets/button'
|
|
4
|
+
|
|
5
|
+
module GlimR
|
|
6
|
+
|
|
7
|
+
module Scrollable
|
|
8
|
+
|
|
9
|
+
def default_config
|
|
10
|
+
super.merge(
|
|
11
|
+
:default_scroll_horiz => 0.1,
|
|
12
|
+
:default_scroll_vert => 0.1,
|
|
13
|
+
:scroll_x => 0.0,
|
|
14
|
+
:scroll_y => 0.0
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Default horizontal scroll amount (=0.1).
|
|
19
|
+
attr_accessor :default_scroll_horiz
|
|
20
|
+
|
|
21
|
+
# Default horizontal scroll amount (=0.1).
|
|
22
|
+
attr_accessor :default_scroll_vert
|
|
23
|
+
|
|
24
|
+
# Accessors for scroll positions
|
|
25
|
+
attr_accessor :scroll_x, :scroll_y
|
|
26
|
+
|
|
27
|
+
# Scrolls to left (decreases scroll_x) by given
|
|
28
|
+
# amount, default is #default_scroll_horiz.
|
|
29
|
+
#
|
|
30
|
+
def scroll_left(amount = default_scroll_horiz)
|
|
31
|
+
self.scroll_x -= amount
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Scrolls to right (increases scroll_x) by given
|
|
35
|
+
# amount, default is #default_scroll_horiz.
|
|
36
|
+
#
|
|
37
|
+
def scroll_right(amount = default_scroll_horiz)
|
|
38
|
+
self.scroll_x += amount
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Scrolls up (decreases scroll_y) by given
|
|
42
|
+
# amount, default is #default_scroll_vert.
|
|
43
|
+
#
|
|
44
|
+
def scroll_up(amount = default_scroll_vert)
|
|
45
|
+
self.scroll_y -= amount
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Scrolls down (increases scroll_y) by given
|
|
49
|
+
# amount, default is #default_scroll_vert.
|
|
50
|
+
#
|
|
51
|
+
def scroll_down(amount = default_scroll_vert)
|
|
52
|
+
self.scroll_y += amount
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Scrolls x to nx, calls scroll_to to do the scrolling.
|
|
56
|
+
def scroll_x=(nx)
|
|
57
|
+
scroll_to(nx, scroll_y)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Scrolls y to ny, calls scroll_to to do the scrolling.
|
|
61
|
+
def scroll_y=(ny)
|
|
62
|
+
scroll_to(scroll_x, ny)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Increases both x and y scroll position by given amounts.
|
|
66
|
+
def scroll(x, y)
|
|
67
|
+
scroll_to(@scroll_position.x + x, @scroll_position.y + y)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def scroll_x
|
|
71
|
+
(@container and @container.scroll_x) or @scroll_x
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def scroll_y
|
|
75
|
+
(@container and @container.scroll_y) or @scroll_y
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Scrolls to given coordinates, clamped between 0.0 and 1.0, and
|
|
79
|
+
# fires a scroll event.
|
|
80
|
+
def scroll_to(x,y)
|
|
81
|
+
@scroll_x = [[x, 0.0].max, 1.0].min
|
|
82
|
+
@scroll_y = [[y, 0.0].max, 1.0].min
|
|
83
|
+
@container.scroll = [@scroll_x, @scroll_y] if @container
|
|
84
|
+
dispatch_event(Event.new(:scroll, :x => scroll_x, :y => scroll_y, :source => self))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class HScrollBar < HLayout
|
|
91
|
+
include Scrollable
|
|
92
|
+
|
|
93
|
+
touching_accessor :container
|
|
94
|
+
|
|
95
|
+
def default_config
|
|
96
|
+
super.merge(
|
|
97
|
+
:item_spacing => 0,
|
|
98
|
+
:expand_width => true, :container => nil,
|
|
99
|
+
:left_button => ScrollLeftButton.new,
|
|
100
|
+
:right_button => ScrollRightButton.new,
|
|
101
|
+
:scroller => HScroller.new
|
|
102
|
+
)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def initialize(*a, &b)
|
|
106
|
+
super
|
|
107
|
+
attach @left_button, @scroller, @right_button
|
|
108
|
+
@updater = lambda{|o,e| @scroller.update_knob }
|
|
109
|
+
self.container = @container
|
|
110
|
+
on_scroll{ @scroller.knob.scroll_handler if @scroller }
|
|
111
|
+
self.min_width = @left_button.width + @right_button.width + @scroller.min_width
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def click(o,e)
|
|
115
|
+
case e.button
|
|
116
|
+
when :wheel_down
|
|
117
|
+
scroll_right
|
|
118
|
+
when :wheel_up
|
|
119
|
+
scroll_left
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def container=(c)
|
|
124
|
+
@container.remove_event_listener(:layout, @updater) if @container
|
|
125
|
+
@container = c
|
|
126
|
+
@container.add_event_listener(:layout, @updater) if @container
|
|
127
|
+
@scroller.update_knob if @scroller
|
|
128
|
+
touch!
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class VScrollBar < VLayout
|
|
135
|
+
include Scrollable
|
|
136
|
+
|
|
137
|
+
touching_accessor :container
|
|
138
|
+
|
|
139
|
+
def default_config
|
|
140
|
+
super.merge(
|
|
141
|
+
:item_spacing => 0,
|
|
142
|
+
:expand_height => true, :container => nil,
|
|
143
|
+
:up_button => ScrollUpButton.new,
|
|
144
|
+
:down_button => ScrollDownButton.new,
|
|
145
|
+
:scroller => VScroller.new
|
|
146
|
+
)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def initialize(*a, &b)
|
|
150
|
+
super
|
|
151
|
+
attach @up_button, @scroller, @down_button
|
|
152
|
+
@updater = lambda{|o,e| @scroller.update_knob }
|
|
153
|
+
self.container = @container
|
|
154
|
+
on_scroll{ @scroller.knob.scroll_handler if @scroller }
|
|
155
|
+
self.min_height = @up_button.height + @down_button.height + @scroller.min_height
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def click(o,e)
|
|
159
|
+
case e.button
|
|
160
|
+
when :wheel_down
|
|
161
|
+
scroll_down
|
|
162
|
+
when :wheel_up
|
|
163
|
+
scroll_up
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def container=(c)
|
|
168
|
+
@container.remove_event_listener(:layout, @updater) if @container
|
|
169
|
+
@container = c
|
|
170
|
+
@container.add_event_listener(:layout, @updater) if @container
|
|
171
|
+
@scroller.update_knob if @scroller
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class HScroller < Widget
|
|
178
|
+
|
|
179
|
+
touching_accessor :knob
|
|
180
|
+
|
|
181
|
+
def default_config
|
|
182
|
+
super.merge(
|
|
183
|
+
:expand_width => true,
|
|
184
|
+
:knob => HScrollKnob.new,
|
|
185
|
+
:background => GlimR::StretchableImage.load_theme('hscroller_bg.png')
|
|
186
|
+
)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def initialize(*a,&b)
|
|
190
|
+
super
|
|
191
|
+
@knob.z = 5
|
|
192
|
+
attach @background, @knob
|
|
193
|
+
self.min_width = @knob.width
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def click(o,e)
|
|
197
|
+
if e.target == @background.geometry
|
|
198
|
+
distance_from_knob_right = (@knob.x + @knob.width - e.rx)
|
|
199
|
+
distance_from_knob_left = (@knob.x - e.rx)
|
|
200
|
+
if distance_from_knob_right.abs > distance_from_knob_left.abs
|
|
201
|
+
@knob.new_x = e.rx
|
|
202
|
+
else
|
|
203
|
+
@knob.new_x = e.rx - @knob.width
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def update_knob
|
|
209
|
+
@knob.layout
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def layout
|
|
213
|
+
return if @layouting
|
|
214
|
+
@layouting = true
|
|
215
|
+
super
|
|
216
|
+
@background.set_dimensions(@width, @height) if @background.width != @width or @background.height != @height
|
|
217
|
+
update_knob
|
|
218
|
+
@layouting = false
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class VScroller < Widget
|
|
225
|
+
|
|
226
|
+
touching_accessor :knob
|
|
227
|
+
|
|
228
|
+
def default_config
|
|
229
|
+
super.merge(
|
|
230
|
+
:expand_height => true,
|
|
231
|
+
:knob => VScrollKnob.new,
|
|
232
|
+
:background => GlimR::StretchableImage.load_theme('vscroller_bg.png')
|
|
233
|
+
)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def initialize(*a,&b)
|
|
237
|
+
super
|
|
238
|
+
@knob.z = 5
|
|
239
|
+
attach @background,@knob
|
|
240
|
+
self.min_height = @knob.height
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def click(o,e)
|
|
244
|
+
if e.target == @background.geometry
|
|
245
|
+
distance_from_knob_bottom = (@knob.y + @knob.height - e.ry)
|
|
246
|
+
distance_from_knob_top = (@knob.y - e.ry)
|
|
247
|
+
if distance_from_knob_bottom.abs > distance_from_knob_top.abs
|
|
248
|
+
@knob.new_y = e.ry
|
|
249
|
+
else
|
|
250
|
+
@knob.new_y = e.ry - @knob.height
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def update_knob
|
|
256
|
+
@knob.layout
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def layout
|
|
260
|
+
return if @layouting
|
|
261
|
+
@layouting = true
|
|
262
|
+
super
|
|
263
|
+
@background.set_dimensions(@width, @height) if @background.width != @width or @background.height != @height
|
|
264
|
+
update_knob
|
|
265
|
+
@layouting = false
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
class HScrollKnob < EmptyButton
|
|
272
|
+
|
|
273
|
+
def default_config
|
|
274
|
+
super.merge(
|
|
275
|
+
:up_background => "scroll_hknob_up.png",
|
|
276
|
+
:down_background => "scroll_hknob_down.png",
|
|
277
|
+
:up_cover => nil, :down_cover => nil, :focus_indicator => nil,
|
|
278
|
+
:label => nil,
|
|
279
|
+
:padding => 0, :rel_x => 0
|
|
280
|
+
)
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def initialize(*a,&b)
|
|
284
|
+
super
|
|
285
|
+
on_scroll(:scroll_handler)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def container
|
|
289
|
+
parent.parent.container
|
|
290
|
+
rescue NoMethodError
|
|
291
|
+
nil
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def layout
|
|
295
|
+
return if @layouting
|
|
296
|
+
@layouting = true
|
|
297
|
+
if container
|
|
298
|
+
self.width = [parent.inner_width,
|
|
299
|
+
[
|
|
300
|
+
self.min_width || 0.0,
|
|
301
|
+
(container.width / container.content.width.to_f)*parent.inner_width
|
|
302
|
+
].max
|
|
303
|
+
].min.to_i
|
|
304
|
+
@background_model.width = @width if @background_model
|
|
305
|
+
parent.parent.scroll_x = parent.parent.scroll_x
|
|
306
|
+
end
|
|
307
|
+
@layouting = false
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def mouse_down(o,e)
|
|
311
|
+
super
|
|
312
|
+
@rel_x = e.rx
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def mouse_move(o,e)
|
|
316
|
+
if @down and e.buttons[:left]
|
|
317
|
+
self.new_x += e.dx
|
|
318
|
+
@rel_x += e.dx
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def new_x
|
|
323
|
+
@new_x || self.x
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def new_x=(nx)
|
|
327
|
+
on_frame(:update_scroll) unless @new_x
|
|
328
|
+
@new_x = [scroll_max, [0, nx].max].min
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# The highest value the scroll knob can have. (Lowest is 0.)
|
|
332
|
+
def scroll_max
|
|
333
|
+
parent.inner_width - self.full_width
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def scroll_handler(*a)
|
|
337
|
+
self.x = parent.parent.scroll_x * scroll_max
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
def update_scroll(o,e)
|
|
341
|
+
new_scroll = (scroll_max > 0 ? (@new_x.to_f / scroll_max) : (@rel_x.to_f / parent.inner_width))
|
|
342
|
+
parent.parent.scroll_x = new_scroll
|
|
343
|
+
@new_x = nil
|
|
344
|
+
remove_event_listener(:frame, :update_scroll)
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
class VScrollKnob < EmptyButton
|
|
351
|
+
|
|
352
|
+
def default_config
|
|
353
|
+
super.merge(
|
|
354
|
+
:up_background => "scroll_vknob_up.png",
|
|
355
|
+
:down_background => "scroll_vknob_down.png",
|
|
356
|
+
:up_cover => nil, :down_cover => nil, :focus_indicator => nil, :label => nil,
|
|
357
|
+
:padding => 0, :rel_y => 0
|
|
358
|
+
)
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def initialize(*a,&b)
|
|
362
|
+
super
|
|
363
|
+
on_scroll(:scroll_handler)
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
def container
|
|
367
|
+
parent.parent.container
|
|
368
|
+
rescue NoMethodError
|
|
369
|
+
nil
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def layout
|
|
373
|
+
return if @layouting
|
|
374
|
+
@layouting = true
|
|
375
|
+
if container
|
|
376
|
+
self.height = [parent.inner_height,
|
|
377
|
+
[
|
|
378
|
+
self.min_height || 0.0,
|
|
379
|
+
(container.height / container.content.height.to_f)*parent.inner_height
|
|
380
|
+
].max
|
|
381
|
+
].min.to_i
|
|
382
|
+
@background_model.height = @height if @background_model
|
|
383
|
+
parent.parent.scroll_y = parent.parent.scroll_y
|
|
384
|
+
end
|
|
385
|
+
@layouting = false
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def mouse_down(o,e)
|
|
389
|
+
super
|
|
390
|
+
@rel_y = e.ry
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
def mouse_move(o,e)
|
|
394
|
+
if @down and e.buttons[:left]
|
|
395
|
+
self.new_y += e.dy
|
|
396
|
+
@rel_y += e.dy
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def new_y
|
|
401
|
+
@new_y || self.y
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def new_y=(ny)
|
|
405
|
+
on_frame(:update_scroll) unless @new_y
|
|
406
|
+
@new_y = [scroll_max, [0, ny].max].min
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# The highest value the scroll knob can have. (Lowest is 0.)
|
|
410
|
+
def scroll_max
|
|
411
|
+
parent.inner_height - self.full_height
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
def scroll_handler(*a)
|
|
415
|
+
self.y = parent.parent.scroll_y * scroll_max
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
def update_scroll(o,e)
|
|
419
|
+
new_scroll = (scroll_max > 0 ? (@new_y.to_f / scroll_max) : (@rel_y.to_f / parent.inner_height))
|
|
420
|
+
parent.parent.scroll_y = new_scroll
|
|
421
|
+
@new_y = nil
|
|
422
|
+
remove_event_listener(:frame, :update_scroll)
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
class ScrollLeftButton < EmptyButton
|
|
429
|
+
|
|
430
|
+
def default_config
|
|
431
|
+
super.merge(
|
|
432
|
+
:up_background => "scroll_left_up.png",
|
|
433
|
+
:down_background => "scroll_left_down.png",
|
|
434
|
+
:up_cover => nil, :down_cover => nil, :focus_indicator => nil, :label => nil,
|
|
435
|
+
:padding => 0
|
|
436
|
+
)
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
def activate(o,e)
|
|
440
|
+
parent.scroll_left
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
class ScrollRightButton < EmptyButton
|
|
446
|
+
|
|
447
|
+
def default_config
|
|
448
|
+
super.merge(
|
|
449
|
+
:up_background => "scroll_right_up.png",
|
|
450
|
+
:down_background => "scroll_right_down.png",
|
|
451
|
+
:up_cover => nil, :down_cover => nil, :focus_indicator => nil, :label => nil,
|
|
452
|
+
:padding => 0
|
|
453
|
+
)
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def activate(o,e)
|
|
457
|
+
parent.scroll_right
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
class ScrollUpButton < EmptyButton
|
|
463
|
+
|
|
464
|
+
def default_config
|
|
465
|
+
super.merge(
|
|
466
|
+
:up_background => "scroll_up_up.png",
|
|
467
|
+
:down_background => "scroll_up_down.png",
|
|
468
|
+
:up_cover => nil, :down_cover => nil, :focus_indicator => nil, :label => nil,
|
|
469
|
+
:padding => 0
|
|
470
|
+
)
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
def activate(o,e)
|
|
474
|
+
parent.scroll_up
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
class ScrollDownButton < EmptyButton
|
|
480
|
+
|
|
481
|
+
def default_config
|
|
482
|
+
super.merge(
|
|
483
|
+
:up_background => "scroll_down_up.png",
|
|
484
|
+
:down_background => "scroll_down_down.png",
|
|
485
|
+
:up_cover => nil, :down_cover => nil, :focus_indicator => nil, :label => nil,
|
|
486
|
+
:padding => 0
|
|
487
|
+
)
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
def activate(o,e)
|
|
491
|
+
parent.scroll_down
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
end
|