glimmer 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb4ee177a1d05942e3d76fd1af52f2d182a8141ffe70c2d15edb868d1c117f4c
4
- data.tar.gz: 26302fbf093855d4c789431752d79b7bfd07e9a763538215cf8aebacbf3bb51f
3
+ metadata.gz: 701abba7777511f578fbf87500a857650e1b5a50fff35ef92ea34be36548d3c4
4
+ data.tar.gz: 2d6d523bfef6b75de1b820321d64c0f3c3208afe0ad21c274e66f9a74d59bd93
5
5
  SHA512:
6
- metadata.gz: c182686702c73057df5d04454804950002a63e58f9be27aeab6142bec34ae6aad35306390ed9d4978a9d235ee1cbb7b7b465126f4986163139d2e8781127bb6e
7
- data.tar.gz: 4a6137b7b492595072795dcd641d7d1c9d1e9ef5da42e66397604249ab021d24645dc73faa321d645d2d51507899235134ab3eaa2b39d342b3514f6111d30e52
6
+ metadata.gz: f1d4cda6b63ee73a5ff2b068979fd79b4f2fb3a30581b7b13bb9686383a485fbe2f1e5afb6c1d486f37e8302badbfae1c14390d1f8a2f4f62031bce21e3fafb7
7
+ data.tar.gz: 8f1fa157a4326a6b0499584473678d45f7141b992274a64705cccd0b64ec326337c67c6165f252eb4a98872692b56ec76004e4e5372910cdb37bf08cffe23a1b
@@ -38,13 +38,13 @@ Glimmer code (from `samples/tictactoe/tic_tac_toe.rb`):
38
38
  shell {
39
39
  text "Tic-Tac-Toe"
40
40
  composite {
41
- layout GridLayout.new(3,true)
41
+ grid_layout 3, true
42
42
  (1..3).each { |row|
43
43
  (1..3).each { |column|
44
44
  button {
45
- layout_data GridData.new(GSWT[:fill], GSWT[:fill], true, true)
46
- text bind(@tic_tac_toe_board.box(row, column), :sign)
47
- enabled bind(@tic_tac_toe_board.box(row, column), :empty)
45
+ layout_data :fill, :fill, true, true
46
+ text bind(@tic_tac_toe_board[row, column], :sign)
47
+ enabled bind(@tic_tac_toe_board[row, column], :empty)
48
48
  on_widget_selected {
49
49
  @tic_tac_toe_board.mark_box(row, column)
50
50
  }
@@ -102,14 +102,14 @@ Please follow these instructions to make the `glimmer` command available on your
102
102
 
103
103
  Run this command to install directly:
104
104
  ```
105
- jgem install glimmer -v 0.4.1
105
+ jgem install glimmer -v 0.4.2
106
106
  ```
107
107
 
108
108
  ### Option 2: Bundler
109
109
 
110
110
  Add the following to `Gemfile`:
111
111
  ```
112
- gem 'glimmer', '~> 0.4.1'
112
+ gem 'glimmer', '~> 0.4.2'
113
113
  ```
114
114
 
115
115
  And, then run:
@@ -141,7 +141,7 @@ Glimmer UIs (user interfaces) are modeled with widgets (wrappers around the SWT
141
141
 
142
142
  In Glimmer DSL, widgets are declared with lowercase underscored naming (you may look at usage examples in the `samples` directory).
143
143
 
144
- The `shell` widget is always the outermost widget containing all others in a desktop windowed application.
144
+ The `shell` widget is always the outermost widget containing all others in a desktop windowed application. It is centered upon initial display and has a minimum width of 130 (can be re-centered when needed with `@shell.center` method)
145
145
 
146
146
  Other widget examples:
147
147
  - `button`: wrapper for `org.eclipse.swt.widgets.Button`
@@ -200,7 +200,7 @@ You may check out all available `SWT` styles here:
200
200
 
201
201
  https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
202
202
 
203
- **Final Note** (advanced case outside of standard Glimmer DSL):
203
+ **Note** (advanced case outside of standard Glimmer DSL):
204
204
 
205
205
  When building a widget-related SWT object manually (e.g. `GridData.new(...)`), you are expected to use `SWT::CONSTANT` directly or BIT-OR a few SWT constants together like `SWT::BORDER | SWT::V_SCROLL`.
206
206
 
@@ -236,11 +236,11 @@ In the above example, the `text` widget `enabled` property was data-bound to `#e
236
236
  Glimmer lays widgets out visually using SWT layouts, which can only be set on composite widget and subclasses.
237
237
 
238
238
  The most common SWT layouts are:
239
- - `FillLayout`: lays widgets out in equal proportion horizontally or vertically with spacing/margin options
239
+ - `FillLayout`: lays widgets out in equal proportion horizontally or vertically with spacing/margin options. This is the ***default*** layout for ***shell*** (with `:horizontal` option) in Glimmer.
240
240
  - `RowLayout`: lays widgets out horizontally or vertically in varying proportions with advanced spacing/margin/justify options
241
- - `GridLayout`(**default**): lays widgets out in a grid with advanced spacing/margin/alignment/indentation options. This is the **default** layout in Glimmer. It is important to master.
241
+ - `GridLayout`: lays widgets out in a grid with advanced spacing/margin/alignment/indentation options. This is the **default** layout for **composite** in Glimmer. It is important to master.
242
242
 
243
- In Glimmer DSL, just like widgets, layouts can be specified with lowercase underscored names followed by a block containing properties (e.g. `RowLayout` is `row_layout`).
243
+ In Glimmer DSL, just like widgets, layouts can be specified with lowercase underscored names followed by a block containing properties, also lowercase underscored names (e.g. `RowLayout` is `row_layout`).
244
244
 
245
245
  Example:
246
246
 
@@ -261,15 +261,70 @@ composite {
261
261
  }
262
262
  ```
263
263
 
264
- Alternatively, a layout may be constructed by following the SWT API for the layout object. For example, a `RowLayout` can be constructed by passing it an SWT style constant.
264
+ Alternatively, a layout may be constructed by following the SWT API for the layout object. For example, a `RowLayout` can be constructed by passing it an SWT style constant (Glimmer automatically accepts symbols (e.g. `:horizontal`) for SWT style arguments like `SWT::HORIZONTAL`.)
265
265
 
266
266
  ```ruby
267
267
  composite {
268
- row_layout(:horizontal)
268
+ row_layout :horizontal
269
269
  # ... widgets follow
270
270
  }
271
271
  ```
272
272
 
273
+ Here is a more sophisticated example taken from [hello_computed.rb](https://github.com/AndyObtiva/glimmer/blob/master/samples/hellocomputed/hello_computed.rb) sample:
274
+ ```ruby
275
+ shell {
276
+ text "Hello Computed"
277
+ composite {
278
+ grid_layout {
279
+ num_columns 2
280
+ make_columns_equal_width true
281
+ horizontal_spacing 20
282
+ vertical_spacing 10
283
+ }
284
+ label {text "First &Name: "}
285
+ text {
286
+ text bind(@contact, :first_name)
287
+ layout_data {
288
+ horizontalAlignment :fill
289
+ grabExcessHorizontalSpace true
290
+ }
291
+ }
292
+ label {text "&Last Name: "}
293
+ text {
294
+ text bind(@contact, :last_name)
295
+ layout_data {
296
+ horizontalAlignment :fill
297
+ grabExcessHorizontalSpace true
298
+ }
299
+ }
300
+ label {text "&Year of Birth: "}
301
+ text {
302
+ text bind(@contact, :year_of_birth)
303
+ layout_data {
304
+ horizontalAlignment :fill
305
+ grabExcessHorizontalSpace true
306
+ }
307
+ }
308
+ label {text "Name: "}
309
+ label {
310
+ text bind(@contact, :name, computed_by: [:first_name, :last_name])
311
+ layout_data {
312
+ horizontalAlignment :fill
313
+ grabExcessHorizontalSpace true
314
+ }
315
+ }
316
+ label {text "Age: "}
317
+ label {
318
+ text bind(@contact, :age, :fixnum, computed_by: [:year_of_birth])
319
+ layout_data {
320
+ horizontalAlignment :fill
321
+ grabExcessHorizontalSpace true
322
+ }
323
+ }
324
+ }
325
+ }.open
326
+ ```
327
+
273
328
  Check out the samples directory for more advanced examples of layouts in Glimmer.
274
329
 
275
330
  **Defaults**:
@@ -296,13 +351,17 @@ By convention, SWT layouts expect widgets to set layout data with a class matchi
296
351
 
297
352
  Not all layouts support layout data to further customize widget layouts. For example, `FillLayout` supports no layout data.
298
353
 
299
- Unlike widgets and layouts in Glimmer DSL, layout data is simply specified with `layout_data` keyword nested inside a widget block body, and followed by arguments and/or a block of its own properties. Glimmer automatically deduces layout data class name by convention as per rule above, with the assumption that the layout data class lives under the same exact Java package as the layout (one can set custom layout data that breaks convention if needed in rare cases. See code below for an example)
354
+ Unlike widgets and layouts in Glimmer DSL, layout data is simply specified with `layout_data` keyword nested inside a widget block body, and followed by arguments and/or a block of its own properties (lowercase underscored names).
355
+
356
+ Glimmer automatically deduces layout data class name by convention as per rule above, with the assumption that the layout data class lives under the same exact Java package as the layout (one can set custom layout data that breaks convention if needed in rare cases. See code below for an example)
357
+
358
+ Glimmer also automatically accepts symbols (e.g. `:fill`) for SWT style arguments like `SWT::FILL`.
300
359
 
301
360
  Examples:
302
361
 
303
362
  ```ruby
304
363
  composite {
305
- row_layout(:horizontal)
364
+ row_layout :horizontal
306
365
  label {
307
366
  layout_data { # followed by properties
308
367
  width 50
@@ -315,17 +374,17 @@ composite {
315
374
 
316
375
  ```ruby
317
376
  composite {
318
- grid_layout(3, false) # grid layout with 3 columns not of equal width
377
+ grid_layout 3, false # grid layout with 3 columns not of equal width
319
378
  label {
320
- # layout data followed by arguments passed to SWT constructor
321
- layout_data(GSWT[:fill], GSWT[:end], true, false)
379
+ # layout data followed by arguments passed to SWT GridData constructor
380
+ layout_data :fill, :end, true, false
322
381
  }
323
382
  }
324
383
  ```
325
384
 
326
385
  ```ruby
327
386
  composite {
328
- grid_layout(3, false) # grid layout with 3 columns not of equal width
387
+ grid_layout 3, false # grid layout with 3 columns not of equal width
329
388
  label {
330
389
  # layout data set explicitly via an object (helps in rare cases that break convention)
331
390
  layout_data GridData.new(GSWT[:fill], GSWT[:end], true, false)
@@ -437,7 +496,7 @@ class TicTacToe
437
496
 
438
497
  def initialize
439
498
  # ...
440
- observe(@tic_tac_toe_board, "game_status")
499
+ observe(@tic_tac_toe_board, :game_status)
441
500
  end
442
501
 
443
502
  def call(game_status)
@@ -448,10 +507,10 @@ class TicTacToe
448
507
  end
449
508
  ```
450
509
 
451
- Alternatively, one can use a default Observer::Proc implementation via Observer#proc method:
510
+ Alternatively, one can use a default Observer::Proc implementation via Observer.proc method:
452
511
  ```ruby
453
512
  observer = Observer.proc { |new_value| puts new_value }
454
- observer.observe(@tic_tac_toe_board, "game_status")
513
+ observer.observe(@tic_tac_toe_board, :game_status)
455
514
  ```
456
515
 
457
516
  Observers can be a good mechanism for displaying dialog messages with Glimmer (using SWT's `MessageBox`).
@@ -465,7 +524,7 @@ class TicTacToe
465
524
 
466
525
  def initialize
467
526
  # ...
468
- observe(@tic_tac_toe_board, "game_status")
527
+ observe(@tic_tac_toe_board, :game_status)
469
528
  end
470
529
 
471
530
  def call(game_status)
@@ -494,7 +553,7 @@ end
494
553
 
495
554
  ## Samples
496
555
 
497
- Check the "samples" folder for examples on how to write Glimmer applications. To run them, make sure to install the `glimmer` gem first and then use the `glimmer` command.
556
+ Check the "[samples](https://github.com/AndyObtiva/glimmer/tree/master/samples)" folder for examples on how to write Glimmer applications. To run a sample, make sure to install the `glimmer` gem first and then use the `glimmer` command to run it (alternatively, you may clone the repo, follow contributing instructions, and run `rake install` to install the gem before running `glimmer` command).
498
557
 
499
558
  Example:
500
559
 
@@ -502,6 +561,10 @@ Example:
502
561
  glimmer samples/hello_world.rb
503
562
  ```
504
563
 
564
+ Here is also a more elaborate project (educational game) built with Glimmer:
565
+
566
+ [Math Bowling](https://github.com/AndyObtiva/MathBowling)
567
+
505
568
  ## SWT Reference
506
569
 
507
570
  https://www.eclipse.org/swt/docs.php
data/bin/girb CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
2
  require_relative '../lib/glimmer_application'
3
- GlimmerApplication.launch('irb')
3
+ GlimmerApplication.new(ARGV + ['irb']).start
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require_relative File.join('..', 'lib', 'glimmer_application')
4
- GlimmerApplication.new(ARGV.first).start
4
+ GlimmerApplication.new(ARGV).start
@@ -35,6 +35,7 @@ module Glimmer
35
35
  return return_value
36
36
  end
37
37
 
38
+ # TODO come up with a better public name for this and put on gwidgets directly
38
39
  def self.add_contents(parent, &block)
39
40
  @@parent_stack.push(parent) if parent.is_a?(Parent)
40
41
  @@parent_stack.last.process_block(block) if block and @@parent_stack.last
@@ -39,7 +39,7 @@ module Glimmer
39
39
  def initialize(underscored_layout_name, composite, args)
40
40
  @underscored_layout_name = underscored_layout_name
41
41
  @composite = composite
42
- args = args.map {|arg| GSWT.constant(arg)}
42
+ args = GSWT.constantify_args(args)
43
43
  @layout = self.class.swt_layout_class_for(underscored_layout_name).new(*args)
44
44
  @composite.setLayout(@layout)
45
45
  end
@@ -12,7 +12,7 @@ module Glimmer
12
12
 
13
13
  def initialize(widget, args)
14
14
  @widget = widget
15
- args = args.map {|arg| GSWT.constant(arg)}
15
+ args = GSWT.constantify_args(args)
16
16
  begin
17
17
  @layout_data = swt_layout_data_class.new(*args)
18
18
  rescue => e
@@ -3,19 +3,41 @@ require_relative 'g_display'
3
3
 
4
4
  module Glimmer
5
5
  class GShell < GWidget
6
+ WIDTH_MIN = 130
7
+ HEIGHT_MIN = 0
8
+
6
9
  include_package 'org.eclipse.swt.layout'
7
10
  include_package 'org.eclipse.swt.widgets'
8
11
 
9
12
  attr_reader :display
10
13
 
11
- def initialize(display = GDisplay.instance.display)
12
- @display = display
13
- @widget = Shell.new(@display)
14
+ # Instantiates shell with same arguments expected by SWT Shell
15
+ def initialize(*args)
16
+ if !args.first.is_a?(Display) && !args.first.is_a?(Shell)
17
+ @display = GDisplay.instance.display
18
+ args = [@display] + args
19
+ end
20
+ args = GSWT.constantify_args(args)
21
+ @widget = Shell.new(*args)
22
+ @display ||= @widget.getDisplay
14
23
  @widget.setLayout(FillLayout.new)
24
+ @widget.setMinimumSize(WIDTH_MIN, HEIGHT_MIN)
25
+ end
26
+
27
+ # Centers shell within screen
28
+ def center
29
+ primary_monitor = @display.getPrimaryMonitor()
30
+ monitor_bounds = primary_monitor.getBounds()
31
+ shell_bounds = @widget.getBounds()
32
+ location_x = monitor_bounds.x + (monitor_bounds.width - shell_bounds.width) / 2
33
+ location_y = monitor_bounds.y + (monitor_bounds.height - shell_bounds.height) / 2
34
+ @widget.setLocation(location_x, location_y)
15
35
  end
16
36
 
37
+ # Opens shell and starts SWT's UI thread event loop
17
38
  def open
18
39
  @widget.pack
40
+ center
19
41
  @widget.open
20
42
  until @widget.isDisposed
21
43
  @display.sleep unless @display.readAndDispatch
@@ -11,19 +11,29 @@ module Glimmer
11
11
 
12
12
  def constant(symbol)
13
13
  return symbol unless symbol.is_a?(Symbol) || symbol.is_a?(String)
14
- swt_constant_symbol = symbol.to_s.upcase.to_sym
14
+ symbol_string = symbol.to_s
15
+ swt_constant_symbol = symbol_string.downcase == symbol_string ? symbol_string.upcase.to_sym : symbol_string.to_sym
15
16
  SWT.const_get(swt_constant_symbol)
16
17
  rescue
17
- swt_constant_symbol = SWT.constants.find {|c| c.to_s.upcase == swt_constant_symbol.to_s}
18
- SWT.const_get(swt_constant_symbol)
18
+ begin
19
+ alternative_swt_constant_symbol = SWT.constants.find {|c| c.to_s.upcase == swt_constant_symbol.to_s}
20
+ SWT.const_get(alternative_swt_constant_symbol)
21
+ rescue
22
+ EXTRA_STYLES[swt_constant_symbol] || symbol
23
+ end
19
24
  end
20
25
 
21
26
  def has_constant?(symbol)
22
27
  return false unless symbol.is_a?(Symbol) || symbol.is_a?(String)
23
- !!constant(symbol)
24
- rescue
25
- false
28
+ constant(symbol).is_a?(Integer)
29
+ end
30
+
31
+ def constantify_args(args)
32
+ args.map {|arg| constant(arg)}
26
33
  end
27
34
  end
35
+ EXTRA_STYLES = {
36
+ NO_RESIZE: GSWT[:shell_trim] & (~GSWT[:resize])
37
+ }
28
38
  end
29
39
  end
@@ -41,6 +41,10 @@ module Glimmer
41
41
  @@default_initializers[underscored_widget_name].call(@widget) if @@default_initializers[underscored_widget_name]
42
42
  end
43
43
 
44
+ def has_style?(swt_style)
45
+ pd(pd(@widget.getStyle) & swt_style) == pd(swt_style)
46
+ end
47
+
44
48
  def has_attribute?(attribute_name, *args)
45
49
  @widget.respond_to?(attribute_setter(attribute_name), args)
46
50
  end
@@ -11,6 +11,8 @@ the glimmer ruby gem and SWT jar dependency.
11
11
  Example: glimmer hello_world.rb
12
12
  This runs the Glimmer application hello_world.rb
13
13
  MULTILINE
14
+ GLIMMER_LIB_LOCAL = File.expand_path(File.join(__FILE__, '..', 'glimmer.rb'))
15
+ GLIMMER_LIB_GEM = 'glimmer'
14
16
 
15
17
  class << self
16
18
  def platform_os
@@ -29,13 +31,19 @@ This runs the Glimmer application hello_world.rb
29
31
  "#{jruby_os_specific_options} -J-classpath \"#{swt_jar_file}\""
30
32
  end
31
33
 
32
- def launch(application)
33
- system "jruby #{jruby_command_options} -r glimmer -S #{application}"
34
+ def launch(application, dev_mode = false)
35
+ glimmer_lib = GLIMMER_LIB_GEM
36
+ if dev_mode
37
+ glimmer_lib = GLIMMER_LIB_LOCAL
38
+ puts "[DEVELOPMENT MODE] (#{glimmer_lib})"
39
+ end
40
+ system "jruby #{jruby_command_options} -r #{glimmer_lib} -S #{application}"
34
41
  end
35
42
  end
36
43
 
37
- def initialize(application_path)
38
- @application_path = application_path
44
+ def initialize(options)
45
+ @dev_mode = !!options.delete('--dev')
46
+ @application_path = options.first
39
47
  end
40
48
 
41
49
  def start
@@ -47,8 +55,8 @@ This runs the Glimmer application hello_world.rb
47
55
  end
48
56
 
49
57
  def launch_application
50
- puts "Launching Glimmer Application: #{@application_path}"
51
- self.class.launch(@application_path)
58
+ puts "Launching Glimmer Application: #{@application_path}" unless @application_path == 'irb'
59
+ self.class.launch(@application_path, @dev_mode)
52
60
  end
53
61
 
54
62
  def display_usage
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-18 00:00:00.000000000 Z
11
+ date: 2020-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement