glimmer-dsl-swt 4.18.7.5 → 4.19.0.2

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -0
  3. data/README.md +29 -11
  4. data/RUBY_VERSION +1 -1
  5. data/VERSION +1 -1
  6. data/bin/girb +10 -9
  7. data/bin/girb_runner.rb +8 -3
  8. data/bin/glimmer +10 -1
  9. data/bin/glimmer-setup +58 -0
  10. data/bin/glimmer_runner.rb +4 -0
  11. data/docs/reference/GLIMMER_COMMAND.md +21 -31
  12. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +6 -2
  13. data/docs/reference/GLIMMER_PACKAGING_AND_DISTRIBUTION.md +7 -1
  14. data/docs/reference/GLIMMER_SAMPLES.md +27 -0
  15. data/glimmer-dsl-swt.gemspec +0 -0
  16. data/lib/glimmer-dsl-swt.rb +8 -0
  17. data/lib/glimmer/data_binding/widget_binding.rb +1 -1
  18. data/lib/glimmer/dsl/swt/c_tab_item_expression.rb +58 -0
  19. data/lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb +2 -1
  20. data/lib/glimmer/dsl/swt/tab_item_expression.rb +7 -3
  21. data/lib/glimmer/dsl/swt/widget_expression.rb +1 -1
  22. data/lib/glimmer/launcher.rb +27 -51
  23. data/lib/glimmer/rake_task.rb +1 -1
  24. data/lib/glimmer/rake_task/package.rb +7 -2
  25. data/lib/glimmer/rake_task/scaffold.rb +227 -254
  26. data/lib/glimmer/swt/c_tab_item_proxy.rb +53 -0
  27. data/lib/glimmer/swt/custom/code_text.rb +19 -3
  28. data/lib/glimmer/swt/custom/shape.rb +15 -1
  29. data/lib/glimmer/swt/sash_form_proxy.rb +6 -0
  30. data/lib/glimmer/swt/shell_proxy.rb +3 -1
  31. data/lib/glimmer/swt/tab_folder_proxy.rb +1 -0
  32. data/lib/glimmer/swt/tab_item_proxy.rb +17 -18
  33. data/lib/glimmer/swt/widget_proxy.rb +9 -0
  34. data/samples/elaborate/mandelbrot_fractal.rb +11 -6
  35. data/samples/elaborate/meta_sample.rb +4 -2
  36. data/samples/elaborate/metronome.rb +1 -1
  37. data/samples/elaborate/stock_ticker.rb +2 -2
  38. data/samples/hello/hello_c_combo.rb +68 -0
  39. data/samples/hello/hello_c_tab.rb +173 -0
  40. data/samples/hello/hello_c_tab/denmark.png +0 -0
  41. data/samples/hello/hello_c_tab/finland.png +0 -0
  42. data/samples/hello/hello_c_tab/france.png +0 -0
  43. data/samples/hello/hello_c_tab/germany.png +0 -0
  44. data/samples/hello/hello_c_tab/italy.png +0 -0
  45. data/samples/hello/hello_c_tab/mexico.png +0 -0
  46. data/samples/hello/hello_c_tab/netherlands.png +0 -0
  47. data/samples/hello/hello_c_tab/norway.png +0 -0
  48. data/samples/hello/hello_c_tab/usa.png +0 -0
  49. data/samples/hello/hello_code_text.rb +141 -73
  50. data/samples/hello/hello_shape.rb +1 -0
  51. data/samples/hello/hello_tab.rb +2 -0
  52. data/vendor/swt/linux/swt.jar +0 -0
  53. data/vendor/swt/mac/swt.jar +0 -0
  54. data/vendor/swt/windows/swt.jar +0 -0
  55. metadata +75 -34
