cyberarm_engine 0.19.1 → 0.20.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94a6e7a7e11272f44550677967ba2c1ad093a03191eec6cf0ce959e61b6c7250
4
- data.tar.gz: 103f4161cad7eeb1296ba9c902fab13c85126fd7e9321567a2ae19b88103e5fd
3
+ metadata.gz: f3c68b386d491e804fe89ef1148cd3a6046af34f998e7e3fdaf9e01a390f06f1
4
+ data.tar.gz: 99f658599500bad421e0257b073e30581a2792410c4f3eabdbccf0348f5ecb83
5
5
  SHA512:
6
- metadata.gz: d6b975e8a81ae351ccb85daecbd4bd31f711929c3fbd00997c6fdcd1b45e1c7430e42a9c0f1ba5584969057044f53c396cdf44dbce8096ad1e3654cc5f63e130
7
- data.tar.gz: 209ea1a470cd1369ea540586c3ea97598adf5ebdbc22ba7a09eb79fb1fdc4e1ab3f1a8866dc8759679798fc90ca0d702874907666633c5ecaa0dcac47dfece0b
6
+ metadata.gz: a1a08c5926b6f2cfde243e6d920aeb4c4a0b7a0524552d45ddc6ccb662606c44ceb15f161538536aa47ea1d1c0346ef380c5469a8fb1db5e63a63ac637aeb228
7
+ data.tar.gz: 05c30bec40740bc07cebb29892e94b535c53fb5439949b61684a3a4c0341df034d689c0b0dae5ae594b37023565592e7d98d3744195aab30aad88c5126940f3e
@@ -27,8 +27,8 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = %w[lib assets]
29
29
 
30
- spec.add_dependency "clipboard", "~> 1.3.5"
31
- spec.add_dependency "excon", "~> 0.78.0"
30
+ spec.add_dependency "clipboard", "~> 1.3"
31
+ spec.add_dependency "excon", "~> 0.88"
32
32
  spec.add_dependency "gosu", "~> 1.1"
33
33
  spec.add_dependency "gosu_more_drawables", "~> 0.3"
34
34
  # spec.add_dependency "ffi", :platforms => [:mswin, :mingw] # Required by Clipboard on Windows
@@ -4,7 +4,7 @@ module CyberarmEngine
4
4
  include Event
5
5
  include Common
6
6
 
7
- attr_accessor :x, :y, :z, :enabled, :tip
7
+ attr_accessor :x, :y, :z, :tip, :element_visible
8
8
  attr_reader :parent, :options, :style, :event_handler, :background_canvas, :border_canvas
9
9
 
10
10
  def initialize(options = {}, block = nil)
@@ -13,9 +13,9 @@ module CyberarmEngine
13
13
  @options = options
14
14
  @block = block
15
15
 
16
- @focus = @options[:focus].nil? ? false : @options[:focus]
17
- @enabled = @options[:enabled].nil? ? true : @options[:enabled]
18
- @visible = @options[:visible].nil? ? true : @options[:visible]
16
+ @focus = !@options.key?(:focus) ? false : @options[:focus]
17
+ @enabled = !@options.key?(:enabled) ? true : @options[:enabled]
18
+ @visible = !@options.key?(:visible) ? true : @options[:visible]
19
19
  @tip = @options[:tip] || ""
20
20
 
21
21
  @debug_color = @options[:debug_color].nil? ? Gosu::Color::RED : @options[:debug_color]
@@ -24,6 +24,7 @@ module CyberarmEngine
24
24
 
25
25
  @root ||= nil
26
26
  @gui_state ||= nil
27
+ @element_visible = true
27
28
 
28
29
  @x = @style.x
29
30
  @y = @style.y
@@ -51,6 +52,9 @@ module CyberarmEngine
51
52
  def stylize
52
53
  set_static_position
53
54
 
55
+ set_color
56
+ set_font
57
+
54
58
  set_padding
55
59
  set_margin
56
60
 
@@ -70,6 +74,15 @@ module CyberarmEngine
70
74
  @y = @style.y if @style.y != 0
71
75
  end
72
76
 
77
+ def set_color
78
+ @style.color = safe_style_fetch(:color)
79
+ @text&.color = @style.color
80
+ end
81
+
82
+ def set_font
83
+ @text&.swap_font(safe_style_fetch(:text_size), safe_style_fetch(:font))
84
+ end
85
+
73
86
  def set_background
