rubygoo 0.0.5 → 0.0.6

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/rubygoo/app.rb CHANGED
@@ -1,14 +1,15 @@
1
1
  module Rubygoo
2
2
  class App < Container
3
3
 
4
- DEFAULT_PARAMS = {:theme=>'default',:x=>10,:y=>10,:width=>600,:height=>480,:data_dir=>File.join(File.dirname(__FILE__),"..","..","themes"),:mouse_cursor => true}
5
- attr_accessor :theme_name, :theme, :data_dir, :theme_dir, :renderer
4
+ DEFAULT_PARAMS = {:theme=>'default',:x=>10,:y=>10,:data_dir=>File.join(File.dirname(__FILE__),"..","..","themes"),:mouse_cursor => true}
5
+ attr_accessor :theme_name, :theme, :data_dir, :theme_dir, :renderer, :tab_groups
6
6
 
7
7
  def initialize(opts={})
8
8
  merged_opts = DEFAULT_PARAMS.merge opts
9
9
  @widgets = []
10
- @tabbed_widgets = []
11
- @focussed_widget = 0
10
+ @tab_groups = []
11
+ @tab_groups << TabGroup.new
12
+
12
13
  theme_name = merged_opts[:theme]
13
14
  @data_dir = merged_opts[:data_dir]
14
15
  @theme_name = theme_name
@@ -17,13 +18,14 @@ module Rubygoo
17
18
  super merged_opts
18
19
 
19
20
  # should this go here?
20
- @mouse_opt = merged_opts[:mouse_cursor]
21
- if @mouse_opt
21
+ @mouse_cursor = merged_opts[:mouse_cursor]
22
+ if @mouse_cursor
22
23
  @mouse = MouseCursor.new
23
24
  @mouse.parent = self
24
25
  @mouse.app = self.app
25
26
  @mouse.added
26
27
  end
28
+ @mouse_dragging = false
27
29
  end
28
30
 
29
31
  def app()
@@ -38,30 +40,28 @@ module Rubygoo
38
40
  def draw(screen)
39
41
  @renderer.start_drawing
40
42
  super @renderer
41
- @mouse.draw @renderer if @mouse_opt
43
+ @mouse.draw @renderer if @mouse_cursor
42
44
  @renderer.finish_drawing
43
45
  end
44
46
 
47
+ def focus(w)
48
+ @tab_groups.last.focus w
49
+ end
50
+
45
51
  def add_tabbed_widget(w)
46
- w.focus_priority = @tabbed_widgets.size unless w.focus_priority
47
- @focussed_widget = 1
48
- w.focus if @tabbed_widgets.empty?
49
- @tabbed_widgets << w
50
- @tabbed_widgets.sort_by {|w| w.focus_priority}
52
+ @tab_groups[0].add w
53
+ end
54
+
55
+ def add_tab_group(tg)
56
+ @tab_groups << tg
51
57
  end
52
58
 
53
59
  def focus_back()
54
- @tabbed_widgets[@focussed_widget].unfocus
55
- @focussed_widget += 1
56
- @focussed_widget %= @tabbed_widgets.size
57
- @tabbed_widgets[@focussed_widget].focus
60
+ @tab_groups.last.previous
58
61
  end
59
62
 
60
63
  def focus_forward()
61
- @tabbed_widgets[@focussed_widget].unfocus
62
- @focussed_widget -= 1
63
- @focussed_widget %= @tabbed_widgets.size
64
- @tabbed_widgets[@focussed_widget].focus
64
+ @tab_groups.last.next
65
65
  end
66
66
 
67
67
  def on_event(event)
@@ -79,13 +79,71 @@ module Rubygoo
79
79
  else
80
80
  modal_keyboard_call :key_pressed, event
81
81
  end
