shoes-core 4.0.0.pre3 → 4.0.0.pre4

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/bin/shoes +1 -1
  3. data/bin/shoes-picker +5 -1
  4. data/bin/shoes-stub +1 -1
  5. data/ext/install/shoes.bat +2 -0
  6. data/lib/rubygems_plugin.rb +2 -2
  7. data/lib/shoes/app.rb +18 -19
  8. data/lib/shoes/arc.rb +8 -8
  9. data/lib/shoes/background.rb +4 -8
  10. data/lib/shoes/border.rb +4 -8
  11. data/lib/shoes/builtin_methods.rb +2 -2
  12. data/lib/shoes/button.rb +2 -9
  13. data/lib/shoes/check_button.rb +0 -12
  14. data/lib/shoes/color.rb +29 -34
  15. data/lib/shoes/common/background_element.rb +4 -0
  16. data/lib/shoes/common/fill.rb +9 -0
  17. data/lib/shoes/common/initialization.rb +59 -0
  18. data/lib/shoes/common/inspect.rb +20 -2
  19. data/lib/shoes/common/rotate.rb +10 -0
  20. data/lib/shoes/common/stroke.rb +9 -0
  21. data/lib/shoes/common/style.rb +21 -7
  22. data/lib/shoes/common/style_normalizer.rb +1 -3
  23. data/lib/shoes/common/ui_element.rb +10 -0
  24. data/lib/shoes/common/visibility.rb +4 -4
  25. data/lib/shoes/configuration.rb +4 -2
  26. data/lib/shoes/core/version.rb +1 -1
  27. data/lib/shoes/dialog.rb +2 -2
  28. data/lib/shoes/dimension.rb +78 -68
  29. data/lib/shoes/dimensions.rb +22 -10
  30. data/lib/shoes/download.rb +26 -10
  31. data/lib/shoes/dsl.rb +32 -51
  32. data/lib/shoes/gradient.rb +6 -13
  33. data/lib/shoes/image.rb +4 -9
  34. data/lib/shoes/input_box.rb +6 -9
  35. data/lib/shoes/internal_app.rb +16 -36
  36. data/lib/shoes/line.rb +29 -10
  37. data/lib/shoes/link.rb +13 -2
  38. data/lib/shoes/list_box.rb +33 -11
  39. data/lib/shoes/logger.rb +12 -13
  40. data/lib/shoes/mock/arc.rb +2 -0
  41. data/lib/shoes/mock/common_methods.rb +9 -0
  42. data/lib/shoes/mock/shape.rb +1 -1
  43. data/lib/shoes/mock/slot.rb +1 -0
  44. data/lib/shoes/oval.rb +13 -8
  45. data/lib/shoes/packager.rb +7 -1
  46. data/lib/shoes/point.rb +26 -3
  47. data/lib/shoes/progress.rb +6 -8
  48. data/lib/shoes/rect.rb +14 -10
  49. data/lib/shoes/shape.rb +28 -14
  50. data/lib/shoes/slot.rb +33 -24
  51. data/lib/shoes/slot_contents.rb +4 -4
  52. data/lib/shoes/star.rb +7 -16
  53. data/lib/shoes/text.rb +5 -3
  54. data/lib/shoes/text_block.rb +17 -16
  55. data/lib/shoes/text_block_dimensions.rb +1 -1
  56. data/lib/shoes/ui/cli.rb +12 -3
  57. data/lib/shoes/ui/picker.rb +64 -19
  58. data/lib/shoes/version.rb +1 -1
  59. data/shoes-core.gemspec +2 -2
  60. data/spec/shoes/animation_spec.rb +1 -1
  61. data/spec/shoes/app_spec.rb +4 -23
  62. data/spec/shoes/color_spec.rb +16 -1
  63. data/spec/shoes/common/style_normalizer_spec.rb +3 -3
  64. data/spec/shoes/common/style_spec.rb +42 -5
  65. data/spec/shoes/dimension_spec.rb +5 -7
  66. data/spec/shoes/dimensions_spec.rb +7 -7
  67. data/spec/shoes/download_spec.rb +49 -8
  68. data/spec/shoes/flow_spec.rb +1 -1
  69. data/spec/shoes/helpers/fake_element.rb +7 -0
  70. data/spec/shoes/helpers/sample17_helper.rb +3 -3
  71. data/spec/shoes/integration_spec.rb +1 -1
  72. data/spec/shoes/internal_app_spec.rb +8 -0
  73. data/spec/shoes/line_spec.rb +35 -3
  74. data/spec/shoes/link_spec.rb +24 -12
  75. data/spec/shoes/list_box_spec.rb +14 -2
  76. data/spec/shoes/point_spec.rb +28 -0
  77. data/spec/shoes/renamed_delegate_spec.rb +2 -2
  78. data/spec/shoes/shape_spec.rb +15 -2
  79. data/spec/shoes/shared_examples/changeable.rb +1 -1
  80. data/spec/shoes/shared_examples/common_methods.rb +1 -1
  81. data/spec/shoes/shared_examples/dsl/style.rb +1 -1
  82. data/spec/shoes/shared_examples/dsl/text_elements.rb +3 -3
  83. data/spec/shoes/shared_examples/dsl/video.rb +1 -1
  84. data/spec/shoes/shared_examples/dsl_app_context.rb +0 -1
  85. data/spec/shoes/shared_examples/parent.rb +1 -1
  86. data/spec/shoes/shared_examples/slot.rb +11 -5
  87. data/spec/shoes/shared_examples/state.rb +2 -2
  88. data/spec/shoes/shared_examples/style.rb +1 -1
  89. data/spec/shoes/spec_helper.rb +1 -1
  90. data/spec/shoes/text_block_spec.rb +20 -3
  91. data/spec/shoes/ui/picker_spec.rb +70 -0
  92. metadata +8 -2