74
87
  @style.background = safe_style_fetch(:background)
75
88
 
@@ -138,14 +151,8 @@ module CyberarmEngine
138
151
  old_width = width
139
152
  old_height = height
140
153
 
141
- _style = @style.send(event)
142
154
  @style_event = event
143
155
 
144
- if @text.is_a?(CyberarmEngine::Text)
145
- @text.color = _style&.dig(:color) || @style.default[:color]
146
- @text.swap_font(_style&.dig(:text_size) || @style.default[:text_size], _style&.dig(:font) || @style.default[:font])
147
- end
148
-
149
156
  return if self.is_a?(ToolTip)
150
157
 
151
158
  if old_width != width || old_height != height
@@ -238,6 +245,14 @@ module CyberarmEngine
238
245
  :handled
239
246
  end
240
247
 
248
+ def enabled=(boolean)
249
+ @enabled = boolean
250
+
251
+ recalculate
252
+
253
+ @enabled
254
+ end
255
+
241
256
  def enabled?
242
257
  @enabled
243
258
  end
@@ -246,6 +261,10 @@ module CyberarmEngine
246
261
  @visible
247
262
  end
248
263
 
264
+ def element_visible?
265
+ @element_visible
266
+ end
267
+
249
268
  def toggle
250
269
  @visible = !@visible
251
270
  root.gui_state.request_recalculate
@@ -265,14 +284,13 @@ module CyberarmEngine
265
284
 
266
285
  def draw
267
286
  return unless visible?
287
+ return unless element_visible?
268
288
 
269
289
  @style.background_canvas.draw
270
290
  @style.background_nine_slice_canvas.draw
271
291
  @style.border_canvas.draw
272
292
 
273
- Gosu.clip_to(@x, @y, width, height) do
274
- render
275
- end
293
+ render
276
294
  end
277
295
 
278
296
  def debug_draw
@@ -370,19 +388,42 @@ module CyberarmEngine
370
388
  end
371
389
 
372
390
  def scroll_width
373
- @children.sum(&:width) + noncontent_width
391
+ @children.sum(&:outer_width)
374
392
  end
375
393
 
376
394
  def scroll_height
377
- @children.sum(&:height) + noncontent_height
395
+ if is_a?(CyberarmEngine::Element::Flow)
396
+ return 0 if @children.size.zero?
397
+
398
+ pairs_ = []
399
+ sorted_children_ = @children.sort_by(&:y)
400
+ a_ = []
401
+ y_position_ = sorted_children_.first.y
402
+
403
+ sorted_children_.each do |child|
404
+ unless child.y == y_position_
405
+ y_position_ = child.y
406
+ pairs_ << a_
407
+ a_ = []
408
+ end
409
+
410
+ a_ << child
411
+ end
412
+
413
+ pairs_ << a_ unless pairs_.last == a_
414
+
415
+ pairs_.sum { |pair| pair.map(&:outer_height).max } + @style.padding_bottom + @style.border_thickness_bottom
416
+ else
417
+ @children.sum(&:outer_height) + @style.padding_bottom + @style.border_thickness_bottom
418
+ end
378
419
  end
379
420
 
380
421
  def max_scroll_width
381
- scroll_width - width
422
+ scroll_width - outer_width
382
423
  end
383
424
 
384
425
  def max_scroll_height
385
- scroll_height - height
426
+ scroll_height - outer_height
386
427
  end
387
428
 
388
429
  def dimensional_size(size, dimension)
@@ -86,9 +86,12 @@ module CyberarmEngine
86
86
 
87
87
  old_width = width
88
88
  old_height = height
89
- recalculate
90
89
 
91
- root.gui_state.request_recalculate if old_width != width || old_height != height
90
+ if old_width != width || old_height != height
91
+ root.gui_state.request_recalculate
92
+ else
93
+ recalculate
94
+ end
92
95
 
93
96
  publish(:changed, self.value)
94
97
  end
@@ -45,7 +45,7 @@ module CyberarmEngine
45
45
  root.gui_state.request_recalculate
46
46
  end
47
47
 
