9 const string WIDGET_VERTICAL_LIST =
"VList";
10 const string WIDGET_SIZE_SCROLL_OFFSET =
"SizeScrollOffset";
11 const string WIDGET_FOCUS_REST =
"BtnFocusRest";
14 [
Attribute(
"", UIWidgets.ResourceNamePicker,
desc:
"Entry widget that list is filled with.")]
15 protected ResourceName m_sEntry;
17 [
Attribute(
"MouseWheel", UIWidgets.EditBox,
desc:
"Reference for scrolling action")]
18 protected string m_sScrollAction;
21 [
Attribute(
"0", UIWidgets.CheckBox,
desc:
"True will automatically set entry limit value by list size and entry size")]
22 protected bool m_bAutomaticEntriesLimit;
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;
27 [
Attribute(
"4", UIWidgets.EditBox,
desc:
"Space between each entry")]
28 protected int m_iEntriesBottomPadding;
30 [
Attribute(
"1", UIWidgets.EditBox,
desc:
"How many entries are move in one scroll")]
31 protected float m_fScrollMove;
33 [
Attribute(
"1", UIWidgets.EditBox,
desc:
"Time for apearing animation")]
34 protected float m_fAnimationAppearTime;
38 protected Widget m_wVerticalList;
39 protected SizeLayoutWidget m_wSizeScrollOffset;
40 protected Widget m_wFocusRest;
43 protected ref array<Widget> m_aEntryWidgets =
new array<Widget>;
49 protected float m_fScrollPosition = 0;
50 protected float m_iLastScrollPosition = 0;
51 protected float m_iEntriesCount = 0;
52 protected float m_fEntryWidgetHeight;
54 protected int m_iFocusedEntryId = 0;
56 protected bool m_bIscrollActive;
57 protected bool m_bAnimateListAppearing;
59 protected bool m_bCreateList =
false;
68 override void HandlerAttached(Widget w)
70 super.HandlerAttached(w);
76 CreateEntriesWidgets();
79 GetGame().GetInputManager().AddActionListener(
"MenuDown", EActionTrigger.DOWN, OnMenuDown);
80 GetGame().GetInputManager().AddActionListener(
"MenuUp", EActionTrigger.DOWN, OnMenuUp);
84 override bool OnUpdate(Widget w)
105 void UpdateEntries(
bool animated =
false)
107 m_bAnimateListAppearing = animated;
110 foreach (Widget w : m_aEntryWidgets)
117 float scrollsCount = ScrollableEntriesCount();
118 SetScrollbarVisible(scrollsCount != -1);
122 void SetScrollbarVisible(
bool visible)
125 m_Scrollbar.GetRootWidget().SetVisible(visible);
130 void FocusFirstAvailableEntry()
133 Widget availableEntry = FirstAvailableEntry();
138 GetGame().GetWorkspace().SetFocusedWidget(
null);
139 GetGame().GetWorkspace().SetFocusedWidget(availableEntry);
148 protected void AccessingHandlers()
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);
158 protected void CreateEntriesWidgets()
160 if(!
m_wRoot || m_sEntry.IsEmpty())
177 for (
int i = 1; i < m_iEntriesLimit; i++)
183 if(m_aEntryWidgets.Count() > 0)
184 GetGame().GetWorkspace().SetFocusedWidget(m_aEntryWidgets[0]);
188 protected void PostCheck()
193 if (m_fEntryWidgetHeight == m_iEntriesBottomPadding)
196 int limitPrev = m_iEntriesLimit;
199 if (m_bAutomaticEntriesLimit)
200 m_iEntriesLimit = CalculateLimit() + 1;
209 for (
int i = 0; i < m_iEntriesLimit; i++)
214 m_bCreateList =
false;
217 if(m_aEntryWidgets.Count() > 0)
218 GetGame().GetWorkspace().SetFocusedWidget(m_aEntryWidgets[0]);
222 protected void CreateEntry()
224 WorkspaceWidget workspace =
GetGame().GetWorkspace();
226 if (!m_sEntry || !m_wVerticalList || !workspace)
229 Widget widget = workspace.CreateWidgets(m_sEntry, m_wVerticalList);
234 SetupEntryBehavior(widget);
237 m_aEntryWidgets.Insert(widget);
240 VerticalLayoutSlot.SetPadding(widget, 0, 0, 0, m_iEntriesBottomPadding);
243 widget.SetVisible(!
GetGame().InPlayMode());
248 protected int CalculateLimit()
251 m_wVerticalList.GetScreenSize(x, wrapHeight);
252 int entryH = m_fEntryWidgetHeight + m_iEntriesBottomPadding;
254 int res = Math.Ceil(wrapHeight / entryH);
261 protected float EntryFractionFromViewPos(
float viewPos,
float scrollPos)
265 m_wVerticalList.GetScreenSize(x, wrapHeight);
268 int entryH = m_fEntryWidgetHeight + m_iEntriesBottomPadding;
270 float entriesLimit = wrapHeight / entryH;
272 float entryFraction = (entriesLimit - Math.Floor(entriesLimit));
273 entriesLimit -= m_iEntriesBottomPadding*2 / m_fEntryWidgetHeight / entriesLimit;
276 return entryFraction;
279 const int ENTRY_FIRST = 0;
283 protected void CheckEntrySize()
285 if (m_iEntriesLimit > ENTRY_FIRST)
288 m_aEntryWidgets[ENTRY_FIRST].GetScreenSize(x, m_fEntryWidgetHeight);
289 m_fEntryWidgetHeight += m_iEntriesBottomPadding;
296 protected void SetupEntryBehavior(Widget entry) { }
301 protected void FillEntry(Widget w) {}
305 protected void ScrollOffsetMove(
float scrollPos)
308 if (m_fEntryWidgetHeight == 0)
312 float scrollsCount = ScrollableEntriesCount();
315 if (scrollsCount == -1)
318 scrollPos *= scrollsCount;
319 float offset = scrollPos - Math.Floor(scrollPos);
320 offset = offset * m_fEntryWidgetHeight;
323 if (m_iLastScrollPosition != Math.Floor(scrollPos))
325 m_iLastScrollPosition = Math.Floor(scrollPos);
330 m_wSizeScrollOffset.SetHeightOverride(-offset);
333 m_fScrollPosition = scrollPos;
338 protected void ScrollWheelMove()
340 if (!m_bIscrollActive)
344 float scrollDir =
GetGame().GetInputManager().GetActionValue(m_sScrollAction);
345 scrollDir = Math.Clamp(scrollDir, -1, 1);
350 ScrollList(m_fScrollMove, -scrollDir);
356 GetGame().GetCallqueue().CallLater(ScrollWheelMove, 0);
361 protected void StayOnLastEntry()
363 int focusedIdInList = m_iFocusedEntryId - Math.Floor(m_fScrollPosition);
365 if (focusedIdInList > -1 && focusedIdInList < m_aEntryWidgets.Count())
366 ChangeFocusWithoutAnimation(m_aEntryWidgets[focusedIdInList]);
368 GetGame().GetWorkspace().SetFocusedWidget(m_wFocusRest);
372 protected void ScrollList(
float step,
float input)
374 float scrollsCount = ScrollableEntriesCount();
377 if (m_bIscrollActive)
379 move = ScrollMove(step, input);
380 ScrollOffsetMove(move);
383 m_fScrollPosition = move * scrollsCount;
387 m_Scrollbar.MoveHandlerPos(move);
391 protected float ScrollMove(
float step,
float inputMove)
393 float scrollsCount = ScrollableEntriesCount();
395 float pos = step / scrollsCount * inputMove;
398 pos += m_fScrollPosition / scrollsCount;
399 pos = Math.Clamp(pos, 0, 1);
405 protected void ChangeFocusWithoutAnimation(Widget w)
408 Widget focused =
GetGame().GetWorkspace().GetFocusedWidget();
414 prevBtn.ShowBorder(
false,
false);
418 GetGame().GetWorkspace().SetFocusedWidget(w);
422 nextBtn.ShowBorder(
true,
false);
423 AnimateWidget.StopAnimation(nextBtn.m_wBorder, WidgetAnimationOpacity);
424 nextBtn.m_wBorder.SetOpacity(1);
430 protected void AnimateEntryOpacity(Widget w,
int delay,
float animTime,
float opacityEnd,
float opacityStart = -1)
432 if (opacityStart != -1)
433 w.SetOpacity(opacityStart);
435 GetGame().GetCallqueue().CallLater(OpacityAnimation, delay,
false, w, animTime, opacityEnd);
439 protected void OpacityAnimation(Widget w,
int time,
float opacityEnd)
441 AnimateWidget.Opacity(w, opacityEnd, time);
446 protected void ClearServerList()
449 foreach (Widget entry : m_aEntryWidgets)
451 entry.RemoveFromHierarchy();
455 m_aEntryWidgets.Clear();
480 protected void OnMenuDown()
483 if (m_iFocusedEntryId >= m_iEntriesCount - 1)
488 int nextClampped = m_iFocusedEntryId - Math.Ceil(m_fScrollPosition);
489 int limit = m_iEntriesLimit - 1;
493 if (nextClampped >= limit)
495 float scrollStep = EntryFractionFromViewPos(1, 0);
496 Print(
"scrollStep: " + scrollStep);
497 ScrollList(scrollStep, 1);
498 GetGame().GetWorkspace().SetFocusedWidget(m_aEntryWidgets[limit - 1]);
504 protected void OnMenuUp()
507 if (m_iFocusedEntryId < 1)
512 int nextClampped = m_iFocusedEntryId - Math.Floor(m_fScrollPosition) - 1;
515 if (nextClampped < 1)
518 GetGame().GetWorkspace().SetFocusedWidget(m_aEntryWidgets[0]);
533 m_Scrollbar = scrollbar;
538 m_Scrollbar.m_OnScroll.Insert(ScrollOffsetMove);
543 void ActivateScrolling(
bool activate)
545 m_bIscrollActive = activate;
548 if (m_bIscrollActive)
553 void UpdateScrollbar()
555 if (!m_Scrollbar || m_iEntriesCount < 1)
558 float fillAmount = m_iEntriesLimit / m_iEntriesCount;
559 m_Scrollbar.SetupHandlerFill(fillAmount);
563 array<Widget> GetEntryWidgets() {
return m_aEntryWidgets; }
569 float dif = m_iEntriesCount - m_iEntriesLimit;
580 Widget FirstAvailableEntry()
582 foreach (Widget entry : m_aEntryWidgets)
584 if (entry.IsVisible() && entry.IsEnabled())