@@ -83,13 +83,12 @@ class Shoes
83
83
  true
84
84
  end
85
85
 
86
- def fullscreen=(state)
87
- gui.fullscreen = state
88
- end
86
+ delegated_to_gui = %w(
87
+ fullscreen= fullscreen quit scroll_top= scroll_top
88
+ clipboard clipboard= gutter
89
+ )
89
90
 
90
- def fullscreen
91
- gui.fullscreen
92
- end
91
+ def_delegators :gui, *delegated_to_gui
93
92
 
94
93
  alias_method :start_as_fullscreen?, :start_as_fullscreen
95
94
 
@@ -99,35 +98,14 @@ class Shoes
99
98
  end
100
99
 
101
100
  def add_mouse_hover_control(element)
102
- unless mouse_hover_controls.include? element
103
- mouse_hover_controls << element
104
- end
101
+ return if mouse_hover_controls.include?(element)
102
+ mouse_hover_controls << element
105
103
  end
106
104
 
107
105
  def open_gui
108
106
  gui.open
109
107
  end
110
108
 
111
- def quit
112
- @gui.quit
113
- end
114
-
115
- def scroll_top
116
- gui.scroll_top
117
- end
118
-
119
- def scroll_top=(n)
120
- gui.scroll_top = n
121
- end
122
-
123
- def clipboard
124
- gui.clipboard
125
- end
126
-
127
- def clipboard=(str)
128
- gui.clipboard = str
129
- end
130
-
131
109
  def download(url, opts, &block)
132
110
  app.download url, opts, &block
133
111
  end
@@ -140,16 +118,12 @@ class Shoes
140
118
  app.instance_eval(&blk)
141
119
  end
142
120
 
143
- def gutter
144
- gui.gutter
145
- end
146
-
147
121
  def add_resize_callback(blk)
148
122
  @resize_callbacks << blk
149
123
  end
150
124
 
151
- def inspect
152
- super.insert(-2, " \"#{@app_title}\" #{@dimensions.inspect})")
125
+ def inspect_details
126
+ "\"#{@app_title}\" #{@dimensions.inspect}"
153
127
  end
154
128
 
155
129
  def self.global_keypresses
@@ -217,7 +191,7 @@ class Shoes
217
191
  def setup_global_keypresses
218
192
  @app.keypress do |key|
219
193
  blk = self.class.global_keypresses[key]
220
- @app.instance_eval(&blk) unless blk.nil?
194
+ execute_block(blk) if blk
221
195
  end
222
196
  end
223
197
 
@@ -226,5 +200,11 @@ class Shoes
226
200
  Logger.setup
227
201
  end
228
202
  end
203
+
204
+ def update_fill
205
+ end
206
+
207
+ def update_stroke
208
+ end
229
209
  end
230
210
  end
