class W3DHub class States class Interface < CyberarmEngine::GuiState APPLICATIONS_UPDATE_INTERVAL = 10 * 60 * 1000 # ten minutes SERVER_LIST_UPDATE_INTERVAL = 5 * 60 * 1000 # five minutes 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] @applications_expire = Gosu.milliseconds + APPLICATIONS_UPDATE_INTERVAL # ten minutes @server_list_expire = Gosu.milliseconds + SERVER_LIST_UPDATE_INTERVAL # 5 minutes @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, background_image: "#{GAME_ROOT_PATH}/media/banners/background.png", background_image_color: 0xff_525252, background_image_mode: :fill) 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 @nav_padding_top_container = flow(fill: true) flow(width: 1.0, height: 36) do # background 0xff_666666 link I18n.t(:"interface.games").upcase, text_size: 34, font: BOLD_FONT do page(W3DHub::Pages::Games) end link I18n.t(:"interface.servers").upcase, text_size: 34, font: BOLD_FONT, margin_left: 12 do page(W3DHub::Pages::ServerBrowser) end link I18n.t(:"interface.community").upcase, text_size: 34, font: BOLD_FONT, margin_left: 12 do page(W3DHub::Pages::Community) end link I18n.t(:"interface.downloads").upcase, text_size: 34, font: BOLD_FONT, margin_left: 12 do page(W3DHub::Pages::DownloadManager) end link I18n.t(:"interface.settings").upcase, text_size: 34, font: BOLD_FONT, margin_left: 12 do page(W3DHub::Pages::Settings) end end @nav_padding_bottom_container = flow(fill: true) # Installer task display @application_taskbar_container = flow(width: 1.0, height: 0.5) do 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 = para "", fill: true, text_wrap: :none @application_taskbar_status_label = para "", width: 0.4, min_width: 256, 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: 22, width: 0.5) { page(W3DHub::Pages::Login) } link I18n.t(:"interface.register"), text_size: 22, 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 if Gosu.milliseconds >= @applications_expire @applications_expire = Gosu.milliseconds + 30_000 Api.on_thread(:applications) do |applications| if applications @applications_expire = Gosu.milliseconds + APPLICATIONS_UPDATE_INTERVAL # ten minutes Store.applications = applications # TODO: Signal Games and ServerBrowser that applications have been updated end end end if Gosu.milliseconds >= @server_list_expire @server_list_expire = Gosu.milliseconds + 30_000 Api.on_thread(:server_list, 2) do |list| if list @server_list_expire = Gosu.milliseconds + SERVER_LIST_UPDATE_INTERVAL # five minutes Store.server_list_last_fetch = Gosu.milliseconds Api::ServerListUpdater.instance.refresh_server_list(list) BackgroundWorker.foreground_job(-> {}, ->(_) { States::Interface.instance&.update_server_browser(nil, :refresh_all) }) end end end 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, mode = :update) return unless @page.is_a?(Pages::ServerBrowser) @page.refresh_server_list(server, mode) end def update_server_ping(server) return unless @page.is_a?(Pages::ServerBrowser) @page.update_server_ping(server) end def show_application_taskbar @nav_padding_top_container.hide @nav_padding_bottom_container.hide @application_taskbar_container.show end def hide_application_taskbar @application_taskbar_container.hide @nav_padding_top_container.show @nav_padding_bottom_container.show 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