Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_DownloadManagerEntry.c
Go to the documentation of this file.
1 
5 //------------------------------------------------------------------------------------------------
8 
9 //------------------------------------------------------------------------------------------------
11 {
12  const int PAUSE_ENABLE_DELAY_MS = 1000; // delay used to prevent spamming pause/resume request
13  protected const int PROCESSING_MESSAGE_UPDATE_DELAY = 2000; // delay to prevent message flickering when downloading switched to copying fragments
14 
15  // State messages
16  protected const string PERCENTAGE = "#AR-SupportStation_ActionFormat_Percentage";
17  protected const string STATE_DOWNLOADING = "#AR-DownloadManager_State_Downloading";
18  protected const string STATE_PROCESSING = "#AR-DownloadManager_State_Processing";
19  protected const string STATE_PAUSED = "#AR-Workshop_ButtonPause";
20  protected const string STATE_CANCELED = "#AR-Workshop_Canceled";
21  protected const string STATE_NO_CONNECTION = "#AR-Workshop_WarningNoConnection";
22  protected const string STATE_DOWNLOAD_FAIL = "#AR-Workshop_DownloadFail";
23  protected const string STATE_COMPLETED = "#AR-Workshop_Details_Downloaded";
24 
25  // State icons
26  protected const string STATE_ICON_DOWNLOADING = "downloading";
27  protected const string STATE_ICON_PROCESSING = "update";
28  protected const string STATE_ICON_PAUSED = "download-pause";
29  protected const string STATE_ICON_CANCELED = "cancelCircle";
30  protected const string STATE_ICON_DOWNLOAD_FAIL = "warning";
31  protected const string STATE_ICON_COMPLETED = "okCircle";
32 
33  [Attribute(UIConstants.ICONS_IMAGE_SET, UIWidgets.ResourceNamePicker, desc: "Imageset for the icon", params: "imageset")]
34  protected ResourceName m_sIconImageset;
35 
36  [Attribute(UIConstants.PROCESSING_SPINNER_ANIMATION_SPEED.ToString())]
37  protected float m_fIconAnimationSpeed;
38 
39  [Attribute(defvalue: SCR_Enum.GetDefault(EAnimationCurve.EASE_IN_OUT_SINE), uiwidget: UIWidgets.ComboBox, enums: ParamEnumArray.FromEnum(EAnimationCurve))]
40  protected EAnimationCurve m_eIconAnimationCurve;
41 
42  [Attribute("0")]
43  protected bool m_bHideProgressBarOnComplete;
44 
46  protected ref SCR_BackendImageComponent m_BackendImage;
47 
48  protected ref SCR_WorkshopItemActionDownload m_Action;
49  protected ref SCR_WorkshopItem m_Item;
50 
51  protected bool m_bPauseEnabled = true;
52  protected bool m_bShowButtons;
53  protected bool m_bDelayedProcessingDisplay;
54  protected EDownloadManagerActionState m_iState = EDownloadManagerActionState.INACTIVE;
55 
56  protected WidgetAnimationImageRotation m_SpinnerAnimation;
57 
58  protected ref ScriptInvokerBase<ScriptInvoker_DownloadManagerEntry> m_OnUpdate;
59 
60  //------------------------------------------------------------------------------------------------
61  ScriptInvokerBase<ScriptInvoker_DownloadManagerEntry> GetOnUpdate()
62  {
63  if (!m_OnUpdate)
64  m_OnUpdate = new ScriptInvokerBase<ScriptInvoker_DownloadManagerEntry>();
65 
66  return m_OnUpdate;
67  }
68 
69  //------------------------------------------------------------------------------------------------
70  // Override
71  //------------------------------------------------------------------------------------------------
72 
73  //------------------------------------------------------------------------------------------------
74  override void HandlerAttached(Widget w)
75  {
76  super.HandlerAttached(w);
77  m_Widgets.Init(w);
78 
79  m_Widgets.m_PauseBtnComponent.m_OnClicked.Insert(OnClickPause);
80  m_Widgets.m_ResumeBtnComponent.m_OnClicked.Insert(OnClickResume);
81  m_Widgets.m_CancelBtnComponent.m_OnClicked.Insert(OnClickCancel);
82  m_Widgets.m_RetryBtnComponent.m_OnClicked.Insert(OnClickRetry);
83 
84  m_Widgets.m_HorizontalButtons.SetVisible(false);
85  m_Widgets.m_PauseBtn.SetVisible(false);
86  m_Widgets.m_ResumeBtn.SetVisible(false);
87  m_Widgets.m_CancelBtn.SetVisible(false);
88  m_Widgets.m_RetryBtn.SetVisible(false);
89 
90  // Processing spinner animation
91  m_Widgets.m_ProcessingSpinner.SetRotation(360);
92  m_SpinnerAnimation = AnimateWidget.Rotation(m_Widgets.m_ProcessingSpinner, 0, m_fIconAnimationSpeed);
94  {
95  m_SpinnerAnimation.GetOnCycleCompleted().Insert(AnimateIcon);
96  AnimateIcon(m_SpinnerAnimation);
97  }
98  }
99 
100  //------------------------------------------------------------------------------------------------
101  override bool OnMouseEnter(Widget w, int x, int y)
102  {
103  m_bShowButtons = true;
104  UpdateButtons();
105 
106  return false;
107  }
108 
109  //------------------------------------------------------------------------------------------------
110  override bool OnMouseLeave(Widget w, Widget enterW,int x, int y)
111  {
112  m_bShowButtons = false;
113  UpdateButtons();
114 
115  return false;
116  }
117 
118  //------------------------------------------------------------------------------------------------
119  // Custom
120  //------------------------------------------------------------------------------------------------
121 
122  //------------------------------------------------------------------------------------------------
123  protected void SetupWidgets()
124  {
125  if (!m_Action)
126  {
127  FallbackVisuals();
128  return;
129  }
130 
131  // Image
132  if (m_Item && m_Item.GetWorkshopItem() && m_Item.GetWorkshopItem().Thumbnail())
133  m_BackendImage.SetImage(m_Item.GetWorkshopItem().Thumbnail());
134  else
135  m_BackendImage.SetImage(null);
136 
137  // Name
138  m_Widgets.m_NameText.SetText(m_Action.GetAddonName());
139 
140  // Versions
141  m_Widgets.m_VersionText.SetText(m_Action.GetTargetRevision().GetVersion());
142  }
143 
144  //------------------------------------------------------------------------------------------------
145  // Display placeholder values if action failed to be loaded
146  protected void FallbackVisuals()
147  {
148  if (!m_Item)
149  {
150  m_Widgets.m_NameText.SetText("...");
151  m_Widgets.m_VersionText.SetText("...");
152  m_BackendImage.SetImage(null);
153 
154  return;
155  }
156 
157  m_Widgets.m_NameText.SetText(m_Item.GetName());
158 
159  // Versions
160  if (m_Item.GetItemTargetRevision())
161  m_Widgets.m_VersionText.SetText(m_Item.GetItemTargetRevision().GetVersion());
162  else
163  m_Widgets.m_VersionText.SetText("...");
164 
165  // Image
166  if (m_Item.GetWorkshopItem() && m_Item.GetWorkshopItem().Thumbnail())
167  m_BackendImage.SetImage(m_Item.GetWorkshopItem().Thumbnail());
168  else
169  m_BackendImage.SetImage(null);
170  }
171 
172  //------------------------------------------------------------------------------------------------
174  protected void UpdateProgressWidgets(bool force = false)
175  {
176  m_iState = DownloadActionState(m_Action);
177 
178  // Progress bar
179  bool running = (m_iState == EDownloadManagerActionState.RUNNING);
180  bool runningOrFailed = running || m_iState == EDownloadManagerActionState.FAILED;
181 
182  if (m_bHideProgressBarOnComplete)
183  m_Widgets.m_Progress.SetVisible(runningOrFailed);
184 
185  // Download size
186  string addonSize = SCR_ByteFormat.ContentDownloadFormat(m_Action.GetSizeBytes());
187 
188  if (runningOrFailed)
189  {
190  // Show progress
191  string downloadSize = SCR_ByteFormat.ContentDownloadFormat(m_Action.GetSizeBytes() * m_Action.GetProgress());
192 
193  m_Widgets.m_DownloadedText.SetText(string.Format("%1/%2", downloadSize, addonSize));
194  m_Widgets.m_ProgressComponent.SetValue(m_Action.GetProgress());
195  }
196  else
197  {
198  m_Widgets.m_DownloadedText.SetText(addonSize);
199 
200  if (m_Action.IsCompleted())
201  m_Widgets.m_ProgressComponent.SetValue(m_Action.GetProgress());
202  }
203 
204  // Update buttons
205  UpdateButtons();
206 
207  bool processing = m_Action.IsProcessing() && !(m_Action.IsPaused() || m_Action.IsFailed() || m_Action.IsCanceled());
208  if (!processing || force)
209  {
210  UpdateMessage(processing);
211  }
212  // Delay to avoid flickering
213  else
214  {
215  m_bDelayedProcessingDisplay = true;
216  GetGame().GetCallqueue().CallLater(UpdateMessage, PROCESSING_MESSAGE_UPDATE_DELAY, false, processing);
217  }
218 
219  // Invoke
220  if (m_OnUpdate)
221  m_OnUpdate.Invoke(this);
222  }
223 
224  //------------------------------------------------------------------------------------------------
225  protected void UpdateMessage(bool processing)
226  {
227  if (m_bDelayedProcessingDisplay)
228  {
229  GetGame().GetCallqueue().Remove(UpdateMessage);
230  m_bDelayedProcessingDisplay = false;
231  }
232 
233  // Show message
234  string msg, imgName;
235  Color col;
236  StateMessage(msg, imgName, col);
237 
238  m_Widgets.m_DownloadStateText.SetText(msg);
239  m_Widgets.m_DownloadIcon.LoadImageFromSet(0, m_sIconImageset, imgName);
240  m_Widgets.m_DownloadIconShadow.LoadImageFromSet(0, m_sIconImageset, imgName);
241 
242  if (col)
243  {
244  m_Widgets.m_DownloadIcon.SetColor(col);
245  m_Widgets.m_DownloadStateText.SetColor(col);
246  m_Widgets.m_ProgressComponent.SetSliderColor(col);
247  m_Widgets.m_ProcessingSpinner.SetColor(col);
248  }
249 
250  m_Widgets.m_ProcessingSpinner.SetVisible(processing);
251  m_Widgets.m_DownloadIcon.SetVisible(!processing);
252  m_Widgets.m_DownloadIconShadow.SetVisible(!processing);
253  }
254 
255  //------------------------------------------------------------------------------------------------
256  protected void UpdateButtons()
257  {
258  m_Widgets.m_HorizontalButtons.SetVisible(m_bShowButtons);
259 
260  if (!m_bShowButtons)
261  return;
262 
263  bool pause, resume, cancel, retry;
264  CanDoActions(pause, resume, cancel, retry);
265 
266  // Buttons
267  m_Widgets.m_PauseBtn.SetVisible(pause);
268  m_Widgets.m_ResumeBtn.SetVisible(resume);
269  m_Widgets.m_CancelBtn.SetVisible(cancel);
270  m_Widgets.m_RetryBtn.SetVisible(retry);
271 
272  m_Widgets.m_PauseBtn.SetEnabled(m_Action.IsRunningAsyncSolved());
273  m_Widgets.m_ResumeBtn.SetEnabled(m_Action.IsPauseAsyncSolved());
274  }
275 
276  //------------------------------------------------------------------------------------------------
278  protected void StateMessage(out string message, out string imageName, out Color color)
279  {
280  float progress;
281 
282  // Downloading
283  if (m_Action.IsActive() && !m_Action.IsCompleted() && !m_Action.IsPaused())
284  {
285  // Copying fragments
286  if (m_Action.IsProcessing())
287  {
288  progress = m_Action.GetProcessingProgress();
289 
290  message = WidgetManager.Translate(PERCENTAGE, STATE_PROCESSING, Math.Round(progress * 100.0));
291  imageName = STATE_ICON_PROCESSING;
292  color = Color.FromInt(UIColors.ONLINE.PackToInt());
293  return;
294  }
295 
296  // Download running
297  progress = m_Action.GetProgress();
298 
299  message = WidgetManager.Translate(PERCENTAGE, STATE_DOWNLOADING, Math.Round(progress * 100.0));
300  imageName = STATE_ICON_DOWNLOADING;
301  color = Color.FromInt(UIColors.CONTRAST_COLOR.PackToInt());
302  return;
303  }
304 
305  // Paused
306  if (m_Action.IsPaused())
307  {
308  progress = m_Action.GetProgress();
309 
310  message = WidgetManager.Translate(PERCENTAGE, STATE_PAUSED, Math.Round(progress * 100.0));
311  imageName = STATE_ICON_PAUSED;
312  color = Color.FromInt(UIColors.CONTRAST_DEFAULT.PackToInt());
313  return;
314  }
315 
316  // Canceled
317  if (m_Action.IsCanceled())
318  {
319  message = STATE_CANCELED;
320  imageName = STATE_ICON_CANCELED;
321  color = Color.FromInt(UIColors.WARNING.PackToInt());
322  return;
323  }
324 
325  // Failed
326  if (m_Action.IsFailed())
327  {
328  FailReason(message, imageName);
329  color = Color.FromInt(UIColors.WARNING.PackToInt());
330  return;
331  }
332 
333  // Success
334  if (m_Action.IsCompleted())
335  {
336  message = STATE_COMPLETED;
337  imageName = STATE_ICON_COMPLETED;
338  color = Color.FromInt(UIColors.CONFIRM.PackToInt());
339  return;
340  }
341  }
342 
343  //------------------------------------------------------------------------------------------------
345  protected void FailReason(out string message, out string icon)
346  {
347  // Addon specific fail
348  message = STATE_DOWNLOAD_FAIL;
349  icon = STATE_ICON_DOWNLOAD_FAIL;
350 
351  // Communication with server failed
352  if (!SCR_ServicesStatusHelper.IsBackendConnectionAvailable())
353  {
354  message = STATE_NO_CONNECTION;
355  icon = UIConstants.ICON_SERVICES_ISSUES;
356  }
357  }
358 
359  //------------------------------------------------------------------------------------------------
361  protected void AnimateIcon(WidgetAnimationBase animation)
362  {
363  if (m_SpinnerAnimation)
364  {
365  m_SpinnerAnimation.GetOnCycleCompleted().Remove(AnimateIcon);
366  m_SpinnerAnimation.Stop();
367  }
368 
369  m_Widgets.m_ProcessingSpinner.SetRotation(360);
370  m_SpinnerAnimation = AnimateWidget.Rotation(m_Widgets.m_ProcessingSpinner, 0, m_fIconAnimationSpeed);
371  if (m_SpinnerAnimation)
372  {
373  m_SpinnerAnimation.SetRepeat(true);
374  m_SpinnerAnimation.SetCurve(m_eIconAnimationCurve);
375  m_SpinnerAnimation.GetOnCycleCompleted().Insert(AnimateIcon);
376  }
377  }
378 
379  //------------------------------------------------------------------------------------------------
380  protected void DisablePauserResume(SCR_ModularButtonComponent button)
381  {
382  m_bPauseEnabled = false;
383  button.SetEnabled(false);
384  // Enable pause button later to prevent request spamming
385  GetGame().GetCallqueue().Remove(EnablePauserResume);
386  GetGame().GetCallqueue().CallLater(EnablePauserResume, PAUSE_ENABLE_DELAY_MS, false, button);
387 
388  if (m_OnUpdate)
389  m_OnUpdate.Invoke(this);
390  }
391 
392  //------------------------------------------------------------------------------------------------
393  protected void EnablePauserResume(SCR_ModularButtonComponent button)
394  {
395  m_bPauseEnabled = true;
396  button.SetEnabled(true);
397 
398  if (m_OnUpdate)
399  m_OnUpdate.Invoke(this);
400  }
401 
402  //------------------------------------------------------------------------------------------------
403  protected void OnActionChanged(SCR_WorkshopItemAction action)
404  {
405  UpdateProgressWidgets();
406  }
407 
408  //------------------------------------------------------------------------------------------------
409  // Public
410  //------------------------------------------------------------------------------------------------
411  //------------------------------------------------------------------------------------------------
414  static EDownloadManagerActionState DownloadActionState(SCR_WorkshopItemActionDownload action)
415  {
416  if (!action)
417  {
418  Print("Download manager entry state can't be update due to missing download action");
419  return EDownloadManagerActionState.INACTIVE;
420  }
421 
422  // Running
423  if (!action.IsCompleted() && !action.IsFailed() && !action.IsCanceled())
424  return EDownloadManagerActionState.RUNNING;
425 
426  // Failed
427  if (action.IsFailed() || action.IsCanceled())
428  return EDownloadManagerActionState.FAILED;
429 
430  // Downloaded
431  if (action.IsCompleted() && !action.IsFailed() && !action.IsCanceled())
432  return EDownloadManagerActionState.DOWNLOADED;
433 
434  // No state
435  return EDownloadManagerActionState.INACTIVE;
436  }
437 
438  //------------------------------------------------------------------------------------------------
441  void InitForDownloadAction(SCR_WorkshopItem item, SCR_WorkshopItemActionDownload action)
442  {
443  m_Item = item;
444  m_Action = action;
445 
446  m_Action.m_OnChanged.Insert(OnActionChanged);
447 
448  m_BackendImage = SCR_BackendImageComponent.Cast(GetRootWidget().FindHandler(SCR_BackendImageComponent));
449 
450  // Setup static
451  SetupWidgets();
452 
453  if (m_Action)
454  UpdateProgressWidgets(true);
455  }
456 
457  //------------------------------------------------------------------------------------------------
459  void CanDoActions(out bool canPause, out bool canResume, out bool canCancel, out bool canRetry)
460  {
461  canPause = m_iState == EDownloadManagerActionState.RUNNING && !m_Action.IsPaused();
462  canResume = m_iState == EDownloadManagerActionState.RUNNING && m_Action.IsPaused();
463  canCancel = m_iState == EDownloadManagerActionState.RUNNING;
464  canRetry = m_iState == EDownloadManagerActionState.FAILED;
465  }
466 
467  //------------------------------------------------------------------------------------------------
468  void OnClickPause()
469  {
470  if (!m_Action)
471  return;
472 
473  if (m_Action.IsActive() && !m_Action.IsPaused())
474  m_Action.Pause();
475 
476  UpdateProgressWidgets();
477 
478  // Set disabled
479  //DisablePauserResume(m_Widgets.m_ResumeBtnComponent);
480  }
481 
482  //------------------------------------------------------------------------------------------------
483  void OnClickResume()
484  {
485  if (!m_Action)
486  return;
487 
488  if (m_Action.IsPaused())
489  m_Action.Resume();
490  else if (m_Action.IsInactive())
491  m_Action.Activate();
492 
493  UpdateProgressWidgets(true);
494 
495  // Set disabled
496  //DisablePauserResume(m_Widgets.m_PauseBtnComponent);
497  }
498 
499  //------------------------------------------------------------------------------------------------
500  void OnClickCancel()
501  {
502  if (m_Action)
503  m_Action.Cancel();
504 
505  UpdateProgressWidgets();
506  }
507 
508  //------------------------------------------------------------------------------------------------
509  void OnClickRetry()
510  {
511  if (m_Action)
512  m_Action.RetryDownload();
513 
514  if (m_wRoot)
515  UpdateProgressWidgets();
516  }
517 
518  //------------------------------------------------------------------------------------------------
519  // Get set
520  //------------------------------------------------------------------------------------------------
521 
522  //------------------------------------------------------------------------------------------------
523  SCR_WorkshopItem GetItem()
524  {
525  return m_Item;
526  }
527 
528  //------------------------------------------------------------------------------------------------
529  SCR_WorkshopItemActionDownload GetDownloadAction()
530  {
531  return m_Action;
532  }
533 
534  //------------------------------------------------------------------------------------------------
535  EDownloadManagerActionState GetState()
536  {
537  return m_iState;
538  }
539 
540  //------------------------------------------------------------------------------------------------
541  bool GetPauseEnabled()
542  {
543  return m_bPauseEnabled;
544  }
545 }
EDownloadManagerActionState
EDownloadManagerActionState
Enum describing current state of downloading action.
Definition: SCR_DownloadManager.c:846
SCR_Enum
Definition: SCR_Enum.c:1
m_wRoot
protected Widget m_wRoot
Definition: SCR_ScenarioFrameworkLayerTaskDefend.c:59
m_Item
NewsFeedItem m_Item
Definition: SCR_NewsSubMenu.c:2
UIConstants
Definition: Constants.c:130
STATE_DOWNLOADING
enum SCR_EDownloadManagerTabs STATE_DOWNLOADING
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_WorkshopItemActionDownload
Definition: SCR_WorkshopItemActionDownload.c:9
m_BackendImage
protected ref BackendImage m_BackendImage
Definition: SCR_BackendImageComponent.c:7
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
func
func
Definition: SCR_AIThreatSystem.c:5
m_Widgets
ref SCR_VoNOverlay_ElementWidgets m_Widgets
Definition: SCR_VonDisplay.c:3
SCR_WorkshopItem
Definition: SCR_WorkshopItem.c:21
m_SpinnerAnimation
protected WidgetAnimationImageRotation m_SpinnerAnimation
Definition: SCR_ConnectionStateButtonComponent.c:33
GetRootWidget
Widget GetRootWidget()
Definition: SCR_UITaskManagerComponent.c:160
SCR_DownloadManagerEntry
Definition: SCR_DownloadManagerEntry.c:10
Attribute
typedef Attribute
Post-process effect of scripted camera.
UIColors
Definition: Constants.c:16
SCR_DownloadManagerEntryWidgets
Definition: SCR_DownloadManagerEntryWidgets.c:4
SCR_ByteFormat
Definition: SCR_ByteFormat.c:5
ScriptInvoker_DownloadManagerEntry
func ScriptInvoker_DownloadManagerEntry
Definition: SCR_DownloadManagerEntry.c:7
SCR_WorkshopItemAction
Definition: SCR_WorkshopItemAction.c:16
SCR_ServicesStatusHelper
Definition: SCR_ServicesStatusHelper.c:15
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
SCR_ScriptedWidgetComponent
Definition: SCR_ScriptedWidgetComponent.c:7