cyberarm_engine 0.15.0 → 0.16.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: 4c56a2a5000efebf2274c880fed0b156ca41ed94216d7f3e7b5c15c24cc1cf2e
4
- data.tar.gz: 7bbdf2cbf1812f8860411d53dcf99c8fcb90d286c130328cdf1d1570cb75df30
3
+ metadata.gz: 074b1687997e6415e2af20d723a2641823e3f3704ae5485bdda305124e5babcc
4
+ data.tar.gz: 01a0161471ff3492f6267b0f2f6460e547c03a937dc305ea0e46de1746774e31
5
5
  SHA512:
6
- metadata.gz: 626116a0cc8d2bdde83e7823ed604e67d573379277ac15be83c2f991c34e0f345c6ba286586125584eabb2e5bcf777a206b337903690ccb0cde09cb3a3504f67
7
- data.tar.gz: 6f61c206112bfaf0885307ccb2cd9ae8aab9abc2ae70d167319866a735b8547500544a56f5c600c72c14003c4b9060db37a96bd958eab9ca88a346df3b04c004
6
+ metadata.gz: 9c35814f0690460e76d8d4050c1ad6fd1599f287de40477976252c228b7a2051545d55f98f223518d148cff6aa3ea8cdd01291871bb28639167a9bbee1fc469f
7
+ data.tar.gz: bf2b94247d7f3ed5519d884235c51298f19f433a11acb198a36c8a29d976f26b68cd2bca159d0088e65ca02f51651113ff3b0da0ff6129c9165a06bedf0c7685
@@ -37,7 +37,7 @@ require_relative "cyberarm_engine/ui/event"
37
37
  require_relative "cyberarm_engine/ui/style"
38
38
  require_relative "cyberarm_engine/ui/border_canvas"
39
39
  require_relative "cyberarm_engine/ui/element"
40
- require_relative "cyberarm_engine/ui/elements/label"
40
+ require_relative "cyberarm_engine/ui/elements/text_block"
41
41
  require_relative "cyberarm_engine/ui/elements/button"
42
42
  require_relative "cyberarm_engine/ui/elements/toggle_button"
43
43
  require_relative "cyberarm_engine/ui/elements/list_box"
@@ -8,11 +8,29 @@ module CyberarmEngine
8
8
  container(CyberarmEngine::Element::Stack, options, &block)
9
9
  end
10
10
 
11
+ # TODO: Remove in version 0.16.0+
11
12
  def label(text, options = {}, &block)
12
13
  options[:parent] = element_parent
13
14
  options[:theme] = current_theme
14
15
 
15
- add_element(Element::Label.new(text, options, block))
16
+ add_element(Element::TextBlock.new(text, options, block))
17
+ end
18
+
19
+ [
20
+ "Banner",
21
+ "Title",
22
+ "Subtitle",
23
+ "Tagline",
24
+ "Caption",
25
+ "Para",
26
+ "Inscription"
27
+ ].each do |const|
28
+ define_method(:"#{const.downcase}") do |text, options = {}, &block|
29
+ options[:parent] = element_parent
30
+ options[:theme] = current_theme
31
+
32
+ add_element(Element.const_get(const).new(text, options, block))
33
+ end
16
34
  end
17
35
 
18
36
  def button(text, options = {}, &block)
@@ -13,10 +13,10 @@ module CyberarmEngine
13
13
  @options = options
14
14
  @block = block
15
15
 
16
- @focus = false
17
- @enabled = true
18
- @visible = true
19
- @tip = @options[:tip] || ""
16
+ @focus = @options[:focus].nil? ? false : @options[:focus]
17
+ @enabled = @options[:enabled].nil? ? true : @options[:enabled]
18
+ @visible = @options[:visible].nil? ? true : @options[:visible]
19
+ @tip = @options[:tip] || ""
20
20
 
21
21
  @style = Style.new(options)
22
22
 
@@ -1,6 +1,6 @@
1
1
  module CyberarmEngine
2
2
  class Element
3
- class Button < Label
3
+ class Button < TextBlock
4
4
  def initialize(text_or_image, options = {}, block = nil)
5
5
  @image = nil
6
6
  @scale_x = 1
@@ -10,7 +10,7 @@ module CyberarmEngine
10
10
 
11
11
  super(text_or_image, options, block)
12
12
 
13
- @style.background_canvas.background = default(:background)
13
+ @style.background_canvas.background = @style.background
14
14
  end
15
15
 
16
16
  def render
@@ -37,12 +37,15 @@ module CyberarmEngine
37
37
  def enter(_sender)
