added everything

This commit is contained in:
Metario
2017-04-17 06:17:10 -06:00
commit 9c6ff74f19
6121 changed files with 1625704 additions and 0 deletions

View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

98
engine/gui/editor/guiEditCtrl.h Executable file
View 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

View 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 );
}

View 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
View 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;
}

View 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

File diff suppressed because it is too large Load Diff

264
engine/gui/editor/guiInspector.h Executable file
View 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

View 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");
}

View 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

File diff suppressed because it is too large Load Diff

201
engine/gui/editor/guiMenuBar.h Executable file
View 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