📄 guipopupctrl.cc
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "dgl/dgl.h"
#include "gui/core/guiCanvas.h"
#include "gui/controls/guiPopUpCtrl.h"
#include "console/consoleTypes.h"
#include "gui/core/guiDefaultControlRender.h"
IMPLEMENT_CONOBJECT(GuiPopUpMenuCtrl);
GuiPopUpBackgroundCtrl::GuiPopUpBackgroundCtrl(GuiPopUpMenuCtrl *ctrl, GuiPopUpTextListCtrl *textList)
{
mPopUpCtrl = ctrl;
mTextList = textList;
}
void GuiPopUpBackgroundCtrl::onMouseDown(const GuiEvent &event)
{
mTextList->setSelectedCell(Point2I(-1,-1));
mPopUpCtrl->closePopUp();
}
//------------------------------------------------------------------------------
GuiPopUpTextListCtrl::GuiPopUpTextListCtrl()
{
mPopUpCtrl = NULL;
}
//------------------------------------------------------------------------------
GuiPopUpTextListCtrl::GuiPopUpTextListCtrl(GuiPopUpMenuCtrl *ctrl)
{
mPopUpCtrl = ctrl;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void GuiPopUpTextListCtrl::onCellSelected( Point2I /*cell*/ )
{
// Do nothing, the parent control will take care of everything...
}
//------------------------------------------------------------------------------
bool GuiPopUpTextListCtrl::onKeyDown(const GuiEvent &event)
{
//if the control is a dead end, don't process the input:
if ( !mVisible || !mActive || !mAwake )
return false;
//see if the key down is a <return> or not
if ( event.modifier == 0 )
{
if ( event.keyCode == KEY_RETURN )
{
mPopUpCtrl->closePopUp();
return true;
}
else if ( event.keyCode == KEY_ESCAPE )
{
mSelectedCell.set( -1, -1 );
mPopUpCtrl->closePopUp();
return true;
}
}
//otherwise, pass the event to it's parent
return Parent::onKeyDown(event);
}
void GuiPopUpTextListCtrl::onMouseDown(const GuiEvent &event)
{
Parent::onMouseDown(event);
mPopUpCtrl->closePopUp();
}
//------------------------------------------------------------------------------
void GuiPopUpTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver)
{
#ifdef TGE_RPG_UI ///TGE_RPG_UI
if(mouseOver)
renderFilledBorder(RectI(offset.x, offset.y, mCellSize.x, mCellSize.y), mProfile->mBorderColor,mProfile->mFillColorHL);
else if(selected)
renderFilledBorder(RectI(offset.x, offset.y, mCellSize.x, mCellSize.y), mProfile->mBorderColorHL,mProfile->mFillColorHL);
S32 yOffset = (mCellSize.y - mFont->getHeight())/2;
#endif
ColorI fontColor;
mPopUpCtrl->getFontColor( fontColor, mList[cell.y].id, selected, mouseOver );
dglSetBitmapModulation( fontColor );
#ifdef TGE_RPG_UI ///TGE_RPG_UI
dglDrawText( mFont, Point2I( offset.x + 4, offset.y + yOffset), mList[cell.y].text );
#else
dglDrawText( mFont, Point2I( offset.x + 4, offset.y ), mList[cell.y].text );
#endif
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GuiPopUpMenuCtrl::GuiPopUpMenuCtrl(void)
{
VECTOR_SET_ASSOCIATION(mEntries);
VECTOR_SET_ASSOCIATION(mSchemes);
mSelIndex = -1;
mActive = true;
mMaxPopupHeight = 200;
mScrollDir = GuiScrollCtrl::None;
mScrollCount = 0;
mLastYvalue = 0;
mIncValue = 0;
mRevNum = 0;
mInAction = false;
}
//------------------------------------------------------------------------------
GuiPopUpMenuCtrl::~GuiPopUpMenuCtrl()
{
}
//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::initPersistFields(void)
{
Parent::initPersistFields();
addField("maxPopupHeight", TypeS32, Offset(mMaxPopupHeight, GuiPopUpMenuCtrl));
}
//------------------------------------------------------------------------------
ConsoleMethod( GuiPopUpMenuCtrl, add, void, 4, 5, "(string name, int idNum, int scheme=0)")
{
if ( argc > 4 )
object->addEntry(argv[2],dAtoi(argv[3]),dAtoi(argv[4]));
else
object->addEntry(argv[2],dAtoi(argv[3]),0);
}
ConsoleMethod( GuiPopUpMenuCtrl, addScheme, void, 6, 6, "(int id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL)")
{
ColorI fontColor, fontColorHL, fontColorSEL;
U32 r, g, b;
char buf[64];
dStrcpy( buf, argv[3] );
char* temp = dStrtok( buf, " \0" );
r = temp ? dAtoi( temp ) : 0;
temp = dStrtok( NULL, " \0" );
g = temp ? dAtoi( temp ) : 0;
temp = dStrtok( NULL, " \0" );
b = temp ? dAtoi( temp ) : 0;
fontColor.set( r, g, b );
dStrcpy( buf, argv[4] );
temp = dStrtok( buf, " \0" );
r = temp ? dAtoi( temp ) : 0;
temp = dStrtok( NULL, " \0" );
g = temp ? dAtoi( temp ) : 0;
temp = dStrtok( NULL, " \0" );
b = temp ? dAtoi( temp ) : 0;
fontColorHL.set( r, g, b );
dStrcpy( buf, argv[5] );
temp = dStrtok( buf, " \0" );
r = temp ? dAtoi( temp ) : 0;
temp = dStrtok( NULL, " \0" );
g = temp ? dAtoi( temp ) : 0;
temp = dStrtok( NULL, " \0" );
b = temp ? dAtoi( temp ) : 0;
fontColorSEL.set( r, g, b );
object->addScheme( dAtoi( argv[2] ), fontColor, fontColorHL, fontColorSEL );
}
ConsoleMethod( GuiPopUpMenuCtrl, setText, void, 3, 3, "(string text)")
{
object->setText(argv[2]);
}
ConsoleMethod( GuiPopUpMenuCtrl, getText, const char*, 2, 2, "")
{
return object->getText();
}
ConsoleMethod( GuiPopUpMenuCtrl, clear, void, 2, 2, "Clear the popup list.")
{
object->clear();
}
ConsoleMethod(GuiPopUpMenuCtrl, sort, void, 2, 2, "Sort the list alphabetically.")
{
object->sort();
}
ConsoleMethod( GuiPopUpMenuCtrl, forceOnAction, void, 2, 2, "")
{
object->onAction();
}
ConsoleMethod( GuiPopUpMenuCtrl, forceClose, void, 2, 2, "")
{
object->closePopUp();
}
ConsoleMethod( GuiPopUpMenuCtrl, getSelected, S32, 2, 2, "")
{
return object->getSelected();
}
ConsoleMethod( GuiPopUpMenuCtrl, setSelected, void, 3, 3, "(int id)")
{
object->setSelected(dAtoi(argv[2]));
}
ConsoleMethod( GuiPopUpMenuCtrl, getTextById, const char*, 3, 3, "(int id)")
{
return(object->getTextById(dAtoi(argv[2])));
}
ConsoleMethod( GuiPopUpMenuCtrl, setEnumContent, void, 4, 4, "(string class, string enum)"
"This fills the popup with a classrep's field enumeration type info.\n\n"
"More of a helper function than anything. If console access to the field list is added, "
"at least for the enumerated types, then this should go away..")
{
AbstractClassRep * classRep = AbstractClassRep::getClassList();
// walk the class list to get our class
while(classRep)
{
if(!dStricmp(classRep->getClassName(), argv[2]))
break;
classRep = classRep->getNextClass();
}
// get it?
if(!classRep)
{
Con::warnf(ConsoleLogEntry::General, "failed to locate class rep for '%s'", argv[2]);
return;
}
// walk the fields to check for this one (findField checks StringTableEntry ptrs...)
U32 i;
for(i = 0; i < classRep->mFieldList.size(); i++)
if(!dStricmp(classRep->mFieldList[i].pFieldname, argv[3]))
break;
// found it?
if(i == classRep->mFieldList.size())
{
Con::warnf(ConsoleLogEntry::General, "failed to locate field '%s' for class '%s'", argv[3], argv[2]);
return;
}
const AbstractClassRep::Field & field = classRep->mFieldList[i];
// check the type
if(field.type != TypeEnum)
{
Con::warnf(ConsoleLogEntry::General, "field '%s' is not an enumeration for class '%s'", argv[3], argv[2]);
return;
}
AssertFatal(field.table, avar("enumeration '%s' for class '%s' with NULL ", argv[3], argv[2]));
// fill it
for(i = 0; i < field.table->size; i++)
object->addEntry(field.table->table[i].label, field.table->table[i].index);
}
//------------------------------------------------------------------------------
ConsoleMethod( GuiPopUpMenuCtrl, findText, S32, 3, 3, "(string text)"
"Returns the position of the first entry containing the specified text.")
{
return( object->findText( argv[2] ) );
}
//------------------------------------------------------------------------------
ConsoleMethod( GuiPopUpMenuCtrl, size, S32, 2, 2, "Get the size of the menu - the number of entries in it.")
{
return( object->getNumEntries() );
}
//------------------------------------------------------------------------------
ConsoleMethod( GuiPopUpMenuCtrl, replaceText, void, 3, 3, "(bool doReplaceText)")
{
object->replaceText(dAtoi(argv[2]));
}
//------------------------------------------------------------------------------
bool GuiPopUpMenuCtrl::onAdd()
{
if (!Parent::onAdd())
return false;
mSelIndex = -1;
mReplaceText = true;
return true;
}
//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::onSleep()
{
Parent::onSleep();
closePopUp(); // Tests in function.
}
//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::clear()
{
mEntries.setSize(0);
setText("");
mSelIndex = -1;
mRevNum = 0;
}
//------------------------------------------------------------------------------
static S32 QSORT_CALLBACK textCompare(const void *a,const void *b)
{
GuiPopUpMenuCtrl::Entry *ea = (GuiPopUpMenuCtrl::Entry *) (a);
GuiPopUpMenuCtrl::Entry *eb = (GuiPopUpMenuCtrl::Entry *) (b);
return (dStricmp(ea->buf, eb->buf));
}
//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::sort()
{
dQsort((void *)&(mEntries[0]), mEntries.size(), sizeof(Entry), textCompare);
}
//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::addEntry(const char *buf, S32 id, U32 scheme)
{
Entry e;
dStrcpy(e.buf, buf);
e.id = id;
e.scheme = scheme;
// see if there is a shortcut key
char * cp = dStrchr(e.buf, '~');
e.ascii = cp ? cp[1] : 0;
mEntries.push_back(e);
if ( mInAction && mTl )
{
// Add the new entry:
mTl->addEntry( e.id, e.buf );
repositionPopup();
}
}
//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::addScheme( U32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL )
{
if ( !id )
return;
Scheme newScheme;
newScheme.id = id;
newScheme.fontColor = fontColor;
newScheme.fontColorHL = fontColorHL;
newScheme.fontColorSEL = fontColorSEL;
mSchemes.push_back( newScheme );
}
//------------------------------------------------------------------------------
S32 GuiPopUpMenuCtrl::getSelected()
{
if (mSelIndex == -1)
return 0;
return mEntries[mSelIndex].id;
}
//------------------------------------------------------------------------------
const char* GuiPopUpMenuCtrl::getTextById(S32 id)
{
for ( U32 i = 0; i < mEntries.size(); i++ )
{
if ( mEntries[i].id == id )
return( mEntries[i].buf );
}
return( "" );
}
//------------------------------------------------------------------------------
S32 GuiPopUpMenuCtrl::findText( const char* text )
{
for ( U32 i = 0; i < mEntries.size(); i++ )
{
if ( dStrcmp( text, mEntries[i].buf ) == 0 )
return( mEntries[i].id );
}
return( -1 );
}
//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::setSelected(S32 id)
{
S32 i;
for (i = 0; U32(i) < mEntries.size(); i++)
if (id == mEntries[i].id)
{
i = (mRevNum > i) ? mRevNum - i : i;
mSelIndex = i;
setText(mEntries[i].buf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -