/* =========================================================================== Copyright (C) 2015 the OpenMoHAA team This file is part of OpenMoHAA source code. OpenMoHAA source code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. OpenMoHAA source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenMoHAA source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ #include "ui_local.h" CLASS_DECLARATION(UIWidget, UIListBase, NULL) { {NULL, NULL} }; UIListBase::UIListBase() { m_currentItem = 0; m_vertscroll = 0; m_bUseVertScroll = 1; AllowActivate(true); } void UIListBase::TrySelectItem(int which) { int numitems; numitems = getNumItems(); if (!numitems) { m_currentItem = 0; return; } if (m_currentItem != which) { int previous = m_currentItem; m_currentItem = which; if (which > numitems) { m_currentItem = numitems; } if (m_currentItem <= 0) { m_currentItem = 1; } if (previous != m_currentItem) { Event ev(EV_UIListBase_ItemSelected); ev.AddInteger(m_currentItem); SendSignal(ev); } } if (m_vertscroll) { if (m_currentItem < m_vertscroll->getTopItem() + 1) { if (m_currentItem - 1 >= 0) { m_vertscroll->setTopItem(m_currentItem - 1); } else { m_vertscroll->setTopItem(0); } } if (m_currentItem >= m_vertscroll->getTopItem() + m_vertscroll->getPageHeight() + 1) { if (m_currentItem - m_vertscroll->getPageHeight() >= 0) { m_vertscroll->setTopItem(m_currentItem - m_vertscroll->getPageHeight()); } else { m_vertscroll->setTopItem(0); } } } } qboolean UIListBase::KeyEvent(int key, unsigned int time) { int offsetitem; qboolean key_rec; int itemindex; offsetitem = 0; key_rec = qfalse; switch (key) { case K_UPARROW: case K_LEFTARROW: offsetitem = -1; key_rec = qtrue; break; case K_DOWNARROW: case K_RIGHTARROW: offsetitem = 1; key_rec = qtrue; break; case K_PGDN: if (GetScrollBar()) { itemindex = GetScrollBar()->getTopItem() + GetScrollBar()->getPageHeight(); if (getCurrentItem() == itemindex) { offsetitem = GetScrollBar()->getPageHeight(); } else { TrySelectItem(itemindex); } } key_rec = qtrue; break; case K_PGUP: if (GetScrollBar()) { if (getCurrentItem() - 1 == GetScrollBar()->getTopItem()) { offsetitem = -GetScrollBar()->getPageHeight(); } else { TrySelectItem(GetScrollBar()->getTopItem() + 1); } } key_rec = qtrue; break; case K_HOME: TrySelectItem(1); key_rec = qtrue; break; case K_END: TrySelectItem(getNumItems()); key_rec = qtrue; break; case K_MWHEELDOWN: if (GetScrollBar()) { GetScrollBar()->AttemptScrollTo(GetScrollBar()->getTopItem() + 2); } key_rec = qtrue; break; case K_MWHEELUP: if (GetScrollBar()) { GetScrollBar()->AttemptScrollTo(GetScrollBar()->getTopItem() - 2); } key_rec = qtrue; break; default: break; } if (offsetitem) { TrySelectItem(getCurrentItem() + offsetitem); } return key_rec; } void UIListBase::FrameInitialized(void) { if (m_vertscroll) { delete m_vertscroll; } m_vertscroll = new UIVertScroll(); m_vertscroll->InitFrame(this, m_frame.size.width - 16.0, 0.0, 16.0, m_frame.size.height, -1); m_vertscroll->setTopItem(0); } int UIListBase::getCurrentItem(void) { return m_currentItem; } int UIListBase::getNumItems(void) { return -1; } void UIListBase::DeleteAllItems(void) {} void UIListBase::DeleteItem(int which) {} UIVertScroll *UIListBase::GetScrollBar(void) { return m_vertscroll; } void UIListBase::SetUseScrollBar(qboolean bUse) { m_bUseVertScroll = bUse; if (bUse) { if (!m_vertscroll) { m_vertscroll = new UIVertScroll(); } m_vertscroll->InitFrame(this, m_frame.size.width - 16.0, 0.0, 16.0, m_frame.size.height, -1); } else { if (m_vertscroll) { delete m_vertscroll; m_vertscroll = NULL; } } } ListItem::ListItem() { index = -1; } ListItem::ListItem(str string, int index, str command) { this->string = string; this->index = index; this->command = command; } Event EV_UIListBase_ItemSelected("listbase_item_selected", EV_DEFAULT, "i", "index", "Signaled when an item is selected"); Event EV_UIListBase_ItemDoubleClicked( "listbase_item_doubleclicked", EV_DEFAULT, "i", "index", "Signaled when an item is double clicked" ); Event EV_Layout_AddListItem("additem", EV_DEFAULT, "sS", "itemname command", "Add an item to the list"); Event EV_Layout_AddConfigstringListItem( "addconfigstringitem", EV_DEFAULT, "iS", "index command", "Add an item to the list that uses a configstring" ); Event EV_UIListBox_DeleteAllItems("deleteallitems", EV_DEFAULT, NULL, NULL, "Delete all the items from the widget"); CLASS_DECLARATION(UIListBase, UIListBox, NULL) { {&W_LeftMouseDown, &UIListBox::MousePressed }, {&W_LeftMouseUp, &UIListBox::MouseReleased }, {&EV_Layout_AddListItem, &UIListBox::LayoutAddListItem }, {&EV_Layout_AddConfigstringListItem, &UIListBox::LayoutAddConfigstringListItem}, {&EV_UIListBox_DeleteAllItems, &UIListBox::DeleteAllItems }, {&EV_Layout_Font, &UIListBox::SetListFont }, {NULL, NULL } }; UIListBox::UIListBox() { m_clickState.point.x = 0.0; m_clickState.point.y = 0.0; } void UIListBox::Draw(void) { // FIXME: stub } void UIListBox::MousePressed(Event *ev) { // FIXME: stub } void UIListBox::MouseReleased(Event *ev) {} void UIListBox::DeleteAllItems(Event *ev) { m_itemlist.ClearObjectList(); m_currentItem = 0; if (m_vertscroll) { m_vertscroll->setNumItems(0); m_vertscroll->setTopItem(0); } } void UIListBox::SetListFont(Event *ev) { LayoutFont(ev); if (m_vertscroll) { m_vertscroll->setPageHeight(m_frame.size.height / m_font->getHeight(m_bVirtual)); } FrameInitialized(); } void UIListBox::TrySelectItem(int which) { UIListBase::TrySelectItem(which); if (!getNumItems()) { return; } if (m_cvarname.length()) { uii.Cvar_Set(m_cvarname.c_str(), m_itemlist.ObjectAt(m_currentItem)->string.c_str()); } } void UIListBox::AddItem(const char *item, const char *command) { ListItem *li; li = new ListItem(); if (!li) { uii.Sys_Error(ERR_DROP, "Couldn't create list item\n"); } li->string = item; if (command) { li->command = command; } m_itemlist.AddObject(li); if (!m_currentItem) { m_currentItem = 1; } if (m_vertscroll) { m_vertscroll->setNumItems(m_itemlist.NumObjects()); } } void UIListBox::AddItem(int index, const char *command) { ListItem *li; li = new ListItem(); if (!li) { uii.Sys_Error(ERR_DROP, "Couldn't create list item\n"); } li->index = index; if (command) { li->command = command; } m_itemlist.AddObject(li); if (!m_currentItem) { m_currentItem = 1; } if (m_vertscroll) { m_vertscroll->setNumItems(m_itemlist.NumObjects()); } } void UIListBox::FrameInitialized(void) { UIListBase::FrameInitialized(); if (m_vertscroll) { m_vertscroll->setPageHeight(m_frame.size.height / m_font->getHeight(m_bVirtual)); m_vertscroll->setNumItems(m_itemlist.NumObjects()); } } void UIListBox::LayoutAddListItem(Event *ev) { if (ev->NumArgs() != 2) { AddItem(ev->GetString(1), NULL); return; } AddItem(ev->GetString(1), ev->GetString(2).c_str()); } void UIListBox::LayoutAddConfigstringListItem(Event *ev) { if (ev->NumArgs() != 2) { AddItem(ev->GetInteger(1), NULL); return; } AddItem(ev->GetInteger(1), ev->GetString(2).c_str()); } str UIListBox::getItemText(int which) { return m_itemlist.ObjectAt(which)->string; } int UIListBox::getNumItems(void) { return m_itemlist.NumObjects(); } void UIListBox::DeleteAllItems(void) { m_itemlist.ClearObjectList(); m_currentItem = 0; if (m_vertscroll) { m_vertscroll->setNumItems(0); m_vertscroll->setTopItem(0); } } void UIListBox::DeleteItem(int which) { m_itemlist.RemoveObjectAt(which); if (m_vertscroll) { m_vertscroll->setNumItems(m_itemlist.NumObjects()); } if (m_currentItem > getNumItems()) { TrySelectItem(getNumItems()); } }