data/lib/shoes/line.rb CHANGED
@@ -1,26 +1,45 @@
1
+ require 'matrix'
2
+
1
3
  class Shoes
2
4
  class Line
3
5
  include Common::UIElement
6
+ include Common::Stroke
4
7
  include Common::Style
5
8
  include Common::Clickable
6
9
 
7
- attr_reader :app, :parent, :dimensions, :gui, :point_a, :point_b
10
+ attr_reader :point_a, :point_b
8
11
 
9
12
  style_with :angle, :art_styles, :dimensions, :x2, :y2
10
- STYLES = { angle: 0 }
13
+ STYLES = { angle: 0, fill: Shoes::COLORS[:black] }
11
14
 
12
- def initialize(app, parent, point_a, point_b, styles = {}, blk = nil)
13
- @app = app
14
- @parent = parent
15
+ def create_dimensions(point_a, point_b)
15
16
  @point_a = point_a
16
17
  @point_b = point_b
17
18
 
18
- style_init styles, x2: point_b.x, y2: point_b.y
19
19
  enclosing_box_of_line
20
20
 
21
- @parent.add_child self
22
- @gui = Shoes.backend_for self
23
- register_click blk
21
+ style[:x2] = point_b.x
22
+ style[:y2] = point_b.y
23
+ end
24
+
25
+ # Check out http://math.stackexchange.com/questions/60070/checking-whether-a-point-lies-on-a-wide-line-segment
26
+ # for explanations how the algorithm works
27
+ def in_bounds?(x, y)
28
+ # c is (x, y)
29
+ left_most, right_most = point_a.x < point_b.x ? [point_a, point_b] : [point_b, point_a]
30
+ left_c = Vector.elements((left_most - [x, y]).to_a, false)
31
+ left_right = Vector.elements((left_most - right_most).to_a, false)
32
+
33
+ boldness = style[:strokewidth].to_i / 2
34
+ left_c_dot_left_right = left_c.inner_product(left_right)
35
+ left_right_dot_left_right = left_right.inner_product(left_right)
36
+
37
+ if left_c_dot_left_right.between?(0, left_right_dot_left_right)
38
+ left_c_dot_left_c = left_c.inner_product(left_c)
39
+ left_right_dot_left_right * left_c_dot_left_c <= boldness ** 2 * left_right_dot_left_right + left_c_dot_left_right ** 2
40
+ else
41
+ false
42
+ end
24
43
  end
25
44
 
26
45
  def update_style(new_styles)
@@ -47,7 +66,7 @@ class Shoes
47
66
  alias_method :x2=, :right=
48
67
  alias_method :y2=, :bottom=
49
68
 
50
- def move(x, y, x2=nil, y2=nil)
69
+ def move(x, y, x2 = nil, y2 = nil)
51
70
  @point_a.x = x
52
71
  @point_a.y = y
53
72
  @point_b.x = x2 if x2
data/lib/shoes/link.rb CHANGED
@@ -47,11 +47,22 @@ class Shoes
47
47
  end
48
48
 
49
49
  def hidden?
50
- @text_block.hidden?
50
+ text_block_guard && @text_block.hidden?
51
51
  end
52
52
 
53
53
  def visible?
54
- @text_block.visible?
54
+ text_block_guard && @text_block.visible?
55
+ end
56
+
57
+ private
58
+
59
+ def text_block_guard
60
+ if @text_block
61
+ true
62
+ else
63
+ @app.warn 'Stray link without TextBlock detected! Links have to be part of a text block like a para or title'
64
+ false
65
+ end
55
66
  end
56
67
  end
57
68
  end
@@ -1,27 +1,49 @@
1
1
  class Shoes
2
+ class ProxyArray < SimpleDelegator
3
+ attr_accessor :gui
4
+
5
+ def initialize(array, gui)
6
+ @gui = gui
7
+ super(array)
8
+ end
9
+
10
+ def method_missing(method, *args, &block)
11
+ res = super(method, *args, &block)
12
+ gui.update_items
13
+
14
+ case res
15
+ when ProxyArray, Array
16
+ self
17
+ else
18
+ res
19
+ end
20
+ end
21
+
22
+ def to_a
23
+ __getobj__
24
+ end
25
+ end
26
+
2
27
  class ListBox
3
28
  include Common::UIElement
4
29
  include Common::Style
