wxruby3-shapes 0.9.0.pre.beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +12 -0
  3. data/CREDITS.md +18 -0
  4. data/INSTALL.md +39 -0
  5. data/LICENSE +21 -0
  6. data/README.md +118 -0
  7. data/assets/screenshot.png +0 -0
  8. data/bin/wx-shapes +9 -0
  9. data/lib/wx/shapes/arrow_base.rb +86 -0
  10. data/lib/wx/shapes/arrows/circle_arrow.rb +39 -0
  11. data/lib/wx/shapes/arrows/diamond_arrow.rb +33 -0
  12. data/lib/wx/shapes/arrows/open_arrow.rb +56 -0
  13. data/lib/wx/shapes/arrows/solid_arrow.rb +69 -0
  14. data/lib/wx/shapes/art/shape_canvas/page.xpm +73 -0
  15. data/lib/wx/shapes/auto_layout.rb +358 -0
  16. data/lib/wx/shapes/base.rb +33 -0
  17. data/lib/wx/shapes/canvas_history.rb +84 -0
  18. data/lib/wx/shapes/connection_point.rb +238 -0
  19. data/lib/wx/shapes/core.rb +19 -0
  20. data/lib/wx/shapes/diagram.rb +659 -0
  21. data/lib/wx/shapes/events.rb +389 -0
  22. data/lib/wx/shapes/printout.rb +136 -0
  23. data/lib/wx/shapes/serializable.rb +440 -0
  24. data/lib/wx/shapes/serialize/core.rb +40 -0
  25. data/lib/wx/shapes/serialize/id.rb +82 -0
  26. data/lib/wx/shapes/serialize/wx.rb +104 -0
  27. data/lib/wx/shapes/serializer/json.rb +258 -0
  28. data/lib/wx/shapes/serializer/yaml.rb +125 -0
  29. data/lib/wx/shapes/shape.rb +2129 -0
  30. data/lib/wx/shapes/shape_canvas.rb +3285 -0
  31. data/lib/wx/shapes/shape_data_object.rb +43 -0
  32. data/lib/wx/shapes/shape_handle.rb +287 -0
  33. data/lib/wx/shapes/shape_list.rb +161 -0
  34. data/lib/wx/shapes/shapes/bitmap_shape.rb +257 -0
  35. data/lib/wx/shapes/shapes/circle_shape.rb +136 -0
  36. data/lib/wx/shapes/shapes/control_shape.rb +483 -0
  37. data/lib/wx/shapes/shapes/curve_shape.rb +231 -0
  38. data/lib/wx/shapes/shapes/diamond_shape.rb +62 -0
  39. data/lib/wx/shapes/shapes/edit_text_shape.rb +317 -0
  40. data/lib/wx/shapes/shapes/ellipse_shape.rb +106 -0
  41. data/lib/wx/shapes/shapes/flex_grid_shape.rb +78 -0
  42. data/lib/wx/shapes/shapes/grid_shape.rb +404 -0
  43. data/lib/wx/shapes/shapes/line_shape.rb +907 -0
  44. data/lib/wx/shapes/shapes/multi_sel_rect.rb +214 -0
  45. data/lib/wx/shapes/shapes/ortho_shape.rb +357 -0
  46. data/lib/wx/shapes/shapes/polygon_shape.rb +294 -0
  47. data/lib/wx/shapes/shapes/rect_shape.rb +378 -0
  48. data/lib/wx/shapes/shapes/round_ortho_shape.rb +131 -0
  49. data/lib/wx/shapes/shapes/round_rect_shape.rb +142 -0
  50. data/lib/wx/shapes/shapes/square_shape.rb +119 -0
  51. data/lib/wx/shapes/shapes/text_shape.rb +324 -0
  52. data/lib/wx/shapes/thumbnail.rb +234 -0
  53. data/lib/wx/shapes/version.rb +12 -0
  54. data/lib/wx/shapes/wx.rb +29 -0
  55. data/lib/wx/shapes.rb +18 -0
  56. data/lib/wx/wx-shapes/base.rb +87 -0
  57. data/lib/wx/wx-shapes/cmd/sampler.rb +58 -0
  58. data/lib/wx/wx-shapes/cmd/test.rb +27 -0
  59. data/rakelib/yard/templates/default/fulldoc/html/css/wxruby3.css +7 -0
  60. data/rakelib/yard/templates/default/layout/html/setup.rb +5 -0
  61. data/rakelib/yard/yard/relative_markdown_links/version.rb +8 -0
  62. data/rakelib/yard/yard/relative_markdown_links.rb +39 -0
  63. data/rakelib/yard/yard-custom-templates.rb +2 -0
  64. data/rakelib/yard/yard-relative_markdown_links.rb +4 -0
  65. data/samples/demo/art/AlignBottom.xpm +35 -0
  66. data/samples/demo/art/AlignCenter.xpm +35 -0
  67. data/samples/demo/art/AlignLeft.xpm +35 -0
  68. data/samples/demo/art/AlignMiddle.xpm +35 -0
  69. data/samples/demo/art/AlignRight.xpm +35 -0
  70. data/samples/demo/art/AlignTop.xpm +35 -0
  71. data/samples/demo/art/Bitmap.xpm +25 -0
  72. data/samples/demo/art/Circle.xpm +22 -0
  73. data/samples/demo/art/Curve.xpm +21 -0
  74. data/samples/demo/art/Diamond.xpm +22 -0
  75. data/samples/demo/art/EditText.xpm +21 -0
  76. data/samples/demo/art/Ellipse.xpm +22 -0
  77. data/samples/demo/art/FixedRect.xpm +22 -0
  78. data/samples/demo/art/FlexGrid.xpm +22 -0
  79. data/samples/demo/art/GC.xpm +23 -0
  80. data/samples/demo/art/Grid.xpm +22 -0
  81. data/samples/demo/art/Line.xpm +21 -0
  82. data/samples/demo/art/NoSource.xpm +69 -0
  83. data/samples/demo/art/OrthoLine.xpm +21 -0
  84. data/samples/demo/art/Rect.xpm +22 -0
  85. data/samples/demo/art/RoundOrthoLine.xpm +21 -0
  86. data/samples/demo/art/RoundRect.xpm +22 -0
  87. data/samples/demo/art/Shadow.xpm +23 -0
  88. data/samples/demo/art/StandAloneLine.xpm +22 -0
  89. data/samples/demo/art/Text.xpm +21 -0
  90. data/samples/demo/art/Tool.xpm +23 -0
  91. data/samples/demo/art/sample.xpm +251 -0
  92. data/samples/demo/demo.rb +658 -0
  93. data/samples/demo/frame_canvas.rb +422 -0
  94. data/samples/demo/images/motyl.bmp +0 -0
  95. data/samples/demo/images/motyl2.bmp +0 -0
  96. data/samples/sample1/art/sample.xpm +251 -0
  97. data/samples/sample1/sample.rb +263 -0
  98. data/samples/sample2/art/sample.xpm +251 -0
  99. data/samples/sample2/sample.rb +133 -0
  100. data/samples/sample2/sample_canvas.rb +35 -0
  101. data/samples/sample2/sample_shape.rb +108 -0
  102. data/samples/sample3/art/sample.xpm +251 -0
  103. data/samples/sample3/sample.rb +281 -0
  104. data/samples/sample4/art/sample.xpm +251 -0
  105. data/samples/sample4/sample.rb +180 -0
  106. data/tests/art/motyl.bmp +0 -0
  107. data/tests/lib/wxapp_runner.rb +64 -0
  108. data/tests/serializer_tests.rb +521 -0
  109. data/tests/test_grid_shapes.rb +42 -0
  110. data/tests/test_serialize.rb +7 -0
  111. data/tests/test_serialize_yaml.rb +17 -0
  112. metadata +242 -0
