/* =========================================================================== Copyright (C) 2023 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" #include "localization.h" CLASS_DECLARATION( UIWidget, UIList, NULL ) { { &W_LeftMouseDown, &UIList::Pressed }, { &W_LeftMouseUp, &UIList::Released }, { &EV_Layout_AddListItem, &UIList::LayoutAddListItem }, { NULL, NULL } }; UIList::UIList() { m_arrow_width = 15.0; m_arrow_width = 0.0; m_currentItem = 0; m_next_arrow_region = 0; m_prev_arrow_region = 0; m_prev_arrow_depressed = 0; m_next_arrow_depressed = 0; AllowActivate(true); m_prev_arrow = uWinMan.RegisterShader("gfx/2d/arrow_left.tga"); if (!m_prev_arrow) { uii.Sys_Printf("UIList::Ulist : Could not register shader gfx/2d/arrow_left.tga"); } m_next_arrow = uWinMan.RegisterShader("gfx/2d/arrow_right.tga"); if (!m_next_arrow) { uii.Sys_Printf("UIList::Ulist : Could not register shader gfx/2d/arrow_right.tga"); } } UIList::~UIList() { for (int i = m_itemlist.NumObjects(); i > 0; i--) { UIListItem* item = m_itemlist.ObjectAt(i); m_itemlist.RemoveObjectAt(i); delete item; } if (m_prev_arrow_region) delete m_prev_arrow_region; if (m_next_arrow_region) delete m_next_arrow_region; } void UIList::Draw ( void ) { UpdateUIElement(); // draw the item text if (m_currentItem) { str itemText; UIListItem *item = m_itemlist.ObjectAt(m_currentItem); if (item->itemalias) { itemText = item->itemalias; } else if (item->itemname) { itemText = item->itemname; } float textX = 0.5f * m_frame.size.width - 0.5f * m_font->getWidth(itemText, -1); float textY = 0.5f * (m_frame.size.height - m_font->getHeight(m_bVirtual ? m_vVirtualScale : uid.scaleRes)) - 1.0f; m_font->setColor(m_foreground_color); const char *text = Sys_LV_CL_ConvertString(itemText); m_font->Print(textX, textY, text, -1, m_bVirtual ? m_vVirtualScale : NULL); } // draw the previous arrow Draw3DBox( 0.0f, 0.0f, m_arrow_width, m_frame.size.height, m_prev_arrow_depressed, m_border_color, m_local_alpha); float height = m_frame.size.height - 4.0; float width = m_arrow_width - 4.0; uii.Rend_DrawPicStretched( 2.0f, 2.0f, width, height, 0.0f, 0.0f, 1.0f, 1.0f, m_prev_arrow->GetMaterial()); // draw the next arrow float x = m_frame.size.width - m_arrow_width; float y = 0.0f; Draw3DBox( x, y, m_arrow_width, m_frame.size.height, m_next_arrow_depressed, m_border_color, m_local_alpha); uii.Rend_DrawPicStretched( x + 2.0f, y + 2.0f, width, height, 0.0f, 0.0f, 1.0f, 1.0f, m_next_arrow->GetMaterial()); } qboolean UIList::KeyEvent ( int key, unsigned int time ) { switch (key) { case K_RIGHTARROW: ScrollNext(); UpdateData(); if (m_commandhandler) { m_commandhandler(m_itemlist.ObjectAt(m_currentItem)->itemname.c_str(), NULL); } return qtrue; case K_LEFTARROW: ScrollPrev(); UpdateData(); if (m_commandhandler) { m_commandhandler(m_itemlist.ObjectAt(m_currentItem)->itemname.c_str(), NULL); } return qtrue; default: return qfalse; } } void UIList::CharEvent ( int ch ) { } void UIList::Pressed ( Event *ev ) { m_held = qtrue; m_depressed = qtrue; float mouse_xpos = ev->GetFloat(1); float mouse_ypos = ev->GetFloat(2); int buttons = ev->GetInteger(3); // unused FrameInitialized(); // previous arrow is clicked if (m_prev_arrow_region->contains(mouse_xpos, mouse_ypos)) { m_prev_arrow_depressed = qtrue; ScrollPrev(); UpdateData(); return; } // next arrow is clicked if (m_next_arrow_region->contains(mouse_xpos, mouse_ypos)) { m_next_arrow_depressed = qtrue; ScrollNext(); UpdateData(); } } void UIList::Released ( Event *ev ) { m_held = qfalse; m_depressed = qfalse; m_prev_arrow_depressed = qfalse; m_next_arrow_depressed = qfalse; } void UIList::ScrollNext ( void ) { m_currentItem++; if (m_currentItem > m_itemlist.NumObjects()) { m_currentItem = m_itemlist.NumObjects(); } } void UIList::ScrollPrev ( void ) { m_currentItem--; if (m_currentItem < 1) { m_currentItem = 1; } } void UIList::FrameInitialized ( void ) { m_prev_arrow_region = new UIRect2D(m_clippedframe.pos.x, m_clippedframe.pos.y, m_arrow_width, m_frame.size.height); m_next_arrow_region = new UIRect2D(m_clippedframe.size.width - m_arrow_width + m_clippedframe.pos.x, m_clippedframe.pos.y, m_arrow_width, m_frame.size.height); } void UIList::LayoutAddListItem ( Event *ev ) { str item = ev->GetString(1); str alias; if (ev->NumArgs() > 1) { alias = ev->GetString(2); } AddItem(item, alias); } void UIList::AddItem ( str item, str alias ) { UIListItem *listItem = new UIListItem(); listItem->itemname = item; listItem->itemalias = alias; m_itemlist.AddObject(listItem); m_currentItem = 1; } void UIList::UpdateUIElement ( void ) { if (!m_cvarname) { return; } const char *cvarstring = UI_GetCvarString(m_cvarname, NULL); if (!cvarstring) { m_currentItem = 1; UpdateData(); return; } for (int i = 1; i <= m_itemlist.NumObjects(); i++) { UIListItem *obj = m_itemlist.ObjectAt(i); if (obj->itemname == cvarstring) { m_currentItem = i; break; } } } void UIList::UpdateData ( void ) { if (!m_currentItem) { return; } if (m_cvarname) { UIListItem *item = m_itemlist.ObjectAt(m_currentItem); if (item->itemname) { uii.Cvar_Set(m_cvarname, item->itemname); } } if (m_command) { UIListItem *item = m_itemlist.ObjectAt(m_currentItem); m_command.append(' '); m_command.append(item->itemname); m_command.append('\n'); Cbuf_AddText(m_command.c_str()); } } CLASS_DECLARATION( UIList, UIListIndex, NULL ) { { NULL, NULL } }; qboolean UIListIndex::KeyEvent ( int key, unsigned int time ) { switch (key) { case K_RIGHTARROW: ScrollNext(); UpdateData(); return qtrue; case K_LEFTARROW: ScrollPrev(); UpdateData(); return qtrue; default: return qfalse; } }