5
30
  include Common::Changeable
6
31
 
7
- attr_reader :app, :parent, :dimensions, :gui
8
32
  style_with :change, :choose, :common_styles, :dimensions, :items, :state, :text
9
33
  STYLES = { width: 200, height: 20, items: [""] }
10
34
 
11
- def initialize(app, parent, styles = {}, blk = nil)
12
- @app = app
13
- @parent = parent
14
- style_init styles
15
- @dimensions = Dimensions.new parent, @style
16
- @parent.add_child self
17
- @gui = Shoes.configuration.backend_for self, @parent.gui
35
+ def handle_block(blk)
18
36
  change(&blk) if blk
37
+ end
19
38
 
20
- choose @style[:choose]
39
+ def after_initialize
40
+ proxy_array = Shoes::ProxyArray.new(items, @gui)
41
+ @style[:items] = proxy_array
21
42
  end
22
43
 
23
- def items=(values)
24
- style(items: values)
44
+ def items=(vanilla_array)
45
+ proxy_array = Shoes::ProxyArray.new(vanilla_array, @gui)
46
+ style(items: proxy_array)
25
47
  @gui.update_items
26
48
  end
27
49
 
data/lib/shoes/logger.rb CHANGED
@@ -18,19 +18,18 @@ class Shoes
18
18
  def self.setup
19
19
  Shoes.app do
20
20
  def update
21
- if @hash != Shoes::LOG.hash
22
- @hash = Shoes::LOG.hash
23
- @log.clear do
24
- Shoes::LOG.each_with_index do |(typ, msg), index|
25
- stack do
26
- background "#f1f5e1" if index % 2 == 0
27
- background rgb(220, 220, 220) if index % 2 != 0
28
- para typ, stroke: blue
29
- flow do
30
- stack margin: 4 do
31
- s = msg.to_s
32
- para s, margin: 4, margin_top: 0
33
- end
21
+ return unless @hash == Shoes::LOG.hash
22
+ @hash = Shoes::LOG.hash
23
+ @log.clear do
24
+ Shoes::LOG.each_with_index do |(typ, msg), index|
25
+ stack do
26
+ background "#f1f5e1" if index.even?
27
+ background rgb(220, 220, 220) if index.odd?
28
+ para typ, stroke: blue
29
+ flow do
30
+ stack margin: 4 do
31
+ s = msg.to_s
32
+ para s, margin: 4, margin_top: 0
34
33
  end
35
34
  end
36
35
  end
@@ -1,7 +1,9 @@
1
1
  class Shoes
2
2
  module Mock
3
3
  class Arc
4
+ include Shoes::Mock::CommonMethods
4
5
  include Shoes::Mock::Clickable
6
+
5
7
  def initialize(_dsl, _app, _opts = {})
6
8
  end
7
9
  end
@@ -7,6 +7,15 @@ class Shoes
7
7
 
8
8
  def update_position
9
9
  end
10
+
11
+ def update_visibility
12
+ end
13
+
14
+ def update_fill
15
+ end
16
+
17
+ def update_stroke
18
+ end
10
19
  end
11
20
  end
12
21
  end
@@ -13,7 +13,7 @@ class Shoes
13
13
  def curve_to(*_args)
14
14
  end
15
15
 
16
- def arc(*_args)
16
+ def arc_to(*_args)
17
17
  end
18
18
  end
19
19
  end
@@ -1,6 +1,7 @@
1
1
  class Shoes
2
2
  module Mock
3
3
  class Slot
4
+ include Shoes::Mock::CommonMethods
4
5
  include Shoes::Mock::Clickable
5
6
 
6
7
  def initialize(dsl, parent)
data/lib/shoes/oval.rb CHANGED
@@ -1,20 +1,25 @@
1
1
  class Shoes
2
2
  class Oval
3
3
  include Common::UIElement
4
+ include Common::Fill
5
+ include Common::Stroke
4
6
  include Common::Style
5
7
  include Common::Clickable
6
8
 
7
- attr_reader :app, :parent, :dimensions, :gui
8
9
  style_with :art_styles, :center, :common_styles, :dimensions, :radius
10
+ STYLES = { fill: Shoes::COLORS[:black] }
11
+
12
+ def create_dimensions(left, top, width, height)
13
+ left ||= @style[:left]
14
+ top ||= @style[:top]
15
+ width ||= @style[:diameter] || @style[:width] || (@style[:radius] || 0) * 2
16
+ height ||= @style[:height] || width
9
17
 
