cyberarm_engine 0.19.1 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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