shoes-swt 4.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (238) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +84 -0
  3. data/Gemfile +24 -0
  4. data/Guardfile +11 -0
  5. data/LICENSE +31 -0
  6. data/README.md +201 -0
  7. data/lib/shoes/swt.rb +118 -0
  8. data/lib/shoes/swt/animation.rb +46 -0
  9. data/lib/shoes/swt/app.rb +314 -0
  10. data/lib/shoes/swt/arc.rb +71 -0
  11. data/lib/shoes/swt/background.rb +41 -0
  12. data/lib/shoes/swt/border.rb +41 -0
  13. data/lib/shoes/swt/button.rb +18 -0
  14. data/lib/shoes/swt/check.rb +14 -0
  15. data/lib/shoes/swt/check_button.rb +19 -0
  16. data/lib/shoes/swt/color.rb +49 -0
  17. data/lib/shoes/swt/color_factory.rb +32 -0
  18. data/lib/shoes/swt/common/child.rb +16 -0
  19. data/lib/shoes/swt/common/clickable.rb +68 -0
  20. data/lib/shoes/swt/common/container.rb +28 -0
  21. data/lib/shoes/swt/common/fill.rb +38 -0
  22. data/lib/shoes/swt/common/painter.rb +92 -0
  23. data/lib/shoes/swt/common/painter_updates_position.rb +12 -0
  24. data/lib/shoes/swt/common/remove.rb +30 -0
  25. data/lib/shoes/swt/common/resource.rb +29 -0
  26. data/lib/shoes/swt/common/selection_listener.rb +14 -0
  27. data/lib/shoes/swt/common/stroke.rb +42 -0
  28. data/lib/shoes/swt/common/update_position.rb +15 -0
  29. data/lib/shoes/swt/common/visibility.rb +13 -0
  30. data/lib/shoes/swt/dialog.rb +90 -0
  31. data/lib/shoes/swt/disposed_protection.rb +23 -0
  32. data/lib/shoes/swt/download.rb +24 -0
  33. data/lib/shoes/swt/font.rb +32 -0
  34. data/lib/shoes/swt/gradient.rb +92 -0
  35. data/lib/shoes/swt/image.rb +128 -0
  36. data/lib/shoes/swt/image_pattern.rb +31 -0
  37. data/lib/shoes/swt/input_box.rb +73 -0
  38. data/lib/shoes/swt/key_listener.rb +145 -0
  39. data/lib/shoes/swt/line.rb +60 -0
  40. data/lib/shoes/swt/link.rb +31 -0
  41. data/lib/shoes/swt/link_segment.rb +111 -0
  42. data/lib/shoes/swt/list_box.rb +48 -0
  43. data/lib/shoes/swt/mouse_move_listener.rb +67 -0
  44. data/lib/shoes/swt/oval.rb +52 -0
  45. data/lib/shoes/swt/progress.rb +35 -0
  46. data/lib/shoes/swt/radio.rb +29 -0
  47. data/lib/shoes/swt/radio_group.rb +54 -0
  48. data/lib/shoes/swt/rect.rb +30 -0
  49. data/lib/shoes/swt/rect_painter.rb +23 -0
  50. data/lib/shoes/swt/redrawing_aspect.rb +123 -0
  51. data/lib/shoes/swt/shape.rb +133 -0
  52. data/lib/shoes/swt/shoes_layout.rb +43 -0
  53. data/lib/shoes/swt/slot.rb +39 -0
  54. data/lib/shoes/swt/sound.rb +119 -0
  55. data/lib/shoes/swt/star.rb +50 -0
  56. data/lib/shoes/swt/support/jl1.0.1.jar +0 -0
  57. data/lib/shoes/swt/support/jogg-0.0.7.jar +0 -0
  58. data/lib/shoes/swt/support/jorbis-0.0.15.jar +0 -0
  59. data/lib/shoes/swt/support/log4j-1.2.16.jar +0 -0
  60. data/lib/shoes/swt/support/mp3spi1.9.5.jar +0 -0
  61. data/lib/shoes/swt/support/tritonus_share.jar +0 -0
  62. data/lib/shoes/swt/support/vorbisspi1.0.3.jar +0 -0
  63. data/lib/shoes/swt/swt_button.rb +56 -0
  64. data/lib/shoes/swt/text_block.rb +124 -0
  65. data/lib/shoes/swt/text_block/centered_text_segment.rb +22 -0
  66. data/lib/shoes/swt/text_block/cursor_painter.rb +53 -0
  67. data/lib/shoes/swt/text_block/fitter.rb +212 -0
  68. data/lib/shoes/swt/text_block/painter.rb +47 -0
  69. data/lib/shoes/swt/text_block/text_font_factory.rb +50 -0
  70. data/lib/shoes/swt/text_block/text_segment.rb +108 -0
  71. data/lib/shoes/swt/text_block/text_segment_collection.rb +160 -0
  72. data/lib/shoes/swt/text_block/text_style_factory.rb +88 -0
  73. data/lib/shoes/swt/timer.rb +19 -0
  74. data/lib/shoes/swt/tooling/leak_hunter.rb +35 -0
  75. data/lib/shoes/swt/version.rb +5 -0
  76. data/manifests/common.rb +34 -0
  77. data/manifests/shoes-swt.rb +29 -0
  78. data/shoes-swt.gemspec +24 -0
  79. data/spec/code_coverage.rb +14 -0
  80. data/spec/shoes/animation_spec.rb +65 -0
  81. data/spec/shoes/app_spec.rb +484 -0
  82. data/spec/shoes/arc_spec.rb +51 -0
  83. data/spec/shoes/background_spec.rb +53 -0
  84. data/spec/shoes/border_spec.rb +47 -0
  85. data/spec/shoes/builtin_methods_spec.rb +110 -0
  86. data/spec/shoes/button_spec.rb +44 -0
  87. data/spec/shoes/check_spec.rb +35 -0
  88. data/spec/shoes/cli_spec.rb +15 -0
  89. data/spec/shoes/color_spec.rb +408 -0
  90. data/spec/shoes/common/inspect_spec.rb +26 -0
  91. data/spec/shoes/common/remove_spec.rb +38 -0
  92. data/spec/shoes/common/style_normalizer_spec.rb +28 -0
  93. data/spec/shoes/common/style_spec.rb +147 -0
  94. data/spec/shoes/configuration_spec.rb +36 -0
  95. data/spec/shoes/constants_spec.rb +38 -0
  96. data/spec/shoes/dialog_spec.rb +163 -0
  97. data/spec/shoes/dimension_spec.rb +407 -0
  98. data/spec/shoes/dimensions_spec.rb +837 -0
  99. data/spec/shoes/download_spec.rb +142 -0
  100. data/spec/shoes/flow_spec.rb +133 -0
  101. data/spec/shoes/font_spec.rb +37 -0
  102. data/spec/shoes/framework_learning_spec.rb +30 -0
  103. data/spec/shoes/gradient_spec.rb +32 -0
  104. data/spec/shoes/helpers/fake_element.rb +17 -0
  105. data/spec/shoes/helpers/inspect_helpers.rb +5 -0
  106. data/spec/shoes/helpers/sample17_helper.rb +66 -0
  107. data/spec/shoes/image_spec.rb +49 -0
  108. data/spec/shoes/images/shoe.jpg +0 -0
  109. data/spec/shoes/input_box_spec.rb +80 -0
  110. data/spec/shoes/integration_spec.rb +20 -0
  111. data/spec/shoes/internal_app_spec.rb +141 -0
  112. data/spec/shoes/keypress_spec.rb +11 -0
  113. data/spec/shoes/keyrelease_spec.rb +12 -0
  114. data/spec/shoes/line_spec.rb +49 -0
  115. data/spec/shoes/link_spec.rb +105 -0
  116. data/spec/shoes/list_box_spec.rb +74 -0
  117. data/spec/shoes/logger/ruby_spec.rb +8 -0
  118. data/spec/shoes/logger_spec.rb +45 -0
  119. data/spec/shoes/oval_spec.rb +24 -0
  120. data/spec/shoes/point_spec.rb +71 -0
  121. data/spec/shoes/progress_spec.rb +54 -0
  122. data/spec/shoes/radio_spec.rb +32 -0
  123. data/spec/shoes/rect_spec.rb +39 -0
  124. data/spec/shoes/renamed_delegate_spec.rb +70 -0
  125. data/spec/shoes/shape_spec.rb +95 -0
  126. data/spec/shoes/shared_examples/button.rb +6 -0
  127. data/spec/shoes/shared_examples/changeable.rb +26 -0
  128. data/spec/shoes/shared_examples/clickable.rb +5 -0
  129. data/spec/shoes/shared_examples/common_methods.rb +35 -0
  130. data/spec/shoes/shared_examples/dimensions.rb +32 -0
  131. data/spec/shoes/shared_examples/dsl.rb +44 -0
  132. data/spec/shoes/shared_examples/dsl/animate.rb +29 -0
  133. data/spec/shoes/shared_examples/dsl/arc.rb +45 -0
  134. data/spec/shoes/shared_examples/dsl/background.rb +26 -0
  135. data/spec/shoes/shared_examples/dsl/border.rb +10 -0
  136. data/spec/shoes/shared_examples/dsl/button.rb +5 -0
  137. data/spec/shoes/shared_examples/dsl/cap.rb +6 -0
  138. data/spec/shoes/shared_examples/dsl/check.rb +11 -0
  139. data/spec/shoes/shared_examples/dsl/edit_box.rb +8 -0
  140. data/spec/shoes/shared_examples/dsl/edit_line.rb +8 -0
  141. data/spec/shoes/shared_examples/dsl/editable_element.rb +29 -0
  142. data/spec/shoes/shared_examples/dsl/fill.rb +27 -0
  143. data/spec/shoes/shared_examples/dsl/flow.rb +15 -0
  144. data/spec/shoes/shared_examples/dsl/gradient.rb +62 -0
  145. data/spec/shoes/shared_examples/dsl/image.rb +21 -0
  146. data/spec/shoes/shared_examples/dsl/line.rb +9 -0
  147. data/spec/shoes/shared_examples/dsl/nofill.rb +6 -0
  148. data/spec/shoes/shared_examples/dsl/nostroke.rb +6 -0
  149. data/spec/shoes/shared_examples/dsl/oval.rb +88 -0
  150. data/spec/shoes/shared_examples/dsl/pattern.rb +34 -0
  151. data/spec/shoes/shared_examples/dsl/progress.rb +7 -0
  152. data/spec/shoes/shared_examples/dsl/rect.rb +92 -0
  153. data/spec/shoes/shared_examples/dsl/rgb.rb +26 -0
  154. data/spec/shoes/shared_examples/dsl/shape.rb +21 -0
  155. data/spec/shoes/shared_examples/dsl/star.rb +48 -0
  156. data/spec/shoes/shared_examples/dsl/stroke.rb +30 -0
  157. data/spec/shoes/shared_examples/dsl/strokewidth.rb +19 -0
  158. data/spec/shoes/shared_examples/dsl/style.rb +32 -0
  159. data/spec/shoes/shared_examples/dsl/text_elements.rb +81 -0
  160. data/spec/shoes/shared_examples/dsl/video.rb +5 -0
  161. data/spec/shoes/shared_examples/dsl_app_context.rb +8 -0
  162. data/spec/shoes/shared_examples/hover_leave.rb +11 -0
  163. data/spec/shoes/shared_examples/parent.rb +6 -0
  164. data/spec/shoes/shared_examples/scroll.rb +41 -0
  165. data/spec/shoes/shared_examples/shared_element_method.rb +60 -0
  166. data/spec/shoes/shared_examples/slot.rb +331 -0
  167. data/spec/shoes/shared_examples/state.rb +19 -0
  168. data/spec/shoes/shared_examples/style.rb +82 -0
  169. data/spec/shoes/slot_spec.rb +130 -0
  170. data/spec/shoes/sound_spec.rb +15 -0
  171. data/spec/shoes/span_spec.rb +112 -0
  172. data/spec/shoes/spec_helper.rb +24 -0
  173. data/spec/shoes/stack_spec.rb +79 -0
  174. data/spec/shoes/star_spec.rb +31 -0
  175. data/spec/shoes/text_block_dimensions_spec.rb +75 -0
  176. data/spec/shoes/text_block_spec.rb +270 -0
  177. data/spec/shoes/url_spec.rb +68 -0
  178. data/spec/shoes/widget_spec.rb +70 -0
  179. data/spec/shoes_spec.rb +44 -0
  180. data/spec/spec_helper.rb +18 -0
  181. data/spec/swt_shoes/animation_spec.rb +86 -0
  182. data/spec/swt_shoes/app_spec.rb +84 -0
  183. data/spec/swt_shoes/arc_spec.rb +103 -0
  184. data/spec/swt_shoes/background_spec.rb +67 -0
  185. data/spec/swt_shoes/border_spec.rb +52 -0
  186. data/spec/swt_shoes/button_spec.rb +101 -0
  187. data/spec/swt_shoes/check_spec.rb +28 -0
  188. data/spec/swt_shoes/color_factory_spec.rb +49 -0
  189. data/spec/swt_shoes/color_spec.rb +67 -0
  190. data/spec/swt_shoes/common/painter_spec.rb +49 -0
  191. data/spec/swt_shoes/common/remove_spec.rb +53 -0
  192. data/spec/swt_shoes/configuration_spec.rb +12 -0
  193. data/spec/swt_shoes/dialog_spec.rb +106 -0
  194. data/spec/swt_shoes/disposed_protection_spec.rb +49 -0
  195. data/spec/swt_shoes/flow_spec.rb +36 -0
  196. data/spec/swt_shoes/font_spec.rb +33 -0
  197. data/spec/swt_shoes/gradient_spec.rb +31 -0
  198. data/spec/swt_shoes/image_pattern_spec.rb +35 -0
  199. data/spec/swt_shoes/image_spec.rb +100 -0
  200. data/spec/swt_shoes/input_box_spec.rb +116 -0
  201. data/spec/swt_shoes/integration_spec.rb +27 -0
  202. data/spec/swt_shoes/key_listener_spec.rb +325 -0
  203. data/spec/swt_shoes/line_spec.rb +49 -0
  204. data/spec/swt_shoes/link_segment_spec.rb +120 -0
  205. data/spec/swt_shoes/link_spec.rb +54 -0
  206. data/spec/swt_shoes/list_box_spec.rb +56 -0
  207. data/spec/swt_shoes/minimal.png +0 -0
  208. data/spec/swt_shoes/mouse_move_listener_spec.rb +123 -0
  209. data/spec/swt_shoes/oval_spec.rb +51 -0
  210. data/spec/swt_shoes/progress_spec.rb +44 -0
  211. data/spec/swt_shoes/radio_group_spec.rb +73 -0
  212. data/spec/swt_shoes/radio_spec.rb +56 -0
  213. data/spec/swt_shoes/rect_painter_spec.rb +45 -0
  214. data/spec/swt_shoes/rect_spec.rb +19 -0
  215. data/spec/swt_shoes/shape_spec.rb +84 -0
  216. data/spec/swt_shoes/shared_examples/button.rb +21 -0
  217. data/spec/swt_shoes/shared_examples/clickable.rb +85 -0
  218. data/spec/swt_shoes/shared_examples/movable.rb +36 -0
  219. data/spec/swt_shoes/shared_examples/paintable.rb +7 -0
  220. data/spec/swt_shoes/shared_examples/painter.rb +83 -0
  221. data/spec/swt_shoes/shared_examples/pattern.rb +32 -0
  222. data/spec/swt_shoes/shared_examples/removable.rb +41 -0
  223. data/spec/swt_shoes/shared_examples/swt_app_context.rb +23 -0
  224. data/spec/swt_shoes/shared_examples/visibility.rb +15 -0
  225. data/spec/swt_shoes/shell_control_listener_spec.rb +23 -0
  226. data/spec/swt_shoes/slot_spec.rb +24 -0
  227. data/spec/swt_shoes/sound.rb +10 -0
  228. data/spec/swt_shoes/spec_helper.rb +31 -0
  229. data/spec/swt_shoes/star_spec.rb +47 -0
  230. data/spec/swt_shoes/text_block/centered_text_segment_spec.rb +16 -0
  231. data/spec/swt_shoes/text_block/cursor_painter_spec.rb +120 -0
  232. data/spec/swt_shoes/text_block/fitter_spec.rb +213 -0
  233. data/spec/swt_shoes/text_block/painter_spec.rb +212 -0
  234. data/spec/swt_shoes/text_block/text_font_factory_spec.rb +40 -0
  235. data/spec/swt_shoes/text_block/text_segment_collection_spec.rb +256 -0
  236. data/spec/swt_shoes/text_block/text_segment_spec.rb +135 -0
  237. data/spec/swt_shoes/text_block_spec.rb +199 -0
  238. metadata +496 -0