48
- def apend(&block)
48
+ def append(&block)
49
49
  old_container = $__current_container__
50
50
 
51
51
  $__current_container__ = self
@@ -57,7 +57,12 @@ module CyberarmEngine
57
57
  end
58
58
 
59
59
  def render
60
- Gosu.clip_to(@x, @y, width, height) do
60
+ Gosu.clip_to(
61
+ @x + @style.border_thickness_left + @style.padding_left,
62
+ @y + @style.border_thickness_top + @style.padding_top,
63
+ content_width + 1,
64
+ content_height + 1
65
+ ) do
61
66
  @children.each(&:draw)
62
67
  end
63
68
  end
@@ -103,6 +108,8 @@ module CyberarmEngine
103
108
 
104
109
  stylize
105
110
 
111
+ # s = Gosu.milliseconds
112
+
106
113
  layout
107
114
 
108
115
  if is_root?
@@ -129,8 +136,13 @@ module CyberarmEngine
129
136
  child.reposition # TODO: Implement top,bottom,left,center, and right positioning
130
137
 
131
138
  Stats.increment(:gui_recalculations_last_frame, 1)
139
+
140
+ child.element_visible = child.x >= @x - child.width && child.x <= @x + width &&
141
+ child.y >= @y - child.height && child.y <= @y + height
132
142
  end
133
143
 
144
+ # puts "TOOK: #{Gosu.milliseconds - s}ms to recalculate #{self.class}:0x#{self.object_id.to_s(16)}"
145
+
134
146
  update_background
135
147
  end
136
148
 
@@ -194,7 +206,8 @@ module CyberarmEngine
194
206
  if @scroll_position.y < 0
195
207
  @scroll_position.y += @scroll_speed
196
208
  @scroll_position.y = 0 if @scroll_position.y > 0
197
- recalculate
209
+
210
+ root.gui_state.request_recalculate_for(self)
198
211
 
199
212
  return :handled
200
213
  end
@@ -208,7 +221,8 @@ module CyberarmEngine
208
221
  if @scroll_position.y.abs < max_scroll_height
209
222
  @scroll_position.y -= @scroll_speed
210
223
  @scroll_position.y = -max_scroll_height if @scroll_position.y.abs > max_scroll_height
211
- recalculate
224
+
225
+ root.gui_state.request_recalculate_for(self)
212
226
 
213
227
  return :handled
214
228
  end
@@ -47,7 +47,7 @@ module CyberarmEngine
47
47
  end
48
48
 
49
49
  def clicked_left_mouse_button(_sender, _x, _y)
50
- @block&.call(self.value) if @enabled
50
+ # @block&.call(self.value) if @enabled
51
51
 
52
52
  :handled
53
53
  end
@@ -56,6 +56,8 @@ module CyberarmEngine
56
56
  @menu.clear
57
57
 
58
58
  @items.each do |item|
