7 protected int m_iColumns;
9 [
Attribute(
"-1",
desc:
"Minimum mumber of rows in content area.\n When -1, value from 'Rows' will be used.")]
10 protected int m_iMinRows;
12 [
Attribute(
"-1",
desc:
"Minimum number of rows in content area.\n When -1, value from 'Columns' will be used.")]
13 protected int m_iMinColumns;
16 protected string m_sContentName;
18 [
Attribute(
desc:
"Name of a widget which, when activated, will move to the previous page. This button is shown when cursor is focused on the area.")]
19 protected string m_sButtonPrevName;
21 [
Attribute(
desc:
"Name of a widget which, when activated, will move to the next page. This button is shown when cursor is focused on the area.")]
22 protected string m_sButtonNextName;
24 [
Attribute(
"PrevButton_NoScroll",
desc:
"Name of a widget which, when activated, will move to the previous page. This button is shown when cursor is not focused on the area.")]
25 protected string m_sButtonPrevName_NoScrolling;
27 [
Attribute(
"NextButton_NoScroll",
desc:
"Name of a widget which, when activated, will move to the next page. This button is shown when cursor is not focused on the area.")]
28 protected string m_sButtonNextName_NoScrolling;
30 [
Attribute(
desc:
"Name of a widget which, when focused, will move to the previous page.\nused to auto-paging when focusing outside of content area in given direction.")]
31 protected string m_sFocusPrevName;
33 [
Attribute(
desc:
"Name of a widget which, when focused, will move to the next page.\nused to auto-paging when focusing outside of content area in given direction.")]
34 protected string m_sFocusNextName;
36 [
Attribute(
desc:
"Name of the widget which will show page numbers.")]
37 protected string m_sPageIndexVisualName;
39 [
Attribute(
"#AR-Editor_ContentBrowser_PageIndex_Text",
desc:
"Format of page number text.")]
40 protected string m_sPageIndexVisualText;
42 [
Attribute(
desc:
"When enabled, button shortcuts will be accepted only when cursor is over content widget.\nWhen disabled, cursor can be anywhere inside area of the widget this component is attached to.\nDoes not affect gamepad controls.")]
43 protected bool m_bMustHoverOverContent;
45 [
Attribute(
desc:
"If content widget is UniformGridSlot, empty grid tiles will be filled with these layouts.\nIf there are more items than defined here, the last layout in the list will be used.\n\nWhen undefined, no filling will be performed.", uiwidget: UIWidgets.ResourceNamePicker,
params:
"layout")]
46 protected ref array<ResourceName> m_aEmptyItemLayouts;
48 [
Attribute(
desc:
"When enabled, going next from the last page will cycle back to the first page, and vice versa.")]
49 protected bool m_bLoop;
51 [
Attribute(
"1",
desc:
"When true it will hide the arrows instead of disabling them if the button is disabled.")]
52 protected bool m_bHideArrowsIfDisabled;
54 [
Attribute(
"0",
desc:
"When true always ignore gamepad input. Set this true if the widget is always on the screen and there is a seperate dialog version of it for the gamepad. Setting this true will make sure the next and prev focus buttons will have 'No Focus' enabled")]
55 protected bool m_bIgnoreGamePadInput;
57 [
Attribute(
"1",
desc:
"If true it will play the next and prev page audio on page change")]
58 protected bool m_bPlayAudioOnPageChange;
61 protected string m_sOnNextPageSfx;
64 protected string m_sOnPrevPageSfx;
66 protected int m_iCurrentPage;
67 protected bool m_bUnderCursor;
68 protected Widget m_ContentWidget, m_ButtonPrevWidget, m_ButtonNextWidget, m_FocusPrevWidget, m_FocusNextWidget, m_ButtonPrevNoScrollWidget, m_ButtonNextNoScrollWidget;
69 protected TextWidget m_PageNumberWidget;
70 protected ref ScriptInvoker m_OnPageChanged =
new ScriptInvoker();
71 protected int m_FocusedIndex[2];
81 protected void ShowEntries(Widget contentWidget,
int indexStart,
int indexEnd);
115 int GetEntryIndex(Widget w)
117 int row = UniformGridSlot.GetRow(w);
118 int column = UniformGridSlot.GetColumn(w);
119 return (
m_iCurrentPage * m_iRows * m_iColumns) + (row * m_iColumns + column);
124 ScriptInvoker GetOnPageChanged()
126 return m_OnPageChanged;
134 sealed
bool SetPage(
int page,
bool isRefresh =
false)
136 if (!m_ContentWidget)
140 int focusedRow = m_FocusedIndex[0];
141 int focusedColumn = m_FocusedIndex[1];
144 int pageCapacity = m_iRows * m_iColumns;
145 int countEntries = GetEntryCount();
146 int totalPages = Math.Ceil(countEntries / (m_iRows * m_iColumns));
147 if (totalPages > 0 && m_bLoop)
148 page = Math.Repeat(page, totalPages);
150 int indexStart = page * pageCapacity;
151 int indexEnd = Math.Min(indexStart + pageCapacity, countEntries);
152 if (indexStart < 0 || (countEntries > 0 && indexStart >= countEntries))
155 if (m_bPlayAudioOnPageChange && !isRefresh &&
m_iCurrentPage != page)
166 while (m_ContentWidget.GetChildren())
168 m_ContentWidget.GetChildren().RemoveFromHierarchy();
172 ShowEntries(m_ContentWidget, indexStart, indexEnd);
173 bool hasContent = m_ContentWidget.GetChildren() !=
null;
176 Widget focusedButton;
177 if (m_ContentWidget.GetTypeID() == WidgetType.UniformGridLayoutWidgetTypeID)
180 Widget child = m_ContentWidget.GetChildren();
183 UniformGridSlot.SetRow(child, row);
184 UniformGridSlot.SetColumn(child, column);
187 if (column == 0 && m_sFocusPrevName)
188 child.SetNavigation(WidgetNavigationDirection.LEFT, WidgetNavigationRuleType.EXPLICIT, m_sFocusPrevName);
190 if (column == m_iColumns - 1 && m_sFocusNextName)
191 child.SetNavigation(WidgetNavigationDirection.RIGHT, WidgetNavigationRuleType.EXPLICIT, m_sFocusNextName);
194 if (row == focusedRow && column == focusedColumn)
195 focusedButton =
SCR_WidgetTools.FindWidgetInChildren(child, WidgetType.ButtonWidgetTypeID);
197 IterateIndex(row, column);
198 child = child.GetSibling();
201 int minRows = m_iRows;
202 if (page == 0 && m_iMinRows >= 0)
203 minRows = Math.Max(m_iMinRows, row);
205 int minColumns = m_iColumns;
206 if (page == 0 && m_iMinColumns >= 0)
207 minColumns = Math.Max(m_iMinColumns, row);
210 int emptyItemsCount = m_aEmptyItemLayouts.Count() - 1;
211 while (row < minRows && column < minColumns)
213 if (m_aEmptyItemLayouts.IsEmpty())
215 emptyWidget =
GetGame().GetWorkspace().CreateWidget(WidgetType.ImageWidgetTypeID, WidgetFlags.VISIBLE | WidgetFlags.IGNORE_CURSOR | WidgetFlags.NOFOCUS,
new Color(0, 0, 0, 0), 0, m_ContentWidget);
219 int index = Math.Min(row * m_iColumns + column, emptyItemsCount);
220 emptyWidget =
GetGame().GetWorkspace().CreateWidgets(m_aEmptyItemLayouts[
index], m_ContentWidget);
223 UniformGridSlot.SetRow(emptyWidget, row);
224 UniformGridSlot.SetColumn(emptyWidget, column);
226 IterateIndex(row, column);
232 focusedButton = m_ContentWidget.GetChildren();
236 GetGame().GetWorkspace().SetFocusedWidget(focusedButton);
249 if (m_PageNumberWidget)
251 if (countEntries == 0)
253 m_PageNumberWidget.SetVisible(
false);
257 m_PageNumberWidget.SetTextFormat(m_sPageIndexVisualText,
m_iCurrentPage + 1, totalPages);
258 m_PageNumberWidget.SetVisible(
true);
263 bool canLoop = m_bLoop && totalPages > 1;
265 EnablePageButton(m_ButtonPrevWidget, canLoop || page > 0);
266 EnablePageButton(m_ButtonPrevNoScrollWidget, canLoop || page > 0);
268 EnablePageButton(m_ButtonNextWidget, canLoop || page < totalPages - 1);
269 EnablePageButton(m_ButtonNextNoScrollWidget, canLoop || page < totalPages - 1);
271 m_OnPageChanged.Invoke(page);
279 sealed
bool RefreshPage()
283 protected void IterateIndex(out
int row, out
int column)
286 if (column >= m_iColumns)
292 protected void EnablePageButton(Widget w,
bool enable)
297 if (m_bHideArrowsIfDisabled)
299 w.SetOpacity(enable);
306 buttonComponent.SetEnabled(enable);
308 w.SetEnabled(enable);
310 protected void OnButtonPrev()
315 if (m_bUnderCursor &&
GetMenu().IsFocused())
319 protected void OnButtonNext()
324 if (m_bUnderCursor &&
GetMenu().IsFocused())
328 protected void SetUnderCursor(
bool newUnderCursor)
330 m_bUnderCursor = newUnderCursor;
332 if (m_ButtonPrevNoScrollWidget && m_ButtonNextNoScrollWidget)
334 m_ButtonPrevWidget.SetVisible(m_bUnderCursor);
335 m_ButtonPrevNoScrollWidget.SetVisible(!m_bUnderCursor);
337 m_ButtonNextWidget.SetVisible(m_bUnderCursor);
338 m_ButtonNextNoScrollWidget.SetVisible(!m_bUnderCursor);
342 protected void OnInputDeviceIsGamepad(
bool isGamepad)
345 SetUnderCursor(isGamepad);
348 override protected bool IsUnique()
352 override bool OnFocus(Widget w,
int x,
int y)
354 if (w == m_FocusPrevWidget)
356 m_FocusedIndex[1] = m_iColumns - 1;
359 else if (w == m_FocusNextWidget)
361 m_FocusedIndex[1] = 0;
369 if (w.GetParent() == m_ContentWidget)
371 m_FocusedIndex[0] = UniformGridSlot.GetRow(w);
372 m_FocusedIndex[1] = UniformGridSlot.GetColumn(w);
381 override bool OnMouseEnter(Widget w,
int x,
int y)
383 if (m_bMustHoverOverContent)
386 if (w == m_ButtonPrevWidget || w == m_ButtonNextWidget)
388 SetUnderCursor(
true);
395 if (w == m_ContentWidget)
397 SetUnderCursor(
true);
405 SetUnderCursor(
true);
409 override bool OnMouseLeave(Widget w, Widget enterW,
int x,
int y)
411 SetUnderCursor(
false);
414 override void HandlerAttached(Widget w)
416 super.HandlerAttached(w);
421 m_ContentWidget = w.FindAnyWidget(m_sContentName);
423 m_PageNumberWidget = TextWidget.Cast(w.FindAnyWidget(m_sPageIndexVisualName));
425 m_ButtonPrevWidget = w.FindAnyWidget(m_sButtonPrevName);
426 m_ButtonNextWidget = w.FindAnyWidget(m_sButtonNextName);
428 m_ButtonPrevNoScrollWidget = w.FindAnyWidget(m_sButtonPrevName_NoScrolling);
429 m_ButtonNextNoScrollWidget = w.FindAnyWidget(m_sButtonNextName_NoScrolling);
431 m_FocusPrevWidget = w.FindAnyWidget(m_sFocusPrevName);
432 m_FocusNextWidget = w.FindAnyWidget(m_sFocusNextName);
434 if (m_bIgnoreGamePadInput)
436 if (m_FocusPrevWidget)
437 m_FocusPrevWidget.SetFlags(WidgetFlags.NOFOCUS);
438 if (m_FocusNextWidget)
439 m_FocusNextWidget.SetFlags(WidgetFlags.NOFOCUS);
441 if (m_ButtonPrevWidget)
442 m_ButtonPrevWidget.SetFlags(WidgetFlags.NOFOCUS);
443 if (m_ButtonNextWidget)
444 m_ButtonNextWidget.SetFlags(WidgetFlags.NOFOCUS);
446 if (m_ButtonPrevNoScrollWidget)
447 m_ButtonPrevNoScrollWidget.SetFlags(WidgetFlags.NOFOCUS);
448 if (m_ButtonNextNoScrollWidget)
449 m_ButtonNextNoScrollWidget.SetFlags(WidgetFlags.NOFOCUS);
453 if (prevButtonComponent)
454 prevButtonComponent.m_OnActivated.Insert(OnButtonPrev);
459 if (nextButtonComponent)
460 nextButtonComponent.m_OnActivated.Insert(OnButtonNext);
464 if (m_ButtonPrevNoScrollWidget)
467 if (prevButtonComponent)
468 prevButtonComponent.m_OnActivated.Insert(OnButtonPrev);
473 if (m_ButtonNextNoScrollWidget)
476 if (nextButtonComponent)
477 nextButtonComponent.m_OnActivated.Insert(OnButtonNext);
483 GetGame().OnInputDeviceIsGamepadInvoker().Insert(OnInputDeviceIsGamepad);
487 override void HandlerDeattached(Widget w)
489 super.HandlerDeattached(w);
492 GetGame().OnInputDeviceIsGamepadInvoker().Remove(OnInputDeviceIsGamepad);