82
+ when :mouse_down
83
+ modal_mouse_call :mouse_down, event
84
+ # TODO: I know this is simplistic and doesn't account for which button
85
+ # is being pressed/released
86
+ @mouse_start_x = event.data[:x]
87
+ @mouse_start_y = event.data[:y]
88
+ when :mouse_up
89
+ x = event.data[:x]
90
+ y = event.data[:y]
91
+ if @mouse_start_x == x and @mouse_start_y == y
92
+ modal_mouse_call :mouse_up, event
93
+ else
94
+ modal_mouse_call :mouse_drag, event
95
+ end
96
+ @mouse_start_x = nil
97
+ @mouse_start_y = nil
98
+ when :mouse_motion
99
+ x = event.data[:x]
100
+ y = event.data[:y]
101
+ if @mouse_start_x
102
+ modal_mouse_call :mouse_dragging, event
103
+ else
104
+ modal_mouse_call :mouse_motion, event
105
+ end
106
+ @mouse.mouse_motion event if @mouse_cursor
107
+ end
108
+ end
109
+
110
+ # redirects all events to this widget
111
+ def add_modal(widget)
112
+ @modal_widgets << widget
113
+ tg = TabGroup.new
114
+ tg.add(widget)
115
+ self.app.add_tab_group tg
116
+ add widget
117
+ end
118
+
119
+ def remove_modal(widget)
120
+ self.app.pop_tab_group
121
+ remove widget
122
+ end
123
+
124
+ def pop_tab_group()
125
+ @tab_groups.pop
126
+ end
127
+
128
+ # distribute our mouse events to our modals first
129
+ def modal_mouse_call(meth, event)
130
+ if @modal_widgets.empty?
131
+ @widgets.each do |w|
132
+ w.send meth, event if w.contains? [event.data[:x],event.data[:y]]
133
+ end
82
134
  else
83
- # ALL mouse events go here
84
- modal_mouse_call event.event_type, event
135
+ @modal_widgets.last.send meth, event
136
+ end
137
+ end
85
138
 
86
- if event.event_type == :mouse_motion
87
- @mouse.mouse_motion event if @mouse_opt
139
+ # distribute our keyboard events to our modals first
140
+ def modal_keyboard_call(meth, event)
141
+ if @modal_widgets.empty?
142
+ @widgets.each do |w|
143
+ w.send meth, event if w.focussed?
88
144
  end
145
+ else
146
+ @modal_widgets.last.send meth, event
89
147
  end
90
148
  end
91
149
 
@@ -3,6 +3,9 @@ module Rubygoo
3
3
  can_fire :pressed
4
4
  def initialize(text, opts={})
5
5
  super opts
6
+
7
+ @icon = opts[:icon]
8
+
6
9
  @text = text
7
10
  end
8
11
 
@@ -14,9 +17,13 @@ module Rubygoo
14
17
  @border_color = theme_property :border_color
15
18
  @focus_color = theme_property :focus_color
16
19
  @font_file = File.join(@app.theme_dir,font)
17
-
18
20
  @rendered_text ||= @app.renderer.render_text @text, @font_file, @font_size, @color
19
- @rect = Rect.new [@x-@x_pad,@y-@y_pad,@rendered_text.width+2*@x_pad,@rendered_text.height+2*@y_pad]
21
+ @w = @rendered_text.width+2*@x_pad
22
+ @h = @rendered_text.height+2*@y_pad
23
+ @x = @x - @x_pad
24
+ @y = @y - @y_pad
25
+
26
+ update_rect
20
27
  end
21
28
 
22
29
  # called when there is a mouse click
@@ -24,6 +31,11 @@ module Rubygoo
24
31
  fire :pressed, event
25
32
  end
26
33
 
34
+ # called when there is a mouse click at the end of a drag
35
+ def mouse_drag(event)
36
+ fire :pressed, event
37
+ end
38
+
27
39
  # called when a key press is sent to us
28
40
  def key_pressed(event)
29
41
  case event.data[:key]
@@ -33,21 +45,28 @@ module Rubygoo
33
45
  end
34
46
 
35
47
  def draw(adapter)
48
+ x1 = @rect[0]
49
+ y1 = @rect[1]
50
+ x2 = @rect[2] + x1
51
+ y2 = @rect[3] + y1
52
+
53
+
36
54
  if @focussed
37
- adapter.fill @focus_color, @rect
55
+ adapter.fill x1, y1, x2, y2, @focus_color
38
56
  elsif @bg_color
39
- adapter.fill @bg_color, @rect
57
+ adapter.fill x1, y1, x2, y2, @bg_color
40
58
  end
41
59
  if @border_color
42
- x1 = @rect[0]
43
- y1 = @rect[1]
44
- x2 = @rect[2] + x1
45
- y2 = @rect[3] + y1
46
60
  adapter.draw_box x1, y1, x2, y2, @border_color
47
61
  end
62
+ if @icon
63
+ # TODO center icon
64
+ ix = x1#+((x2-x1)-@icon.w)
65
+ iy = y1#+((y2-y1)-@icon.h)
66
+ adapter.draw_image @icon, ix+@x_pad,iy+@y_pad
67
+ end
48
68
 