59
+ next if item == self.value
60
+
59
61
  btn = Button.new(
60
62
  item,
61
63
  {
@@ -1,9 +1,16 @@
1
1
  module CyberarmEngine
2
2
  class Element
3
3
  class Progress < Element
4
+ attr_reader :type
5
+
4
6
  def initialize(options = {}, block = nil)
5
7
  super(options, block)
6
8
 
9
+ @animation_speed = options[:animation_speed] || 3_000
10
+ @marquee_width = options[:marquee_width] || 0.25
11
+ @marquee_offset = 0
12
+ @marquee_animation_time = Gosu.milliseconds
13
+ @type = options[:type] || :linear
7
14
  @fraction_background = Background.new(background: @style.fraction_background)
8
15
  self.value = options[:fraction] || 0.0
9
16
  end
@@ -24,15 +31,45 @@ module CyberarmEngine
24
31
  def update_background
25
32
  super
26
33
 
27
- @fraction_background.x = @style.border_thickness_left + @style.padding_left + @x
34
+ @fraction_background.x = (@style.border_thickness_left + @style.padding_left + @x) + @marquee_offset
28
35
  @fraction_background.y = @style.border_thickness_top + @style.padding_top + @y
29
36
  @fraction_background.z = @z
30
- @fraction_background.width = @width * @fraction
37
+ @fraction_background.width = @width * (@type == :marquee ? @marquee_width : @fraction)
31
38
  @fraction_background.height = @height
32
39
 
33
40
  @fraction_background.background = @style.fraction_background
34
41
  end
35
42
 
43
+ def update
44
+ super
45
+
46
+ return unless @type == :marquee
47
+
48
+ marquee_width = @width * @marquee_width
49
+ range = @width + marquee_width
50
+
51
+ @marquee_offset = (@width * (Gosu.milliseconds - @marquee_animation_time) / @animation_speed) - marquee_width
52
+ @marquee_animation_time = Gosu.milliseconds if @marquee_offset > range
53
+
54
+ update_background
55
+ end
56
+
57
+ def type=(type)
58
+ @type = type
59
+
60
+ case type
61
+ when :linear
62
+ @marquee_offset = 0
63
+ when :marquee
64
+ @marquee_offset = 0
65
+ @marquee_animation_time = Gosu.milliseconds
66
+ else
67
+ raise ArgumentError, "Only types :linear and :marquee are supported"
68
+ end
69
+
70
+ update_background
71
+ end
72
+
36
73
  def value
37
74
  @fraction
38
75
  end
@@ -47,8 +47,8 @@ module CyberarmEngine
47
47
  when :left
48
48
  @text.x = @style.border_thickness_left + @style.padding_left + @x
49
49
  when :center
50
- @text.x = if @text.width <= outer_width
51
- @x + outer_width / 2 - @text.width / 2
50
+ @text.x = if @text.width <= width
51
+ @x + width / 2 - @text.width / 2
52
52
  else # Act as left aligned
53
53
  @style.border_thickness_left + @style.padding_left + @x
54
54
  end
@@ -61,46 +61,64 @@ module CyberarmEngine
61
61
  end
62
62
 
63
63
  def handle_text_wrapping(max_width)
64
- max_width ||= @parent&.width
64
+ max_width ||= @parent&.content_width
65
65
  max_width ||= @x - (window.width + noncontent_width)
66
66
  wrap_behavior = style.text_wrap
67
67
  copy = @raw_text.to_s.dup
68
68
 
69
- if line_width(copy[0]) <= max_width && line_width(copy) > max_width && wrap_behavior != :none
70
- breaks = []
69
+ # Only perform text wrapping: if it is enabled, is possible to wrap, and text is too long to fit on one line
70
+ if wrap_behavior != :none && line_width(copy[0]) <= max_width && line_width(copy) > max_width
71
+ breaks = [] # list of indexes to insert a line break
71
72
  line_start = 0
72
- line_end = copy.length
73
-
74
- while line_start != copy.length
75
- if line_width(copy[line_start...line_end]) > max_width
76
- line_end = ((line_end - line_start) / 2.0)
77
- line_end = 1.0 if line_end <= 1
78
- elsif line_end < copy.length && line_width(copy[line_start...line_end + 1]) < max_width
79
- # To small, grow!
80
- # TODO: find a more efficient way
81
- line_end += 1
82
-
83
- else # FOUND IT!
84
- entering_line_end = line_end.floor
85
- max_reach = line_end.floor - line_start < 63 ? line_end.floor - line_start : 63
86
- reach = 0
87
-
88
- if wrap_behavior == :word_wrap
89
- max_reach.times do |i|
90
- reach = i
91
- break if copy[line_end.floor - i].to_s.match(/[[:punct:]]| /)
92
- end
93
-
94
- # puts "Max width: #{max_width}/#{line_width(@raw_text)} Reach: {#{reach}/#{max_reach}} Line Start: #{line_start}/#{line_end.floor} (#{copy.length}|#{@raw_text.length}) [#{entering_line_end}] '#{copy}' {#{copy[line_start...line_end]}}"
95
- line_end = line_end.floor - reach + 1 if reach != max_reach # Add +1 to walk in front of punctuation
73
+ line_end = copy.length
74
+
75
+ stalled = false
76
+ stalled_interations = 0
77
+ max_stalled_iterations = 10
78
+ checked_copy_length = line_width(copy[line_start..line_end])
79
+
80
+ # find length of lines
81
+ while line_width(copy[line_start..line_end]) > max_width && stalled_interations < max_stalled_iterations
82
+ search_start = line_start
83
+ search_end = line_end
84
+
85
+ # Perform a binary search to find length of line
86
+ while search_start < search_end
87
+ midpoint = ((search_start.to_f + search_end) / 2.0).floor
88
+
89
+ if line_width(copy[line_start..midpoint]) > max_width
90
+ search_end = midpoint
91
+ else
92
+ search_start = midpoint + 1
96
93
  end
94
+ end
97
95
 
98
- breaks << line_end.floor
99
- line_start = line_end.floor
100
- line_end = copy.length
96
+ if wrap_behavior == :word_wrap
97
+ word_search_end = search_end
98
+ failed = false
99
+
100
+ until(copy[word_search_end].to_s.match(/[[:punct:]]| /))
101
+ word_search_end -= 1
102
+
103
+ if word_search_end <= 1 || word_search_end < line_start
104
+ failed = true
105
+ break
106
+ end
107
+ end
101
108
 
102
- break if entering_line_end == copy.length || reach == max_reach
109
+ line_start = failed ? search_end : word_search_end + 1 # walk in front of punctuation
110
+ else
111
+ line_start = search_end
103
112
  end
113
+
114
+ breaks << line_start
115
+
116
+ # Prevent locking up due to outer while loop text width < max_width check not being satisfied.
117
+ stalled = checked_copy_length == line_width(copy[line_start..line_end])
118
+ checked_copy_length = line_width(copy[line_start..line_end])
119
+
120
+ stalled_interations += 1 if stalled
121
+ stalled_interations = 0 unless stalled
104
122
  end
105
123
 
106
124
  breaks.each_with_index do |pos, index|
@@ -124,9 +142,12 @@ module CyberarmEngine
124
142
 
125
143
  old_width = width
126
144
  old_height = height
127
- recalculate
128
145
 
129
- root.gui_state.request_recalculate if old_width != width || old_height != height
146
+ if old_width != width || old_height != height
147
+ root.gui_state.request_recalculate
148
+ else
149
+ recalculate
150
+ end
130
151
 
131
152
  publish(:changed, self.value)
132
153
  end
@@ -25,6 +25,7 @@ module CyberarmEngine
25
25
  @last_mouse_pos = nil
26
26
  @dragging_element = nil
27
27
  @pending_recalculate_request = false
28
+ @pending_element_recalculate_requests = []
28
29
 
29
30
  @menu = nil
30
31
  @min_drag_distance = 0
@@ -56,6 +57,7 @@ module CyberarmEngine
56
57
 
57
58
  if @tip.value.length.positive?
58
59
  Gosu.flush
60
+
59
61
  @tip.draw
60
62
  end
61
63
 
@@ -75,6 +77,9 @@ module CyberarmEngine
75
77
  @pending_recalculate_request = false
76
78
  end
77
79
 
80
+ @pending_element_recalculate_requests.each(&:recalculate)
81
+ @pending_element_recalculate_requests.clear
82
+
78
83
  if @pending_focus_request
79
84
  @pending_focus_request = false
80
85
 
@@ -231,6 +236,13 @@ module CyberarmEngine
231
236
  @pending_recalculate_request = true
232
237
  end
233
238
 
239
+ def request_recalculate_for(element)
240
+ # element is already queued
241
+ return if @pending_element_recalculate_requests.detect { |e| e == element }
242
+
243
+ @pending_element_recalculate_requests << element
244
+ end
245
+
234
246
  def request_focus(element)
235
247
  @pending_focus_request = true
236
248
  @pending_focus_element = element
@@ -1,4 +1,4 @@
1
1
  module CyberarmEngine
2
2
  NAME = "InDev".freeze
3
- VERSION = "0.19.1".freeze
3
+ VERSION = "0.20.0".freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cyberarm_engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.1
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyberarm
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-23 00:00:00.000000000 Z
11
+ date: 2022-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.3.5
19
+ version: '1.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.3.5
26
+ version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: excon
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.78.0
33
+ version: '0.88'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.78.0
40
+ version: '0.88'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: gosu
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -210,7 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
210
  - !ruby/object:Gem::Version
211
211
  version: '0'
212
212
  requirements: []
213
- rubygems_version: 3.2.22
213
+ rubygems_version: 3.2.28
214
214
  signing_key:
215
215
  specification_version: 4
216
216
  summary: Make games quickly and easily with gosu