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.
Files changed (90) hide show
  1. data/lib/glimr.rb +2 -0
  2. data/lib/glimr/configurable.rb +37 -0
  3. data/lib/glimr/default_theme/button_bg.png +0 -0
  4. data/lib/glimr/default_theme/button_bg_down.png +0 -0
  5. data/lib/glimr/default_theme/button_cover.png +0 -0
  6. data/lib/glimr/default_theme/button_cover_down.png +0 -0
  7. data/lib/glimr/default_theme/button_focus.png +0 -0
  8. data/lib/glimr/default_theme/checkbox_bg.png +0 -0
  9. data/lib/glimr/default_theme/checkbox_checked_bg.png +0 -0
  10. data/lib/glimr/default_theme/font.ttf +0 -0
  11. data/lib/glimr/default_theme/hscroller_bg.png +0 -0
  12. data/lib/glimr/default_theme/radiobutton_bg.png +0 -0
  13. data/lib/glimr/default_theme/radiobutton_checked_bg.png +0 -0
  14. data/lib/glimr/default_theme/resizer_down.png +0 -0
  15. data/lib/glimr/default_theme/resizer_up.png +0 -0
  16. data/lib/glimr/default_theme/scroll_down_down.png +0 -0
  17. data/lib/glimr/default_theme/scroll_down_up.png +0 -0
  18. data/lib/glimr/default_theme/scroll_hknob_down.png +0 -0
  19. data/lib/glimr/default_theme/scroll_hknob_up.png +0 -0
  20. data/lib/glimr/default_theme/scroll_left_down.png +0 -0
  21. data/lib/glimr/default_theme/scroll_left_up.png +0 -0
  22. data/lib/glimr/default_theme/scroll_right_down.png +0 -0
  23. data/lib/glimr/default_theme/scroll_right_up.png +0 -0
  24. data/lib/glimr/default_theme/scroll_up_down.png +0 -0
  25. data/lib/glimr/default_theme/scroll_up_up.png +0 -0
  26. data/lib/glimr/default_theme/scroll_vknob_down.png +0 -0
  27. data/lib/glimr/default_theme/scroll_vknob_up.png +0 -0
  28. data/lib/glimr/default_theme/text_cursor.png +0 -0
  29. data/lib/glimr/default_theme/text_cursor_insert.png +0 -0
  30. data/lib/glimr/default_theme/text_input_bg.png +0 -0
  31. data/lib/glimr/default_theme/vscroller_bg.png +0 -0
  32. data/lib/glimr/event.rb +41 -0
  33. data/lib/glimr/eventlistener.rb +209 -0
  34. data/lib/glimr/layoutable.rb +520 -0
  35. data/lib/glimr/renderer.rb +2 -0
  36. data/lib/glimr/renderer/camera.rb +63 -0
  37. data/lib/glimr/renderer/geometry.rb +194 -0
  38. data/lib/glimr/renderer/glutwindow.rb +387 -0
  39. data/lib/glimr/renderer/light.rb +43 -0
  40. data/lib/glimr/renderer/material.rb +66 -0
  41. data/lib/glimr/renderer/model.rb +103 -0
  42. data/lib/glimr/renderer/orthoprojection.rb +21 -0
  43. data/lib/glimr/renderer/raw.rb +34 -0
  44. data/lib/glimr/renderer/sceneobject.rb +279 -0
  45. data/lib/glimr/renderer/shader.rb +14 -0
  46. data/lib/glimr/renderer/texture.rb +280 -0
  47. data/lib/glimr/renderer/transform.rb +322 -0
  48. data/lib/glimr/renderer/viewport.rb +349 -0
  49. data/lib/glimr/renderer_core.rb +10 -0
  50. data/lib/glimr/util.rb +247 -0
  51. data/lib/glimr/widget.rb +87 -0
  52. data/lib/glimr/widgets.rb +37 -0
  53. data/lib/glimr/widgets/button.rb +277 -0
  54. data/lib/glimr/widgets/checkbox.rb +82 -0
  55. data/lib/glimr/widgets/container.rb +84 -0
  56. data/lib/glimr/widgets/image.rb +82 -0
  57. data/lib/glimr/widgets/label.rb +91 -0
  58. data/lib/glimr/widgets/layout.rb +227 -0
  59. data/lib/glimr/widgets/list.rb +28 -0
  60. data/lib/glimr/widgets/radiogroup.rb +118 -0
  61. data/lib/glimr/widgets/resizer.rb +31 -0
  62. data/lib/glimr/widgets/scrollable_container.rb +67 -0
  63. data/lib/glimr/widgets/scrollbar.rb +496 -0
  64. data/lib/glimr/widgets/stretchable_image.rb +135 -0
  65. data/lib/glimr/widgets/text_editor.rb +349 -0
  66. data/tests/assets/datatowers_crop.jpg +0 -0
  67. data/tests/assets/download_progress_meter.png +0 -0
  68. data/tests/assets/metalwing2.png +0 -0
  69. data/tests/assets/redhairgreeneyes3.jpg +0 -0
  70. data/tests/demo_apps/spinning_ruby.rb +37 -0
  71. data/tests/integration_tests/run_all.rb +8 -0
  72. data/tests/integration_tests/test_button.rb +22 -0
  73. data/tests/integration_tests/test_checkbox.rb +21 -0
  74. data/tests/integration_tests/test_container.rb +22 -0
  75. data/tests/integration_tests/test_label.rb +12 -0
  76. data/tests/integration_tests/test_layout.rb +43 -0
  77. data/tests/integration_tests/test_radiogroup.rb +16 -0
  78. data/tests/integration_tests/test_renderer.rb +44 -0
  79. data/tests/integration_tests/test_renderer2.rb +36 -0
  80. data/tests/integration_tests/test_scrollable_container.rb +34 -0
  81. data/tests/integration_tests/test_scrollbar.rb +20 -0
  82. data/tests/integration_tests/test_stretchable_image.rb +34 -0
  83. data/tests/integration_tests/test_text_input.rb +20 -0
  84. data/tests/integration_tests/test_zsort.rb +18 -0
  85. data/tests/unit_tests/test_button.rb +93 -0
  86. data/tests/unit_tests/test_checkbox.rb +35 -0
  87. data/tests/unit_tests/test_label.rb +36 -0
  88. data/tests/unit_tests/test_layout.rb +229 -0
  89. data/tests/unit_tests/test_widget.rb +3 -0
  90. metadata +139 -0