@@ -0,0 +1,53 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/swt/widget_proxy'
23
+ require 'glimmer/swt/tab_item_proxy'
24
+
25
+ module Glimmer
26
+ module SWT
27
+ # Proxy for org.eclipse.swt.custom.CTabItem
28
+ #
29
+ # Functions differently from other widget proxies.
30
+ #
31
+ # Glimmer instantiates an SWT Composite alongside the SWT TabItem
32
+ # and returns it for `#swt_widget` to allow adding widgets into it.
33
+ #
34
+ # In order to get the SWT TabItem object, one must call `#swt_tab_item`.
35
+ #
36
+ # Behind the scenes, this creates a tab item widget proxy separately from a composite that
37
+ # is set as the control of the tab item and `#swt_widget`.
38
+ #
39
+ # In order to retrieve the tab item widget proxy, one must call `#widget_proxy`
40
+ #
41
+ # Follows the Proxy Design Pattern
42
+ class CTabItemProxy < TabItemProxy
43
+ ATTRIBUTES = TabItemProxy::ATTRIBUTES + %w[foreground selection_foreground show_close font]
44
+
45
+ def attributes
46
+ ATTRIBUTES
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -64,14 +64,30 @@ module Glimmer
64
64
  respond_to?(method_name)
65
65
  end
66
66
 
67
+ def can_add_observer?(attribute_name)
68
+ @styled_text_proxy&.can_add_observer?(attribute_name) || super
69
+ end
70
+
71
+ def add_observer(observer, attribute_name)
72
+ if @styled_text_proxy&.can_add_observer?(attribute_name)
73
+ @styled_text_proxy.add_observer(observer, attribute_name)
74
+ else
75
+ super
76
+ end
77
+ end
78
+
67
79
  def can_handle_observation_request?(observation_request)
68
- @styled_text_proxy.can_handle_observation_request?(observation_request)
80
+ @styled_text_proxy&.can_handle_observation_request?(observation_request) || super
69
81
  rescue
70
82
  super
71
83
  end
72
-
84
+
73
85
  def handle_observation_request(observation_request, &block)
74
- @styled_text_proxy.handle_observation_request(observation_request, &block)
86
+ if @styled_text_proxy&.can_handle_observation_request?(observation_request)
87
+ @styled_text_proxy.handle_observation_request(observation_request, &block)
88
+ else
89
+ super
90
+ end
75
91
  rescue
76
92
  super
77
93
  end
@@ -572,7 +572,7 @@ module Glimmer
572
572
  end
573
573
 
574
574
  def dispose(dispose_images: true, dispose_patterns: true, redraw: true)
575
- shapes.each { |shape| shape.is_a?(Shape::Path) && shape.dispose }
575
+ shapes.each { |shape| shape.is_a?(Shape::Path) && shape.dispose } # TODO look into why I'm only disposing paths
576
576
  if dispose_patterns
577
577
  @background_pattern&.dispose
578
578
  @background_pattern = nil
@@ -587,6 +587,20 @@ module Glimmer
587
587
  drawable.redraw if redraw && !drawable.is_a?(ImageProxy)
588
588
  end
589
589
 
590
+ # clear all shapes
591
+ # indicate whether to dispose images, dispose patterns, and redraw after clearing shapes.
592
+ # redraw can be `:all` or `true` to mean redraw after all shapes are disposed, `:each` to mean redraw after each shape is disposed, or `false` to avoid redraw altogether
593
+ def clear_shapes(dispose_images: true, dispose_patterns: true, redraw: :all)
594
+ if redraw == true || redraw == :all
595
+ shapes.dup.each {|shape| shape.dispose(dispose_images: dispose_images, dispose_patterns: dispose_patterns, redraw: false) }
596
+ drawable.redraw if redraw && !drawable.is_a?(ImageProxy)
597
+ elsif redraw == :each
598
+ shapes.dup.each {|shape| shape.dispose(dispose_images: dispose_images, dispose_patterns: dispose_patterns, redraw: true) }
599
+ else
600
+ shapes.dup.each {|shape| shape.dispose(dispose_images: dispose_images, dispose_patterns: dispose_patterns, redraw: false) }
601
+ end
602
+ end
603
+
590
604
  # Indicate if this is a container shape (meaning a shape bag that is just there to contain nested shapes, but doesn't render anything of its own)
591
605
  def container?
592
606
  @name == 'shape'
@@ -20,6 +20,7 @@
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
22
  require 'glimmer/swt/widget_proxy'
23
+ require 'glimmer/swt/color_proxy'
23
24
 
24
25
  module Glimmer
25
26
  module SWT
@@ -27,6 +28,11 @@ module Glimmer
27
28
  #
