806 lines
17 KiB
ActionScript
806 lines
17 KiB
ActionScript
import elements.BaseGuiElement;
|
|
import elements.GuiScrollbar;
|
|
import elements.GuiMarkupText;
|
|
|
|
export GuiListElement, GuiListText, GuiListbox;
|
|
export GuiMarkupListText;
|
|
|
|
class GuiListElement {
|
|
void set(const string& txt) {
|
|
throw("Setting item text on a non-textual list element.");
|
|
}
|
|
|
|
string get() {
|
|
return "";
|
|
}
|
|
|
|
string get_tooltipText() {
|
|
return "";
|
|
}
|
|
|
|
ITooltip@ get_tooltip() {
|
|
return null;
|
|
}
|
|
|
|
bool get_isSelectable() {
|
|
return true;
|
|
}
|
|
|
|
bool onMouseEvent(const MouseEvent& event) {
|
|
return false;
|
|
}
|
|
|
|
void onSelect() {
|
|
}
|
|
|
|
void draw(GuiListbox@ ele, uint flags, const recti& absPos) {
|
|
}
|
|
|
|
int opCmp(const GuiListElement@ other) const {
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
class GuiListText : GuiListElement {
|
|
string text;
|
|
Sprite icon;
|
|
|
|
GuiListText(const string& txt, const Sprite& icon = Sprite()) {
|
|
text = txt;
|
|
this.icon = icon;
|
|
}
|
|
|
|
void set(const string& txt) {
|
|
text = txt;
|
|
}
|
|
|
|
string get() {
|
|
return text;
|
|
}
|
|
|
|
void draw(GuiListbox@ ele, uint flags, const recti& absPos) {
|
|
const Font@ font = ele.skin.getFont(ele.TextFont);
|
|
int baseLine = font.getBaseline();
|
|
vec2i textOffset(ele.horizPadding, (absPos.size.height - baseLine) / 2);
|
|
|
|
if(ele.itemStyle == SS_NULL)
|
|
ele.skin.draw(SS_ListboxItem, flags, absPos);
|
|
|
|
if(icon.valid) {
|
|
vec2i iconSize = icon.size;
|
|
if(iconSize.y > absPos.height) {
|
|
iconSize.x = double(absPos.height) / double(iconSize.y) * double(iconSize.x);
|
|
iconSize.y = absPos.height;
|
|
}
|
|
vec2i iconOffset(ele.horizPadding, (absPos.height - iconSize.height) / 2);
|
|
icon.draw(recti_area(absPos.topLeft + iconOffset, iconSize));
|
|
textOffset.x += iconSize.width + 8;
|
|
}
|
|
|
|
font.draw(absPos.topLeft + textOffset, text);
|
|
}
|
|
};
|
|
|
|
class GuiMarkupListText : GuiListElement {
|
|
string text;
|
|
string basicText;
|
|
MarkupRenderer renderer;
|
|
|
|
GuiMarkupListText(const string& txt, FontType font = FT_Normal) {
|
|
text = txt;
|
|
renderer.parseTree(txt);
|
|
renderer.defaultFont = font;
|
|
}
|
|
|
|
void set(const string& txt) {
|
|
text = txt;
|
|
renderer.parseTree(txt);
|
|
}
|
|
|
|
string get() {
|
|
return basicText.length == 0 ? text : basicText;
|
|
}
|
|
|
|
void draw(GuiListbox@ ele, uint flags, const recti& absPos) {
|
|
if(ele.itemStyle == SS_NULL)
|
|
ele.skin.draw(SS_ListboxItem, flags, absPos);
|
|
renderer.draw(ele.skin, absPos.padded(ele.horizPadding, ele.vertPadding));
|
|
}
|
|
};
|
|
|
|
class GuiListbox : BaseGuiElement {
|
|
FontType TextFont = FT_Normal;
|
|
|
|
GuiListElement@[] items;
|
|
int selected = -1;
|
|
int hovered = -1;
|
|
int lineHeight = 0;
|
|
int horizPadding = 6;
|
|
int vertPadding = 5;
|
|
bool Required = false;
|
|
bool hoverSelect = false;
|
|
bool ElementHovered = false;
|
|
bool ElementFocused = false;
|
|
|
|
bool Multiple = false;
|
|
bool autoMultiple = true;
|
|
bool[] SelectedItems;
|
|
bool DblClickConfirm = true;
|
|
int SelectedCount = 0;
|
|
int PrevSelected = -1;
|
|
int itemHeight = -1;
|
|
bool disabled = false;
|
|
|
|
string search;
|
|
double searchTime = 0;
|
|
double doubleTime = 0;
|
|
|
|
SkinStyle style = SS_Listbox;
|
|
SkinStyle itemStyle = SS_NULL;
|
|
|
|
GuiScrollbar@ scroll;
|
|
|
|
GuiListbox(IGuiElement@ ParentElement, const recti& Rectangle) {
|
|
_GuiListbox();
|
|
super(ParentElement, Rectangle);
|
|
@scroll.parent = this;
|
|
}
|
|
|
|
GuiListbox(IGuiElement@ ParentElement, Alignment@ Align) {
|
|
_GuiListbox();
|
|
super(ParentElement, Align);
|
|
@scroll.parent = this;
|
|
}
|
|
|
|
void sortAsc() {
|
|
items.sortAsc();
|
|
}
|
|
|
|
void sortDesc() {
|
|
items.sortDesc();
|
|
}
|
|
|
|
void scrollToEnd() {
|
|
scroll.pos = max(0.0, scroll.end - scroll.page);
|
|
}
|
|
|
|
void _GuiListbox() {
|
|
@scroll = GuiScrollbar(null, recti());
|
|
scroll.alignment.set(
|
|
AS_Right, 0.0, 20, AS_Top, 0.0, 0,
|
|
AS_Right, 0.0, 0, AS_Bottom, 0.0, 0);
|
|
}
|
|
|
|
void addItem(GuiListElement@ elem, uint where) {
|
|
items.insertAt(where, elem);
|
|
|
|
if(multiple) {
|
|
if(Required && SelectedCount <= 0) {
|
|
SelectedItems.insertLast(true);
|
|
SelectedCount = 1;
|
|
}
|
|
else
|
|
SelectedItems.insertLast(false);
|
|
}
|
|
else if(Required && selected == -1) {
|
|
selected = 0;
|
|
}
|
|
|
|
updateAbsolutePosition();
|
|
}
|
|
|
|
void addItem(GuiListElement@ elem) {
|
|
addItem(elem, items.length);
|
|
}
|
|
|
|
void addItem(const string& item, uint where) {
|
|
addItem(GuiListText(item), where);
|
|
}
|
|
|
|
void addItem(const string& item) {
|
|
addItem(GuiListText(item), items.length);
|
|
}
|
|
|
|
void removeItem(uint index) {
|
|
if(index < items.length()) {
|
|
items.removeAt(index);
|
|
|
|
if(multiple) {
|
|
if(SelectedItems[index])
|
|
SelectedCount -= 1;
|
|
SelectedItems.removeAt(index);
|
|
}
|
|
else {
|
|
if(selected >= int(items.length()))
|
|
selected = items.length() - 1;
|
|
}
|
|
}
|
|
|
|
updateAbsolutePosition();
|
|
}
|
|
|
|
void removeItemsFrom(uint index) {
|
|
if(items.length > index)
|
|
items.length = index;
|
|
if(selected > 0 && selected >= int(index))
|
|
selected = index - 1;
|
|
updateAbsolutePosition();
|
|
}
|
|
|
|
void clearItems() {
|
|
SelectedItems.length = 0;
|
|
items.length = 0;
|
|
selected = -1;
|
|
hovered = -1;
|
|
if(Tooltip !is null)
|
|
Tooltip.update(skin, this);
|
|
updateAbsolutePosition();
|
|
}
|
|
|
|
void setItem(uint index, const string& item) {
|
|
if(index < items.length())
|
|
items[index].set(item);
|
|
else
|
|
addItem(item);
|
|
}
|
|
|
|
void setItem(uint index, GuiListElement@ elem) {
|
|
if(index < items.length())
|
|
@items[index] = elem;
|
|
else
|
|
addItem(elem);
|
|
}
|
|
|
|
string getItem(uint index) {
|
|
if(index < items.length())
|
|
return items[index].get();
|
|
return "";
|
|
}
|
|
|
|
GuiListElement@ getItemElement(uint index) {
|
|
if(index < items.length())
|
|
return items[index];
|
|
return null;
|
|
}
|
|
|
|
GuiListElement@ get_selectedItem() {
|
|
if(selected == -1 || Multiple)
|
|
return null;
|
|
return items[selected];
|
|
}
|
|
|
|
GuiListElement@ get_hoveredItem() {
|
|
if(hovered == -1)
|
|
return null;
|
|
return items[hovered];
|
|
}
|
|
|
|
uint get_itemCount() {
|
|
return items.length();
|
|
}
|
|
|
|
bool isSelected(uint index) {
|
|
if(index >= items.length())
|
|
return false;
|
|
|
|
if(multiple)
|
|
return SelectedItems[index];
|
|
else
|
|
return int(index) == selected;
|
|
}
|
|
|
|
uint get_selectedCount() {
|
|
if(multiple)
|
|
return SelectedCount;
|
|
else
|
|
return selected == -1 ? 0 : 1;
|
|
}
|
|
|
|
void clearSelection() {
|
|
if(multiple) {
|
|
for(uint i = 0, cnt = items.length(); i < cnt; ++i)
|
|
SelectedItems[i] = false;
|
|
|
|
if(Required && SelectedItems.length() > 0) {
|
|
SelectedCount = 1;
|
|
SelectedItems[0] = true;
|
|
}
|
|
else {
|
|
SelectedCount = 0;
|
|
}
|
|
}
|
|
else {
|
|
selected = -1;
|
|
}
|
|
}
|
|
|
|
ITooltip@ get_tooltipObject() {
|
|
if(hovered >= 0 && hovered < int(items.length)) {
|
|
ITooltip@ tt = items[hovered].tooltip;
|
|
if(tt !is null)
|
|
return tt;
|
|
}
|
|
return Tooltip;
|
|
}
|
|
|
|
string get_tooltip() {
|
|
if(hovered != -1 && uint(hovered) < items.length) {
|
|
string tt = items[hovered].tooltipText;
|
|
if(tt.length != 0)
|
|
return tt;
|
|
}
|
|
return BaseGuiElement::get_tooltip();
|
|
}
|
|
|
|
void set_multiple(bool mult) {
|
|
if(Multiple == mult)
|
|
return;
|
|
Multiple = mult;
|
|
|
|
if(Multiple) {
|
|
SelectedItems.resize(items.length());
|
|
for(uint i = 0, cnt = items.length(); i < cnt; ++i)
|
|
SelectedItems[i] = false;
|
|
|
|
if(selected != -1) {
|
|
SelectedItems[selected] = true;
|
|
SelectedCount = 1;
|
|
}
|
|
else {
|
|
if(Required && SelectedItems.length() > 0) {
|
|
SelectedItems[0] = true;
|
|
SelectedCount = 1;
|
|
}
|
|
else {
|
|
SelectedCount = 0;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
SelectedItems.resize(0);
|
|
|
|
if(Required && items.length() > 0)
|
|
selected = 0;
|
|
else
|
|
selected = -1;
|
|
}
|
|
}
|
|
|
|
bool get_multiple() {
|
|
return Multiple;
|
|
}
|
|
|
|
void set_font(FontType type) {
|
|
if(TextFont == type)
|
|
return;
|
|
TextFont = type;
|
|
updateAbsolutePosition();
|
|
}
|
|
|
|
FontType get_font() const {
|
|
return TextFont;
|
|
}
|
|
|
|
void set_required(bool req) {
|
|
Required = req;
|
|
|
|
if(Required) {
|
|
if(Multiple) {
|
|
if(SelectedCount <= 0 && items.length() > 0) {
|
|
SelectedCount = 1;
|
|
SelectedItems[0] = true;
|
|
}
|
|
}
|
|
else {
|
|
if(selected == -1 && items.length() > 0)
|
|
selected = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool get_required() const {
|
|
return Required;
|
|
}
|
|
|
|
void emitChange() {
|
|
GuiEvent evt;
|
|
evt.type = GUI_Changed;
|
|
@evt.caller = this;
|
|
onGuiEvent(evt);
|
|
}
|
|
|
|
bool onGuiEvent(const GuiEvent& event) {
|
|
if(event.caller is this) {
|
|
switch(event.type) {
|
|
case GUI_Mouse_Entered:
|
|
ElementHovered = true;
|
|
break;
|
|
case GUI_Mouse_Left:
|
|
ElementHovered = false;
|
|
break;
|
|
case GUI_Focused:
|
|
ElementFocused = true;
|
|
break;
|
|
case GUI_Focus_Lost:
|
|
ElementFocused = false;
|
|
break;
|
|
}
|
|
}
|
|
return BaseGuiElement::onGuiEvent(event);
|
|
}
|
|
|
|
void updateHover() {
|
|
vec2i offset = mousePos - AbsolutePosition.topLeft;
|
|
int prevHovered = hovered;
|
|
hovered = getOffsetItem(offset);
|
|
|
|
if(prevHovered != hovered)
|
|
emitHoverChanged(hovered);
|
|
if(hovered != prevHovered && Tooltip !is null)
|
|
Tooltip.update(skin, this);
|
|
if(hoverSelect && hovered >= 0 && !disabled)
|
|
selected = hovered;
|
|
}
|
|
|
|
bool onMouseEvent(const MouseEvent& event, IGuiElement@ source) {
|
|
if(source is this) {
|
|
updateHover();
|
|
if(hovered >= 0 && items[hovered].onMouseEvent(event))
|
|
return true;
|
|
|
|
switch(event.type) {
|
|
case MET_Button_Down:
|
|
if(event.button == 0)
|
|
return true;
|
|
break;
|
|
case MET_Button_Up: {
|
|
if(disabled)
|
|
return true;
|
|
if(hoverSelect || !ElementFocused || event.button != 0)
|
|
break;
|
|
|
|
bool wasConfirmation = false;
|
|
if(hovered == -1 || !items[hovered].isSelectable) {
|
|
if(!Required)
|
|
clearSelection();
|
|
}
|
|
else if(Multiple) {
|
|
if(shiftKey && PrevSelected != -1) {
|
|
int from = PrevSelected <= hovered ? PrevSelected : hovered;
|
|
int to = PrevSelected > hovered ? PrevSelected : hovered;
|
|
|
|
bool doSelected = SelectedItems[PrevSelected];
|
|
|
|
for(int i = from; i <= to; ++i) {
|
|
if(doSelected) {
|
|
if(!SelectedItems[i]) {
|
|
SelectedItems[i] = true;
|
|
SelectedCount += 1;
|
|
}
|
|
}
|
|
else {
|
|
if(SelectedItems[i] && (!Required || SelectedCount > 1)) {
|
|
SelectedItems[i] = false;
|
|
SelectedCount -= 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
PrevSelected = hovered;
|
|
|
|
if(SelectedItems[hovered]) {
|
|
if(!ctrlKey && DblClickConfirm && frameTime < doubleTime + double(settings::iDoubleClickMS) * 0.001) {
|
|
wasConfirmation = true;
|
|
emitConfirmed(hovered);
|
|
doubleTime = -INFINITY;
|
|
}
|
|
else if(ctrlKey || autoMultiple) {
|
|
if(!Required || SelectedCount > 1) {
|
|
SelectedItems[hovered] = false;
|
|
SelectedCount -= 1;
|
|
}
|
|
}
|
|
else {
|
|
for(uint i = 0, cnt = items.length(); i < cnt; ++i)
|
|
SelectedItems[i] = false;
|
|
|
|
if(Required || SelectedCount > 1) {
|
|
SelectedItems[hovered] = true;
|
|
SelectedCount = 1;
|
|
}
|
|
else {
|
|
SelectedCount = 0;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if(ctrlKey || autoMultiple) {
|
|
SelectedItems[hovered] = true;
|
|
SelectedCount += 1;
|
|
doubleTime = frameTime;
|
|
}
|
|
else {
|
|
for(uint i = 0, cnt = items.length(); i < cnt; ++i)
|
|
SelectedItems[i] = false;
|
|
SelectedItems[hovered] = true;
|
|
SelectedCount = 1;
|
|
doubleTime = frameTime;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if(selected == hovered && DblClickConfirm && frameTime < doubleTime + double(settings::iDoubleClickMS) * 0.001) {
|
|
wasConfirmation = true;
|
|
emitConfirmed(hovered);
|
|
doubleTime = -INFINITY;
|
|
}
|
|
else if(selected == hovered && !Required)
|
|
selected = -1;
|
|
else if(!Required || hovered != -1)
|
|
selected = hovered;
|
|
}
|
|
|
|
if(!wasConfirmation)
|
|
doubleTime = frameTime;
|
|
|
|
if(selected >= 0 && !wasConfirmation)
|
|
items[selected].onSelect();
|
|
|
|
emitChange();
|
|
} return true;
|
|
case MET_Scrolled:
|
|
if(scroll.visible)
|
|
return scroll.onMouseEvent(event, scroll);
|
|
break;
|
|
}
|
|
}
|
|
return BaseGuiElement::onMouseEvent(event, source);
|
|
}
|
|
|
|
void nextItem() {
|
|
if(selected >= 0 && selected < int(items.length()) - 1) {
|
|
selected += 1;
|
|
|
|
if((selected + 1) * lineHeight - scroll.pos >= AbsolutePosition.height)
|
|
scroll.pos = min(scroll.end - scroll.page, scroll.pos + lineHeight);
|
|
}
|
|
}
|
|
|
|
void prevItem() {
|
|
if(selected > 0) {
|
|
selected -= 1;
|
|
|
|
if(selected * lineHeight - scroll.pos < 0)
|
|
scroll.pos = max(0.0, scroll.pos - lineHeight);
|
|
}
|
|
}
|
|
|
|
void updateScroll() {
|
|
if(selected * lineHeight - scroll.pos < 0)
|
|
scroll.pos = max(0.0, double(selected * lineHeight));
|
|
else if((selected + 1) * lineHeight - scroll.pos >= AbsolutePosition.height)
|
|
scroll.pos = min(scroll.end - scroll.page, double(selected * lineHeight));
|
|
}
|
|
|
|
void doSearch() {
|
|
searchTime = frameTime;
|
|
|
|
uint start = selected == -1 ? 0 : uint(selected);
|
|
int found = -1;
|
|
for(uint i = 0, cnt = items.length; i < cnt; ++i) {
|
|
int index = int((start + i) % cnt);
|
|
string text = items[index].get();
|
|
if(text.length == 0)
|
|
continue;
|
|
if(text.startswith_nocase(search)) {
|
|
found = index;
|
|
break;
|
|
}
|
|
}
|
|
if(found != -1 && selected != found) {
|
|
selected = found;
|
|
emitChange();
|
|
updateScroll();
|
|
}
|
|
}
|
|
|
|
bool onKeyEvent(const KeyboardEvent& event, IGuiElement@ source) {
|
|
if(source is this) {
|
|
if(!Multiple) {
|
|
if(event.type == KET_Key_Down) {
|
|
int pageItems = ceil(double(AbsolutePosition.height) / double(lineHeight));
|
|
|
|
switch(event.key) {
|
|
case KEY_UP:
|
|
if(!disabled)
|
|
prevItem();
|
|
return true;
|
|
case KEY_DOWN:
|
|
if(!disabled)
|
|
nextItem();
|
|
return true;
|
|
case KEY_ENTER:
|
|
return true;
|
|
case KEY_PAGEUP:
|
|
if(selected > 0) {
|
|
if(disabled)
|
|
return true;
|
|
selected = max(0, selected - pageItems);
|
|
scroll.pos = max(0.0, scroll.pos - AbsolutePosition.height);
|
|
return true;
|
|
}
|
|
break;
|
|
case KEY_PAGEDOWN:
|
|
if(selected >= 0) {
|
|
if(disabled)
|
|
return true;
|
|
selected = min(items.length() - 1, selected + pageItems);
|
|
scroll.pos = min(scroll.end - scroll.page, scroll.pos + AbsolutePosition.height);
|
|
return true;
|
|
}
|
|
break;
|
|
case KEY_BACKSPACE: {
|
|
if(disabled)
|
|
return true;
|
|
int len = search.length;
|
|
int curs = len;
|
|
int prevPos = len;
|
|
int tmp = 0;
|
|
if(prevPos == 0)
|
|
return true;
|
|
u8prev(search, prevPos, tmp);
|
|
string newText;
|
|
if(prevPos > 0)
|
|
newText += search.substr(0, prevPos);
|
|
if(len - curs > 0)
|
|
newText += search.substr(curs, len - curs);
|
|
search = newText;
|
|
doSearch();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
else if(event.type == KET_Key_Up) {
|
|
switch(event.key) {
|
|
case KEY_UP:
|
|
return true;
|
|
case KEY_DOWN:
|
|
return true;
|
|
case KEY_ENTER:
|
|
emitChange();
|
|
emitConfirmed();
|
|
return true;
|
|
case KEY_PAGEUP:
|
|
if(selected > 0)
|
|
return true;
|
|
break;
|
|
case KEY_PAGEDOWN:
|
|
if(selected >= 0)
|
|
return true;
|
|
break;
|
|
case KEY_BACKSPACE:
|
|
return true;
|
|
}
|
|
}
|
|
else if(event.type == KET_Key_Typed) {
|
|
if(disabled)
|
|
return true;
|
|
if(searchTime < frameTime - 0.5)
|
|
search = "";
|
|
|
|
u8append(search, event.key);
|
|
doSearch();
|
|
return true;
|
|
}
|
|
}
|
|
return scroll.onKeyEvent(event, scroll);
|
|
}
|
|
return BaseGuiElement::onKeyEvent(event, source);
|
|
}
|
|
|
|
void updateAbsolutePosition() {
|
|
BaseGuiElement::updateAbsolutePosition();
|
|
|
|
if(skin is null)
|
|
return;
|
|
|
|
const Font@ font = skin.getFont(TextFont);
|
|
|
|
if(itemHeight == -1)
|
|
lineHeight = font.getLineHeight() + vertPadding * 2;
|
|
else
|
|
lineHeight = itemHeight;
|
|
scroll.scroll = lineHeight * 2;
|
|
|
|
scroll.page = AbsolutePosition.height;
|
|
scroll.bar = scroll.page;
|
|
scroll.end = lineHeight * items.length();
|
|
scroll.pos = max(0.0, min(scroll.end - scroll.page, scroll.pos));
|
|
scroll.visible = scroll.end > scroll.page;
|
|
scroll.updateAbsolutePosition();
|
|
}
|
|
|
|
vec2i get_desiredSize() const {
|
|
return vec2i(size.width, lineHeight * items.length);
|
|
}
|
|
|
|
int getOffsetItem(const vec2i& offset) {
|
|
if(offset.x < 0 || offset.x > AbsolutePosition.width)
|
|
return -1;
|
|
|
|
int item = floor(double(offset.y + scroll.pos) / double(lineHeight));
|
|
|
|
if(item < 0 || item >= int(items.length()))
|
|
return -1;
|
|
else
|
|
return item;
|
|
}
|
|
|
|
vec2i getItemOffset(int item) {
|
|
if(item < 0 || item >= int(items.length))
|
|
return vec2i();
|
|
return vec2i(0, (item * lineHeight) - int(scroll.pos));
|
|
}
|
|
|
|
void draw() {
|
|
//Draw element background
|
|
uint flags = SF_Normal;
|
|
if(ElementHovered)
|
|
flags |= SF_Hovered;
|
|
if(ElementFocused)
|
|
flags |= SF_Focused;
|
|
if(disabled)
|
|
flags |= SF_Disabled;
|
|
skin.draw(style, SF_Normal, AbsoluteClipRect);
|
|
|
|
//Draw items
|
|
int itemWidth = AbsolutePosition.width;
|
|
|
|
if(scroll.visible)
|
|
itemWidth -= 20;
|
|
|
|
recti itemPos = recti_area(
|
|
AbsolutePosition.topLeft - vec2i(0, scroll.pos),
|
|
vec2i(itemWidth, lineHeight));
|
|
|
|
for(uint i = 0, cnt = items.length(); i < cnt; ++i) {
|
|
//Don't display completely invisible items
|
|
if(itemPos.botRight.y < AbsolutePosition.topLeft.y) {
|
|
itemPos += vec2i(0, lineHeight);
|
|
continue;
|
|
}
|
|
|
|
if(itemPos.topLeft.y > AbsolutePosition.botRight.y)
|
|
break;
|
|
|
|
//Figure correct style to use
|
|
uint itFlags = SF_Normal;
|
|
if(items[i].isSelectable) {
|
|
if(int(i) == hovered && !disabled) {
|
|
if(ElementHovered)
|
|
itFlags |= SF_Hovered;
|
|
if(ElementFocused)
|
|
itFlags |= SF_Focused;
|
|
}
|
|
if(Multiple) {
|
|
if(SelectedItems[i])
|
|
itFlags |= SF_Active;
|
|
}
|
|
else if(int(i) == selected) {
|
|
itFlags |= SF_Active;
|
|
}
|
|
}
|
|
|
|
//Draw item
|
|
if(itemStyle != SS_NULL)
|
|
skin.draw(itemStyle, itFlags, itemPos);
|
|
items[i].draw(this, itFlags, itemPos);
|
|
itemPos += vec2i(0, lineHeight);
|
|
}
|
|
|
|
BaseGuiElement::draw();
|
|
}
|
|
};
|