@@ -0,0 +1,213 @@
1
+ require 'swt_shoes/spec_helper'
2
+
3
+ describe Shoes::Swt::TextBlock::Fitter do
4
+ let(:dsl) { double('dsl', parent: parent_dsl, text: "Text goes here",
5
+ desired_width: 85, centered?: false,
6
+ absolute_left: 25, absolute_top: 75,
7
+ element_left: 26, element_top: 76,
8
+ margin_left: 1, margin_top: 1) }
9
+
10
+ let(:parent_dsl) { double('parent_dsl', parent: grandparent_dsl,
11
+ absolute_top: 0, absolute_left: 0, absolute_right: 100,
12
+ width: parent_width, height: 200) }
13
+
14
+ let(:grandparent_dsl) { double('grandparent_dsl', parent: app,
15
+ width: grandparent_width) }
16
+
17
+ let(:app) { double('app', width: app_width) }
18
+
19
+ let(:parent_width) { 100 }
20
+ let(:grandparent_width) { 1000 }
21
+ let(:app_width) { 2000 }
22
+
23
+ let(:text_block) { double('text_block', dsl: dsl) }
24
+ let(:segment) { double('segment') }
25
+
26
+ let(:current_position) { double('current_position') }
27
+
28
+ subject { Shoes::Swt::TextBlock::Fitter.new(text_block, current_position) }
29
+
30
+ before(:each) do
31
+ allow(Shoes::Swt::TextBlock::TextSegment).to receive(:new) { segment }
32
+ end
33
+
34
+ describe "determining available space" do
35
+ it "should offset by parent with current position" do
36
+ when_positioned_at(x: 15, y: 5, next_line_start: 30)
37
+ expect(subject.available_space).to eq([85, 24])
38
+ end
39
+
40
+ it "should move to next line with at very end of vertical space" do
41
+ when_positioned_at(x: 15, y: 5, next_line_start: 5)
42
+ expect(subject.available_space).to eq([85, :unbounded])
43
+ end
44
+
45
+ it "should move to next line when top is past the projected next line" do
46
+ when_positioned_at(x: 15, y: 100, next_line_start: 5)
47
+ expect(subject.available_space).to eq([85, :unbounded])
48
+ end
49
+
50
+ context "positioned outside parent" do
51
+ before(:each) do
52
+ allow(dsl).to receive(:desired_width) { -1 }
53
+ end
54
+
55
+ it "bumps to parent width when at end of vertical space" do
56
+ when_positioned_at(x: 110, y: 5, next_line_start: 5)
57
+ allow(dsl).to receive(:desired_width).with(grandparent_width) { 890 }
58
+
59
+ expect(subject.available_space).to eq([890, :unbounded])
60
+ end
61
+
62
+ it "bumps out until it fits" do
63
+ when_positioned_at(x:1010, y: 5, next_line_start: 5)
64
+ allow(dsl).to receive(:desired_width).with(app_width) { 990 }
65
+
66
+ expect(subject.available_space).to eq([990, :unbounded])
67
+ end
68
+
69
+ it "just gives up if it still won't fit" do
70
+ when_positioned_at(x:1010, y: 5, next_line_start: 5)
71
+ expect(subject.available_space).to eq([0, 0])
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "finding what didn't fit" do
77
+ it "should tell split text by offsets and heights" do
78
+ segment = double('segment', line_offsets: [0, 5, 9], text: "Text Split")
79
+ allow(segment).to receive(:line_bounds) { double('line_bounds', height: 50)}
80
+
81
+ expect(subject.split_text(segment, 55)).to eq(["Text ", "Split"])
82
+ end
83
+
84
+ it "should be able to split text when too small" do
85
+ segment = double('segment', line_offsets: [0, 10], text: "Text Split")
86
+ allow(segment).to receive(:line_bounds).with(0) { double('line_bounds', height: 21)}
87
+ allow(segment).to receive(:line_bounds).with(1) { raise "Boom" }
88
+
89
+ expect(subject.split_text(segment, 33)).to eq(["Text Split", ""])
90
+ end
91
+ end
92
+
93
+ describe "fit it in" do
94
+ let(:bounds) { double('bounds', width: 100, height: 50)}
95
+ let(:segment) { double('segment',
96
+ text: "something something", :text= => nil,
97
+ line_count: 1, line_offsets:[], bounds: bounds) }
98
+
99
+ before(:each) do
100
+ layout = double('swt_layout', :spacing => 4, :spacing= => nil)
101
+ allow(segment).to receive(:position_at) { segment }
102
+ allow(segment).to receive(:spacing) { 4 }
103
+ allow(segment).to receive(:layout) { layout }
104
+
105
+ end
106
+
107
+ context "to one segment" do
108
+ it "should work" do
109
+ segments = when_fit_at(x: 25, y: 75, next_line_start: 130)
110
+ expect_segments(segments, [26, 76])
111
+ end
112
+
113
+ it "with one line, even if height is bigger" do
114
+ allow(bounds).to receive_messages(width: 50)
115
+ segments = when_fit_at(x: 25, y: 75, next_line_start: 95)
116
+ expect_segments(segments, [26, 76])
117
+ end
118
+ end
119
+
120
+ context "to two segments" do
121
+ before(:each) do
122
+ allow(segment).to receive_messages(line_count: 2, line_bounds: double(height: 15))
123
+ allow(bounds).to receive_messages(width: 50)
124
+ allow(dsl).to receive_messages(containing_width: :unused)
125
+ end
126
+
127
+ it "should split text and overflow to second segment" do
128
+ with_text_split("something ", "something")
129
+ expect(segment).to receive(:dispose).once
130
+
131
+ segments = when_fit_at(x: 25, y: 75, next_line_start: 95)
132
+ expect_segments(segments, [26, 76], [1, 123])
133
+ end
134
+
135
+ it "should overflow all text to second segment" do
136
+ with_text_split("", "something something")
137
+ expect(segment).to receive(:dispose).once
138
+
139
+ segments = when_fit_at(x: 25, y: 75, next_line_start: 95)
140
+ expect_segments(segments, [26, 76], [1, 96])
141
+ end
142
+ end
143
+
144
+ context "to empty first segment" do
145
+ before(:each) do
146
+ allow(dsl).to receive_messages(containing_width: 100)
147
+ end
148
+
149
+ it "rolls to second segment when 0 remaining width" do
150
+ allow(dsl).to receive_messages(desired_width: 0)
151
+ segments = when_fit_at(x: 0, y: 75, next_line_start: 95)
152
+ expect_segments(segments, [26, 76], [1, 97])
153
+ end
154
+
155
+ it "rolls to second segment when negative remaining width" do
156
+ allow(dsl).to receive_messages(desired_width: -1)
157
+ segments = when_fit_at(x: 0, y: 75, next_line_start: 95)
158
+ expect_segments(segments, [26, 76], [1, 97])
159
+ end
160
+ end
161
+
162
+ context "to center segment" do
163
+ before do
164
+ allow(dsl).to receive_messages(centered?: true)
165
+ allow(dsl).to receive_messages(containing_width: 100)
166
+ end
167
+
168
+ it "uses full width" do
169
+ allow(dsl).to receive_messages(element_left: 0, left: 0)
170
+ segments = when_fit_at(x: 0, y: 75, next_line_start: 95)
171
+ expect_segments(segments, [0, 76])
172
+ end
173
+
174
+ it "bumps down a line if not at start" do
175
+ allow(dsl).to receive_messages(element_left: 20, left: 20)
176
+ segments = when_fit_at(x: 20, y: 75, next_line_start: 95)
177
+ expect_segments(segments, [20, 76], [1, 96])
178
+ end
179
+
180
+ it "if unbounded height, still bumps down properly" do
181
+ allow(dsl).to receive_messages(absolute_top: 95, element_left: 20, left: 20, margin_left: 1)
182
+ segments = when_fit_at(x: 20, y: 75, next_line_start: 95)
183
+ expect_segments(segments, [20, 76], [1, 96])
184
+ end
185
+ end
186
+ end
187
+
188
+ def with_text_split(first, second)
189
+ allow(dsl).to receive_messages(text: first + second)
190
+ allow(segment).to receive_messages(line_offsets: [0, first.length, first.length + second.length])
191
+ end
192
+
193
+ def when_positioned_at(args)
194
+ x = args.fetch(:x)
195
+ y = args.fetch(:y)
196
+ next_line_start = args.fetch(:next_line_start)
197
+
198
+ allow(dsl).to receive_messages(absolute_left: x, absolute_top: y)
199
+ allow(current_position).to receive(:next_line_start) { next_line_start }
200
+ end
201
+
202
+ def when_fit_at(args)
203
+ when_positioned_at(args)
204
+ subject.fit_it_in
205
+ end
206
+
207
+ def expect_segments(segments, *coordinates)
208
+ segments.each_with_index do |segment, index|
209
+ x, y = coordinates[index]
210
+ expect(segment).to have_received(:position_at).with(x, y)
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,212 @@
1
+ require 'swt_shoes/spec_helper'
2
+
3
+ describe Shoes::Swt::TextBlock::Painter do
4
+ include_context "swt app"
5
+
6
+ let(:dsl_style) { {justify: true, leading: 10, underline: "single"} }
7
+ let(:gui) { double("gui", dispose: nil) }
8
+ let(:dsl) { double("dsl", app: shoes_app, gui: gui,
9
+ text: text, cursor: nil, style: dsl_style,
10
+ element_width: 200, element_height: 180,
11
+ element_left: 0, element_top: 10, font: "font",
12
+ size: 16, margin_left: 0, margin_top: 0,
13
+ text_styles: text_styles, :hidden? => false).as_null_object
14
+ }
15
+
16
+ let(:segment) do
17
+ allow(::Swt::Font).to receive(:new) { font }
18
+ allow(::Swt::TextLayout).to receive(:new) { text_layout }
19
+ allow(::Swt::TextStyle).to receive(:new) { style }
20
+
21
+ Shoes::Swt::TextBlock::TextSegment.new(dsl, text, 200).position_at(0, 10)
22
+ end
23
+
24
+ let(:text_layout) { double("text layout", text: text).as_null_object }
25
+
26
+ let(:event) { double("event").as_null_object }
27
+ let(:style) { double(:style).as_null_object }
28
+ let(:font) { double(:font, font_data: [font_data]).as_null_object }
29
+ let(:font_data) { double(name: "font", height: 16.0, style: ::Swt::SWT::NORMAL) }
30
+
31
+ let(:blue) { Shoes::Color.new(0, 0, 255) }
32
+ let(:swt_blue) { Shoes::Swt::Color.new(blue).real}
33
+ let(:text_styles) {{}}
34
+ let(:text) {'hello world'}
35
+
36
+ subject { Shoes::Swt::TextBlock::Painter.new(dsl) }
37
+
38
+ before :each do
39
+ allow(::Swt::TextStyle).to receive(:new) { style.as_null_object }
40
+
41
+ # Can't stub this in during initial let because of circular reference
42
+ # segments -> dsl -> gui -> segments...
43
+ allow(gui).to receive_messages(segments: [segment])
44
+ end
45
+
46
+ it "draws" do
47
+ expect(segment).to receive(:draw)
48
+ subject.paintControl(event)
49
+ end
50
+
51
+ it "sets justify" do
52
+ expect(text_layout).to receive(:justify=).with(dsl_style[:justify])
53
+ subject.paintControl(event)
54
+ end
55
+
56
+ it "sets spacing" do
57
+ expect(text_layout).to receive(:spacing=).with(dsl_style[:leading])
58
+ subject.paintControl(event)
59
+ end
60
+
61
+ it "sets alignment" do
62
+ expect(text_layout).to receive(:alignment=).with(anything)
63
+ subject.paintControl(event)
64
+ end
65
+
66
+ it "sets text styles" do
67
+ expect(text_layout).to receive(:set_style).with(anything, anything, anything).at_least(1).times
68
+ subject.paintControl(event)
69
+ end
70
+
71
+ context "rise option" do
72
+ it "sets default rise value to nil" do
73
+ expect(style).to receive(:rise=).with(nil)
74
+ subject.paintControl(event)
75
+ end
76
+
77
+ it "sets correct rise value" do
78
+ dsl_style[:rise] = 10
79
+ expect(style).to receive(:rise=).with(10)
80
+
81
+ subject.paintControl(event)
82
+ end
83
+ end
84
+
85
+ context "underline option" do
86
+ it "sets default underline style to none" do
87
+ dsl_style.delete(:underline)
88
+
89
+ expect(style).to receive(:underline=).with(false)
90
+ expect(style).to receive(:underlineStyle=).with(nil)
91
+
92
+ subject.paintControl(event)
93
+ end
94
+
95
+ it "sets correct underline style" do
96
+
97
+ expect(style).to receive(:underline=).with(true)
98
+ expect(style).to receive(:underlineStyle=).with(Shoes::Swt::TextStyleFactory::UNDERLINE_STYLES["single"])
99
+
100
+ subject.paintControl(event)
101
+ end
102
+
103
+ it "sets underline color" do
104
+ dsl_style[:undercolor] = blue
105
+
106
+ expect(style).to receive(:underlineColor=).with(swt_blue)
107
+
108
+ subject.paintControl(event)
109
+ end
110
+
111
+ it "sets default underline color to nil" do
112
+ expect(style).to receive(:underlineColor=).with(nil)
113
+
114
+ subject.paintControl(event)
115
+ end
116
+ end
117
+
118
+ context "strikethrough option" do
119
+ it "sets default strikethrough to none" do
120
+ expect(style).to receive(:strikeout=).with(false)
121
+
122
+ subject.paintControl(event)
123
+ end
124
+
125
+ it "sets strikethrough" do
126
+ dsl_style[:strikethrough] = "single"
127
+
128
+ expect(style).to receive(:strikeout=).with(true)
129
+
130
+ subject.paintControl(event)
131
+ end
132
+
133
+ it "sets strikethrough color" do
134
+ dsl_style[:strikecolor] = blue
135
+
136
+ expect(style).to receive(:strikeoutColor=).with(swt_blue)
137
+
138
+ subject.paintControl(event)
139
+ end
140
+
141
+ it "sets default strikethrough color to nil" do
142
+ expect(style).to receive(:strikeoutColor=).with(nil)
143
+
144
+ subject.paintControl(event)
145
+ end
146
+ end
147
+
148
+ context "font styles" do
149
+ it "sets font style to bold" do
150
+ dsl_style[:weight] = true
151
+ expect(::Swt::Font).to receive(:new).with(anything, anything, anything, ::Swt::SWT::BOLD)
152
+ subject.paintControl(event)
153
+ end
154
+
155
+ it "sets font style to italic" do
156
+ dsl_style[:emphasis] = true
157
+ expect(::Swt::Font).to receive(:new).with(anything, anything, anything, ::Swt::SWT::ITALIC)
158
+ subject.paintControl(event)
159
+ end
160
+
161
+ it "sets font style to both bold and italic" do
162
+ dsl_style[:weight] = true
163
+ dsl_style[:emphasis] = true
164
+ expect(::Swt::Font).to receive(:new).with(anything, anything, anything, ::Swt::SWT::BOLD | ::Swt::SWT::ITALIC)
165
+
166
+ subject.paintControl(event)
167
+ end
168
+ end
169
+
170
+ context "colors" do
171
+ let(:black) { Shoes::Swt::Color.new(Shoes::COLORS[:black]).real }
172
+ let(:salmon) { Shoes::Swt::Color.new(Shoes::COLORS[:salmon]).real }
173
+
174
+ describe "stroke" do
175
+ it "is black by default" do
176
+ expect(::Swt::TextStyle).to receive(:new).with(anything, black, anything)
177
+ subject.paintControl(event)
178
+ end
179
+
180
+ it "is set with dsl_style[:stroke]" do
181
+ dsl_style[:stroke] = Shoes::COLORS[:salmon]
182
+ expect(::Swt::TextStyle).to receive(:new).with(anything, salmon, anything)
183
+ subject.paintControl(event)
184
+ end
185
+ end
186
+
187
+ describe "fill" do
188
+ it "is nil by default" do
189
+ expect(::Swt::TextStyle).to receive(:new).with(anything, anything, nil)
190
+ subject.paintControl(event)
191
+ end
192
+
193
+ it "is set with dsl_style[:fill]" do
194
+ dsl_style[:fill] = Shoes::COLORS[:salmon]
195
+ expect(::Swt::TextStyle).to receive(:new).with(anything, anything, salmon)
196
+ subject.paintControl(event)
197
+ end
198
+ end
199
+ end
200
+
201
+ describe 'text_styles' do
202
+ # this text_styles relies a lot on the internal structure of TextBlock/Painter
203
+ # right now, which I'm not too fond of... :)
204
+ let(:text_styles) {[[0...text.length, [Shoes::Span.new([text], size: 50)]]]}
205
+ it 'sets the font size to 50' do
206
+ expect(::Swt::Font).to receive(:new).
207
+ with(anything, anything, 50, anything)
208
+
209
+ subject.paintControl event
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,40 @@
1
+ require 'swt_shoes/spec_helper'
2
+
3
+ describe Shoes::Swt::TextFontFactory do
4
+ let(:font_details) {
5
+ {
6
+ :name => "Helvetica",
7
+ :size => 16,
8
+ :styles => [::Swt::SWT::BOLD]
9
+ }
10
+ }
11
+
12
+ subject { Shoes::Swt::TextFontFactory.new() }
13
+
14
+ it "creates a font" do
15
+ font = subject.create_font(font_details)
16
+ expect(font).not_to be(nil)
17
+ end
18
+
19
+ it "disposes of fonts" do
20
+ font = subject.create_font(font_details)
21
+ expect(font).to receive(:dispose)
22
+
23
+ subject.dispose
24
+ end
25
+
26
+ it "doesn't dispose already disposed fonts" do
27
+ font = subject.create_font(font_details)
28
+ font.dispose
29
+
30
+ expect(font).not_to receive(:dispose)
31
+ subject.dispose
32
+ end
33
+
34
+ it "reuses font instances" do
35
+ font1 = subject.create_font(font_details)
36
+ font2 = subject.create_font(font_details)
37
+
38
+ expect(font1).to be(font2)
39
+ end
40
+ end