Files
bearstonem--openmohaa-vr/code/uilib/uiconsole.cpp
T
smallmodel 6fe1e86b31 Automatically scale UI elements for high resolutions
This fixes UI elements being tiny on high resolutions like 4K. Now most UI elements will scale automatically with resolutions above 1920x1080.
2024-11-30 22:40:00 +01:00

1607 lines
30 KiB
C++

/*
===========================================================================
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,
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
)
{
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,
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,
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,
UColor *pColor
)
{
if (m_console) {
m_console->AddText(text, pColor);
}
}
void UIFloatingDMConsole::AddDMMessageText
(
const char *text,
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);
}
}