diff --git a/lib/pages/community.rb b/lib/pages/community.rb index c4876f5..423843b 100644 --- a/lib/pages/community.rb +++ b/lib/pages/community.rb @@ -6,17 +6,15 @@ class W3DHub body.clear do stack(width: 1.0, height: 1.0, padding: 8) do - stack(width: 1.0, height: 0.15) do + stack(width: 1.0) do tagline "Welcome to #{I18n.t(:app_name)}" para "The #{I18n.t(:app_name_simple)} is a one-stop shop for your W3D gaming needs, providing game downloads, automatic updating, an integrated server browser, and centralized management of in-game options." end - flow(width: 1.0, height: 0.15, margin_bottom: 24) do - icon_container_width = 0.37 - flow(width: (1.0 - icon_container_width) / 2, height: 1.0) do - end + flow(width: 1.0, height: 64, margin_bottom: 24) do + flow(fill: true, height: 1.0) - flow(width: icon_container_width, height: 1.0) do + flow(width: 64 * 4 + (3 * 32), height: 1.0) do image "#{GAME_ROOT_PATH}/media/icons/app.png", hover: { color: 0xaa_ffffff }, height: 1.0, tip: "#{I18n.t(:app_name)} Github Repository" do Launchy.open("https://github.com/cyberarm/w3d_hub_linux_launcher") end @@ -30,16 +28,18 @@ class W3DHub Launchy.open("https://www.facebook.com/w3dhub") end end + + flow(fill: true, height: 1.0) end - stack(width: 1.0, height: 0.55) do - tagline "Latest Updates", height: 0.1 + stack(width: 1.0, fill: true) do + tagline "Latest Updates" - @wd3hub_news_container = flow(width: 1.0, height: 0.9, padding: 8, scroll: true) do + @wd3hub_news_container = flow(width: 1.0, fill: true, padding: 8, scroll: true) do end end - stack(width: 1.0, height: 0.15, margin_top: 16) do + stack(width: 1.0, height: 72, margin_top: 16) do tagline "Help & Support" flow(width: 1.0) do para "For help and support using this launcher or playing any W3D Hub game visit the" @@ -83,7 +83,7 @@ class W3DHub return unless news - news.items[0..9].each do |item| + news.items[0..15].each do |item| Cache.fetch(uri: item.image, async: false) end @@ -98,7 +98,7 @@ class W3DHub if (feed = @w3dhub_news) @wd3hub_news_container.clear do feed.items.sort_by { |i| i.timestamp }.reverse[0..9].each do |item| - flow(width: 0.5, height: 128, margin: 4) do + flow(width: 0.5, max_width: 312, height: 128, margin: 4) do # background 0x88_000000 path = Cache.path(item.image) diff --git a/lib/pages/games.rb b/lib/pages/games.rb index df39047..80b5d57 100644 --- a/lib/pages/games.rb +++ b/lib/pages/games.rb @@ -194,7 +194,7 @@ class W3DHub return false unless news - news.items[0..9].each do |item| + news.items[0..15].each do |item| Cache.fetch(uri: item.image, async: false) end diff --git a/lib/pages/login.rb b/lib/pages/login.rb index c1bd7b5..51001b2 100644 --- a/lib/pages/login.rb +++ b/lib/pages/login.rb @@ -93,7 +93,6 @@ class W3DHub def populate_account_info @host.instance_variable_get(:"@account_container").clear do stack(width: 0.7, height: 1.0) do - # background 0xff_222222 tagline "#{Store.account.username}" flow(width: 1.0) do @@ -104,7 +103,8 @@ class W3DHub end end - stack(fill: true, height: 1.0) do + flow(fill: true, height: 1.0) do + flow(fill: true) # Fill empty space to push image over to container edge image Cache.path(Store.account.avatar_uri), height: 1.0 end end @@ -125,8 +125,7 @@ class W3DHub end @host.instance_variable_get(:"@account_container").clear do - stack(width: 0.7, height: 1.0) do - # background 0xff_222222 + stack(width: 1.0, height: 1.0) do tagline "#{I18n.t(:"interface.not_logged_in")}", text_wrap: :none flow(width: 1.0) do diff --git a/lib/pages/server_browser.rb b/lib/pages/server_browser.rb index 8d688ec..1b4b380 100644 --- a/lib/pages/server_browser.rb +++ b/lib/pages/server_browser.rb @@ -17,12 +17,23 @@ class W3DHub body.clear do stack(width: 1.0, height: 1.0, padding: 8) do - stack(width: 1.0, height: 0.04) do + stack(width: 1.0, height: 18) do inscription "#{I18n.t(:"server_browser.filters")}" end flow(width: 1.0, height: 32) do - flow(width: 0.75, height: 1.0) do + flow(width: 128, height: 1.0) do + # para I18n.t(:"server_browser.region"), width: 0.5 + list_box items: ["Any", "North America", "Europe"], choose: Store.settings[:server_list_region], width: 1.0, height: 1.0, padding_top: 4, padding_bottom: 4 do |value| + @filter_region = value + Store.settings[:server_list_region] = @filter_region + Store.settings.save_settings + + populate_server_list + end + end + + flow(fill: true, height: 1.0) do @filters.each do |app_id, enabled| app = Store.applications.games.find { |a| a.id == app_id.to_s } next unless app @@ -31,7 +42,7 @@ class W3DHub image image_path, tip: "#{app.name}", height: 1.0, border_thickness_bottom: 1, border_color_bottom: 0x00_000000, - color: enabled ? 0xff_ffffff : 0xff_444444, hover: { border_color_bottom: 0xff_aaaaaa }, margin_right: 16 do |img| + color: enabled ? 0xff_ffffff : 0xff_444444, hover: { border_color_bottom: 0xff_aaaaaa }, margin_left: 16 do |img| @filters[app_id] = !@filters[app_id] Store.settings[:server_list_filters] = @filters Store.settings.save_settings @@ -48,21 +59,12 @@ class W3DHub end end - para I18n.t(:"server_browser.region") - list_box items: ["Any", "North America", "Europe"], choose: Store.settings[:server_list_region], width: 0.2, max_width: 64, height: 1.0 do |value| - @filter_region = value - Store.settings[:server_list_region] = @filter_region - Store.settings.save_settings - - populate_server_list - end - # button get_image("#{GAME_ROOT_PATH}/media/ui_icons/return.png"), tip: I18n.t(:"server_browser.refresh"), image_height: 1.0, margin_left: 16, padding_left: 2, padding_right: 2, padding_top: 2, padding_bottom: 2 do # fetch_server_list # end end - flow(width: 0.249, height: 1.0) do + flow(min_width: 372, width: 0.38, max_width: 512, height: 1.0) do inscription "#{I18n.t(:"server_browser.nickname")}:", width: 0.32 @nickname_label = inscription "#{Store.settings[:server_list_username]}", width: 0.6 image "#{GAME_ROOT_PATH}/media/ui_icons/wrench.png", height: 16, hover: { color: 0xaa_ffffff }, tip: I18n.t(:"server_browser.set_nickname") do @@ -78,14 +80,14 @@ class W3DHub end end - flow(width: 1.0, height: 0.9, margin_top: 16) do - stack(width: 0.62, height: 1.0) do + flow(width: 1.0, fill: true, margin_top: 16) do + stack(fill: true, height: 1.0) do # Icon # Hostname # Current Map # Players # Ping - flow(width: 1.0, height: 0.05) do + flow(width: 1.0, height: 24) do stack(width: 48, padding: 4) do end @@ -106,12 +108,12 @@ class W3DHub end end - @server_list_container = stack(width: 1.0, height: 0.95, scroll: true) do + @server_list_container = stack(width: 1.0, fill: true, scroll: true) do para I18n.t(:"server_browser.fetching_server_list") end end - @game_server_info_container = stack(width: 0.38, height: 1.0) do + @game_server_info_container = stack(min_width: 372, width: 0.38, max_width: 512, height: 1.0) do para I18n.t(:"server_browser.no_server_selected"), width: 1.0, text_align: :center end end @@ -244,13 +246,13 @@ class W3DHub def populate_server_info(server) @game_server_info_container.clear do stack(width: 1.0, height: 1.0, padding: 8) do - stack(width: 1.0, height: 0.3) do + stack(width: 1.0, height: 220) do flow(width: 1.0, height: 0.2) do image game_icon(server), width: 0.05 tagline server.status.name, width: 0.949, text_wrap: :none end - stack(width: 1.0, height: 0.25) do + stack(width: 1.0, height: 0.2) do game_installed = Store.application_manager.installed?(server.game, server.channel) game_updatable = Store.application_manager.updateable?(server.game, server.channel) style = server.channel != "release" ? TESTING_BUTTON : {} @@ -294,30 +296,42 @@ class W3DHub end end - stack(width: 1.0, height: 0.55, margin_top: 16) do - flow(width: 1.0, height: 0.33) do + # Server Info + stack(width: 1.0, fill: true, margin_top: 16) do + flow(width: 1.0) do inscription "#{I18n.t(:"server_browser.game")}", width: 0.28, text_wrap: :none inscription "#{game_name(server.game)} (#{server.channel})", width: 0.71, text_wrap: :none end - flow(width: 1.0, height: 0.33) do + flow(width: 1.0) do inscription "#{I18n.t(:"server_browser.map")}", width: 0.28, text_wrap: :none inscription server.status.map, width: 0.71, text_wrap: :none end - flow(width: 1.0, height: 0.33) do + flow(width: 1.0) do inscription "#{I18n.t(:"server_browser.max_players")}", width: 0.28, text_wrap: :none inscription "#{server.status.max_players}", width: 0.71, text_wrap: :none end + + flow(width: 1.0) do + inscription "#{I18n.t(:"server_browser.time")}", width: 0.28, text_wrap: :none + inscription formatted_rentime(server.status.started), width: 0.71, text_wrap: :none + end + + flow(width: 1.0) do + inscription "#{I18n.t(:"server_browser.remaining")}", width: 0.28, text_wrap: :none + inscription "#{server.status.remaining}", width: 0.71, text_wrap: :none + end end end game_balance = server_game_balance(server) - flow(width: 1.0, height: 0.1, border_thickness_bottom: 2, border_color_bottom: 0x44_ffffff) do + # Game score and balance display + flow(width: 1.0, height: 48, border_thickness_bottom: 2, border_color_bottom: 0x44_ffffff) do stack(width: 0.4, height: 1.0) do para "#{server.status.teams[0].name} (#{server.status.players.select { |pl| pl.team == 0 }.count})", width: 1.0, text_align: :center - para game_balance[:team_0_score].to_i.to_s, width: 1.0, text_align: :center + para formatted_score(game_balance[:team_0_score].to_i), width: 1.0, text_align: :center end stack(width: 0.2, height: 1.0) do @@ -327,34 +341,39 @@ class W3DHub stack(width: 0.4, height: 1.0) do para "#{server.status.teams[1].name} (#{server.status.players.select { |pl| pl.team == 1 }.count})", width: 1.0, text_align: :center - para game_balance[:team_1_score].to_i.to_s, width: 1.0, text_align: :center + para formatted_score(game_balance[:team_1_score].to_i), width: 1.0, text_align: :center end end - flow(width: 1.0, height: 0.60, scroll: true) do + # Team roster + flow(width: 1.0, fill: true, scroll: true) do stack(width: 0.5) do - server.status.players.select { |ply| ply.team == 0 }.sort_by { |ply| ply.score }.reverse.each do |player| + server.status.players.select { |ply| ply.team == 0 }.sort_by { |ply| ply.score }.reverse.each_with_index do |player, i| flow(width: 1.0, height: 18) do + background 0xff_333333 if i.even? + stack(width: 0.6, height: 1.0) do inscription player.nick, text_size: 14, text_wrap: :none end stack(width: 0.4, height: 1.0) do - inscription "#{player.score}", text_size: 14, width: 1.0, text_align: :right, text_wrap: :none + inscription formatted_score(player.score), text_size: 14, width: 1.0, text_align: :right, text_wrap: :none end end end end stack(width: 0.5, border_thickness_left: 2, border_color_left: 0xff_000000) do - server.status.players.select { |ply| ply.team == 1 }.sort_by { |ply| ply.score }.reverse.each do |player| + server.status.players.select { |ply| ply.team == 1 }.sort_by { |ply| ply.score }.reverse.each_with_index do |player, i| flow(width: 1.0, height: 18) do + background 0xff_333333 if i.even? + stack(width: 0.6, height: 1.0) do inscription player.nick, text_size: 14, text_wrap: :none end stack(width: 0.4, height: 1.0) do - inscription "#{player.score}", text_size: 14, width: 1.0, text_align: :right, text_wrap: :none + inscription formatted_score(player.score), text_size: 14, width: 1.0, text_align: :right, text_wrap: :none end end end @@ -485,6 +504,20 @@ class W3DHub window.push_state(W3DHub::States::MessageDialog, type: "?", title: "?", message: "?") end end + + def formatted_score(int) + int.to_s.reverse.scan(/.{1,3}/).join(",").reverse + end + + def formatted_rentime(time) + range = Time.now - Time.parse(time) + + hours = range / 60.0 / 60.0 / 24.0 + minutes = (range / 60.0) % 59 + seconds = range % 59 + + format("%02d:%02d:%02d", hours, minutes, seconds) + end end end end diff --git a/lib/states/interface.rb b/lib/states/interface.rb index 83ea22f..c9ac5de 100644 --- a/lib/states/interface.rb +++ b/lib/states/interface.rb @@ -27,78 +27,87 @@ class W3DHub theme(W3DHub::THEME) - stack(width: 1.0, height: 1.0, border_thickness: 1, border_color: 0xff_aaaaaa) do - background 0xff_252525 + @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 - @header_container = flow(width: 1.0, height: 100, padding: 4) do - image "#{GAME_ROOT_PATH}/media/icons/app.png", width: 108 + flow(fill: true, height: 1.0) - stack(fill: true, height: 1.0) do - # background 0xff_885500 + stack(width: 1.0, max_width: MAX_PAGE_WIDTH, height: 1.0, border_thickness: 1, border_color: 0xff_aaaaaa) do + background 0xff_252525 - @app_info_container = flow(width: 1.0, height: 0.65) do - # background 0xff_8855ff + @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 - 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 + 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 - - @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: 0.7, height: 1.0) do - background 0xff_222222 - tagline "#{I18n.t(:"interface.not_logged_in")}", text_wrap: :none + @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 - Launchy.open("https://secure.w3dhub.com/forum/index.php?app=core&module=global§ion=register") + 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 + Launchy.open("https://secure.w3dhub.com/forum/index.php?app=core&module=global§ion=register") + end end end end end - 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 + @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.server_browser"), margin_left: 18 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"), margin_left: 18 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"), margin_left: 18 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"), margin_left: 18 do - page(W3DHub::Pages::Settings) + link I18n.t(:"interface.settings"), margin_left: 18 do + page(W3DHub::Pages::Settings) + end + flow(fill: true, height: 1.0) # Hacky centering end - flow(fill: true, height: 1.0) # Hacky centering end end end + + @content_container = flow(width: 1.0, fill: true) do + end end - @content_container = flow(width: 1.0, fill: true) do - end + flow(fill: true, height: 1.0) end if Store.account diff --git a/lib/theme.rb b/lib/theme.rb index 4d10018..8758f61 100644 --- a/lib/theme.rb +++ b/lib/theme.rb @@ -2,6 +2,8 @@ class W3DHub REGULAR_FONT = "#{GAME_ROOT_PATH}/media/fonts/NotoSans-Regular.ttf" BOLD_FONT = "#{GAME_ROOT_PATH}/media/fonts/NotoSans-Bold.ttf" + MAX_PAGE_WIDTH = 1200 + TESTING_BUTTON = { background: 0xff_ff8800, hover: { diff --git a/locales/en.yml b/locales/en.yml index ae5d31a..114e1d7 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -53,3 +53,5 @@ en: set_nickname_message: Set a nickname that will be used when joining a server enter_password: Enter Password enter_password_message: This server requires a password + time: Time + remaining: Remaining