49
-
50
- adapter.draw_image @rendered_text, @x, @y, @color
69
+ adapter.draw_image @rendered_text, @x+@x_pad, @y+@y_pad, @color
51
70
 
52
71
  end
53
72
  end
@@ -31,12 +31,12 @@ module Rubygoo
31
31
 
32
32
  def check()
33
33
  @checked = true
34
- fire :checked
34
+ fire :checked, self
35
35
  end
36
36
 
37
37
  def uncheck()
38
38
  @checked = false
39
- fire :checked
39
+ fire :checked, self
40
40
  end
41
41
 
42
42
  # called when there is a mouse click
@@ -44,6 +44,11 @@ module Rubygoo
44
44
  toggle
45
45
  end
46
46
 
47
+ # called when there is a mouse click at the end of a drag
48
+ def mouse_drag(event)
49
+ toggle
50
+ end
51
+
47
52
  # called when a key press is sent to us
48
53
  def key_pressed(event)
49
54
  case event.data[:key]
@@ -52,23 +57,28 @@ module Rubygoo
52
57
  end
53
58
  end
54
59
 
55
- def draw(screen)
60
+ def draw(adapter)
61
+ x1 = @rect[0]
62
+ y1 = @rect[1]
63
+ x2 = @rect[2] + x1
64
+ y2 = @rect[3] + y1
56
65
  if @focussed
57
- screen.fill @focus_color, @rect
66
+ adapter.fill x1, y1, x2, y2, @focus_color
58
67
  elsif @bg_color
59
- screen.fill @bg_color, @rect
68
+ adapter.fill x1, y1, x2, y2, @bg_color
60
69
  end
61
70
 
62
71
  if @checked
63
- screen.fill @checked_color, @rect.inflate(-@x_pad,-@y_pad)
72
+ rect = @rect.inflate(-@x_pad,-@y_pad)
73
+ cx1 = rect[0]
74
+ cy1 = rect[1]
75
+ cx2 = rect[2] + x1
76
+ cy2 = rect[3] + y1
77
+ adapter.fill cx1, cy1, cx2, cy2, @checked_color
64
78
  end
65
79
 
66
80
  if @border_color
67
- x1 = @rect[0]
68
- y1 = @rect[1]
69
- x2 = @rect[2] + x1
70
- y2 = @rect[3] + y1
71
- screen.draw_box x1, y1, x2, y2, @border_color
81
+ adapter.draw_box x1, y1, x2, y2, @border_color
72
82
  end
73
83
  end
74
84
  end
@@ -1,7 +1,8 @@
1
+ require 'publisher'
1
2
  module Rubygoo
2
3
  class Container < Widget
3
-
4
- attr_accessor :widgets, :bg_color, :rect
4
+ extend Publisher
5
+ attr_accessor :widgets, :bg_color, :rect, :queued_widgets
5
6
 
6
7
  def initialize(opts={})
7
8
  super opts
@@ -14,25 +15,33 @@ module Rubygoo
14
15
 
15
16
  # called when we are added to another container
16
17
  def added()
18
+ @bg_color = theme_property :bg_color
17
19
  add *@queued_widgets
18
20
  @queued_widgets = []
19
21
  end
20
22
 
21
- def add_modal(widget)
22
- @modal_widgets << widget
23
- add widget
24
- end
25
-
26
23
  # Add widget(s) to the container.
27
24
  def add(*widgets)
28
25
  widgets.uniq.each do |w|
29
26
  unless @widgets.include? w
30
27
  if self.app
28
+ if w.relative
29
+ w.x += @x
30
+ w.y += @y
31
+ w.update_rect
32
+ end
31
33
  w.container = self
32
34
  w.parent = self
33
35
  w.app = self.app
34
- w.app.add_tabbed_widget w
36
+ if !modal? and w.tab_to? and !w.modal?
37
+ w.app.add_tabbed_widget w
38
+ end
35
39
  w.added
40
+
41
+ w.when :resized do |resized_widget|
42
+ resize resized_widget
43
+ end
44
+
36
45
  @widgets << w
37
46
  else
38
47
  @queued_widgets << w
@@ -55,19 +64,23 @@ module Rubygoo
55
64
  end
56
65
 
57
66
  # draw ourself and our children
58
- def draw(screen)
67
+ def draw(adapter)
59
68
  # any container specific code here (border_colors?)
60
69
  if @bg_color
61
70
  if app == self
62
- screen.fill @bg_color
71
+ adapter.fill_screen @bg_color
63
72
  else
