glimmer-dsl-swt 4.18.7.2 → 4.18.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +4 -4
- data/VERSION +1 -1
- data/glimmer-dsl-swt.gemspec +4 -3
- data/lib/glimmer/swt/custom/shape.rb +359 -195
- data/lib/glimmer/swt/custom/shape/image.rb +7 -9
- data/lib/glimmer/swt/custom/shape/path.rb +1 -5
- data/lib/glimmer/swt/custom/shape/polygon.rb +24 -8
- data/lib/glimmer/swt/custom/shape/polyline.rb +5 -0
- data/lib/glimmer/swt/custom/shape/rectangle.rb +10 -19
- data/samples/elaborate/tetris.rb +1 -12
- data/samples/elaborate/tetris/model/game.rb +3 -0
- data/samples/elaborate/tetris/view/bevel.rb +78 -0
- data/samples/elaborate/tetris/view/block.rb +6 -29
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98ad3496a7f7eec9bebe867be21b6fefd3764baf67b8336a2177086826fc6e0c
|
4
|
+
data.tar.gz: 6093daa8c240d0e02f43078590f84eb77c9cdba070c2c8ba5c7e665fb4455338
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43d3ffa17ae9ad9fae4f867d483439116d0e08055614f83c2ef59f87a38268472ace3821ee6b2521588d02fda8da6a6f009ff9ea93085dc60170835cb6aa4aff
|
7
|
+
data.tar.gz: 0f4bb8712916ddb9ee5cd25ded0bdce6b5fc008f2ab23a53ccac07f19eac556daf4eb3594944e91c3a47efd3df3794012abd572fb6ea17ed74357622a67a5253
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
### 4.18.7.3
|
4
|
+
|
5
|
+
- Support the ability for nested shapes to override their parent `shape` common shared properties
|
6
|
+
- Refactor Tetris to use a custom shape (`bevel`) for its blocks given they are used in both the game and the icon, thus achieving code reuse
|
7
|
+
- Fix issue with moving filled polygon (moving drawn polygon works)
|
8
|
+
|
3
9
|
### 4.18.7.2
|
4
10
|
|
5
11
|
- Enable defining custom shapes with direct args just like basic shapes (alternative to using keyword arg options)
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 4.18.7.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 4.18.7.3
|
2
2
|
## JRuby Desktop Development GUI Framework
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
|
4
4
|
[![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
|
@@ -13,7 +13,7 @@
|
|
13
13
|
[<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
|
14
14
|
Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) and [Chalmers/Gothenburg University Software Engineering Master's Lecture Material](http://www.cse.chalmers.se/~bergert/slides/guest_lecture_DSLs.pdf)
|
15
15
|
|
16
|
-
[Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.18.7.
|
16
|
+
[Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.18.7.3 includes [SWT 4.18](https://download.eclipse.org/eclipse/downloads/drops4/R-4.18-202012021800/), which was released on December 2, 2020. Gem version numbers are in sync with the SWT library versions. The first two digits represent the SWT version number. The last two digits represent the minor and patch versions of Glimmer DSL for SWT.
|
17
17
|
|
18
18
|
[Glimmer DSL for SWT receives two updates per month](https://rubygems.org/gems/glimmer-dsl-swt/versions). You can trust [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) with your Ruby desktop GUI development needs! [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) brings great ideas to the table, such as declarative programming via domain specific languages, currently under-utilized in the GUI domain. That said, it may not be feature complete enough for everybody's needs, so please help make [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) even better by providing feedback and [contributing](#contributing) when possible. The project is very active, so any feature suggestions that are accepted could be implemented within weeks if not days. Also, you are welcome to [hire me](#hire-me) full-time if you want long-term development of [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) for your project needs.
|
19
19
|
|
@@ -340,7 +340,7 @@ jgem install glimmer-dsl-swt
|
|
340
340
|
|
341
341
|
Or this command if you want a specific version:
|
342
342
|
```
|
343
|
-
jgem install glimmer-dsl-swt -v 4.18.7.
|
343
|
+
jgem install glimmer-dsl-swt -v 4.18.7.3
|
344
344
|
```
|
345
345
|
|
346
346
|
`jgem` is JRuby's version of `gem` command.
|
@@ -358,7 +358,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
|
|
358
358
|
|
359
359
|
Add the following to `Gemfile`:
|
360
360
|
```
|
361
|
-
gem 'glimmer-dsl-swt', '~> 4.18.7.
|
361
|
+
gem 'glimmer-dsl-swt', '~> 4.18.7.3'
|
362
362
|
```
|
363
363
|
|
364
364
|
And, then run:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
4.18.7.
|
1
|
+
4.18.7.3
|
data/glimmer-dsl-swt.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer-dsl-swt 4.18.7.
|
5
|
+
# stub: glimmer-dsl-swt 4.18.7.3 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-dsl-swt".freeze
|
9
|
-
s.version = "4.18.7.
|
9
|
+
s.version = "4.18.7.3"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["AndyMaleh".freeze]
|
14
|
-
s.date = "2021-03-
|
14
|
+
s.date = "2021-03-09"
|
15
15
|
s.description = "Glimmer DSL for SWT (JRuby Desktop Development GUI Framework) is a native-GUI cross-platform desktop development library written in JRuby, an OS-threaded faster JVM version of Ruby. Glimmer's main innovation is a declarative Ruby DSL that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust Eclipse SWT library. Glimmer additionally innovates by having built-in data-binding support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models (test-first) afterwards. Not only does Glimmer provide a large set of GUI widgets, but it also supports drawing Canvas Graphics like Shapes and Animations. To get started quickly, Glimmer offers scaffolding options for Apps, Gems, and Custom Widgets. Glimmer also includes native-executable packaging support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in Ruby as truly native DMG/PKG/APP files on the Mac + App Store, MSI/EXE files on Windows, and Gem Packaged Shell Scripts on Linux.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.executables = ["glimmer".freeze, "girb".freeze]
|
@@ -176,6 +176,7 @@ Gem::Specification.new do |s|
|
|
176
176
|
"samples/elaborate/tetris/model/game.rb",
|
177
177
|
"samples/elaborate/tetris/model/past_game.rb",
|
178
178
|
"samples/elaborate/tetris/model/tetromino.rb",
|
179
|
+
"samples/elaborate/tetris/view/bevel.rb",
|
179
180
|
"samples/elaborate/tetris/view/block.rb",
|
180
181
|
"samples/elaborate/tetris/view/high_score_dialog.rb",
|
181
182
|
"samples/elaborate/tetris/view/playfield.rb",
|
@@ -171,7 +171,13 @@ module Glimmer
|
|
171
171
|
|
172
172
|
# The bounding box top-left x, y, width, height in absolute positioning
|
173
173
|
def bounds
|
174
|
-
|
174
|
+
bounds_dependencies = [absolute_x, absolute_y, calculated_width, calculated_height]
|
175
|
+
if bounds_dependencies != @bounds_dependencies
|
176
|
+
# avoid repeating calculations
|
177
|
+
absolute_x, absolute_y, calculated_width, calculated_height = @bounds_dependencies = bounds_dependencies
|
178
|
+
@bounds = org.eclipse.swt.graphics.Rectangle.new(absolute_x, absolute_y, calculated_width, calculated_height)
|
179
|
+
end
|
180
|
+
@bounds
|
175
181
|
end
|
176
182
|
|
177
183
|
# The bounding box top-left x and y
|
@@ -181,7 +187,13 @@ module Glimmer
|
|
181
187
|
|
182
188
|
# The bounding box width and height (as a Point object with x being width and y being height)
|
183
189
|
def size
|
184
|
-
|
190
|
+
size_dependencies = [calculated_width, calculated_height]
|
191
|
+
if size_dependencies != @size_dependencies
|
192
|
+
# avoid repeating calculations
|
193
|
+
calculated_width, calculated_height = @size_dependencies = size_dependencies
|
194
|
+
@size = org.eclipse.swt.graphics.Point.new(calculated_width, calculated_height)
|
195
|
+
end
|
196
|
+
@size
|
185
197
|
end
|
186
198
|
|
187
199
|
def extent
|
@@ -308,10 +320,10 @@ module Glimmer
|
|
308
320
|
end
|
309
321
|
@pattern_args ||= {}
|
310
322
|
pattern_type = method_name.to_s.match(/set(.+)Pattern/)[1]
|
311
|
-
if args.first.is_a?(Pattern)
|
323
|
+
if args.first.is_a?(org.eclipse.swt.graphics.Pattern)
|
312
324
|
new_args = @pattern_args[pattern_type]
|
313
325
|
else
|
314
|
-
new_args = args.first.is_a?(Display) ? args : ([DisplayProxy.instance.swt_display] + args)
|
326
|
+
new_args = args.first.is_a?(org.eclipse.swt.widgets.Display) ? args : ([DisplayProxy.instance.swt_display] + args)
|
315
327
|
@pattern_args[pattern_type] = new_args.dup
|
316
328
|
end
|
317
329
|
args[0] = pattern(*new_args, type: pattern_type)
|
@@ -429,6 +441,10 @@ module Glimmer
|
|
429
441
|
parameter_names.index(attribute_name.to_s.to_sym)
|
430
442
|
end
|
431
443
|
|
444
|
+
def get_parameter_attribute(attribute_name)
|
445
|
+
@args[parameter_index(ruby_attribute_getter(attribute_name))]
|
446
|
+
end
|
447
|
+
|
432
448
|
def set_parameter_attribute(attribute_name, *args)
|
433
449
|
@args[parameter_index(ruby_attribute_getter(attribute_name))] = args.size == 1 ? args.first : args
|
434
450
|
end
|
@@ -444,31 +460,43 @@ module Glimmer
|
|
444
460
|
args.pop if !options.nil? && !options[:redraw].nil?
|
445
461
|
perform_redraw = @perform_redraw
|
446
462
|
perform_redraw = options[:redraw] if perform_redraw.nil? && !options.nil?
|
447
|
-
perform_redraw
|
463
|
+
perform_redraw ||= true
|
464
|
+
property_change = nil
|
465
|
+
ruby_attribute_getter_name = ruby_attribute_getter(attribute_name)
|
466
|
+
ruby_attribute_setter_name = ruby_attribute_setter(attribute_name)
|
448
467
|
if parameter_name?(attribute_name)
|
449
|
-
|
450
|
-
|
451
|
-
|
468
|
+
return if ruby_attribute_getter_name == (args.size == 1 ? args.first : args)
|
469
|
+
set_parameter_attribute(ruby_attribute_getter_name, *args)
|
470
|
+
elsif (respond_to?(attribute_name, super: true) and respond_to?(ruby_attribute_setter_name, super: true))
|
471
|
+
return if self.send(ruby_attribute_getter_name) == (args.size == 1 ? args.first : args)
|
472
|
+
self.send(ruby_attribute_setter_name, *args)
|
452
473
|
else
|
453
|
-
|
474
|
+
# TODO consider this optimization of preconverting args (removing conversion from other methods) to reject equal args
|
475
|
+
args = apply_property_arg_conversions(ruby_attribute_getter_name, args)
|
476
|
+
return if @properties[ruby_attribute_getter_name] == args
|
477
|
+
@properties[ruby_attribute_getter_name] = args
|
478
|
+
property_change = true
|
454
479
|
end
|
455
480
|
if @content_added && perform_redraw && !drawable.is_disposed
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
481
|
+
redrawn = false
|
482
|
+
unless property_change
|
483
|
+
@calculated_paint_args = false
|
484
|
+
if is_a?(PathSegment)
|
485
|
+
root_path&.calculated_path_args = @calculated_path_args = false
|
486
|
+
calculated_args_changed!
|
487
|
+
root_path&.calculated_args_changed!
|
488
|
+
end
|
489
|
+
if location_parameter_names.map(&:to_s).include?(ruby_attribute_getter_name)
|
490
|
+
calculated_args_changed!(children: true)
|
491
|
+
redrawn = parent.calculated_args_changed_for_defaults! if parent.is_a?(Shape)
|
492
|
+
end
|
493
|
+
if ['width', 'height'].include?(ruby_attribute_getter_name)
|
494
|
+
redrawn = calculated_args_changed_for_defaults!
|
495
|
+
end
|
469
496
|
end
|
470
497
|
# TODO consider redrawing an image proxy's gc in the future
|
471
|
-
|
498
|
+
# TODO consider ensuring only a single redraw happens for a hierarchy of nested shapes
|
499
|
+
drawable.redraw unless redrawn || drawable.is_a?(ImageProxy)
|
472
500
|
end
|
473
501
|
end
|
474
502
|
|
@@ -479,7 +507,7 @@ module Glimmer
|
|
479
507
|
elsif (respond_to?(attribute_name, super: true) and respond_to?(ruby_attribute_setter(attribute_name), super: true))
|
480
508
|
self.send(attribute_name)
|
481
509
|
else
|
482
|
-
@properties
|
510
|
+
@properties[attribute_name.to_s]
|
483
511
|
end
|
484
512
|
end
|
485
513
|
|
@@ -555,35 +583,73 @@ module Glimmer
|
|
555
583
|
drawable.redraw if redraw && !drawable.is_a?(ImageProxy)
|
556
584
|
end
|
557
585
|
|
558
|
-
# Indicate if this is a shape
|
559
|
-
def
|
586
|
+
# 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)
|
587
|
+
def container?
|
560
588
|
@name == 'shape'
|
561
589
|
end
|
562
590
|
|
591
|
+
# Indicate if this is a composite shape (meaning a shape that contains nested shapes like a rectangle with ovals inside it)
|
592
|
+
def composite?
|
593
|
+
!shapes.empty?
|
594
|
+
end
|
595
|
+
|
563
596
|
# ordered from closest to farthest parent
|
564
597
|
def parent_shapes
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
598
|
+
if @parent_shapes.nil?
|
599
|
+
if parent.is_a?(Drawable)
|
600
|
+
@parent_shapes = []
|
601
|
+
else
|
602
|
+
@parent_shapes = parent.parent_shapes + [parent]
|
603
|
+
end
|
604
|
+
end
|
605
|
+
@parent_shapes
|
606
|
+
end
|
607
|
+
|
608
|
+
# ordered from closest to farthest parent
|
609
|
+
def parent_shape_containers
|
610
|
+
if @parent_shape_containers.nil?
|
611
|
+
if parent.is_a?(Drawable)
|
612
|
+
@parent_shape_containers = []
|
613
|
+
elsif !parent.container?
|
614
|
+
@parent_shape_containers = parent.parent_shape_containers
|
615
|
+
else
|
616
|
+
@parent_shape_containers = parent.parent_shape_containers + [parent]
|
617
|
+
end
|
570
618
|
end
|
571
|
-
|
619
|
+
@parent_shape_containers
|
572
620
|
end
|
573
621
|
|
574
622
|
# ordered from closest to farthest parent
|
575
623
|
def parent_shape_composites
|
576
|
-
|
624
|
+
if @parent_shape_composites.nil?
|
625
|
+
if parent.is_a?(Drawable)
|
626
|
+
@parent_shape_composites = []
|
627
|
+
elsif !parent.container?
|
628
|
+
@parent_shape_composites = parent.parent_shape_composites
|
629
|
+
else
|
630
|
+
@parent_shape_composites = parent.parent_shape_composites + [parent]
|
631
|
+
end
|
632
|
+
end
|
633
|
+
@parent_shape_composites
|
577
634
|
end
|
578
635
|
|
579
|
-
def
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
parent_properties.each do |property, args|
|
584
|
-
parent_properties[property] = apply_property_arg_conversions(property, args)
|
636
|
+
def convert_properties!
|
637
|
+
if @properties != @converted_properties
|
638
|
+
@properties.each do |property, args|
|
639
|
+
@properties[property] = apply_property_arg_conversions(property, args)
|
585
640
|
end
|
586
|
-
|
641
|
+
@converted_properties = @properties.dup
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
def converted_properties
|
646
|
+
convert_properties!
|
647
|
+
@properties
|
648
|
+
end
|
649
|
+
|
650
|
+
def all_parent_properties
|
651
|
+
@all_parent_properties ||= parent_shape_containers.reverse.reduce({}) do |all_properties, parent_shape|
|
652
|
+
all_properties.merge(parent_shape.converted_properties)
|
587
653
|
end
|
588
654
|
end
|
589
655
|
|
@@ -600,11 +666,10 @@ module Glimmer
|
|
600
666
|
|
601
667
|
def paint_self(paint_event)
|
602
668
|
@painting = true
|
603
|
-
unless
|
669
|
+
unless container?
|
604
670
|
calculate_paint_args!
|
605
671
|
@original_gc_properties = {} # this stores GC properties before making calls to updates TODO avoid using in pixel graphics
|
606
|
-
@
|
607
|
-
@properties.merge(all_parent_properties).each do |property, args|
|
672
|
+
@properties.each do |property, args|
|
608
673
|
method_name = attribute_setter(property)
|
609
674
|
@original_gc_properties[method_name] = paint_event.gc.send(method_name.sub('set', 'get')) rescue nil
|
610
675
|
paint_event.gc.send(method_name, *args)
|
@@ -614,10 +679,8 @@ module Glimmer
|
|
614
679
|
end
|
615
680
|
ensure_extent(paint_event)
|
616
681
|
end
|
617
|
-
|
618
|
-
|
619
|
-
end
|
620
|
-
unless shape_composite?
|
682
|
+
@calculated_args ||= calculate_args!
|
683
|
+
unless container?
|
621
684
|
# paint unless parent's calculated args are not calculated yet, meaning it is about to get painted and trigger a paint on this child anyways
|
622
685
|
paint_event.gc.send(@method_name, *@calculated_args) unless (parent.is_a?(Shape) && !parent.calculated_args?)
|
623
686
|
@original_gc_properties.each do |method_name, value|
|
@@ -663,26 +726,27 @@ module Glimmer
|
|
663
726
|
end
|
664
727
|
end
|
665
728
|
|
666
|
-
def parent_shape_absolute_location_changed?
|
667
|
-
(parent.is_a?(Shape) && (parent.absolute_x != @parent_absolute_x || parent.absolute_y != @parent_absolute_y))
|
668
|
-
end
|
669
|
-
|
670
729
|
def calculated_args_changed!(children: true)
|
671
730
|
# TODO add a children: true option to enable setting to false to avoid recalculating children args
|
672
731
|
@calculated_args = nil
|
673
732
|
shapes.each(&:calculated_args_changed!) if children
|
674
733
|
end
|
675
734
|
|
735
|
+
# Notifies object that calculated args changed for defaults. Returns true if redrawing and false otherwise.
|
676
736
|
def calculated_args_changed_for_defaults!
|
677
737
|
has_default_dimensions = default_width? || default_height?
|
678
738
|
parent_calculated_args_changed_for_defaults = has_default_dimensions
|
679
|
-
|
739
|
+
calculated_args_changed!(children: false) if default_x? || default_y? || has_default_dimensions
|
680
740
|
if has_default_dimensions && parent.is_a?(Shape)
|
681
741
|
parent.calculated_args_changed_for_defaults!
|
682
742
|
elsif @content_added && !drawable.is_disposed
|
683
743
|
# TODO consider optimizing in the future if needed by ensuring one redraw for all parents in the hierarchy at the end instead of doing one per parent that needs it
|
684
|
-
|
744
|
+
if !@painting && !drawable.is_a?(ImageProxy)
|
745
|
+
drawable.redraw
|
746
|
+
return true
|
747
|
+
end
|
685
748
|
end
|
749
|
+
false
|
686
750
|
end
|
687
751
|
|
688
752
|
def calculated_args?
|
@@ -690,76 +754,101 @@ module Glimmer
|
|
690
754
|
end
|
691
755
|
|
692
756
|
# args translated to absolute coordinates
|
693
|
-
def
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
757
|
+
def calculate_args!
|
758
|
+
# TODO add conditions for parent having default width/height too
|
759
|
+
return @args if parent.is_a?(Drawable) && !default_x? && !default_y? && !default_width? && !default_height? && !max_width? && !max_height?
|
760
|
+
calculated_args_dependencies = [
|
761
|
+
x,
|
762
|
+
y,
|
763
|
+
parent.is_a?(Shape) && parent.absolute_x,
|
764
|
+
parent.is_a?(Shape) && parent.absolute_y,
|
765
|
+
default_width? && default_width,
|
766
|
+
default_width? && width_delta,
|
767
|
+
default_height? && default_height,
|
768
|
+
default_height? && height_delta,
|
769
|
+
max_width? && max_width,
|
770
|
+
max_width? && width_delta,
|
771
|
+
max_height? && max_height,
|
772
|
+
max_height? && height_delta,
|
773
|
+
default_x? && default_x,
|
774
|
+
default_x? && x_delta,
|
775
|
+
default_y? && default_y,
|
776
|
+
default_y? && y_delta,
|
777
|
+
]
|
778
|
+
if calculated_args_dependencies != @calculated_args_dependencies
|
779
|
+
# avoid recalculating values again
|
780
|
+
x, y, parent_absolute_x, parent_absolute_y, default_width, default_width_delta, default_height, default_height_delta, max_width, max_width_delta, max_height, max_height_delta, default_x, default_x_delta, default_y, default_y_delta = @calculated_args_dependencies = calculated_args_dependencies
|
781
|
+
# Note: Must set x and move_by because not all shapes have a real x and some must translate all their points with move_by
|
782
|
+
# TODO change that by setting a bounding box for all shapes with a calculated top-left x, y and
|
783
|
+
# a setter that does the moving inside them instead so that I could rely on absolute_x and absolute_y
|
784
|
+
# here to get the job done of calculating absolute args
|
785
|
+
@perform_redraw = false
|
786
|
+
original_x = nil
|
787
|
+
original_y = nil
|
788
|
+
original_width = nil
|
789
|
+
original_height = nil
|
790
|
+
if parent.is_a?(Shape)
|
791
|
+
@parent_absolute_x = parent_absolute_x
|
792
|
+
@parent_absolute_y = parent_absolute_y
|
793
|
+
end
|
794
|
+
if default_width?
|
795
|
+
original_width = width
|
796
|
+
self.width = default_width + default_width_delta
|
797
|
+
end
|
798
|
+
if default_height?
|
799
|
+
original_height = height
|
800
|
+
self.height = default_height + default_height_delta
|
801
|
+
end
|
802
|
+
if max_width?
|
803
|
+
original_width = width
|
804
|
+
self.width = max_width + max_width_delta
|
805
|
+
end
|
806
|
+
if max_height?
|
807
|
+
original_height = height
|
808
|
+
self.height = max_height + max_height_delta
|
809
|
+
end
|
810
|
+
if default_x?
|
811
|
+
original_x = x
|
812
|
+
self.x = default_x + default_x_delta
|
813
|
+
end
|
814
|
+
if default_y?
|
815
|
+
original_y = y
|
816
|
+
self.y = default_y + default_y_delta
|
817
|
+
end
|
818
|
+
if parent.is_a?(Shape)
|
819
|
+
move_by(@parent_absolute_x, @parent_absolute_y)
|
820
|
+
@result_calculated_args = @args.clone
|
821
|
+
move_by(-1*@parent_absolute_x, -1*@parent_absolute_y)
|
822
|
+
else
|
823
|
+
@result_calculated_args = @args.clone
|
824
|
+
end
|
825
|
+
if original_x
|
826
|
+
self.x = original_x
|
827
|
+
end
|
828
|
+
if original_y
|
829
|
+
self.y = original_y
|
830
|
+
end
|
831
|
+
if original_width
|
832
|
+
self.width = original_width
|
833
|
+
end
|
834
|
+
if original_height
|
835
|
+
self.height = original_height
|
836
|
+
end
|
837
|
+
@perform_redraw = true
|
750
838
|
end
|
751
|
-
@
|
752
|
-
result_args
|
839
|
+
@result_calculated_args
|
753
840
|
end
|
754
841
|
|
755
842
|
def default_x?
|
756
|
-
current_parameter_name?(:x)
|
757
|
-
|
843
|
+
return false unless current_parameter_name?(:x)
|
844
|
+
x = self.x
|
845
|
+
x.nil? || x.to_s == 'default' || (x.is_a?(Array) && x.first.to_s == 'default')
|
758
846
|
end
|
759
847
|
|
760
848
|
def default_y?
|
761
|
-
current_parameter_name?(:y)
|
762
|
-
|
849
|
+
return false unless current_parameter_name?(:y)
|
850
|
+
y = self.y
|
851
|
+
y.nil? || y.to_s == 'default' || (y.is_a?(Array) && y.first.to_s == 'default')
|
763
852
|
end
|
764
853
|
|
765
854
|
def default_width?
|
@@ -775,108 +864,157 @@ module Glimmer
|
|
775
864
|
end
|
776
865
|
|
777
866
|
def max_width?
|
778
|
-
current_parameter_name?(:width)
|
779
|
-
|
867
|
+
return false unless current_parameter_name?(:width)
|
868
|
+
width = self.width
|
869
|
+
(width.nil? || width.to_s == 'max' || (width.is_a?(Array) && width.first.to_s == 'max'))
|
780
870
|
end
|
781
871
|
|
782
872
|
def max_height?
|
783
|
-
current_parameter_name?(:height)
|
784
|
-
|
873
|
+
return false unless current_parameter_name?(:height)
|
874
|
+
height = self.height
|
875
|
+
(height.nil? || height.to_s == 'max' || (height.is_a?(Array) && height.first.to_s == 'max'))
|
785
876
|
end
|
786
877
|
|
787
878
|
def default_x
|
788
|
-
|
789
|
-
|
790
|
-
|
879
|
+
default_x_dependencies = [parent.size.x, size.x, parent.is_a?(Shape) && parent.irregular? && parent.bounds.x, parent.is_a?(Shape) && parent.irregular? && parent.absolute_x]
|
880
|
+
if default_x_dependencies != @default_x_dependencies
|
881
|
+
@default_x_dependencies = default_x_dependencies
|
882
|
+
result = ((parent.size.x - size.x) / 2)
|
883
|
+
result += parent.bounds.x - parent.absolute_x if parent.is_a?(Shape) && parent.irregular?
|
884
|
+
@default_x = result
|
885
|
+
end
|
886
|
+
@default_x
|
791
887
|
end
|
792
888
|
|
793
889
|
def default_y
|
794
|
-
|
795
|
-
|
796
|
-
|
890
|
+
default_y_dependencies = [parent.size.y, size.y, parent.is_a?(Shape) && parent.irregular? && parent.bounds.y, parent.is_a?(Shape) && parent.irregular? && parent.absolute_y]
|
891
|
+
if default_y_dependencies != @default_y_dependencies
|
892
|
+
result = ((parent.size.y - size.y) / 2)
|
893
|
+
result += parent.bounds.y - parent.absolute_y if parent.is_a?(Shape) && parent.irregular?
|
894
|
+
@default_y = result
|
895
|
+
end
|
896
|
+
@default_y
|
897
|
+
end
|
898
|
+
|
899
|
+
# right-most x coordinate in this shape (adding up its width and location)
|
900
|
+
def x_end
|
901
|
+
x_end_dependencies = [calculated_width, default_x?, !default_x? && x]
|
902
|
+
if x_end_dependencies != @x_end_dependencies
|
903
|
+
# avoid recalculation of dependencies
|
904
|
+
calculated_width, is_default_x, x = @x_end_dependencies = x_end_dependencies
|
905
|
+
shape_width = calculated_width.to_f
|
906
|
+
shape_x = is_default_x ? 0 : x.to_f
|
907
|
+
@x_end = shape_x + shape_width
|
908
|
+
end
|
909
|
+
@x_end
|
910
|
+
end
|
911
|
+
|
912
|
+
# right-most y coordinate in this shape (adding up its height and location)
|
913
|
+
def y_end
|
914
|
+
y_end_dependencies = [calculated_height, default_y?, !default_y? && y]
|
915
|
+
if y_end_dependencies != @y_end_dependencies
|
916
|
+
# avoid recalculation of dependencies
|
917
|
+
calculated_height, is_default_y, y = @y_end_dependencies = y_end_dependencies
|
918
|
+
shape_height = calculated_height.to_f
|
919
|
+
shape_y = is_default_y ? 0 : y.to_f
|
920
|
+
@y_end = shape_y + shape_height
|
921
|
+
end
|
922
|
+
@y_end
|
797
923
|
end
|
798
924
|
|
799
925
|
def default_width
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
926
|
+
default_width_dependencies = [shapes.empty? && max_width, shapes.size == 1 && shapes.first.max_width? && parent.size.x, shapes.size >= 1 && !shapes.first.max_width? && shapes.map {|s| s.max_width? ? 0 : s.x_end}]
|
927
|
+
if default_width_dependencies != @default_width_dependencies
|
928
|
+
# Do not repeat calculations
|
929
|
+
max_width, parent_size_x, x_ends = @default_width_dependencies = default_width_dependencies
|
930
|
+
@default_width = if shapes.empty?
|
931
|
+
max_width
|
932
|
+
elsif shapes.size == 1 && shapes.first.max_width?
|
933
|
+
parent_size_x
|
804
934
|
else
|
805
|
-
|
806
|
-
shape_x = shape.default_x? ? 0 : shape.x.to_f
|
807
|
-
shape_x + shape_width
|
935
|
+
x_ends.max.to_f
|
808
936
|
end
|
809
937
|
end
|
810
|
-
|
811
|
-
max_width
|
812
|
-
elsif shapes.size == 1 && shapes.first.max_width?
|
813
|
-
self.parent.size.x
|
814
|
-
else
|
815
|
-
x_ends.max.to_f
|
816
|
-
end
|
938
|
+
@default_width
|
817
939
|
end
|
818
940
|
|
819
941
|
def default_height
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
942
|
+
default_height_dependencies = [shapes.empty? && max_height, shapes.size == 1 && shapes.first.max_height? && parent.size.y, shapes.size >= 1 && !shapes.first.max_height? && shapes.map {|s| s.max_height? ? 0 : s.y_end}]
|
943
|
+
if default_height_dependencies != @default_height_dependencies
|
944
|
+
# Do not repeat calculations
|
945
|
+
max_height, parent_size_y, y_ends = @default_height_dependencies = default_height_dependencies
|
946
|
+
@default_height = if shapes.empty?
|
947
|
+
max_height
|
948
|
+
elsif shapes.size == 1 && shapes.first.max_height?
|
949
|
+
parent_size_y
|
824
950
|
else
|
825
|
-
|
826
|
-
shape_y = shape.default_y? ? 0 : shape.y.to_f
|
827
|
-
shape_y + shape_height
|
951
|
+
y_ends.max.to_f
|
828
952
|
end
|
829
953
|
end
|
830
|
-
|
831
|
-
max_height
|
832
|
-
elsif shapes.size == 1 && shapes.first.max_height?
|
833
|
-
self.parent.size.y
|
834
|
-
else
|
835
|
-
y_ends.max.to_f
|
836
|
-
end
|
954
|
+
@default_height
|
837
955
|
end
|
838
956
|
|
839
957
|
def max_width
|
840
|
-
|
841
|
-
|
958
|
+
max_width_dependencies = [parent.is_a?(Drawable) && parent.size.x, !parent.is_a?(Drawable) && parent.calculated_width]
|
959
|
+
if max_width_dependencies != @max_width_dependencies
|
960
|
+
# do not repeat calculations
|
961
|
+
parent_size_x, parent_calculated_width = @max_width_dependencies = max_width_dependencies
|
962
|
+
@max_width = parent.is_a?(Drawable) ? parent_size_x : parent_calculated_width
|
963
|
+
end
|
964
|
+
@max_width
|
842
965
|
end
|
843
966
|
|
844
967
|
def max_height
|
845
|
-
|
846
|
-
|
968
|
+
max_height_dependencies = [parent.is_a?(Drawable) && parent.size.y, !parent.is_a?(Drawable) && parent.calculated_height]
|
969
|
+
if max_height_dependencies != @max_height_dependencies
|
970
|
+
# do not repeat calculations
|
971
|
+
parent_size_y, parent_calculated_height = @max_height_dependencies = max_height_dependencies
|
972
|
+
@max_height = parent.is_a?(Drawable) ? parent_size_y : parent_calculated_height
|
973
|
+
end
|
974
|
+
@max_height
|
847
975
|
end
|
848
976
|
|
849
977
|
def calculated_width
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
978
|
+
calculated_width_dependencies = [width, default_width? && (default_width + width_delta), max_width? && (max_width + width_delta)]
|
979
|
+
if calculated_width_dependencies != @calculated_width_dependencies
|
980
|
+
@calculated_width_dependencies = calculated_width_dependencies
|
981
|
+
result_width = width
|
982
|
+
result_width = (default_width + width_delta) if default_width?
|
983
|
+
result_width = (max_width + width_delta) if max_width?
|
984
|
+
@calculated_width = result_width
|
985
|
+
end
|
986
|
+
@calculated_width
|
854
987
|
end
|
855
988
|
|
856
989
|
def calculated_height
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
990
|
+
calculated_height_dependencies = [height, default_height? && (default_height + height_delta), max_height? && (max_height + height_delta)]
|
991
|
+
if calculated_height_dependencies != @calculated_height_dependencies
|
992
|
+
@calculated_height_dependencies = calculated_height_dependencies
|
993
|
+
result_height = height
|
994
|
+
result_height = (default_height + height_delta) if default_height?
|
995
|
+
result_height = (max_height + height_delta) if max_height?
|
996
|
+
@calculated_height = result_height
|
997
|
+
end
|
998
|
+
@calculated_height
|
861
999
|
end
|
862
1000
|
|
863
1001
|
def x_delta
|
864
|
-
return 0 unless
|
1002
|
+
return 0 unless x.is_a?(Array) && default_x?
|
865
1003
|
x[1].to_f
|
866
1004
|
end
|
867
1005
|
|
868
1006
|
def y_delta
|
869
|
-
return 0 unless
|
1007
|
+
return 0 unless y.is_a?(Array) && default_y?
|
870
1008
|
y[1].to_f
|
871
1009
|
end
|
872
1010
|
|
873
1011
|
def width_delta
|
874
|
-
return 0 unless (default_width? || max_width?)
|
1012
|
+
return 0 unless width.is_a?(Array) && (default_width? || max_width?)
|
875
1013
|
width[1].to_f
|
876
1014
|
end
|
877
1015
|
|
878
1016
|
def height_delta
|
879
|
-
return 0 unless (default_height? || max_height?)
|
1017
|
+
return 0 unless height.is_a?(Array) && (default_height? || max_height?)
|
880
1018
|
height[1].to_f
|
881
1019
|
end
|
882
1020
|
|
@@ -905,39 +1043,68 @@ module Glimmer
|
|
905
1043
|
end
|
906
1044
|
|
907
1045
|
def calculated_x
|
908
|
-
|
909
|
-
|
910
|
-
|
1046
|
+
calculated_x_dependencies = [default_x? && default_x, !default_x? && self.x, self.x_delta]
|
1047
|
+
if calculated_x_dependencies != @calculated_x_dependencies
|
1048
|
+
default_x, x, x_delta = @calculated_x_dependencies = calculated_x_dependencies
|
1049
|
+
result = default_x? ? default_x : x
|
1050
|
+
result += x_delta
|
1051
|
+
@calculated_x = result
|
1052
|
+
end
|
1053
|
+
@calculated_x
|
911
1054
|
end
|
912
1055
|
|
913
1056
|
def calculated_y
|
914
|
-
|
915
|
-
|
916
|
-
|
1057
|
+
calculated_y_dependencies = [default_y? && default_y, !default_y? && self.y, self.y_delta]
|
1058
|
+
if calculated_y_dependencies != @calculated_y_dependencies
|
1059
|
+
default_y, y, y_delta = @calculated_y_dependencies = calculated_y_dependencies
|
1060
|
+
result = default_y? ? default_y : y
|
1061
|
+
result += y_delta
|
1062
|
+
@calculated_y = result
|
1063
|
+
end
|
1064
|
+
@calculated_y
|
917
1065
|
end
|
918
1066
|
|
919
1067
|
def absolute_x
|
920
|
-
|
921
|
-
if
|
922
|
-
|
923
|
-
|
924
|
-
x
|
1068
|
+
absolute_x_dependencies = [calculated_x, parent.is_a?(Shape) && parent.absolute_x]
|
1069
|
+
if absolute_x_dependencies != @absolute_x_dependencies
|
1070
|
+
# do not repeat calculations
|
1071
|
+
calculated_x, parent_absolute_x = @absolute_x_dependencies = absolute_x_dependencies
|
1072
|
+
x = calculated_x
|
1073
|
+
@absolute_x = if parent.is_a?(Shape)
|
1074
|
+
parent_absolute_x + x
|
1075
|
+
else
|
1076
|
+
x
|
1077
|
+
end
|
925
1078
|
end
|
1079
|
+
@absolute_x
|
926
1080
|
end
|
927
1081
|
|
928
1082
|
def absolute_y
|
929
|
-
|
930
|
-
if
|
931
|
-
|
932
|
-
|
933
|
-
|
1083
|
+
absolute_y_dependencies = [calculated_y, parent.is_a?(Shape) && parent.absolute_y]
|
1084
|
+
if absolute_y_dependencies != @absolute_y_dependencies
|
1085
|
+
calculated_y, parent_absolute_y = @absolute_y_dependencies = absolute_y_dependencies
|
1086
|
+
y = calculated_y
|
1087
|
+
@absolute_y = if parent.is_a?(Shape)
|
1088
|
+
parent_absolute_y + y
|
1089
|
+
else
|
1090
|
+
y
|
1091
|
+
end
|
934
1092
|
end
|
1093
|
+
@absolute_y
|
935
1094
|
end
|
936
1095
|
|
937
|
-
# Overriding inspect to avoid printing very long shape hierarchies
|
938
|
-
def inspect
|
939
|
-
|
1096
|
+
# Overriding inspect to avoid printing very long nested shape hierarchies (recurses onces only)
|
1097
|
+
def inspect(recursive: 1, calculated: false, args: true, properties: true, calculated_args: false)
|
1098
|
+
recurse = recursive == true || recursive.is_a?(Integer) && recursive.to_i > 0
|
1099
|
+
recursive = [recursive -= 1, 0].max if recursive.is_a?(Integer)
|
1100
|
+
args_string = " args=#{@args.inspect}" if args
|
1101
|
+
properties_string = " properties=#{@properties.inspect}}" if properties
|
1102
|
+
calculated_args_string = " calculated_args=#{@calculated_args.inspect}" if calculated_args
|
1103
|
+
calculated_string = " absolute_x=#{absolute_x} absolute_y=#{absolute_y} calculated_width=#{calculated_width} calculated_height=#{calculated_height}" if calculated
|
1104
|
+
recursive_string = " shapes=#{@shapes.map {|s| s.inspect(recursive: recursive, calculated: calculated, args: args, properties: properties)}}" if recurse
|
1105
|
+
"#<#{self.class.name}:0x#{self.hash.to_s(16)}#{args_string}#{properties_string}#{calculated_args_string}#{calculated_string}#{recursive_string}>"
|
940
1106
|
rescue => e
|
1107
|
+
Glimmer::Config.logger.error { e.full_message }
|
941
1108
|
"#<#{self.class.name}:0x#{self.hash.to_s(16)}"
|
942
1109
|
end
|
943
1110
|
|
@@ -958,17 +1125,14 @@ module Glimmer
|
|
958
1125
|
end
|
959
1126
|
end
|
960
1127
|
else
|
1128
|
+
@properties = all_parent_properties.merge(@properties)
|
961
1129
|
@properties['background'] = [@drawable.background] if fill? && !has_some_background?
|
962
1130
|
@properties['foreground'] = [@drawable.foreground] if @drawable.respond_to?(:foreground) && draw? && !has_some_foreground?
|
963
1131
|
# TODO regarding alpha, make sure to reset it to parent stored alpha once we allow setting shape properties on parents directly without shapes
|
964
|
-
@properties['
|
965
|
-
@properties['font'] = [@drawable.font] if @drawable.respond_to?(:font) && draw? && !@properties.keys.map(&:to_s).include?('font')
|
1132
|
+
@properties['font'] = [@drawable.font] if @drawable.respond_to?(:font) && @name == 'text' && draw? && !@properties.keys.map(&:to_s).include?('font')
|
966
1133
|
# TODO regarding transform, make sure to reset it to parent stored transform once we allow setting shape properties on parents directly without shapes
|
967
1134
|
# Also do that with all future-added properties
|
968
|
-
|
969
|
-
@properties.each do |property, args|
|
970
|
-
@properties[property] = apply_property_arg_conversions(property, args)
|
971
|
-
end
|
1135
|
+
convert_properties!
|
972
1136
|
apply_shape_arg_conversions!
|
973
1137
|
apply_shape_arg_defaults!
|
974
1138
|
tolerate_shape_extra_args!
|
@@ -34,13 +34,9 @@ module Glimmer
|
|
34
34
|
class Shape
|
35
35
|
class Image < Shape
|
36
36
|
def parameter_names
|
37
|
-
|
38
|
-
image_part_parameter_names
|
39
|
-
else
|
40
|
-
image_whole_parameter_names
|
41
|
-
end
|
37
|
+
@parameter_names || image_whole_parameter_names
|
42
38
|
end
|
43
|
-
|
39
|
+
|
44
40
|
def possible_parameter_names
|
45
41
|
(image_part_parameter_names + image_whole_parameter_names).uniq
|
46
42
|
end
|
@@ -53,13 +49,15 @@ module Glimmer
|
|
53
49
|
[:image, :x, :y]
|
54
50
|
end
|
55
51
|
|
56
|
-
def
|
52
|
+
def set_parameter_attribute(attribute_name, *args)
|
53
|
+
return super if @parameter_names.to_a.map(&:to_s).include?(attribute_name.to_s)
|
57
54
|
####TODO refactor and improve this method through meta-programming (and share across other shapes)
|
58
55
|
if image_part_parameter_names.map(&:to_s).include?(attribute_name.to_s)
|
59
|
-
image_part_parameter_names
|
56
|
+
@parameter_names = image_part_parameter_names
|
60
57
|
elsif image_whole_parameter_names.map(&:to_s).include?(attribute_name.to_s)
|
61
|
-
image_whole_parameter_names
|
58
|
+
@parameter_names = image_whole_parameter_names
|
62
59
|
end
|
60
|
+
super
|
63
61
|
end
|
64
62
|
|
65
63
|
def x
|
@@ -112,11 +112,7 @@ module Glimmer
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
def
|
116
|
-
super
|
117
|
-
end
|
118
|
-
|
119
|
-
def calculated_args
|
115
|
+
def calculate_args!
|
120
116
|
new_swt_path = @swt_path.nil? || !@calculated_paint_args || !@calculated_path_args
|
121
117
|
if new_swt_path
|
122
118
|
Glimmer::SWT::DisplayProxy.instance.auto_exec do
|
@@ -119,16 +119,28 @@ module Glimmer
|
|
119
119
|
|
120
120
|
# Logical x coordinate relative to parent
|
121
121
|
def x
|
122
|
-
|
123
|
-
|
124
|
-
|
122
|
+
x_dependencies = [bounds.x, parent.is_a?(Shape) && parent.absolute_x]
|
123
|
+
if x_dependencies != @x_dependencies
|
124
|
+
# avoid recalculating values
|
125
|
+
bounds_x, parent_absolute_x = @x_dependencies = x_dependencies
|
126
|
+
x_value = bounds_x
|
127
|
+
x_value -= parent_absolute_x if parent.is_a?(Shape)
|
128
|
+
@x = x_value
|
129
|
+
end
|
130
|
+
@x
|
125
131
|
end
|
126
132
|
|
127
133
|
# Logical y coordinate relative to parent
|
128
134
|
def y
|
129
|
-
|
130
|
-
|
131
|
-
|
135
|
+
y_dependencies = [bounds.y, parent.is_a?(Shape) && parent.absolute_y]
|
136
|
+
if y_dependencies != @y_dependencies
|
137
|
+
# avoid recalculating values
|
138
|
+
bounds_y, parent_absolute_y = @y_dependencies = y_dependencies
|
139
|
+
y_value = bounds_y
|
140
|
+
y_value -= parent_absolute_y if parent.is_a?(Shape)
|
141
|
+
@y = y_value
|
142
|
+
end
|
143
|
+
@y
|
132
144
|
end
|
133
145
|
|
134
146
|
def width
|
@@ -144,8 +156,12 @@ module Glimmer
|
|
144
156
|
end
|
145
157
|
|
146
158
|
def include?(x, y)
|
147
|
-
|
148
|
-
|
159
|
+
if filled?
|
160
|
+
contain?(x, y)
|
161
|
+
else
|
162
|
+
comparison_lines = absolute_point_xy_array.zip(absolute_point_xy_array.rotate(1))
|
163
|
+
comparison_lines.any? {|line| Line.include?(line.first.first, line.first.last, line.last.first, line.last.last, x, y)}
|
164
|
+
end
|
149
165
|
end
|
150
166
|
|
151
167
|
def move_by(x_delta, y_delta)
|
@@ -42,19 +42,23 @@ module Glimmer
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def point_count
|
45
|
+
point_array = args.size > 1 ? args : self.point_array
|
45
46
|
point_array.count / 2
|
46
47
|
end
|
47
48
|
|
48
49
|
def [](index)
|
50
|
+
point_array = args.size > 1 ? args : self.point_array
|
49
51
|
index = 0 if index == point_count
|
50
52
|
org.eclipse.swt.graphics.Point.new(point_array[index * 2], point_array[index * 2 + 1])
|
51
53
|
end
|
52
54
|
|
53
55
|
def x_array
|
56
|
+
point_array = args.size > 1 ? args : self.point_array
|
54
57
|
point_array.each_with_index.select {|pair| pair.last.even?}.map(&:first)
|
55
58
|
end
|
56
59
|
|
57
60
|
def y_array
|
61
|
+
point_array = args.size > 1 ? args : self.point_array
|
58
62
|
point_array.each_with_index.select {|pair| pair.last.odd?}.map(&:first)
|
59
63
|
end
|
60
64
|
|
@@ -63,6 +67,7 @@ module Glimmer
|
|
63
67
|
end
|
64
68
|
|
65
69
|
def absolute_point_array
|
70
|
+
point_array = args.size > 1 ? args : self.point_array
|
66
71
|
if parent.is_a?(Shape)
|
67
72
|
point_array.each_with_index.map do |coordinate, i|
|
68
73
|
if i.even?
|
@@ -23,7 +23,6 @@ require 'glimmer/swt/custom/shape'
|
|
23
23
|
require 'glimmer/swt/swt_proxy'
|
24
24
|
require 'glimmer/swt/display_proxy'
|
25
25
|
require 'glimmer/swt/color_proxy'
|
26
|
-
require 'glimmer/swt/font_proxy'
|
27
26
|
require 'glimmer/swt/transform_proxy'
|
28
27
|
|
29
28
|
module Glimmer
|
@@ -34,16 +33,7 @@ module Glimmer
|
|
34
33
|
class Shape
|
35
34
|
class Rectangle < Shape
|
36
35
|
def parameter_names
|
37
|
-
|
38
|
-
if @args.to_a.size >= 6
|
39
|
-
rectangle_round_parameter_names
|
40
|
-
elsif @args.to_a.size == 5
|
41
|
-
rectangle_gradient_parameter_names
|
42
|
-
elsif @args.to_a.size == 1
|
43
|
-
rectangle_rectangle_parameter_names
|
44
|
-
else
|
45
|
-
rectangle_parameter_names
|
46
|
-
end
|
36
|
+
@parameter_names || rectangle_parameter_names
|
47
37
|
end
|
48
38
|
|
49
39
|
def possible_parameter_names
|
@@ -68,17 +58,18 @@ module Glimmer
|
|
68
58
|
[:rectangle]
|
69
59
|
end
|
70
60
|
|
71
|
-
def
|
72
|
-
|
73
|
-
if
|
74
|
-
|
61
|
+
def set_parameter_attribute(attribute_name, *args)
|
62
|
+
return super if @parameter_names.to_a.map(&:to_s).include?(attribute_name.to_s)
|
63
|
+
if rectangle_parameter_names.map(&:to_s).include?(attribute_name.to_s)
|
64
|
+
@parameter_names = rectangle_parameter_names
|
65
|
+
elsif rectangle_round_parameter_names.map(&:to_s).include?(attribute_name.to_s)
|
66
|
+
@parameter_names = rectangle_round_parameter_names
|
75
67
|
elsif rectangle_gradient_parameter_names.map(&:to_s).include?(attribute_name.to_s)
|
76
|
-
rectangle_gradient_parameter_names
|
77
|
-
elsif rectangle_parameter_names.map(&:to_s).include?(attribute_name.to_s)
|
78
|
-
rectangle_parameter_names.map(&:to_s).index(attribute_name.to_s)
|
68
|
+
@parameter_names = rectangle_gradient_parameter_names
|
79
69
|
elsif rectangle_rectangle_parameter_names.map(&:to_s).include?(attribute_name.to_s)
|
80
|
-
rectangle_rectangle_parameter_names
|
70
|
+
@parameter_names = rectangle_rectangle_parameter_names
|
81
71
|
end
|
72
|
+
super
|
82
73
|
end
|
83
74
|
|
84
75
|
def point_xy_array
|
data/samples/elaborate/tetris.rb
CHANGED
@@ -158,18 +158,7 @@ class Tetris
|
|
158
158
|
y = row * icon_block_size
|
159
159
|
rectangle(x, y, icon_block_size, icon_block_size) {
|
160
160
|
background color
|
161
|
-
|
162
|
-
polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
163
|
-
background rgb(color.red + 4*BEVEL_CONSTANT, color.green + 4*BEVEL_CONSTANT, color.blue + 4*BEVEL_CONSTANT)
|
164
|
-
}
|
165
|
-
polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
|
166
|
-
background rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
167
|
-
}
|
168
|
-
polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
|
169
|
-
background rgb(color.red - 2*BEVEL_CONSTANT, color.green - 2*BEVEL_CONSTANT, color.blue - 2*BEVEL_CONSTANT)
|
170
|
-
}
|
171
|
-
polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
172
|
-
background rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
161
|
+
bevel(base_color: color, size: icon_block_size)
|
173
162
|
}
|
174
163
|
}
|
175
164
|
}
|
@@ -33,6 +33,8 @@ class Tetris
|
|
33
33
|
class Game
|
34
34
|
PLAYFIELD_WIDTH = 10
|
35
35
|
PLAYFIELD_HEIGHT = 20
|
36
|
+
# PLAYFIELD_WIDTH = 5
|
37
|
+
# PLAYFIELD_HEIGHT = 5
|
36
38
|
PREVIEW_PLAYFIELD_WIDTH = 4
|
37
39
|
PREVIEW_PLAYFIELD_HEIGHT = 2
|
38
40
|
SCORE_MULTIPLIER = {1 => 40, 2 => 100, 3 => 300, 4 => 1200}
|
@@ -199,6 +201,7 @@ class Tetris
|
|
199
201
|
|
200
202
|
def delay
|
201
203
|
[1.1 - (level.to_i * 0.1), 0.001].max
|
204
|
+
# 99999
|
202
205
|
end
|
203
206
|
|
204
207
|
def beep
|
@@ -0,0 +1,78 @@
|
|
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
|
+
# Creates a class-based custom shape representing the `bevel` keyword by convention
|
23
|
+
class Tetris
|
24
|
+
module View
|
25
|
+
class Bevel
|
26
|
+
include Glimmer::UI::CustomShape
|
27
|
+
|
28
|
+
options :base_color, :size, :bevel_pixel_size
|
29
|
+
|
30
|
+
before_body {
|
31
|
+
self.bevel_pixel_size = 0.16*size.to_f if bevel_pixel_size.nil?
|
32
|
+
}
|
33
|
+
|
34
|
+
body {
|
35
|
+
shape(0, 0, size, size) {
|
36
|
+
polygon(0, 0, size, 0, size - bevel_pixel_size, bevel_pixel_size, bevel_pixel_size, bevel_pixel_size) {
|
37
|
+
background bind(self, :base_color) { |color_value|
|
38
|
+
unless color_value.nil?
|
39
|
+
color = color(color_value)
|
40
|
+
rgb(color.red + 4*BEVEL_CONSTANT, color.green + 4*BEVEL_CONSTANT, color.blue + 4*BEVEL_CONSTANT)
|
41
|
+
end
|
42
|
+
}
|
43
|
+
}
|
44
|
+
polygon(size, 0, size - bevel_pixel_size, bevel_pixel_size, size - bevel_pixel_size, size - bevel_pixel_size, size, size) {
|
45
|
+
background bind(self, :base_color) { |color_value|
|
46
|
+
unless color_value.nil?
|
47
|
+
color = color(color_value)
|
48
|
+
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
49
|
+
end
|
50
|
+
}
|
51
|
+
}
|
52
|
+
polygon(size, size, 0, size, bevel_pixel_size, size - bevel_pixel_size, size - bevel_pixel_size, size - bevel_pixel_size) {
|
53
|
+
background bind(self, :base_color) { |color_value|
|
54
|
+
unless color_value.nil?
|
55
|
+
color = color(color_value)
|
56
|
+
rgb(color.red - 2*BEVEL_CONSTANT, color.green - 2*BEVEL_CONSTANT, color.blue - 2*BEVEL_CONSTANT)
|
57
|
+
end
|
58
|
+
}
|
59
|
+
}
|
60
|
+
polygon(0, 0, 0, size, bevel_pixel_size, size - bevel_pixel_size, bevel_pixel_size, bevel_pixel_size) {
|
61
|
+
background bind(self, :base_color) { |color_value|
|
62
|
+
unless color_value.nil?
|
63
|
+
color = color(color_value)
|
64
|
+
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
65
|
+
end
|
66
|
+
}
|
67
|
+
}
|
68
|
+
rectangle(0, 0, size, size) {
|
69
|
+
foreground bind(self, :base_color) { |color_value|
|
70
|
+
# use gray instead of white for the border
|
71
|
+
color_value == Model::Block::COLOR_CLEAR ? :gray : color_value
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -19,6 +19,8 @@
|
|
19
19
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
|
+
require_relative 'bevel'
|
23
|
+
|
22
24
|
class Tetris
|
23
25
|
module View
|
24
26
|
class Block
|
@@ -27,36 +29,11 @@ class Tetris
|
|
27
29
|
options :game_playfield, :block_size, :row, :column
|
28
30
|
|
29
31
|
body {
|
30
|
-
canvas {
|
32
|
+
canvas { |canvas_proxy|
|
31
33
|
background bind(game_playfield[row][column], :color)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
rgb(color.red + 4*BEVEL_CONSTANT, color.green + 4*BEVEL_CONSTANT, color.blue + 4*BEVEL_CONSTANT)
|
36
|
-
}
|
37
|
-
}
|
38
|
-
polygon(block_size, 0, block_size - 4, 4, block_size - 4, block_size - 4, block_size, block_size) {
|
39
|
-
background bind(game_playfield[row][column], :color) { |color_value|
|
40
|
-
color = color(color_value)
|
41
|
-
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
42
|
-
}
|
43
|
-
}
|
44
|
-
polygon(block_size, block_size, 0, block_size, 4, block_size - 4, block_size - 4, block_size - 4) {
|
45
|
-
background bind(game_playfield[row][column], :color) { |color_value|
|
46
|
-
color = color(color_value)
|
47
|
-
rgb(color.red - 2*BEVEL_CONSTANT, color.green - 2*BEVEL_CONSTANT, color.blue - 2*BEVEL_CONSTANT)
|
48
|
-
}
|
49
|
-
}
|
50
|
-
polygon(0, 0, 0, block_size, 4, block_size - 4, 4, 4) {
|
51
|
-
background bind(game_playfield[row][column], :color) { |color_value|
|
52
|
-
color = color(color_value)
|
53
|
-
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
54
|
-
}
|
55
|
-
}
|
56
|
-
rectangle(0, 0, block_size, block_size) {
|
57
|
-
foreground bind(game_playfield[row][column], :color) { |color_value|
|
58
|
-
color_value == Model::Block::COLOR_CLEAR ? :gray : color_value
|
59
|
-
}
|
34
|
+
|
35
|
+
bevel(base_color: game_playfield[row][column].color, size: block_size) {
|
36
|
+
base_color bind(game_playfield[row][column], :color)
|
60
37
|
}
|
61
38
|
}
|
62
39
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-swt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.18.7.
|
4
|
+
version: 4.18.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -495,6 +495,7 @@ files:
|
|
495
495
|
- samples/elaborate/tetris/model/game.rb
|
496
496
|
- samples/elaborate/tetris/model/past_game.rb
|
497
497
|
- samples/elaborate/tetris/model/tetromino.rb
|
498
|
+
- samples/elaborate/tetris/view/bevel.rb
|
498
499
|
- samples/elaborate/tetris/view/block.rb
|
499
500
|
- samples/elaborate/tetris/view/high_score_dialog.rb
|
500
501
|
- samples/elaborate/tetris/view/playfield.rb
|