diff --git a/lib/cyberarm_engine/background_nine_slice.rb b/lib/cyberarm_engine/background_nine_slice.rb index db72f0f..272bf13 100644 --- a/lib/cyberarm_engine/background_nine_slice.rb +++ b/lib/cyberarm_engine/background_nine_slice.rb @@ -1,6 +1,9 @@ module CyberarmEngine class BackgroundNineSlice include CyberarmEngine::Common + + CACHE = {} + attr_accessor :x, :y, :z, :width, :height, :mode, :color attr_reader :image, :left, :top, :right, :bottom diff --git a/lib/cyberarm_engine/text.rb b/lib/cyberarm_engine/text.rb index 50a02dc..d3ecce7 100644 --- a/lib/cyberarm_engine/text.rb +++ b/lib/cyberarm_engine/text.rb @@ -23,7 +23,7 @@ module CyberarmEngine @color = Gosu::Color::WHITE end @mode = options[:mode] || :default - @alignment = options[:alignment] || nil + @alignment = options[:alignment] || :left @border = options[:border] @border = true if options[:border].nil? @@ -39,17 +39,6 @@ module CyberarmEngine @static = options[:static] || (options[:static].nil? || options[:static] == false ? false : true) @textobject = check_cache(@size, @font) - - if @alignment - case @alignment - when :left - @x = 0 + BUTTON_PADDING - when :center - @x = (CyberarmEngine::Window.instance.width / 2) - (@textobject.text_width(@text) / 2) - when :right - @x = CyberarmEngine::Window.instance.width - BUTTON_PADDING - @textobject.text_width(@text) - end - end end def check_cache(size, font_name) @@ -113,6 +102,38 @@ module CyberarmEngine invalidate_cache! if old_color != color end + def alignment=(value) + invalidate_cache! if @alignment != value + @alignment = value + end + + def shadow=(value) + invalidate_cache! if @shadow != value + @shadow = value + end + + def shadow_color=(color) + old_color = @shadow_color + + if color + @shadow_color = color.is_a?(Gosu::Color) ? color : Gosu::Color.new(color) + else + raise "color cannot be nil" + end + + invalidate_cache! if old_color != color + end + + def shadow_alpha=(value) + invalidate_cache! if @shadow_alpha != value + @shadow_alpha = value + end + + def shadow_size=(value) + invalidate_cache! if @shadow_size != value + @shadow_size = value + end + def border=(boolean) invalidate_cache! if @border != boolean @border = boolean @@ -129,8 +150,15 @@ module CyberarmEngine end def border_color=(n) - invalidate_cache! if @border_color != n - @border_color = n + old_color = @border_color + + if color + @border_color = color.is_a?(Gosu::Color) ? color : Gosu::Color.new(color) + else + raise "color cannot be nil" + end + + invalidate_cache! if old_color != color end def width(text = @text) @@ -194,9 +222,9 @@ module CyberarmEngine end end - @cached_text_shadow_image ||= Gosu::Image.send(:"from_#{method.to_s.split("_").last}", @text, @size, font: @font) if @shadow + @cached_text_shadow_image ||= Gosu::Image.send(:"from_#{method.to_s.split("_").last}", @text, @size, font: @font, align: @alignment) if @shadow - @gosu_cached_text_image ||= Gosu::Image.send(:"from_#{method.to_s.split("_").last}", @text, @size, font: @font) + @gosu_cached_text_image ||= Gosu::Image.send(:"from_#{method.to_s.split("_").last}", @text, @size, font: @font, align: @alignment) @cached_text_border_image.draw(@x, @y, @z, @factor_x, @factor_y, @border_color, @mode) if @border diff --git a/lib/cyberarm_engine/ui/element.rb b/lib/cyberarm_engine/ui/element.rb index 0b7228d..247c7d2 100644 --- a/lib/cyberarm_engine/ui/element.rb +++ b/lib/cyberarm_engine/ui/element.rb @@ -18,7 +18,7 @@ module CyberarmEngine @visible = !@options.key?(:visible) ? true : @options[:visible] @tip = @options[:tip] || "" - @debug = @options[:debug] || false + @debug = @options[:debug] || CyberarmEngine.const_defined?("GUI_DEBUG") && CyberarmEngine::GUI_DEBUG || false @debug_color = @options[:debug_color].nil? ? Gosu::Color::RED : @options[:debug_color] @style = Style.new(options) @@ -44,7 +44,7 @@ module CyberarmEngine @background_image_canvas = nil # BackgroundImage.new @border_canvas = nil # BorderCanvas.new(element: self) - @style_event = :default + @style_event = enabled? ? :default : :disabled stylize @@ -53,7 +53,15 @@ module CyberarmEngine root.gui_state.request_focus(self) if @options[:autofocus] end + def resolution_scaled(n) + return n unless @style.design_width + + ((@style.design_width / Gosu.screen_width(window).to_f) * n).floor + end + def stylize + @style_event = :disabled unless enabled? + set_static_position set_color @@ -108,7 +116,7 @@ module CyberarmEngine end def set_font - @text&.swap_font(safe_style_fetch(:text_size), safe_style_fetch(:font)) + @text&.swap_font(resolution_scaled(safe_style_fetch(:text_size)), safe_style_fetch(:font)) end def set_background @@ -275,6 +283,7 @@ module CyberarmEngine root.gui_state.request_repaint if @enabled != boolean @enabled = boolean + @style_event = :default if boolean && @style_event == :disabled recalculate diff --git a/lib/cyberarm_engine/ui/elements/button.rb b/lib/cyberarm_engine/ui/elements/button.rb index f300a46..9c9361c 100644 --- a/lib/cyberarm_engine/ui/elements/button.rb +++ b/lib/cyberarm_engine/ui/elements/button.rb @@ -35,13 +35,8 @@ module CyberarmEngine end def layout - unless @enabled - @background_canvas.background = @style.disabled.background - @text.color = @style.disabled.color - else - @background_canvas.background = styled(:background) - @text.color = styled(:color) - end + @background_canvas.background = styled(:background) + @text.color = styled(:color) if @image @width = 0 @@ -78,6 +73,8 @@ module CyberarmEngine end def value=(value) + old_value = self.value + if value.is_a?(Gosu::Image) @image = value else @@ -93,7 +90,9 @@ module CyberarmEngine recalculate end - publish(:changed, self.value) + publish(:changed, self.value) if value != old_value + + self.value end end end diff --git a/lib/cyberarm_engine/ui/elements/check_box.rb b/lib/cyberarm_engine/ui/elements/check_box.rb index b9ec560..ec1d8a9 100644 --- a/lib/cyberarm_engine/ui/elements/check_box.rb +++ b/lib/cyberarm_engine/ui/elements/check_box.rb @@ -46,8 +46,12 @@ module CyberarmEngine end def value=(bool) + old_value = this.value + @toggle_button.value = bool - publish(:changed, @toggle_button.value) + publish(:changed, bool) if bool != old_value + + bool end end end diff --git a/lib/cyberarm_engine/ui/elements/edit_box.rb b/lib/cyberarm_engine/ui/elements/edit_box.rb index 69780bb..ec6fbad 100644 --- a/lib/cyberarm_engine/ui/elements/edit_box.rb +++ b/lib/cyberarm_engine/ui/elements/edit_box.rb @@ -45,19 +45,23 @@ module CyberarmEngine def draw_selection selection_width = caret_position - selection_start_position + selection_start_line = calculate_line(@text_input.caret_pos) + selection_end_line = calculate_line(@text_input.selection_start) - Gosu.draw_rect(selection_start_position, @text.y, selection_width, @text.textobject.height, + # pp [selection_width, selection_start_line, selection_end_line] + + Gosu.draw_rect(selection_start_position, @text.y + selection_start_line * @text.textobject.height, selection_width, @text.textobject.height, default(:selection_color), @z) end - def text_input_position_for(_method) - line = @text_input.text[0...@text_input.caret_pos].lines.last + def text_input_position_for(method) + line = @text_input.text[0...@text_input.send(method)].lines.last _x = @text.x + @offset_x if @type == :password - _x + @text.width(default(:password_character) * line.length) + _x + @text.width(default(:password_character) * line.length) - @style.border_thickness_left else - _x + @text.width(line) + _x + @text.width(line) - @style.border_thickness_left end end @@ -66,9 +70,12 @@ module CyberarmEngine @text_input.selection_start = @text_input.caret_pos = int end + def calculate_line(caret_pos = @text_input.caret_pos) + sub_text = @text_input.text[0...caret_pos].lines.size - 1 + end + def calculate_active_line - sub_text = @text_input.text[0...@text_input.caret_pos] - @active_line = sub_text.lines.size - 1 + @active_line = calculate_line(@text_input.caret_pos) end def caret_stay_left_of_last_newline @@ -92,7 +99,7 @@ module CyberarmEngine end active_line = row_at(mouse_y - y_scroll_offset) - right_offset = column_at(mouse_x, mouse_y) + right_offset = column_at(mouse_x, mouse_y - y_scroll_offset) buffer = @text_input.text.lines[0..active_line].join if active_line != 0 buffer = @text_input.text.lines.first if active_line == 0 @@ -176,6 +183,8 @@ module CyberarmEngine pos = text.length end + pp [direction, pos, @active_line] + set_position(pos) end diff --git a/lib/cyberarm_engine/ui/elements/edit_line.rb b/lib/cyberarm_engine/ui/elements/edit_line.rb index de3b423..e3e7322 100644 --- a/lib/cyberarm_engine/ui/elements/edit_line.rb +++ b/lib/cyberarm_engine/ui/elements/edit_line.rb @@ -291,6 +291,8 @@ module CyberarmEngine def value=(string) @text_input.text = string + + string end end end diff --git a/lib/cyberarm_engine/ui/elements/image.rb b/lib/cyberarm_engine/ui/elements/image.rb index be720ad..ed54900 100644 --- a/lib/cyberarm_engine/ui/elements/image.rb +++ b/lib/cyberarm_engine/ui/elements/image.rb @@ -56,12 +56,18 @@ module CyberarmEngine end def value=(path_or_image, retro: false, tileable: false) + old_value = self.value + @path = path_or_image if path_or_image.is_a?(String) @image = Gosu::Image.new(path_or_image, retro: retro, tileable: tileable) if @path @image = path_or_image unless @path recalculate + + publish(:changed, @image) if old_value != self.value + + self.value end def path diff --git a/lib/cyberarm_engine/ui/elements/progress.rb b/lib/cyberarm_engine/ui/elements/progress.rb index c67f4b4..9468a2a 100644 --- a/lib/cyberarm_engine/ui/elements/progress.rb +++ b/lib/cyberarm_engine/ui/elements/progress.rb @@ -83,9 +83,11 @@ module CyberarmEngine @fraction = decimal.clamp(0.0, 1.0) update_background - root.gui_state.request_repaint if @fraction != old_value + if @fraction != old_value + root.gui_state.request_repaint + publish(:changed, @fraction) + end - publish(:changed, @fraction) @fraction end end diff --git a/lib/cyberarm_engine/ui/elements/slider.rb b/lib/cyberarm_engine/ui/elements/slider.rb index 791f563..8c087ed 100644 --- a/lib/cyberarm_engine/ui/elements/slider.rb +++ b/lib/cyberarm_engine/ui/elements/slider.rb @@ -94,13 +94,17 @@ module CyberarmEngine end def value=(n) + old_value = this.value + @value = n position_handle @handle.recalculate root.gui_state.request_repaint - publish(:changed, @value) + publish(:changed, @value) if old_value != n + + n end end end diff --git a/lib/cyberarm_engine/ui/elements/text_block.rb b/lib/cyberarm_engine/ui/elements/text_block.rb index d0d8ff3..c86a418 100644 --- a/lib/cyberarm_engine/ui/elements/text_block.rb +++ b/lib/cyberarm_engine/ui/elements/text_block.rb @@ -8,6 +8,7 @@ module CyberarmEngine text, font: @options[:font], z: @z, color: @options[:color], size: @options[:text_size], shadow: @options[:text_shadow], static: @options[:text_static], + alignment: @options[:text_align], shadow_size: @options[:text_shadow_size], shadow_color: @options[:text_shadow_color], border: @options[:text_border], @@ -41,11 +42,18 @@ module CyberarmEngine end def layout - unless @enabled - @text.color = @style.disabled.color - else - @text.color = styled(:color) - end + @text.color = styled(:color) + @text.alignment = styled(:text_align) + + @text.shadow = styled(:text_shadow) + @text.shadow_color = styled(:text_shadow_color) + @text.shadow_alpha = styled(:text_shadow_alpha) + @text.shadow_size = styled(:text_shadow_size) + + @text.border = styled(:text_border) + @text.border_color = styled(:text_border_color) + @text.border_alpha = styled(:text_border_alpha) + @text.border_size = styled(:text_border_size) @width = 0 @height = 0 @@ -186,9 +194,12 @@ module CyberarmEngine recalculate end - root.gui_state.request_repaint if old_value != @raw_text + if old_value != @raw_text + root.gui_state.request_repaint + publish(:changed, @raw_text) + end - publish(:changed, self.value) + value end end diff --git a/lib/cyberarm_engine/ui/elements/toggle_button.rb b/lib/cyberarm_engine/ui/elements/toggle_button.rb index 4efb3c2..ddbb5ff 100644 --- a/lib/cyberarm_engine/ui/elements/toggle_button.rb +++ b/lib/cyberarm_engine/ui/elements/toggle_button.rb @@ -50,6 +50,8 @@ module CyberarmEngine end def value=(boolean) + old_value = self.value + @value = boolean if boolean @@ -60,7 +62,9 @@ module CyberarmEngine recalculate - publish(:changed, @value) + publish(:changed, @value) if old_value != boolean + + boolean end end end diff --git a/lib/cyberarm_engine/ui/event.rb b/lib/cyberarm_engine/ui/event.rb index 4a95c7d..dafa527 100644 --- a/lib/cyberarm_engine/ui/event.rb +++ b/lib/cyberarm_engine/ui/event.rb @@ -13,7 +13,7 @@ module CyberarmEngine def publish(event, *args) raise ArgumentError, "#{self.class} does not handle #{event.inspect}" unless @event_handler.include?(event) - return unless enabled? + return if !enabled? && event != :changed was_handled = false diff --git a/lib/cyberarm_engine/ui/style.rb b/lib/cyberarm_engine/ui/style.rb index ea3401a..ca0583c 100644 --- a/lib/cyberarm_engine/ui/style.rb +++ b/lib/cyberarm_engine/ui/style.rb @@ -23,7 +23,7 @@ module CyberarmEngine end %i[ - x y z width height min_width min_height max_width max_height color background + x y z design_width width height min_width min_height max_width max_height color background background_image background_image_mode background_image_color background_nine_slice background_nine_slice_mode background_nine_slice_color background_nine_slice_from_edge background_nine_slice_left background_nine_slice_top background_nine_slice_right background_nine_slice_bottom @@ -33,7 +33,10 @@ module CyberarmEngine margin margin_left margin_right margin_top margin_bottom aspect_ratio - fraction_background scroll fill text_wrap v_align h_align delay tag font text_size + fraction_background scroll fill text_wrap v_align h_align delay tag font + text_align text_static text_size + text_shadow text_shadow_size text_shadow_alpha text_shadow_color + text_border text_border_size text_border_alpha text_border_color image_width image_height ].each do |item| define_method(item) do diff --git a/lib/cyberarm_engine/ui/theme.rb b/lib/cyberarm_engine/ui/theme.rb index f660fc5..c8f4ba8 100644 --- a/lib/cyberarm_engine/ui/theme.rb +++ b/lib/cyberarm_engine/ui/theme.rb @@ -30,6 +30,11 @@ module CyberarmEngine end end + # css-like style classes, however First In, First Out- that is, + options[:style_class]&.each do |klass| + hash = deep_merge(hash, _theme[klass]) if _theme[klass] + end + deep_merge(hash, options) end @@ -53,6 +58,7 @@ module CyberarmEngine y: 0, z: 30, + design_width: nil, width: nil, height: nil, color: Gosu::Color::WHITE, @@ -68,7 +74,7 @@ module CyberarmEngine debug_color: Gosu::Color::YELLOW }, - Button: { # < Label + Button: { # < TextBlock margin: 1, padding: 4, border_thickness: 1, @@ -121,7 +127,13 @@ module CyberarmEngine text_size: 28, text_wrap: :word_wrap, # :word_wrap, :break_word, :none text_shadow: false, + text_shadow_color: 0, + text_shadow_alpha: 30, + text_shadow_size: 2, text_border: false, + text_border_color: 0, + text_border_alpha: 30, + text_border_size: 2, text_align: :left, font: "Arial", margin: 0,