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