shoes-swt 4.0.0.pre2

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 (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,50 @@
1
+ class Shoes
2
+ module Swt
3
+ class TextFontFactory
4
+ def initialize
5
+ @fonts = []
6
+ end
7
+
8
+ def create_font(font_style)
9
+ name = font_style[:name]
10
+ size = font_style[:size]
11
+ styles = styles_bitmask(font_style[:styles])
12
+
13
+ existing_font = find_existing_font(name, size, styles)
14
+ if existing_font
15
+ existing_font
16
+ else
17
+ build_font(name, size, styles)
18
+ end
19
+ end
20
+
21
+ def dispose
22
+ @fonts.each { |font| font.dispose unless font.disposed? }
23
+ @fonts.clear
24
+ end
25
+
26
+ def find_existing_font(name, size, styles)
27
+ # Bit odd, but fonts on some OS's have multiple font_data elements,
28
+ # so check if any of them match.
29
+ @fonts.find do |font|
30
+ font.font_data.any? do |font_data|
31
+ font_data.name == name &&
32
+ # Windows seems to create fonts of height 15.75 when requesting 16
33
+ font_data.height.round == size.round &&
34
+ font_data.style == styles
35
+ end
36
+ end
37
+ end
38
+
39
+ def build_font(name, size, styles)
40
+ font = ::Swt::Graphics::Font.new @display, name, size, styles
41
+ @fonts << font
42
+ font
43
+ end
44
+
45
+ def styles_bitmask(styles)
46
+ styles.reduce { |result, s| result | s }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,108 @@
1
+ class Shoes
2
+ module Swt
3
+ class TextBlock
4
+ # Resources created here need to be disposed (see #dispose). Note that
5
+ # this applies to ::Swt::Font and ::Swt::TextLayout. ::Swt::TextStyle
6
+ # does not need to be disposed, because it is not backed by system
7
+ # resources.
8
+ #
9
+ # The instance factories and our own instances will track these resources
10
+ # and ensure that they get properly disposed when TextBlock or Fitter
11
+ # tell us we're done.
12
+ #
13
+ # These are only expected to be called during contents_alignment
14
+ class TextSegment
15
+ DEFAULT_SPACING = 4
16
+
17
+ attr_reader :layout, :element_left, :element_top
18
+
19
+ extend Forwardable
20
+ def_delegators :@layout, :text, :text=, :bounds, :width, :spacing,
21
+ :line_bounds, :line_count, :line_offsets
22
+
23
+ def initialize(dsl, text, width)
24
+ @dsl = dsl
25
+ @layout = ::Swt::TextLayout.new Shoes.display
26
+ @font_factory = TextFontFactory.new
27
+ @style_factory = TextStyleFactory.new
28
+
29
+ layout.text = text
30
+ layout.width = width unless layout_fits_in?(width)
31
+ style_from(font_styling, @dsl.style)
32
+ end
33
+
34
+ def dispose
35
+ @layout.dispose unless @layout.disposed?
36
+ @font_factory.dispose
37
+ @style_factory.dispose
38
+ end
39
+
40
+ def position_at(element_left, element_top)
41
+ @element_left = element_left
42
+ @element_top = element_top
43
+ self
44
+ end
45
+
46
+ def get_location(cursor, trailing=false)
47
+ @layout.get_location(cursor, trailing)
48
+ end
49
+
50
+ def style_from(default_text_styles, style)
51
+ layout.justify = style[:justify]
52
+ layout.spacing = (style[:leading] || DEFAULT_SPACING)
53
+ layout.alignment = case style[:align]
54
+ when 'center'; ::Swt::SWT::CENTER
55
+ when 'right'; ::Swt::SWT::RIGHT
56
+ else ::Swt::SWT::LEFT
57
+ end
58
+
59
+ set_style(TextStyleFactory.apply_styles(default_text_styles, style))
60
+ end
61
+
62
+ def set_style(styles, range=(0...text.length))
63
+ # If we've been given an empty/nonsense range, just ignore it
64
+ return unless range.count > 0
65
+
66
+ font = @font_factory.create_font(styles[:font_detail])
67
+ style = @style_factory.create_style(font, styles[:fg], styles[:bg], styles)
68
+ layout.set_style(style, range.min, range.max)
69
+ end
70
+
71
+ def font_styling
72
+ {
73
+ font_detail: {
74
+ name: @dsl.font,
75
+ size: @dsl.size,
76
+ styles:[::Swt::SWT::NORMAL]
77
+ }
78
+ }
79
+ end
80
+
81
+ def layout_fits_in?(width)
82
+ layout.bounds.width <= width
83
+ end
84
+
85
+ def height
86
+ layout.bounds.height - layout.spacing
87
+ end
88
+
89
+ def last_line_height
90
+ layout.line_bounds(layout.line_count - 1).height
91
+ end
92
+
93
+ def last_line_width
94
+ layout.line_bounds(layout.line_count - 1).width
95
+ end
96
+
97
+ def draw(graphics_context)
98
+ layout.draw(graphics_context, element_left, element_top)
99
+ end
100
+
101
+ # x,y in app coordinates, so translate for layout's element-local values
102
+ def in_bounds?(x, y)
103
+ layout.bounds.contains?(x - element_left, y - element_top)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,160 @@
1
+ class Shoes
2
+ module Swt
3
+ class TextBlock
4
+ class TextSegmentCollection
5
+ extend Forwardable
6
+ def_delegators :@segments, :length
7
+
8
+ attr_reader :dsl, :default_text_styles
9
+
10
+ def initialize(dsl, segments, default_text_styles)
11
+ @dsl = dsl
12
+ @segments = segments
13
+ @default_text_styles = default_text_styles
14
+ end
15
+
16
+ def paint_control(graphic_context)
17
+ style_from(dsl.style)
18
+ style_segment_ranges(dsl.text_styles)
19
+ create_links(dsl.text_styles)
20
+ draw(graphic_context)
21
+ draw_cursor
22
+ end
23
+
24
+ def style_from(style)
25
+ @segments.each do |segment|
26
+ segment.style_from(default_text_styles, style)
27
+ end
28
+ end
29
+
30
+ def draw(graphic_context)
31
+ @segments.each do |segment|
32
+ segment.draw(graphic_context)
33
+ end
34
+ end
35
+
36
+ def draw_cursor
37
+ TextBlock::CursorPainter.new(dsl, self).draw
38
+ end
39
+
40
+ def style_segment_ranges(elements_by_range)
41
+ elements_by_range.each do |range, elements|
42
+ style = calculate_style(elements)
43
+ segment_ranges(range).each do |segment, inner_range|
44
+ segment.set_style(style, inner_range)
45
+ end
46
+ end
47
+ end
48
+
49
+ def calculate_style(elements)
50
+ elements.inject(default_text_styles) do |current_style, element|
51
+ if element.respond_to?(:style)
52
+ TextStyleFactory.apply_styles(current_style, element.style)
53
+ else
54
+ # Didn't know how to style from the element, so punt
55
+ current_style
56
+ end
57
+ end
58
+ end
59
+
60
+ def create_links(elements_by_range)
61
+ elements_by_range.each do |range, elements|
62
+ elements.each do |element|
63
+ if supports_links?(element)
64
+ element.gui.create_links_in(segment_ranges(range))
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ def supports_links?(element)
71
+ element.respond_to?(:gui) &&
72
+ element.gui &&
73
+ element.gui.respond_to?(:create_links_in)
74
+ end
75
+
76
+ def segment_at_text_position(index)
77
+ return @segments.last if index < 0
78
+ segment_ranges(index..index).first.first
79
+ end
80
+
81
+ # If we've got segments that style us across different ranges, it might
82
+ # be in either, or both, of the segments. This method figures out which
83
+ # segments apply, and what the relative ranges within each segment to use.
84
+ def segment_ranges(text_range)
85
+ return [] unless @segments.first # TODO WTF #636
86
+ first_text = @segments.first.text
87
+ slice = first_text[text_range]
88
+
89
+ if slice.nil? || slice.empty?
90
+ results_in_last_segment(text_range, first_text)
91
+ elsif slice.length < text_range.count
92
+ results_spanning_segments(text_range, first_text, slice)
93
+ else
94
+ results_in_first_segment(text_range)
95
+ end
96
+ end
97
+
98
+ def results_in_first_segment(text_range)
99
+ [[@segments.first, text_range]]
100
+ end
101
+
102
+ def results_spanning_segments(text_range, first_text, slice)
103
+ result = []
104
+ result << [@segments.first, (text_range.first..first_text.length)]
105
+ # If first == last, then requested range was longer than our one and
106
+ # only segment, so just stick with full range of the first segment.
107
+ if @segments.first != @segments.last
108
+ result << [@segments.last, (0..text_range.count - slice.length - 1)]
109
+ end
110
+ result
111
+ end
112
+
113
+ def results_in_last_segment(text_range, first_text)
114
+ range_start = text_range.first - first_text.length
115
+ range_end = text_range.last - first_text.length
116
+ [[@segments.last, (range_start..range_end)]]
117
+ end
118
+
119
+ # Returns the relative position within the appropriate segment for index
120
+ # in the overall DSL text
121
+ def relative_text_position(index)
122
+ if at_end?(index)
123
+ relative_end_position
124
+ elsif relative_in_first_segment?(index)
125
+ relative_in_first_segment(index)
126
+ else
127
+ relative_in_last_segment(index)
128
+ end
129
+ end
130
+
131
+ def relative_in_first_segment?(index)
132
+ index >= 0 &&
133
+ (@segments.one? || index < @segments.first.text.length)
134
+ end
135
+
136
+ def at_end?(index)
137
+ index < 0 || index > @dsl.text.length
138
+ end
139
+
140
+ def relative_end_position
141
+ @segments.last.text.length
142
+ end
143
+
144
+ def relative_in_first_segment(index)
145
+ index
146
+ end
147
+
148
+ def relative_in_last_segment(index)
149
+ index - @segments.first.text.length
150
+ end
151
+
152
+ # This could be smarter, basing height on the actual line the cursor's
153
+ # in. For now, just use the first line's height.
154
+ def cursor_height
155
+ @segments.first.line_bounds(0).height
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,88 @@
1
+ class Shoes
2
+ module Swt
3
+ class TextStyleFactory
4
+ UNDERLINE_STYLES = {
5
+ "single" => 0,
6
+ "double" => 1,
7
+ "error" => 2,
8
+ }
9
+
10
+ def initialize
11
+ @colors = []
12
+ end
13
+
14
+ def dispose
15
+ @colors.each { |color| color.dispose unless color.disposed? }
16
+ @colors.clear
17
+ end
18
+
19
+ def create_style(font, foreground, background, style)
20
+ fg = swt_color(foreground, ::Shoes::COLORS[:black])
21
+ bg = swt_color(background)
22
+ @gui_style = ::Swt::TextStyle.new font, fg, bg
23
+ set_underline(style)
24
+ set_undercolor(style)
25
+ set_rise(style)
26
+ set_strikethrough(style)
27
+ set_strikecolor(style)
28
+ @gui_style
29
+ end
30
+
31
+ def self.apply_styles(gui_style, dsl_style)
32
+ gui_style[:font_detail][:styles] = parse_font_style(dsl_style)
33
+ gui_style[:font_detail][:name] = dsl_style[:font] if dsl_style[:font]
34
+ gui_style[:font_detail][:size] = dsl_style[:size] if dsl_style[:size]
35
+ gui_style[:fg] = dsl_style[:stroke]
36
+ gui_style[:bg] = dsl_style[:fill]
37
+ gui_style[:font_detail][:size] *= dsl_style[:size_modifier] if dsl_style[:size_modifier]
38
+ gui_style.merge(dsl_style)
39
+ end
40
+
41
+ def self.parse_font_style(style)
42
+ font_styles = []
43
+ font_styles << ::Swt::SWT::BOLD if style[:weight]
44
+ font_styles << ::Swt::SWT::ITALIC if style[:emphasis]
45
+ font_styles << ::Swt::SWT::NORMAL if !style[:weight] && !style[:emphasis]
46
+ font_styles
47
+ end
48
+
49
+ private
50
+ def set_rise(style)
51
+ @gui_style.rise = style[:rise]
52
+ end
53
+
54
+ def set_underline(style)
55
+ @gui_style.underline = style[:underline].nil? || style[:underline] == "none" ? false : true
56
+ @gui_style.underlineStyle = UNDERLINE_STYLES[style[:underline]]
57
+ end
58
+
59
+ def set_undercolor(style)
60
+ @gui_style.underlineColor = color_from_dsl style[:undercolor]
61
+ end
62
+
63
+ def set_strikethrough(style)
64
+ @gui_style.strikeout = style[:strikethrough].nil? || style[:strikethrough] == "none" ? false : true
65
+ end
66
+
67
+ def set_strikecolor(style)
68
+ @gui_style.strikeoutColor = color_from_dsl style[:strikecolor]
69
+ end
70
+
71
+ def swt_color(color, default = nil)
72
+ return color if color.is_a? ::Swt::Color
73
+ color_from_dsl color, default
74
+ end
75
+
76
+ def color_from_dsl(dsl_color, default = nil)
77
+ return nil if dsl_color.nil? and default.nil?
78
+ return color_from_dsl default if dsl_color.nil?
79
+ color = ::Swt::Color.new(Shoes.display, dsl_color.red, dsl_color.green, dsl_color.blue)
80
+
81
+ # Hold a reference to the color so we can dispose it when the time comes
82
+ @colors << color
83
+
84
+ color
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,19 @@
1
+ class Shoes
2
+ module Swt
3
+ class Timer
4
+ def initialize(dsl, app, blk)
5
+ @blk = blk
6
+ task = Proc.new do
7
+ unless app.real.disposed?
8
+ eval_block
9
+ end
10
+ end
11
+ ::Swt.display.timer_exec(dsl.n, task)
12
+ end
13
+
14
+ def eval_block
15
+ @blk.call
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ require 'swt'
2
+ require 'shoes/swt'
3
+ # Interested what hometown is and what it does?
4
+ # check here: https://github.com/jasonrclark/hometown
5
+ require 'hometown'
6
+
7
+ # All known subclasses of Swt::Graphics::Resource
8
+ # see http://help.eclipse.org/helios/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fswt%2Fpackage-summary.html
9
+ [
10
+ ::Swt::Graphics::Color,
11
+ ::Swt::Graphics::Cursor,
12
+ ::Swt::Graphics::Font,
13
+ ::Swt::Graphics::Image,
14
+ ::Swt::Graphics::Path,
15
+ ::Swt::Graphics::Pattern,
16
+ ::Swt::Graphics::Region,
17
+ ::Swt::Graphics::TextLayout,
18
+ ::Swt::Graphics::Transform,
19
+
20
+ # Excluded GC as we don't create any directly and it's quite noisy
21
+ #::Swt::Graphics::GC,
22
+ ].each do |clazz|
23
+ Hometown.watch_for_disposal(clazz, :dispose)
24
+ end
25
+
26
+ Hometown.undisposed_report_at_exit
27
+
28
+ # Register an internal keystroke for closing the app, making sure to clear
29
+ # out the contents first (to avoid false positives for still-exiting elements.
30
+ Shoes::InternalApp.add_global_keypress(:'control_alt_q') do
31
+ clear
32
+ quit
33
+ end
34
+
35
+ puts "Registered Ctrl+Alt+Q for leak hunting clean shutdown."