10
- def initialize(app, parent, left, top, width, height, styles = {}, blk = nil)
11
- @app = app
12
- @parent = parent
13
- style_init styles
14
18
  @dimensions = AbsoluteDimensions.new left, top, width, height, @style
15
- @parent.add_child self
16
- @gui = Shoes.backend_for self
17
- register_click blk
19
+ end
20
+
21
+ def needs_rotate?
22
+ rotate != 0
18
23
  end
19
24
  end
20
25
  end
@@ -3,7 +3,11 @@ class Shoes
3
3
  attr_reader :packages, :backend
4
4
 
5
5
  def initialize
6
- @backend = Shoes.configuration.backend_for(self)
6
+ begin
7
+ @backend = Shoes.configuration.backend_for(self)
8
+ rescue ArgumentError
9
+ # Packaging unsupported by this backend
10
+ end
7
11
  @packages = []
8
12
  end
9
13
 
@@ -16,10 +20,12 @@ class Shoes
16
20
  end
17
21
 
18
22
  def run(path)
23
+ raise "Packaging unsupported by this backend" if @backend.nil?
19
24
  @backend.run(path)
20
25
  end
21
26
 
22
27
  def help(program_name)
28
+ return "" if @backend.nil?
23
29
  @backend.help(program_name)
24
30
  end
25
31
  end
data/lib/shoes/point.rb CHANGED
@@ -4,6 +4,7 @@ class Shoes
4
4
 
5
5
  def initialize(x, y)
6
6
  @x, @y = x, y
7
+ @dimensions = 2
7
8
  end
8
9
 
9
10
  attr_accessor :x, :y
@@ -30,6 +31,18 @@ class Shoes
30
31
  Shoes::Point.new(@x + x, @y + y)
31
32
  end
32
33
 
34
+ def +(other)
35
+ other = other.to_a
36
+ assert_dimensions_match(other.length)
37
+ Shoes::Point.new(x + other[0], y + other[1])
38
+ end
39
+
40
+ def -(other)
41
+ other = other.to_a
42
+ assert_dimensions_match(other.length)
43
+ Shoes::Point.new(x - other[0], y - other[1])
44
+ end
45
+
33
46
  def width(other = self)
34
47
  (@x - other.x).abs
35
48
  end
@@ -39,7 +52,7 @@ class Shoes
39
52
  end
40
53
 
41
54
  def ==(other)
42
- other.respond_to?(:x) && @x == other.x && other.respond_to?(:y) && @y == other.y
55
+ other.respond_to?(:x, :y) && [x, y] == [other.x, other.y]
43
56
  end
44
57
 
45
58
  def to_s
@@ -47,8 +60,18 @@ class Shoes
47
60
  "(#{@x || nothing},#{@y || nothing})"
48
61
  end
49
62
 
50
- def inspect
51
- super.insert(-2, " #{self}")
63
+ def to_a
64
+ [x, y]
65
+ end
66
+
67
+ private
68
+
69
+ def inspect_details
70
+ " #{self}"
71
+ end
72
+
73
+ def assert_dimensions_match(other_dimension)
74
+ raise ArgumentError, "Dimensions mismatch: expected #{@dimensions}D point, given #{other_dimension}D point" if @dimensions != other_dimension
52
75
  end
53
76
  end
54
77
  end
@@ -3,18 +3,16 @@ class Shoes
3
3
  include Common::UIElement
4
4
  include Common::Style
5
5
 
6
- attr_reader :app, :parent, :dimensions, :gui
7
6
  style_with :common_styles, :dimensions, :fraction
8
7
  STYLES = { fraction: 0.0 }
9
8
 
10
- def initialize(app, parent, styles = {}, _blk = nil)
11
- @app = app
12
- @parent = parent
13
- style_init styles
14
- @dimensions = Dimensions.new parent, @style
15
- @parent.add_child self
16
- @gui = Shoes.configuration.backend_for self, @parent.gui
9
+ def after_initialize(*_)
17
10
  @gui.fraction = @style[:fraction]
11
+ update_visibility
12
+ end
13
+
14
+ def handle_block(*_)
15
+ # No-op since we're not clickable
18
16
  end