38
38
  @focus = false unless window.button_down?(Gosu::MsLeft)
39
39
 
40
- if @focus
41
- @style.background_canvas.background = default(:active, :background)
42
- @text.color = default(:active, :color)
40
+ if !@enabled
41
+ @style.background_canvas.background = @style.disabled[:background]
42
+ @text.color = @style.disabled[:color]
43
+ elsif @focus
44
+ @style.background_canvas.background = @style.active[:background]
45
+ @text.color = @style.active[:color]
43
46
  else
44
- @style.background_canvas.background = default(:hover, :background)
45
- @text.color = default(:hover, :color)
47
+ @style.background_canvas.background = @style.hover[:background]
48
+ @text.color = @style.hover[:color]
46
49
  end
47
50
 
48
51
  :handled
@@ -50,9 +53,16 @@ module CyberarmEngine
50
53
 
51
54
  def left_mouse_button(_sender, _x, _y)
52
55
  @focus = true
53
- @style.background_canvas.background = default(:active, :background)
56
+
57
+ unless @enabled
58
+ @style.background_canvas.background = @style.disabled[:background]
59
+ @text.color = @style.disabled[:color]
60
+ else
61
+ @style.background_canvas.background = @style.active[:background]
62
+ @text.color = @style.active[:color]
63
+ end
64
+
54
65
  window.current_state.focus = self
55
- @text.color = default(:active, :color)
56
66
 
57
67
  :handled
58
68
  end
@@ -64,14 +74,19 @@ module CyberarmEngine
64
74
  end
65
75
 
66
76
  def clicked_left_mouse_button(_sender, _x, _y)
67
- @block.call(self) if @block
77
+ @block.call(self) if @enabled && @block
68
78
 
69
79
  :handled
70
80
  end
71
81
 
72
82
  def leave(_sender)
73
- @style.background_canvas.background = default(:background)
74
- @text.color = default(:color)
83
+ unless @enabled
84
+ @style.background_canvas.background = @style.disabled[:background]
85
+ @text.color = @style.disabled[:color]
86
+ else
87
+ @style.background_canvas.background = @style.background
88
+ @text.color = @style.color
89
+ end
75
90
 
76
91
  :handled
77
92
  end
@@ -83,6 +98,14 @@ module CyberarmEngine
83
98
  end
84
99
 
85
100
  def recalculate
101
+ unless @enabled
102
+ @style.background_canvas.background = @style.disabled[:background]
103
+ @text.color = @style.disabled[:color]
104
+ else
105
+ @style.background_canvas.background = @style.background
106
+ @text.color = @style.color
107
+ end
108
+
86
109
  if @image
87
110
  @width = 0
88
111
  @height = 0
@@ -6,7 +6,7 @@ module CyberarmEngine
6
6
  options[:toggled] = options[:checked]
7
7
 
8
8
  @toggle_button = ToggleButton.new(options)
9
- @label = Label.new(text, options)
9
+ @label = TextBlock.new(text, options)
10
10
 
11
11
  @label.subscribe(:holding_left_mouse_button) do |sender, x, y|
12
12
  @toggle_button.left_mouse_button(sender, x, y)
@@ -1,11 +1,13 @@
1
1
  module CyberarmEngine
2
2
  class Element
3
3
  class Image < Element
4
- def initialize(path, options = {}, block = nil)
4
+ def initialize(path_or_image, options = {}, block = nil)
5
5
  super(options, block)
6
- @path = path
6
+ @path = path_or_image if path_or_image.is_a?(String)
7
+
8
+ @image = Gosu::Image.new(path_or_image, retro: @options[:retro], tileable: @options[:tileable]) if @path
9
+ @image = path_or_image unless @path
7
10
 
8
- @image = Gosu::Image.new(path, retro: @options[:image_retro])
9
11
  @scale_x = 1
10
12
  @scale_y = 1
11
13
  end
@@ -45,9 +47,24 @@ module CyberarmEngine
45
47
 
46
48
  @width = _width || @image.width.round * @scale_x
47
49
  @height = _height || @image.height.round * @scale_y
50
+
51
+ update_background
48
52
  end
49
53
 
50
54
  def value
55
+ @image
56
+ end
57
+
58
+ def value=(path_or_image, retro: false, tileable: false)
59
+ @path = path_or_image if path_or_image.is_a?(String)
60
+
61
+ @image = Gosu::Image.new(path_or_image, retro: retro, tileable: tileable) if @path
62
+ @image = path_or_image unless @path
63
+
64
+ recalculate
65
+ end
66
+
67
+ def path
51
68
  @path
52
69
  end