64
- screen.fill @bg_color, @rect
73
+ x1 = @rect[0]
74
+ y1 = @rect[1]
75
+ x2 = @rect[2] + x1
76
+ y2 = @rect[3] + y1
77
+ adapter.fill x1, y1, x2, y2, @bg_color
65
78
  end
66
79
  end
67
80
 
68
81
  # draw kiddies
69
82
  @widgets.each do |w|
70
- w.draw screen
83
+ w.draw adapter
71
84
  end
72
85
  end
73
86
 
@@ -92,6 +105,13 @@ module Rubygoo
92
105
  end
93
106
  end
94
107
 
108
+ # called when there is a mouse release after dragging
109
+ def mouse_drag(event)
110
+ @widgets.each do |w|
111
+ w.mouse_drag event if w.contains? [event.data[:x],event.data[:y]]
112
+ end
113
+ end
114
+
95
115
  # pass on the key press to our widgets
96
116
  def key_pressed(event)
97
117
  @widgets.each do |w|
@@ -106,27 +126,6 @@ module Rubygoo
106
126
  end
107
127
  end
108
128
 
109
- # distribute our mouse events to our modals first
110
- def modal_mouse_call(meth, event)
111
- if @modal_widgets.empty?
112
- @widgets.each do |w|
113
- w.send meth, event if w.contains? [event.data[:x],event.data[:y]]
114
- end
115
- else
116
- @modal_widgets.last.send meth, event
117
- end
118
- end
119
-
120
- # distribute our keyboard events to our modals first
121
- def modal_keyboard_call(meth, event)
122
- if @modal_widgets.empty?
123
- @widgets.each do |w|
124
- w.send meth, event if w.focussed?
125
- end
126
- else
127
- @modal_widgets.last.send meth, event
128
- end
129
- end
130
129
 
131
130
  # called each update cycle with the amount of time that has passed. useful
132
131
  # for animations, etc
@@ -135,6 +134,27 @@ module Rubygoo
135
134
  w.update time
136
135
  end
137
136
  end
137
+
138
+ # does this widget want tabbed focus? Containers don't usually
139
+ def tab_to?
140
+ false
141
+ end
142
+
143
+ # called when we need to update our size
144
+ def resize(w)
145
+ # check the rects of all our children?
146
+ max_w = 1
147
+ max_h = 1
148
+ @widgets.each do |w|
149
+ w_width = w.x + w.w
150
+ w_height = w.y + w.h
151
+ max_w = w_width if w_width > max_w
152
+ max_h = w_height if w_height > max_h
153
+ end
154
+ @w = max_w - @x + 2*@x_pad
155
+ @h = max_h - @y + 2*@y_pad
156
+ update_rect
157
+ end
138
158
  end
139
159
  end
140
160
 
@@ -19,21 +19,16 @@ module Rubygoo
19
19
  @rect = Rect.new [@x-@x_pad,@y-@y_pad,@w+2*@x_pad,@h+2*@y_pad]
20
20
  end
21
21
 
22
+ def modal?()
23
+ @modal_target
24
+ end
25
+
22
26
  # show the dialog by adding it to the @modal_target and
23
27
  # intercepting all of its events
24
28
  def show()
25
29
  @modal_target.add_modal self
26
30
  end
27
31
 
28
- # def on_mouse_dragging(x,y,event); end
29
- # def on_mouse_motion(event); end
30
- # def on_mouse_drag(start_x, start_y, event); end
31
- # def on_click(event); end
32
- # def on_key_up(event); end
33
- # def draw(destination); end
34
- # def on_network(event); end
35
- # def update(time);end
36
-
37
32
  end
38
33
  end
39
34
 
data/lib/rubygoo/label.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'publisher'
1
2
  module Rubygoo
2
3
  class Label < Widget
3
4
  def initialize(text, opts={})
@@ -23,22 +24,26 @@ module Rubygoo
23
24
  @rect = Rect.new [@x,@y,@rendered_text.width+@x_pad,@rendered_text.height+@y_pad]
24
25
  end
25
26
 
26
- def draw(screen)
27
+ def draw(adapter)
28
+ x1 = @rect[0]
29
+ y1 = @rect[1]
30
+ x2 = @rect[2] + x1
31
+ y2 = @rect[3] + y1
27
32
  if @focussed
28
- screen.fill @focus_color, @rect
33
+ adapter.fill x1, y1, x2, y2, @focus_color
29
34
  elsif @bg_color