@@ -0,0 +1,37 @@
1
+ puts "TODO (before this can run):
2
+ + port Ruby and OmniLight over from librend
3
+ + make 3D scene and lights handling for GLUTWindow
4
+
5
+ Exiting."
6
+ exit
7
+
8
+ require 'glimr'
9
+
10
+ braking = false
11
+ spin = 10
12
+
13
+ ruby = GlimR::Ruby.new :scale => 1.2
14
+ ruby.add_time_handler{|o,t,dt|
15
+ if spin > 0
16
+ o.angle += spin * dt * 20
17
+ spin -= dt * 5
18
+ spin -= dt * 20 if braking
19
+ end
20
+ }
21
+
22
+ spinner = GlimR::Button.new(:label => "Spin it!"){ spin += 10 }
23
+ braker = GlimR::Button.new(:label => "Brake!")
24
+ braker.on_down{ braking = true }
25
+ braker.on_up{ braking = false }
26
+ quitter = GlimR::Button.new(:label => "Quit"){ exit }
27
+
28
+ controls = GlimR::HLayout.new
29
+ controls.attach spinner, braker, quitter
30
+
31
+ window = GlimR::GLUTWindow.new(300,300, "Spinning Ruby")
32
+ window.attach controls
33
+ window.scene.camera.y = 0.5
34
+ light1 = GlimR::OmniLight.new(:position => [2,5,2])
35
+ light2 = GlimR::OmniLight.new(:position => [2,-2,2])
36
+ window.scene.attach light1, light2, ruby
37
+ window.run
@@ -0,0 +1,8 @@
1
+ tests = Dir[File.join( File.dirname(__FILE__), "test_*.rb")]
2
+
3
+ tests.each{|t|
4
+ puts t
5
+ system("ruby", t)
6
+ puts "-"*72
7
+ }
8
+
@@ -0,0 +1,22 @@
1
+ GC.disable
2
+ require 'glimr'
3
+
4
+ vl = GlimR::VLayout.new
5
+ b1 = GlimR::Button.new( :label => "Button" ){|o,e| puts "You pushed #{o.label}" }
6
+ b2 = GlimR::Button.new( :label => "Button with long label" ){|o,e| puts "You pushed #{o.label}" }
7
+ b3 = GlimR::Button.new( :label => "Button\nwith\nseveral lines\nin its\nlabel" ){|o,e| puts "You pushed #{o.label}" }
8
+ vl.attach b1, b2, b3
9
+
10
+ w = GlimR::GLUTWindow.new(400,400)
11
+ w.attach vl
12
+
13
+ f = w.frames_drawn
14
+ puts "Frame: #{f}"
15
+ vl.on_frame{
16
+ if f != w.frames_drawn
17
+ f = w.frames_drawn
18
+ puts "Frame: #{f}"
19
+ end
20
+ }
21
+
22
+ w.run
@@ -0,0 +1,21 @@
1
+ require 'glimr'
2
+
3
+
4
+ vl = GlimR::VLayout.new
5
+ b1 = GlimR::Checkbox.new(:label => "Checkbox")
6
+ b1.on_change{|o,e|
7
+ puts "#{o.label}: #{o.state}"
8
+ }
9
+ b2 = GlimR::Checkbox.new(:label => "Checkbox with a long label")
10
+ b2.on_change{|o,e|
11
+ puts "#{o.label}: #{o.state}"
12
+ }
13
+ b3 = GlimR::Checkbox.new(:label => "Checkbox\nwith\nmany\nlines\nin its\nlabel")
14
+ b3.on_change{|o,e|
15
+ puts "#{o.label}: #{o.state}"
16
+ }
17
+ vl.attach b1, b2, b3
18
+
19
+ gw = GlimR::GLUTWindow.new
20
+ gw.attach vl
21
+ gw.run
@@ -0,0 +1,22 @@
1
+ require 'glimr'
2
+
3
+
4
+ c = GlimR::Container.new(
5
+ :expand_height => true, :expand_width => true,
6
+ :content => GlimR::Image.new(
7
+ :image => File.join(File.dirname(__FILE__), "..", "assets",
8
+ "datatowers_crop.jpg"))
9
+ )
10
+ c.on_mouse_move{|o,e|
11
+ if e.buttons[:left]
12
+ o.scroll_x -= e.dx
13
+ o.scroll_y -= e.dy
14
+ end
15
+ }
16
+
17
+ gw = GlimR::GLUTWindow.new
18
+ gw.attach c
19
+
20
+ p [c.width, c.height]
21
+ p [c.content_view.viewport_width, c.content_view.viewport_height]
22
+ gw.run
@@ -0,0 +1,12 @@
1
+ require 'glimr'
2
+
3
+ include GlimR
4
+
5
+ w = GLUTWindow.new
6
+
7
+ w.attach GlimR::Label.new(
8
+ :text => "This is a simple label",
9
+ :color => [1,0,0,1]
10
+ )
11
+
12
+ w.run
@@ -0,0 +1,43 @@
1
+ require 'glimr'
2
+
3
+
4
+ b = GlimR::VLayout.new
5
+ b << GlimR::Image.new(:image => GlimR.theme + 'button_bg.png')
6
+ b << GlimR::Image.new(:image => GlimR.theme + 'button_bg.png')
7
+ b.children.last.scale = 0.5
8
+ b << GlimR::Image.new(:image => GlimR.theme + 'button_bg.png')
9
+ b.children.last.scale = 2.0
10
+ b << GlimR::Image.new(:image => GlimR.theme + 'button_bg.png')
11
+ b << GlimR::Button.new(:label => "Button")
12
+
13
+ h = GlimR::HLayout.new(
14
+ :min_width => 600, :min_height => 200,
15
+ :align => :right
16
+ )
17
+ h << GlimR::Button.new(:label => "Pad"){|o,e| o.margin = o.margin_left + 2 }
18
+ h << GlimR::Container.new(
19
+ :expand_width => true,
20
+ :content => GlimR::Image.new(:image => File.join(File.dirname(__FILE__), "..", "assets", "datatowers_crop.jpg"))
21
+ ){|c|
22
+ scroll = [0,0]
23
+ changed = false
24
+ c.on_mouse_move{|o,e|
25
+ if e.buttons[:left]
26
+ scroll[0] -= e.dx
27
+ scroll[1] -= e.dy
28
+ changed = true
29
+ end
30
+ }
31
+ c.on_frame{|o,e|
32
+ if changed
33
+ o.scroll = scroll
34
+ changed = false
35
+ end
36
+ }
37
+ }
38
+
39
+ b << h
40
+
41
+ gw = GlimR::GLUTWindow.new
42
+ gw << b
43
+ gw.run
@@ -0,0 +1,16 @@
1
+ require 'glimr'
2
+
3
+ #GlimR.label_font = "GNU Unifont"
4
+ b = GlimR::RadioGroup.new(
5
+ :label => "Selection from the alphabet",
6
+ :options => [
7
+ "A", "B", "C", "D", "E", "F",
8
+ "I can't see my letter here..."
9
+ ]
10
+ )
11
+ b.on_select{|o,e|
12
+ puts "Selected option number #{e.selected_index}: #{e.option}"
13
+ }
14
+ gw = GlimR::GLUTWindow.new
15
+ gw.attach b
16
+ gw.run
@@ -0,0 +1,44 @@
1
+ require 'glimr/renderer'
2
+
3
+ include GlimR
4
+
5
+ t = Transform.new
6
+ t.position = [100, 100]
7
+ t.scale = Math.sin(Time.now.to_f)
8
+ angle = (90*Time.now.to_f)%360
9
+ t.rotation = AngleAxis[angle, 0, 0, 1]
10
+
11
+ g = Geometry.new
12
+ g.vertices = [-100,-100,0, 100,-100,0, 100,100,0, -100,100,0].pack("f*")
13
+ g.texcoords = [0,1, 1,1, 1,0, 0,0].pack("f*")
14
+ g.type = GL::QUADS
15
+
16
+ tex = Texture.load('../assets/datatowers_crop.jpg')
17
+ tex2 = Texture.load('../assets/redhairgreeneyes3.jpg')
18
+
19
+ cam = Camera.new
20
+ cam.position = [-150,-150,100]
21
+ cam.looking_at = [-0,-0,0]
22
+ cam.perspective = true
23
+ cam.up = [0,1,0]
24
+
25
+ r = Raw.new
26
+ r.renderer = lambda do
27
+ end
28
+
29
+ t.add_event_listener(:frame) do |o,e|
30
+ o.scale = Math.sin(e.time)
31
+ o.rotation = AngleAxis[ (90*e.time)%360, 0, 0, 1 ]
32
+ end
33
+ s2 = Transform.scale 2
34
+ r.attach s2
35
+ s2.attach t
36
+ t.attach tex
37
+ tex.attach g
38
+ tex2.attach g.clone
39
+ s2.attach tex2
40
+
41
+ vp = GlimR::GLUTWindow.new(500,500)
42
+ vp.camera = cam
43
+ vp.attach r
44
+ vp.run
@@ -0,0 +1,36 @@
1
+ require 'glimr/widgets/image'
2
+ require 'glimr/renderer/glutwindow'
3
+
4
+
5
+ include GlimR
6
+
7
+ img = Image.load("../assets/redhairgreeneyes3.jpg")
8
+ img.scale = 0.5
9
+ img.add_event_listener(:frame){|o, e|
10
+ o.angle = (120*e.time) % 360
11
+ hw = o.viewport.width/2
12
+ hh = o.viewport.height/2
13
+ o.x = hw+50*Math.sin(e.time)
14
+ o.y = hh+50*Math.cos(e.time)
15
+ }
16
+
17
+ img.attach
18
+ t1 = Transform.new
19
+ t1.position = [0,500]
20
+ t1.attach img.geometry.clone(false)
21
+ t2 = Transform.new
22
+ t2.attach img.geometry.clone(false)
23
+ t3 = Transform.new
24
+ t3.position = [500,0]
25
+ t3.attach t2
26
+
27
+ img.shader.attach t1, t3
28
+
29
+ w = GLUTWindow.new(500,500)
30
+ w.attach img
31
+
32
+ #~ bob = Image.load("../assets/datatowers_crop.jpg")
33
+ #~ d = GLUTWindow.new(400,200,"bob",500,500)
34
+ #~ d.attach bob
35
+
36
+ w.run
@@ -0,0 +1,34 @@
1
+ require 'glimr'
2
+
3
+ images = []
4
+ imagedir = (Pathname.new(__FILE__).dirname + "../assets")
5
+ imagedir.entries.map{|e|
6
+ if e.extname =~ /\.(jpg|png)/i
7
+ images << imagedir+e
8
+ end
9
+ }
10
+
11
+ sc = GlimR::ScrollableContainer.new(
12
+ :width => 400, :height => 300, :fit_children => false,
13
+ :content => GlimR::Image.load(images[0])
14
+ )
15
+ sc.container.on_click{|o,e|
16
+ if e.button == :left
17
+ images.push images.shift
18
+ o.content.load images[0]
19
+ elsif e.button == :right
20
+ images.unshift images.pop
21
+ o.content.load images[0]
22
+ end
23
+ }
24
+ sc.container.on_drag{|o,e|
25
+ if e.buttons[:left]
26
+ sc.x += e.dx
27
+ sc.y += e.dy
28
+ end
29
+ }
30
+
31
+ gw = GlimR::GLUTWindow.new(400, 300)
32
+ gw.attach sc
33
+ gw.run
34
+
@@ -0,0 +1,20 @@
1
+ require 'glimr'
2
+
3
+ vsb = GlimR::VScrollBar.new
4
+ vsb.on_scroll{|o,e|
5
+ puts "vert scroll = #{e.y}"
6
+ }
7
+ hsb = GlimR::HScrollBar.new
8
+ hsb.on_scroll{|o,e|
9
+ puts "horiz scroll = #{e.x}"
10
+ }
11
+ lv = GlimR::VLayout.new(:expand_width => true, :expand_height => true)
12
+ ew = GlimR::Widget.new(:expand_height=>true, :expand_width=>true)
13
+ lv.attach ew, hsb
14
+
15
+ lh = GlimR::HLayout.new(:expand_height => true, :expand_width => true)
16
+ lh.attach lv, vsb
17
+
18
+ gw = GlimR::GLUTWindow.new
19
+ gw.attach lh
20
+ gw.run
@@ -0,0 +1,34 @@
1
+ require 'glimr'
2
+
3
+
4
+ include GlimR
5
+
6
+ vl = VLayout.new(:expand_width => true, :expand_height => true)
7
+ i = Image.load_theme('button_bg.png')
8
+ b = StretchableImage.load_theme('button_bg.png')
9
+ b2 = StretchableImage.new(:image => GlimR.theme + 'button_bg.png', :width => 200, :height => 100)
10
+
11
+ b2.on_mouse_over{|o,e|
12
+ o.load(GlimR.theme + 'button_bg_down.png')
13
+ }
14
+ b2.on_mouse_out{|o,e|
15
+ o.load(GlimR.theme + 'button_bg.png')
16
+ }
17
+
18
+ vl << Label.new(:text => "Normal image")
19
+ vl << i
20
+ vl << Label.new(:text => "Stretchable version of image\n(should look like the one above)")
21
+ vl << b
22
+ vl << Label.new(:text => "Stretched to 200x100")
23
+ vl << b2
24
+
25
+ w = GLUTWindow.new 300,300
26
+ w.background = [1,1,1,1]
27
+ w.attach vl
28
+
29
+ p [i.width, i.height]
30
+ p [b.width, b.height]
31
+ p [b2.width, b2.height]
32
+ p [vl.width, vl.height]
33
+
34
+ w.run
@@ -0,0 +1,20 @@
1
+ require 'glimr'
2
+ include GlimR
3
+
4
+ name_form = VLayout.new(
5
+ :expand_height => true, :expand_width => true,
6
+ :align => :center, :valign => :middle)
7
+
8
+ label = Label.new(:text => "Enter your name:")
9
+ name_input = TextInput.new(:text => ""){|o,e|
10
+ name_form.attach Label.new(:text => "Hi, #{e.text}!")
11
+ }
12
+ submit = Button.new(:label => "OK"){|o,e|
13
+ name_input.submit
14
+ }
15
+ name_form.attach label, name_input, submit
16
+
17
+ window = GLUTWindow.new(400, 200, "My App")
18
+ window.attach name_form
19
+ window.run
20
+
@@ -0,0 +1,18 @@
1
+ require 'glimr'
2
+
3
+ include GlimR
4
+
5
+ gw = GLUTWindow.new
6
+
7
+ tf = Transform.translate(0, 0)
8
+
9
+ ts = StretchableImage.load_theme('button_bg.png')
10
+ ts.z = -1
11
+ ts2 = StretchableImage.load_theme('button_cover.png')
12
+ ts2.z = 0
13
+ ts3 = StretchableImage.load_theme('button_focus.png')
14
+ ts3.z = 1
15
+
16
+ gw.attach ts3, ts, ts2
17
+ #gw.attach tf
18
+ gw.run
@@ -0,0 +1,93 @@
1
+ require 'glimr'
2
+ require 'test/unit'
3
+
4
+ class ButtonTest < Test::Unit::TestCase
5
+ include GlimR
6
+
7
+ def setup
8
+ @b = GlimR::Button.new(:label => "My Button")
9
+ end
10
+
11
+ def test_label
12
+ assert_equal "My Button", @b.label
13
+ @b.label = "Bob"
14
+ assert_equal "Bob", @b.label
15
+ end
16
+
17
+ def test_label_resize
18
+ w,h = @b.width, @b.height
19
+ @b.label = "This is a really really long label for a button"
20
+ assert_equal h, @b.height
21
+ assert w < @b.width
22
+
23
+ label = GlimR::Label.new(:text => @b.label)
24
+ assert_equal(
25
+ label.width,
26
+ @b.inner_width
27
+ )
28
+ assert_equal(
29
+ 24,
30
+ @b.height
31
+ )
32
+
33
+ @b.label = "My Button\nHas\nMany\nLines"
34
+ assert_equal w, @b.width
35
+ assert h < @b.height
36
+ label = GlimR::Label.new(:text => @b.label)
37
+ assert_equal(
38
+ label.width + @b.padding_left + @b.padding_right,
39
+ @b.width
40
+ )
41
+ assert_equal(
42
+ label.height + @b.padding_top + @b.padding_bottom,
43
+ @b.height
44
+ )
45
+ end
46
+
47
+ def test_activation
48
+ @activated = false
49
+ @b.on_activate{|o,e|
50
+ @activated = true
51
+ }
52
+ send_activate_event
53
+ send_mouse_up_down
54
+ send_enter_up_down
55
+ @b = GlimR::Button.new{ @activated = true }
56
+ assert_equal 2, @b.event_listeners[:activate][:bubble].size
57
+ @b.event_listeners[:activate][:bubble][1].call
58
+ assert @activated
59
+ @activated = false
60
+ send_activate_event
61
+ send_mouse_up_down
62
+ send_enter_up_down
63
+ end
64
+
65
+ def send_activate_event
66
+ @b.multicast_event Event.new(:activate)
67
+ assert @activated
68
+ @activated = false
69
+ end
70
+
71
+ def send_mouse_up_down
72
+ @b.multicast_event Event.new(:mouse_over, {:button => :left})
73
+ @b.multicast_event Event.new(:mouse_down, {:button => :left})
74
+ @b.multicast_event Event.new(:mouse_up, {:button => :left})
75
+ assert @activated
76
+ @activated = false
77
+ end
78
+
79
+ def send_enter_up_down
80
+ @b.focused = true
81
+ assert @b.focused
82
+ @b.multicast_event Event.new(:key_down, {:key => 13})
83
+ assert @b.down
84
+ assert @b.focused
85
+ @b.multicast_event Event.new(:key_up, {:key => 13})
86
+ assert @activated
87
+ assert !@b.down
88
+ @activated = false
89
+ end
90
+
91
+
92
+ end
93
+