19
17
 
20
18
  def fraction=(value)
data/lib/shoes/rect.rb CHANGED
@@ -1,21 +1,25 @@
1
1
  class Shoes
2
2
  class Rect
3
3
  include Common::UIElement
4
- include Common::Style
4
+ include Common::Fill
5
+ include Common::Stroke
5
6
  include Common::Clickable
7
+ include Common::Style
6
8
 
7
- attr_reader :app, :parent, :dimensions, :gui
8
9
  style_with :angle, :art_styles, :curve, :common_styles, :dimensions
9
- STYLES = { angle: 0 }
10
+ STYLES = { angle: 0, curve: 0, fill: Shoes::COLORS[:black] }
11
+
12
+ def create_dimensions(left, top, width, height)
13
+ left ||= @style[:left] || 0
14
+ top ||= @style[:top] || 0
15
+ width ||= @style[:width] || 0
16
+ height ||= @style[:height] || width
10
17
 
11
- def initialize(app, parent, left, top, width, height, styles = {}, blk = nil)
12
- @app = app
13
- @parent = parent
14
- style_init styles
15
18
  @dimensions = AbsoluteDimensions.new left, top, width, height, @style
16
- @parent.add_child self
17
- @gui = Shoes.backend_for self
18
- register_click blk
19
+ end
20
+
21
+ def needs_rotate?
22
+ rotate != 0
19
23
  end
20
24
  end
21
25
  end
data/lib/shoes/shape.rb CHANGED
@@ -1,28 +1,34 @@
1
1
  class Shoes
2
2
  class Shape
3
3
  include Common::UIElement
4
+ include Common::Fill
5
+ include Common::Stroke
4
6
  include Common::Style
5
7
  include Common::Clickable
6
8
 
7
- attr_reader :app, :parent, :dimensions, :gui, :blk, :x, :y
8
- attr_reader :left_bound, :top_bound, :right_bound, :bottom_bound
9
+ attr_reader :blk, :x, :y, :left_bound, :top_bound, :right_bound, :bottom_bound
10
+
9
11
  style_with :art_styles, :center, :common_styles, :dimensions
10
12
 
11
- # Creates a new Shoes::Shape
12
- #
13
- def initialize(app, parent, styles = {}, blk = nil)
14
- @app = app
15
- @parent = parent
16
- style_init styles
13
+ STYLES = { fill: Shoes::COLORS[:black] }
14
+
15
+ def create_dimensions()
17
16
  @dimensions = AbsoluteDimensions.new @style
18
- @parent.add_child self
19
- @gui = Shoes.backend_for self
17
+ end
18
+
19
+ def handle_block(blk)
20
+ # Will register click from styles if present, but blk is for drawing!
20
21
  register_click
21
22
 
22
23
  @blk = blk
23
- # True until we've asked the pen to draw
24
+ end
25
+
26
+ def after_initialize(*_)
24
27
  @before_drawing = true
25
- @app.eval_with_additional_context self, &blk
28
+ @app.eval_with_additional_context self, &@blk
29
+
30
+ # If we haven't drawn enough to get our bounds, default them out
31
+ update_bounds([0], [0]) if @left_bound.nil?
26
32
  end
27
33
 
28
34
  def width
@@ -93,13 +99,21 @@ class Shoes
93
99
  # @param [Integer] start_angle The start angle
94
100
  # @param [Integer] arc_angle The angular extent of the arc, relative to the start angle
95
101
  # @return [Shoes::Shape] This shape
96
- def arc(x, y, width, height, start_angle, arc_angle)
102
+ def arc_to(x, y, width, height, start_angle, arc_angle)
97
103
  update_bounds_rect(x - width / 2, y - height / 2, x + width / 2, y + height / 2)
98
104
  @x, @y = x, y
99
- @gui.arc(x, y, width, height, start_angle, arc_angle)
105
+ @gui.arc_to(x, y, width, height, start_angle, arc_angle)
100
106
  self
101
107
  end
102
108
 
109
+ # Determines if a given point is in the boundary of the shape. Given the
110
+ # many possibilities of what a shape could contain, this just checks the
111
+ # outer bounding box of the shape, nothing more sophisticated.
112
+ def in_bounds?(x, y)
113
+ (@left_bound..@right_bound).include?(x) &&
114
+ (@top_bound..@bottom_bound).include?(y)
115
+ end
116
+
103
117
  private