28
29
  # Follows the Proxy Design Pattern
29
30
  class SashFormProxy < WidgetProxy
31
+ def initialize(*args, &block)
32
+ super
33
+ self.background = ColorProxy.new(230, 230, 230).swt_color
34
+ end
35
+
30
36
  def post_add_content
31
37
  self.weights = @weights unless @weights.nil?
32
38
  end
@@ -74,7 +74,9 @@ module Glimmer
74
74
  # TODO make this an option not the default
75
75
  shell_swt_display = Glimmer::SWT::DisplayProxy.instance.swt_display
76
76
  on_swt_show do
77
- @swt_widget.set_size(@display.bounds.width, @display.bounds.height) if fill_screen
77
+ if @filled_screen.nil? && fill_screen # only the first time
78
+ @swt_widget.set_size(@display.bounds.width, @display.bounds.height)
79
+ end
78
80
  Thread.new do
79
81
  sleep(0.25)
80
82
  shell_swt_display.async_exec do
@@ -48,5 +48,6 @@ module Glimmer
48
48
  end
49
49
  end
50
50
  end
51
+ CTabFolderProxy = TabFolderProxy
51
52
  end
52
53
  end
@@ -39,44 +39,40 @@ module Glimmer
39
39
  #
40
40
  # Follows the Proxy Design Pattern
41
41
  class TabItemProxy < WidgetProxy
42
- ATTRIBUTES = %w[text image]
42
+ ATTRIBUTES = %w[text image tool_tip_text]
43
43
  include_package 'org.eclipse.swt.widgets'
44
44
 
45
45
  attr_reader :widget_proxy, :swt_tab_item
46
46
 
47
47
  def initialize(parent, style, &contents)
48
48
  super("composite", parent, style, &contents)
49
- @widget_proxy = SWT::WidgetProxy.new('tab_item', parent, style)
49
+ keyword = self.class.name.split('::').last.underscore.sub('_proxy', '')
50
+ @widget_proxy = SWT::WidgetProxy.new(keyword, parent, style)
50
51
  @swt_tab_item = @widget_proxy.swt_widget
51
52
  @swt_tab_item.control = swt_widget
52
- # parent.pack # TODO auto fix the tab folder to avoid having to do this manually (including maintaining bounds and minimum size of shell)
53
+ end
54
+
55
+ def attributes
56
+ ATTRIBUTES
53
57
  end
54
58
 
55
59
  def has_attribute?(attribute_name, *args)
56
- if ATTRIBUTES.include?(attribute_name.to_s)
57
- true
58
- else
59
- super(attribute_name, *args)
60
- end
60
+ attributes.include?(attribute_name.to_s) || super(attribute_name, *args)
61
61
  end
62
62
 
63
63
  def set_attribute(attribute_name, *args)
64
- attribute_name
65
- if attribute_name.to_s == "text"
66
- text_value = args[0]
67
- @swt_tab_item.setText text_value
68
- elsif attribute_name.to_s == "image"
69
- widget_proxy.set_attribute('image', *args)
64
+ attribute_name = attribute_name.to_s
65
+ if attributes.include?(attribute_name)
66
+ widget_proxy.set_attribute(attribute_name, *args)
70
67
  else
71
68
  super(attribute_name, *args)
72
69
  end
73
70
  end
74
71
 
75
72
  def get_attribute(attribute_name)
76
- if attribute_name.to_s == "text"
77
- @swt_tab_item.getText
78
- elsif attribute_name.to_s == "image"
79
- widget_proxy.get_attribute('image')
73
+ attribute_name = attribute_name.to_s
74
+ if attributes.include?(attribute_name)
75
+ widget_proxy.get_attribute(attribute_name)
80
76
  else
81
77
  super(attribute_name)
82
78
  end
@@ -89,6 +85,9 @@ module Glimmer
89
85
  swt_tab_item.dispose
90
86
  end
91
87
  end
88
+
92
89
  end
90
+
93
91
  end
92
+
94
93
  end
@@ -51,6 +51,7 @@ module Glimmer
51
51
  'arrow' => [:arrow],
52
52
  'button' => [:push],
53
53
  'canvas' => ([:double_buffered] unless OS.mac?),
54
+ 'ccombo' => [:border],
54
55
  'checkbox' => [:check],
