Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_ListViewComponent.c
Go to the documentation of this file.
1/*
2Scrollable list view with static count of entries.
3*/
4
5//------------------------------------------------------------------------------------------------
7{
8 // Constant widget names
9 const string WIDGET_VERTICAL_LIST = "VList";
10 const string WIDGET_SIZE_SCROLL_OFFSET = "SizeScrollOffset";
11 const string WIDGET_FOCUS_REST = "BtnFocusRest";
12
13 // Entries
14 [Attribute("", UIWidgets.ResourceNamePicker, desc: "Entry widget that list is filled with.")]
16
17 [Attribute("MouseWheel", UIWidgets.EditBox, desc: "Reference for scrolling action")]
18 protected string m_sScrollAction;
19
20 // Entries properties
21 [Attribute("0", UIWidgets.CheckBox, desc: "True will automatically set entry limit value by list size and entry size")]
23
24 [Attribute("10", UIWidgets.EditBox, desc: "Number of item that should be crated to the list, that player is able to see in list")]
25 protected int m_iEntriesLimit;
26
27 [Attribute("4", UIWidgets.EditBox, desc: "Space between each entry")]
29
30 [Attribute("1", UIWidgets.EditBox, desc: "How many entries are move in one scroll")]
31 protected float m_fScrollMove;
32
33 [Attribute("1", UIWidgets.EditBox, desc: "Time for apearing animation")]
34 protected float m_fAnimationAppearTime;
35
36 // widgets
41
42 // Server entries data
43 protected ref array<Widget> m_aEntryWidgets = new array<Widget>;
44
45 // Hadling conponents
47
48 // Scroll properties
49 protected float m_fScrollPosition = 0; // Whole number = entry id on top, decimal point = offset between whole step
50 protected float m_iLastScrollPosition = 0;
51 protected float m_iEntriesCount = 0;
52 protected float m_fEntryWidgetHeight;
53
54 protected int m_iFocusedEntryId = 0;
55
56 protected bool m_bIscrollActive;
58
59 protected bool m_bCreateList = false;
60
61 // Animations properties
62
63 //-------------------------------------
64 // ScriptedWidgetComponent override
65 //-------------------------------------
66
67 //------------------------------------------------------------------------------------------------
68 override void HandlerAttached(Widget w)
69 {
70 super.HandlerAttached(w);
71
72 // Accessing handlers and widgets
73 m_wRoot = w;
75
77
78 // Setup inputs invokers
79 GetGame().GetInputManager().AddActionListener(UIConstants.MENU_ACTION_DOWN, EActionTrigger.DOWN, OnMenuDown);
80 GetGame().GetInputManager().AddActionListener(UIConstants.MENU_ACTION_UP, EActionTrigger.DOWN, OnMenuUp);
81 }
82
83 //------------------------------------------------------------------------------------------------
84 override bool OnUpdate(Widget w)
85 {
86 super.OnUpdate(w);
87
88 if (m_bCreateList)
89 {
90 PostCheck();
91 //UpdateEntries();
92
93 //m_bCreateList = false;
94 }
95
96 return false;
97 }
98
99 //-------------------------------------
100 // public functions
101 //-------------------------------------
102
103 //------------------------------------------------------------------------------------------------
105 void UpdateEntries(bool animated = false)
106 {
107 m_bAnimateListAppearing = animated;
108
109 // Fill list with data
110 foreach (Widget w : m_aEntryWidgets)
111 {
112 if (w)
113 FillEntry(w);
114 }
115
116 // Hide scrollbar if list is not overfloating
117 float scrollsCount = ScrollableEntriesCount();
118 SetScrollbarVisible(scrollsCount != -1);
119 }
120
121 //------------------------------------------------------------------------------------------------
122 void SetScrollbarVisible(bool visible)
123 {
124 if (m_Scrollbar)
125 m_Scrollbar.GetRootWidget().SetVisible(visible);
126 }
127
128 //------------------------------------------------------------------------------------------------
131 {
132 // Get and check widget
133 Widget availableEntry = FirstAvailableEntry();
134 if (!availableEntry)
135 return;
136
137 // Focus
138 GetGame().GetWorkspace().SetFocusedWidget(null);
139 GetGame().GetWorkspace().SetFocusedWidget(availableEntry);
140 }
141
142 //-------------------------------------
143 // protected functions
144 //-------------------------------------
145
146 //------------------------------------------------------------------------------------------------
148 protected void AccessingHandlers()
149 {
150 // Get Widgets
151 m_wVerticalList = m_wRoot.FindWidget(WIDGET_VERTICAL_LIST);
152 m_wSizeScrollOffset = SizeLayoutWidget.Cast(m_wRoot.FindAnyWidget(WIDGET_SIZE_SCROLL_OFFSET));
153 m_wFocusRest = m_wRoot.FindAnyWidget(WIDGET_FOCUS_REST);
154 }
155
156 //------------------------------------------------------------------------------------------------
158 protected void CreateEntriesWidgets()
159 {
160 if(!m_wRoot || m_sEntry.IsEmpty())
161 return;
162
163 // Create first entry
164 CreateEntry();
165 //m_bCreateList = true;
167
168 // Allow create rest of entries
169
170 //GetGame().GetCallqueue().CallLater(PostCheck, 500);
171
172 // Auto calculate limit
173 /*if (m_bAutomaticEntriesLimit)
174 m_iEntriesLimit = CalculateLimit();*/
175
176 // Create server entry widgets
177 for (int i = 1; i < m_iEntriesLimit; i++)
178 {
179 CreateEntry();
180 }
181
182 // Focus on first entry
183 if(m_aEntryWidgets.Count() > 0)
184 GetGame().GetWorkspace().SetFocusedWidget(m_aEntryWidgets[0]);
185 }
186
187 //------------------------------------------------------------------------------------------------
188 protected void PostCheck()
189 {
191
192 // Check size
194 return;
195
196 int limitPrev = m_iEntriesLimit;
197
198 // Auto calculate limit
201
202 // Remove widgets over limit
203 /*for (int i = limitPrev - 1; i > m_iEntriesLimit; i--)
204 {
205 m_aEntryWidgets[i].RemoveFromHierarchy();
206 m_aEntryWidgets.RemoveItem(m_aEntryWidgets[i]);
207 }*/
208
209 for (int i = 0; i < m_iEntriesLimit; i++)
210 {
211 CreateEntry();
212 }
213
214 m_bCreateList = false;
215
216 // Focus on first entry
217 if(m_aEntryWidgets.Count() > 0)
218 GetGame().GetWorkspace().SetFocusedWidget(m_aEntryWidgets[0]);
219 }
220
221 //------------------------------------------------------------------------------------------------
222 protected void CreateEntry()
223 {
224 WorkspaceWidget workspace = GetGame().GetWorkspace();
225
226 if (!m_sEntry || !m_wVerticalList || !workspace)
227 return;
228
229 Widget widget = workspace.CreateWidgets(m_sEntry, m_wVerticalList);
230 if (!widget)
231 return;
232
233 // Setup widget entry behavior
234 SetupEntryBehavior(widget);
235
236 // Save in widget list
237 m_aEntryWidgets.Insert(widget);
238
239 // Set padding
240 VerticalLayoutSlot.SetPadding(widget, 0, 0, 0, m_iEntriesBottomPadding);
241
242 // Visible in editor
243 widget.SetVisible(!GetGame().InPlayMode());
244 }
245
246 //------------------------------------------------------------------------------------------------
248 protected int CalculateLimit()
249 {
250 float wrapHeight, x;
251 m_wVerticalList.GetScreenSize(x, wrapHeight);
253
254 int res = Math.Ceil(wrapHeight / entryH);
255 return res;
256 }
257
258 //------------------------------------------------------------------------------------------------
261 protected float EntryFractionFromViewPos(float viewPos, float scrollPos)
262 {
263 // Wrap
264 float wrapHeight, x;
265 m_wVerticalList.GetScreenSize(x, wrapHeight);
266
267 // Entry
269
270 float entriesLimit = wrapHeight / entryH;
271
272 float entryFraction = (entriesLimit - Math.Floor(entriesLimit));
273 entriesLimit -= m_iEntriesBottomPadding*2 / m_fEntryWidgetHeight / entriesLimit;
274 //float scrollFracion = scrollPos
275
276 return entryFraction;
277 }
278
279 const int ENTRY_FIRST = 0;
280
281 //------------------------------------------------------------------------------------------------
283 protected void CheckEntrySize()
284 {
286 {
287 float x;
290 }
291 }
292
293 //------------------------------------------------------------------------------------------------
296 protected void SetupEntryBehavior(Widget entry) { }
297
298 //------------------------------------------------------------------------------------------------
301 protected void FillEntry(Widget w) {}
302
303 //------------------------------------------------------------------------------------------------
305 protected void ScrollOffsetMove(float scrollPos)
306 {
307 // Check first entry height if = 0
308 if (m_fEntryWidgetHeight == 0)
310
311 // Get offset from scroll position
312 float scrollsCount = ScrollableEntriesCount();
313
314 // Prevent scroll if there are no entries to scroll
315 if (scrollsCount == -1)
316 return;
317
318 scrollPos *= scrollsCount;
319 float offset = scrollPos - Math.Floor(scrollPos);
320 offset = offset * m_fEntryWidgetHeight;
321
322 // Move list if offset is overflown
323 if (m_iLastScrollPosition != Math.Floor(scrollPos))
324 {
325 m_iLastScrollPosition = Math.Floor(scrollPos);
327 }
328
329 // Move list offset
330 m_wSizeScrollOffset.SetHeightOverride(-offset);
331
332 // Save scroll position
333 m_fScrollPosition = scrollPos;
334 }
335
336 //------------------------------------------------------------------------------------------------
338 protected void ScrollWheelMove()
339 {
340 if (!m_bIscrollActive)
341 return;
342
343 // Check scroll input value
344 float scrollDir = GetGame().GetInputManager().GetActionValue(m_sScrollAction);
345 scrollDir = Math.Clamp(scrollDir, -1, 1);
346
347 // Scroll if any move
348 if (scrollDir != 0)
349 {
350 ScrollList(m_fScrollMove, -scrollDir);
351
353 }
354
355 // Repeat scrolling
356 GetGame().GetCallqueue().CallLater(ScrollWheelMove, 0);
357 }
358
359 //------------------------------------------------------------------------------------------------
361 protected void StayOnLastEntry()
362 {
363 int focusedIdInList = m_iFocusedEntryId - Math.Floor(m_fScrollPosition);
364
365 if (focusedIdInList > -1 && focusedIdInList < m_aEntryWidgets.Count())
367 else
368 GetGame().GetWorkspace().SetFocusedWidget(m_wFocusRest);
369 }
370
371 //------------------------------------------------------------------------------------------------
372 protected void ScrollList(float step, float input)
373 {
374 float scrollsCount = ScrollableEntriesCount();
375 float move = 0;
376
378 {
379 move = ScrollMove(step, input);
380 ScrollOffsetMove(move);
381
382 // Update scroll position
383 m_fScrollPosition = move * scrollsCount;
384 }
385
386 if (m_Scrollbar)
387 m_Scrollbar.MoveHandlerPos(move);
388 }
389
390 //------------------------------------------------------------------------------------------------
391 protected float ScrollMove(float step, float inputMove)
392 {
393 float scrollsCount = ScrollableEntriesCount();
394
395 float pos = step / scrollsCount * inputMove;
396
397 // Move scrollbar
398 pos += m_fScrollPosition / scrollsCount;
399 pos = Math.Clamp(pos, 0, 1);
400
401 return pos;
402 }
403
404 //------------------------------------------------------------------------------------------------
406 {
407 // Unfocus previous
408 Widget focused = GetGame().GetWorkspace().GetFocusedWidget();
409
410 if (focused)
411 {
413 if (prevBtn)
414 prevBtn.ShowBorder(false, false);
415 }
416
417 // Focus next
418 GetGame().GetWorkspace().SetFocusedWidget(w);
420 if (nextBtn)
421 {
422 nextBtn.ShowBorder(true, false);
424 nextBtn.m_wBorder.SetOpacity(1);
425 }
426 }
427
428 //------------------------------------------------------------------------------------------------
430 protected void AnimateEntryOpacity(Widget w, int delay, float animTime, float opacityEnd, float opacityStart = -1)
431 {
432 if (opacityStart != -1)
433 w.SetOpacity(opacityStart);
434
435 GetGame().GetCallqueue().CallLater(OpacityAnimation, delay, false, w, animTime, opacityEnd);
436 }
437
438 //------------------------------------------------------------------------------------------------
439 protected void OpacityAnimation(Widget w, int time, float opacityEnd)
440 {
441 AnimateWidget.Opacity(w, opacityEnd, time);
442 }
443
444 //------------------------------------------------------------------------------------------------
446 protected void ClearServerList()
447 {
448 // Remove widgets
449 foreach (Widget entry : m_aEntryWidgets)
450 {
451 entry.RemoveFromHierarchy();
452 }
453
454 // Clear list
455 m_aEntryWidgets.Clear();
456 }
457
458 //------------------------------------------------------------------------------------------------
461 /*protected void SteppingOutside(int next)
462 {
463 int nextClampped = m_iFocusedEntryId - Math.Floor(m_fScrollPosition) + next;
464
465 // Settping down to next hidden
466 if (nextClampped > m_iEntriesLimit)
467 {
468 GetGame().GetWorkspace().SetFocusedWidget(m_aEntryWidgets[m_iEntriesLimit - 1]);
469 }
470
471 // Stepping up to next hidden
472 if (nextClampped < 1)
473 {
474 GetGame().GetWorkspace().SetFocusedWidget(m_aEntryWidgets[0]);
475 }
476 }*/
477
478 //------------------------------------------------------------------------------------------------
480 protected void OnMenuDown()
481 {
482 // Check room coount boundary
484 return;
485
486 // Move focus
488 int nextClampped = m_iFocusedEntryId - Math.Ceil(m_fScrollPosition);
489 int limit = m_iEntriesLimit - 1;
490
491
492 // Settping down to next hidden
493 if (nextClampped >= limit)
494 {
495 float scrollStep = EntryFractionFromViewPos(1, 0);
496 Print("scrollStep: " + scrollStep);
497 ScrollList(scrollStep, 1);
498 GetGame().GetWorkspace().SetFocusedWidget(m_aEntryWidgets[limit - 1]);
499 }
500 }
501
502 //------------------------------------------------------------------------------------------------//------------------------------------------------------------------------------------------------
504 protected void OnMenuUp()
505 {
506 // Check 0
507 if (m_iFocusedEntryId < 1)
508 return;
509
510 // Move focus
512 int nextClampped = m_iFocusedEntryId - Math.Floor(m_fScrollPosition) - 1;
513
514 // Settping down to next hidden
515 if (nextClampped < 1)
516 {
517 ScrollList(1, -1);
518 GetGame().GetWorkspace().SetFocusedWidget(m_aEntryWidgets[0]);
519 }
520 }
521
522 //-------------------------------------
523 // Get & Set
524 //-------------------------------------
525
526 //------------------------------------------------------------------------------------------------
528 {
529 // Check and assign
530 if (!scrollbar)
531 return;
532
533 m_Scrollbar = scrollbar;
534
536
537 // Invoker
538 m_Scrollbar.m_OnScroll.Insert(ScrollOffsetMove);
539 }
540
541 //------------------------------------------------------------------------------------------------
543 void ActivateScrolling(bool activate)
544 {
545 m_bIscrollActive = activate;
546
547 // Start scrolling update
550 }
551
552 //------------------------------------------------------------------------------------------------
554 {
555 if (!m_Scrollbar || m_iEntriesCount < 1)
556 return;
557
558 float fillAmount = m_iEntriesLimit / m_iEntriesCount;
559 m_Scrollbar.SetupHandlerFill(fillAmount);
560 }
561
562 //------------------------------------------------------------------------------------------------
563 array<Widget> GetEntryWidgets() { return m_aEntryWidgets; }
564
565 //------------------------------------------------------------------------------------------------\
566 //! Return how many entries can be scrolled
568 {
569 float dif = m_iEntriesCount - m_iEntriesLimit;
570
571 // No entries check
572 if (dif <= 0)
573 return -1;
574
575 return dif;
576 }
577
578 //------------------------------------------------------------------------------------------------
581 {
582 foreach (Widget entry : m_aEntryWidgets)
583 {
584 if (entry.IsVisible() && entry.IsEnabled())
585 return entry;
586 }
587
588 return null;
589 }
590};
ArmaReforgerScripted GetGame()
Definition game.c:1398
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
static bool StopAnimation(Widget w, typename typeName)
static WidgetAnimationOpacity Opacity(Widget widget, float targetValue, float speed, bool toggleVisibility=false)
Definition Math.c:13
Base class for any button, regardless its own content.
void ShowBorder(bool show, bool animate=true)
void SetupEntryBehavior(Widget entry)
override void HandlerAttached(Widget w)
void FocusFirstAvailableEntry()
Find first available entry and focus it.
ref array< Widget > m_aEntryWidgets
void ScrollList(float step, float input)
void SetScrollbar(SCR_ScrollBarComponent scrollbar)
array< Widget > GetEntryWidgets()
void ScrollOffsetMove(float scrollPos)
Modify offset size to fake scrolling by scroll position.
void AccessingHandlers()
Get reference to all needed component for handling.
float ScrollMove(float step, float inputMove)
Widget FirstAvailableEntry()
Return first that is visible and enabled.
override bool OnUpdate(Widget w)
void SetScrollbarVisible(bool visible)
void OpacityAnimation(Widget w, int time, float opacityEnd)
void ScrollWheelMove()
Scroll list based on input action.
void CreateEntriesWidgets()
Create server entries widget.
void ChangeFocusWithoutAnimation(Widget w)
float EntryFractionFromViewPos(float viewPos, float scrollPos)
SCR_ScrollBarComponent m_Scrollbar
void OnMenuDown()
Check stepping over limit down.
SizeLayoutWidget m_wSizeScrollOffset
void CheckEntrySize()
Get size of widget entry used in list.
int CalculateLimit()
Calulate entry limit number from list size and entry size.
void ActivateScrolling(bool activate)
Activate scrolling with input action.
void StayOnLastEntry()
Kepp focus on last entry on scroll.
void ClearServerList()
Clear widgets from server list.
void AnimateEntryOpacity(Widget w, int delay, float animTime, float opacityEnd, float opacityStart=-1)
Setup opacity animation.
void OnMenuUp()
Check stepping over limit up.
void UpdateEntries(bool animated=false)
Fill entries with data.
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
SCR_FieldOfViewSettings Attribute
EActionTrigger