104
118
 
105
119
  # Updates the bounds of this shape to include the rectangle described by
data/lib/shoes/slot.rb CHANGED
@@ -10,30 +10,32 @@ class Shoes
10
10
  NEXT_ELEMENT_OFFSET = 1
11
11
 
12
12
  attr_reader :parent, :dimensions, :gui, :contents, :blk, :hover_proc, :leave_proc
13
+
13
14
  style_with :art_styles, :attach, :common_styles, :dimensions, :scroll
14
- STYLES = { scroll: false }
15
+ STYLES = { scroll: false, fill: Shoes::COLORS[:black] }
15
16
 
16
- def initialize(app, parent, styles = {}, blk = nil)
17
- init_attributes(app, parent, styles, blk)
18
- @parent.add_child self
19
- @gui = Shoes.configuration.backend_for self, @parent.gui
20
- eval_block blk
21
- contents_alignment
22
- end
17
+ def create_dimensions(*args)
18
+ super(*args)
23
19
 
24
- def init_attributes(app, parent, styles, blk)
25
- @app = app
26
- @parent = parent
27
- @contents = SlotContents.new
28
- @blk = blk
29
- style_init styles
30
- @dimensions = Dimensions.new parent, @style
31
- @fixed_height = height || false
32
- @scroll_top = 0
20
+ @fixed_height = height || false
21
+ @scroll_top = 0
33
22
  set_default_dimension_values
34
23
  @pass_coordinates = true
35
24
  end
36
25
 
26
+ def before_initialize(*_)
27
+ @contents = SlotContents.new
28
+ end
29
+
30
+ def handle_block(blk)
31
+ @blk = blk
32
+ eval_block blk
33
+ end
34
+
35
+ def after_initialize(*_)
36
+ contents_alignment
37
+ end
38
+
37
39
  def set_default_dimension_values
38
40
  self.width ||= 1.0
39
41
  self.height ||= 0
@@ -54,7 +56,7 @@ class Shoes
54
56
  end
55
57
 
56
58
  def create_bound_block(blk)
57
- Proc.new do |*args|
59
+ proc do |*args|
58
60
  eval_block(blk, *args)
59
61
  end
60
62
  end
@@ -150,6 +152,13 @@ class Shoes
150
152
  else
151
153
  current_position
152
154
  end
155
+ rescue => e
156
+ puts "SWALLOWED POSITIONING EXCEPTION ON #{element} - go take care of it: " + e.to_s
157
+ puts e.backtrace.join("\n\t")
158
+ puts 'Unfortunately we have to swallow it or risk SWT hanging.'
159
+ puts "It doesn't like exceptions during layout. :O"
160
+
161
+ current_position
153
162
  end
154
163
 
155
164
  def position_element(_element, _current_position)
@@ -203,9 +212,9 @@ class Shoes
203
212
 
204
213
  def absolute_x_position(element)
205
214
  if element.absolute_left_position?
206
- self.element_left + element.left
215
+ element_left + element.left
207
216
  elsif element.absolute_right_position?
208
- self.element_right - (element.right + element.width)
217
+ element_right - (element.right + element.width)
209
218
  end
210
219
  end
211
220
 
@@ -219,11 +228,11 @@ class Shoes
219
228
 
220
229
  def absolute_y_position(element)
221
230
  if element.absolute_top_position?
222
- self.element_top + element.top
231
+ element_top + element.top
223
232
  elsif element.absolute_bottom_position?
224
233
  # TODO: slots grow... to really position it relative to the bottom
225
234
  # we probably need to position it after everything has been positioned
226
- self.element_bottom - (element.bottom + element.height)
235
+ element_bottom - (element.bottom + element.height)
227
236
  end
228
237
  end
229
238
 
@@ -235,7 +244,7 @@ class Shoes
235
244
 
236
245
  def determine_slot_height
237
246
  content_height = compute_content_height
238
- self.height = content_height if has_variable_height?
247
+ self.height = content_height if variable_height?
239
248
  content_height
240
249
  end
241
250
 
@@ -253,7 +262,7 @@ class Shoes
253
262
  end
254
263
  end
255
264
 
256
- def has_variable_height?
265
+ def variable_height?
257
266
  !@fixed_height
258
267
  end
259
268
  end