53
70
  end
@@ -1,6 +1,6 @@
1
1
  module CyberarmEngine
2
2
  class Element
3
- class Label < Element
3
+ class TextBlock < Element
4
4
  def initialize(text, options = {}, block = nil)
5
5
  super(options, block)
6
6
 
@@ -19,7 +19,7 @@ module CyberarmEngine
19
19
  end
20
20
 
21
21
  def clicked_left_mouse_button(_sender, _x, _y)
22
- @block&.call(self)
22
+ @block&.call(self) if @enabled
23
23
 
24
24
  # return :handled
25
25
  end
@@ -127,5 +127,30 @@ module CyberarmEngine
127
127
  publish(:changed, self.value)
128
128
  end
129
129
  end
130
+
131
+ class Banner < TextBlock
132
+ end
133
+
134
+ class Title < TextBlock
135
+ end
136
+
137
+ class Subtitle < TextBlock
138
+ end
139
+
140
+ class Tagline < TextBlock
141
+ end
142
+
143
+ class Caption < TextBlock
144
+ end
145
+
146
+ class Para < TextBlock
147
+ end
148
+
149
+ class Inscription < TextBlock
150
+ end
151
+
152
+ # TODO: Remove in version 0.16.0+
153
+ class Label < TextBlock
154
+ end
130
155
  end
131
156
  end
@@ -22,13 +22,16 @@ module CyberarmEngine
22
22
 
23
23
  def @menu.recalculate
24
24
  super
25
+
25
26
  recalculate_menu
26
27
  end
28
+
29
+ self.choose = @choose
27
30
  end
28
31
 
29
32
  def choose=(item)
30
33
  valid = @items.detect { |i| i == item }
31
- return unless valid # TODO: Throw an error?
34
+ raise "Invalid value '#{item}' for choose, valid options were: #{@items.map { |i| "#{i.inspect}" }.join(", ")}" unless valid
32
35
 
33
36
  @choose = item
34
37
 
@@ -45,13 +48,24 @@ module CyberarmEngine
45
48
 
46
49
  def show_menu
47
50
  @menu.clear
48
- @items.each do |item|
49
- [@block]
50
- block = proc { self.choose = item; @block.call(item) if @block }
51
- b = Button.new(item,
52
- { parent: @menu, width: 1.0, theme: @options[:theme], margin: 0, border_color: 0x00ffffff }, block)
53
51
 
54
- @menu.add(b)
52
+ @items.each do |item|
53
+ btn = Button.new(
54
+ item,
55
+ {
56
+ parent: @menu,
57
+ width: 1.0,
58
+ theme: @options[:theme],
59
+ margin: 0,
60
+ border_color: 0x00ffffff
61
+ },
62
+ proc do
63
+ self.choose = item
64
+ @block&.call(item)
65
+ end
66
+ )
67
+
68
+ @menu.add(btn)
55
69
  end
56
70
  recalculate
57
71
 
