/* =========================================================================== 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" Event W_Console_ChildSizeChanged ( "_console_childsizechanged", EV_DEFAULT, NULL, NULL, "Signal that the child area of the floating window has changed" ); Event EV_Console_Print ( "print", EV_DEFAULT, "s", "string", "Print the string to the console" ); CLASS_DECLARATION( UIWidget, UIConsole, NULL ) { { &W_SizeChanged, &UIConsole::OnSizeChanged }, { &EV_Console_Print, &UIConsole::Print }, { NULL, NULL } }; UIConsole::UIConsole() { m_scroll = NULL; m_firstitem = 0; m_numitems = 0; m_caret = 0; m_scroll = new UIVertScroll(); AllowActivate(true); } int UIConsole::getFirstItem ( void ) { return m_firstitem; } int UIConsole::getNextItem ( int prev ) { if (prev == -1) { return -1; } prev = prev + 1; if (m_numitems < MAX_CONSOLE_ITEMS) { if (prev > m_firstitem) { if (prev - m_firstitem >= m_numitems) return -1; } else if (m_firstitem + m_numitems >= prev + MAX_CONSOLE_ITEMS) { return -1; } } if (prev >= MAX_CONSOLE_ITEMS) { prev = 0; } if (prev != m_firstitem) { return prev; } return -1; } int UIConsole::getLastItem ( void ) { int item = m_firstitem + m_numitems; if (item - 1 >= MAX_CONSOLE_ITEMS) { return item - (MAX_CONSOLE_ITEMS + 1); } return item - 1; } int UIConsole::AddLine ( void ) { int line = getLastItem() + 1; if (line >= MAX_CONSOLE_ITEMS) { line = 0; } if (m_numitems < MAX_CONSOLE_ITEMS) { m_numitems++; } else { m_firstitem++; if (m_firstitem >= MAX_CONSOLE_ITEMS) { m_firstitem = 0; } } assert(line < MAX_CONSOLE_ITEMS); return line; } void UIConsole::DrawBottomLine ( void ) { int promptwidth; static str prompt = ">"; int top; float topScaled; int iXPos; int iMaxStringWidth; int widthbeforecaret; promptwidth = m_font->getWidth(prompt.c_str(), -1); top = m_frame.size.height - m_font->getHeight(getHighResScale()); topScaled = top / getHighResScale()[1]; m_font->Print(0.0, topScaled, prompt.c_str(), -1, getHighResScale()); iXPos = promptwidth + 1; iMaxStringWidth = m_frame.size.width - iXPos - m_scroll->getSize().width; if (m_caret > m_currentline.length()) { // Make sure to not overflow m_caret = m_currentline.length(); } if (m_caret < 0) m_caret = 0; widthbeforecaret = promptwidth + m_font->getWidth(m_currentline.c_str(), m_caret); if (m_refreshcompletionbuffer || m_completionbuffer.length() >= m_currentline.length()) { static str indicator; const char* pString; int indicatorwidth; int iChar; int iCharLength; int iStringLength; if (widthbeforecaret < iMaxStringWidth) { m_font->Print(iXPos, topScaled, m_currentline.c_str(), -1, getHighResScale()); } else { indicatorwidth = m_font->getWidth(indicator.c_str(), -1); m_font->Print(iXPos, topScaled, indicator.c_str(), -1, getHighResScale()); iXPos += indicatorwidth; iMaxStringWidth -= indicatorwidth; pString = &m_currentline[m_caret - 1]; iStringLength = 0; iCharLength = m_font->getCharWidth(pString[0]); for (iChar = m_caret; iChar > 1; --iChar) { iStringLength += iCharLength; iCharLength = m_font->getCharWidth(pString[iChar - 1]); } m_font->Print(iXPos, topScaled, pString + 1, -1, getHighResScale()); widthbeforecaret = iXPos + m_font->getWidth(pString + 1, m_caret - iChar); } } else { int completewidth; int linewidth; completewidth = m_font->getWidth(m_completionbuffer.c_str(), -1); linewidth = m_font->getWidth(&m_currentline[m_completionbuffer.length()], -1); m_font->Print(iXPos, topScaled, m_completionbuffer.c_str(), -1, getHighResScale()); iXPos += completewidth; m_font->Print(iXPos, topScaled, &m_currentline[m_completionbuffer.length()], -1, getHighResScale()); DrawBoxWithSolidBorder(UIRect2D(iXPos * getHighResScale()[0], top, linewidth * getHighResScale()[0], m_font->getHeight(getHighResScale())), UBlack, URed, 1, 2, 1.0); } // // Make the caret blink // if ((uid.time % 750) > 375 && IsActive()) { DrawBox(UIRect2D(widthbeforecaret * getHighResScale()[0], top, 1.0, m_font->getHeight(getHighResScale())), m_foreground_color, 1.0); } } void UIConsole::AddHistory ( void ) { if (m_history.IterateFromTail()) { if (m_history.getCurrent() != m_currentline) { m_history.AddTail(m_currentline); } } else { m_history.AddTail(m_currentline); } while (m_history.getCount() > 20) { m_history.IterateFromHead(); m_history.RemoveCurrentSetNext(); } m_historyposition = NULL; } void UIConsole::Print ( Event *ev ) { AddText(ev->GetString(1), NULL); } void UIConsole::KeyEnter ( void ) { AddHistory(); AddText(str(">") + m_currentline + "\n", NULL); if (m_consolehandler) { // // call the console handler // m_consolehandler((m_currentline + "\n").c_str()); } // clear the console input m_currentline = ""; m_caret = 0; } void UIConsole::setConsoleHandler ( consoleHandler_t handler ) { m_consolehandler = handler; } void UIConsole::AddText ( const char *text, const UColor *pColor ) { bool atbottom; int newtop; int i, size; item* curitem; atbottom = m_scroll->getPageHeight() + m_scroll->getTopItem() >= m_scroll->getNumItems(); newtop = m_scroll->getTopItem(); if (!m_numitems) { m_numitems = 1; m_items[m_firstitem].string = ""; m_items[m_firstitem].lines = 0; m_items[m_firstitem].pColor = &m_foreground_color; } curitem = &m_items[getLastItem()]; if (!pColor) { pColor = &m_foreground_color; } for (i = 0; text[i]; i++) { if (text[i] == '\n') { curitem->pColor = pColor; CalcLineBreaks(*curitem); int line = AddLine(); curitem = &m_items[line]; newtop -= curitem->lines; curitem->lines = 0; curitem->string = ""; } else { curitem->string += text[i]; } } curitem->pColor = pColor; CalcLineBreaks(*curitem); size = 0; for (i = m_firstitem; i != -1; i = getNextItem(i)) { size += m_items[i].lines; } m_scroll->setNumItems(size); if (atbottom || newtop > m_scroll->getNumItems() - m_scroll->getPageHeight()) { m_scroll->setTopItem(m_scroll->getNumItems() - m_scroll->getPageHeight()); } else { m_scroll->setTopItem(newtop); } if (m_scroll->getTopItem() < 0) { m_scroll->setTopItem(0); } if (curitem->lines == 9) { AddText("\n", NULL); } } void UIConsole::CalcLineBreaks ( item& theItem ) { int i; str sofar, checking; int lensofar, lenchecking, len_of_space; const char* remaining; lensofar = 0; lenchecking = 0; len_of_space = m_font->getCharWidth(' '); theItem.lines = 0; remaining = theItem.string.c_str(); for (i = 0; remaining[i]; i++) { if (remaining[i] == ' ') { sofar += ' '; checking = ""; lensofar += lenchecking + len_of_space; lenchecking = 0; } else { int charlen = m_font->getCharWidth(remaining[i]); if (m_frame.size.width - m_scroll->getSize().width < (charlen + lenchecking + lensofar)) { if (lensofar) { lensofar = lenchecking; theItem.breaks[theItem.lines] = sofar.length(); sofar = checking; lenchecking = charlen; checking = remaining[i]; } else { theItem.breaks[theItem.lines] = checking.length(); sofar = remaining[i]; lenchecking = 0; checking = ""; } theItem.lines++; if (theItem.lines == 8) { break; } } checking += remaining[i]; lenchecking += charlen; } } if (remaining[i] || lenchecking || lensofar) { theItem.breaks[theItem.lines++] = -1; } lensofar = 0; for (i = 0; i < theItem.lines; i++) { theItem.begins[i] = lensofar; if (theItem.breaks[i] != -1) { lensofar += theItem.breaks[i]; } } } void UIConsole::Clear ( void ) { int i; // clear items line for (i = 0; i < MAX_CONSOLE_ITEMS; i++) { m_items[i].lines = 0; } m_numitems = 0; m_firstitem = 0; m_caret = 0; m_currentline = ""; if (m_scroll) { m_scroll->setNumItems(0); } } void UIConsole::FrameInitialized ( void ) { Connect(this, W_SizeChanged, W_SizeChanged); OnSizeChanged(NULL); } void UIConsole::Draw ( void ) { const UColor* pCurrColor; m_font->setColor(m_foreground_color); pCurrColor = &m_foreground_color; m_scroll->setSolidBorderColor(m_background_color); m_scroll->setBackgroundColor(m_background_color, true); m_scroll->setBackgroundAlpha(m_alpha); m_scroll->setForegroundColor(m_foreground_color); if (m_numitems) { int i, item; int top; int lines_drawn, at_line; int topitem; top = (int)(m_frame.size.height - m_font->getHeight(getHighResScale()) * (m_scroll->getPageHeight() + 2)); item = m_firstitem; topitem = m_scroll->getTopItem() - 1; if (item == -1) { return; } for (i = m_items[item].lines; i < topitem; i += m_items[item].lines) { item = getNextItem(item); if (item == -1) { return; } } if (item == -1) { // no item available return; } at_line = m_items[item].lines - (i - topitem); lines_drawn = 0; while (lines_drawn < m_scroll->getPageHeight() + 1) { while (at_line >= m_items[item].lines) { item = getNextItem(item); at_line = 0; if (item == -1) { break; } } if (item == -1) { break; } if (at_line >= 0) { if (at_line >= m_items[item].lines) { break; } const ::item* theItem = &m_items[item]; if (theItem->pColor != pCurrColor) { m_font->setColor(*theItem->pColor); pCurrColor = theItem->pColor; } m_font->setAlpha(m_alpha); m_font->Print(0.0, top / getHighResScale()[1], &theItem->string.c_str()[theItem->begins[at_line]], theItem->breaks[at_line], getHighResScale()); } top += m_font->getHeight(getHighResScale()); lines_drawn++; at_line++; } } if (pCurrColor != &m_foreground_color) { m_font->setColor(m_foreground_color); } DrawBottomLine(); } void UIConsole::CharEvent ( int ch ) { if (ch <= 31) { // Not a valid char for the console return; } m_refreshcompletionbuffer = true; if (m_caret > m_currentline.length()) { m_caret = m_currentline.length(); } if (m_caret < 0) { m_caret = 0; } if (m_currentline.length() == m_caret) { m_currentline.append(str(char(ch))); m_caret++; } else if (m_caret) { m_currentline = str(m_currentline, 0, m_caret) + str(char(ch)) + (m_currentline.c_str() + m_caret); m_caret++; } else { m_currentline = str(char(ch)) + m_currentline; m_caret++; } } qboolean UIConsole::KeyEvent ( int key, unsigned int time ) { const char* command; if (key != K_TAB && key != K_BACKSPACE) { m_refreshcompletionbuffer = true; } switch (key) { case K_TAB: if (m_refreshcompletionbuffer) { m_completionbuffer = m_currentline; m_refreshcompletionbuffer = false; m_cntcvarnumber = 0; m_cntcmdnumber = 0; } command = uii.Cmd_CompleteCommandByNumber(m_completionbuffer.c_str(), m_cntcmdnumber++); if (!command) { command = uii.Cvar_CompleteCvarByNumber(m_completionbuffer.c_str(), m_cntcvarnumber++); if (!command) { m_currentline = m_completionbuffer; m_refreshcompletionbuffer = true; m_caret = m_currentline.length(); break; } } m_currentline = command; m_currentline += ' '; m_caret = m_currentline.length(); break; case K_ENTER: case K_KP_ENTER: if (m_currentline.length()) { KeyEnter(); } break; case K_BACKSPACE: if (!m_caret) { break; } if (m_refreshcompletionbuffer) { m_currentline = str(m_currentline, 0, m_caret - 1) + (m_currentline.c_str() + m_caret); m_caret--; } else { m_currentline = m_completionbuffer; m_cntcvarnumber = 0; m_cntcmdnumber = 0; m_refreshcompletionbuffer = true; m_caret = m_currentline.length(); } break; case K_UPARROW: if (uii.Sys_IsKeyDown(K_CTRL)) { // scroll up using the arrow key if (m_scroll->getTopItem() > 0) { m_scroll->setTopItem(m_scroll->getTopItem() - 1); } } else { if (m_history.getCount()) { if (m_historyposition) { m_history.setPosition(m_historyposition); if (!m_history.IteratePrev()) { break; } } else { m_history.IterateFromTail(); } m_historyposition = m_history.getPosition(); m_currentline = m_history.getCurrent(); m_caret = m_currentline.length(); } } break; case K_DOWNARROW: if (uii.Sys_IsKeyDown(K_CTRL)) { // scroll down using the arrow key if (m_scroll->getTopItem() + m_scroll->getPageHeight() < m_scroll->getNumItems()) { m_scroll->setTopItem(m_scroll->getTopItem() + 1); } } else { if (m_history.getCount() && m_historyposition) { m_history.setPosition(m_historyposition); if (!m_history.IterateNext()) { m_currentline = str(); m_caret = 0; m_historyposition = NULL; break; } m_historyposition = m_history.getPosition(); m_currentline = m_history.getCurrent(); m_caret = m_currentline.length(); } } break; case K_LEFTARROW: if (m_caret > 0) { m_caret--; } break; case K_RIGHTARROW: if (m_caret < m_currentline.length()) { m_caret++; } break; case K_DEL: if (m_caret >= m_currentline.length()) { break; } m_currentline = str(m_currentline, 0, m_caret) + (m_currentline.c_str() + m_caret + 1); break; case K_PGDN: if (m_scroll->getNumItems() >= m_scroll->getPageHeight()) { unsigned int top = m_scroll->getNumItems() - m_scroll->getPageHeight(); if (m_scroll->getPageHeight() + m_scroll->getTopItem() < top) { top = m_scroll->getPageHeight() + m_scroll->getTopItem(); } m_scroll->setTopItem(top); } break; case K_PGUP: if (m_scroll->getNumItems() >= m_scroll->getPageHeight()) { m_scroll->setTopItem(m_scroll->getTopItem() - m_scroll->getPageHeight()); } break; case K_HOME: if (uii.Sys_IsKeyDown(K_CTRL)) { m_scroll->setTopItem(0); } else { m_caret = 0; } break; case K_END: if (uii.Sys_IsKeyDown(K_CTRL)) { m_scroll->setTopItem(m_scroll->getNumItems()); } else { m_caret = m_currentline.length(); } break; case K_MWHEELDOWN: m_scroll->AttemptScrollTo(m_scroll->getTopItem() + 2); break; case K_MWHEELUP: m_scroll->AttemptScrollTo(m_scroll->getTopItem() - 2); break; } return true; } void UIConsole::OnSizeChanged ( Event *ev ) { int linesperpage; int numscroll; int item; int topitem; int topline; int atscroll; bool attop; bool atbottom; numscroll = 0; topitem = -1; topline = 0; atscroll = 0; attop = false; atbottom = false; linesperpage = (m_frame.size.height / (float)m_font->getHeight(getHighResScale())); m_scroll->InitFrameAlignRight(this, 0, 0); if (ev) { attop = m_scroll->getTopItem() == 0; atbottom = m_scroll->getPageHeight() + m_scroll->getTopItem() >= m_scroll->getNumItems(); } m_scroll->setPageHeight(linesperpage - 1); if (m_scroll->getPageHeight() < 1) { m_scroll->setPageHeight(1); } for (item = m_firstitem; item != -1; item = getNextItem(item)) { atscroll += m_items[item].lines; if (atscroll >= m_scroll->getTopItem() && topitem == -1) { topitem = item; } CalcLineBreaks(m_items[item]); numscroll += m_items[item].lines; if (topitem == -1 || topitem == item) { topline += m_items[item].lines; } } m_scroll->setNumItems(numscroll); if (topitem != -1) { if (topline > m_scroll->getNumItems() - m_scroll->getPageHeight()) { atbottom = true; } if (!atbottom) { if (attop) { m_scroll->setTopItem(0); } else { if (topline < 0) { topline = 0; } m_scroll->setTopItem(topline); } } } m_scroll->setTopItem(m_scroll->getNumItems() - m_scroll->getPageHeight()); if (m_scroll->getTopItem() < 0) { m_scroll->setTopItem(0); } } CLASS_DECLARATION( UIFloatingWindow, UIFloatingConsole, NULL ) { { &W_Console_ChildSizeChanged, &UIFloatingConsole::OnChildSizeChanged }, { &UIFloatingConsole::W_ClosePressed, &UIFloatingConsole::OnClosePressed }, { NULL, NULL } }; UIFloatingConsole::UIFloatingConsole() { m_status = NULL; m_handler = NULL; setConsoleColor(UWhite); setConsoleBackground(UBlack, 1.0); } UIFloatingConsole::~UIFloatingConsole() { if (m_console) { delete m_console; } if (m_status) { delete m_status; } } void UIFloatingConsole::FrameInitialized ( void ) { // call the parent initialisation UIFloatingWindow::FrameInitialized(); m_status = new UIStatusBar(alignment_t::WND_ALIGN_BOTTOM, 20.0 * getHighResScale()[1]); m_status->InitFrame(getChildSpace(), UIRect2D(0, 0, 20.0 * getHighResScale()[0], 20.0 * getHighResScale()[1]), 0, "verdana-12"); m_status->EnableSizeBox(this); m_status->setTitle(str()); m_console = new UIConsole(); m_console->InitFrame(getChildSpace(), UIRect2D(0, 0, 20.0 * getHighResScale()[0], 20.0 * getHighResScale()[1]), 0, "verdana-14"); setConsoleColor(m_consoleColor); setConsoleBackground(m_consoleBackground, m_consoleAlpha); m_console->setConsoleHandler(m_handler); getChildSpace()->Connect(this, W_SizeChanged, W_Console_ChildSizeChanged); getChildSpace()->AllowActivate(false); OnChildSizeChanged(NULL); m_background_color.a = 0.0; m_alpha = 1.0; getChildSpace()->setBackgroundAlpha(1.0); } void UIFloatingConsole::OnChildSizeChanged ( Event *ev ) { const UISize2D childSpaceSize = getChildSpace()->getSize(); const UISize2D statusSize = m_status->getSize(); const UISize2D newSize(childSpaceSize.width, childSpaceSize.height - statusSize.height); m_console->setFrame(UIRect2D(UIPoint2D(0, 0), newSize)); } void UIFloatingConsole::AddText ( const char *text, const UColor *pColor ) { if (m_console) { m_console->AddText(text, pColor); } } void UIFloatingConsole::setConsoleHandler ( consoleHandler_t handler ) { if (m_console) { m_console->setConsoleHandler(handler); } else { m_handler = handler; } } void UIFloatingConsole::Clear ( void ) { if (m_console) { m_console->Clear(); } } void UIFloatingConsole::OnClosePressed ( Event *ev ) { SendSignal(UIFloatingWindow::W_ClosePressed); } void UIFloatingConsole::setConsoleBackground ( const UColor& color, float alpha ) { m_alpha = alpha; m_consoleBackground = color; m_consoleAlpha = alpha; if (m_console) { m_console->setBackgroundAlpha(alpha); m_console->setBackgroundColor(color, true); } if (m_status) { m_status->setBackgroundAlpha(alpha); m_status->setBackgroundColor(color, true); } } void UIFloatingConsole::setConsoleColor ( const UColor& color ) { m_consoleColor = color; if (m_console) { m_console->setForegroundColor(color); } if (m_status) { m_status->setForegroundColor(color); } } CLASS_DECLARATION( UIConsole, UIDMConsole, NULL ) { { NULL, NULL } }; UIDMConsole::UIDMConsole() { m_bQuickMessageMode = qfalse; m_iMessageMode = 100; } void UIDMConsole::KeyEnter ( void ) { if (!str::icmp(m_currentline, "exit") || !str::icmp(m_currentline, "quit") || !str::icmp(m_currentline, "close")) { m_currentline = ""; uii.UI_CloseDMConsole(); return; } AddHistory(); if (!GetQuickMessageMode()) { if (!str::icmp(m_currentline, "say") || !str::icmp(m_currentline, "all")) { if (GetMessageMode() != 100) { uii.Cmd_Stuff("messagemode_all;wait 1;messagemode_all\n"); } m_currentline = ""; m_caret = 0; return; } else if (!str::icmp(m_currentline, "sayteam") || !str::icmp(m_currentline, "team") || !str::icmp(m_currentline, "teamsay")) { if (GetMessageMode() != 200) { uii.Cmd_Stuff("messagemode_team;wait 1;messagemode_team\n"); } m_currentline = ""; m_caret = 0; return; } else if (strstr(m_currentline, "wisper") || strstr(m_currentline, "private") // This one is opm-exclusive || strstr(m_currentline, "whisper")) { char szString[128]; const char* pszToken; strncpy(szString, m_currentline.c_str(), sizeof(szString) / sizeof(szString[0])); szString[127] = 0; pszToken = strtok(szString, " "); if (pszToken) { if (!Q_stricmp(pszToken, "wisper") || !Q_stricmp(pszToken, "private")) { pszToken = strtok(0, " "); if (!pszToken) { AddText("Mode Change Error: You need to specify a client number (private #)\n", NULL); m_currentline = ""; m_caret = 0; return; } int mode = atoi(pszToken); if (mode && mode != GetMessageMode()) { uii.Cmd_Stuff(va("messagemode_private %i;wait 1;messagemode_private %i\n", mode, mode)); m_currentline = ""; m_caret = 0; return; } } } } } if (m_consolehandler) { m_consolehandler((m_currentline + "\n").c_str()); } else { AddText(">" + m_currentline + "\n", NULL); } m_currentline = ""; m_caret = 0; if (GetQuickMessageMode()) { uii.UI_CloseDMConsole(); } } void UIDMConsole::AddDMMessageText ( const char *text, const UColor *pColor ) { AddText(text, NULL); if (com_target_game->integer >= TG_MOHTA) { uii.Snd_PlaySound("radio_click"); } else { uii.Snd_PlaySound("objective_text"); } } void UIDMConsole::Draw ( void ) { if (!IsThisOrChildActive()) { SendSignal(W_Deactivated); } if (GetQuickMessageMode()) { m_scroll->ProcessEvent(EV_Widget_Disable); } else { m_scroll->ProcessEvent(EV_Widget_Enable); } UIConsole::Draw(); } qboolean UIDMConsole::KeyEvent ( int key, unsigned int time ) { const char* command; if (key != K_TAB && key != K_BACKSPACE) { m_refreshcompletionbuffer = true; } switch (key) { case K_TAB: if (m_refreshcompletionbuffer) { m_completionbuffer = m_currentline; m_refreshcompletionbuffer = false; m_cntcvarnumber = 0; m_cntcmdnumber = 0; } command = uii.Cmd_CompleteCommandByNumber(m_completionbuffer.c_str(), m_cntcmdnumber++); if (!command) { command = uii.Cvar_CompleteCvarByNumber(m_completionbuffer.c_str(), m_cntcvarnumber++); if (!command) { m_currentline = m_completionbuffer; m_refreshcompletionbuffer = true; m_caret = m_currentline.length(); break; } } m_currentline = command; m_currentline += ' '; m_caret = m_currentline.length(); break; case K_ENTER: case K_KP_ENTER: if (m_currentline.length()) { KeyEnter(); } else { // nothing, close the dm console uii.UI_CloseDMConsole(); } break; case K_BACKSPACE: if (!m_caret) { break; } if (m_refreshcompletionbuffer) { m_currentline = str(m_currentline, 0, m_caret - 1) + (m_currentline.c_str() + m_caret); m_caret--; } else { m_currentline = m_completionbuffer; m_cntcvarnumber = 0; m_cntcmdnumber = 0; m_refreshcompletionbuffer = true; m_caret = m_currentline.length(); } break; case K_UPARROW: if (uii.Sys_IsKeyDown(K_CTRL)) { // scroll up using the arrow key if (m_scroll->getTopItem() > 0) { m_scroll->setTopItem(m_scroll->getTopItem() - 1); } } else { if (m_history.getCount()) { if (m_historyposition) { m_history.setPosition(m_historyposition); if (!m_history.IteratePrev()) { break; } } else { m_history.IterateFromTail(); } m_historyposition = m_history.getPosition(); m_currentline = m_history.getCurrent(); m_caret = m_currentline.length(); } } break; case K_DOWNARROW: if (uii.Sys_IsKeyDown(K_CTRL)) { // scroll down using the arrow key if (m_scroll->getTopItem() + m_scroll->getPageHeight() < m_scroll->getNumItems()) { m_scroll->setTopItem(m_scroll->getTopItem() + 1); } } else { if (m_history.getCount() && m_historyposition) { m_history.setPosition(m_historyposition); if (!m_history.IterateNext()) { m_currentline = str(); m_caret = 0; m_historyposition = NULL; break; } m_historyposition = m_history.getPosition(); m_currentline = m_history.getCurrent(); m_caret = m_currentline.length(); } } break; case K_LEFTARROW: if (m_caret > 0) { m_caret--; } break; case K_RIGHTARROW: if (m_caret < m_currentline.length()) { m_caret++; } break; case K_DEL: if (m_caret >= m_currentline.length()) { break; } m_currentline = str(m_currentline, 0, m_caret) + (m_currentline.c_str() + m_caret + 1); break; case K_PGDN: if (m_scroll->getNumItems() >= m_scroll->getPageHeight()) { unsigned int top = m_scroll->getNumItems() - m_scroll->getPageHeight(); if (m_scroll->getPageHeight() + m_scroll->getTopItem() < top) { top = m_scroll->getPageHeight() + m_scroll->getTopItem(); } m_scroll->setTopItem(top); } break; case K_PGUP: if (m_scroll->getNumItems() >= m_scroll->getPageHeight()) { m_scroll->setTopItem(m_scroll->getTopItem() - m_scroll->getPageHeight()); } break; case K_HOME: if (uii.Sys_IsKeyDown(K_CTRL)) { m_scroll->setTopItem(0); } else { m_caret = 0; } break; case K_END: if (uii.Sys_IsKeyDown(K_CTRL)) { m_scroll->setTopItem(m_scroll->getNumItems()); } else { m_caret = m_currentline.length(); } break; case K_MWHEELDOWN: m_scroll->AttemptScrollTo(m_scroll->getTopItem() + 2); break; case K_MWHEELUP: m_scroll->AttemptScrollTo(m_scroll->getTopItem() - 2); break; } return true; } qboolean UIDMConsole::GetQuickMessageMode ( void ) { return m_bQuickMessageMode; } void UIDMConsole::SetQuickMessageMode ( qboolean bQuickMessage ) { m_bQuickMessageMode = bQuickMessage; } int UIDMConsole::GetMessageMode ( void ) { return m_iMessageMode; } void UIDMConsole::SetMessageMode ( int iMode ) { m_iMessageMode = iMode; } CLASS_DECLARATION( UIFloatingConsole, UIFloatingDMConsole, NULL ) { { &W_Console_ChildSizeChanged, &UIFloatingDMConsole::OnChildSizeChanged }, { &UIFloatingConsole::W_ClosePressed, &UIFloatingDMConsole::OnClosePressed }, { &W_Deactivated, &UIFloatingDMConsole::OnClosePressed }, { NULL, NULL } }; UIFloatingDMConsole::UIFloatingDMConsole() : m_status(NULL) , m_handler(NULL) , m_consoleColor(0, 0, 0, 1) , m_consoleBackground(0, 0, 0, 1) { setConsoleColor(UWhite); setConsoleBackground(UBlack, 1); } UIFloatingDMConsole::~UIFloatingDMConsole() { if (m_console) { delete m_console; } if (m_status) { delete m_status; } } void UIFloatingDMConsole::FrameInitialized ( void ) { // call the parent initialisation UIFloatingWindow::FrameInitialized(); m_console = new UIDMConsole(); m_console->InitFrame(getChildSpace(), UIRect2D(0, 0, 20.0 * getHighResScale()[0], 20.0 * getHighResScale()[1]), 0, "facfont-20"); m_console->Connect(this, W_Deactivated, W_Deactivated); setConsoleColor(m_consoleColor); setConsoleBackground(m_consoleBackground, m_consoleAlpha); getChildSpace()->Connect(this, W_SizeChanged, W_Console_ChildSizeChanged); m_console->setConsoleHandler(m_handler); getChildSpace()->AllowActivate(false); OnChildSizeChanged(NULL); m_background_color.a = 1.0; m_alpha = 1.0; getChildSpace()->setBackgroundAlpha(1.0); } void UIFloatingDMConsole::OnChildSizeChanged ( Event *ev ) { const UISize2D childSpaceSize = getChildSpace()->getSize(); if (m_status) { const UISize2D statusSize = m_status->getSize(); const UISize2D newSize(childSpaceSize.width, childSpaceSize.height - statusSize.height); m_console->setFrame(UIRect2D(UIPoint2D(0, 0), newSize)); } else { m_console->setFrame(UIRect2D(UIPoint2D(0, 0), childSpaceSize)); } } void UIFloatingDMConsole::AddText ( const char *text, const UColor *pColor ) { if (m_console) { m_console->AddText(text, pColor); } } void UIFloatingDMConsole::AddDMMessageText ( const char *text, const UColor *pColor ) { if (m_console) { m_console->AddDMMessageText(text, pColor); } } void UIFloatingDMConsole::setConsoleHandler ( consoleHandler_t handler ) { if (m_console) { m_console->setConsoleHandler(handler); } } void UIFloatingDMConsole::Clear ( void ) { if (m_console) { m_console->Clear(); } } void UIFloatingDMConsole::OnClosePressed ( Event *ev ) { SendSignal(UIFloatingWindow::W_ClosePressed); } void UIFloatingDMConsole::setConsoleBackground ( const UColor& color, float alpha ) { m_consoleBackground = color; m_consoleAlpha = alpha; if (m_console) { m_console->setBackgroundAlpha(alpha); m_console->setBackgroundColor(color, true); } if (m_status) { m_status->setBackgroundAlpha(alpha); m_status->setBackgroundColor(color, true); } } void UIFloatingDMConsole::setConsoleColor ( const UColor& color ) { m_consoleColor = color; if (m_console) { m_console->setForegroundColor(color); } if (m_status) { m_status->setForegroundColor(color); } } qboolean UIFloatingDMConsole::GetQuickMessageMode ( void ) { if (m_console) { return m_console->GetQuickMessageMode(); } return qfalse; } void UIFloatingDMConsole::SetQuickMessageMode ( qboolean bQuickMessage ) { if (m_console) { return m_console->SetQuickMessageMode(bQuickMessage); } } int UIFloatingDMConsole::GetMessageMode ( void ) { if (m_console) { return m_console->GetMessageMode(); } return qfalse; } void UIFloatingDMConsole::SetMessageMode ( int iMode ) { if (m_console) { return m_console->SetMessageMode(iMode); } }