ddnet/src/game/client/ui_listbox.h
Robert Müller 91a23f00cb Port CListBox from upstream, smooth scrolling for all lists
Replace existing listbox implementations (`CMenus::UiDoListbox*` and `HandleListInputs` functions) with `CListBox` from upstream.

Reimplement additional feature that was already present in ddnet: page up/down, home and end key handling.

Affects the following lists:

- server browser
- server browser scoreboard
- server browser friends
- country / region selection popup (server browser filter)
- player skin list
- player country / region list
- theme list
- assets list
- graphics resolutions list
- dropdown menus (e.g. graphics fullscreen mode)
- ingame player list
- vote options list
- kick/specvote lists
- ghost list
- language list (in settings and in popup on first launch)
- demo browser
- editor file browser (saving, loading, adding images / sounds)
  - The search / filename input is also improved so navigating a filtered list works correctly by porting the logic from upstream.

There are minor changes to the visual appearance of some lists, due to changed margins.

The vertical alignment of some list item texts is improved so the text is centered vertically.
2023-01-06 12:46:16 +01:00

69 lines
2.4 KiB
C++

/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#ifndef GAME_CLIENT_UI_LISTBOX_H
#define GAME_CLIENT_UI_LISTBOX_H
#include "ui_scrollregion.h"
struct CListboxItem
{
bool m_Visible;
bool m_Selected;
CUIRect m_Rect;
};
// Instances of CListBox must be static, as member addresses are used as UI item IDs
class CListBox : private CUIElementBase
{
private:
CUIRect m_ListBoxView;
CUIRect m_RowView;
float m_ListBoxRowHeight;
int m_ListBoxItemIndex;
int m_ListBoxSelectedIndex;
int m_ListBoxNewSelected;
int m_ListBoxNewSelOffset;
bool m_ListBoxUpdateScroll;
bool m_ListBoxDoneEvents;
int m_ListBoxNumItems;
int m_ListBoxItemsPerRow;
bool m_ListBoxItemSelected;
bool m_ListBoxItemActivated;
bool m_ScrollbarIsShown;
const char *m_pBottomText;
float m_FooterHeight;
float m_AutoSpacing;
CScrollRegion m_ScrollRegion;
vec2 m_ScrollOffset;
char m_aFilterString[128];
float m_FilterOffset;
int m_BackgroundCorners;
bool m_HasHeader;
protected:
CListboxItem DoNextRow();
public:
CListBox();
void DoBegin(const CUIRect *pRect);
void DoHeader(const CUIRect *pRect, const char *pTitle, float HeaderHeight = 20.0f, float Spacing = 2.0f);
void DoAutoSpacing(float Spacing = 20.0f) { m_AutoSpacing = Spacing; }
void DoSpacing(float Spacing = 20.0f);
bool DoFilter(float FilterHeight = 20.0f, float Spacing = 2.0f);
void DoFooter(const char *pBottomText, float FooterHeight = 20.0f); // call before DoStart to create a footer
void DoStart(float RowHeight, int NumItems, int ItemsPerRow, int RowsPerScroll, int SelectedIndex, const CUIRect *pRect = nullptr, bool Background = true, bool *pActive = nullptr, int BackgroundCorners = IGraphics::CORNER_ALL);
void ScrollToSelected() { m_ListBoxUpdateScroll = true; }
CListboxItem DoNextItem(const void *pID, bool Selected = false, bool *pActive = nullptr);
CListboxItem DoSubheader();
int DoEnd();
bool FilterMatches(const char *pNeedle) const;
bool WasItemSelected() const { return m_ListBoxItemSelected; }
bool WasItemActivated() const { return m_ListBoxItemActivated; }
bool ScrollbarIsShown() const { return m_ScrollbarIsShown; }
float ScrollbarWidth() const { return ScrollbarIsShown() ? ScrollbarWidthMax() : 0.0f; }
float ScrollbarWidthMax() const { return 20.0f; }
};
#endif