@@ -0,0 +1,258 @@
1
+ # Wx::SF::Serializer - shape serializer module
2
+ # Copyright (c) M.J.N. Corino, The Netherlands
3
+
4
+ require 'json'
5
+ require 'json/add/core'
6
+ require 'json/add/set'
7
+ require 'json/add/ostruct'
8
+
9
+ module Wx::SF
10
+
11
+ module Serializable
12
+
13
+ module JSON
14
+
15
+ # Derived Hash class to use for deserialized JSON object data which
16
+ # supports using Symbol keys.
17
+ class ObjectHash < ::Hash
18
+ # Returns the object associated with given key.
19
+ # @param [String,Symbol] key key value
20
+ # @return [Object] associated object
21
+ # @see ::Hash#[]
22
+ def [](key)
23
+ super(key.to_s)
24
+ end
25
+ # Returns true if the given key exists in self otherwise false.
26
+ # @param [String,Symbol] key key value
27
+ # @return [Boolean]
28
+ # @see ::Hash#include?
29
+ def include?(key)
30
+ super(key.to_s)
31
+ end
32
+ alias member? include?
33
+ alias has_key? include?
34
+ alias key? include?
35
+ end
36
+
37
+ # Mixin module to patch hash objects during JSON serialization.
38
+ # By default JSON will not consider hash keys for custom serialization
39
+ # but assumes any key should be serialized as it's string representation.
40
+ # This is restrictive but compatible with "pure" JSON object notation.
41
+ # JSON however also does not (correctly?) honour overriding Hash#to_json to
42
+ # customize serialization of Hash-es which seems too restrictive (stupid?)
43
+ # as using more complex custom keys for Hash-es instead of String/Symbol-s
44
+ # is not that uncommon.
45
+ # This mixin is used to "patch" Hash **instances** through #extend.
46
+ module HashInstancePatch
47
+ def patch_nested_hashes(obj)
48
+ case obj
49
+ when ::Hash
50
+ obj.extend(HashInstancePatch) unless obj.singleton_class.include?(HashInstancePatch)
51
+ obj.each_pair { |k, v| patch_nested_hashes(k); patch_nested_hashes(v) }
52
+ when ::Array
53
+ obj.each { |e| patch_nested_hashes(e) }
54
+ end
55
+ obj
56
+ end
57
+ private :patch_nested_hashes
58
+
59
+ # Returns JSON representation (String) of self.
60
+ # Hash data which is part of object properties/members being serialized
61
+ # (including any nested Hash-es) will be patched with HashInstancePatch.
62
+ # Patched Hash instances will be serialized as JSON-creatable objects
63
+ # (so provided with a JSON#create_id) with the hash contents represented
64
+ # as an array of key/value pairs (arrays).
65
+ # @param [Array<Object>] args any args passed by the JSON generator
66
+ # @return [String] JSON representation
67
+ def to_json(*args)
68
+ if self.has_key?(::JSON.create_id)
69
+ if self.has_key?('data')
70
+ if (data = self['data']).is_a?(::Hash)
71
+ data.each_value { |v| patch_nested_hashes(v) }
72
+ end
73
+ else # core class extensions use different data members for property serialization
74
+ self.each_value { |v| patch_nested_hashes(v) }
75
+ end
76
+ super
77
+ else
78
+ {
79
+ ::JSON.create_id => self.class.name,
80
+ 'data' => patch_nested_hashes(to_a)
81
+ }.to_json(*args)
82
+ end
83
+ end
84
+ end
85
+
86
+ # Mixin module to patch singleton_clas of the Hash class to make Hash-es
87
+ # JSON creatable (#json_creatable? returns true).
88
+ module HashClassPatch
89
+ # Create a new Hash instance from deserialized JSON data.
90
+ # @param [Hash] object deserialized JSON object
91
+ # @return [Hash] restored Hash instance
92
+ def json_create(object)
93
+ object['data'].to_h
94
+ end
95
+ end
96
+
97
+ class ::Hash
98
+ include Wx::SF::Serializable::JSON::HashInstancePatch
99
+ class << self
100
+ include Wx::SF::Serializable::JSON::HashClassPatch
101
+ end
102
+ end
103
+
104
+ class << self
105
+ def serializables
106
+ ::Set.new [::NilClass, ::TrueClass, ::FalseClass, ::Integer, ::Float, ::String, ::Array, ::Hash,
107
+ ::Date, ::DateTime, ::Exception, ::Range, ::Regexp, ::Struct, ::Symbol, ::Time, ::Set, ::OpenStruct]
108
+ end
109
+
110
+ TLS_SAFE_DESERIALIZE_KEY = :wx_sf_json_safe_deserialize.freeze
111
+ private_constant :TLS_SAFE_DESERIALIZE_KEY
112
+
113
+ TLS_PARSE_STACK_KEY = :wx_sf_json_parse_stack.freeze
114
+ private_constant :TLS_PARSE_STACK_KEY
115
+
116
+ def safe_deserialize
117
+ ::Thread.current[TLS_SAFE_DESERIALIZE_KEY] ||= []
118
+ end
119
+ private :safe_deserialize
120
+
121
+ def start_safe_deserialize
122
+ safe_deserialize.push(true)
123
+ end
124
+
125
+ def end_safe_deserialize
126
+ safe_deserialize.pop
127
+ end
128
+
129
+ def parse_stack
130
+ ::Thread.current[TLS_PARSE_STACK_KEY] ||= []
131
+ end
132
+ private :parse_stack
133
+
134
+ def start_parse
135
+ parse_stack.push(safe_deserialize.pop)
136
+ end
137
+
138
+ def end_parse
139
+ unless (val = parse_stack.pop).nil?
140
+ safe_deserialize.push(val)
141
+ end
142
+ end
143
+
144
+ def safe_parsing?
145
+ !!parse_stack.last
146
+ end
147
+ end
148
+
149
+ def self.dump(obj, io=nil, pretty: false)
150
+ obj.extend(HashInstancePatch) if obj.is_a?(::Hash)
151
+ if pretty
152
+ if io || io.respond_to?(:write)
153
+ io.write(::JSON.pretty_generate(obj))
154
+ io
155
+ else
156
+ ::JSON.pretty_generate(obj)
157
+ end
158
+ else
159
+ ::JSON.dump(obj, io)
160
+ end
161
+ end
162
+
163
+ def self.load(source)
164
+ begin
165
+ # initialize ID restoration map
166
+ Serializable::ID.init_restoration_map
167
+ # enable safe deserializing
168
+ self.start_safe_deserialize
169
+ ::JSON.parse!(source,
170
+ **{create_additions: true,
171
+ object_class: Serializable::JSON::ObjectHash})
172
+ ensure
173
+ # reset safe deserializing
174
+ self.end_safe_deserialize
175
+ # reset ID restoration map
176
+ Serializable::ID.clear_restoration_map
177
+ end
178
+ end
179
+
180
+ end
181
+
182
+ # extend serialization class methods
183
+ module SerializeClassMethods
184
+
185
+ def json_create(object)
186
+ create_for_deserialize(data = object['data'])
187
+ .__send__(:from_serialized, data)
188
+ end
189
+
190
+ end
191
+
192
+ # extend instance serialization methods
193
+ module SerializeInstanceMethods
194
+
195
+ def to_json(*args)
196
+ {
197
+ ::JSON.create_id => self.class.name,
198
+ 'data' => for_serialize(Hash.new)
199
+ }.to_json(*args)
200
+ end
201
+
202
+ end
203
+
204
+ class ID
205
+
206
+ def self.json_create(object)
207
+ create_for_deserialize(data = object['data'])
208
+ end
209
+
210
+ def to_json(*args)
211
+ {
212
+ ::JSON.create_id => self.class.name,
213
+ 'data' => for_serialize(Hash.new)
214
+ }.to_json(*args)
215
+ end
216
+
217
+ end
218
+
219
+ register(Serializable.default_format, JSON)
220
+
221
+ end
222
+
223
+ end
224
+
225
+ module ::JSON
226
+ class << self
227
+
228
+ alias :pre_wxsf_parse! :parse!
229
+ def parse!(*args, **kwargs)
230
+ begin
231
+ # setup parsing stack for safe or normal deserializing
232
+ # the double bracketing provided from Wx::SF::Serializable::JSON#load and here
233
+ # makes sure to support both nested Wx::SF deserializing as well as nested
234
+ # hybrid deserializing (Wx::SF -> common JSON -> ...)
235
+ Wx::SF::Serializable::JSON.start_parse
236
+ pre_wxsf_parse!(*args, **kwargs)
237
+ ensure
238
+ # reset parsing stack
239
+ Wx::SF::Serializable::JSON.end_parse
240
+ end
241
+ end
242
+
243
+ end
244
+ end
245
+
246
+ class ::Class
247
+
248
+ # override this to be able to do safe deserializing
249
+ def json_creatable?
250
+ if Wx::SF::Serializable::JSON.safe_parsing?
251
+ return false unless Wx::SF::Serializable::JSON.serializables.include?(self) ||
252
+ Wx::SF::Serializable.serializables.include?(self) ||
253
+ ::Struct > self
254
+ end
255
+ respond_to?(:json_create)
256
+ end
257
+
258
+ end
@@ -0,0 +1,125 @@
1
+ # Wx::SF::Serializer - shape serializer module
2
+ # Copyright (c) M.J.N. Corino, The Netherlands
3
+
4
+ require 'yaml'
5
+ require 'set'
6
+ require 'ostruct'
7
+
8
+ module Wx::SF
9
+
10
+ module Serializable
11
+
12
+ module YAML
13
+
14
+ class << self
15
+ def serializables
16
+ [Date, DateTime, Exception, Range, Regexp, Struct, Symbol, Time, Set, OpenStruct]
17
+ end
18
+ end
19
+
20
+ module YamlSerializePatch
21
+
22
+ ALLOWED_ALIASES = [Serializable::ID, Wx::Pen, Wx::Colour, Wx::Brush, Wx::Enum, Wx::Rect, Wx::Point, Wx::RealPoint, Wx::Size]
23
+
24
+ if ::RUBY_VERSION >= '3.1.0'
25
+ def revive(klass, node)
26
+ if Wx::SF::Serializable > klass
27
+ s = register(node, klass.create_for_deserialize(data = revive_hash({}, node, true)))
28
+ init_with(s, data, node)
29
+ else
30
+ super
31
+ end
32
+ end
33
+ else
34
+ def revive(klass, node)
35
+ if Wx::SF::Serializable > klass
36
+ s = register(node, klass.create_for_deserialize(data = revive_hash({}, node)))
37
+ init_with(s, data, node)
38
+ else
39
+ super
40
+ end
41
+ end
42
+ end
43
+ def visit_Psych_Nodes_Alias o
44
+ rc = @st.fetch(o.anchor) { raise ::YAML::AnchorNotDefined, o.anchor }
45
+ # only allow Serializable::ID aliases
46
+ raise ::YAML::AliasesNotEnabled unless ALLOWED_ALIASES.any? { |klass| klass === rc }
47
+ rc
48
+ end
49
+ end
50
+
51
+ class RestrictedRelaxed < ::YAML::ClassLoader
52
+ def initialize(classes)
53
+ @classes = classes
54
+ @allow_struct = @classes.include?('Struct')
55
+ super()
56
+ end
57
+
58
+ private
59
+
60
+ def find(klassname)
61
+ if @classes.include?(klassname)
62
+ super
63
+ elsif @allow_struct && ::Struct > super
64
+ @cache[klassname]
65
+ else
66
+ raise ::YAML::DisallowedClass.new('load', klassname)
67
+ end
68
+ end
69
+ end
70
+
71
+ def self.dump(obj, io=nil, pretty: false)
72
+ ::YAML.dump(obj, io)
73
+ end
74
+
75
+ def self.load(source)
76
+ result = ::YAML.parse(source, filename: nil)
77
+ return nil unless result
78
+ begin
79
+ # initialize ID restoration map
80
+ Serializable::ID.init_restoration_map
81
+ allowed_classes =(YAML.serializables + Serializable.serializables.to_a).map(&:to_s)
82
+ class_loader = RestrictedRelaxed.new(allowed_classes)
83
+ scanner = ::YAML::ScalarScanner.new(class_loader)
84
+ visitor = ::YAML::Visitors::NoAliasRuby.new(scanner, class_loader)
85
+ visitor.extend(YamlSerializePatch)
86
+ result = visitor.accept result
87
+ ensure
88
+ # reset ID restoration map
89
+ Serializable::ID.clear_restoration_map
90
+ end
91
+ result
92
+ end
93
+
94
+ end
95
+
96
+ # extend instance serialization methods
97
+ module SerializeInstanceMethods
98
+
99
+ def encode_with(coder)
100
+ for_serialize(coder)
101
+ end
102
+
103
+ def init_with(coder)
104
+ from_serialized(coder.map)
105
+ end
106
+
107
+ end
108
+
109
+ class ID
110
+
111
+ def encode_with(coder)
112
+ for_serialize(coder)
113
+ end
114
+
115
+ def init_with(_coder)
116
+ # noop
117
+ end
118
+
119
+ end
120
+
121
+ register(:yaml, YAML)
122
+
123
+ end
124
+
125
+ end