glimmer-dsl-swt 4.18.5.0 → 4.18.5.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +43 -0
- data/README.md +16 -11
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +179 -33
- data/docs/reference/GLIMMER_SAMPLES.md +58 -0
- data/glimmer-dsl-swt.gemspec +7 -7
- data/lib/glimmer/data_binding/widget_binding.rb +4 -1
- data/lib/glimmer/dsl/swt/dialog_expression.rb +18 -9
- data/lib/glimmer/dsl/swt/dsl.rb +1 -0
- data/lib/glimmer/dsl/swt/font_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/shape_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/shell_expression.rb +1 -1
- data/lib/glimmer/swt/custom/drawable.rb +10 -2
- data/lib/glimmer/swt/custom/shape.rb +458 -58
- data/lib/glimmer/swt/custom/shape/arc.rb +35 -0
- data/lib/glimmer/swt/custom/shape/focus.rb +2 -2
- data/lib/glimmer/swt/custom/shape/image.rb +35 -9
- data/lib/glimmer/swt/custom/shape/line.rb +88 -4
- data/lib/glimmer/swt/custom/shape/oval.rb +18 -0
- data/lib/glimmer/swt/custom/shape/point.rb +10 -5
- data/lib/glimmer/swt/custom/shape/polygon.rb +105 -15
- data/lib/glimmer/swt/custom/shape/polyline.rb +88 -15
- data/lib/glimmer/swt/custom/shape/rectangle.rb +19 -0
- data/lib/glimmer/swt/custom/shape/text.rb +13 -3
- data/lib/glimmer/swt/{directory_dialog_proxy.rb → dialog_proxy.rb} +36 -7
- data/lib/glimmer/swt/font_proxy.rb +12 -6
- data/lib/glimmer/swt/message_box_proxy.rb +1 -0
- data/lib/glimmer/swt/properties.rb +3 -0
- data/lib/glimmer/swt/proxy_properties.rb +145 -0
- data/lib/glimmer/swt/transform_proxy.rb +39 -35
- data/lib/glimmer/swt/widget_proxy.rb +32 -60
- data/samples/elaborate/contact_manager.rb +2 -0
- data/samples/elaborate/login.rb +2 -0
- data/samples/elaborate/mandelbrot_fractal.rb +1 -0
- data/samples/elaborate/meta_sample.rb +1 -0
- data/samples/elaborate/tetris.rb +2 -1
- data/samples/elaborate/tic_tac_toe.rb +2 -0
- data/samples/elaborate/user_profile.rb +10 -8
- data/samples/hello/hello_browser.rb +2 -0
- data/samples/hello/hello_button.rb +2 -0
- data/samples/hello/hello_canvas.rb +157 -77
- data/samples/hello/hello_canvas_animation.rb +2 -0
- data/samples/hello/hello_canvas_transform.rb +2 -0
- data/samples/hello/hello_checkbox.rb +2 -0
- data/samples/hello/hello_checkbox_group.rb +2 -0
- data/samples/hello/hello_code_text.rb +2 -0
- data/{lib/glimmer/dsl/swt/directory_dialog_expression.rb → samples/hello/hello_color_dialog.rb} +44 -24
- data/samples/hello/hello_combo.rb +2 -0
- data/samples/hello/hello_computed.rb +2 -0
- data/samples/hello/hello_cursor.rb +2 -0
- data/samples/hello/hello_custom_shell.rb +1 -0
- data/samples/hello/hello_custom_widget.rb +2 -0
- data/samples/hello/hello_date_time.rb +2 -0
- data/samples/hello/hello_dialog.rb +2 -0
- data/samples/hello/hello_directory_dialog.rb +2 -0
- data/samples/hello/hello_drag_and_drop.rb +5 -3
- data/samples/hello/hello_expand_bar.rb +2 -0
- data/samples/hello/hello_file_dialog.rb +2 -0
- data/samples/hello/hello_font_dialog.rb +84 -0
- data/samples/hello/hello_group.rb +2 -0
- data/samples/hello/hello_link.rb +2 -0
- data/samples/hello/hello_list_multi_selection.rb +2 -0
- data/samples/hello/hello_list_single_selection.rb +2 -0
- data/samples/hello/hello_menu_bar.rb +2 -0
- data/samples/hello/hello_message_box.rb +2 -0
- data/samples/hello/hello_pop_up_context_menu.rb +2 -0
- data/samples/hello/hello_progress_bar.rb +2 -0
- data/samples/hello/hello_radio.rb +2 -0
- data/samples/hello/hello_radio_group.rb +2 -0
- data/samples/hello/hello_sash_form.rb +2 -0
- data/samples/hello/hello_spinner.rb +2 -0
- data/samples/hello/hello_styled_text.rb +19 -17
- data/samples/hello/hello_tab.rb +2 -0
- data/samples/hello/hello_table.rb +2 -0
- data/samples/hello/hello_world.rb +2 -0
- metadata +6 -6
- data/lib/glimmer/dsl/swt/file_dialog_expression.rb +0 -48
- data/lib/glimmer/swt/file_dialog_proxy.rb +0 -68
@@ -36,6 +36,8 @@
|
|
36
36
|
- [Hello, Cursor!](#hello-cursor)
|
37
37
|
- [Hello, Progress Bar!](#hello-progress-bar)
|
38
38
|
- [Hello, Tree!](#hello-tree)
|
39
|
+
- [Hello, Color Dialog!](#hello-color-dialog)
|
40
|
+
- [Hello, Font Dialog!](#hello-font-dialog)
|
39
41
|
- [Elaborate Samples](#elaborate-samples)
|
40
42
|
- [User Profile](#user-profile)
|
41
43
|
- [Login](#login)
|
@@ -562,6 +564,30 @@ Hello, Canvas!
|
|
562
564
|
|
563
565
|
![Hello Canvas](/images/glimmer-hello-canvas.png)
|
564
566
|
|
567
|
+
Hello, Canvas! Moving Shapes and Nested Shapes via Drag'n'Drop
|
568
|
+
|
569
|
+
![Hello Canvas Moving Shapes](/images/glimmer-hello-canvas-moving-shapes.gif)
|
570
|
+
|
571
|
+
Hello, Canvas! with Moved Shapes (via Drag'n'Drop)
|
572
|
+
|
573
|
+
![Hello Canvas Moved Shapes](/images/glimmer-hello-canvas-moved-shapes.png)
|
574
|
+
|
575
|
+
Hello, Canvas! Menu (for background/foreground color changes)
|
576
|
+
|
577
|
+
![Hello Canvas Menu](/images/glimmer-hello-canvas-menu.png)
|
578
|
+
|
579
|
+
Hello, Canvas! Color Dialog
|
580
|
+
|
581
|
+
![Hello Canvas Color Dialog](/images/glimmer-hello-canvas-color-dialog.png)
|
582
|
+
|
583
|
+
Hello, Canvas! Colors Changed
|
584
|
+
|
585
|
+
![Hello Canvas Colors Changed](/images/glimmer-hello-canvas-colors-changed.png)
|
586
|
+
|
587
|
+
Hello, Canvas! Data-Binding (changing a `text` shape `string` via data-binding changes from another thread)
|
588
|
+
|
589
|
+
![Hello Canvas Data Binding](/images/glimmer-hello-canvas-data-binding.gif)
|
590
|
+
|
565
591
|
#### Hello, Canvas Animation!
|
566
592
|
|
567
593
|
This sample demonstrates the use of the `canvas` widget and [Animation DSL](#canvas-animation-dsl) in Glimmer.
|
@@ -630,6 +656,38 @@ Hello, Tree!
|
|
630
656
|
|
631
657
|
![Hello Tree](/images/glimmer-hello-tree.png)
|
632
658
|
|
659
|
+
#### Hello, Color Dialog!
|
660
|
+
|
661
|
+
This sample demonstrates the use of the `color_dialog` keyword.
|
662
|
+
|
663
|
+
Code:
|
664
|
+
|
665
|
+
[samples/hello/hello_color_dialog.rb](/samples/hello/hello_color_dialog.rb)
|
666
|
+
|
667
|
+
Hello, Color Dialog!
|
668
|
+
|
669
|
+
![Hello Color Dialog](/images/glimmer-hello-color-dialog.png)
|
670
|
+
|
671
|
+
![Hello Color Dialog Choose Color](/images/glimmer-hello-color-dialog-choose-color.png)
|
672
|
+
|
673
|
+
![Hello Color Dialog Color Changed](/images/glimmer-hello-color-dialog-color-changed.png)
|
674
|
+
|
675
|
+
#### Hello, Font Dialog!
|
676
|
+
|
677
|
+
This sample demonstrates the use of the `font_dialog` keyword.
|
678
|
+
|
679
|
+
Code:
|
680
|
+
|
681
|
+
[samples/hello/hello_font_dialog.rb](/samples/hello/hello_font_dialog.rb)
|
682
|
+
|
683
|
+
Hello, Font Dialog!
|
684
|
+
|
685
|
+
![Hello Font Dialog](/images/glimmer-hello-font-dialog.png)
|
686
|
+
|
687
|
+
![Hello Font Dialog Choose Font](/images/glimmer-hello-font-dialog-choose-font.png)
|
688
|
+
|
689
|
+
![Hello Font Dialog Font Changed](/images/glimmer-hello-font-dialog-font-changed.png)
|
690
|
+
|
633
691
|
### Elaborate Samples
|
634
692
|
|
635
693
|
For more elaborate samples, check the following:
|
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.5.
|
5
|
+
# stub: glimmer-dsl-swt 4.18.5.5 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-dsl-swt".freeze
|
9
|
-
s.version = "4.18.5.
|
9
|
+
s.version = "4.18.5.5"
|
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-02-
|
14
|
+
s.date = "2021-02-27"
|
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]
|
@@ -69,13 +69,11 @@ Gem::Specification.new do |s|
|
|
69
69
|
"lib/glimmer/dsl/swt/custom_widget_expression.rb",
|
70
70
|
"lib/glimmer/dsl/swt/data_binding_expression.rb",
|
71
71
|
"lib/glimmer/dsl/swt/dialog_expression.rb",
|
72
|
-
"lib/glimmer/dsl/swt/directory_dialog_expression.rb",
|
73
72
|
"lib/glimmer/dsl/swt/display_expression.rb",
|
74
73
|
"lib/glimmer/dsl/swt/dnd_expression.rb",
|
75
74
|
"lib/glimmer/dsl/swt/dsl.rb",
|
76
75
|
"lib/glimmer/dsl/swt/exec_expression.rb",
|
77
76
|
"lib/glimmer/dsl/swt/expand_item_expression.rb",
|
78
|
-
"lib/glimmer/dsl/swt/file_dialog_expression.rb",
|
79
77
|
"lib/glimmer/dsl/swt/font_expression.rb",
|
80
78
|
"lib/glimmer/dsl/swt/image_expression.rb",
|
81
79
|
"lib/glimmer/dsl/swt/layout_data_expression.rb",
|
@@ -127,11 +125,10 @@ Gem::Specification.new do |s|
|
|
127
125
|
"lib/glimmer/swt/custom/shape/rectangle.rb",
|
128
126
|
"lib/glimmer/swt/custom/shape/text.rb",
|
129
127
|
"lib/glimmer/swt/date_time_proxy.rb",
|
130
|
-
"lib/glimmer/swt/
|
128
|
+
"lib/glimmer/swt/dialog_proxy.rb",
|
131
129
|
"lib/glimmer/swt/display_proxy.rb",
|
132
130
|
"lib/glimmer/swt/dnd_proxy.rb",
|
133
131
|
"lib/glimmer/swt/expand_item_proxy.rb",
|
134
|
-
"lib/glimmer/swt/file_dialog_proxy.rb",
|
135
132
|
"lib/glimmer/swt/font_proxy.rb",
|
136
133
|
"lib/glimmer/swt/image_proxy.rb",
|
137
134
|
"lib/glimmer/swt/layout_data_proxy.rb",
|
@@ -140,6 +137,7 @@ Gem::Specification.new do |s|
|
|
140
137
|
"lib/glimmer/swt/message_box_proxy.rb",
|
141
138
|
"lib/glimmer/swt/packages.rb",
|
142
139
|
"lib/glimmer/swt/properties.rb",
|
140
|
+
"lib/glimmer/swt/proxy_properties.rb",
|
143
141
|
"lib/glimmer/swt/sash_form_proxy.rb",
|
144
142
|
"lib/glimmer/swt/scrolled_composite_proxy.rb",
|
145
143
|
"lib/glimmer/swt/shell_proxy.rb",
|
@@ -186,6 +184,7 @@ Gem::Specification.new do |s|
|
|
186
184
|
"samples/hello/hello_checkbox.rb",
|
187
185
|
"samples/hello/hello_checkbox_group.rb",
|
188
186
|
"samples/hello/hello_code_text.rb",
|
187
|
+
"samples/hello/hello_color_dialog.rb",
|
189
188
|
"samples/hello/hello_combo.rb",
|
190
189
|
"samples/hello/hello_computed.rb",
|
191
190
|
"samples/hello/hello_computed/contact.rb",
|
@@ -198,6 +197,7 @@ Gem::Specification.new do |s|
|
|
198
197
|
"samples/hello/hello_drag_and_drop.rb",
|
199
198
|
"samples/hello/hello_expand_bar.rb",
|
200
199
|
"samples/hello/hello_file_dialog.rb",
|
200
|
+
"samples/hello/hello_font_dialog.rb",
|
201
201
|
"samples/hello/hello_group.rb",
|
202
202
|
"samples/hello/hello_link.rb",
|
203
203
|
"samples/hello/hello_list_multi_selection.rb",
|
@@ -52,7 +52,10 @@ module Glimmer
|
|
52
52
|
unregister_all_observables
|
53
53
|
return
|
54
54
|
end
|
55
|
-
|
55
|
+
# need the rescue false for a scenario with tree items not being equal to model objects raising an exception
|
56
|
+
unless ((value == evaluate_property) rescue false) # need the rescue false for a scenario with tree items not being equal to model objects raising an exception
|
57
|
+
@widget.set_attribute(@property, value)
|
58
|
+
end
|
56
59
|
end
|
57
60
|
end
|
58
61
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (c) 2007-2021 Andy Maleh
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
# a copy of this software and associated documentation files (the
|
5
5
|
# "Software"), to deal in the Software without restriction, including
|
@@ -7,10 +7,10 @@
|
|
7
7
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
8
|
# permit persons to whom the Software is furnished to do so, subject to
|
9
9
|
# the following conditions:
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# The above copyright notice and this permission notice shall be
|
12
12
|
# included in all copies or substantial portions of the Software.
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
15
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
16
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
@@ -23,24 +23,33 @@ require 'glimmer/dsl/static_expression'
|
|
23
23
|
require 'glimmer/dsl/parent_expression'
|
24
24
|
require 'glimmer/dsl/top_level_expression'
|
25
25
|
require 'glimmer/swt/shell_proxy'
|
26
|
+
require 'glimmer/swt/dialog_proxy'
|
26
27
|
|
27
28
|
module Glimmer
|
28
29
|
module DSL
|
29
30
|
module SWT
|
30
|
-
class DialogExpression <
|
31
|
+
class DialogExpression < Expression
|
31
32
|
include TopLevelExpression
|
32
33
|
include ParentExpression
|
33
34
|
|
34
35
|
def can_interpret?(parent, keyword, *args, &block)
|
35
|
-
|
36
|
-
(
|
36
|
+
(
|
37
|
+
(keyword == 'dialog') or
|
38
|
+
(keyword.to_s.end_with?('dialog') and Glimmer::SWT::DialogProxy.dialog_class(keyword))
|
39
|
+
) and
|
40
|
+
(parent.nil? or parent.is_a?(org.eclipse.swt.widgets.Shell) or parent.is_a?(Glimmer::SWT::ShellProxy))
|
37
41
|
end
|
38
42
|
|
39
43
|
def interpret(parent, keyword, *args, &block)
|
40
44
|
# TODO reconcile this with the actual org.eclipse.swt.widgets.Dialog widget (maybe rename this as dialog_shell)
|
41
|
-
|
42
|
-
|
43
|
-
|
45
|
+
if keyword == 'dialog'
|
46
|
+
args = [parent] + args unless parent.nil?
|
47
|
+
args += [:dialog_trim, :application_modal]
|
48
|
+
Glimmer::SWT::ShellProxy.new(*args)
|
49
|
+
else
|
50
|
+
args = [parent] + args unless parent.nil?
|
51
|
+
Glimmer::SWT::DialogProxy.new(keyword, *args)
|
52
|
+
end
|
44
53
|
end
|
45
54
|
end
|
46
55
|
end
|
data/lib/glimmer/dsl/swt/dsl.rb
CHANGED
@@ -37,7 +37,7 @@ module Glimmer
|
|
37
37
|
(parent.nil? || !parent.respond_to?('font')) and
|
38
38
|
!parent.is_a?(Glimmer::SWT::Custom::Shape) and
|
39
39
|
args.size == 1 and
|
40
|
-
args.first.is_a?(Hash)
|
40
|
+
(args.first.is_a?(Hash) || args.first.is_a?(org.eclipse.swt.graphics.FontData))
|
41
41
|
end
|
42
42
|
|
43
43
|
def interpret(parent, keyword, *args, &block)
|
@@ -32,7 +32,7 @@ module Glimmer
|
|
32
32
|
include ParentExpression
|
33
33
|
|
34
34
|
def can_interpret?(parent, keyword, *args, &block)
|
35
|
-
parent.is_a?(Glimmer::SWT::Custom::Drawable) and
|
35
|
+
(parent.is_a?(Glimmer::SWT::Custom::Drawable) or parent.is_a?(Glimmer::SWT::Custom::Shape)) and
|
36
36
|
Glimmer::SWT::Custom::Shape.valid?(parent, keyword, *args, &block)
|
37
37
|
end
|
38
38
|
|
@@ -34,12 +34,20 @@ module Glimmer
|
|
34
34
|
@shapes ||= []
|
35
35
|
end
|
36
36
|
|
37
|
+
def expanded_shapes
|
38
|
+
@shapes.map do |shape|
|
39
|
+
[shape] + shape.expanded_shapes
|
40
|
+
end.flatten
|
41
|
+
end
|
42
|
+
|
37
43
|
def image_buffered_shapes
|
38
44
|
@image_buffered_shapes ||= []
|
39
45
|
end
|
40
46
|
|
47
|
+
# TODO add a method like shapes that specifies drawable_properties to be able to adjust properties like transform in between shapes
|
48
|
+
|
41
49
|
def shape_at_location(x, y)
|
42
|
-
|
50
|
+
expanded_shapes.reverse.detect {|shape| shape.include?(x, y)}
|
43
51
|
end
|
44
52
|
|
45
53
|
def add_shape(shape)
|
@@ -132,7 +140,7 @@ module Glimmer
|
|
132
140
|
@paint_listener_proxy = on_swt_paint(&shape_painter)
|
133
141
|
end
|
134
142
|
else
|
135
|
-
redraw if @finished_add_content && !is_disposed
|
143
|
+
redraw if respond_to?(:redraw) && @finished_add_content && !is_disposed
|
136
144
|
end
|
137
145
|
end
|
138
146
|
alias resetup_shape_painting setup_shape_painting
|
@@ -26,6 +26,34 @@ require 'glimmer/swt/color_proxy'
|
|
26
26
|
require 'glimmer/swt/font_proxy'
|
27
27
|
require 'glimmer/swt/transform_proxy'
|
28
28
|
|
29
|
+
class Java::OrgEclipseSwtGraphics::GC
|
30
|
+
def setLineDashOffset(value)
|
31
|
+
lineMiterLimit = getLineAttributes&.miterLimit || 999_999
|
32
|
+
setLineAttributes(Java::OrgEclipseSwtGraphics::LineAttributes.new(getLineWidth, getLineCap, getLineJoin, getLineStyle, getLineDash.map(&:to_f).to_java(:float), value, lineMiterLimit))
|
33
|
+
end
|
34
|
+
alias set_line_dash_offset setLineDashOffset
|
35
|
+
alias line_dash_offset= setLineDashOffset
|
36
|
+
|
37
|
+
def getLineDashOffset
|
38
|
+
getLineAttributes&.dashOffset
|
39
|
+
end
|
40
|
+
alias get_line_dash_offset getLineDashOffset
|
41
|
+
alias line_dash_offset getLineDashOffset
|
42
|
+
|
43
|
+
def setLineMiterLimit(value)
|
44
|
+
lineDashOffset = getLineAttributes&.dashOffset || 0
|
45
|
+
setLineAttributes(Java::OrgEclipseSwtGraphics::LineAttributes.new(getLineWidth, getLineCap, getLineJoin, getLineStyle, getLineDash.map(&:to_f).to_java(:float), lineDashOffset, value))
|
46
|
+
end
|
47
|
+
alias set_line_miter_limit setLineMiterLimit
|
48
|
+
alias line_miter_limit= setLineMiterLimit
|
49
|
+
|
50
|
+
def getLineMiterLimit
|
51
|
+
getLineAttributes&.miterLimit
|
52
|
+
end
|
53
|
+
alias get_line_miter_limit getLineMiterLimit
|
54
|
+
alias line_miter_limit getLineMiterLimit
|
55
|
+
end
|
56
|
+
|
29
57
|
module Glimmer
|
30
58
|
module SWT
|
31
59
|
module Custom
|
@@ -34,8 +62,6 @@ module Glimmer
|
|
34
62
|
class Shape
|
35
63
|
include Packages
|
36
64
|
include Properties
|
37
|
-
# TODO support textExtent sized shapes nested within text/string
|
38
|
-
# TODO support a Pattern DSL for methods that take Pattern arguments
|
39
65
|
|
40
66
|
class << self
|
41
67
|
def create(parent, keyword, *args, &property_block)
|
@@ -100,15 +126,18 @@ module Glimmer
|
|
100
126
|
end
|
101
127
|
end
|
102
128
|
|
103
|
-
attr_reader :parent, :name, :args, :options
|
129
|
+
attr_reader :drawable, :parent, :name, :args, :options, :shapes
|
130
|
+
attr_accessor :extent
|
104
131
|
|
105
132
|
def initialize(parent, keyword, *args, &property_block)
|
106
133
|
@parent = parent
|
134
|
+
@drawable = @parent.is_a?(Drawable) ? @parent : @parent.drawable
|
107
135
|
@name = keyword
|
108
136
|
@options = self.class.arg_options(args, extract: true)
|
109
137
|
@method_name = self.class.method_name(keyword, @options)
|
110
138
|
@args = args
|
111
139
|
@properties = {}
|
140
|
+
@shapes = [] # nested shapes
|
112
141
|
@options.reject {|key, value| %w[fill gradient round].include?(key.to_s)}.each do |property, property_args|
|
113
142
|
@properties[property] = property_args
|
114
143
|
end
|
@@ -116,13 +145,20 @@ module Glimmer
|
|
116
145
|
post_add_content if property_block.nil?
|
117
146
|
end
|
118
147
|
|
148
|
+
def add_shape(shape)
|
149
|
+
@shapes << shape
|
150
|
+
calculated_args_changed_for_defaults!
|
151
|
+
end
|
152
|
+
|
119
153
|
def draw?
|
120
154
|
!fill?
|
121
155
|
end
|
156
|
+
alias drawn? draw?
|
122
157
|
|
123
158
|
def fill?
|
124
159
|
@options[:fill]
|
125
160
|
end
|
161
|
+
alias filled? fill?
|
126
162
|
|
127
163
|
def gradient?
|
128
164
|
@options[:gradient]
|
@@ -132,26 +168,60 @@ module Glimmer
|
|
132
168
|
@options[:round]
|
133
169
|
end
|
134
170
|
|
135
|
-
#
|
136
|
-
|
171
|
+
# The bounding box top-left x, y, width, height in absolute positioning
|
172
|
+
def bounds
|
173
|
+
org.eclipse.swt.graphics.Rectangle.new(absolute_x, absolute_y, calculated_width, calculated_height)
|
174
|
+
end
|
175
|
+
|
176
|
+
# The bounding box top-left x and y
|
177
|
+
def location
|
178
|
+
org.eclipse.swt.graphics.Point.new(bounds.x, bounds.y)
|
179
|
+
end
|
180
|
+
|
181
|
+
# The bounding box width and height (as a Point object with x being width and y being height)
|
182
|
+
def size
|
183
|
+
org.eclipse.swt.graphics.Point.new(calculated_width, calculated_height)
|
184
|
+
end
|
185
|
+
|
186
|
+
def extent
|
187
|
+
@extent || size
|
188
|
+
end
|
189
|
+
|
190
|
+
# Returns if shape contains a point
|
191
|
+
# Subclasses (like polygon) may override to indicate if a point x,y coordinates falls inside the shape
|
192
|
+
# some shapes may choose to provide a fuzz factor to make usage of this method for mouse clicking more user friendly
|
193
|
+
def contain?(x, y)
|
194
|
+
# assume a rectangular filled shape by default (works for several shapes like image, text, and focus)
|
195
|
+
x.between?(self.absolute_x, self.absolute_x + calculated_width) && y.between?(self.absolute_y, self.absolute_y + calculated_height)
|
196
|
+
end
|
197
|
+
|
198
|
+
# Returns if shape includes a point. When the shape is filled, this is the same as contain. When the shape is drawn, it only returns true if the point lies on the edge (boundary/border)
|
199
|
+
# Subclasses (like polygon) may override to indicate if a point x,y coordinates falls on the edge of a drawn shape or inside a filled shape
|
200
|
+
# some shapes may choose to provide a fuzz factor to make usage of this method for mouse clicking more user friendly
|
137
201
|
def include?(x, y)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
else
|
146
|
-
false
|
147
|
-
end
|
202
|
+
# assume a rectangular shape by default
|
203
|
+
contain?(x, y)
|
204
|
+
end
|
205
|
+
|
206
|
+
# Indicates if a shape's x, y, width, height differ from its bounds calculation (e.g. arc / polygon)
|
207
|
+
def irregular?
|
208
|
+
false
|
148
209
|
end
|
149
210
|
|
211
|
+
# moves by x delta and y delta. Subclasses must implement
|
212
|
+
# provdies a default implementation that assumes moving x and y is sufficient by default (not for polygons though, which must override)
|
150
213
|
def move_by(x_delta, y_delta)
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
214
|
+
if respond_to?(:x) && respond_to?(:y) && respond_to?(:x=) && respond_to?(:y=)
|
215
|
+
if default_x?
|
216
|
+
self.default_x_delta += x_delta
|
217
|
+
else
|
218
|
+
self.x += x_delta
|
219
|
+
end
|
220
|
+
if default_y?
|
221
|
+
self.default_y_delta += y_delta
|
222
|
+
else
|
223
|
+
self.y += y_delta
|
224
|
+
end
|
155
225
|
end
|
156
226
|
end
|
157
227
|
|
@@ -166,7 +236,7 @@ module Glimmer
|
|
166
236
|
def post_add_content
|
167
237
|
unless @content_added
|
168
238
|
amend_method_name_options_based_on_properties!
|
169
|
-
@
|
239
|
+
@drawable.setup_shape_painting unless @drawable.is_a?(ImageProxy)
|
170
240
|
@content_added = true
|
171
241
|
end
|
172
242
|
end
|
@@ -174,10 +244,18 @@ module Glimmer
|
|
174
244
|
def apply_property_arg_conversions(method_name, property, args)
|
175
245
|
args = args.dup
|
176
246
|
the_java_method = org.eclipse.swt.graphics.GC.java_class.declared_instance_methods.detect {|m| m.name == method_name}
|
247
|
+
return args if the_java_method.nil?
|
248
|
+
if the_java_method.parameter_types.first == Color.java_class && args.first.is_a?(RGB)
|
249
|
+
args[0] = [args[0].red, args[0].green, args[0].blue]
|
250
|
+
end
|
177
251
|
if ['setBackground', 'setForeground'].include?(method_name.to_s) && args.first.is_a?(Array)
|
178
252
|
args[0] = ColorProxy.new(args[0])
|
179
253
|
end
|
180
|
-
if
|
254
|
+
if method_name.to_s == 'setLineDash' && args.size > 1
|
255
|
+
args[0] = args.dup
|
256
|
+
args[1..-1] = []
|
257
|
+
end
|
258
|
+
if args.first.is_a?(Symbol) || args.first.is_a?(::String)
|
181
259
|
if the_java_method.parameter_types.first == Color.java_class
|
182
260
|
args[0] = ColorProxy.new(args[0])
|
183
261
|
end
|
@@ -188,7 +266,7 @@ module Glimmer
|
|
188
266
|
if args.first.is_a?(ColorProxy)
|
189
267
|
args[0] = args[0].swt_color
|
190
268
|
end
|
191
|
-
if args.first.is_a?(Hash) && the_java_method.parameter_types.first == Font.java_class
|
269
|
+
if (args.first.is_a?(Hash) || args.first.is_a?(FontData)) && the_java_method.parameter_types.first == Font.java_class
|
192
270
|
args[0] = FontProxy.new(args[0])
|
193
271
|
end
|
194
272
|
if args.first.is_a?(FontProxy)
|
@@ -198,21 +276,21 @@ module Glimmer
|
|
198
276
|
args[0] = args[0].swt_transform
|
199
277
|
end
|
200
278
|
if ['setBackgroundPattern', 'setForegroundPattern'].include?(method_name.to_s)
|
201
|
-
@
|
279
|
+
@drawable.requires_shape_disposal = true
|
280
|
+
args = args.first if args.first.is_a?(Array)
|
202
281
|
args.each_with_index do |arg, i|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
end
|
282
|
+
arg = ColorProxy.new(arg.red, arg.green, arg.blue) if arg.is_a?(RGB)
|
283
|
+
arg = ColorProxy.new(arg) if arg.is_a?(Symbol) || arg.is_a?(::String)
|
284
|
+
arg = arg.swt_color if arg.is_a?(ColorProxy)
|
285
|
+
args[i] = arg
|
208
286
|
end
|
209
287
|
@pattern_args ||= {}
|
210
288
|
pattern_type = method_name.to_s.match(/set(.+)Pattern/)[1]
|
211
289
|
if args.first.is_a?(Pattern)
|
212
290
|
new_args = @pattern_args[pattern_type]
|
213
291
|
else
|
214
|
-
new_args = [DisplayProxy.instance.swt_display] + args
|
215
|
-
@pattern_args[pattern_type] = new_args
|
292
|
+
new_args = args.first.is_a?(Display) ? args : ([DisplayProxy.instance.swt_display] + args)
|
293
|
+
@pattern_args[pattern_type] = new_args.dup
|
216
294
|
end
|
217
295
|
args[0] = pattern(*new_args, type: pattern_type)
|
218
296
|
args[1..-1] = []
|
@@ -226,7 +304,7 @@ module Glimmer
|
|
226
304
|
@args[1..-1] = []
|
227
305
|
end
|
228
306
|
if @name == 'image'
|
229
|
-
if @args.first.is_a?(String)
|
307
|
+
if @args.first.is_a?(::String)
|
230
308
|
@args[0] = ImageProxy.new(@args[0])
|
231
309
|
end
|
232
310
|
if @args.first.is_a?(ImageProxy)
|
@@ -237,7 +315,7 @@ module Glimmer
|
|
237
315
|
end
|
238
316
|
end
|
239
317
|
if @name == 'text'
|
240
|
-
if @args[3].is_a?(Symbol) || @args[3].is_a?(String)
|
318
|
+
if @args[3].is_a?(Symbol) || @args[3].is_a?(::String)
|
241
319
|
@args[3] = [@args[3]]
|
242
320
|
end
|
243
321
|
if @args[3].is_a?(Array)
|
@@ -250,19 +328,21 @@ module Glimmer
|
|
250
328
|
end
|
251
329
|
|
252
330
|
def apply_shape_arg_defaults!
|
331
|
+
self.x = :default if current_parameter_name?(:x) && x.nil?
|
332
|
+
self.y = :default if current_parameter_name?(:y) && y.nil?
|
333
|
+
self.dest_x = :default if current_parameter_name?(:dest_x) && dest_x.nil?
|
334
|
+
self.dest_y = :default if current_parameter_name?(:dest_y) && dest_y.nil?
|
335
|
+
self.width = :default if current_parameter_name?(:width) && width.nil?
|
336
|
+
self.height = :default if current_parameter_name?(:height) && height.nil?
|
253
337
|
if @name.include?('rectangle') && round? && @args.size.between?(4, 5)
|
254
338
|
(6 - @args.size).times {@args << 60}
|
255
339
|
elsif @name.include?('rectangle') && gradient? && @args.size == 4
|
256
|
-
|
257
|
-
elsif (@name.include?('text') || @name.include?('
|
258
|
-
|
340
|
+
set_attribute('vertical', true, redraw: false)
|
341
|
+
elsif (@name.include?('text') || @name.include?('string')) && !@properties.keys.map(&:to_s).include?('background') && @args.size < 4
|
342
|
+
set_attribute('is_transparent', true, redraw: false)
|
259
343
|
end
|
260
344
|
if @name.include?('image')
|
261
|
-
@
|
262
|
-
if @args.size == 1
|
263
|
-
@args[1] = 0
|
264
|
-
@args[2] = 0
|
265
|
-
end
|
345
|
+
@drawable.requires_shape_disposal = true
|
266
346
|
end
|
267
347
|
end
|
268
348
|
|
@@ -279,7 +359,7 @@ module Glimmer
|
|
279
359
|
|
280
360
|
def amend_method_name_options_based_on_properties!
|
281
361
|
return if @name == 'point'
|
282
|
-
if @name != 'text' && has_some_background? && !has_some_foreground?
|
362
|
+
if @name != 'text' && @name != 'string' && has_some_background? && !has_some_foreground?
|
283
363
|
@options[:fill] = true
|
284
364
|
elsif !has_some_background? && has_some_foreground?
|
285
365
|
@options[:fill] = false
|
@@ -298,6 +378,12 @@ module Glimmer
|
|
298
378
|
[]
|
299
379
|
end
|
300
380
|
|
381
|
+
# subclasses may override to specify location parameter names if different from x and y (e.g. all polygon points are location parameters)
|
382
|
+
# used in calculating movement changes
|
383
|
+
def location_parameter_names
|
384
|
+
[:x, :y]
|
385
|
+
end
|
386
|
+
|
301
387
|
def possible_parameter_names
|
302
388
|
parameter_names
|
303
389
|
end
|
@@ -306,8 +392,12 @@ module Glimmer
|
|
306
392
|
possible_parameter_names.map(&:to_s).include?(ruby_attribute_getter(attribute_name))
|
307
393
|
end
|
308
394
|
|
395
|
+
def current_parameter_name?(attribute_name)
|
396
|
+
parameter_names.include?(attribute_name.to_s.to_sym)
|
397
|
+
end
|
398
|
+
|
309
399
|
def parameter_index(attribute_name)
|
310
|
-
parameter_names.
|
400
|
+
parameter_names.index(attribute_name.to_s.to_sym)
|
311
401
|
end
|
312
402
|
|
313
403
|
def set_parameter_attribute(attribute_name, *args)
|
@@ -316,24 +406,44 @@ module Glimmer
|
|
316
406
|
|
317
407
|
def has_attribute?(attribute_name, *args)
|
318
408
|
self.class.gc_instance_methods.include?(attribute_setter(attribute_name)) or
|
319
|
-
parameter_name?(attribute_name)
|
409
|
+
parameter_name?(attribute_name) or
|
410
|
+
(respond_to?(attribute_name, super: true) and respond_to?(ruby_attribute_setter(attribute_name), super: true))
|
320
411
|
end
|
321
|
-
|
412
|
+
|
322
413
|
def set_attribute(attribute_name, *args)
|
414
|
+
options = args.last if args.last.is_a?(Hash)
|
415
|
+
args.pop if !options.nil? && !options[:redraw].nil?
|
416
|
+
perform_redraw = @perform_redraw
|
417
|
+
perform_redraw = options[:redraw] if perform_redraw.nil? && !options.nil?
|
418
|
+
perform_redraw = true if perform_redraw.nil?
|
323
419
|
if parameter_name?(attribute_name)
|
324
420
|
set_parameter_attribute(attribute_name, *args)
|
421
|
+
elsif (respond_to?(attribute_name, super: true) and respond_to?(ruby_attribute_setter(attribute_name), super: true))
|
422
|
+
self.send(ruby_attribute_setter(attribute_name), *args)
|
325
423
|
else
|
326
|
-
@properties[attribute_name] = args
|
424
|
+
@properties[ruby_attribute_getter(attribute_name)] = args
|
327
425
|
end
|
328
|
-
if @content_added &&
|
426
|
+
if @content_added && perform_redraw && !drawable.is_disposed
|
329
427
|
@calculated_paint_args = false
|
330
|
-
|
428
|
+
attribute_name = ruby_attribute_getter(attribute_name)
|
429
|
+
if location_parameter_names.map(&:to_s).include?(attribute_name)
|
430
|
+
@calculated_args = nil
|
431
|
+
parent.calculated_args_changed_for_defaults! if parent.is_a?(Shape)
|
432
|
+
end
|
433
|
+
if ['width', 'height'].include?(attribute_name)
|
434
|
+
calculated_args_changed_for_defaults!
|
435
|
+
end
|
436
|
+
# TODO consider redrawing an image proxy's gc in the future
|
437
|
+
drawable.redraw unless drawable.is_a?(ImageProxy)
|
331
438
|
end
|
332
439
|
end
|
333
440
|
|
334
441
|
def get_attribute(attribute_name)
|
335
442
|
if parameter_name?(attribute_name)
|
336
|
-
|
443
|
+
arg_index = parameter_index(attribute_name)
|
444
|
+
@args[arg_index] if arg_index
|
445
|
+
elsif (respond_to?(attribute_name, super: true) and respond_to?(ruby_attribute_setter(attribute_name), super: true))
|
446
|
+
self.send(attribute_name)
|
337
447
|
else
|
338
448
|
@properties.symbolize_keys[attribute_name.to_s.to_sym]
|
339
449
|
end
|
@@ -350,7 +460,9 @@ module Glimmer
|
|
350
460
|
end
|
351
461
|
|
352
462
|
def respond_to?(method_name, *args, &block)
|
353
|
-
if
|
463
|
+
options = args.last if args.last.is_a?(Hash)
|
464
|
+
super_invocation = options && options[:super]
|
465
|
+
if !super_invocation && has_attribute?(method_name)
|
354
466
|
true
|
355
467
|
else
|
356
468
|
super
|
@@ -366,6 +478,18 @@ module Glimmer
|
|
366
478
|
the_pattern
|
367
479
|
end
|
368
480
|
|
481
|
+
def pattern_args(type: nil)
|
482
|
+
@pattern_args && @pattern_args[type.to_s.capitalize]
|
483
|
+
end
|
484
|
+
|
485
|
+
def background_pattern_args
|
486
|
+
pattern_args(type: 'background')
|
487
|
+
end
|
488
|
+
|
489
|
+
def foreground_pattern_args
|
490
|
+
pattern_args(type: 'foreground')
|
491
|
+
end
|
492
|
+
|
369
493
|
def dispose(dispose_images: true, dispose_patterns: true)
|
370
494
|
if dispose_patterns
|
371
495
|
@background_pattern&.dispose
|
@@ -379,21 +503,297 @@ module Glimmer
|
|
379
503
|
end
|
380
504
|
@parent.shapes.delete(self)
|
381
505
|
end
|
382
|
-
|
506
|
+
|
383
507
|
def paint(paint_event)
|
508
|
+
# pre-paint children an extra-time first when default width/height need to be calculated for defaults
|
509
|
+
paint_children(paint_event) if default_width? || default_height?
|
510
|
+
paint_self(paint_event)
|
511
|
+
# re-paint children from scratch in the special case of pre-calculating parent width/height to re-center within new parent dimensions
|
512
|
+
shapes.each(&:calculated_args_changed!) if default_width? || default_height?
|
513
|
+
paint_children(paint_event)
|
514
|
+
rescue => e
|
515
|
+
Glimmer::Config.logger.error {"Error encountered in painting shape (#{self.inspect}) with calculated args (#{@calculated_args}) and args (#{@args})"}
|
516
|
+
Glimmer::Config.logger.error {e.full_message}
|
517
|
+
end
|
518
|
+
|
519
|
+
def paint_self(paint_event)
|
520
|
+
@painting = true
|
384
521
|
calculate_paint_args!
|
522
|
+
@original_properties_backup = {}
|
385
523
|
@properties.each do |property, args|
|
386
524
|
method_name = attribute_setter(property)
|
387
|
-
|
525
|
+
@original_properties_backup[method_name] = paint_event.gc.send(method_name.sub('set', 'get')) rescue nil
|
388
526
|
paint_event.gc.send(method_name, *args)
|
389
527
|
if property == 'transform' && args.first.is_a?(TransformProxy)
|
390
528
|
args.first.swt_transform.dispose
|
391
529
|
end
|
392
530
|
end
|
393
|
-
paint_event
|
531
|
+
ensure_extent(paint_event)
|
532
|
+
if !@calculated_args || parent_shape_absolute_location_changed?
|
533
|
+
@calculated_args = calculated_args
|
534
|
+
end
|
535
|
+
# 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
|
536
|
+
paint_event.gc.send(@method_name, *@calculated_args) unless parent.is_a?(Shape) && !parent.calculated_args?
|
537
|
+
@original_properties_backup.each do |method_name, value|
|
538
|
+
paint_event.gc.send(method_name, value)
|
539
|
+
end
|
540
|
+
@painting = false
|
394
541
|
rescue => e
|
395
|
-
Glimmer::Config.logger.error {"Error encountered in painting shape
|
542
|
+
Glimmer::Config.logger.error {"Error encountered in painting shape (#{self.inspect}) with calculated args (#{@calculated_args}) and args (#{@args})"}
|
396
543
|
Glimmer::Config.logger.error {e.full_message}
|
544
|
+
ensure
|
545
|
+
@painting = false
|
546
|
+
end
|
547
|
+
|
548
|
+
def paint_children(paint_event)
|
549
|
+
shapes.to_a.each do |shape|
|
550
|
+
shape.paint(paint_event)
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
def ensure_extent(paint_event)
|
555
|
+
old_extent = @extent
|
556
|
+
if ['text', 'string'].include?(@name)
|
557
|
+
extent_args = [string]
|
558
|
+
extent_flags = SWTProxy[:draw_transparent] if current_parameter_name?(:is_transparent) && is_transparent
|
559
|
+
extent_flags = flags if current_parameter_name?(:flags)
|
560
|
+
extent_args << extent_flags unless extent_flags.nil?
|
561
|
+
self.extent = paint_event.gc.send("#{@name}Extent", *extent_args)
|
562
|
+
end
|
563
|
+
if !@extent.nil? && (old_extent&.x != @extent&.x || old_extent&.y != @extent&.y)
|
564
|
+
calculated_args_changed!
|
565
|
+
parent.calculated_args_changed_for_defaults! if parent.is_a?(Shape)
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
def expanded_shapes
|
570
|
+
if shapes.to_a.any?
|
571
|
+
shapes.map do |shape|
|
572
|
+
[shape] + shape.expanded_shapes
|
573
|
+
end.flatten
|
574
|
+
else
|
575
|
+
[]
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
def parent_shape_absolute_location_changed?
|
580
|
+
(parent.is_a?(Shape) && (parent.absolute_x != @parent_absolute_x || parent.absolute_y != @parent_absolute_y))
|
581
|
+
end
|
582
|
+
|
583
|
+
def calculated_args_changed!(children: true)
|
584
|
+
# TODO add a children: true option to enable setting to false to avoid recalculating children args
|
585
|
+
@calculated_args = nil
|
586
|
+
shapes.each(&:calculated_args_changed!) if children
|
587
|
+
end
|
588
|
+
|
589
|
+
def calculated_args_changed_for_defaults!
|
590
|
+
has_default_dimensions = default_width? || default_height?
|
591
|
+
parent_calculated_args_changed_for_defaults = has_default_dimensions
|
592
|
+
@calculated_args = nil if default_x? || default_y? || has_default_dimensions
|
593
|
+
if has_default_dimensions && parent.is_a?(Shape)
|
594
|
+
parent.calculated_args_changed_for_defaults!
|
595
|
+
elsif @content_added && !drawable.is_disposed
|
596
|
+
# 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
|
597
|
+
drawable.redraw if !@painting && !drawable.is_a?(ImageProxy)
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
def calculated_args?
|
602
|
+
!!@calculated_args
|
603
|
+
end
|
604
|
+
|
605
|
+
# args translated to absolute coordinates
|
606
|
+
def calculated_args
|
607
|
+
return @args if !default_x? && !default_y? && !default_width? && !default_height? && parent.is_a?(Drawable)
|
608
|
+
# 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
|
609
|
+
# TODO change that by setting a bounding box for all shapes with a calculated top-left x, y and
|
610
|
+
# a setter that does the moving inside them instead so that I could rely on absolute_x and absolute_y
|
611
|
+
# here to get the job done of calculating absolute args
|
612
|
+
@perform_redraw = false
|
613
|
+
original_x = nil
|
614
|
+
original_y = nil
|
615
|
+
original_width = nil
|
616
|
+
original_height = nil
|
617
|
+
if parent.is_a?(Shape)
|
618
|
+
@parent_absolute_x = parent.absolute_x
|
619
|
+
@parent_absolute_y = parent.absolute_y
|
620
|
+
end
|
621
|
+
if default_width?
|
622
|
+
original_width = width
|
623
|
+
self.width = default_width + default_width_delta
|
624
|
+
end
|
625
|
+
if default_height?
|
626
|
+
original_height = height
|
627
|
+
self.height = default_height + default_height_delta
|
628
|
+
end
|
629
|
+
if default_x?
|
630
|
+
original_x = x
|
631
|
+
self.x = default_x + default_x_delta
|
632
|
+
end
|
633
|
+
if default_y?
|
634
|
+
original_y = y
|
635
|
+
self.y = default_y + default_y_delta
|
636
|
+
end
|
637
|
+
if parent.is_a?(Shape)
|
638
|
+
move_by(@parent_absolute_x, @parent_absolute_y)
|
639
|
+
result_args = @args.clone
|
640
|
+
move_by(-1*@parent_absolute_x, -1*@parent_absolute_y)
|
641
|
+
else
|
642
|
+
result_args = @args.clone
|
643
|
+
end
|
644
|
+
if original_x
|
645
|
+
self.x = original_x
|
646
|
+
end
|
647
|
+
if original_y
|
648
|
+
self.y = original_y
|
649
|
+
end
|
650
|
+
if original_width
|
651
|
+
self.width = original_width
|
652
|
+
end
|
653
|
+
if original_height
|
654
|
+
self.height = original_height
|
655
|
+
end
|
656
|
+
@perform_redraw = true
|
657
|
+
result_args
|
658
|
+
end
|
659
|
+
|
660
|
+
def default_x?
|
661
|
+
current_parameter_name?(:x) and
|
662
|
+
(x.nil? || x.to_s == 'default' || (x.is_a?(Array) && x.first.to_s == 'default'))
|
663
|
+
end
|
664
|
+
|
665
|
+
def default_y?
|
666
|
+
current_parameter_name?(:y) and
|
667
|
+
(y.nil? || y.to_s == 'default' || (y.is_a?(Array) && y.first.to_s == 'default'))
|
668
|
+
end
|
669
|
+
|
670
|
+
def default_width?
|
671
|
+
return false unless current_parameter_name?(:width)
|
672
|
+
width = self.width
|
673
|
+
(width.nil? || width == :default || width == 'default' || (width.is_a?(Array) && (width.first.to_s == :default || width.first.to_s == 'default')))
|
674
|
+
end
|
675
|
+
|
676
|
+
def default_height?
|
677
|
+
return false unless current_parameter_name?(:height)
|
678
|
+
height = self.height
|
679
|
+
(height.nil? || height == :default || height == 'default' || (height.is_a?(Array) && (height.first.to_s == :default || height.first.to_s == 'default')))
|
680
|
+
end
|
681
|
+
|
682
|
+
def default_x
|
683
|
+
result = ((parent.size.x - size.x) / 2)
|
684
|
+
result += parent.bounds.x - parent.absolute_x if parent.is_a?(Shape) && parent.irregular?
|
685
|
+
result
|
686
|
+
end
|
687
|
+
|
688
|
+
def default_y
|
689
|
+
result = ((parent.size.y - size.y) / 2)
|
690
|
+
result += parent.bounds.y - parent.absolute_y if parent.is_a?(Shape) && parent.irregular?
|
691
|
+
result
|
692
|
+
end
|
693
|
+
|
694
|
+
def default_width
|
695
|
+
# TODO consider caching
|
696
|
+
x_ends = shapes.map do |shape|
|
697
|
+
shape_width = shape.calculated_width.to_f
|
698
|
+
shape_x = shape.default_x? ? 0 : shape.x.to_f
|
699
|
+
shape_x + shape_width
|
700
|
+
end
|
701
|
+
x_ends.max.to_f
|
702
|
+
end
|
703
|
+
|
704
|
+
def default_height
|
705
|
+
# TODO consider caching
|
706
|
+
y_ends = shapes.map do |shape|
|
707
|
+
shape_height = shape.calculated_height.to_f
|
708
|
+
shape_y = shape.default_y? ? 0 : shape.y.to_f
|
709
|
+
shape_y + shape_height
|
710
|
+
end
|
711
|
+
y_ends.max.to_f
|
712
|
+
end
|
713
|
+
|
714
|
+
def calculated_width
|
715
|
+
default_width? ? (default_width + default_width_delta) : width
|
716
|
+
end
|
717
|
+
|
718
|
+
def calculated_height
|
719
|
+
default_height? ? (default_height + default_height_delta) : height
|
720
|
+
end
|
721
|
+
|
722
|
+
def default_x_delta
|
723
|
+
return 0 unless default_x? && x.is_a?(Array)
|
724
|
+
x[1].to_f
|
725
|
+
end
|
726
|
+
|
727
|
+
def default_y_delta
|
728
|
+
return 0 unless default_y? && y.is_a?(Array)
|
729
|
+
y[1].to_f
|
730
|
+
end
|
731
|
+
|
732
|
+
def default_width_delta
|
733
|
+
return 0 unless default_width? && width.is_a?(Array)
|
734
|
+
width[1].to_f
|
735
|
+
end
|
736
|
+
|
737
|
+
def default_height_delta
|
738
|
+
return 0 unless default_height? && height.is_a?(Array)
|
739
|
+
height[1].to_f
|
740
|
+
end
|
741
|
+
|
742
|
+
def default_x_delta=(delta)
|
743
|
+
return unless default_x?
|
744
|
+
self.x = [:default, delta]
|
745
|
+
end
|
746
|
+
|
747
|
+
def default_y_delta=(delta)
|
748
|
+
return unless default_y?
|
749
|
+
self.y = [:default, delta]
|
750
|
+
end
|
751
|
+
|
752
|
+
def default_width_delta=(delta)
|
753
|
+
return unless default_width?
|
754
|
+
self.width = [:default, delta]
|
755
|
+
end
|
756
|
+
|
757
|
+
def default_height_delta=(delta)
|
758
|
+
return unless default_height?
|
759
|
+
self.height = [:default, delta]
|
760
|
+
end
|
761
|
+
|
762
|
+
def calculated_x
|
763
|
+
result = default_x? ? default_x : self.x
|
764
|
+
result += default_x_delta
|
765
|
+
result
|
766
|
+
end
|
767
|
+
|
768
|
+
def calculated_y
|
769
|
+
result = default_y? ? default_y : self.y
|
770
|
+
result += default_y_delta
|
771
|
+
result
|
772
|
+
end
|
773
|
+
|
774
|
+
def absolute_x
|
775
|
+
x = calculated_x
|
776
|
+
if parent.is_a?(Shape)
|
777
|
+
parent.absolute_x + x
|
778
|
+
else
|
779
|
+
x
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
783
|
+
def absolute_y
|
784
|
+
y = calculated_y
|
785
|
+
if parent.is_a?(Shape)
|
786
|
+
parent.absolute_y + y
|
787
|
+
else
|
788
|
+
y
|
789
|
+
end
|
790
|
+
end
|
791
|
+
|
792
|
+
# Overriding inspect to avoid printing very long shape hierarchies
|
793
|
+
def inspect
|
794
|
+
"#<#{self.class.name}:0x#{self.hash.to_s(16)} args=#{@args.inspect}, properties=#{@properties.inspect}}>"
|
795
|
+
rescue => e
|
796
|
+
"#<#{self.class.name}:0x#{self.hash.to_s(16)}"
|
397
797
|
end
|
398
798
|
|
399
799
|
def calculate_paint_args!
|
@@ -405,7 +805,7 @@ module Glimmer
|
|
405
805
|
if @properties[:foreground].is_a?(Array)
|
406
806
|
@properties[:foreground] = ColorProxy.new(@properties[:foreground], ensure_bounds: false)
|
407
807
|
end
|
408
|
-
if @properties[:foreground].is_a?(Symbol) || @properties[:foreground].is_a?(String)
|
808
|
+
if @properties[:foreground].is_a?(Symbol) || @properties[:foreground].is_a?(::String)
|
409
809
|
@properties[:foreground] = ColorProxy.new(@properties[:foreground], ensure_bounds: false)
|
410
810
|
end
|
411
811
|
if @properties[:foreground].is_a?(ColorProxy)
|
@@ -413,14 +813,14 @@ module Glimmer
|
|
413
813
|
end
|
414
814
|
end
|
415
815
|
else
|
416
|
-
@properties['background'] = [@
|
417
|
-
@properties['foreground'] = [@
|
816
|
+
@properties['background'] = [@drawable.background] if fill? && !has_some_background?
|
817
|
+
@properties['foreground'] = [@drawable.foreground] if @drawable.respond_to?(:foreground) && draw? && !has_some_foreground?
|
418
818
|
# TODO regarding alpha, make sure to reset it to parent stored alpha once we allow setting shape properties on parents directly without shapes
|
419
819
|
@properties['alpha'] ||= [255]
|
420
|
-
@properties['font'] = [@
|
820
|
+
@properties['font'] = [@drawable.font] if @drawable.respond_to?(:font) && draw? && !@properties.keys.map(&:to_s).include?('font')
|
421
821
|
# TODO regarding transform, make sure to reset it to parent stored alpha once we allow setting shape properties on parents directly without shapes
|
422
822
|
# Also do that with all future-added properties
|
423
|
-
@properties['transform'] = [nil] if @
|
823
|
+
@properties['transform'] = [nil] if @drawable.respond_to?(:transform) && !@properties.keys.map(&:to_s).include?('transform')
|
424
824
|
@properties.each do |property, args|
|
425
825
|
method_name = attribute_setter(property)
|
426
826
|
converted_args = apply_property_arg_conversions(method_name, property, args)
|