30
- screen.fill @bg_color, @rect
35
+ adapter.fill x1, y1, x2, y2, @bg_color
31
36
  end
32
37
 
33
38
  if @border_color
34
- x1 = @rect[0]
35
- y1 = @rect[1]
36
- x2 = @rect[2] + x1
37
- y2 = @rect[3] + y1
38
- screen.draw_box x1, y1, x2, y2, @border_color
39
+ adapter.draw_box x1, y1, x2, y2, @border_color
39
40
  end
40
41
 
41
- screen.draw_image @rendered_text, @x, @y, @color
42
+ adapter.draw_image @rendered_text, @x, @y, @color
43
+ end
44
+
45
+ def tab_to?()
46
+ false
42
47
  end
43
48
  end
44
49
  end
@@ -0,0 +1,29 @@
1
+ module Rubygoo
2
+ # this is basically a round checkbox
3
+ class RadioButton < CheckBox
4
+
5
+ def draw(adapter)
6
+ x1 = @rect[0]
7
+ y1 = @rect[1]
8
+ x2 = @rect[2] + x1
9
+ y2 = @rect[3] + y1
10
+
11
+ radius = (@rect[2]/2.0).ceil
12
+
13
+ if @focussed
14
+ adapter.draw_circle @rect.centerx, @rect.centery, radius, @focus_color
15
+ elsif @bg_color
16
+ adapter.draw_circle @rect.centerx, @rect.centery, radius, @bg_color
17
+ end
18
+
19
+ if @checked
20
+ adapter.draw_circle_filled @rect.centerx, @rect.centery, radius-@x_pad, @checked_color
21
+ end
22
+
23
+ if @border_color
24
+ adapter.draw_circle @rect.centerx, @rect.centery, radius, @border_color
25
+ end
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,40 @@
1
+ require 'publisher'
2
+ module Rubygoo
3
+ # contains radio buttons, allowing only one to be checked at a time
4
+ class RadioGroup < Container
5
+
6
+ def initialize(opts={})
7
+ # TODO add label, border
8
+ super opts
9
+ end
10
+
11
+ def add(*widgets)
12
+ widgets.uniq.each do |w|
13
+ if w.respond_to? :checked?
14
+ w.when :checked do |*opts|
15
+ widget = opts.first
16
+ if widget.checked?
17
+ update_group_selection widget
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ super *widgets
24
+ end
25
+
26
+ def update_group_selection(selected_widget)
27
+ @widgets.each do |w|
28
+ if w.respond_to? :checked?
29
+ if w.checked?
30
+ unless selected_widget == w
31
+ w.uncheck
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ end
40
+
@@ -0,0 +1,67 @@
1
+ module Rubygoo
2
+ # this class represents a collection of widgets that can be
3
+ # tabbed through
4
+ class TabGroup
5
+ attr_accessor :selected_index, :widgets
6
+
7
+ def initialize()
8
+ @widgets = []
9
+ @selected_index = 1
10
+ end
11
+
12
+ def add(*widgets)
13
+
14
+ widgets.uniq.each do |w|
15
+ unless @widgets.include? w
16
+ if w.tab_to?
17
+ @widgets << w
18
+ w.focus_priority = @widgets.size unless w.focus_priority
19
+ else
20
+ if w.respond_to? :widgets and w.widgets.size > 0
21
+ add *w.widgets
22
+ end
23
+ if w.respond_to? :queued_widgets and w.queued_widgets.size > 0
24
+ add *w.queued_widgets
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ @widgets.sort_by {|w| w.focus_priority}
31
+
32
+ end
33
+
34
+ def remove(*widgets)
35
+ widgets.uniq.each do |w|
36
+ @widgets.delete(w)
37
+ end
38
+ end
39
+
40
+ def next()
41
+ rotate 1
42
+ end
43
+
44
+ def previous()
45
+ rotate -1
46
+ end
47
+
48
+ def focus(w)
49
+ index = @widgets.index w
50
+ if index
51
+ @widgets[@selected_index].unfocus if @widgets[@selected_index]
52
+ @selected_index = index
53
+ @widgets[@selected_index].focus
54
+ end
55
+ end
56
+
57
+ def rotate(dir)
58
+ if @widgets.size > 0
59
+ @widgets[@selected_index].unfocus if @widgets[@selected_index]
60
+ @selected_index += dir
61
+ @selected_index %= @widgets.size
62
+ @widgets[@selected_index].focus
63
+ end
64
+ end
65
+
66
+ end
67
+ end