diff --git a/lib/pages/games.rb b/lib/pages/games.rb
index ef97011..287052d 100644
--- a/lib/pages/games.rb
+++ b/lib/pages/games.rb
@@ -3,21 +3,28 @@ class W3DHub
class Games < Page
def setup
@game_news ||= {}
+ @game_events ||= {}
+
@focused_game ||= Store.applications.games.find { |g| g.id == Store.settings[:last_selected_app] }
@focused_game ||= Store.applications.games.find { |g| g.id == "ren" }
@focused_channel ||= @focused_game.channels.find { |c| c.id == Store.settings[:last_selected_channel] }
@focused_channel ||= @focused_game.channels.first
body.clear do
- # Games List
- @games_list_container = stack(width: 0.15, max_width: 148, height: 1.0, scroll: true, border_thickness_right: 1, border_color_right: W3DHub::BORDER_COLOR) do
- end
+ stack(width: 1.0, height: 1.0) do
+ # Games List
+ @games_list_container = flow(width: 1.0, height: 64, scroll: true, border_thickness_bottom: 1, border_color_bottom: W3DHub::BORDER_COLOR, padding_left: 32, padding_right: 32) do
+ end
- # Game Menu
- @game_page_container = stack(fill: true, height: 1.0) do
+ # Game Menu
+ @game_page_container = stack(width: 1.0, fill: true, background_image: "#{GAME_ROOT_PATH}/media/textures/noiseb.png", background_image_mode: :tiled) do
+ # , background_image: "C:/Users/cyber/Downloads/vlcsnap-2022-04-24-22h24m15s854.png"
+ end
end
end
+ # return if Store.offline_mode
+
populate_game_page(@focused_game, @focused_channel)
populate_games_list
end
@@ -26,25 +33,37 @@ class W3DHub
@games_list_container.clear do
background 0xff_121920
+ stack(width: 128, height: 1.0) do
+ flow(fill: true)
+
+ button "All Games" do
+ populate_all_games_view
+ end
+
+ flow(fill: true)
+ end
+
+ has_favorites = Store.settings[:favorites].size.positive?
+
Store.applications.games.each do |game|
+ next if has_favorites && !Store.application_manager.favorite?(game.id)
+
selected = game == @focused_game
- game_button = stack(width: 1.0, border_thickness_left: 4,
- border_color_left: selected ? 0xff_00acff : 0x00_000000,
+ game_button = stack(width: 64, height: 1.0, border_thickness_bottom: 4,
+ border_color_bottom: selected ? 0xff_00acff : 0x00_000000,
hover: { background: selected ? game.color : 0xff_444444 },
- padding_top: 4, padding_bottom: 4) do
+ padding_left: 4, padding_right: 4, tip: game.name) do
background game.color if selected
- flow(width: 1.0, height: 48) do
- stack(width: 0.3) do
- image "#{GAME_ROOT_PATH}/media/ui_icons/return.png", width: 1.0, color: Gosu::Color::GRAY if Store.application_manager.updateable?(game.id, game.channels.first.id)
- image "#{GAME_ROOT_PATH}/media/ui_icons/import.png", width: 0.5, color: 0x88_ffffff unless Store.application_manager.installed?(game.id, game.channels.first.id)
- end
- image_path = File.exist?("#{GAME_ROOT_PATH}/media/icons/#{game.id}.png") ? "#{GAME_ROOT_PATH}/media/icons/#{game.id}.png" : "#{GAME_ROOT_PATH}/media/icons/default_icon.png"
+ image_path = File.exist?("#{GAME_ROOT_PATH}/media/icons/#{game.id}.png") ? "#{GAME_ROOT_PATH}/media/icons/#{game.id}.png" : "#{GAME_ROOT_PATH}/media/icons/default_icon.png"
+ image_color = Store.application_manager.installed?(game.id, game.channels.first.id) ? 0xff_ffffff : 0x66_ffffff
- image image_path, height: 48, color: Store.application_manager.installed?(game.id, game.channels.first.id) ? 0xff_ffffff : 0x88_ffffff
+ flow(width: 1.0, height: 1.0, margin: 8, background_image: image_path, background_image_color: image_color, background_image_mode: :fill_height) do
+ image "#{GAME_ROOT_PATH}/media/ui_icons/import.png", width: 24, margin_left: -4, margin_top: -6, color: 0xff_ff8800 if Store.application_manager.updateable?(game.id, game.channels.first.id)
end
- inscription game.name, width: 1.0, text_align: :center
+
+ # inscription game.name, width: 1.0, text_align: :center, text_size: 14
end
def game_button.hit_element?(x, y)
@@ -68,120 +87,279 @@ class W3DHub
@game_page_container.clear do
background game.color
-
- # Release channel
- flow(width: 1.0, height: 18) do
- # background 0xff_444411
-
- inscription I18n.t(:"games.channel")
- list_box(items: game.channels.map(&:name), choose: channel.name, enabled: game.channels.count > 1,
- margin_top: 0, margin_bottom: 0, width: 128,
- padding_left: 1, padding_top: 1, padding_right: 1, padding_bottom: 1, text_size: 14) do |value|
- populate_game_page(game, game.channels.find { |c| c.name == value })
- end
- end
+ @game_page_container.style.background_image_color = game.color
+ @game_page_container.style.default[:background_image_color] = game.color
+ @game_page_container.update_background_image
# Game Stuff
flow(width: 1.0, fill: true) do
# background 0xff_9999ff
# Game options
- stack(width: 208, height: 1.0, padding: 8, scroll: true) do
- # background 0xff_550055
+ stack(width: 360, height: 1.0, padding: 8, scroll: true, border_thickness_right: 1, border_color_right: W3DHub::BORDER_COLOR) do
+ background 0x55_000000
- if Store.application_manager.installed?(game.id, channel.id)
- Hash.new.tap { |hash|
- hash[I18n.t(:"games.game_settings")] = { icon: "gear", block: proc { Store.application_manager.settings(game.id, channel.id) } }
- hash[I18n.t(:"games.wine_configuration")] = { icon: "gear", block: proc { Store.application_manager.wine_configuration(game.id, channel.id) } } if W3DHub.unix?
- hash[I18n.t(:"games.game_modifications")] = { icon: "gear", enabled: true, block: proc { populate_game_modifications(game, channel) } }
- if game.id != "ren"
- hash[I18n.t(:"games.repair_installation")] = { icon: "wrench", block: proc { Store.application_manager.repair(game.id, channel.id) } }
- hash[I18n.t(:"games.uninstall_game")] = { icon: "trashCan", block: proc { Store.application_manager.uninstall(game.id, channel.id) } }
+ # Game Banner
+ image_path = "#{GAME_ROOT_PATH}/media/banners/#{game.id}.png"
+
+ if File.exist?(image_path)
+ image image_path, width: 1.0
+ else
+ banner game.name unless File.exist?(image_path)
+ end
+
+ stack(width: 1.0, fill: true, scroll: true, margin_top: 32) do
+ if Store.application_manager.installed?(game.id, channel.id)
+ Hash.new.tap { |hash|
+ # hash[I18n.t(:"games.game_settings")] = { icon: "gear", block: proc { Store.application_manager.settings(game.id, channel.id) } }
+ # hash[I18n.t(:"games.wine_configuration")] = { icon: "gear", block: proc { Store.application_manager.wine_configuration(game.id, channel.id) } } if W3DHub.unix?
+ # hash[I18n.t(:"games.game_modifications")] = { icon: "gear", enabled: true, block: proc { populate_game_modifications(game, channel) } }
+ # if game.id != "ren"
+ # hash[I18n.t(:"games.repair_installation")] = { icon: "wrench", block: proc { Store.application_manager.repair(game.id, channel.id) } }
+ # hash[I18n.t(:"games.uninstall_game")] = { icon: "trashCan", block: proc { Store.application_manager.uninstall(game.id, channel.id) } }
+ # end
+ hash[I18n.t(:"games.install_folder")] = { icon: nil, block: proc { Store.application_manager.show_folder(game.id, channel.id, :installation) } }
+ hash[I18n.t(:"games.user_data_folder")] = { icon: nil, block: proc { Store.application_manager.show_folder(game.id, channel.id, :user_data) } }
+ hash[I18n.t(:"games.view_screenshots")] = { icon: nil, block: proc { Store.application_manager.show_folder(game.id, channel.id, :screenshots) } }
+ }.each do |key, hash|
+ flow(width: 1.0, height: 22, margin_bottom: 8) do
+ image "#{GAME_ROOT_PATH}/media/ui_icons/#{hash[:icon]}.png", width: 24 if hash[:icon]
+ image EMPTY_IMAGE, width: 24 unless hash[:icon]
+ link key, text_size: 18, enabled: hash.key?(:enabled) ? hash[:enabled] : true do
+ hash[:block]&.call
+ end
+ end
end
- hash[I18n.t(:"games.install_folder")] = { icon: nil, block: proc { Store.application_manager.show_folder(game.id, channel.id, :installation) } }
- hash[I18n.t(:"games.user_data_folder")] = { icon: nil, block: proc { Store.application_manager.show_folder(game.id, channel.id, :user_data) } }
- hash[I18n.t(:"games.view_screenshots")] = { icon: nil, block: proc { Store.application_manager.show_folder(game.id, channel.id, :screenshots) } }
- }.each do |key, hash|
+ end
+
+ game.web_links.each do |item|
flow(width: 1.0, height: 22, margin_bottom: 8) do
- image "#{GAME_ROOT_PATH}/media/ui_icons/#{hash[:icon]}.png", width: 0.11 if hash[:icon]
- image EMPTY_IMAGE, width: 0.11 unless hash[:icon]
- link key, text_size: 18, enabled: hash.key?(:enabled) ? hash[:enabled] : true do
- hash[:block]&.call
+ image "#{GAME_ROOT_PATH}/media/ui_icons/share1.png", width: 24
+ link item.name, text_size: 18 do
+ W3DHub.url(item.uri)
end
end
end
end
- game.web_links.each do |item|
- flow(width: 1.0, height: 22, margin_bottom: 8) do
- image "#{GAME_ROOT_PATH}/media/ui_icons/share1.png", width: 0.11
- link item.name, text_size: 18 do
- W3DHub.url(item.uri)
+ if game.channels.count > 1
+ # Release channel
+
+ inscription I18n.t(:"games.game_version"), width: 1.0, text_align: :center
+
+ flow(width: 1.0, height: 48) do
+ # background 0xff_444411
+ list_box(width: 1.0, items: game.channels.map(&:name), choose: channel.name, enabled: game.channels.count > 1) do |value|
+ populate_game_page(game, game.channels.find { |c| c.name == value })
+ end
+ end
+ end
+
+ # Play buttons
+ flow(width: 1.0, height: 48, padding_top: 6, margin_bottom: 16) do
+ # background 0xff_551100
+
+ if Store.application_manager.installed?(game.id, channel.id)
+ if Store.application_manager.updateable?(game.id, channel.id)
+ button "#{I18n.t(:"interface.install_update")}", fill: true, text_size: 32, **UPDATE_BUTTON do
+ Store.application_manager.update(game.id, channel.id)
+ end
+ else
+ play_now_server = Store.application_manager.play_now_server(game.id, channel.id)
+ play_now_button = button "#{I18n.t(:"interface.play")}", fill: true, text_size: 32, enabled: !play_now_server.nil? do
+ Store.application_manager.play_now(game.id, channel.id)
+ end
+
+ play_now_button.subscribe(:enter) do |btn|
+ server = Store.application_manager.play_now_server(game.id, channel.id)
+ btn.enabled = !server.nil?
+ btn.instance_variable_set(:"@tip", server ? "#{server.status.name} [#{server.status.player_count}/#{server.status.max_players}]" : "")
+ end
+ end
+
+ button get_image("#{GAME_ROOT_PATH}/media/ui_icons/singleplayer.png"), tip: I18n.t(:"interface.single_player"), image_height: 32, margin_left: 0 do
+ Store.application_manager.run(game.id, channel.id)
+ end
+
+ button get_image("#{GAME_ROOT_PATH}/media/ui_icons/gear.png"), tip: I18n.t(:"games.game_options"), image_height: 32, margin_left: 0 do |btn|
+ items = []
+
+ items << { label: I18n.t(:"games.game_settings"), block: proc { push_state(States::GameSettingsDialog, app_id: game.id, channel: channel.id) } } #, block: proc { Store.application_manager.wwconfig(game.id, channel.id) } }
+ # items << { label: I18n.t(:"games.game_settings"), block: proc { Store.application_manager.settings(game.id, channel.id) } }
+ items << { label: I18n.t(:"games.wine_configuration"), block: proc { Store.application_manager.wine_configuration(game.id, channel.id) } } if W3DHub.unix?
+ items << { label: I18n.t(:"games.game_modifications"), block: proc { populate_game_modifications(game, channel) } } unless Store.offline_mode
+ if game.id != "ren"
+ items << { label: I18n.t(:"games.repair_installation"), block: proc { Store.application_manager.repair(game.id, channel.id) } } unless Store.offline_mode
+ items << { label: I18n.t(:"games.uninstall_game"), block: proc { Store.application_manager.uninstall(game.id, channel.id) } } unless Store.offline_mode
+ end
+
+ # From gui_state_ext.rb
+ # TODO: Implement in engine proper
+ menu(btn, items: items)
+ end
+
+ else
+ installing = Store.application_manager.task?(:installer, game.id, channel.id)
+
+ unless game.id == "ren"
+ button "#{I18n.t(:"interface.install")}", fill: true, margin_right: 8, text_size: 32, enabled: !installing do |button|
+ button.enabled = false
+ @import_button.enabled = false
+ Store.application_manager.install(game.id, channel.id)
+ end
+ end
+
+ @import_button = button "#{I18n.t(:"interface.import")}", fill: true, margin_left: 8, text_size: 32, enabled: !installing do
+ Store.application_manager.import(game.id, channel.id)
end
end
end
end
- # Game News
- @game_news_container = flow(fill: true, height: 1.0, padding: 8, scroll: true) do
- # background 0xff_005500
- end
- end
-
- # Play buttons
- flow(width: 1.0, height: 48, padding_top: 6) do
- # background 0xff_551100
-
- if Store.application_manager.installed?(game.id, channel.id)
- if Store.application_manager.updateable?(game.id, channel.id)
- button "#{I18n.t(:"interface.install_update")}", margin_left: 24, **UPDATE_BUTTON do
- Store.application_manager.update(game.id, channel.id)
- end
- else
- button "#{I18n.t(:"interface.play_now")}", margin_left: 24 do
- Store.application_manager.play_now(game.id, channel.id)
+ stack(fill: true, height: 1.0) do
+ # Game Description
+ if false # description
+ # Height should match Game Banner container height
+ stack(width: 1.0, padding: 16) do
+ title "About #{game.name}", border_bottom_color: 0xff_666666, border_bottom_thickness: 1, width: 1.0
+ para "Command & Conquer: Tiberian Sun is a 1999 real-time stretegy video game by Westwood Studios, published by Electronic Arts, releaseed exclusively for Microsoft Windows on August 27th, 1999. The game is the sequel to the 1995 game Command & Conquer. It featured new semi-3D graphics, a more futuristic sci-fi setting, and new gameplay features such as vehicles capable of hovering and burrowing.", width: 1.0, text_size: 20
end
end
- button "#{I18n.t(:"interface.single_player")}", margin_left: 24 do
- Store.application_manager.run(game.id, channel.id)
- end
- else
- installing = Store.application_manager.task?(:installer, game.id, channel.id)
-
- unless game.id == "ren"
- button "#{I18n.t(:"interface.install")}", margin_left: 24, enabled: !installing do |button|
- button.enabled = false
- @import_button.enabled = false
- Store.application_manager.install(game.id, channel.id)
- end
+ # Game Events
+ @game_events_container = flow(width: 1.0, height: 128, padding: 8, visible: false) do
end
- @import_button = button "#{I18n.t(:"interface.import")}", margin_left: 24, enabled: !installing do
- Store.application_manager.import(game.id, channel.id)
+ # Game News
+ @game_news_container = flow(width: 1.0, fill: true, padding: 8, scroll: true) do
+ # background 0xff_005500
end
end
end
end
- return if Cache.net_lock?("game_news_#{game.id}")
+ return if Store.offline_mode
- if @game_news[game.id]
- populate_game_news(game)
- else
- @game_news_container.clear do
- title I18n.t(:"games.fetching_news"), padding: 8
+ unless Cache.net_lock?("game_news_#{game.id}")
+ if @game_events[game.id]
+ populate_game_events(game)
+ else
+ BackgroundWorker.foreground_job(
+ -> { fetch_game_events(game) },
+ lambda do |result|
+ if result
+ populate_game_events(game)
+ Cache.release_net_lock(result)
+ end
+ end
+ )
end
+ end
- BackgroundWorker.foreground_job(
- -> { fetch_game_news(game) },
- lambda do |result|
- if result
- populate_game_news(game)
- Cache.release_net_lock(result)
+ unless Cache.net_lock?("game_events_#{game.id}")
+ if @game_news[game.id]
+ populate_game_news(game)
+ else
+ @game_news_container.clear do
+ title I18n.t(:"games.fetching_news"), padding: 8
+ end
+
+ BackgroundWorker.foreground_job(
+ -> { fetch_game_news(game) },
+ lambda do |result|
+ if result
+ populate_game_news(game)
+ Cache.release_net_lock(result)
+ end
+ end
+ )
+ end
+ end
+ end
+
+ def populate_all_games_view
+ @game_page_container.clear do
+ background 0x88_353535
+ @game_page_container.style.background_image_color = 0x88_353535
+ @game_page_container.style.default[:background_image_color] = 0x88_353535
+ @game_page_container.update_background_image
+
+ @focused_game = nil
+ @focused_channel = nil
+
+ populate_games_list
+
+ flow(width: 1.0, height: 1.0) do
+ games_view_container = nil
+ # Options
+ stack(width: 360, height: 1.0, padding: 8, scroll: true, border_thickness_right: 1, border_color_right: W3DHub::BORDER_COLOR) do
+ background 0x55_000000
+
+ flow(width: 1.0, height: 48) do
+ button "All Games", width: 280 do
+ # games_view_container.clear
+ end
+ tagline Store.applications.games.count.to_s, fill: true, text_align: :right
+ end
+
+ flow(width: 1.0, height: 48, margin_top: 8) do
+ button "Installed", enabled: false, width: 280
+ tagline "0", fill: true, text_align: :right
+ end
+
+ flow(width: 1.0, height: 48, margin_top: 8) do
+ button "Favorites", enabled: false, width: 280
+ tagline Store.settings[:favorites].count, fill: true, text_align: :right
end
end
- )
+
+ # Games list
+ games_view_container = stack(fill: true, height: 1.0, padding: 8, margin: 8) do
+ title "All Games"
+
+ flow(width: 1.0, fill: true, scroll: true) do
+ Store.applications.games.each do |game|
+ stack(width: 166, height: 224, margin: 8, background: 0x88_151515, border_color: game.color, border_thickness: 1) do
+ flow(width: 1.0, height: 24, padding: 8) do
+ para "Favorite", fill: true
+ toggle_button checked: Store.application_manager.favorite?(game.id), text_size: 18, padding_top: 3, padding_right: 3, padding_bottom: 3, padding_left: 3 do |btn|
+ Store.application_manager.favorive(game.id, btn.value)
+ Store.settings.save_settings
+
+ populate_games_list
+ end
+ end
+
+ container = stack(fill: true, width: 1.0, padding: 8) do
+ image_path = File.exist?("#{GAME_ROOT_PATH}/media/icons/#{game.id}.png") ? "#{GAME_ROOT_PATH}/media/icons/#{game.id}.png" : "#{GAME_ROOT_PATH}/media/icons/default_icon.png"
+ flow(width: 1.0, margin_top: 8) do
+ flow(fill: true)
+ image image_path, width: 0.5
+ flow(fill: true)
+ end
+
+ caption game.name, margin_top: 8
+ end
+
+ def container.hit_element?(x, y)
+ return unless hit?(x, y)
+
+ self
+ end
+
+ container.subscribe(:clicked_left_mouse_button) do |element|
+ populate_game_page(game, game.channels.first)
+ populate_games_list
+ end
+
+ container.subscribe(:enter) do |element|
+ element.background = 0x88_454545
+ end
+ end
+ end
+ end
+ end
+ end
end
end
@@ -208,32 +386,79 @@ class W3DHub
if (feed = @game_news[game.id])
@game_news_container.clear do
+ # Patch Notes
+ if false # Patch notes
+ flow(width: 1.0, max_width: 346 * 3 + (8 * 4), height: 346, margin: 8, margin_right: 32, border_thickness: 1, border_color: darken(Gosu::Color.new(game.color))) do
+ background darken(Gosu::Color.new(game.color), 10)
+
+ stack(width: 346, height: 1.0, padding: 8) do
+ background 0xff_181d22
+
+ para "Patch Notes"
+
+ tagline "Patch 2.0 is now out!"
+
+ para "words go here " * 20
+
+ flow(fill: true)
+
+ button "Read More", width: 1.0
+ end
+
+ flow(fill: true)
+
+ title "Eye Candy Banner Goes Here."
+ end
+ end
+
feed.items.sort_by { |i| i.timestamp }.reverse[0..9].each do |item|
- flow(width: 0.5, max_width: 312, height: 128, margin: 4) do
- # background 0x88_000000
+ image_path = Cache.path(item.image)
+ news_blurb_container = nil
+ news_title_container = nil
- path = Cache.path(item.image)
+ news_container = stack(width: 300, height: 300, margin: 8, background_image: image_path, border_thickness: 1, border_color: lighten(Gosu::Color.new(game.color))) do
+ background 0x88_000000
- if File.exist?(path)
- image path, width: 0.4, padding: 4
+ # Detailed view
+ news_blurb_container = stack(width: 1.0, height: 1.0, background: 0xaa_000000, padding: 4) do
+ tagline "#{item.title}", width: 1.0
+ inscription "#{item.author} • #{item.timestamp.strftime("%Y-%m-%d")}"
+ inscription item.blurb.gsub(/\n+/, "\n").strip[0..1024], fill: true
+
+ button I18n.t(:"games.read_more"), width: 1.0, margin_top: 8, margin_bottom: 0, padding_top: 4, padding_bottom: 4 do
+ W3DHub.url(item.uri)
+ end
+ end
+
+ # Just title
+ news_title_container = stack(width: 1.0, height: 1.0) do
+ flow(fill: true)
+
+ tagline "#{item.title}", width: 1.0, background: 0xaa_000000, padding: 4
+ end
+ end
+
+ news_blurb_container.hide
+
+ def news_container.hit_element?(x, y)
+ return unless hit?(x, y)
+
+ if @children.first.visible? && (btn = @children.first.children.find { |child| child.visible? && child.is_a?(CyberarmEngine::Element::Button) && child.hit?(x, y) })
+ btn
else
- image BLACK_IMAGE, width: 0.4, padding: 4
+ self
end
+ end
- stack(width: 0.6, height: 1.0) do
- stack(width: 1.0, height: 112) do
- link "#{item.title}", text_size: 18 do
- W3DHub.url(item.uri)
- end
- inscription item.blurb.gsub(/\n+/, "\n").strip[0..180]
- end
+ news_container.subscribe(:enter) do
+ news_title_container.hide
+ news_blurb_container.show
+ end
- flow(width: 1.0) do
- inscription item.timestamp.strftime("%Y-%m-%d"), width: 0.5
- link I18n.t(:"games.read_more"), width: 0.5, text_align: :right, text_size: 14 do
- W3DHub.url(item.uri)
- end
- end
+ news_container.subscribe(:leave) do
+ unless news_container.hit?(window.mouse_x, window.mouse_y)
+ news_title_container.show
+ news_blurb_container.hide
end
end
end
@@ -241,6 +466,41 @@ class W3DHub
end
end
+ def fetch_game_events(game)
+ lock = Cache.acquire_net_lock("game_events_#{game.id}")
+ return false unless lock
+
+ events = Api.events(game.id)
+ Cache.release_net_lock("game_events_#{game.id}") unless events
+
+ return false unless events
+
+ @game_events[game.id] = events
+
+ "game_events_#{game.id}"
+ end
+
+ def populate_game_events(game)
+ return unless @focused_game == game
+
+ if (events = @game_events[game.id])
+ @game_events_container.show unless events.empty?
+ @game_events_container.hide if events.empty?
+
+ @game_events_container.clear do
+ events.flatten.each do |event|
+ stack(width: 300, height: 1.0, margin_left: 8, margin_right: 8, border_thickness: 1, border_color: lighten(Gosu::Color.new(game.color))) do
+ background 0xaa_222222
+
+ title event.title, width: 1.0, text_align: :center
+ tagline event.start_time.strftime("%A"), text_size: 36, width: 1.0, text_align: :center
+ caption event.start_time.strftime("%B %e, %Y %l:%M %p"), width: 1.0, text_align: :center
+ end
+ end
+ end
+ end
+ end
+
def populate_game_modifications(application, channel)
@game_news_container.clear do
([
diff --git a/lib/pages/games_redesign.rb b/lib/pages/games_redesign.rb
deleted file mode 100644
index 287052d..0000000
--- a/lib/pages/games_redesign.rb
+++ /dev/null
@@ -1,545 +0,0 @@
-class W3DHub
- class Pages
- class Games < Page
- def setup
- @game_news ||= {}
- @game_events ||= {}
-
- @focused_game ||= Store.applications.games.find { |g| g.id == Store.settings[:last_selected_app] }
- @focused_game ||= Store.applications.games.find { |g| g.id == "ren" }
- @focused_channel ||= @focused_game.channels.find { |c| c.id == Store.settings[:last_selected_channel] }
- @focused_channel ||= @focused_game.channels.first
-
- body.clear do
- stack(width: 1.0, height: 1.0) do
- # Games List
- @games_list_container = flow(width: 1.0, height: 64, scroll: true, border_thickness_bottom: 1, border_color_bottom: W3DHub::BORDER_COLOR, padding_left: 32, padding_right: 32) do
- end
-
- # Game Menu
- @game_page_container = stack(width: 1.0, fill: true, background_image: "#{GAME_ROOT_PATH}/media/textures/noiseb.png", background_image_mode: :tiled) do
- # , background_image: "C:/Users/cyber/Downloads/vlcsnap-2022-04-24-22h24m15s854.png"
- end
- end
- end
-
- # return if Store.offline_mode
-
- populate_game_page(@focused_game, @focused_channel)
- populate_games_list
- end
-
- def populate_games_list
- @games_list_container.clear do
- background 0xff_121920
-
- stack(width: 128, height: 1.0) do
- flow(fill: true)
-
- button "All Games" do
- populate_all_games_view
- end
-
- flow(fill: true)
- end
-
- has_favorites = Store.settings[:favorites].size.positive?
-
- Store.applications.games.each do |game|
- next if has_favorites && !Store.application_manager.favorite?(game.id)
-
- selected = game == @focused_game
-
- game_button = stack(width: 64, height: 1.0, border_thickness_bottom: 4,
- border_color_bottom: selected ? 0xff_00acff : 0x00_000000,
- hover: { background: selected ? game.color : 0xff_444444 },
- padding_left: 4, padding_right: 4, tip: game.name) do
- background game.color if selected
-
- image_path = File.exist?("#{GAME_ROOT_PATH}/media/icons/#{game.id}.png") ? "#{GAME_ROOT_PATH}/media/icons/#{game.id}.png" : "#{GAME_ROOT_PATH}/media/icons/default_icon.png"
- image_color = Store.application_manager.installed?(game.id, game.channels.first.id) ? 0xff_ffffff : 0x66_ffffff
-
- flow(width: 1.0, height: 1.0, margin: 8, background_image: image_path, background_image_color: image_color, background_image_mode: :fill_height) do
- image "#{GAME_ROOT_PATH}/media/ui_icons/import.png", width: 24, margin_left: -4, margin_top: -6, color: 0xff_ff8800 if Store.application_manager.updateable?(game.id, game.channels.first.id)
- end
-
- # inscription game.name, width: 1.0, text_align: :center, text_size: 14
- end
-
- def game_button.hit_element?(x, y)
- self if hit?(x, y)
- end
-
- game_button.subscribe(:clicked_left_mouse_button) do
- populate_game_page(game, game.channels.first)
- populate_games_list
- end
- end
- end
- end
-
- def populate_game_page(game, channel)
- @focused_game = game
- @focused_channel = channel
-
- Store.settings[:last_selected_app] = game.id
- Store.settings[:last_selected_channel] = channel.id
-
- @game_page_container.clear do
- background game.color
- @game_page_container.style.background_image_color = game.color
- @game_page_container.style.default[:background_image_color] = game.color
- @game_page_container.update_background_image
-
- # Game Stuff
- flow(width: 1.0, fill: true) do
- # background 0xff_9999ff
-
- # Game options
- stack(width: 360, height: 1.0, padding: 8, scroll: true, border_thickness_right: 1, border_color_right: W3DHub::BORDER_COLOR) do
- background 0x55_000000
-
- # Game Banner
- image_path = "#{GAME_ROOT_PATH}/media/banners/#{game.id}.png"
-
- if File.exist?(image_path)
- image image_path, width: 1.0
- else
- banner game.name unless File.exist?(image_path)
- end
-
- stack(width: 1.0, fill: true, scroll: true, margin_top: 32) do
- if Store.application_manager.installed?(game.id, channel.id)
- Hash.new.tap { |hash|
- # hash[I18n.t(:"games.game_settings")] = { icon: "gear", block: proc { Store.application_manager.settings(game.id, channel.id) } }
- # hash[I18n.t(:"games.wine_configuration")] = { icon: "gear", block: proc { Store.application_manager.wine_configuration(game.id, channel.id) } } if W3DHub.unix?
- # hash[I18n.t(:"games.game_modifications")] = { icon: "gear", enabled: true, block: proc { populate_game_modifications(game, channel) } }
- # if game.id != "ren"
- # hash[I18n.t(:"games.repair_installation")] = { icon: "wrench", block: proc { Store.application_manager.repair(game.id, channel.id) } }
- # hash[I18n.t(:"games.uninstall_game")] = { icon: "trashCan", block: proc { Store.application_manager.uninstall(game.id, channel.id) } }
- # end
- hash[I18n.t(:"games.install_folder")] = { icon: nil, block: proc { Store.application_manager.show_folder(game.id, channel.id, :installation) } }
- hash[I18n.t(:"games.user_data_folder")] = { icon: nil, block: proc { Store.application_manager.show_folder(game.id, channel.id, :user_data) } }
- hash[I18n.t(:"games.view_screenshots")] = { icon: nil, block: proc { Store.application_manager.show_folder(game.id, channel.id, :screenshots) } }
- }.each do |key, hash|
- flow(width: 1.0, height: 22, margin_bottom: 8) do
- image "#{GAME_ROOT_PATH}/media/ui_icons/#{hash[:icon]}.png", width: 24 if hash[:icon]
- image EMPTY_IMAGE, width: 24 unless hash[:icon]
- link key, text_size: 18, enabled: hash.key?(:enabled) ? hash[:enabled] : true do
- hash[:block]&.call
- end
- end
- end
- end
-
- game.web_links.each do |item|
- flow(width: 1.0, height: 22, margin_bottom: 8) do
- image "#{GAME_ROOT_PATH}/media/ui_icons/share1.png", width: 24
- link item.name, text_size: 18 do
- W3DHub.url(item.uri)
- end
- end
- end
- end
-
- if game.channels.count > 1
- # Release channel
-
- inscription I18n.t(:"games.game_version"), width: 1.0, text_align: :center
-
- flow(width: 1.0, height: 48) do
- # background 0xff_444411
- list_box(width: 1.0, items: game.channels.map(&:name), choose: channel.name, enabled: game.channels.count > 1) do |value|
- populate_game_page(game, game.channels.find { |c| c.name == value })
- end
- end
- end
-
- # Play buttons
- flow(width: 1.0, height: 48, padding_top: 6, margin_bottom: 16) do
- # background 0xff_551100
-
- if Store.application_manager.installed?(game.id, channel.id)
- if Store.application_manager.updateable?(game.id, channel.id)
- button "#{I18n.t(:"interface.install_update")}", fill: true, text_size: 32, **UPDATE_BUTTON do
- Store.application_manager.update(game.id, channel.id)
- end
- else
- play_now_server = Store.application_manager.play_now_server(game.id, channel.id)
- play_now_button = button "#{I18n.t(:"interface.play")}", fill: true, text_size: 32, enabled: !play_now_server.nil? do
- Store.application_manager.play_now(game.id, channel.id)
- end
-
- play_now_button.subscribe(:enter) do |btn|
- server = Store.application_manager.play_now_server(game.id, channel.id)
- btn.enabled = !server.nil?
- btn.instance_variable_set(:"@tip", server ? "#{server.status.name} [#{server.status.player_count}/#{server.status.max_players}]" : "")
- end
- end
-
- button get_image("#{GAME_ROOT_PATH}/media/ui_icons/singleplayer.png"), tip: I18n.t(:"interface.single_player"), image_height: 32, margin_left: 0 do
- Store.application_manager.run(game.id, channel.id)
- end
-
- button get_image("#{GAME_ROOT_PATH}/media/ui_icons/gear.png"), tip: I18n.t(:"games.game_options"), image_height: 32, margin_left: 0 do |btn|
- items = []
-
- items << { label: I18n.t(:"games.game_settings"), block: proc { push_state(States::GameSettingsDialog, app_id: game.id, channel: channel.id) } } #, block: proc { Store.application_manager.wwconfig(game.id, channel.id) } }
- # items << { label: I18n.t(:"games.game_settings"), block: proc { Store.application_manager.settings(game.id, channel.id) } }
- items << { label: I18n.t(:"games.wine_configuration"), block: proc { Store.application_manager.wine_configuration(game.id, channel.id) } } if W3DHub.unix?
- items << { label: I18n.t(:"games.game_modifications"), block: proc { populate_game_modifications(game, channel) } } unless Store.offline_mode
- if game.id != "ren"
- items << { label: I18n.t(:"games.repair_installation"), block: proc { Store.application_manager.repair(game.id, channel.id) } } unless Store.offline_mode
- items << { label: I18n.t(:"games.uninstall_game"), block: proc { Store.application_manager.uninstall(game.id, channel.id) } } unless Store.offline_mode
- end
-
- # From gui_state_ext.rb
- # TODO: Implement in engine proper
- menu(btn, items: items)
- end
-
- else
- installing = Store.application_manager.task?(:installer, game.id, channel.id)
-
- unless game.id == "ren"
- button "#{I18n.t(:"interface.install")}", fill: true, margin_right: 8, text_size: 32, enabled: !installing do |button|
- button.enabled = false
- @import_button.enabled = false
- Store.application_manager.install(game.id, channel.id)
- end
- end
-
- @import_button = button "#{I18n.t(:"interface.import")}", fill: true, margin_left: 8, text_size: 32, enabled: !installing do
- Store.application_manager.import(game.id, channel.id)
- end
- end
- end
- end
-
- stack(fill: true, height: 1.0) do
- # Game Description
- if false # description
- # Height should match Game Banner container height
- stack(width: 1.0, padding: 16) do
- title "About #{game.name}", border_bottom_color: 0xff_666666, border_bottom_thickness: 1, width: 1.0
- para "Command & Conquer: Tiberian Sun is a 1999 real-time stretegy video game by Westwood Studios, published by Electronic Arts, releaseed exclusively for Microsoft Windows on August 27th, 1999. The game is the sequel to the 1995 game Command & Conquer. It featured new semi-3D graphics, a more futuristic sci-fi setting, and new gameplay features such as vehicles capable of hovering and burrowing.", width: 1.0, text_size: 20
- end
- end
-
- # Game Events
- @game_events_container = flow(width: 1.0, height: 128, padding: 8, visible: false) do
- end
-
- # Game News
- @game_news_container = flow(width: 1.0, fill: true, padding: 8, scroll: true) do
- # background 0xff_005500
- end
- end
- end
- end
-
- return if Store.offline_mode
-
- unless Cache.net_lock?("game_news_#{game.id}")
- if @game_events[game.id]
- populate_game_events(game)
- else
- BackgroundWorker.foreground_job(
- -> { fetch_game_events(game) },
- lambda do |result|
- if result
- populate_game_events(game)
- Cache.release_net_lock(result)
- end
- end
- )
- end
- end
-
- unless Cache.net_lock?("game_events_#{game.id}")
- if @game_news[game.id]
- populate_game_news(game)
- else
- @game_news_container.clear do
- title I18n.t(:"games.fetching_news"), padding: 8
- end
-
- BackgroundWorker.foreground_job(
- -> { fetch_game_news(game) },
- lambda do |result|
- if result
- populate_game_news(game)
- Cache.release_net_lock(result)
- end
- end
- )
- end
- end
- end
-
- def populate_all_games_view
- @game_page_container.clear do
- background 0x88_353535
- @game_page_container.style.background_image_color = 0x88_353535
- @game_page_container.style.default[:background_image_color] = 0x88_353535
- @game_page_container.update_background_image
-
- @focused_game = nil
- @focused_channel = nil
-
- populate_games_list
-
- flow(width: 1.0, height: 1.0) do
- games_view_container = nil
- # Options
- stack(width: 360, height: 1.0, padding: 8, scroll: true, border_thickness_right: 1, border_color_right: W3DHub::BORDER_COLOR) do
- background 0x55_000000
-
- flow(width: 1.0, height: 48) do
- button "All Games", width: 280 do
- # games_view_container.clear
- end
- tagline Store.applications.games.count.to_s, fill: true, text_align: :right
- end
-
- flow(width: 1.0, height: 48, margin_top: 8) do
- button "Installed", enabled: false, width: 280
- tagline "0", fill: true, text_align: :right
- end
-
- flow(width: 1.0, height: 48, margin_top: 8) do
- button "Favorites", enabled: false, width: 280
- tagline Store.settings[:favorites].count, fill: true, text_align: :right
- end
- end
-
- # Games list
- games_view_container = stack(fill: true, height: 1.0, padding: 8, margin: 8) do
- title "All Games"
-
- flow(width: 1.0, fill: true, scroll: true) do
- Store.applications.games.each do |game|
- stack(width: 166, height: 224, margin: 8, background: 0x88_151515, border_color: game.color, border_thickness: 1) do
- flow(width: 1.0, height: 24, padding: 8) do
- para "Favorite", fill: true
- toggle_button checked: Store.application_manager.favorite?(game.id), text_size: 18, padding_top: 3, padding_right: 3, padding_bottom: 3, padding_left: 3 do |btn|
- Store.application_manager.favorive(game.id, btn.value)
- Store.settings.save_settings
-
- populate_games_list
- end
- end
-
- container = stack(fill: true, width: 1.0, padding: 8) do
- image_path = File.exist?("#{GAME_ROOT_PATH}/media/icons/#{game.id}.png") ? "#{GAME_ROOT_PATH}/media/icons/#{game.id}.png" : "#{GAME_ROOT_PATH}/media/icons/default_icon.png"
- flow(width: 1.0, margin_top: 8) do
- flow(fill: true)
- image image_path, width: 0.5
- flow(fill: true)
- end
-
- caption game.name, margin_top: 8
- end
-
- def container.hit_element?(x, y)
- return unless hit?(x, y)
-
- self
- end
-
- container.subscribe(:clicked_left_mouse_button) do |element|
- populate_game_page(game, game.channels.first)
- populate_games_list
- end
-
- container.subscribe(:enter) do |element|
- element.background = 0x88_454545
- end
- end
- end
- end
- end
- end
- end
- end
-
- def fetch_game_news(game)
- lock = Cache.acquire_net_lock("game_news_#{game.id}")
- return false unless lock
-
- news = Api.news(game.id)
- Cache.release_net_lock("game_news_#{game.id}") unless news
-
- return false unless news
-
- news.items[0..15].each do |item|
- Cache.fetch(uri: item.image, async: false)
- end
-
- @game_news[game.id] = news
-
- "game_news_#{game.id}"
- end
-
- def populate_game_news(game)
- return unless @focused_game == game
-
- if (feed = @game_news[game.id])
- @game_news_container.clear do
- # Patch Notes
- if false # Patch notes
- flow(width: 1.0, max_width: 346 * 3 + (8 * 4), height: 346, margin: 8, margin_right: 32, border_thickness: 1, border_color: darken(Gosu::Color.new(game.color))) do
- background darken(Gosu::Color.new(game.color), 10)
-
- stack(width: 346, height: 1.0, padding: 8) do
- background 0xff_181d22
-
- para "Patch Notes"
-
- tagline "Patch 2.0 is now out!"
-
- para "words go here " * 20
-
- flow(fill: true)
-
- button "Read More", width: 1.0
- end
-
- flow(fill: true)
-
- title "Eye Candy Banner Goes Here."
- end
- end
-
- feed.items.sort_by { |i| i.timestamp }.reverse[0..9].each do |item|
- image_path = Cache.path(item.image)
- news_blurb_container = nil
- news_title_container = nil
-
- news_container = stack(width: 300, height: 300, margin: 8, background_image: image_path, border_thickness: 1, border_color: lighten(Gosu::Color.new(game.color))) do
- background 0x88_000000
-
- # Detailed view
- news_blurb_container = stack(width: 1.0, height: 1.0, background: 0xaa_000000, padding: 4) do
- tagline "#{item.title}", width: 1.0
- inscription "#{item.author} • #{item.timestamp.strftime("%Y-%m-%d")}"
- inscription item.blurb.gsub(/\n+/, "\n").strip[0..1024], fill: true
-
- button I18n.t(:"games.read_more"), width: 1.0, margin_top: 8, margin_bottom: 0, padding_top: 4, padding_bottom: 4 do
- W3DHub.url(item.uri)
- end
- end
-
- # Just title
- news_title_container = stack(width: 1.0, height: 1.0) do
- flow(fill: true)
-
- tagline "#{item.title}", width: 1.0, background: 0xaa_000000, padding: 4
- end
- end
-
- news_blurb_container.hide
-
- def news_container.hit_element?(x, y)
- return unless hit?(x, y)
-
- if @children.first.visible? && (btn = @children.first.children.find { |child| child.visible? && child.is_a?(CyberarmEngine::Element::Button) && child.hit?(x, y) })
- btn
- else
- self
- end
- end
-
- news_container.subscribe(:enter) do
- news_title_container.hide
- news_blurb_container.show
- end
-
- news_container.subscribe(:leave) do
- unless news_container.hit?(window.mouse_x, window.mouse_y)
- news_title_container.show
- news_blurb_container.hide
- end
- end
- end
- end
- end
- end
-
- def fetch_game_events(game)
- lock = Cache.acquire_net_lock("game_events_#{game.id}")
- return false unless lock
-
- events = Api.events(game.id)
- Cache.release_net_lock("game_events_#{game.id}") unless events
-
- return false unless events
-
- @game_events[game.id] = events
-
- "game_events_#{game.id}"
- end
-
- def populate_game_events(game)
- return unless @focused_game == game
-
- if (events = @game_events[game.id])
- @game_events_container.show unless events.empty?
- @game_events_container.hide if events.empty?
-
- @game_events_container.clear do
- events.flatten.each do |event|
- stack(width: 300, height: 1.0, margin_left: 8, margin_right: 8, border_thickness: 1, border_color: lighten(Gosu::Color.new(game.color))) do
- background 0xaa_222222
-
- title event.title, width: 1.0, text_align: :center
- tagline event.start_time.strftime("%A"), text_size: 36, width: 1.0, text_align: :center
- caption event.start_time.strftime("%B %e, %Y %l:%M %p"), width: 1.0, text_align: :center
- end
- end
- end
- end
- end
-
- def populate_game_modifications(application, channel)
- @game_news_container.clear do
- ([
- {
- id: "4E4CB0548029FF234E289B4B8B3E357A",
- name: "HD Purchase Terminal Icons",
- author: "username",
- description: "Replaces them blurry low res icons with juicy hi-res ones.",
- icon: nil,
- type: "Textures",
- subtype: "Purchase Terminal",
- multiplayer_approved: true,
- games: ["ren", "ia"],
- versions: ["0.0.1", "0.0.2", "0.1.0"],
- url: "https://w3dhub.com/mods/username/hd_purchase_terminal_icons"
- }
- ] * 10).flatten.each do |mod|
- flow(width: 1.0, height: 128, margin: 4, border_bottom_thickness: 1, border_bottom_color: 0xff_ffffff) do
- stack(width: 128, height: 128, padding: 4) do
- image BLACK_IMAGE, height: 1.0
- end
-
- stack(width: 0.75, height: 1.0) do
- stack(width: 1.0, height: 128 - 28) do
- link(mod[:name]) { W3DHub.url(mod[:url]) }
- inscription "Author: #{mod[:author]} | #{mod[:type]} | #{mod[:subtype]}"
- para mod[:description][0..180]
- end
-
- flow(width: 1.0, height: 28, padding: 4) do
- inscription "Version", width: 0.25, text_align: :center
- list_box items: mod[:versions], width: 0.5, enabled: mod[:versions].size > 1, padding_top: 0, padding_bottom: 0
- button "Install", width: 0.25, padding_top: 0, padding_bottom: 0
- end
- end
- end
- end
- end
- end
- end
- end
-end
\ No newline at end of file
diff --git a/lib/states/confirm_dialog.rb b/lib/states/dialogs/confirm_dialog.rb
similarity index 89%
rename from lib/states/confirm_dialog.rb
rename to lib/states/dialogs/confirm_dialog.rb
index 163874b..9a56e8e 100644
--- a/lib/states/confirm_dialog.rb
+++ b/lib/states/dialogs/confirm_dialog.rb
@@ -1,6 +1,6 @@
class W3DHub
class States
- class ConfirmDialog < CyberarmEngine::GuiState
+ class ConfirmDialog < Dialog
def setup
window.show_cursor = true
@@ -36,14 +36,6 @@ class W3DHub
end
end
end
-
- def draw
- previous_state&.draw
-
- Gosu.flush
-
- super
- end
end
end
end
diff --git a/lib/states/direct_connect_dialog.rb b/lib/states/dialogs/direct_connect_dialog.rb
similarity index 99%
rename from lib/states/direct_connect_dialog.rb
rename to lib/states/dialogs/direct_connect_dialog.rb
index dfa28d2..c2e950a 100644
--- a/lib/states/direct_connect_dialog.rb
+++ b/lib/states/dialogs/direct_connect_dialog.rb
@@ -1,6 +1,6 @@
class W3DHub
class States
- class DirectConnectDialog < CyberarmEngine::GuiState
+ class DirectConnectDialog < Dialog
def setup
window.show_cursor = true
W3DHub::Store[:asterisk_config] ||= Asterisk::Config.new
@@ -214,14 +214,6 @@ class W3DHub
end
end
- def draw
- previous_state&.draw
-
- Gosu.flush
-
- super
- end
-
def populate_from_server_profile(profile)
@server_nickname.value = profile.nickname
@server_password.value = Base64.strict_decode64(profile.password)
diff --git a/lib/states/message_dialog.rb b/lib/states/dialogs/message_dialog.rb
similarity index 86%
rename from lib/states/message_dialog.rb
rename to lib/states/dialogs/message_dialog.rb
index bbfad92..113c9d4 100644
--- a/lib/states/message_dialog.rb
+++ b/lib/states/dialogs/message_dialog.rb
@@ -1,6 +1,6 @@
class W3DHub
class States
- class MessageDialog < CyberarmEngine::GuiState
+ class MessageDialog < Dialog
def setup
window.show_cursor = true
@@ -28,14 +28,6 @@ class W3DHub
end
end
end
-
- def draw
- previous_state&.draw
-
- Gosu.flush
-
- super
- end
end
end
end
diff --git a/lib/states/prompt_dialog.rb b/lib/states/dialogs/prompt_dialog.rb
similarity index 94%
rename from lib/states/prompt_dialog.rb
rename to lib/states/dialogs/prompt_dialog.rb
index b7d866f..fd87d3f 100644
--- a/lib/states/prompt_dialog.rb
+++ b/lib/states/dialogs/prompt_dialog.rb
@@ -1,6 +1,6 @@
class W3DHub
class States
- class PromptDialog < CyberarmEngine::GuiState
+ class PromptDialog < Dialog
def setup
window.show_cursor = true
@@ -65,14 +65,6 @@ class W3DHub
end
end
end
-
- def draw
- previous_state&.draw
-
- Gosu.flush
-
- super
- end
end
end
end
diff --git a/lib/states/game_settings_dialog.rb b/lib/states/game_settings_dialog.rb
deleted file mode 100644
index 40243d9..0000000
--- a/lib/states/game_settings_dialog.rb
+++ /dev/null
@@ -1,163 +0,0 @@
-class W3DHub
- class States
- class GameSettingsDialog < CyberarmEngine::GuiState
- BUTTON_STYLE = { text_size: 18, padding_top: 3, padding_bottom: 3, padding_left: 3, padding_right: 3 }
- def setup
- window.show_cursor = true
-
- theme(W3DHub::THEME)
-
- background 0xee_444444
-
- stack(width: 1.0, max_width: 720, height: 1.0, max_height: 512, v_align: :center, h_align: :center, background: 0xee_222222) do
- flow(width: 1.0, height: 0.1, padding: 8) do
- background 0x88_000000
-
- image "#{GAME_ROOT_PATH}/media/icons/#{@options[:app_id]}.png", width: 0.04, align: :center
-
- tagline "#{@options[:title]}", width: 0.9, text_align: :center
- end
-
- stack(width: 1.0, fill: true, padding: 16) do
- flow(width: 1.0, fill: true) do
- stack(width: 0.5, height: 1.0) do
- caption "General"
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Default to First Person", fill: true
- toggle_button tip: "Default to First Person", **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Enable Chat Log", fill: true
- toggle_button tip: "Enable Chat Log", **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Background Downloads", fill: true
- toggle_button tip: "Background Downloads", **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Show FPS", fill: true
- toggle_button tip: "Show FPS", **BUTTON_STYLE
- end
- end
-
- stack(width: 0.5, height: 1.0) do
- caption "Video"
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Resolution", fill: true
- list_box items: ["#{Gosu.screen_width}x#{Gosu.screen_height}"], width: 128, **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Windowed Mode", fill: true
- list_box items: ["Windowed", "Borderless", "Fullscreen"], width: 128, **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Enable VSync", fill: true
- toggle_button tip: "Enable VSync", **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "MSAA Mode", fill: true
- list_box items: %w[0 2 4 8 16], width: 48, **BUTTON_STYLE
- end
- end
- end
-
- flow(width: 1.0, fill: true) do
- stack(width: 0.5, height: 1.0) do
- caption "Audio"
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Sound Effects", fill: true
- slider height: 1.0, width: 172, margin_right: 8
- toggle_button tip: "Sound Effects", checked: true, **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Dialogue", fill: true
- slider height: 1.0, width: 172, margin_right: 8
- toggle_button tip: "Dialogue", checked: true, **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Music", fill: true
- slider height: 1.0, width: 172, margin_right: 8
- toggle_button tip:"Music", checked: true, **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Cinematic", fill: true
- slider height: 1.0, width: 172, margin_right: 8
- toggle_button tip: "Cinematic", checked: true, **BUTTON_STYLE
- end
- end
-
- stack(width: 0.5, height: 1.0) do
- caption "Performance"
- flow(width: 1.0, height: 24, margin: 4) do
- para "Texture Detail", fill: true
- list_box items: ["Low", "Medium", "High"], width: 128, **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Shader Detail", fill: true
- list_box items: ["Low", "Medium", "High"], width: 128, **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Post Proccessing Detail", fill: true
- list_box items: ["Low", "Medium", "High"], width: 128, **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "Shadow Detail", fill: true
- list_box items: ["Low", "Medium", "High"], width: 128, **BUTTON_STYLE
- end
-
- flow(width: 1.0, height: 24, margin: 4) do
- para "High Quality Shadows", fill: true
- toggle_button tip: "High Quality Shadows", **BUTTON_STYLE
- end
- end
- end
- end
-
- flow(width: 1.0, height: 0.1, padding: 8) do
- button "Cancel", width: 0.25 do
- pop_state
- @options[:cancel_callback]&.call
- end
-
- flow(fill: true)
-
- button "WWConfig", width: 0.25 do
- pop_state
- Store.application_manager.wwconfig(@options[:app_id], @options[:channel])
- end
-
- flow(fill: true)
-
- button "Save", width: 0.25 do
- pop_state
- @options[:accept_callback]&.call
- end
- end
- end
- end
-
- def draw
- previous_state&.draw
-
- Gosu.flush
-
- super
- end
- end
- end
-end
diff --git a/lib/states/interface.rb b/lib/states/interface.rb
index f25028c..5e84bac 100644
--- a/lib/states/interface.rb
+++ b/lib/states/interface.rb
@@ -23,91 +23,84 @@ class W3DHub
@page = nil
@pages = {}
- Store.application_manager.auto_import
+ Store.application_manager.auto_import # unless Store.offline_mode
theme(W3DHub::THEME)
- @interface_container = flow(width: 1.0, height: 1.0) do
- # TODO: Override this background color to be a darkened version of the selected games
- # or a default color
- background 0xff_212121..0xff_111111
+ @interface_container = stack(width: 1.0, height: 1.0, border_thickness: 1, border_color: W3DHub::BORDER_COLOR) do
+ background 0xff_252525
- flow(fill: true, height: 1.0)
+ @header_container = flow(width: 1.0, height: 84, padding: 4, border_thickness_bottom: 1, border_color_bottom: W3DHub::BORDER_COLOR) do
+ flow(width: 148, height: 1.0) do
+ flow(fill: true)
+ image "#{GAME_ROOT_PATH}/media/icons/app.png", height: 84
+ flow(fill: true)
+ end
- stack(width: 1.0, max_width: MAX_PAGE_WIDTH, height: 1.0, border_thickness: 1, border_color: 0xff_aaaaaa) do
- background 0xff_252525
+ @navigation_container = stack(fill: true, height: 1.0) do
+ flow(width: 1.0, fill: true) do
+ # background 0xff_666666
- @header_container = flow(width: 1.0, height: 100, padding: 4) do
- image "#{GAME_ROOT_PATH}/media/icons/app.png", width: 108
-
- stack(fill: true, height: 1.0) do
- # background 0xff_885500
-
- @app_info_container = flow(width: 1.0, height: 0.65) do
- # background 0xff_8855ff
-
- stack(fill: true, height: 1.0) do
- title "#{I18n.t(:"app_name")}", height: 0.5
- flow(width: 1.0, height: 0.5) do
- @application_taskbar_container = stack(width: 1.0, height: 1.0, margin_left: 16, margin_right: 16) do
- flow(width: 1.0, height: 0.65) do
- @application_taskbar_label = inscription "", width: 0.60, text_wrap: :none
- @application_taskbar_status_label = inscription "", width: 0.40, text_align: :right, text_wrap: :none
- end
-
- @application_taskbar_progressbar = progress fraction: 0.0, height: 2, width: 1.0
- end
- end
- end
-
- @account_container = flow(width: 256, height: 1.0) do
- stack(width: 1.0, height: 1.0) do
- tagline "#{I18n.t(:"interface.not_logged_in")}", text_wrap: :none
-
- flow(width: 1.0) do
- link(I18n.t(:"interface.log_in"), text_size: 16, width: 0.5) { page(W3DHub::Pages::Login) }
- link I18n.t(:"interface.register"), text_size: 16, width: 0.49 do
- W3DHub.url("https://secure.w3dhub.com/forum/index.php?app=core&module=global§ion=register")
- end
- end
- end
- end
+ link I18n.t(:"interface.games").upcase, text_size: 34 do
+ page(W3DHub::Pages::Games)
end
- @navigation_container = flow(width: 1.0, height: 0.35) do
- # background 0xff_666666
- flow(width: 1.0, height: 1.0) do
- flow(fill: true, height: 1.0) # Hacky centering
- link I18n.t(:"interface.games") do
- page(W3DHub::Pages::Games)
- end
+ link I18n.t(:"interface.servers").upcase, text_size: 34, margin_left: 12 do
+ page(W3DHub::Pages::ServerBrowser)
+ end
- link I18n.t(:"interface.server_browser"), margin_left: 18 do
- page(W3DHub::Pages::ServerBrowser)
- end
+ link I18n.t(:"interface.community").upcase, text_size: 34, margin_left: 12 do
+ page(W3DHub::Pages::Community)
+ end
- link I18n.t(:"interface.community"), margin_left: 18 do
- page(W3DHub::Pages::Community)
- end
+ link I18n.t(:"interface.downloads").upcase, text_size: 34, margin_left: 12 do
+ page(W3DHub::Pages::DownloadManager)
+ end
- link I18n.t(:"interface.downloads"), margin_left: 18 do
- page(W3DHub::Pages::DownloadManager)
- end
+ link I18n.t(:"interface.settings").upcase, text_size: 34, margin_left: 12 do
+ page(W3DHub::Pages::Settings)
+ end
+ end
- link I18n.t(:"interface.settings"), margin_left: 18 do
- page(W3DHub::Pages::Settings)
- end
- flow(fill: true, height: 1.0) # Hacky centering
+ # Installer task display
+ flow(width: 1.0, height: 0.5) do
+ @application_taskbar_container = stack(width: 1.0, height: 1.0, margin_left: 16, margin_right: 16) do
+ flow(width: 1.0, height: 0.65) do
+ @application_taskbar_label = inscription "", width: 0.60, text_wrap: :none
+ @application_taskbar_status_label = inscription "", width: 0.40, text_align: :right, text_wrap: :none
end
+
+ @application_taskbar_progressbar = progress fraction: 0.0, height: 2, width: 1.0
end
end
end
- @content_container = flow(width: 1.0, fill: true) do
+ @account_container = flow(width: 256, height: 1.0) do
+ if Store.offline_mode
+ stack(width: 1.0, height: 1.0) do
+ flow(fill: true)
+
+ title "OFFLINE", text_wrap: :none, width: 1.0, text_align: :center
+
+ flow(fill: true)
+ end
+ else
+ stack(width: 1.0, height: 1.0) do
+ tagline "#{I18n.t(:"interface.not_logged_in")}", text_wrap: :none
+
+ flow(width: 1.0) do
+ link(I18n.t(:"interface.log_in"), text_size: 16, width: 0.5) { page(W3DHub::Pages::Login) }
+ link I18n.t(:"interface.register"), text_size: 16, width: 0.49 do
+ W3DHub.url("https://secure.w3dhub.com/forum/index.php?app=core&module=global§ion=register")
+ end
+ end
+ end
+ end
end
end
- flow(fill: true, height: 1.0)
+ @content_container = flow(width: 1.0, fill: true) do
+ end
end
if Store.account
@@ -172,6 +165,12 @@ class W3DHub
@page.refresh_server_list(server)
end
+ def update_server_ping(server)
+ return unless @page.is_a?(Pages::ServerBrowser)
+
+ @page.update_server_ping(server)
+ end
+
def show_application_taskbar
@application_taskbar_container.show
end
diff --git a/lib/states/interface_redesign.rb b/lib/states/interface_redesign.rb
deleted file mode 100644
index 5e84bac..0000000
--- a/lib/states/interface_redesign.rb
+++ /dev/null
@@ -1,223 +0,0 @@
-class W3DHub
- class States
- class Interface < CyberarmEngine::GuiState
- attr_accessor :interface_task_update_pending
-
- @@instance = nil
-
- def self.instance
- @@instance
- end
-
- def setup
- @@instance = self
-
- window.show_cursor = true
-
- @account = @options[:account]
- @service_status = @options[:service_status]
- @applications = @options[:applications]
-
- @interface_task_update_pending = nil
-
- @page = nil
- @pages = {}
-
- Store.application_manager.auto_import # unless Store.offline_mode
-
- theme(W3DHub::THEME)
-
- @interface_container = stack(width: 1.0, height: 1.0, border_thickness: 1, border_color: W3DHub::BORDER_COLOR) do
- background 0xff_252525
-
- @header_container = flow(width: 1.0, height: 84, padding: 4, border_thickness_bottom: 1, border_color_bottom: W3DHub::BORDER_COLOR) do
- flow(width: 148, height: 1.0) do
- flow(fill: true)
- image "#{GAME_ROOT_PATH}/media/icons/app.png", height: 84
- flow(fill: true)
- end
-
- @navigation_container = stack(fill: true, height: 1.0) do
- flow(width: 1.0, fill: true) do
- # background 0xff_666666
-
- link I18n.t(:"interface.games").upcase, text_size: 34 do
- page(W3DHub::Pages::Games)
- end
-
- link I18n.t(:"interface.servers").upcase, text_size: 34, margin_left: 12 do
- page(W3DHub::Pages::ServerBrowser)
- end
-
- link I18n.t(:"interface.community").upcase, text_size: 34, margin_left: 12 do
- page(W3DHub::Pages::Community)
- end
-
- link I18n.t(:"interface.downloads").upcase, text_size: 34, margin_left: 12 do
- page(W3DHub::Pages::DownloadManager)
- end
-
- link I18n.t(:"interface.settings").upcase, text_size: 34, margin_left: 12 do
- page(W3DHub::Pages::Settings)
- end
- end
-
- # Installer task display
- flow(width: 1.0, height: 0.5) do
- @application_taskbar_container = stack(width: 1.0, height: 1.0, margin_left: 16, margin_right: 16) do
- flow(width: 1.0, height: 0.65) do
- @application_taskbar_label = inscription "", width: 0.60, text_wrap: :none
- @application_taskbar_status_label = inscription "", width: 0.40, text_align: :right, text_wrap: :none
- end
-
- @application_taskbar_progressbar = progress fraction: 0.0, height: 2, width: 1.0
- end
- end
- end
-
- @account_container = flow(width: 256, height: 1.0) do
- if Store.offline_mode
- stack(width: 1.0, height: 1.0) do
- flow(fill: true)
-
- title "OFFLINE", text_wrap: :none, width: 1.0, text_align: :center
-
- flow(fill: true)
- end
- else
- stack(width: 1.0, height: 1.0) do
- tagline "#{I18n.t(:"interface.not_logged_in")}", text_wrap: :none
-
- flow(width: 1.0) do
- link(I18n.t(:"interface.log_in"), text_size: 16, width: 0.5) { page(W3DHub::Pages::Login) }
- link I18n.t(:"interface.register"), text_size: 16, width: 0.49 do
- W3DHub.url("https://secure.w3dhub.com/forum/index.php?app=core&module=global§ion=register")
- end
- end
- end
- end
- end
- end
-
- @content_container = flow(width: 1.0, fill: true) do
- end
- end
-
- if Store.account
- page(W3DHub::Pages::Login)
- else
- page(W3DHub::Pages::Games)
- end
-
- hide_application_taskbar
- end
-
- def draw
- super
-
- @page&.draw
- end
-
- def update
- super
-
- @page&.update
-
- update_interface_task_status(@interface_task_update_pending) if @interface_task_update_pending
- end
-
- def button_down(id)
- super
-
- @page&.button_down(id)
- end
-
- def button_up(id)
- super
-
- @page&.button_up(id)
- end
-
- def body
- @content_container
- end
-
- def page(klass, options = {})
- body.clear
-
- @page.blur if @page
-
- @pages[klass] = klass.new(host: self) unless @pages[klass]
- @page = @pages[klass]
-
- @page.options = options
- @page.setup
- @page.focus
- end
-
- def current_page
- @page
- end
-
- def update_server_browser(server)
- return unless @page.is_a?(Pages::ServerBrowser)
-
- @page.refresh_server_list(server)
- end
-
- def update_server_ping(server)
- return unless @page.is_a?(Pages::ServerBrowser)
-
- @page.update_server_ping(server)
- end
-
- def show_application_taskbar
- @application_taskbar_container.show
- end
-
- def hide_application_taskbar
- @application_taskbar_container.hide
- end
-
- def update_interface_task_status(task)
- @application_taskbar_label.value = task.status.label
- @application_taskbar_status_label.value = "#{task.status.value} (#{format("%.2f%%", task.status.progress.clamp(0.0, 1.0) * 100.0)})"
- @application_taskbar_progressbar.value = task.status.progress.clamp(0.0, 1.0)
-
- return unless @page.is_a?(Pages::DownloadManager)
-
- operation_info = @page.operation_info
- operation_step = @page.operation_info[:___step]
-
- if task.status.step != operation_step
- @page.regenerate(task)
-
- return
- end
-
- task.status.operations.each do |key, operation|
-
- name_ = operation_info["#{key}_name"]
- status_ = operation_info["#{key}_status"]
- progress_ = operation_info["#{key}_progress"]
-
- next if name_.value == operation.label &&
- status_.value == operation.value &&
- progress_.value == operation.value
-
- name_.value = operation.label if operation.label
- status_.value = operation.value if operation.value
-
- if operation.progress
- if operation.progress == Float::INFINITY
- progress_.type = :marquee unless progress_.type == :marquee
- else
- progress_.type = :linear unless progress_.type == :linear
- progress_.value = operation.progress.clamp(0.0, 1.0)
- end
- end
- end
- end
- end
- end
-end
diff --git a/w3d_hub_linux_launcher.rb b/w3d_hub_linux_launcher.rb
index 5db844e..c27f066 100644
--- a/w3d_hub_linux_launcher.rb
+++ b/w3d_hub_linux_launcher.rb
@@ -103,15 +103,13 @@ require_relative "lib/application_manager/tasks/repairer"
require_relative "lib/application_manager/tasks/importer"
require_relative "lib/states/demo_input_delay"
require_relative "lib/states/boot"
-# require_relative "lib/states/interface"
-require_relative "lib/states/interface_redesign"
+require_relative "lib/states/interface"
require_relative "lib/states/welcome"
require_relative "lib/states/dialog"
-require_relative "lib/states/message_dialog"
-require_relative "lib/states/prompt_dialog"
-require_relative "lib/states/confirm_dialog"
-require_relative "lib/states/direct_connect_dialog"
-# require_relative "lib/states/game_settings_dialog"
+require_relative "lib/states/dialogs/message_dialog"
+require_relative "lib/states/dialogs/prompt_dialog"
+require_relative "lib/states/dialogs/confirm_dialog"
+require_relative "lib/states/dialogs/direct_connect_dialog"
require_relative "lib/states/dialogs/game_settings_dialog"
require_relative "lib/api"
@@ -125,8 +123,7 @@ require_relative "lib/api/package"
require_relative "lib/api/event"
require_relative "lib/page"
-# require_relative "lib/pages/games"
-require_relative "lib/pages/games_redesign"
+require_relative "lib/pages/games"
require_relative "lib/pages/server_browser"
require_relative "lib/pages/community"
require_relative "lib/pages/login"