@@ -0,0 +1,156 @@
1
+ module CyberarmEngine
2
+ class Element
3
+ class TextBlock < Element
4
+ def initialize(text, options = {}, block = nil)
5
+ super(options, block)
6
+
7
+ @text = Text.new(
8
+ text, font: @options[:font], z: @z, color: @options[:color],
9
+ size: @options[:text_size], shadow: @options[:text_shadow],
10
+ shadow_size: @options[:text_shadow_size],
11
+ shadow_color: @options[:text_shadow_color]
12
+ )
13
+
14
+ @raw_text = text
15
+ end
16
+
17
+ def render
18
+ @text.draw
19
+ end
20
+
21
+ def clicked_left_mouse_button(_sender, _x, _y)
22
+ @block&.call(self) if @enabled
23
+
24
+ # return :handled
25
+ end
26
+
27
+ def recalculate
28
+ @width = 0
29
+ @height = 0
30
+
31
+ _width = dimensional_size(@style.width, :width)
32
+ _height = dimensional_size(@style.height, :height)
33
+
34
+ handle_text_wrapping(_width)
35
+
36
+ @width = _width || @text.width.round
37
+ @height = _height || @text.height.round
38
+
39
+ @text.y = @style.border_thickness_top + @style.padding_top + @y
40
+ @text.z = @z + 3
41
+
42
+ if (text_alignment = @options[:text_align])
43
+ case text_alignment
44
+ when :left
45
+ @text.x = @style.border_thickness_left + @style.padding_left + @x
46
+ when :center
47
+ @text.x = if @text.width <= outer_width
48
+ @x + outer_width / 2 - @text.width / 2
49
+ else # Act as left aligned
50
+ @style.border_thickness_left + @style.padding_left + @x
51
+ end
52
+ when :right
53
+ @text.x = @x + outer_width - (@text.width + @style.border_thickness_right + @style.padding_right)
54
+ end
55
+ end
56
+
57
+ update_background
58
+ end
59
+
60
+ def handle_text_wrapping(max_width)
61
+ max_width ||= @parent&.width
62
+ max_width ||= @x - (window.width + noncontent_width)
63
+ wrap_behavior = style.text_wrap
64
+ copy = @raw_text.to_s.dup
65
+
66
+ if line_width(copy[0]) <= max_width && line_width(copy) > max_width && wrap_behavior != :none
67
+ breaks = []
68
+ line_start = 0
69
+ line_end = copy.length
70
+
71
+ while line_start != copy.length
72
+ if line_width(copy[line_start...line_end]) > max_width
73
+ line_end = ((line_end - line_start) / 2.0)
74
+ line_end = 1.0 if line_end <= 1
75
+ elsif line_end < copy.length && line_width(copy[line_start...line_end + 1]) < max_width
76
+ # To small, grow!
77
+ # TODO: find a more efficient way
78
+ line_end += 1
79
+
80
+ else # FOUND IT!
81
+ entering_line_end = line_end.floor
82
+ max_reach = line_end.floor - line_start < 63 ? line_end.floor - line_start : 63
83
+ reach = 0
84
+
85
+ if wrap_behavior == :word_wrap
86
+ max_reach.times do |i|
87
+ reach = i
88
+ break if copy[line_end.floor - i].to_s.match(/[[:punct:]]| /)
89
+ end
90
+
91
+ # 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]}}"
92
+ line_end = line_end.floor - reach + 1 if reach != max_reach # Add +1 to walk in front of punctuation
93
+ end
94
+
95
+ breaks << line_end.floor
96
+ line_start = line_end.floor
97
+ line_end = copy.length
98
+
99
+ break if entering_line_end == copy.length || reach == max_reach
100
+ end
101
+ end
102
+
103
+ breaks.each_with_index do |pos, index|
104
+ copy.insert(pos + index, "\n") if pos + index >= 0 && pos + index < copy.length
105
+ end
106
+ end
107
+
108
+ @text.text = copy
109
+ end
110
+
111
+ def line_width(text)
112
+ (@text.textobject.markup_width(text) + noncontent_width)
113
+ end
114
+
115
+ def value
116
+ @raw_text
117
+ end
118
+
119
+ def value=(value)
120
+ @raw_text = value.to_s.chomp
121
+
122
+ old_width = width
123
+ old_height = height
124
+ recalculate
125
+
126
+ root.gui_state.request_recalculate if old_width != width || old_height != height
127
+
128
+ publish(:changed, self.value)
129
+ end
130
+ end
131
+
132
+ class Banner < TextBlock
133
+ end
134
+
135
+ class Title < TextBlock
136
+ end
137
+
138
+ class Subtitle < TextBlock
139
+ end
140
+
141
+ class Tagline < TextBlock
142
+ end
143
+
144
+ class Caption < TextBlock
145
+ end
146
+
147
+ class Para < TextBlock
148
+ end
149
+
150
+ class Inscription < TextBlock
151
+ end
152
+
153
+ class ToolTip < TextBlock
154
+ end
155
+ end
156
+ end
@@ -26,7 +26,7 @@ module CyberarmEngine
26
26
  @dragging_element = nil
27
27
  @pending_recalculate_request = false
28
28
 
29
- @tip = CyberarmEngine::Text.new("", size: 22, z: Float::INFINITY)
29
+ @tip = Element::ToolTip.new("", parent: @root_container, z: Float::INFINITY)
30
30
  @menu = nil
31
31
  @min_drag_distance = 0
32
32
  @mouse_pos = Vector.new
@@ -51,9 +51,8 @@ module CyberarmEngine
51
51
  @menu.draw
52
52
  end
53
53
 
54
- if @tip.text.length.positive?
54
+ if @tip.value.length.positive?
55
55
  Gosu.flush
56
- Gosu.draw_rect(@tip.x - 2, @tip.y - 2, @tip.width + 4, @tip.height + 4, 0xff020202, Float::INFINITY)
57
56
  @tip.draw
58
57
  end
59
58
  end
@@ -87,11 +86,17 @@ module CyberarmEngine
87
86
 
88
87
  if Vector.new(window.mouse_x, window.mouse_y) == @last_mouse_pos
89
88
  if @mouse_over && (Gosu.milliseconds - @mouse_moved_at) > tool_tip_delay
90
- @tip.text = @mouse_over.tip if @mouse_over
89
+ @tip.value = @mouse_over.tip if @mouse_over
91
90
  @tip.x = window.mouse_x - @tip.width / 2
92
- @tip.y = window.mouse_y - @tip.height - 4
91
+ @tip.x = 0 if @tip.x < 0
92
+ @tip.x = window.width - @tip.width if @tip.x + @tip.width > window.width
93
+ @tip.y = window.mouse_y - @tip.height
94
+ @tip.y = 0 if @tip.y < 0
95
+ @tip.y = window.height - @tip.height if @tip.y + @tip.height > window.height
96
+ @tip.update
97
+ @tip.recalculate
93
98
  else
94
- @tip.text = ""
99
+ @tip.value = ""
95
100
  end
96
101
  else
97
102
  @mouse_moved_at = Gosu.milliseconds
@@ -107,7 +112,7 @@ module CyberarmEngine
107
112
  end
108
113
 
109
114
  def tool_tip_delay
110
- 500 # ms
115
+ 250 # ms
111
116
  end
112
117
 
113
118
  def button_down(id)
@@ -82,6 +82,11 @@ module CyberarmEngine
82
82
  active: {
83
83
  color: Gosu::Color::BLACK,
84
84
  background: ["ffB23E41".to_i(16)]
85
+ },
86
+
87
+ disabled: {
88
+ color: Gosu::Color::GRAY,
89
+ background: 0xff303030
85
90
  }
86
91
  },
87
92
 
@@ -98,12 +103,13 @@ module CyberarmEngine
98
103
 
99
104
  Image: { # < Element
100
105
  color: Gosu::Color::WHITE,
106
+ tileable: false,
101
107
  retro: false
102
108
  },
103
109
 
104
- Label: { # < Element
110
+ TextBlock: { # < Element
105
111
  text_size: 28,
106
- text_wrap: :none, # :word_wrap, :break_word, :none
112
+ text_wrap: :word_wrap, # :word_wrap, :break_word, :none
107
113
  text_shadow: false,
108
114
  text_align: :left,
109
115
  font: "Arial",
@@ -111,6 +117,45 @@ module CyberarmEngine
111
117
  padding: 2
112
118
  },
113
119
 
120
+ Banner: { # < TextBlock
121
+ text_size: 48
122
+ },
123
+
124
+ Title: { # < TextBlock
125
+ text_size: 34
126
+ },
127
+
128
+ Subtitle: { # < TextBlock
129
+ text_size: 26
130
+ },
131
+
132
+ Tagline: { # < TextBlock
133
+ text_size: 24
134
+ },
135
+
136
+ Caption: { # < TextBlock
137
+ text_size: 22
138
+ },
139
+
140
+ Para: { # < TextBlock
141
+ text_size: 18
142
+ },
143
+
144
+ Inscription: { # < TextBlock
145
+ text_size: 16
146
+ },
147
+
148
+ ToolTip: { # < TextBlock
149
+ color: Gosu::Color::WHITE,
150
+ padding_top: 4,
151
+ padding_bottom: 4,
152
+ padding_left: 8,
153
+ padding_right: 8,
154
+ border_thickness: 1,
155
+ border_color: 0xffaaaaaa,
156
+ background: 0xff404040
157
+ },
158
+
114
159
  ToggleButton: { # < Button
115
160
  checkmark: "√"
116
161
  },
@@ -1,4 +1,4 @@
1
1
  module CyberarmEngine
2
2
  NAME = "InDev".freeze
3
- VERSION = "0.15.0".freeze
3
+ VERSION = "0.16.0".freeze
4
4
  end
@@ -1,5 +1,7 @@
1
1
  module CyberarmEngine
2
2
  class Window < Gosu::Window
3
+ include Common
4
+
3
5
  IMAGES = {}
4
6
  SAMPLES = {}
5
7
  SONGS = {}
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.15.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyberarm
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-31 00:00:00.000000000 Z
11
+ date: 2021-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard
@@ -175,6 +175,7 @@ files:
175
175
  - lib/cyberarm_engine/ui/elements/radio.rb
176
176
  - lib/cyberarm_engine/ui/elements/slider.rb
177
177
  - lib/cyberarm_engine/ui/elements/stack.rb
178
+ - lib/cyberarm_engine/ui/elements/text_block.rb
178
179
  - lib/cyberarm_engine/ui/elements/toggle_button.rb
179
180
  - lib/cyberarm_engine/ui/event.rb
180
181
  - lib/cyberarm_engine/ui/gui_state.rb