55
56
  'check' => [:check],
56
57
  'drag_source' => [:drop_copy],
@@ -339,6 +340,13 @@ module Glimmer
339
340
  }
340
341
  end,
341
342
  },
343
+ Java::OrgEclipseSwtCustom::CCombo => {
344
+ :text => lambda do |observer|
345
+ on_modify_text { |modify_event|
346
+ observer.call(@swt_widget.getText)
347
+ }
348
+ end,
349
+ },
342
350
  Java::OrgEclipseSwtWidgets::Table => {
343
351
  :selection => lambda do |observer|
344
352
  on_widget_selected { |selection_event|
@@ -985,6 +993,7 @@ module Glimmer
985
993
  !!value
986
994
  end,
987
995
  foreground: color_converter,
996
+ selection_foreground: color_converter,
988
997
  link_foreground: color_converter,
989
998
  font: lambda do |value|
990
999
  if value.is_a?(Hash) || value.is_a?(FontData)
@@ -56,7 +56,7 @@ class Mandelbrot
56
56
  end
57
57
 
58
58
  def processor_count
59
- @processor_count ||= Concurrent.physical_processor_count
59
+ @processor_count ||= Concurrent.processor_count
60
60
  end
61
61
  end
62
62
 
@@ -103,7 +103,7 @@ class Mandelbrot
103
103
  puts "Points calculated already. Returning previously calculated points..."
104
104
  return @points
105
105
  end
106
- thread_pool = Concurrent::FixedThreadPool.new(Mandelbrot.processor_count, fallback_policy: :discard)
106
+ @thread_pool = Concurrent::FixedThreadPool.new(Mandelbrot.processor_count, fallback_policy: :discard)
107
107
  @points = Concurrent::Array.new(height)
108
108
  Mandelbrot.work_in_progress = "Calculating Mandelbrot Points for Zoom #{zoom}x"
109
109
  Mandelbrot.progress = 0
@@ -112,15 +112,15 @@ class Mandelbrot
112
112
  height.times do |y|
113
113
  @points[y] ||= Concurrent::Array.new(width)
114
114
  width.times do |x|
115
- thread_pool.post do
115
+ @thread_pool.post do
116
116
  @points[y][x] = calculate(x_array[x], y_array[y]).last
117
117
  point_index += 1
118
118
  Mandelbrot.progress += 1 if (point_index.to_f / point_count.to_f)*PROGRESS_MAX >= Mandelbrot.progress
119
119
  end
120
120
  end
121
121
  end
122
- thread_pool.shutdown
123
- thread_pool.wait_for_termination
122
+ @thread_pool.shutdown
123
+ @thread_pool.wait_for_termination
124
124
  Mandelbrot.progress = PROGRESS_MAX
125
125
  @points_calculated = true
126
126
  @points
@@ -164,7 +164,7 @@ class MandelbrotFractal
164
164
  }
165
165
  # pre-calculate zoomed mandelbrot images even before the user zooms in
166
166
  puts 'Starting background calculation thread...'
167
- Thread.new {
167
+ @thread = Thread.new {
168
168
  future_zoom = 1.5
169
169
  loop {
170
170
  puts "Creating mandelbrot for background calculation at zoom: #{future_zoom}"
@@ -183,6 +183,11 @@ class MandelbrotFractal
183
183
  text bind(self, :mandelbrot_shell_title)
184
184
  minimum_size mandelbrot.width + 29, mandelbrot.height + 77
185
185
  image @mandelbrot_image
186
+
187
+ on_shell_closed {
188
+ @thread.kill # should not be dangerous in this case
189
+ puts "Mandelbrot background calculation stopped!"
190
+ }
186
191
 
187
192
  progress_bar {
188
193
  layout_data :fill, :center, true, false
@@ -268,8 +268,10 @@ class MetaSampleApplication
268
268
  root {
269
269
  grid_layout(2, false) {
270
270
  horizontal_spacing 0
271
- margin_width 0
272
- margin_height 0
271
+ margin_left 0
272
+ margin_right 0
273
+ margin_top 0
274
+ margin_bottom 0
273
275
  }
274
276
  }
275
277
  line_numbers {
@@ -69,7 +69,7 @@ class Metronome
69
69
  }
70
70
 
71
71
  body {
72
- shell {
72
+ shell(:no_resize) {
73
73
  row_layout(:vertical) {
74
74
  center true
75
75
  }
@@ -110,13 +110,13 @@ class StockTicker
110
110
  tab[:canvas].set_size(new_x_location, @tabs.first[:canvas].bounds.height)
111
111
  tab[:canvas].cursor = :hand
112
112
  tab[:scrolled_composite].set_min_size(new_x_location, @tabs.first[:canvas].bounds.height)
113
- tab[:scrolled_composite].set_origin(tab[:scrolled_composite].origin.x + 1, tab[:scrolled_composite].origin.y) if (tab[:scrolled_composite].origin.x + tab[:scrolled_composite].client_area.width) == canvas_width
113
+ tab[:scrolled_composite].set_origin(tab[:scrolled_composite].origin.x + 1, tab[:scrolled_composite].origin.y) if (tab[:scrolled_composite].origin.x + tab[:scrolled_composite].client_area.width + (OS.mac? ? 0 : 20)) == canvas_width
114
114
  end
115
115
  else
116
116
  tab[:canvas_header].content {
117
117
  text(stock.name, 15, new_y - 10) {
118
118
  foreground @stock_colors[stock_index]
119
- font height: 14
119
+ font height: 13
120
120
  }
121
121
  }
122
122
  end
@@ -0,0 +1,68 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer-dsl-swt'
23
+
24
+ class HelloCCombo
25
+ class Person
26
+ attr_accessor :country, :country_options
27
+
28
+ def initialize
29
+ self.country_options = ['', 'Canada', 'US', 'Mexico']
30
+ reset_country!
31
+ end
32
+
33
+ def reset_country!
34
+ self.country = 'Canada'
35
+ end
36
+ end
37
+
38
+ include Glimmer::UI::CustomShell
39
+
40
+ before_body {
41
+ @person = Person.new
42
+ }
43
+
44
+ body {
45
+ shell {
46
+ row_layout(:vertical) {
47
+ fill true
48
+ }
49
+
50
+ text 'Hello, C Combo!'
51
+
52
+ c_combo(:read_only) {
53
+ selection bind(@person, :country) # also binds to country_options by convention
54
+ font height: 45 # unlike `combo`, `c_combo` changes height when setting the font height
55
+ }
56
+
57
+ button {
58
+ text 'Reset Selection'
59
+
60
+ on_widget_selected do
61
+ @person.reset_country!
62
+ end
63
+ }
64
+ }
65
+ }
66
+ end
67
+
68
+ HelloCCombo.launch
@@ -0,0 +1,173 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ # Country flag images were made by [Freepik](https://www.flaticon.com/authors/freepik) from [www.flaticon.com](http://www.flaticon.com)
23
+
24
+ require 'glimmer-dsl-swt'
25
+
26
+ class HelloCTab
27
+ include Glimmer::UI::CustomShell
28
+
29
+ body {
30
+ shell {
31
+ row_layout
32
+ text 'Hello, C Tab!'
33
+ minimum_size 200, 200
34
+
35
+ c_tab_folder { # accepts styles: :close, :top, :bottom, :flat, :border, :single, :multi
36
+ layout_data {
37
+ width 1024
38
+ height 200
39
+ }
40
+ c_tab_item(:close) {
41
+ text 'English'
42
+ tool_tip_text 'English Greeting'
43
+ foreground :blue
44
+ selection_foreground :dark_blue
45
+ font name: 'Times New Roman', height: 30, style: [:bold, :italic]
46
+ image File.expand_path('hello_c_tab/usa.png', __dir__)
47
+
48
+ label {
49
+ text 'Hello, World!'
50
+ font name: 'Times New Roman', height: 90, style: [:bold, :italic]
51
+ }
52
+ }
53
+
54
+ c_tab_item(:close) {
55
+ text 'French'
56
+ tool_tip_text 'French Greeting'
57
+ foreground :blue
58
+ selection_foreground :dark_blue
59
+ font name: 'Times New Roman', height: 30, style: [:bold, :italic]
60
+ image File.expand_path('hello_c_tab/france.png', __dir__)
61
+
62
+ label {
63
+ text 'Bonjour, Univers!'
64
+ font name: 'Times New Roman', height: 90, style: [:bold, :italic]
65
+ }
66
+ }
67
+
68
+ c_tab_item(:close) {
69
+ text 'Spanish'
70
+ tool_tip_text 'Spanish Greeting'
71
+ foreground :blue
72
+ selection_foreground :dark_blue
73
+ font name: 'Times New Roman', height: 30, style: [:bold, :italic]
74
+ image File.expand_path('hello_c_tab/mexico.png', __dir__)
75
+
76
+ label {
77
+ text 'Hola, Mundo!'
78
+ font name: 'Times New Roman', height: 90, style: [:bold, :italic]
79
+ }
80
+ }
81
+
82
+ c_tab_item(:close) {
83
+ text 'German'
84
+ tool_tip_text 'German Greeting'
85
+ foreground :blue
86
+ selection_foreground :dark_blue
87
+ font name: 'Times New Roman', height: 30, style: [:bold, :italic]
88
+ image File.expand_path('hello_c_tab/germany.png', __dir__)
89
+
90
+ label {
91
+ text 'Hallo, Welt!'
92
+ font name: 'Times New Roman', height: 90, style: [:bold, :italic]
93
+ }
94
+ }
95
+
96
+ c_tab_item(:close) {
97
+ text 'Italian'
98
+ tool_tip_text 'Italian Greeting'
99
+ foreground :blue
100
+ selection_foreground :dark_blue
101
+ font name: 'Times New Roman', height: 30, style: [:bold, :italic]
102
+ image File.expand_path('hello_c_tab/italy.png', __dir__)
103
+
104
+ label {
105
+ text 'Ciao, Mondo!'
106
+ font name: 'Times New Roman', height: 90, style: [:bold, :italic]
107
+ }
108
+ }
109
+
110
+ c_tab_item(:close) {
111
+ text 'Dutch'
112
+ tool_tip_text 'Dutch Greeting'
113
+ foreground :blue
114
+ selection_foreground :dark_blue
115
+ font name: 'Times New Roman', height: 30, style: [:bold, :italic]
116
+ image File.expand_path('hello_c_tab/netherlands.png', __dir__)
117
+
118
+ label {
119
+ text 'Hallo, Wereld!'
120
+ font name: 'Times New Roman', height: 90, style: [:bold, :italic]
121
+ }
122
+ }
123
+
124
+ c_tab_item(:close) {
125
+ text 'Danish'
126
+ tool_tip_text 'Danish Greeting'
127
+ foreground :blue
128
+ selection_foreground :dark_blue
129
+ font name: 'Times New Roman', height: 30, style: [:bold, :italic]
130
+ image File.expand_path('hello_c_tab/denmark.png', __dir__)
131
+
132
+ label {
133
+ text 'Hej, Verden!'
134
+ font name: 'Times New Roman', height: 90, style: [:bold, :italic]
135
+ }
136
+ }
137
+
138
+ c_tab_item(:close) {
139
+ text 'Finnish'
140
+ tool_tip_text 'Finnish Greeting'
141
+ foreground :blue
142
+ selection_foreground :dark_blue
143
+ font name: 'Times New Roman', height: 30, style: [:bold, :italic]
144
+ image File.expand_path('hello_c_tab/finland.png', __dir__)
145
+
146
+ label {
147
+ text 'Hei, Maailma!'
148
+ font name: 'Times New Roman', height: 90, style: [:bold, :italic]
149
+ }
150
+ }
151
+
152
+ c_tab_item(:close) {
153
+ text 'Norwegian'
154
+ tool_tip_text 'Norwegian Greeting'
155
+ foreground :blue
156
+ selection_foreground :dark_blue
157
+ font name: 'Times New Roman', height: 30, style: [:bold, :italic]
158
+ image File.expand_path('hello_c_tab/norway.png', __dir__)
159
+
160
+ label {
161
+ text 'Hei, Verden!'
162
+ font name: 'Times New Roman', height: 90, style: [:bold, :italic]
163
+ }
164
+ }
165
+
166
+ }
167
+
168
+ }
169
+
170
+ }
171
+ end
172
+
173
+ HelloCTab.launch