From 0fe1d859245d31a23920b714ee9661a9154c7ee4 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Thu, 3 Jun 2021 15:14:06 +0000 Subject: [PATCH] Added Window#input_hijack to allow objects to get exclusive access to button_down/up callbacks, improved Chat widget --- lib/hud.rb | 8 ++++ lib/hud/widget.rb | 14 ++++++ lib/hud/widgets/chat.rb | 80 ++++++++++++++++++++++++++++------ lib/states/game_states/game.rb | 4 ++ lib/ui/menus/main_menu.rb | 7 ++- lib/window.rb | 10 +++++ 6 files changed, 107 insertions(+), 16 deletions(-) diff --git a/lib/hud.rb b/lib/hud.rb index 993479a..2c0091d 100644 --- a/lib/hud.rb +++ b/lib/hud.rb @@ -32,5 +32,13 @@ class IMICFPS def update @hud_elements.each(&:update) end + + def button_down(id) + @hud_elements.each { |e| e.button_down(id) } + end + + def button_up(id) + @hud_elements.each { |e| e.button_up(id) } + end end end diff --git a/lib/hud/widget.rb b/lib/hud/widget.rb index 61862ed..4b5be65 100644 --- a/lib/hud/widget.rb +++ b/lib/hud/widget.rb @@ -57,6 +57,20 @@ class IMICFPS def update end + + def button_down(id) + end + + def button_up(id) + end + + def hijack_input! + $window.input_hijack = self + end + + def release_input! + $window.input_hijack = nil + end end end end diff --git a/lib/hud/widgets/chat.rb b/lib/hud/widgets/chat.rb index e381143..083e324 100644 --- a/lib/hud/widgets/chat.rb +++ b/lib/hud/widgets/chat.rb @@ -4,41 +4,93 @@ class IMICFPS class HUD class ChatWidget < HUD::Widget def setup + @deliver_to_text = Text.new("", size: 28, font: BOLD_SANS_FONT) @text = Text.new("", size: 28, font: SANS_FONT) + + @text_input = nil @background = Gosu::Color.new(0x88c64600) + @selection_color = Gosu::Color.new(0x88222222) + @width = @options[:width] || 400 + + @delivery_options = [:all, :team, :squad] end def draw - return unless window.text_input + return unless @text_input Gosu.draw_rect( - @text.x - Widget.horizontal_padding, @text.y - Widget.horizontal_padding, - @text.width + Widget.vertical_padding * 2, @text.height + Widget.vertical_padding * 2, + Widget.horizontal_margin, $window.height / 2 - (@text.height / 2 + Widget.horizontal_padding), + @width - Widget.horizontal_padding * 2, @text.height + Widget.vertical_padding * 2, @background ) - @text.draw + @deliver_to_text.draw + + clip_width = @deliver_to_text.width + Widget.horizontal_padding * 3 + Widget.horizontal_margin + Gosu.clip_to(@text.x, @text.y, @width - clip_width, @text.height) do + x = Widget.horizontal_margin + Widget.horizontal_padding + @deliver_to_text.width + + cursor_x = x + @text.width(@text_input.text[0...@text_input.caret_pos]) + selection_x = x + @text.width(@text_input.text[0...@text_input.selection_start]) + selection_width = cursor_x - selection_x + cursor_thickness = 2 + + Gosu.draw_rect(selection_x, @text.y, selection_width, @text.height, @selection_color) + Gosu.draw_rect(cursor_x, @text.y, cursor_thickness, @text.height, Gosu::Color::WHITE) + @text.draw + end end def update - # NOTE: Account for Y in QWERTZ layout - text = window.text_input&.text + @deliver_to_text.text = "#{@deliver_to}: " + @deliver_to_text.x = Widget.horizontal_margin + Widget.horizontal_padding + @deliver_to_text.y = $window.height / 2 - (@text.height / 2) - if window.text_input.nil? && (Gosu.button_down?(Gosu::KbT) || Gosu.button_down?(Gosu::KbY) || Gosu.button_down?(Gosu::KbU)) - window.text_input = Gosu::TextInput.new + @text.text = @text_input&.text.to_s + @text.x = Widget.horizontal_margin + Widget.horizontal_padding + @deliver_to_text.width + @text.y = $window.height / 2 - (@text.height / 2) + end + + def button_down(id) + # TODO: Use InputMapper keymap to function + # NOTE: Account for Y in QWERTZ layout + case id + when Gosu::KB_T, Gosu::KB_Y, Gosu::KB_U + return if @text_input + + hijack_input! + + @text_input = window.text_input = Gosu::TextInput.new @deliver_to = :all if Gosu.button_down?(Gosu::KbT) @deliver_to = :team if Gosu.button_down?(Gosu::KbY) @deliver_to = :squad if Gosu.button_down?(Gosu::KbU) - end + when Gosu::KB_TAB + return unless @text_input - if window.text_input && (Gosu.button_down?(Gosu::KbEnter) || Gosu.button_down?(Gosu::KbReturn)) - window.text_input = nil + cycle_deliver_to end + end - @text.text = text.to_s - @text.x = window.width / 2 - (Widget.horizontal_margin + @text.width / 2 + Widget.horizontal_padding) - @text.y = window.height - (Widget.vertical_margin + @text.height + Widget.vertical_padding) + def button_up(id) + return unless @text_input + + case id + when Gosu::KB_ENTER, Gosu::KB_RETURN + release_input! + + # TODO: Deliver message to server + + @text_input = window.text_input = nil + when Gosu::KB_ESCAPE + release_input! + @text_input = window.text_input = nil + end + end + + def cycle_deliver_to + i = @delivery_options.index(@deliver_to) + @deliver_to = @delivery_options[(i + 1) % (@delivery_options.size)] end end end diff --git a/lib/states/game_states/game.rb b/lib/states/game_states/game.rb index e70a36f..f37b96a 100644 --- a/lib/states/game_states/game.rb +++ b/lib/states/game_states/game.rb @@ -69,6 +69,8 @@ class IMICFPS window.director.map.entities.each do |entity| entity.button_down(id) if defined?(entity.button_down) end + + @hud.button_down(id) end def button_up(id) @@ -81,6 +83,8 @@ class IMICFPS window.director.map.entities.each do |entity| entity.button_up(id) if defined?(entity.button_up) end + + @hud.button_up(id) end end end diff --git a/lib/ui/menus/main_menu.rb b/lib/ui/menus/main_menu.rb index 9d5f02a..3f2a8b9 100644 --- a/lib/ui/menus/main_menu.rb +++ b/lib/ui/menus/main_menu.rb @@ -40,14 +40,17 @@ Fallback immediate mode renderer will be used." (Linux Only) For MESA based drivers append --mesa-override as a commandline argument to override reported version." message += linux_mesa_message if RUBY_PLATFORM =~ /linux/ && gl_version.downcase.include?(" mesa ") - @old_gl_warning = Gosu::Image.from_markup(message, 24, align: :center, font: "") + @old_gl_warning = Text.new(message, size: 24, z: Float::INFINITY, border: true, border_color: Gosu::Color::BLACK) end end def draw super - @old_gl_warning&.draw(window.width / 2 - @old_gl_warning.width / 2, window.height - (@old_gl_warning.height + 10), Float::INFINITY) + @old_gl_warning&.x = window.width / 2 - @old_gl_warning.width / 2 + @old_gl_warning&.y = window.height - (@old_gl_warning.height + 10) + + @old_gl_warning&.draw end end end diff --git a/lib/window.rb b/lib/window.rb index 3cce7a8..05bf088 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -53,6 +53,12 @@ class IMICFPS end end + def input_hijack=(hijacker) + @input_hijacker = hijacker + + InputMapper.reset_keys + end + def needs_cursor? false end @@ -92,6 +98,8 @@ class IMICFPS def button_down(id) if @show_console @console.button_down(id) + elsif @input_hijacker + @input_hijacker.button_down(id) else super end @@ -105,6 +113,8 @@ class IMICFPS def button_up(id) if @show_console @console.button_up(id) + elsif @input_hijacker + @input_hijacker.button_up(id) else super end