added everything
This commit is contained in:
42
engine/gui/editor/guiControlListPopup.cc
Executable file
42
engine/gui/editor/guiControlListPopup.cc
Executable file
@ -0,0 +1,42 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gui/controls/guiPopUpCtrl.h"
|
||||
#include "gui/core/guiCanvas.h"
|
||||
#include "gui/utility/guiInputCtrl.h"
|
||||
|
||||
class GuiControlListPopUp : public GuiPopUpMenuCtrl
|
||||
{
|
||||
typedef GuiPopUpMenuCtrl Parent;
|
||||
public:
|
||||
bool onAdd();
|
||||
|
||||
DECLARE_CONOBJECT(GuiControlListPopUp);
|
||||
};
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiControlListPopUp);
|
||||
|
||||
bool GuiControlListPopUp::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
clear();
|
||||
|
||||
for(AbstractClassRep *rep = AbstractClassRep::getClassList(); rep; rep = rep->getNextClass())
|
||||
{
|
||||
ConsoleObject *obj = rep->create();
|
||||
if(obj && dynamic_cast<GuiControl *>(obj))
|
||||
{
|
||||
if( !dynamic_cast<GuiCanvas*>(obj) && !dynamic_cast<GuiInputCtrl*>(obj))
|
||||
addEntry(rep->getClassName(), 0);
|
||||
}
|
||||
delete obj;
|
||||
}
|
||||
|
||||
// We want to be alphabetical!
|
||||
sort();
|
||||
|
||||
return true;
|
||||
}
|
702
engine/gui/editor/guiDebugger.cc
Executable file
702
engine/gui/editor/guiDebugger.cc
Executable file
@ -0,0 +1,702 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "console/console.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "gui/core/guiCanvas.h"
|
||||
#include "gui/editor/guiDebugger.h"
|
||||
#include "core/stream.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(DbgFileView);
|
||||
|
||||
static const char* itoa(S32 i)
|
||||
{
|
||||
static char buf[32];
|
||||
dSprintf(buf, sizeof(buf), "%d", i);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const char* itoa2(S32 i)
|
||||
{
|
||||
static char buf[32];
|
||||
dSprintf(buf, sizeof(buf), "%d", i);
|
||||
return buf;
|
||||
}
|
||||
|
||||
DbgFileView::~DbgFileView()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
DbgFileView::DbgFileView()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION(mFileView);
|
||||
|
||||
mFileName = NULL;
|
||||
mPCFileName = NULL;
|
||||
mPCCurrentLine = -1;
|
||||
|
||||
mBlockStart = -1;
|
||||
mBlockEnd = -1;
|
||||
|
||||
mFindString[0] = '\0';
|
||||
mFindLineNumber = -1;
|
||||
|
||||
mSize.set(1, 0);
|
||||
}
|
||||
|
||||
ConsoleMethod(DbgFileView, setCurrentLine, void, 4, 4, "(int line, bool selected)"
|
||||
"Set the current highlighted line.")
|
||||
{
|
||||
object->setCurrentLine(dAtoi(argv[2]), dAtob(argv[3]));
|
||||
}
|
||||
|
||||
ConsoleMethod(DbgFileView, getCurrentLine, const char *, 2, 2, "()"
|
||||
"Get the currently executing file and line, if any.\n\n"
|
||||
"@returns A string containing the file, a tab, and then the line number."
|
||||
" Use getField() with this.")
|
||||
{
|
||||
S32 lineNum;
|
||||
const char *file = object->getCurrentLine(lineNum);
|
||||
char* ret = Con::getReturnBuffer(256);
|
||||
dSprintf(ret, sizeof(ret), "%s\t%d", file, lineNum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ConsoleMethod(DbgFileView, open, bool, 3, 3, "(string filename)"
|
||||
"Open a file for viewing.\n\n"
|
||||
"@note This loads the file from the local system.")
|
||||
{
|
||||
return object->openFile(argv[2]);
|
||||
}
|
||||
|
||||
ConsoleMethod(DbgFileView, clearBreakPositions, void, 2, 2, "()"
|
||||
"Clear all break points in the current file.")
|
||||
{
|
||||
object->clearBreakPositions();
|
||||
}
|
||||
|
||||
ConsoleMethod(DbgFileView, setBreakPosition, void, 3, 3, "(int line)"
|
||||
"Set a breakpoint at the specified line.")
|
||||
{
|
||||
object->setBreakPosition(dAtoi(argv[2]));
|
||||
}
|
||||
|
||||
ConsoleMethod(DbgFileView, setBreak, void, 3, 3, "(int line)"
|
||||
"Set a breakpoint at the specified line.")
|
||||
{
|
||||
object->setBreakPointStatus(dAtoi(argv[2]), true);
|
||||
}
|
||||
|
||||
ConsoleMethod(DbgFileView, removeBreak, void, 3, 3, "(int line)"
|
||||
"Remove a breakpoint from the specified line.")
|
||||
{
|
||||
object->setBreakPointStatus(dAtoi(argv[2]), false);
|
||||
}
|
||||
|
||||
ConsoleMethod(DbgFileView, findString, bool, 3, 3, "(string findThis)"
|
||||
"Find the specified string in the currently viewed file and "
|
||||
"scroll it into view.")
|
||||
{
|
||||
return object->findString(argv[2]);
|
||||
}
|
||||
|
||||
//this value is the offset used in the ::onRender() method...
|
||||
static S32 gFileXOffset = 44;
|
||||
|
||||
void DbgFileView::AdjustCellSize()
|
||||
{
|
||||
if (! bool(mFont))
|
||||
return;
|
||||
S32 maxWidth = 1;
|
||||
for (U32 i = 0; i < mFileView.size(); i++)
|
||||
{
|
||||
S32 cellWidth = gFileXOffset + mFont->getStrWidth((const UTF8 *)mFileView[i].text);
|
||||
maxWidth = getMax(maxWidth, cellWidth);
|
||||
}
|
||||
|
||||
mCellSize.set(maxWidth, mFont->getHeight() + 2);
|
||||
setSize(mSize);
|
||||
}
|
||||
|
||||
bool DbgFileView::onWake()
|
||||
{
|
||||
if (! Parent::onWake())
|
||||
return false;
|
||||
|
||||
//clear the mouse over var
|
||||
mMouseOverVariable[0] = '\0';
|
||||
mbMouseDragging = false;
|
||||
|
||||
//adjust the cellwidth to the maximum line length
|
||||
AdjustCellSize();
|
||||
mSize.set(1, mFileView.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DbgFileView::addLine(const char *string, U32 strLen)
|
||||
{
|
||||
// first compute the size
|
||||
U32 size = 1; // for null
|
||||
for(U32 i = 0; i < strLen; i++)
|
||||
{
|
||||
if(string[i] == '\t')
|
||||
size += 3;
|
||||
else if(string[i] != '\r')
|
||||
size++;
|
||||
}
|
||||
FileLine fl;
|
||||
fl.breakPosition = false;
|
||||
fl.breakOnLine = false;
|
||||
if(size)
|
||||
{
|
||||
fl.text = (char *) dMalloc(size);
|
||||
|
||||
U32 dstIndex = 0;
|
||||
for(U32 i = 0; i < strLen; i++)
|
||||
{
|
||||
if(string[i] == '\t')
|
||||
{
|
||||
fl.text[dstIndex] = ' ';
|
||||
fl.text[dstIndex + 1] = ' ';
|
||||
fl.text[dstIndex + 2] = ' ';
|
||||
dstIndex += 3;
|
||||
}
|
||||
else if(string[i] != '\r')
|
||||
fl.text[dstIndex++] = string[i];
|
||||
}
|
||||
fl.text[dstIndex] = 0;
|
||||
}
|
||||
else
|
||||
fl.text = NULL;
|
||||
mFileView.push_back(fl);
|
||||
}
|
||||
|
||||
void DbgFileView::clear()
|
||||
{
|
||||
for(Vector<FileLine>::iterator i = mFileView.begin(); i != mFileView.end(); i++)
|
||||
dFree(i->text);
|
||||
mFileView.clear();
|
||||
}
|
||||
|
||||
bool DbgFileView::findString(const char *text)
|
||||
{
|
||||
//make sure we have a valid string to find
|
||||
if (!text || !text[0])
|
||||
return false;
|
||||
|
||||
//see which line we start searching from
|
||||
S32 curLine = 0;
|
||||
bool searchAgain = false;
|
||||
if (mFindLineNumber >= 0 && !dStricmp(mFindString, text))
|
||||
{
|
||||
searchAgain = true;
|
||||
curLine = mFindLineNumber;
|
||||
}
|
||||
else
|
||||
mFindLineNumber = -1;
|
||||
|
||||
//copy the search text
|
||||
dStrncpy(mFindString, text, 255);
|
||||
S32 length = dStrlen(mFindString);
|
||||
|
||||
//loop through looking for the next instance
|
||||
while (curLine < mFileView.size())
|
||||
{
|
||||
char *curText;
|
||||
if (curLine == mFindLineNumber && mBlockStart >= 0)
|
||||
curText = &mFileView[curLine].text[mBlockStart + 1];
|
||||
else
|
||||
curText = &mFileView[curLine].text[0];
|
||||
|
||||
//search for the string (the hard way... - apparently dStrupr is broken...
|
||||
char *found = NULL;
|
||||
char *curTextPtr = curText;
|
||||
while (*curTextPtr != '\0')
|
||||
{
|
||||
if (!dStrnicmp(mFindString, curTextPtr, length))
|
||||
{
|
||||
found = curTextPtr;
|
||||
break;
|
||||
}
|
||||
else
|
||||
curTextPtr++;
|
||||
}
|
||||
|
||||
//did we find it?
|
||||
if (found)
|
||||
{
|
||||
//scroll first
|
||||
mFindLineNumber = curLine;
|
||||
scrollToLine(mFindLineNumber + 1);
|
||||
|
||||
//then hilite
|
||||
mBlockStart = (S32)(found - &mFileView[curLine].text[0]);
|
||||
mBlockEnd = mBlockStart + length;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
curLine++;
|
||||
}
|
||||
|
||||
//didn't find anything - reset the vars for the next search
|
||||
mBlockStart = -1;
|
||||
mBlockEnd = -1;
|
||||
mFindLineNumber = -1;
|
||||
|
||||
setSelectedCell(Point2I(-1, -1));
|
||||
return false;
|
||||
}
|
||||
|
||||
void DbgFileView::setCurrentLine(S32 lineNumber, bool setCurrentLine)
|
||||
{
|
||||
//update the line number
|
||||
if (setCurrentLine)
|
||||
{
|
||||
mPCFileName = mFileName;
|
||||
mPCCurrentLine = lineNumber;
|
||||
mBlockStart = -1;
|
||||
mBlockEnd = -1;
|
||||
if (lineNumber >= 0)
|
||||
scrollToLine(mPCCurrentLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
scrollToLine(lineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
const char* DbgFileView::getCurrentLine(S32 &lineNumber)
|
||||
{
|
||||
lineNumber = mPCCurrentLine;
|
||||
return mPCFileName;
|
||||
}
|
||||
|
||||
bool DbgFileView::openFile(const char *fileName)
|
||||
{
|
||||
if ((! fileName) || (! fileName[0]))
|
||||
return false;
|
||||
|
||||
StringTableEntry newFile = StringTable->insert(fileName);
|
||||
if (mFileName == newFile)
|
||||
return true;
|
||||
|
||||
U32 fileSize = ResourceManager->getSize(fileName);
|
||||
char *fileBuf;
|
||||
if (fileSize)
|
||||
{
|
||||
fileBuf = new char [fileSize+1];
|
||||
Stream *s = ResourceManager->openStream(fileName);
|
||||
if (s)
|
||||
{
|
||||
s->read(fileSize, fileBuf);
|
||||
ResourceManager->closeStream(s);
|
||||
fileBuf[fileSize] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
delete [] fileBuf;
|
||||
fileBuf = NULL;
|
||||
}
|
||||
}
|
||||
if (!fileSize || !fileBuf)
|
||||
{
|
||||
Con::printf("DbgFileView: unable to open file %s.", fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
//copy the file name
|
||||
mFileName = newFile;
|
||||
|
||||
//clear the old mFileView
|
||||
clear();
|
||||
setSize(Point2I(1, 0));
|
||||
|
||||
//begin reading and parsing at each '\n'
|
||||
char *parsePtr = fileBuf;
|
||||
for(;;) {
|
||||
char *tempPtr = dStrchr(parsePtr, '\n');
|
||||
if(tempPtr)
|
||||
addLine(parsePtr, tempPtr - parsePtr);
|
||||
else if(parsePtr[0])
|
||||
addLine(parsePtr, dStrlen(parsePtr));
|
||||
if(!tempPtr)
|
||||
break;
|
||||
parsePtr = tempPtr + 1;
|
||||
}
|
||||
//delete the buffer
|
||||
delete [] fileBuf;
|
||||
|
||||
//set the file size
|
||||
AdjustCellSize();
|
||||
setSize(Point2I(1, mFileView.size()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DbgFileView::scrollToLine(S32 lineNumber)
|
||||
{
|
||||
GuiControl *parent = getParent();
|
||||
if (! parent)
|
||||
return;
|
||||
|
||||
S32 yOffset = (lineNumber - 1) * mCellSize.y;
|
||||
|
||||
//see if the line is already visible
|
||||
if (! (yOffset + mBounds.point.y >= 0 && yOffset + mBounds.point.y < parent->mBounds.extent.y - mCellSize.y))
|
||||
{
|
||||
//reposition the control
|
||||
S32 newYOffset = getMin(0, getMax(parent->mBounds.extent.y - mBounds.extent.y, (mCellSize.y * 4) - yOffset));
|
||||
resize(Point2I(mBounds.point.x, newYOffset), mBounds.extent);
|
||||
}
|
||||
|
||||
//hilite the line
|
||||
cellSelected(Point2I(0, lineNumber - 1));
|
||||
}
|
||||
|
||||
S32 DbgFileView::findMouseOverChar(const char *text, S32 stringPosition)
|
||||
{
|
||||
static char tempBuf[512];
|
||||
char *bufPtr = &tempBuf[1];
|
||||
|
||||
// Handle the empty string correctly.
|
||||
if (text[0] == '\0') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Copy the line's text into the scratch buffer.
|
||||
dStrncpy(tempBuf, text, 512);
|
||||
|
||||
// Make sure we have a null terminator.
|
||||
tempBuf[511] = '\0';
|
||||
|
||||
// Loop over the characters...
|
||||
bool found = false;
|
||||
bool finished = false;
|
||||
do {
|
||||
// Note the current character, then replace it with EOL.
|
||||
char c = *bufPtr;
|
||||
*bufPtr = '\0';
|
||||
// Is the resulting string long enough to include the current
|
||||
// mouse position?
|
||||
if ((S32)mFont->getStrWidth((const UTF8 *)tempBuf) > stringPosition) {
|
||||
// Yep.
|
||||
// Restore the character.
|
||||
*bufPtr = c;
|
||||
// Set bufPtr to point to the char under the mouse.
|
||||
bufPtr--;
|
||||
// Bail.
|
||||
found = true;
|
||||
finished = true;
|
||||
}
|
||||
else {
|
||||
// Nope.
|
||||
// Restore the character.
|
||||
*bufPtr = c;
|
||||
// Move on to the next character.
|
||||
bufPtr++;
|
||||
// Bail if EOL.
|
||||
if (*bufPtr == '\0') finished = true;
|
||||
}
|
||||
} while (!finished);
|
||||
|
||||
// Did we find a character under the mouse?
|
||||
if (found) {
|
||||
// If so, return its position.
|
||||
return bufPtr - tempBuf;
|
||||
}
|
||||
// If not, return -1.
|
||||
else return -1;
|
||||
}
|
||||
|
||||
bool DbgFileView::findMouseOverVariable()
|
||||
{
|
||||
GuiCanvas *root = getRoot();
|
||||
AssertFatal(root, "Unable to get the root Canvas.");
|
||||
|
||||
Point2I curMouse = root->getCursorPos();
|
||||
Point2I pt = globalToLocalCoord(curMouse);
|
||||
|
||||
//find out which cell was hit
|
||||
Point2I cell((pt.x < 0 ? -1 : pt.x / mCellSize.x), (pt.y < 0 ? -1 : pt.y / mCellSize.y));
|
||||
if(cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y)
|
||||
{
|
||||
S32 stringPosition = pt.x - gFileXOffset;
|
||||
char tempBuf[256], *varNamePtr = &tempBuf[1];
|
||||
dStrcpy(tempBuf, mFileView[cell.y].text);
|
||||
|
||||
//find the current mouse over char
|
||||
S32 charNum = findMouseOverChar(mFileView[cell.y].text, stringPosition);
|
||||
if (charNum >= 0)
|
||||
{
|
||||
varNamePtr = &tempBuf[charNum];
|
||||
}
|
||||
else
|
||||
{
|
||||
mMouseOverVariable[0] = '\0';
|
||||
mMouseOverValue[0] = '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
//now make sure we can go from the current cursor mPosition to the beginning of a var name
|
||||
bool found = false;
|
||||
while (varNamePtr >= &tempBuf[0])
|
||||
{
|
||||
if (*varNamePtr == '%' || *varNamePtr == '$')
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
else if ((dToupper(*varNamePtr) >= 'A' && dToupper(*varNamePtr) <= 'Z') ||
|
||||
(*varNamePtr >= '0' && *varNamePtr <= '9') || *varNamePtr == '_' || *varNamePtr == ':')
|
||||
{
|
||||
varNamePtr--;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//mouse wasn't over a possible variable name
|
||||
if (! found)
|
||||
{
|
||||
mMouseOverVariable[0] = '\0';
|
||||
mMouseOverValue[0] = '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
//set the var char start positions
|
||||
mMouseVarStart = varNamePtr - tempBuf;
|
||||
|
||||
//now copy the (possible) var name into the buf
|
||||
char *tempPtr = &mMouseOverVariable[0];
|
||||
|
||||
//copy the leading '%' or '$'
|
||||
*tempPtr++ = *varNamePtr++;
|
||||
|
||||
//now copy letters and numbers until the end of the name
|
||||
while ((dToupper(*varNamePtr) >= 'A' && dToupper(*varNamePtr) <= 'Z') ||
|
||||
(*varNamePtr >= '0' && *varNamePtr <= '9') || *varNamePtr == '_' || *varNamePtr == ':')
|
||||
{
|
||||
*tempPtr++ = *varNamePtr++;
|
||||
}
|
||||
*tempPtr = '\0';
|
||||
|
||||
//set the var char end positions
|
||||
mMouseVarEnd = varNamePtr - tempBuf;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DbgFileView::clearBreakPositions()
|
||||
{
|
||||
for(Vector<FileLine>::iterator i = mFileView.begin(); i != mFileView.end(); i++)
|
||||
{
|
||||
i->breakPosition = false;
|
||||
i->breakOnLine = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DbgFileView::setBreakPosition(U32 line)
|
||||
{
|
||||
if(line > mFileView.size())
|
||||
return;
|
||||
mFileView[line-1].breakPosition = true;
|
||||
}
|
||||
|
||||
void DbgFileView::setBreakPointStatus(U32 line, bool set)
|
||||
{
|
||||
if(line > mFileView.size())
|
||||
return;
|
||||
mFileView[line-1].breakOnLine = set;
|
||||
}
|
||||
|
||||
void DbgFileView::onPreRender()
|
||||
{
|
||||
setUpdate();
|
||||
char oldVar[256];
|
||||
dStrcpy(oldVar, mMouseOverVariable);
|
||||
bool found = findMouseOverVariable();
|
||||
if (found && mPCCurrentLine >= 0)
|
||||
{
|
||||
//send the query only when the var changes
|
||||
if (dStricmp(oldVar, mMouseOverVariable))
|
||||
Con::executef(2, "DbgSetCursorWatch", mMouseOverVariable);
|
||||
}
|
||||
else
|
||||
Con::executef(2, "DbgSetCursorWatch", "");
|
||||
}
|
||||
|
||||
void DbgFileView::onMouseDown(const GuiEvent &event)
|
||||
{
|
||||
if (! mActive)
|
||||
{
|
||||
Parent::onMouseDown(event);
|
||||
return;
|
||||
}
|
||||
|
||||
Point2I pt = globalToLocalCoord(event.mousePoint);
|
||||
bool doubleClick = (event.mouseClickCount > 1);
|
||||
|
||||
//find out which cell was hit
|
||||
Point2I cell((pt.x < 0 ? -1 : pt.x / mCellSize.x), (pt.y < 0 ? -1 : pt.y / mCellSize.y));
|
||||
if(cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y)
|
||||
{
|
||||
//if we clicked on the breakpoint mark
|
||||
if (pt.x >= 0 && pt.x <= 12)
|
||||
{
|
||||
//toggle the break point
|
||||
if (mFileView[cell.y].breakPosition)
|
||||
{
|
||||
if (mFileView[cell.y].breakOnLine)
|
||||
Con::executef(this, 2, "onRemoveBreakPoint", itoa(cell.y + 1));
|
||||
else
|
||||
Con::executef(this, 2, "onSetBreakPoint", itoa(cell.y + 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Point2I prevSelected = mSelectedCell;
|
||||
Parent::onMouseDown(event);
|
||||
mBlockStart= -1;
|
||||
mBlockEnd = -1;
|
||||
|
||||
//open the file view
|
||||
if (mSelectedCell.y == prevSelected.y && doubleClick && mMouseOverVariable[0])
|
||||
{
|
||||
Con::executef(this, 2, "onSetWatch", mMouseOverVariable);
|
||||
mBlockStart = mMouseVarStart;
|
||||
mBlockEnd = mMouseVarEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 stringPosition = pt.x - gFileXOffset;
|
||||
|
||||
//find which character we're over
|
||||
S32 charNum = findMouseOverChar(mFileView[mSelectedCell.y].text, stringPosition);
|
||||
if (charNum >= 0)
|
||||
{
|
||||
//lock the mouse
|
||||
mouseLock();
|
||||
setFirstResponder();
|
||||
|
||||
//set the block hilite start and end
|
||||
mbMouseDragging = true;
|
||||
mMouseDownChar = charNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Parent::onMouseDown(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DbgFileView::onMouseDragged(const GuiEvent &event)
|
||||
{
|
||||
if (mbMouseDragging)
|
||||
{
|
||||
Point2I pt = globalToLocalCoord(event.mousePoint);
|
||||
S32 stringPosition = pt.x - gFileXOffset;
|
||||
|
||||
//find which character we're over
|
||||
S32 charNum = findMouseOverChar(mFileView[mSelectedCell.y].text, stringPosition);
|
||||
if (charNum >= 0)
|
||||
{
|
||||
if (charNum < mMouseDownChar)
|
||||
{
|
||||
|
||||
mBlockEnd = mMouseDownChar + 1;
|
||||
mBlockStart = charNum;
|
||||
}
|
||||
else
|
||||
{
|
||||
mBlockEnd = charNum + 1;
|
||||
mBlockStart = mMouseDownChar;
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise, the cursor is past the end of the string
|
||||
else
|
||||
{
|
||||
mBlockStart = mMouseDownChar;
|
||||
mBlockEnd = dStrlen(mFileView[mSelectedCell.y].text) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DbgFileView::onMouseUp(const GuiEvent &)
|
||||
{
|
||||
//unlock the mouse
|
||||
mouseUnlock();
|
||||
|
||||
mbMouseDragging = false;
|
||||
}
|
||||
|
||||
void DbgFileView::onRenderCell(Point2I offset, Point2I cell, bool selected, bool)
|
||||
{
|
||||
Point2I cellOffset = offset;
|
||||
cellOffset.x += 4;
|
||||
|
||||
//draw the break point marks
|
||||
if (mFileView[cell.y].breakOnLine)
|
||||
{
|
||||
dglSetBitmapModulation(mProfile->mFontColorHL);
|
||||
dglDrawText(mFont, cellOffset, "#");
|
||||
}
|
||||
else if (mFileView[cell.y].breakPosition)
|
||||
{
|
||||
dglSetBitmapModulation(mProfile->mFontColor);
|
||||
dglDrawText(mFont, cellOffset, "-");
|
||||
}
|
||||
cellOffset.x += 8;
|
||||
|
||||
//draw in the "current line" indicator
|
||||
if (mFileName == mPCFileName && (cell.y + 1 == mPCCurrentLine))
|
||||
{
|
||||
dglSetBitmapModulation(mProfile->mFontColorHL);
|
||||
dglDrawText(mFont, cellOffset, "=>");
|
||||
}
|
||||
|
||||
//by this time, the cellOffset has been incremented by 44 - the value of gFileXOffset
|
||||
cellOffset.x += 32;
|
||||
|
||||
//hilite the line if selected
|
||||
if (selected)
|
||||
{
|
||||
if (mBlockStart == -1)
|
||||
{
|
||||
dglDrawRectFill(RectI(cellOffset.x - 2, cellOffset.y - 3,
|
||||
mCellSize.x + 4, mCellSize.y + 6), mProfile->mFillColorHL);
|
||||
}
|
||||
else if (mBlockStart >= 0 && mBlockEnd > mBlockStart && mBlockEnd <= S32(dStrlen(mFileView[cell.y].text) + 1))
|
||||
{
|
||||
S32 startPos, endPos;
|
||||
char tempBuf[256];
|
||||
dStrcpy(tempBuf, mFileView[cell.y].text);
|
||||
|
||||
//get the end coord
|
||||
tempBuf[mBlockEnd] = '\0';
|
||||
endPos = mFont->getStrWidth((const UTF8 *)tempBuf);
|
||||
|
||||
//get the start coord
|
||||
tempBuf[mBlockStart] = '\0';
|
||||
startPos = mFont->getStrWidth((const UTF8 *)tempBuf);
|
||||
|
||||
//draw the hilite
|
||||
dglDrawRectFill(RectI(cellOffset.x + startPos, cellOffset.y - 3, endPos - startPos + 2, mCellSize.y + 6), mProfile->mFillColorHL);
|
||||
}
|
||||
}
|
||||
|
||||
//draw the line of text
|
||||
dglSetBitmapModulation(mFileView[cell.y].breakOnLine ? mProfile->mFontColorHL : mProfile->mFontColor);
|
||||
dglDrawText(mFont, cellOffset, mFileView[cell.y].text);
|
||||
}
|
82
engine/gui/editor/guiDebugger.h
Executable file
82
engine/gui/editor/guiDebugger.h
Executable file
@ -0,0 +1,82 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUIDEBUGGER_H_
|
||||
#define _GUIDEBUGGER_H_
|
||||
|
||||
#ifndef _GUIARRAYCTRL_H_
|
||||
#include "gui/core/guiArrayCtrl.h"
|
||||
#endif
|
||||
|
||||
class DbgFileView : public GuiArrayCtrl
|
||||
{
|
||||
private:
|
||||
|
||||
typedef GuiArrayCtrl Parent;
|
||||
|
||||
struct FileLine
|
||||
{
|
||||
bool breakPosition;
|
||||
bool breakOnLine;
|
||||
char *text;
|
||||
};
|
||||
|
||||
Vector<FileLine> mFileView;
|
||||
|
||||
StringTableEntry mFileName;
|
||||
|
||||
void AdjustCellSize();
|
||||
|
||||
//used to display the program counter
|
||||
StringTableEntry mPCFileName;
|
||||
S32 mPCCurrentLine;
|
||||
|
||||
//vars used to highlight the selected line segment for copying
|
||||
bool mbMouseDragging;
|
||||
S32 mMouseDownChar;
|
||||
S32 mBlockStart;
|
||||
S32 mBlockEnd;
|
||||
|
||||
char mMouseOverVariable[256];
|
||||
char mMouseOverValue[256];
|
||||
S32 findMouseOverChar(const char *text, S32 stringPosition);
|
||||
bool findMouseOverVariable();
|
||||
S32 mMouseVarStart;
|
||||
S32 mMouseVarEnd;
|
||||
|
||||
//find vars
|
||||
char mFindString[256];
|
||||
S32 mFindLineNumber;
|
||||
|
||||
public:
|
||||
|
||||
DbgFileView();
|
||||
~DbgFileView();
|
||||
DECLARE_CONOBJECT(DbgFileView);
|
||||
|
||||
bool onWake();
|
||||
|
||||
void clear();
|
||||
void clearBreakPositions();
|
||||
|
||||
void setCurrentLine(S32 lineNumber, bool setCurrentLine);
|
||||
const char *getCurrentLine(S32 &lineNumber);
|
||||
bool openFile(const char *fileName);
|
||||
void scrollToLine(S32 lineNumber);
|
||||
void setBreakPointStatus(U32 lineNumber, bool value);
|
||||
void setBreakPosition(U32 line);
|
||||
void addLine(const char *text, U32 textLen);
|
||||
|
||||
bool findString(const char *text);
|
||||
|
||||
void onMouseDown(const GuiEvent &event);
|
||||
void onMouseDragged(const GuiEvent &event);
|
||||
void onMouseUp(const GuiEvent &event);
|
||||
|
||||
void onPreRender();
|
||||
void onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver);
|
||||
};
|
||||
|
||||
#endif //_GUI_DEBUGGER_H
|
1162
engine/gui/editor/guiEditCtrl.cc
Executable file
1162
engine/gui/editor/guiEditCtrl.cc
Executable file
File diff suppressed because it is too large
Load Diff
98
engine/gui/editor/guiEditCtrl.h
Executable file
98
engine/gui/editor/guiEditCtrl.h
Executable file
@ -0,0 +1,98 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUIEDITCTRL_H_
|
||||
#define _GUIEDITCTRL_H_
|
||||
|
||||
#ifndef _GUICONTROL_H_
|
||||
#include "gui/core/guiControl.h"
|
||||
#endif
|
||||
|
||||
class GuiEditCtrl : public GuiControl
|
||||
{
|
||||
typedef GuiControl Parent;
|
||||
|
||||
Vector<GuiControl *> mSelectedControls;
|
||||
GuiControl* mCurrentAddSet;
|
||||
GuiControl* mContentControl;
|
||||
Point2I mLastMousePos;
|
||||
Point2I mSelectionAnchor;
|
||||
Point2I mGridSnap;
|
||||
Point2I mDragBeginPoint;
|
||||
Vector<Point2I> mDragBeginPoints;
|
||||
|
||||
// Sizing Cursors
|
||||
GuiCursor* mDefaultCursor;
|
||||
GuiCursor* mLeftRightCursor;
|
||||
GuiCursor* mUpDownCursor;
|
||||
GuiCursor* mNWSECursor;
|
||||
GuiCursor* mNESWCursor;
|
||||
GuiCursor* mMoveCursor;
|
||||
|
||||
enum mouseModes { Selecting, MovingSelection, SizingSelection, DragSelecting };
|
||||
enum sizingModes { sizingNone = 0, sizingLeft = 1, sizingRight = 2, sizingTop = 4, sizingBottom = 8 };
|
||||
|
||||
mouseModes mMouseDownMode;
|
||||
sizingModes mSizingMode;
|
||||
|
||||
public:
|
||||
GuiEditCtrl();
|
||||
DECLARE_CONOBJECT(GuiEditCtrl);
|
||||
|
||||
bool onWake();
|
||||
void onSleep();
|
||||
|
||||
void select(GuiControl *ctrl);
|
||||
void setRoot(GuiControl *ctrl);
|
||||
void setEditMode(bool value);
|
||||
S32 getSizingHitKnobs(const Point2I &pt, const RectI &box);
|
||||
void getDragRect(RectI &b);
|
||||
void drawNut(const Point2I &nut, ColorI &outlineColor, ColorI &nutColor);
|
||||
void drawNuts(RectI &box, ColorI &outlineColor, ColorI &nutColor);
|
||||
void onPreRender();
|
||||
void onRender(Point2I offset, const RectI &updateRect);
|
||||
void addNewControl(GuiControl *ctrl);
|
||||
bool selectionContains(GuiControl *ctrl);
|
||||
void setCurrentAddSet(GuiControl *ctrl);
|
||||
void setSelection(GuiControl *ctrl, bool inclusive = false);
|
||||
|
||||
// Sizing Cursors
|
||||
bool initCursors();
|
||||
void getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent);
|
||||
|
||||
|
||||
const Vector<GuiControl *> *getSelected() const { return &mSelectedControls; }
|
||||
const GuiControl *getAddSet() const { return mCurrentAddSet; }; //JDD
|
||||
|
||||
bool onKeyDown(const GuiEvent &event);
|
||||
void onMouseDown(const GuiEvent &event);
|
||||
void onMouseUp(const GuiEvent &event);
|
||||
void onMouseDragged(const GuiEvent &event);
|
||||
void onRightMouseDown(const GuiEvent &event);
|
||||
|
||||
enum Justification {
|
||||
JUSTIFY_LEFT,
|
||||
JUSTIFY_CENTER,
|
||||
JUSTIFY_RIGHT,
|
||||
JUSTIFY_TOP,
|
||||
JUSTIFY_BOTTOM,
|
||||
SPACING_VERTICAL,
|
||||
SPACING_HORIZONTAL
|
||||
};
|
||||
|
||||
void justifySelection( Justification j);
|
||||
void moveSelection(const Point2I &delta);
|
||||
void saveSelection(const char *filename);
|
||||
void loadSelection(const char *filename);
|
||||
void addSelection(S32 id);
|
||||
void removeSelection(S32 id);
|
||||
void deleteSelection();
|
||||
void clearSelection();
|
||||
void selectAll();
|
||||
void bringToFront();
|
||||
void pushToBack();
|
||||
};
|
||||
|
||||
#endif //_GUI_EDIT_CTRL_H
|
246
engine/gui/editor/guiFilterCtrl.cc
Executable file
246
engine/gui/editor/guiFilterCtrl.cc
Executable file
@ -0,0 +1,246 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "dgl/gTexManager.h"
|
||||
#include "gui/editor/guiFilterCtrl.h"
|
||||
#include "platform/event.h"
|
||||
#include "math/mMath.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiFilterCtrl);
|
||||
|
||||
GuiFilterCtrl::GuiFilterCtrl()
|
||||
{
|
||||
mControlPointRequest = 7;
|
||||
mFilter.setSize(7);
|
||||
identity();
|
||||
}
|
||||
|
||||
|
||||
void GuiFilterCtrl::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
addField("controlPoints", TypeS32, Offset(mControlPointRequest, GuiFilterCtrl));
|
||||
addField("filter", TypeF32Vector, Offset(mFilter, GuiFilterCtrl));
|
||||
}
|
||||
|
||||
ConsoleMethod( GuiFilterCtrl, getValue, const char*, 2, 2, "Return a tuple containing all the values in the filter.")
|
||||
{
|
||||
argv;
|
||||
static char buffer[512];
|
||||
const Filter *filter = object->get();
|
||||
*buffer = 0;
|
||||
|
||||
for (U32 i=0; i < filter->size(); i++)
|
||||
{
|
||||
char value[32];
|
||||
dSprintf(value, 31, "%1.5f ", *(filter->begin()+i) );
|
||||
dStrcat(buffer, value);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ConsoleMethod( GuiFilterCtrl, setValue, void, 3, 20, "(f1, f2, ...)"
|
||||
"Reset the filter to use the specified points, spread equidistantly across the domain.")
|
||||
{
|
||||
Filter filter;
|
||||
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
|
||||
filter.set(argc, argv);
|
||||
object->set(filter);
|
||||
}
|
||||
|
||||
ConsoleMethod( GuiFilterCtrl, identity, void, 2, 2, "Reset the filtering.")
|
||||
{
|
||||
object->identity();
|
||||
}
|
||||
|
||||
bool GuiFilterCtrl::onWake()
|
||||
{
|
||||
if (!Parent::onWake())
|
||||
return false;
|
||||
|
||||
if (U32(mControlPointRequest) != mFilter.size())
|
||||
{
|
||||
mFilter.setSize(mControlPointRequest);
|
||||
identity();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void GuiFilterCtrl::identity()
|
||||
{
|
||||
S32 size = mFilter.size()-1;
|
||||
for (U32 i=0; S32(i) <= size; i++)
|
||||
mFilter[i] = (F32)i/(F32)size;
|
||||
}
|
||||
|
||||
|
||||
void GuiFilterCtrl::onMouseDown(const GuiEvent &event)
|
||||
{
|
||||
mouseLock();
|
||||
setFirstResponder();
|
||||
|
||||
Point2I p = globalToLocalCoord(event.mousePoint);
|
||||
|
||||
// determine which knot (offset same as in onRender)
|
||||
F32 w = F32(mBounds.extent.x-4) / F32(mFilter.size()-1);
|
||||
F32 val = (F32(p.x) + (w / 2.f)) / w;
|
||||
mCurKnot = S32(val);
|
||||
|
||||
mFilter[mCurKnot] = 1.0f - F32(getMin(getMax(0, p.y), mBounds.extent.y)/(F32)mBounds.extent.y);
|
||||
setUpdate();
|
||||
}
|
||||
|
||||
|
||||
void GuiFilterCtrl::onMouseDragged(const GuiEvent &event)
|
||||
{
|
||||
mouseLock();
|
||||
setFirstResponder();
|
||||
|
||||
Point2I p = globalToLocalCoord(event.mousePoint);
|
||||
mFilter[mCurKnot] = 1.0f - F32(getMin(getMax(0, p.y), mBounds.extent.y)/(F32)mBounds.extent.y);
|
||||
setUpdate();
|
||||
}
|
||||
|
||||
void GuiFilterCtrl::onMouseUp(const GuiEvent &)
|
||||
{
|
||||
mouseUnlock();
|
||||
if (mConsoleCommand[0])
|
||||
{
|
||||
char buf[16];
|
||||
dSprintf(buf, sizeof(buf), "%d", getId());
|
||||
Con::setVariable("$ThisControl", buf);
|
||||
Con::evaluate(mConsoleCommand, false);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiFilterCtrl::onPreRender()
|
||||
{
|
||||
if(U32(mControlPointRequest) != mFilter.size())
|
||||
{
|
||||
mFilter.setSize(mControlPointRequest);
|
||||
identity();
|
||||
setUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void GuiFilterCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||
{
|
||||
Point2I pos = offset;
|
||||
Point2I ext = mBounds.extent;
|
||||
|
||||
RectI r(pos, ext);
|
||||
dglDrawRectFill(r, ColorI(255,255,255));
|
||||
dglDrawRect(r, ColorI(0,0,0));
|
||||
|
||||
// shrink by 2 pixels
|
||||
pos.x += 2;
|
||||
pos.y += 2;
|
||||
ext.x -= 4;
|
||||
ext.y -= 4;
|
||||
|
||||
// draw the identity line
|
||||
glColor3f(0.9, 0.9, 0.9);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2i(pos.x, pos.y+ext.y);
|
||||
glVertex2i(pos.x+ext.x, pos.y);
|
||||
glEnd();
|
||||
|
||||
// draw the curv
|
||||
glColor3f(0.4, 0.4, 0.4);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
|
||||
F32 scale = 1.0f/F32(ext.x);
|
||||
for (U32 i=0; S32(i) < ext.x; i++)
|
||||
{
|
||||
F32 index = F32(i)*scale;
|
||||
S32 y = (S32)(ext.y*(1.0f-mFilter.getValue(index)));
|
||||
glVertex2i(pos.x+i, pos.y+y );
|
||||
}
|
||||
glEnd();
|
||||
|
||||
// draw the knots
|
||||
for (U32 k=0; k < mFilter.size(); k++)
|
||||
{
|
||||
RectI r;
|
||||
r.point.x = (S32)(((F32)ext.x/(F32)(mFilter.size()-1)*(F32)k));
|
||||
r.point.y = (S32)(ext.y - ((F32)ext.y * mFilter[k]));
|
||||
r.point += pos + Point2I(-2,-2);
|
||||
r.extent = Point2I(5,5);
|
||||
|
||||
dglDrawRectFill(r, ColorI(255,0,0));
|
||||
}
|
||||
|
||||
renderChildControls(offset, updateRect);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
void Filter::set(S32 argc, const char *argv[])
|
||||
{
|
||||
setSize(0);
|
||||
if (argc == 1)
|
||||
{ // in the form of one string "1.0 1.0 1.0"
|
||||
char list[1024];
|
||||
dStrcpy(list, *argv); // strtok modifies the string so we need to copy it
|
||||
char *value = dStrtok(list, " ");
|
||||
while (value)
|
||||
{
|
||||
push_back(dAtof(value));
|
||||
value = dStrtok(NULL, " ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // in the form of seperate strings "1.0" "1.0" "1.0"
|
||||
for (; argc ; argc--, argv++)
|
||||
push_back(dAtof(*argv));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
F32 Filter::getValue(F32 x) const
|
||||
{
|
||||
if (size() < 2)
|
||||
return 0.0f;
|
||||
|
||||
x = mClampF(x, 0.0f, 1.0f);
|
||||
x *= F32(size()-1);
|
||||
|
||||
F32 p0,p1,p2,p3;
|
||||
S32 i1 = (S32)mFloor(x);
|
||||
S32 i2 = i1+1;
|
||||
F32 dt = x - F32(i1);
|
||||
|
||||
p1 = *(begin()+i1);
|
||||
p2 = *(begin()+i2);
|
||||
|
||||
if (i1 == 0)
|
||||
p0 = p1 + (p1 - p2);
|
||||
else
|
||||
p0 = *(begin()+i1-1);
|
||||
|
||||
if (i2 == S32(size()-1))
|
||||
p3 = p2 + (p2 - p1);
|
||||
else
|
||||
p3 = *(begin()+i2+1);
|
||||
|
||||
return mClampF( mCatmullrom(dt, p0, p1, p2, p3), 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
74
engine/gui/editor/guiFilterCtrl.h
Executable file
74
engine/gui/editor/guiFilterCtrl.h
Executable file
@ -0,0 +1,74 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUIFILTERCTRL_H_
|
||||
#define _GUIFILTERCTRL_H_
|
||||
|
||||
#ifndef _GUICONTROL_H_
|
||||
#include "gui/core/guiControl.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
// helper class
|
||||
class Filter: public Vector<F32>
|
||||
{
|
||||
public:
|
||||
Filter() : Vector<F32>(__FILE__, __LINE__) { }
|
||||
|
||||
void set(S32 argc, const char *argv[]);
|
||||
F32 getValue(F32 t) const;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
class GuiFilterCtrl : public GuiControl
|
||||
{
|
||||
private:
|
||||
typedef GuiControl Parent;
|
||||
|
||||
S32 mControlPointRequest;
|
||||
S32 mCurKnot;
|
||||
Filter mFilter;
|
||||
|
||||
public:
|
||||
//creation methods
|
||||
DECLARE_CONOBJECT(GuiFilterCtrl);
|
||||
GuiFilterCtrl();
|
||||
static void initPersistFields();
|
||||
|
||||
//Parental methods
|
||||
bool onWake();
|
||||
|
||||
void onMouseDown(const GuiEvent &event);
|
||||
void onMouseDragged(const GuiEvent &event);
|
||||
void onMouseUp(const GuiEvent &);
|
||||
|
||||
F32 getValue(S32 n);
|
||||
const Filter* get() { return &mFilter; }
|
||||
void set(const Filter &f);
|
||||
S32 getNumControlPoints() {return mFilter.size(); }
|
||||
void identity();
|
||||
|
||||
void onPreRender();
|
||||
void onRender(Point2I offset, const RectI &updateRect );
|
||||
};
|
||||
|
||||
|
||||
inline F32 GuiFilterCtrl::getValue(S32 n)
|
||||
{
|
||||
S32 index = getMin(getMax(n,0), (S32)mFilter.size()-1);
|
||||
return mFilter[n];
|
||||
}
|
||||
|
||||
|
||||
inline void GuiFilterCtrl::set(const Filter &f)
|
||||
{
|
||||
mControlPointRequest = f.size();
|
||||
mFilter = f;
|
||||
}
|
||||
|
||||
#endif
|
350
engine/gui/editor/guiGraphCtrl.cc
Executable file
350
engine/gui/editor/guiGraphCtrl.cc
Executable file
@ -0,0 +1,350 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "dgl/dgl.h"
|
||||
|
||||
#include "gui/editor/guiGraphCtrl.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiGraphCtrl);
|
||||
|
||||
GuiGraphCtrl::GuiGraphCtrl()
|
||||
{
|
||||
|
||||
for(int i = 0; i < MaxPlots; i++)
|
||||
{
|
||||
mPlots[i].mAutoPlot = NULL;
|
||||
mPlots[i].mAutoPlotDelay = 0;
|
||||
mPlots[i].mGraphColor = ColorF(1.0, 1.0, 1.0);
|
||||
VECTOR_SET_ASSOCIATION(mPlots[i].mGraphData);
|
||||
mPlots[i].mGraphMax = 1;
|
||||
mPlots[i].mGraphType = Polyline;
|
||||
for(int j = 0; j < MaxDataPoints; j++)
|
||||
mPlots[i].mGraphData.push_front(0.0);
|
||||
}
|
||||
|
||||
AssertWarn(MaxPlots == 6, "Only 6 plot colors initialized. Update following code if you change MaxPlots.");
|
||||
|
||||
mPlots[0].mGraphColor = ColorF(1.0, 1.0, 1.0);
|
||||
mPlots[1].mGraphColor = ColorF(1.0, 0.0, 0.0);
|
||||
mPlots[2].mGraphColor = ColorF(0.0, 1.0, 0.0);
|
||||
mPlots[3].mGraphColor = ColorF(0.0, 0.0, 1.0);
|
||||
mPlots[4].mGraphColor = ColorF(0.0, 1.0, 1.0);
|
||||
mPlots[5].mGraphColor = ColorF(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
static EnumTable::Enums enumGraphTypes[] = {
|
||||
{ GuiGraphCtrl::Bar, "bar" },
|
||||
{ GuiGraphCtrl::Filled, "filled" },
|
||||
{ GuiGraphCtrl::Point, "point" },
|
||||
{ GuiGraphCtrl::Polyline , "polyline" },
|
||||
};
|
||||
|
||||
static EnumTable gGraphTypeTable( 4, &enumGraphTypes[0] );
|
||||
|
||||
bool GuiGraphCtrl::onWake()
|
||||
{
|
||||
if (! Parent::onWake())
|
||||
return false;
|
||||
setActive(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiGraphCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||
{
|
||||
if (mProfile->mBorder)
|
||||
{
|
||||
RectI rect(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
|
||||
dglDrawRect(rect, mProfile->mBorderColor);
|
||||
}
|
||||
|
||||
glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
|
||||
glEnable(GL_BLEND);
|
||||
ColorF color(1.0, 1.0, 1.0, 0.5);
|
||||
dglDrawRectFill(updateRect, color);
|
||||
glDisable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
|
||||
for (int k = 0; k < MaxPlots; k++)
|
||||
{
|
||||
|
||||
|
||||
// Check if there is an autoplot and the proper amount of time has passed, if so add datum.
|
||||
if((mPlots[k].mAutoPlot!=NULL) &&
|
||||
(mPlots[k].mAutoPlotDelay < (Sim::getCurrentTime() - mPlots[k].mAutoPlotLastDisplay)))
|
||||
{
|
||||
mPlots[k].mAutoPlotLastDisplay = Sim::getCurrentTime();
|
||||
addDatum(k, Con::getFloatVariable(mPlots[k].mAutoPlot));
|
||||
Con::setIntVariable(mPlots[k].mAutoPlot, 0);
|
||||
}
|
||||
|
||||
// Adjust scale to max value + 5% so we can see high values
|
||||
F32 Scale = (F32(getExtent().y) / (F32(mPlots[k].mGraphMax*1.05)));
|
||||
|
||||
// Nothing to graph
|
||||
if (mPlots[k].mGraphData.size() == 0)
|
||||
continue;
|
||||
|
||||
// Bar graph
|
||||
if(mPlots[k].mGraphType == Bar)
|
||||
{
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3fv(mPlots[k].mGraphColor);
|
||||
|
||||
S32 temp1,temp2;
|
||||
temp1 = 0;
|
||||
|
||||
for (S32 sample = 0; sample < getExtent().x; sample++)
|
||||
{
|
||||
if(mPlots[k].mGraphData.size() >= getExtent().x)
|
||||
temp2 = sample;
|
||||
else
|
||||
temp2 = (S32)(((F32)getExtent().x / (F32)mPlots[k].mGraphData.size()) * (F32)sample);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
temp1 = temp2;
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Filled graph
|
||||
else if(mPlots[k].mGraphType == Filled)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3fv(mPlots[k].mGraphColor);
|
||||
|
||||
S32 temp1,temp2;
|
||||
temp1 = 0;
|
||||
|
||||
for (S32 sample = 0; sample < (getExtent().x-1); sample++)
|
||||
{
|
||||
if(mPlots[k].mGraphData.size() >= getExtent().x)
|
||||
temp2 = sample;
|
||||
else
|
||||
temp2 = (S32)(((F32)getExtent().x / (F32)mPlots[k].mGraphData.size()) * (F32)sample);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample+1) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
temp1 = temp2;
|
||||
}
|
||||
|
||||
|
||||
// last point
|
||||
S32 sample = getExtent().x;
|
||||
|
||||
if(mPlots[k].mGraphData.size() >= getExtent().x)
|
||||
temp2 = sample;
|
||||
else
|
||||
temp2 = (S32)(((F32)getExtent().x / (F32)mPlots[k].mGraphData.size()) * (F32)sample);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
|
||||
glVertex2i(getPosition().x + temp2,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
glVertex2i(getPosition().x + temp1,
|
||||
getPosition().y + getExtent().y);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
// Point or Polyline graph
|
||||
else if((mPlots[k].mGraphType == Point) || (mPlots[k].mGraphType == Polyline))
|
||||
{
|
||||
if(mPlots[k].mGraphType == Point)
|
||||
glBegin(GL_POINTS);
|
||||
else
|
||||
glBegin(GL_LINE_STRIP);
|
||||
|
||||
glColor3fv(mPlots[k].mGraphColor);
|
||||
|
||||
for (S32 sample = 0; sample < getExtent().x; sample++)
|
||||
{
|
||||
S32 temp;
|
||||
if(mPlots[k].mGraphData.size() >= getExtent().x)
|
||||
temp = sample;
|
||||
else
|
||||
temp = (S32)(((F32)getExtent().x / (F32)mPlots[k].mGraphData.size()) * (F32)sample);
|
||||
|
||||
glVertex2i(getPosition().x + temp,
|
||||
(getPosition().y + getExtent().y) - (S32)(getDatum(k, sample) * Scale));
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GuiGraphCtrl::addDatum(S32 plotID, F32 v)
|
||||
{
|
||||
AssertFatal(plotID > -1 && plotID < MaxPlots, "Invalid plot specified!");
|
||||
|
||||
// Add the data and trim the vector...
|
||||
mPlots[plotID].mGraphData.push_front( v );
|
||||
|
||||
if(mPlots[plotID].mGraphData.size() > MaxDataPoints)
|
||||
mPlots[plotID].mGraphData.pop_back();
|
||||
|
||||
// Keep record of maximum data value for scaling purposes.
|
||||
if(v > mPlots[plotID].mGraphMax)
|
||||
mPlots[plotID].mGraphMax = v;
|
||||
}
|
||||
|
||||
float GuiGraphCtrl::getDatum( int plotID, int sample)
|
||||
{
|
||||
AssertFatal(plotID > -1 && plotID < MaxPlots, "Invalid plot specified!");
|
||||
AssertFatal(sample > -1 && sample < MaxDataPoints, "Invalid sample specified!");
|
||||
return mPlots[plotID].mGraphData[sample];
|
||||
}
|
||||
|
||||
void GuiGraphCtrl::addAutoPlot(S32 plotID, const char *variable, S32 update)
|
||||
{
|
||||
mPlots[plotID].mAutoPlot = StringTable->insert(variable);
|
||||
mPlots[plotID].mAutoPlotDelay = update;
|
||||
Con::setIntVariable(mPlots[plotID].mAutoPlot, 0);
|
||||
}
|
||||
|
||||
void GuiGraphCtrl::removeAutoPlot(S32 plotID)
|
||||
{
|
||||
mPlots[plotID].mAutoPlot = NULL;
|
||||
}
|
||||
|
||||
void GuiGraphCtrl::setGraphType(S32 plotID, const char *graphType)
|
||||
{
|
||||
AssertFatal(plotID > -1 && plotID < MaxPlots, "Invalid plot specified!");
|
||||
if(!dStricmp(graphType,"Bar"))
|
||||
mPlots[plotID].mGraphType = Bar;
|
||||
else if(!dStricmp(graphType,"Filled"))
|
||||
mPlots[plotID].mGraphType = Filled;
|
||||
else if(!dStricmp(graphType,"Point"))
|
||||
mPlots[plotID].mGraphType = Point;
|
||||
else if(!dStricmp(graphType,"Polyline"))
|
||||
mPlots[plotID].mGraphType = Polyline;
|
||||
else AssertWarn(true, "Invalid graph type!");
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, addDatum, void, 4, 4, "(int plotID, float v)"
|
||||
"Add a data point to the given plot.")
|
||||
{
|
||||
S32 plotID = dAtoi(argv[2]);
|
||||
if(plotID > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return;
|
||||
}
|
||||
object->addDatum( plotID, dAtof(argv[3]));
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, getDatum, F32, 4, 4, "(int plotID, int samples)"
|
||||
"Get a data point from the plot specified, samples from the start of the graph.")
|
||||
{
|
||||
S32 plotID = dAtoi(argv[2]);
|
||||
S32 samples = dAtoi(argv[3]);
|
||||
|
||||
if(plotID > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return -1;
|
||||
}
|
||||
if(samples > object->MaxDataPoints)
|
||||
{
|
||||
Con::errorf("Invalid sample.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return object->getDatum(plotID, samples);
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, addAutoPlot, void, 5, 5, "(int plotID, string variable, int update)"
|
||||
"Adds a data point with value variable, every update ms.")
|
||||
{
|
||||
S32 plotID = dAtoi(argv[2]);
|
||||
|
||||
if(plotID > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return;
|
||||
}
|
||||
|
||||
object->addAutoPlot(plotID,argv[3],dAtoi(argv[4]));
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, removeAutoPlot, void, 3, 3, "(int plotID)"
|
||||
"Stops automatic pointing over set interval.")
|
||||
{
|
||||
S32 plotID = dAtoi(argv[2]);
|
||||
|
||||
if(plotID > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return;
|
||||
}
|
||||
|
||||
object->removeAutoPlot(plotID);
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, setGraphType, void, 4, 4, "(int plotID, string graphType)"
|
||||
"Change GraphType of plot plotID.")
|
||||
{
|
||||
S32 plotID = dAtoi(argv[2]);
|
||||
|
||||
if(plotID > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return;
|
||||
}
|
||||
|
||||
object->setGraphType(dAtoi(argv[2]), argv[3]);
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiGraphCtrl, matchScale, void, 3, GuiGraphCtrl::MaxPlots+2, "(int plotID, int plotID, ...)"
|
||||
"Sets the scale of all specified plots to the maximum scale among them.")
|
||||
{
|
||||
F32 Max = 0;
|
||||
for(int i=0; i < (argc-2); i++)
|
||||
{
|
||||
if(dAtoi(argv[2+i]) > object->MaxPlots)
|
||||
{
|
||||
Con::errorf("Invalid plotID.");
|
||||
return;
|
||||
}
|
||||
if (object->mPlots[dAtoi(argv[2+i])].mGraphMax > Max)
|
||||
Max = object->mPlots[dAtoi(argv[2+i])].mGraphMax;
|
||||
}
|
||||
for(int i=0; i < (argc-2); i++)
|
||||
object->mPlots[dAtoi(argv[2+i])].mGraphMax = Max;
|
||||
}
|
65
engine/gui/editor/guiGraphCtrl.h
Executable file
65
engine/gui/editor/guiGraphCtrl.h
Executable file
@ -0,0 +1,65 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUIGRAPHCTRL_H_
|
||||
#define _GUIGRAPHCTRL_H_
|
||||
|
||||
#ifndef _GUICONTROL_H_
|
||||
#include "gui/core/guiControl.h"
|
||||
#endif
|
||||
#ifndef _GTEXMANAGER_H_
|
||||
#include "dgl/gTexManager.h"
|
||||
#endif
|
||||
|
||||
|
||||
class GuiGraphCtrl : public GuiControl
|
||||
{
|
||||
private:
|
||||
typedef GuiControl Parent;
|
||||
|
||||
public:
|
||||
enum Constants {
|
||||
MaxPlots = 6,
|
||||
MaxDataPoints = 200
|
||||
};
|
||||
|
||||
enum GraphType {
|
||||
Point,
|
||||
Polyline,
|
||||
Filled,
|
||||
Bar
|
||||
};
|
||||
|
||||
struct PlotInfo
|
||||
{
|
||||
const char *mAutoPlot;
|
||||
U32 mAutoPlotDelay;
|
||||
SimTime mAutoPlotLastDisplay;
|
||||
ColorF mGraphColor;
|
||||
Vector<F32> mGraphData;
|
||||
F32 mGraphMax;
|
||||
GraphType mGraphType;
|
||||
};
|
||||
|
||||
PlotInfo mPlots[MaxPlots];
|
||||
|
||||
//creation methods
|
||||
DECLARE_CONOBJECT(GuiGraphCtrl);
|
||||
GuiGraphCtrl();
|
||||
|
||||
//Parental methods
|
||||
bool onWake();
|
||||
|
||||
void onRender(Point2I offset, const RectI &updateRect);
|
||||
|
||||
// Graph interface
|
||||
void addDatum(S32 plotID, F32 v);
|
||||
F32 getDatum(S32 plotID, S32 samples);
|
||||
void addAutoPlot(S32 plotID, const char *variable, S32 update);
|
||||
void removeAutoPlot(S32 plotID);
|
||||
void setGraphType(S32 plotID, const char *graphType);
|
||||
};
|
||||
|
||||
#endif
|
1421
engine/gui/editor/guiInspector.cc
Executable file
1421
engine/gui/editor/guiInspector.cc
Executable file
File diff suppressed because it is too large
Load Diff
264
engine/gui/editor/guiInspector.h
Executable file
264
engine/gui/editor/guiInspector.h
Executable file
@ -0,0 +1,264 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _GUI_INSPECTOR_H_
|
||||
#define _GUI_INSPECTOR_H_
|
||||
|
||||
#ifndef _DYNAMIC_CONSOLETYPES_H_
|
||||
#include "console/dynamicTypes.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUICONTROL_H_
|
||||
#include "gui/core/guiControl.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUICANVAS_H_
|
||||
#include "gui/core/guiCanvas.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUISTACKCTRL_H_
|
||||
#include "gui/containers/guiStackCtrl.h"
|
||||
#endif
|
||||
|
||||
#ifndef _H_GUIDEFAULTCONTROLRENDER_
|
||||
#include "gui/core/guiDefaultControlRender.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUITICKCTRL_H_
|
||||
#include "gui/shiny/guiTickCtrl.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUISCROLLCTRL_H_
|
||||
#include "gui/containers/guiScrollCtrl.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUITEXTEDITCTRL_H_
|
||||
#include "gui/controls/guiTextEditCtrl.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUIBITMAPBUTTON_H_
|
||||
#include "gui/controls/guiBitmapButtonCtrl.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUIPOPUPCTRL_H_
|
||||
#include "gui/controls/guiPopUpCtrl.h"
|
||||
#endif
|
||||
|
||||
|
||||
// Forward Declare GuiInspectorGroup
|
||||
class GuiInspectorGroup;
|
||||
// Forward Declare GuiInspectorField
|
||||
class GuiInspectorField;
|
||||
// Forward Declare GuiInspectorDatablockField
|
||||
class GuiInspectorDatablockField;
|
||||
|
||||
class GuiInspector : public GuiStackControl
|
||||
{
|
||||
private:
|
||||
typedef GuiStackControl Parent;
|
||||
public:
|
||||
// Members
|
||||
Vector<GuiInspectorGroup*> mGroups;
|
||||
SimObjectPtr<SimObject> mTarget;
|
||||
|
||||
GuiInspector();
|
||||
~GuiInspector();
|
||||
DECLARE_CONOBJECT(GuiInspector);
|
||||
|
||||
virtual void parentResized(const Point2I &oldParentExtent, const Point2I &newParentExtent);
|
||||
void inspectObject( SimObject *object );
|
||||
inline SimObject *getInspectObject() { return mTarget.isNull() ? NULL : mTarget; };
|
||||
void setName( StringTableEntry newName );
|
||||
void clearGroups();
|
||||
bool onAdd();
|
||||
bool findExistentGroup( StringTableEntry groupName );
|
||||
};
|
||||
|
||||
class GuiInspectorField : public GuiControl
|
||||
{
|
||||
private:
|
||||
typedef GuiControl Parent;
|
||||
public:
|
||||
// Static Caption Width (in percentage) for all inspector fields
|
||||
static S32 smCaptionWidth;
|
||||
|
||||
// Members
|
||||
StringTableEntry mCaption;
|
||||
GuiInspectorGroup* mParent;
|
||||
SimObjectPtr<SimObject> mTarget;
|
||||
AbstractClassRep::Field* mField;
|
||||
StringTableEntry mFieldArrayIndex;
|
||||
|
||||
// Constructed Field Edit Control
|
||||
GuiControl* mEdit;
|
||||
|
||||
GuiInspectorField( GuiInspectorGroup* parent, SimObjectPtr<SimObject> target, AbstractClassRep::Field* field );
|
||||
GuiInspectorField();
|
||||
~GuiInspectorField();
|
||||
DECLARE_CONOBJECT(GuiInspectorField);
|
||||
|
||||
virtual void setTarget( SimObjectPtr<SimObject> target ) { mTarget = target; };
|
||||
virtual void setParent( GuiInspectorGroup* parent ) { mParent = parent; };
|
||||
virtual void setField( AbstractClassRep::Field *field, const char*arrayIndex = NULL );
|
||||
|
||||
protected:
|
||||
void registerEditControl( GuiControl *ctrl );
|
||||
public:
|
||||
virtual GuiControl* constructEditControl();
|
||||
virtual void updateValue( StringTableEntry newValue );
|
||||
virtual StringTableEntry getFieldName();
|
||||
virtual void setData( StringTableEntry data );
|
||||
virtual StringTableEntry getData();
|
||||
|
||||
virtual void resize(const Point2I &newPosition, const Point2I &newExtent);
|
||||
virtual bool onAdd();
|
||||
virtual void onRender(Point2I offset, const RectI &updateRect);
|
||||
};
|
||||
|
||||
class GuiInspectorGroup : public GuiTickCtrl
|
||||
{
|
||||
private:
|
||||
typedef GuiControl Parent;
|
||||
public:
|
||||
// Members
|
||||
StringTableEntry mCaption;
|
||||
Point2I mBarWidth;
|
||||
bool mIsExpanded;
|
||||
bool mIsAnimating;
|
||||
bool mCollapsing;
|
||||
S32 mAnimateDestHeight;
|
||||
S32 mAnimateStep;
|
||||
S32 mChildHeight;
|
||||
SimObjectPtr<SimObject> mTarget;
|
||||
SimObjectPtr<GuiInspector> mParent;
|
||||
Vector<GuiInspectorField*> mChildren;
|
||||
GuiStackControl* mStack;
|
||||
|
||||
// Constructor/Destructor/Conobject Declaration
|
||||
GuiInspectorGroup();
|
||||
GuiInspectorGroup( SimObjectPtr<SimObject> target, StringTableEntry groupName, SimObjectPtr<GuiInspector> parent );
|
||||
~GuiInspectorGroup();
|
||||
DECLARE_CONOBJECT(GuiInspectorGroup);
|
||||
|
||||
// Persistence ( Inspector Exposed Fields )
|
||||
static void initPersistFields();
|
||||
|
||||
// Mouse Events
|
||||
virtual void onMouseDown( const GuiEvent &event );
|
||||
|
||||
// Sizing Helpers
|
||||
virtual S32 getExpandedHeight();
|
||||
void resize( const Point2I &newPosition, const Point2I &newExtent );
|
||||
|
||||
// Sizing Animation Functions
|
||||
void animateTo( S32 height );
|
||||
virtual void processTick();
|
||||
|
||||
virtual GuiInspectorField* constructField( S32 fieldType );
|
||||
virtual GuiInspectorField* findField( StringTableEntry fieldName );
|
||||
|
||||
// Control Rendering
|
||||
virtual void onRender(Point2I offset, const RectI &updateRect);
|
||||
|
||||
// Publicly Accessible Information about this group
|
||||
StringTableEntry getGroupName() { return mCaption; };
|
||||
SimObjectPtr<SimObject> getGroupTarget() { return mTarget; };
|
||||
SimObjectPtr<GuiInspector> getContentCtrl() { return mParent; };
|
||||
|
||||
bool onAdd();
|
||||
virtual bool inspectGroup();
|
||||
|
||||
};
|
||||
|
||||
class GuiInspectorDynamicField : public GuiInspectorField
|
||||
{
|
||||
private:
|
||||
typedef GuiInspectorField Parent;
|
||||
SimObjectPtr<GuiControl> mRenameCtrl;
|
||||
public:
|
||||
SimFieldDictionary::Entry* mDynField;
|
||||
|
||||
GuiInspectorDynamicField( GuiInspectorGroup* parent, SimObjectPtr<SimObject> target, SimFieldDictionary::Entry* field );
|
||||
GuiInspectorDynamicField() {};
|
||||
~GuiInspectorDynamicField() {};
|
||||
DECLARE_CONOBJECT(GuiInspectorDynamicField);
|
||||
|
||||
virtual void setData( StringTableEntry data );
|
||||
virtual StringTableEntry getData();
|
||||
|
||||
virtual StringTableEntry getFieldName() { return ( mDynField != NULL ) ? mDynField->slotName : ""; };
|
||||
|
||||
// Override onAdd so we can construct our custom field name edit control
|
||||
virtual bool onAdd();
|
||||
// Rename a dynamic field
|
||||
void renameField( StringTableEntry newFieldName );
|
||||
// Create an edit control to overlay the field name (for renaming dynamic fields)
|
||||
GuiControl* constructRenameControl();
|
||||
// Rendering (We custom render this field type because it contains no caption rendering)
|
||||
virtual void onRender(Point2I offset, const RectI &updateRect);
|
||||
// Override parentResized so we can resize our renaming control
|
||||
virtual void resize(const Point2I &newPosition, const Point2I &newExtent);
|
||||
};
|
||||
|
||||
class GuiInspectorDynamicGroup : public GuiInspectorGroup
|
||||
{
|
||||
private:
|
||||
typedef GuiInspectorGroup Parent;
|
||||
public:
|
||||
GuiInspectorDynamicGroup( SimObjectPtr<SimObject> target, StringTableEntry groupName, SimObjectPtr<GuiInspector> parent ) : GuiInspectorGroup( target, groupName, parent) {};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// inspectGroup is overridden in GuiInspectorDynamicGroup to inspect an
|
||||
// objects FieldDictionary (dynamic fields) instead of regular persistent
|
||||
// fields.
|
||||
bool inspectGroup();
|
||||
|
||||
// For scriptable dynamic field additions
|
||||
void addDynamicField();
|
||||
|
||||
// To make sure we expand to show add field 'button'
|
||||
virtual S32 getExpandedHeight();
|
||||
|
||||
// Clear our fields (delete them)
|
||||
void clearFields();
|
||||
|
||||
// For handling creation of dynamic fields
|
||||
virtual void onMouseDown( const GuiEvent &event );
|
||||
|
||||
// Find an already existent field by name in the dictionary
|
||||
virtual SimFieldDictionary::Entry* findDynamicFieldInDictionary( StringTableEntry fieldName );
|
||||
|
||||
// Find an already existent field by name in the stack control
|
||||
virtual GuiInspectorDynamicField* findDynamicField( StringTableEntry fieldName );
|
||||
|
||||
|
||||
// Override onRender to add an 'Add Field' button
|
||||
virtual void onRender(Point2I offset, const RectI &updateRect);
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GuiInspectorDatablockField - custom field type for datablock enumeration
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class GuiInspectorDatablockField : public GuiInspectorField
|
||||
{
|
||||
private:
|
||||
typedef GuiInspectorField Parent;
|
||||
|
||||
AbstractClassRep *mDesiredClass;
|
||||
public:
|
||||
DECLARE_CONOBJECT(GuiInspectorDatablockField);
|
||||
GuiInspectorDatablockField( StringTableEntry className );
|
||||
GuiInspectorDatablockField() { mDesiredClass = NULL; };
|
||||
|
||||
void setClassName( StringTableEntry className );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Override able methods for custom edit fields (Both are REQUIRED)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual GuiControl* constructEditControl();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
350
engine/gui/editor/guiInspectorTypes.cc
Executable file
350
engine/gui/editor/guiInspectorTypes.cc
Executable file
@ -0,0 +1,350 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "gui/editor/guiInspectorTypes.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GuiInspectorTypeEnum
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_CONOBJECT(GuiInspectorTypeEnum);
|
||||
|
||||
GuiControl* GuiInspectorTypeEnum::constructEditControl()
|
||||
{
|
||||
GuiControl* retCtrl = new GuiPopUpMenuCtrl();
|
||||
|
||||
// If we couldn't construct the control, bail!
|
||||
if( retCtrl == NULL )
|
||||
return retCtrl;
|
||||
|
||||
GuiPopUpMenuCtrl *menu = dynamic_cast<GuiPopUpMenuCtrl*>(retCtrl);
|
||||
|
||||
// Let's make it look pretty.
|
||||
retCtrl->setField( "profile", "InspectorTypeEnumProfile" );
|
||||
|
||||
menu->setField("text", getData());
|
||||
|
||||
registerEditControl( retCtrl );
|
||||
|
||||
// Configure it to update our value when the popup is closed
|
||||
char szBuffer[512];
|
||||
dSprintf( szBuffer, 512, "%d.%s = %d.getText();%d.inspect(%d);",mTarget->getId(), mField->pFieldname, menu->getId(), mParent->mParent->getId(), mTarget->getId() );
|
||||
menu->setField("Command", szBuffer );
|
||||
|
||||
//now add the entries
|
||||
for(S32 i = 0; i < mField->table->size; i++)
|
||||
menu->addEntry(mField->table->table[i].label, mField->table->table[i].index);
|
||||
|
||||
return retCtrl;
|
||||
}
|
||||
|
||||
void GuiInspectorTypeEnum::consoleInit()
|
||||
{
|
||||
Parent::consoleInit();
|
||||
|
||||
ConsoleBaseType::getType(TypeEnum)->setInspectorFieldType("GuiInspectorTypeEnum");
|
||||
}
|
||||
|
||||
void GuiInspectorTypeEnum::updateValue( StringTableEntry newValue )
|
||||
{
|
||||
GuiPopUpMenuCtrl *ctrl = dynamic_cast<GuiPopUpMenuCtrl*>( mEdit );
|
||||
if( ctrl != NULL )
|
||||
ctrl->setText( newValue );
|
||||
}
|
||||
|
||||
void GuiInspectorTypeEnum::setData( StringTableEntry data )
|
||||
{
|
||||
if( mField == NULL || mTarget == NULL )
|
||||
return;
|
||||
|
||||
mTarget->setDataField( mField->pFieldname, NULL, data );
|
||||
|
||||
// Force our edit to update
|
||||
updateValue( data );
|
||||
}
|
||||
|
||||
StringTableEntry GuiInspectorTypeEnum::getData()
|
||||
{
|
||||
if( mField == NULL || mTarget == NULL )
|
||||
return "";
|
||||
|
||||
return mTarget->getDataField( mField->pFieldname, NULL );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GuiInspectorTypeCheckBox
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_CONOBJECT(GuiInspectorTypeCheckBox);
|
||||
|
||||
GuiControl* GuiInspectorTypeCheckBox::constructEditControl()
|
||||
{
|
||||
GuiControl* retCtrl = new GuiCheckBoxCtrl();
|
||||
|
||||
// If we couldn't construct the control, bail!
|
||||
if( retCtrl == NULL )
|
||||
return retCtrl;
|
||||
|
||||
GuiCheckBoxCtrl *check = dynamic_cast<GuiCheckBoxCtrl*>(retCtrl);
|
||||
|
||||
// Let's make it look pretty.
|
||||
retCtrl->setField( "profile", "InspectorTypeCheckboxProfile" );
|
||||
retCtrl->setField( "text", "" );
|
||||
|
||||
check->mIndent = 4;
|
||||
|
||||
retCtrl->setScriptValue( getData() );
|
||||
|
||||
registerEditControl( retCtrl );
|
||||
|
||||
// Configure it to update our value when the popup is closed
|
||||
char szBuffer[512];
|
||||
dSprintf( szBuffer, 512, "%d.apply(%d.getValue());",getId(),check->getId() );
|
||||
check->setField("Command", szBuffer );
|
||||
|
||||
return retCtrl;
|
||||
}
|
||||
|
||||
|
||||
void GuiInspectorTypeCheckBox::consoleInit()
|
||||
{
|
||||
Parent::consoleInit();
|
||||
|
||||
ConsoleBaseType::getType(TypeBool)->setInspectorFieldType("GuiInspectorTypeCheckBox");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GuiInspectorTypeGuiProfile
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_CONOBJECT(GuiInspectorTypeGuiProfile);
|
||||
|
||||
void GuiInspectorTypeGuiProfile::consoleInit()
|
||||
{
|
||||
Parent::consoleInit();
|
||||
|
||||
ConsoleBaseType::getType(TypeGuiProfile)->setInspectorFieldType("GuiInspectorTypeGuiProfile");
|
||||
}
|
||||
|
||||
static S32 QSORT_CALLBACK stringCompare(const void *a,const void *b)
|
||||
{
|
||||
StringTableEntry sa = *(StringTableEntry*)a;
|
||||
StringTableEntry sb = *(StringTableEntry*)b;
|
||||
return(dStricmp(sb, sa));
|
||||
}
|
||||
|
||||
GuiControl* GuiInspectorTypeGuiProfile::constructEditControl()
|
||||
{
|
||||
GuiControl* retCtrl = new GuiPopUpMenuCtrl();
|
||||
|
||||
// If we couldn't construct the control, bail!
|
||||
if( retCtrl == NULL )
|
||||
return retCtrl;
|
||||
|
||||
GuiPopUpMenuCtrl *menu = dynamic_cast<GuiPopUpMenuCtrl*>(retCtrl);
|
||||
|
||||
// Let's make it look pretty.
|
||||
retCtrl->setField( "profile", "InspectorTypeEnumProfile" );
|
||||
|
||||
menu->setField("text", getData());
|
||||
|
||||
registerEditControl( retCtrl );
|
||||
|
||||
// Configure it to update our value when the popup is closed
|
||||
char szBuffer[512];
|
||||
dSprintf( szBuffer, 512, "%d.apply(%d.getText());",getId(),menu->getId() );
|
||||
menu->setField("Command", szBuffer );
|
||||
|
||||
Vector<StringTableEntry> entries;
|
||||
|
||||
SimGroup * grp = Sim::getGuiDataGroup();
|
||||
for(SimGroup::iterator i = grp->begin(); i != grp->end(); i++)
|
||||
{
|
||||
GuiControlProfile * profile = dynamic_cast<GuiControlProfile *>(*i);
|
||||
if(profile)
|
||||
entries.push_back(profile->getName());
|
||||
}
|
||||
|
||||
// sort the entries
|
||||
dQsort(entries.address(), entries.size(), sizeof(StringTableEntry), stringCompare);
|
||||
for(U32 j = 0; j < entries.size(); j++)
|
||||
menu->addEntry(entries[j], 0);
|
||||
|
||||
return retCtrl;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GuiInspectorTypeFileName
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_CONOBJECT(GuiInspectorTypeFileName);
|
||||
|
||||
void GuiInspectorTypeFileName::consoleInit()
|
||||
{
|
||||
Parent::consoleInit();
|
||||
|
||||
ConsoleBaseType::getType(TypeFilename)->setInspectorFieldType("GuiInspectorTypeFileName");
|
||||
}
|
||||
|
||||
GuiControl* GuiInspectorTypeFileName::constructEditControl()
|
||||
{
|
||||
GuiControl* retCtrl = new GuiTextEditCtrl();
|
||||
|
||||
// If we couldn't construct the control, bail!
|
||||
if( retCtrl == NULL )
|
||||
return retCtrl;
|
||||
|
||||
// Let's make it look pretty.
|
||||
retCtrl->setField( "profile", "GuiInspectorTextEditProfile" );
|
||||
|
||||
// Don't forget to register ourselves
|
||||
registerEditControl( retCtrl );
|
||||
|
||||
char szBuffer[512];
|
||||
dSprintf( szBuffer, 512, "%d.apply(%d.getText());",getId(),retCtrl->getId() );
|
||||
retCtrl->setField("AltCommand", szBuffer );
|
||||
retCtrl->setField("Validate", szBuffer );
|
||||
|
||||
mBrowseButton = new GuiButtonCtrl();
|
||||
|
||||
if( mBrowseButton != NULL )
|
||||
{
|
||||
RectI browseRect( Point2I( ( mBounds.point.x + mBounds.extent.x) - 26, mBounds.point.y + 2), Point2I(20, mBounds.extent.y - 4) );
|
||||
char szBuffer[512];
|
||||
dSprintf( szBuffer, 512, "getLoadFilename(\"*.*\", \"%d.apply\", \"%s\");",getId(), getData());
|
||||
mBrowseButton->setField( "Command", szBuffer );
|
||||
mBrowseButton->setField( "text", "..." );
|
||||
mBrowseButton->setField( "Profile", "GuiInspectorTypeFileNameProfile" );
|
||||
mBrowseButton->registerObject();
|
||||
addObject( mBrowseButton );
|
||||
|
||||
// Position
|
||||
mBrowseButton->resize( browseRect.point, browseRect.extent );
|
||||
}
|
||||
|
||||
return retCtrl;
|
||||
}
|
||||
|
||||
void GuiInspectorTypeFileName::resize( const Point2I &newPosition, const Point2I &newExtent )
|
||||
{
|
||||
Parent::resize( newPosition, newExtent );
|
||||
|
||||
if( mEdit != NULL )
|
||||
{
|
||||
// Calculate Caption Rect
|
||||
RectI captionRect( mBounds.point , Point2I( mFloor( mBounds.extent.x * (F32)( (F32)GuiInspectorField::smCaptionWidth / 100.0 ) ) - 2, mBounds.extent.y ) );
|
||||
|
||||
// Calculate Edit Field Rect
|
||||
RectI editFieldRect( Point2I( captionRect.extent.x + 1, 0 ) , Point2I( mBounds.extent.x - ( captionRect.extent.x + 25 ) , mBounds.extent.y ) );
|
||||
|
||||
mEdit->resize( editFieldRect.point, editFieldRect.extent );
|
||||
|
||||
if( mBrowseButton != NULL )
|
||||
{
|
||||
RectI browseRect( Point2I( ( mBounds.point.x + mBounds.extent.x) - 26, 2), Point2I(20, mBounds.extent.y - 4) );
|
||||
mBrowseButton->resize( browseRect.point, browseRect.extent );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GuiInspectorTypeColor (Base for ColorI/ColorF)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_CONOBJECT(GuiInspectorTypeColor);
|
||||
|
||||
GuiControl* GuiInspectorTypeColor::constructEditControl()
|
||||
{
|
||||
GuiControl* retCtrl = new GuiTextEditCtrl();
|
||||
|
||||
// If we couldn't construct the control, bail!
|
||||
if( retCtrl == NULL )
|
||||
return retCtrl;
|
||||
|
||||
// Let's make it look pretty.
|
||||
retCtrl->setField( "profile", "GuiInspectorTextEditProfile" );
|
||||
|
||||
// Don't forget to register ourselves
|
||||
registerEditControl( retCtrl );
|
||||
|
||||
char szBuffer[512];
|
||||
dSprintf( szBuffer, 512, "%d.apply(%d.getText());",getId(), retCtrl->getId() );
|
||||
retCtrl->setField("AltCommand", szBuffer );
|
||||
retCtrl->setField("Validate", szBuffer );
|
||||
|
||||
mBrowseButton = new GuiButtonCtrl();
|
||||
|
||||
if( mBrowseButton != NULL )
|
||||
{
|
||||
RectI browseRect( Point2I( ( mBounds.point.x + mBounds.extent.x) - 26, mBounds.point.y + 2), Point2I(20, mBounds.extent.y - 4) );
|
||||
char szBuffer[512];
|
||||
dSprintf( szBuffer, 512, "%s(\"%s\", \"%d.apply\");", mColorFunction, getData(), getId());
|
||||
mBrowseButton->setField( "Command", szBuffer );
|
||||
mBrowseButton->setField( "text", "..." );
|
||||
mBrowseButton->setField( "Profile", "GuiInspectorTypeFileNameProfile" );
|
||||
mBrowseButton->registerObject();
|
||||
addObject( mBrowseButton );
|
||||
|
||||
// Position
|
||||
mBrowseButton->resize( browseRect.point, browseRect.extent );
|
||||
}
|
||||
|
||||
return retCtrl;
|
||||
}
|
||||
|
||||
void GuiInspectorTypeColor::resize( const Point2I &newPosition, const Point2I &newExtent )
|
||||
{
|
||||
Parent::resize( newPosition, newExtent );
|
||||
|
||||
if( mEdit != NULL )
|
||||
{
|
||||
// Calculate Caption Rect
|
||||
RectI captionRect( mBounds.point , Point2I( mFloor( mBounds.extent.x * (F32)( (F32)GuiInspectorField::smCaptionWidth / 100.0 ) ) - 2, mBounds.extent.y ) );
|
||||
|
||||
// Calculate Edit Field Rect
|
||||
RectI editFieldRect( Point2I( captionRect.extent.x + 1, 0 ) , Point2I( mBounds.extent.x - ( captionRect.extent.x + 25 ) , mBounds.extent.y ) );
|
||||
|
||||
mEdit->resize( editFieldRect.point, editFieldRect.extent );
|
||||
|
||||
if( mBrowseButton != NULL )
|
||||
{
|
||||
RectI browseRect( Point2I( ( mBounds.point.x + mBounds.extent.x) - 26, 2), Point2I(20, mBounds.extent.y - 4) );
|
||||
mBrowseButton->resize( browseRect.point, browseRect.extent );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GuiInspectorTypeColorI
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_CONOBJECT(GuiInspectorTypeColorI);
|
||||
|
||||
void GuiInspectorTypeColorI::consoleInit()
|
||||
{
|
||||
Parent::consoleInit();
|
||||
|
||||
ConsoleBaseType::getType(TypeColorI)->setInspectorFieldType("GuiInspectorTypeColorI");
|
||||
}
|
||||
|
||||
GuiInspectorTypeColorI::GuiInspectorTypeColorI()
|
||||
{
|
||||
mColorFunction = StringTable->insert("getColorI");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GuiInspectorTypeColorF
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_CONOBJECT(GuiInspectorTypeColorF);
|
||||
|
||||
void GuiInspectorTypeColorF::consoleInit()
|
||||
{
|
||||
Parent::consoleInit();
|
||||
|
||||
ConsoleBaseType::getType(TypeColorF)->setInspectorFieldType("GuiInspectorTypeColorF");
|
||||
}
|
||||
|
||||
GuiInspectorTypeColorF::GuiInspectorTypeColorF()
|
||||
{
|
||||
mColorFunction = StringTable->insert("getColorF");
|
||||
}
|
||||
|
||||
|
||||
|
162
engine/gui/editor/guiInspectorTypes.h
Executable file
162
engine/gui/editor/guiInspectorTypes.h
Executable file
@ -0,0 +1,162 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _GUI_INSPECTOR_TYPES_H_
|
||||
#define _GUI_INSPECTOR_TYPES_H_
|
||||
|
||||
#ifndef _GUI_INSPECTOR_H_
|
||||
#include "gui/editor/guiInspector.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUICONTROL_H_
|
||||
#include "gui/core/guiControl.h"
|
||||
#endif
|
||||
|
||||
#ifndef _H_GUIDEFAULTCONTROLRENDER_
|
||||
#include "gui/core/guiDefaultControlRender.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUISCROLLCTRL_H_
|
||||
#include "gui/containers/guiScrollCtrl.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUITEXTEDITCTRL_H_
|
||||
#include "gui/controls/guiTextEditCtrl.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUIPOPUPCTRL_H_
|
||||
#include "gui/controls/guiPopUpCtrl.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GUICHECKBOXCTRL_H_
|
||||
#include "gui/controls/guiCheckBoxCtrl.h"
|
||||
#endif
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TypeEnum GuiInspectorField Class
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class GuiInspectorTypeEnum : public GuiInspectorField
|
||||
{
|
||||
private:
|
||||
typedef GuiInspectorField Parent;
|
||||
public:
|
||||
DECLARE_CONOBJECT(GuiInspectorTypeEnum);
|
||||
static void consoleInit();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Override able methods for custom edit fields
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual GuiControl* constructEditControl();
|
||||
virtual void setData( StringTableEntry data );
|
||||
virtual StringTableEntry getData();
|
||||
virtual void updateValue( StringTableEntry newValue );
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GuiInspectorTypeCheckBox Class
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class GuiInspectorTypeCheckBox : public GuiInspectorField
|
||||
{
|
||||
private:
|
||||
typedef GuiInspectorField Parent;
|
||||
public:
|
||||
DECLARE_CONOBJECT(GuiInspectorTypeCheckBox);
|
||||
static void consoleInit();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Override able methods for custom edit fields (Both are REQUIRED)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual GuiControl* constructEditControl();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GuiInspectorTypeGuiProfile Class
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class GuiInspectorTypeGuiProfile : public GuiInspectorTypeEnum
|
||||
{
|
||||
private:
|
||||
typedef GuiInspectorTypeEnum Parent;
|
||||
public:
|
||||
DECLARE_CONOBJECT(GuiInspectorTypeGuiProfile);
|
||||
static void consoleInit();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Override able methods for custom edit fields (Both are REQUIRED)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual GuiControl* constructEditControl();
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TypeFileName GuiInspectorField Class
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class GuiInspectorTypeFileName : public GuiInspectorField
|
||||
{
|
||||
private:
|
||||
typedef GuiInspectorField Parent;
|
||||
public:
|
||||
DECLARE_CONOBJECT(GuiInspectorTypeFileName);
|
||||
static void consoleInit();
|
||||
|
||||
SimObjectPtr<GuiButtonCtrl> mBrowseButton;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Override able methods for custom edit fields
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual GuiControl* constructEditControl();
|
||||
virtual void resize(const Point2I &newPosition, const Point2I &newExtent);
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TypeColor GuiInspectorField Class (Base for ColorI/ColorF)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class GuiInspectorTypeColor : public GuiInspectorField
|
||||
{
|
||||
private:
|
||||
typedef GuiInspectorField Parent;
|
||||
public:
|
||||
DECLARE_CONOBJECT(GuiInspectorTypeColor);
|
||||
|
||||
StringTableEntry mColorFunction;
|
||||
SimObjectPtr<GuiButtonCtrl> mBrowseButton;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Override able methods for custom edit fields
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual GuiControl* constructEditControl();
|
||||
virtual void resize(const Point2I &newPosition, const Point2I &newExtent);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TypeColorI GuiInspectorField Class
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class GuiInspectorTypeColorI : public GuiInspectorTypeColor
|
||||
{
|
||||
private:
|
||||
typedef GuiInspectorTypeColor Parent;
|
||||
public:
|
||||
GuiInspectorTypeColorI();
|
||||
|
||||
DECLARE_CONOBJECT(GuiInspectorTypeColorI);
|
||||
static void consoleInit();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TypeColorF GuiInspectorField Class
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class GuiInspectorTypeColorF : public GuiInspectorTypeColor
|
||||
{
|
||||
private:
|
||||
typedef GuiInspectorTypeColor Parent;
|
||||
public:
|
||||
GuiInspectorTypeColorF();
|
||||
|
||||
DECLARE_CONOBJECT(GuiInspectorTypeColorF);
|
||||
static void consoleInit();
|
||||
};
|
||||
|
||||
#endif
|
1575
engine/gui/editor/guiMenuBar.cc
Executable file
1575
engine/gui/editor/guiMenuBar.cc
Executable file
File diff suppressed because it is too large
Load Diff
201
engine/gui/editor/guiMenuBar.h
Executable file
201
engine/gui/editor/guiMenuBar.h
Executable file
@ -0,0 +1,201 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUIMENUBAR_H_
|
||||
#define _GUIMENUBAR_H_
|
||||
|
||||
#ifndef _GUITEXTLISTCTRL_H_
|
||||
#include "gui/controls/guiTextListCtrl.h"
|
||||
#endif
|
||||
#ifndef _GUITICKCTRL_H_
|
||||
#include "gui/shiny/guiTickCtrl.h"
|
||||
#endif
|
||||
|
||||
class GuiMenuBar;
|
||||
class GuiMenuTextListCtrl;
|
||||
|
||||
class GuiMenuBackgroundCtrl : public GuiControl
|
||||
{
|
||||
typedef GuiControl Parent;
|
||||
|
||||
protected:
|
||||
GuiMenuBar *mMenuBarCtrl;
|
||||
GuiMenuTextListCtrl *mTextList;
|
||||
public:
|
||||
GuiMenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl* textList);
|
||||
void onMouseDown(const GuiEvent &event);
|
||||
void onMouseMove(const GuiEvent &event);
|
||||
void onMouseDragged(const GuiEvent &event);
|
||||
};
|
||||
|
||||
class GuiSubmenuBackgroundCtrl : public GuiMenuBackgroundCtrl
|
||||
{
|
||||
typedef GuiMenuBackgroundCtrl Parent;
|
||||
|
||||
public:
|
||||
GuiSubmenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl* textList);
|
||||
bool pointInControl(const Point2I & parentCoordPoint);
|
||||
void onMouseDown(const GuiEvent &event);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class GuiMenuTextListCtrl : public GuiTextListCtrl
|
||||
{
|
||||
private:
|
||||
typedef GuiTextListCtrl Parent;
|
||||
|
||||
protected:
|
||||
GuiMenuBar *mMenuBarCtrl;
|
||||
|
||||
public:
|
||||
bool isSubMenu; // DAW: Indicates that this text list is in a submenu
|
||||
|
||||
GuiMenuTextListCtrl(); // for inheritance
|
||||
GuiMenuTextListCtrl(GuiMenuBar *ctrl);
|
||||
|
||||
// GuiControl overloads:
|
||||
bool onKeyDown(const GuiEvent &event);
|
||||
void onMouseDown(const GuiEvent &event);
|
||||
void onMouseUp(const GuiEvent &event);
|
||||
void onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver);
|
||||
|
||||
virtual void onCellHighlighted(Point2I cell); // DAW: Added
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class GuiMenuBar : public GuiTickCtrl // DAW: Was: GuiControl
|
||||
{
|
||||
typedef GuiTickCtrl Parent; // DAW: Was: GuiControl Parent;
|
||||
public:
|
||||
|
||||
class Menu;
|
||||
|
||||
struct MenuItem // an individual item in a pull-down menu
|
||||
{
|
||||
char *text; // the text of the menu item
|
||||
U32 id; // a script-assigned identifier
|
||||
char *accelerator; // the keyboard accelerator shortcut for the menu item
|
||||
U32 acceleratorIndex; // index of this accelerator
|
||||
bool enabled; // true if the menu item is selectable
|
||||
bool visible; // true if the menu item is visible
|
||||
S32 bitmapIndex; // index of the bitmap in the bitmap array
|
||||
S32 checkGroup; // the group index of the item visa vi check marks -
|
||||
// only one item in the group can be checked.
|
||||
MenuItem *nextMenuItem; // next menu item in the linked list
|
||||
|
||||
bool isSubmenu; // DAW: This menu item has a submenu that will be displayed
|
||||
MenuItem *firstSubmenuItem; // DAW: The first menu item in the submenu
|
||||
|
||||
Menu* submenuParentMenu; // DAW: For a submenu, this is the parent menu
|
||||
|
||||
};
|
||||
struct Menu
|
||||
{
|
||||
char *text;
|
||||
U32 id;
|
||||
RectI bounds;
|
||||
bool visible;
|
||||
|
||||
S32 bitmapIndex; // Index of the bitmap in the bitmap array (-1 = no bitmap)
|
||||
bool drawBitmapOnly; // Draw only the bitmap and not the text
|
||||
bool drawBorder; // Should a border be drawn around this menu (usually if we only have a bitmap, we don't want a border)
|
||||
|
||||
Menu *nextMenu;
|
||||
MenuItem *firstMenuItem;
|
||||
};
|
||||
|
||||
GuiMenuBackgroundCtrl *mBackground;
|
||||
GuiMenuTextListCtrl *mTextList;
|
||||
|
||||
GuiSubmenuBackgroundCtrl *mSubmenuBackground; // DAW: Background for a submenu
|
||||
GuiMenuTextListCtrl *mSubmenuTextList; // DAW: Text list for a submenu
|
||||
|
||||
Menu *menuList;
|
||||
Menu *mouseDownMenu;
|
||||
Menu *mouseOverMenu;
|
||||
|
||||
MenuItem* mouseDownSubmenu; // DAW: Stores the menu item that is a submenu that has been selected
|
||||
MenuItem* mouseOverSubmenu; // DAW: Stores the menu item that is a submenu that has been highlighted
|
||||
|
||||
bool menuBarDirty;
|
||||
U32 mCurAcceleratorIndex;
|
||||
Point2I maxBitmapSize;
|
||||
|
||||
S32 mCheckmarkBitmapIndex; // Index in the bitmap array to use for the check mark image
|
||||
|
||||
S32 mPadding;
|
||||
S32 mHorizontalMargin; // Left and right margin around the text of each menu
|
||||
S32 mVerticalMargin; // Top and bottom margin around the text of each menu
|
||||
S32 mBitmapMargin; // Margin between a menu's bitmap and text
|
||||
|
||||
// DAW: Used to keep track of the amount of ticks that the mouse is hovering
|
||||
// over a menu.
|
||||
S32 mMouseOverCounter;
|
||||
bool mCountMouseOver;
|
||||
S32 mMouseHoverAmount;
|
||||
|
||||
GuiMenuBar();
|
||||
bool onWake();
|
||||
void onSleep();
|
||||
|
||||
// internal menu handling functions
|
||||
// these are used by the script manipulation functions to add/remove/change menu items
|
||||
|
||||
void addMenu(const char *menuText, U32 menuId);
|
||||
Menu *findMenu(const char *menu); // takes either a menu text or a string id
|
||||
MenuItem *findMenuItem(Menu *menu, const char *menuItem); // takes either a menu text or a string id
|
||||
void removeMenu(Menu *menu);
|
||||
void removeMenuItem(Menu *menu, MenuItem *menuItem);
|
||||
void addMenuItem(Menu *menu, const char *text, U32 id, const char *accelerator, S32 checkGroup);
|
||||
void clearMenuItems(Menu *menu);
|
||||
void clearMenus();
|
||||
|
||||
// DAW: Methods to deal with submenus
|
||||
MenuItem* findSubmenuItem(Menu *menu, const char *menuItem, const char *submenuItem);
|
||||
void addSubmenuItem(Menu *menu, MenuItem *submenu, const char *text, U32 id, const char *accelerator, S32 checkGroup);
|
||||
void removeSubmenuItem(MenuItem *menuItem, MenuItem *submenuItem);
|
||||
void clearSubmenuItems(MenuItem *menuitem);
|
||||
void onSubmenuAction(S32 selectionIndex, RectI bounds, Point2I cellSize);
|
||||
void closeSubmenu();
|
||||
void checkSubmenuMouseMove(const GuiEvent &event);
|
||||
MenuItem *findHitMenuItem(Point2I mousePoint);
|
||||
|
||||
void highlightedMenuItem(S32 selectionIndex, RectI bounds, Point2I cellSize); // DAW: Called whenever a menu item is highlighted by the mouse
|
||||
|
||||
// display/mouse functions
|
||||
|
||||
Menu *findHitMenu(Point2I mousePoint);
|
||||
|
||||
// DAW: Called when the GUI theme changes and a bitmap arrary may need updating
|
||||
// void onThemeChange();
|
||||
|
||||
void onPreRender();
|
||||
void onRender(Point2I offset, const RectI &updateRect);
|
||||
|
||||
void checkMenuMouseMove(const GuiEvent &event);
|
||||
void onMouseMove(const GuiEvent &event);
|
||||
void onMouseLeave(const GuiEvent &event);
|
||||
void onMouseDown(const GuiEvent &event);
|
||||
void onMouseDragged(const GuiEvent &event);
|
||||
void onMouseUp(const GuiEvent &event);
|
||||
|
||||
void onAction();
|
||||
void closeMenu();
|
||||
void buildAcceleratorMap();
|
||||
void acceleratorKeyPress(U32 index);
|
||||
|
||||
void menuItemSelected(Menu *menu, MenuItem *item);
|
||||
|
||||
// DAW: Added to support 'ticks'
|
||||
void processTick();
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(GuiMenuBar);
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user