cyberarm_engine 0.15.0 → 0.16.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: 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