Initial commit
This commit is contained in:
420
engine/gui/core/guiArrayCtrl.cc
Executable file
420
engine/gui/core/guiArrayCtrl.cc
Executable file
@ -0,0 +1,420 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "console/console.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "platform/event.h"
|
||||
#include "gui/containers/guiScrollCtrl.h"
|
||||
#include "gui/core/guiArrayCtrl.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiArrayCtrl);
|
||||
|
||||
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //
|
||||
|
||||
GuiArrayCtrl::GuiArrayCtrl()
|
||||
{
|
||||
mActive = true;
|
||||
|
||||
mCellSize.set(80, 30);
|
||||
mSize = Point2I(5, 30);
|
||||
mSelectedCell.set(-1, -1);
|
||||
mMouseOverCell.set(-1, -1);
|
||||
mHeaderDim.set(0, 0);
|
||||
}
|
||||
|
||||
bool GuiArrayCtrl::onWake()
|
||||
{
|
||||
if (! Parent::onWake())
|
||||
return false;
|
||||
|
||||
//get the font
|
||||
mFont = mProfile->mFont;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onSleep()
|
||||
{
|
||||
Parent::onSleep();
|
||||
mFont = NULL;
|
||||
}
|
||||
|
||||
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //
|
||||
|
||||
void GuiArrayCtrl::setSize(Point2I newSize)
|
||||
{
|
||||
mSize = newSize;
|
||||
Point2I newExtent(newSize.x * mCellSize.x + mHeaderDim.x, newSize.y * mCellSize.y + mHeaderDim.y);
|
||||
|
||||
resize(mBounds.point, newExtent);
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::getScrollDimensions(S32 &cell_size, S32 &num_cells)
|
||||
{
|
||||
cell_size = mCellSize.y;
|
||||
num_cells = mSize.y;
|
||||
}
|
||||
|
||||
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //
|
||||
|
||||
bool GuiArrayCtrl::cellSelected(Point2I cell)
|
||||
{
|
||||
if (cell.x < 0 || cell.x >= mSize.x || cell.y < 0 || cell.y >= mSize.y)
|
||||
{
|
||||
mSelectedCell = Point2I(-1,-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
mSelectedCell = cell;
|
||||
scrollSelectionVisible();
|
||||
onCellSelected(cell);
|
||||
setUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onCellSelected(Point2I cell)
|
||||
{
|
||||
Con::executef(this, 3, "onSelect", Con::getFloatArg(cell.x), Con::getFloatArg(cell.y));
|
||||
|
||||
//call the console function
|
||||
if (mConsoleCommand[0])
|
||||
Con::evaluate(mConsoleCommand, false);
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::setSelectedCell(Point2I cell)
|
||||
{
|
||||
cellSelected(cell);
|
||||
}
|
||||
|
||||
Point2I GuiArrayCtrl::getSelectedCell()
|
||||
{
|
||||
return mSelectedCell;
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::scrollSelectionVisible()
|
||||
{
|
||||
scrollCellVisible(mSelectedCell);
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::scrollCellVisible(Point2I cell)
|
||||
{
|
||||
//make sure we have a parent
|
||||
//make sure we have a valid cell selected
|
||||
GuiScrollCtrl *parent = dynamic_cast<GuiScrollCtrl*>(getParent());
|
||||
if(!parent || cell.x < 0 || cell.y < 0)
|
||||
return;
|
||||
|
||||
RectI cellBounds(cell.x * mCellSize.x, cell.y * mCellSize.y, mCellSize.x, mCellSize.y);
|
||||
parent->scrollRectVisible(cellBounds);
|
||||
}
|
||||
|
||||
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //
|
||||
|
||||
void GuiArrayCtrl::onRenderColumnHeaders(Point2I offset, Point2I parentOffset, Point2I headerDim)
|
||||
{
|
||||
if (mProfile->mBorder)
|
||||
{
|
||||
RectI cellR(offset.x + headerDim.x, parentOffset.y, mBounds.extent.x - headerDim.x, headerDim.y);
|
||||
dglDrawRectFill(cellR, mProfile->mBorderColor);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onRenderRowHeader(Point2I offset, Point2I parentOffset, Point2I headerDim, Point2I cell)
|
||||
{
|
||||
ColorI color;
|
||||
RectI cellR;
|
||||
if (cell.x % 2)
|
||||
color.set(255, 0, 0, 255);
|
||||
else
|
||||
color.set(0, 255, 0, 255);
|
||||
|
||||
cellR.point.set(parentOffset.x, offset.y);
|
||||
cellR.extent.set(headerDim.x, mCellSize.y);
|
||||
dglDrawRectFill(cellR, color);
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver)
|
||||
{
|
||||
ColorI color(255 * (cell.x % 2), 255 * (cell.y % 2), 255 * ((cell.x + cell.y) % 2), 255);
|
||||
if (selected)
|
||||
{
|
||||
color.set(255, 0, 0, 255);
|
||||
}
|
||||
else if (mouseOver)
|
||||
{
|
||||
color.set(0, 0, 255, 255);
|
||||
}
|
||||
|
||||
//draw the cell
|
||||
RectI cellR(offset.x, offset.y, mCellSize.x, mCellSize.y);
|
||||
dglDrawRectFill(cellR, color);
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||
{
|
||||
//make sure we have a parent
|
||||
GuiControl *parent = getParent();
|
||||
if (! parent)
|
||||
return;
|
||||
|
||||
S32 i, j;
|
||||
RectI headerClip;
|
||||
RectI clipRect(updateRect.point, updateRect.extent);
|
||||
|
||||
Point2I parentOffset = parent->localToGlobalCoord(Point2I(0, 0));
|
||||
|
||||
//if we have column headings
|
||||
if (mHeaderDim.y > 0)
|
||||
{
|
||||
headerClip.point.x = parentOffset.x + mHeaderDim.x;
|
||||
headerClip.point.y = parentOffset.y;
|
||||
headerClip.extent.x = clipRect.extent.x;// - headerClip.point.x; // This seems to fix some strange problems with some Gui's, bug? -pw
|
||||
headerClip.extent.y = mHeaderDim.y;
|
||||
|
||||
if (headerClip.intersect(clipRect))
|
||||
{
|
||||
dglSetClipRect(headerClip);
|
||||
|
||||
//now render the header
|
||||
onRenderColumnHeaders(offset, parentOffset, mHeaderDim);
|
||||
|
||||
clipRect.point.y = headerClip.point.y + headerClip.extent.y - 1;
|
||||
}
|
||||
offset.y += mHeaderDim.y;
|
||||
}
|
||||
|
||||
//if we have row headings
|
||||
if (mHeaderDim.x > 0)
|
||||
{
|
||||
clipRect.point.x = getMax(clipRect.point.x, parentOffset.x + mHeaderDim.x);
|
||||
offset.x += mHeaderDim.x;
|
||||
}
|
||||
|
||||
//save the original for clipping the row headers
|
||||
RectI origClipRect = clipRect;
|
||||
|
||||
for (j = 0; j < mSize.y; j++)
|
||||
{
|
||||
//skip until we get to a visible row
|
||||
if ((j + 1) * mCellSize.y + offset.y < updateRect.point.y)
|
||||
continue;
|
||||
|
||||
//break once we've reached the last visible row
|
||||
if(j * mCellSize.y + offset.y >= updateRect.point.y + updateRect.extent.y)
|
||||
break;
|
||||
|
||||
//render the header
|
||||
if (mHeaderDim.x > 0)
|
||||
{
|
||||
headerClip.point.x = parentOffset.x;
|
||||
headerClip.extent.x = mHeaderDim.x;
|
||||
headerClip.point.y = offset.y + j * mCellSize.y;
|
||||
headerClip.extent.y = mCellSize.y;
|
||||
if (headerClip.intersect(origClipRect))
|
||||
{
|
||||
dglSetClipRect(headerClip);
|
||||
|
||||
//render the row header
|
||||
onRenderRowHeader(Point2I(0, offset.y + j * mCellSize.y),
|
||||
Point2I(parentOffset.x, offset.y + j * mCellSize.y),
|
||||
mHeaderDim, Point2I(0, j));
|
||||
}
|
||||
}
|
||||
|
||||
//render the cells for the row
|
||||
for (i = 0; i < mSize.x; i++)
|
||||
{
|
||||
//skip past columns off the left edge
|
||||
if ((i + 1) * mCellSize.x + offset.x < updateRect.point.x)
|
||||
continue;
|
||||
|
||||
//break once past the last visible column
|
||||
if (i * mCellSize.x + offset.x >= updateRect.point.x + updateRect.extent.x)
|
||||
break;
|
||||
|
||||
S32 cellx = offset.x + i * mCellSize.x;
|
||||
S32 celly = offset.y + j * mCellSize.y;
|
||||
|
||||
RectI cellClip(cellx, celly, mCellSize.x, mCellSize.y);
|
||||
|
||||
//make sure the cell is within the update region
|
||||
if (cellClip.intersect(clipRect))
|
||||
{
|
||||
//set the clip rect
|
||||
dglSetClipRect(cellClip);
|
||||
|
||||
//render the cell
|
||||
onRenderCell(Point2I(cellx, celly), Point2I(i, j),
|
||||
i == mSelectedCell.x && j == mSelectedCell.y,
|
||||
i == mMouseOverCell.x && j == mMouseOverCell.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onMouseDown(const GuiEvent &event)
|
||||
{
|
||||
if ( !mActive || !mAwake || !mVisible )
|
||||
return;
|
||||
|
||||
//let the guiControl method take care of the rest
|
||||
Parent::onMouseDown(event);
|
||||
|
||||
Point2I pt = globalToLocalCoord(event.mousePoint);
|
||||
pt.x -= mHeaderDim.x; pt.y -= mHeaderDim.y;
|
||||
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)
|
||||
{
|
||||
|
||||
//store the previously selected cell
|
||||
Point2I prevSelected = mSelectedCell;
|
||||
|
||||
//select the new cell
|
||||
cellSelected(Point2I(cell.x, cell.y));
|
||||
|
||||
//if we double clicked on the *same* cell, evaluate the altConsole Command
|
||||
if ( ( event.mouseClickCount > 1 ) && ( prevSelected == mSelectedCell ) && mAltConsoleCommand[0] )
|
||||
Con::evaluate( mAltConsoleCommand, false );
|
||||
}
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onMouseEnter(const GuiEvent &event)
|
||||
{
|
||||
Point2I pt = globalToLocalCoord(event.mousePoint);
|
||||
pt.x -= mHeaderDim.x; pt.y -= mHeaderDim.y;
|
||||
|
||||
//get the cell
|
||||
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)
|
||||
{
|
||||
mMouseOverCell = cell;
|
||||
setUpdateRegion(Point2I(cell.x * mCellSize.x + mHeaderDim.x,
|
||||
cell.y * mCellSize.y + mHeaderDim.y), mCellSize );
|
||||
}
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onMouseLeave(const GuiEvent & /*event*/)
|
||||
{
|
||||
setUpdateRegion(Point2I(mMouseOverCell.x * mCellSize.x + mHeaderDim.x,
|
||||
mMouseOverCell.y * mCellSize.y + mHeaderDim.y), mCellSize);
|
||||
mMouseOverCell.set(-1,-1);
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onMouseDragged(const GuiEvent &event)
|
||||
{
|
||||
// for the array control, the behaviour of onMouseDragged is the same
|
||||
// as on mouse moved - basically just recalc the currend mouse over cell
|
||||
// and set the update regions if necessary
|
||||
GuiArrayCtrl::onMouseMove(event);
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onMouseMove(const GuiEvent &event)
|
||||
{
|
||||
Point2I pt = globalToLocalCoord(event.mousePoint);
|
||||
pt.x -= mHeaderDim.x; pt.y -= mHeaderDim.y;
|
||||
Point2I cell((pt.x < 0 ? -1 : pt.x / mCellSize.x), (pt.y < 0 ? -1 : pt.y / mCellSize.y));
|
||||
if (cell.x != mMouseOverCell.x || cell.y != mMouseOverCell.y)
|
||||
{
|
||||
if (mMouseOverCell.x != -1)
|
||||
{
|
||||
setUpdateRegion(Point2I(mMouseOverCell.x * mCellSize.x + mHeaderDim.x,
|
||||
mMouseOverCell.y * mCellSize.y + mHeaderDim.y), mCellSize);
|
||||
}
|
||||
|
||||
if (cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y)
|
||||
{
|
||||
setUpdateRegion(Point2I(cell.x * mCellSize.x + mHeaderDim.x,
|
||||
cell.y * mCellSize.y + mHeaderDim.y), mCellSize);
|
||||
mMouseOverCell = cell;
|
||||
}
|
||||
else
|
||||
mMouseOverCell.set(-1,-1);
|
||||
}
|
||||
}
|
||||
|
||||
bool GuiArrayCtrl::onKeyDown(const GuiEvent &event)
|
||||
{
|
||||
//if this control is a dead end, kill the event
|
||||
if ((! mVisible) || (! mActive) || (! mAwake)) return true;
|
||||
|
||||
//get the parent
|
||||
S32 pageSize = 1;
|
||||
GuiControl *parent = getParent();
|
||||
if (parent && mCellSize.y > 0)
|
||||
{
|
||||
pageSize = getMax(1, (parent->mBounds.extent.y / mCellSize.y) - 1);
|
||||
}
|
||||
|
||||
Point2I delta(0,0);
|
||||
switch (event.keyCode)
|
||||
{
|
||||
case KEY_LEFT:
|
||||
delta.set(-1, 0);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
delta.set(1, 0);
|
||||
break;
|
||||
case KEY_UP:
|
||||
delta.set(0, -1);
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
delta.set(0, 1);
|
||||
break;
|
||||
case KEY_PAGE_UP:
|
||||
delta.set(0, -pageSize);
|
||||
break;
|
||||
case KEY_PAGE_DOWN:
|
||||
delta.set(0, pageSize);
|
||||
break;
|
||||
case KEY_HOME:
|
||||
cellSelected( Point2I( 0, 0 ) );
|
||||
return( true );
|
||||
case KEY_END:
|
||||
cellSelected( Point2I( 0, mSize.y - 1 ) );
|
||||
return( true );
|
||||
default:
|
||||
return Parent::onKeyDown(event);
|
||||
}
|
||||
if (mSize.x < 1 || mSize.y < 1)
|
||||
return true;
|
||||
|
||||
//select the first cell if no previous cell was selected
|
||||
if (mSelectedCell.x == -1 || mSelectedCell.y == -1)
|
||||
{
|
||||
cellSelected(Point2I(0,0));
|
||||
return true;
|
||||
}
|
||||
|
||||
//select the cell
|
||||
Point2I cell = mSelectedCell;
|
||||
cell.x = getMax(0, getMin(mSize.x - 1, cell.x + delta.x));
|
||||
cell.y = getMax(0, getMin(mSize.y - 1, cell.y + delta.y));
|
||||
cellSelected(cell);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiArrayCtrl::onRightMouseDown(const GuiEvent &event)
|
||||
{
|
||||
if ( !mActive || !mAwake || !mVisible )
|
||||
return;
|
||||
|
||||
Parent::onRightMouseDown( event );
|
||||
|
||||
Point2I pt = globalToLocalCoord( event.mousePoint );
|
||||
pt.x -= mHeaderDim.x; pt.y -= mHeaderDim.y;
|
||||
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)
|
||||
{
|
||||
char buf[32];
|
||||
dSprintf( buf, sizeof( buf ), "%d %d", event.mousePoint.x, event.mousePoint.y );
|
||||
// Pass it to the console:
|
||||
Con::executef(this, 4, "onRightMouseDown", Con::getIntArg(cell.x), Con::getIntArg(cell.y), buf);
|
||||
}
|
||||
}
|
78
engine/gui/core/guiArrayCtrl.h
Executable file
78
engine/gui/core/guiArrayCtrl.h
Executable file
@ -0,0 +1,78 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUIARRAYCTRL_H_
|
||||
#define _GUIARRAYCTRL_H_
|
||||
|
||||
#ifndef _GUITYPES_H_
|
||||
#include "gui/core/guiTypes.h"
|
||||
#endif
|
||||
#ifndef _GUITEXTCTRL_H_
|
||||
#include "gui/controls/guiTextCtrl.h"
|
||||
#endif
|
||||
|
||||
/// Renders a grid of cells.
|
||||
class GuiArrayCtrl : public GuiControl
|
||||
{
|
||||
typedef GuiControl Parent;
|
||||
|
||||
protected:
|
||||
|
||||
Point2I mHeaderDim;
|
||||
Point2I mSize;
|
||||
Point2I mCellSize;
|
||||
Point2I mSelectedCell;
|
||||
Point2I mMouseOverCell;
|
||||
|
||||
Resource<GFont> mFont;
|
||||
|
||||
bool cellSelected(Point2I cell);
|
||||
virtual void onCellSelected(Point2I cell);
|
||||
public:
|
||||
|
||||
GuiArrayCtrl();
|
||||
DECLARE_CONOBJECT(GuiArrayCtrl);
|
||||
|
||||
bool onWake();
|
||||
void onSleep();
|
||||
|
||||
/// @name Array attribute methods
|
||||
/// @{
|
||||
Point2I getSize() { return mSize; }
|
||||
virtual void setSize(Point2I size);
|
||||
void setHeaderDim(const Point2I &dim) { mHeaderDim = dim; }
|
||||
void getScrollDimensions(S32 &cell_size, S32 &num_cells);
|
||||
/// @}
|
||||
|
||||
/// @name Selected cell methods
|
||||
/// @{
|
||||
void setSelectedCell(Point2I cell);
|
||||
void deselectCells() { mSelectedCell.set(-1,-1); }
|
||||
Point2I getSelectedCell();
|
||||
void scrollSelectionVisible();
|
||||
void scrollCellVisible(Point2I cell);
|
||||
/// @}
|
||||
|
||||
/// @name Rendering methods
|
||||
/// @{
|
||||
virtual void onRenderColumnHeaders(Point2I offset, Point2I parentOffset, Point2I headerDim);
|
||||
virtual void onRenderRowHeader(Point2I offset, Point2I parentOffset, Point2I headerDim, Point2I cell);
|
||||
virtual void onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver);
|
||||
void onRender(Point2I offset, const RectI &updateRect);
|
||||
/// @}
|
||||
|
||||
/// @name Mouse input methods
|
||||
/// @{
|
||||
void onMouseDown(const GuiEvent &event);
|
||||
void onMouseMove(const GuiEvent &event);
|
||||
void onMouseDragged(const GuiEvent &event);
|
||||
void onMouseEnter(const GuiEvent &event);
|
||||
void onMouseLeave(const GuiEvent &event);
|
||||
bool onKeyDown(const GuiEvent &event);
|
||||
void onRightMouseDown(const GuiEvent &event);
|
||||
/// @}
|
||||
};
|
||||
|
||||
#endif //_GUI_ARRAY_CTRL_H
|
1333
engine/gui/core/guiCanvas.cc
Executable file
1333
engine/gui/core/guiCanvas.cc
Executable file
File diff suppressed because it is too large
Load Diff
334
engine/gui/core/guiCanvas.h
Executable file
334
engine/gui/core/guiCanvas.h
Executable file
@ -0,0 +1,334 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUICANVAS_H_
|
||||
#define _GUICANVAS_H_
|
||||
|
||||
#ifndef _SIMBASE_H_
|
||||
#include "console/simBase.h"
|
||||
#endif
|
||||
#ifndef _EVENT_H_
|
||||
#include "platform/event.h"
|
||||
#endif
|
||||
#ifndef _GUICONTROL_H_
|
||||
#include "gui/core/guiControl.h"
|
||||
#endif
|
||||
|
||||
/// A canvas on which rendering occurs.
|
||||
///
|
||||
///
|
||||
/// @section GuiCanvas_contents What a GUICanvas Can Contain...
|
||||
///
|
||||
/// @subsection GuiCanvas_content_contentcontrol Content Control
|
||||
/// A content control is the top level GuiControl for a screen. This GuiControl
|
||||
/// will be the parent control for all other GuiControls on that particular
|
||||
/// screen.
|
||||
///
|
||||
/// @subsection GuiCanvas_content_dialogs Dialogs
|
||||
///
|
||||
/// A dialog is essentially another screen, only it gets overlaid on top of the
|
||||
/// current content control, and all input goes to the dialog. This is most akin
|
||||
/// to the "Open File" dialog box found in most operating systems. When you
|
||||
/// choose to open a file, and the "Open File" dialog pops up, you can no longer
|
||||
/// send input to the application, and must complete or cancel the open file
|
||||
/// request. Torque keeps track of layers of dialogs. The dialog with the highest
|
||||
/// layer is on top and will get all the input, unless the dialog is
|
||||
/// modeless, which is a profile option.
|
||||
///
|
||||
/// @see GuiControlProfile
|
||||
///
|
||||
/// @section GuiCanvas_dirty Dirty Rectangles
|
||||
///
|
||||
/// The GuiCanvas is based on dirty regions.
|
||||
///
|
||||
/// Every frame the canvas paints only the areas of the canvas that are 'dirty'
|
||||
/// or need updating. In most cases, this only is the area under the mouse cursor.
|
||||
/// This is why if you look in guiCanvas.cc the call to glClear is commented out.
|
||||
/// If you want a really good idea of what exactly dirty regions are and how they
|
||||
/// work, un-comment that glClear line in the renderFrame method of guiCanvas.cc
|
||||
///
|
||||
/// What you will see is a black screen, except in the dirty regions, where the
|
||||
/// screen will be painted normally. If you are making an animated GuiControl
|
||||
/// you need to add your control to the dirty areas of the canvas.
|
||||
///
|
||||
class GuiCanvas : public GuiControl
|
||||
{
|
||||
|
||||
protected:
|
||||
typedef GuiControl Parent;
|
||||
typedef SimObject Grandparent;
|
||||
|
||||
/// @name Rendering
|
||||
/// @{
|
||||
|
||||
///
|
||||
RectI mOldUpdateRects[2];
|
||||
RectI mCurUpdateRect;
|
||||
F32 rLastFrameTime;
|
||||
/// @}
|
||||
|
||||
/// @name Cursor Properties
|
||||
/// @{
|
||||
|
||||
|
||||
F32 mPixelsPerMickey; ///< This is the scale factor which relates
|
||||
/// mouse movement in pixels (one unit of
|
||||
/// mouse movement is a mickey) to units in
|
||||
/// the GUI.
|
||||
bool cursorON;
|
||||
bool mShowCursor;
|
||||
bool mRenderFront;
|
||||
Point2F cursorPt;
|
||||
Point2I lastCursorPt;
|
||||
GuiCursor *defaultCursor;
|
||||
GuiCursor *lastCursor;
|
||||
bool lastCursorON;
|
||||
/// @}
|
||||
|
||||
/// @name Mouse Input
|
||||
/// @{
|
||||
|
||||
SimObjectPtr<GuiControl> mMouseCapturedControl; ///< All mouse events will go to this ctrl only
|
||||
SimObjectPtr<GuiControl> mMouseControl; ///< the control the mouse was last seen in unless some other one captured it
|
||||
bool mMouseControlClicked; ///< whether the current ctrl has been clicked - used by helpctrl
|
||||
U32 mPrevMouseTime; ///< this determines how long the mouse has been in the same control
|
||||
U32 mNextMouseTime; ///< used for onMouseRepeat()
|
||||
U32 mInitialMouseDelay; ///< also used for onMouseRepeat()
|
||||
bool mMouseButtonDown; ///< Flag to determine if the button is depressed
|
||||
bool mMouseRightButtonDown; ///< bool to determine if the right button is depressed
|
||||
bool mMouseMiddleButtonDown; ///< Middle button flag
|
||||
GuiEvent mLastEvent;
|
||||
|
||||
U8 mLastMouseClickCount;
|
||||
S32 mLastMouseDownTime;
|
||||
bool mLeftMouseLast;
|
||||
bool mMiddleMouseLast;
|
||||
|
||||
virtual void findMouseControl(const GuiEvent &event);
|
||||
virtual void refreshMouseControl();
|
||||
/// @}
|
||||
|
||||
/// @name Keyboard Input
|
||||
/// @{
|
||||
|
||||
GuiControl *keyboardControl; ///< All keyboard events will go to this ctrl first
|
||||
U32 nextKeyTime;
|
||||
|
||||
|
||||
/// Accelerator key map
|
||||
struct AccKeyMap
|
||||
{
|
||||
GuiControl *ctrl;
|
||||
U32 index;
|
||||
U32 keyCode;
|
||||
U32 modifier;
|
||||
};
|
||||
Vector <AccKeyMap> mAcceleratorMap;
|
||||
|
||||
//for tooltip rendering
|
||||
U32 hoverControlStart;
|
||||
GuiControl* hoverControl;
|
||||
Point2I hoverPosition;
|
||||
bool hoverPositionSet;
|
||||
U32 hoverLeftControlTime;
|
||||
|
||||
/// @}
|
||||
|
||||
public:
|
||||
DECLARE_CONOBJECT(GuiCanvas);
|
||||
GuiCanvas();
|
||||
virtual ~GuiCanvas();
|
||||
|
||||
/// @name Rendering methods
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Repaints the dirty regions of the canvas
|
||||
/// @param preRenderOnly If set to true, only the onPreRender methods of all the GuiControls will be called
|
||||
/// @param bufferSwap If set to true, it will swap buffers at the end. This is to support canvas-subclassing.
|
||||
virtual void renderFrame(bool preRenderOnly, bool bufferSwap = true);
|
||||
|
||||
/// Repaints the entire canvas by calling resetUpdateRegions() and then renderFrame()
|
||||
virtual void paint();
|
||||
|
||||
/// Adds a dirty area to the canvas so it will be updated on the next frame
|
||||
/// @param pos Screen-coordinates of the upper-left hand corner of the dirty area
|
||||
/// @param ext Width/height of the dirty area
|
||||
virtual void addUpdateRegion(Point2I pos, Point2I ext);
|
||||
|
||||
/// Resets the update regions so that the next call to renderFrame will
|
||||
/// repaint the whole canvas
|
||||
virtual void resetUpdateRegions();
|
||||
|
||||
/// This builds a rectangle which encompasses all of the dirty regions to be
|
||||
/// repainted
|
||||
/// @param updateUnion (out) Rectangle which surrounds all dirty areas
|
||||
virtual void buildUpdateUnion(RectI *updateUnion);
|
||||
|
||||
/// This will swap the buffers at the end of renderFrame. It was added for canvas
|
||||
/// sub-classes in case they wanted to do some custom code before the buffer
|
||||
/// flip occured.
|
||||
virtual void swapBuffers();
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Canvas Content Management
|
||||
/// @{
|
||||
|
||||
/// This sets the content control to something different
|
||||
/// @param gui New content control
|
||||
virtual void setContentControl(GuiControl *gui);
|
||||
|
||||
/// Returns the content control
|
||||
virtual GuiControl *getContentControl();
|
||||
|
||||
/// Adds a dialog control onto the stack of dialogs
|
||||
/// @param gui Dialog to add
|
||||
/// @param layer Layer to put dialog on
|
||||
virtual void pushDialogControl(GuiControl *gui, S32 layer = 0);
|
||||
|
||||
/// Removes a specific layer of dialogs
|
||||
/// @param layer Layer to pop off from
|
||||
virtual void popDialogControl(S32 layer = 0);
|
||||
|
||||
/// Removes a specific dialog control
|
||||
/// @param gui Dialog to remove from the dialog stack
|
||||
virtual void popDialogControl(GuiControl *gui);
|
||||
///@}
|
||||
|
||||
/// This turns on/off front-buffer rendering
|
||||
/// @param front True if all rendering should be done to the front buffer
|
||||
virtual void setRenderFront(bool front) { mRenderFront = front; }
|
||||
|
||||
/// @name Cursor commands
|
||||
/// A cursor can be on, but not be shown. If a cursor is not on, than it does not
|
||||
/// process input.
|
||||
/// @{
|
||||
|
||||
/// Sets the cursor for the canvas.
|
||||
/// @param cursor New cursor to use.
|
||||
virtual void setCursor(GuiCursor *cursor);
|
||||
|
||||
/// Returns true if the cursor is on.
|
||||
virtual bool isCursorON() {return cursorON; }
|
||||
|
||||
/// Turns the cursor on or off.
|
||||
/// @param onOff True if the cursor should be on.
|
||||
virtual void setCursorON(bool onOff);
|
||||
|
||||
/// Sets the position of the cursor
|
||||
/// @param pt Point, in screenspace for the cursor
|
||||
virtual void setCursorPos(const Point2I &pt) { cursorPt.x = F32(pt.x); cursorPt.y = F32(pt.y); }
|
||||
|
||||
/// Returns the point, in screenspace, at which the cursor is located.
|
||||
virtual Point2I getCursorPos() { return Point2I(S32(cursorPt.x), S32(cursorPt.y)); }
|
||||
|
||||
/// Enable/disable rendering of the cursor.
|
||||
/// @param state True if we should render cursor
|
||||
virtual void showCursor(bool state) { mShowCursor = state; }
|
||||
|
||||
/// Returns true if the cursor is being rendered.
|
||||
virtual bool isCursorShown() { return(mShowCursor); }
|
||||
/// @}
|
||||
///used by the tooltip resource
|
||||
Point2I getCursorExtent() { return defaultCursor->getExtent(); }
|
||||
|
||||
/// @name Input Processing
|
||||
/// @{
|
||||
|
||||
/// Processes an input event
|
||||
/// @see InputEvent
|
||||
/// @param event Input event to process
|
||||
virtual bool processInputEvent(const InputEvent *event);
|
||||
|
||||
/// Processes a mouse movement event
|
||||
/// @see MouseMoveEvent
|
||||
/// @param event Mouse move event to process
|
||||
virtual void processMouseMoveEvent(const MouseMoveEvent *event);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Mouse Methods
|
||||
/// @{
|
||||
|
||||
/// When a control gets the mouse lock this means that that control gets
|
||||
/// ALL mouse input and no other control recieves any input.
|
||||
/// @param lockingControl Control to lock mouse to
|
||||
virtual void mouseLock(GuiControl *lockingControl);
|
||||
|
||||
/// Unlocks the mouse from a control
|
||||
/// @param lockingControl Control to unlock from
|
||||
virtual void mouseUnlock(GuiControl *lockingControl);
|
||||
|
||||
/// Returns the control which the mouse is over
|
||||
virtual GuiControl* getMouseControl() { return mMouseControl; }
|
||||
|
||||
/// Returns the control which the mouse is locked to if any
|
||||
virtual GuiControl* getMouseLockedControl() { return mMouseCapturedControl; }
|
||||
|
||||
/// Returns true if the left mouse button is down
|
||||
virtual bool mouseButtonDown(void) { return mMouseButtonDown; }
|
||||
|
||||
/// Returns true if the right mouse button is down
|
||||
virtual bool mouseRightButtonDown(void) { return mMouseRightButtonDown; }
|
||||
|
||||
virtual void checkLockMouseMove(const GuiEvent &event);
|
||||
/// @}
|
||||
|
||||
/// @name Mouse input methods
|
||||
/// These events process the events before passing them down to the
|
||||
/// controls they effect. This allows for things such as the input
|
||||
/// locking and such.
|
||||
///
|
||||
/// Each of these methods corosponds to the action in it's method name
|
||||
/// and processes the GuiEvent passd as a parameter
|
||||
/// @{
|
||||
virtual void rootMouseUp(const GuiEvent &event);
|
||||
virtual void rootMouseDown(const GuiEvent &event);
|
||||
virtual void rootMouseMove(const GuiEvent &event);
|
||||
virtual void rootMouseDragged(const GuiEvent &event);
|
||||
|
||||
virtual void rootRightMouseDown(const GuiEvent &event);
|
||||
virtual void rootRightMouseUp(const GuiEvent &event);
|
||||
virtual void rootRightMouseDragged(const GuiEvent &event);
|
||||
|
||||
virtual void rootMiddleMouseDown(const GuiEvent &event);
|
||||
virtual void rootMiddleMouseUp(const GuiEvent &event);
|
||||
virtual void rootMiddleMouseDragged(const GuiEvent &event);
|
||||
|
||||
virtual void rootMouseWheelUp(const GuiEvent &event);
|
||||
virtual void rootMouseWheelDown(const GuiEvent &event);
|
||||
/// @}
|
||||
|
||||
/// @name Keyboard input methods
|
||||
/// First responders
|
||||
///
|
||||
/// A first responder is a the GuiControl which responds first to input events
|
||||
/// before passing them off for further processing.
|
||||
/// @{
|
||||
|
||||
/// Moves the first responder to the next tabable controle
|
||||
virtual void tabNext(void);
|
||||
|
||||
/// Moves the first responder to the previous tabable control
|
||||
virtual void tabPrev(void);
|
||||
|
||||
/// Setups a keyboard accelerator which maps to a GuiControl.
|
||||
///
|
||||
/// @param ctrl GuiControl to map to.
|
||||
/// @param index
|
||||
/// @param keyCode Key code.
|
||||
/// @param modifier Shift, ctrl, etc.
|
||||
virtual void addAcceleratorKey(GuiControl *ctrl, U32 index, U32 keyCode, U32 modifier);
|
||||
|
||||
/// Sets the first responder.
|
||||
/// @param firstResponder Control to designate as first responder
|
||||
virtual void setFirstResponder(GuiControl *firstResponder);
|
||||
/// @}
|
||||
};
|
||||
|
||||
extern GuiCanvas *Canvas;
|
||||
|
||||
#endif
|
1389
engine/gui/core/guiControl.cc
Executable file
1389
engine/gui/core/guiControl.cc
Executable file
File diff suppressed because it is too large
Load Diff
569
engine/gui/core/guiControl.h
Executable file
569
engine/gui/core/guiControl.h
Executable file
@ -0,0 +1,569 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUICONTROL_H_
|
||||
#define _GUICONTROL_H_
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#include "platform/platform.h"
|
||||
#endif
|
||||
#ifndef _MPOINT_H_
|
||||
#include "math/mPoint.h"
|
||||
#endif
|
||||
#ifndef _MRECT_H_
|
||||
#include "math/mRect.h"
|
||||
#endif
|
||||
#ifndef _COLOR_H_
|
||||
#include "core/color.h"
|
||||
#endif
|
||||
#ifndef _SIMBASE_H_
|
||||
#include "console/simBase.h"
|
||||
#endif
|
||||
#ifndef _GUITYPES_H_
|
||||
#include "gui/core/guiTypes.h"
|
||||
#endif
|
||||
#ifndef _EVENT_H_
|
||||
#include "platform/event.h"
|
||||
#endif
|
||||
|
||||
#ifndef _LANG_H_
|
||||
#include "i18n/lang.h"
|
||||
#endif
|
||||
class GuiCanvas;
|
||||
class GuiEditCtrl;
|
||||
|
||||
/// Root class for all GUI controls in Torque.
|
||||
///
|
||||
/// @see GUI for an overview of the Torque GUI system.
|
||||
///
|
||||
/// @section GuiControl_Intro Introduction
|
||||
///
|
||||
/// GuiControl is the base class for GUI controls in Torque. It provides these
|
||||
/// basic areas of functionality:
|
||||
/// - Inherits from SimGroup, so that controls can have children.
|
||||
/// - Interfacing with a GuiControlProfile.
|
||||
/// - An abstraction from the details of handling user input
|
||||
/// and so forth, providing friendly hooks like onMouseEnter(), onMouseMove(),
|
||||
/// and onMouseLeave(), onKeyDown(), and so forth.
|
||||
/// - An abstraction from the details of rendering and resizing.
|
||||
/// - Helper functions to manipulate the mouse (mouseLock and
|
||||
/// mouseUnlock), and convert coordinates (localToGlobalCoord() and
|
||||
/// globalToLocalCoord()).
|
||||
///
|
||||
/// @ref GUI has an overview of the GUI system.
|
||||
///
|
||||
/// @nosubgrouping
|
||||
class GuiControl : public SimGroup
|
||||
{
|
||||
private:
|
||||
typedef SimGroup Parent;
|
||||
|
||||
public:
|
||||
|
||||
/// @name Control State
|
||||
/// @{
|
||||
|
||||
GuiControlProfile *mProfile;
|
||||
|
||||
GuiControlProfile *mTooltipProfile;
|
||||
|
||||
|
||||
bool mVisible;
|
||||
bool mActive;
|
||||
bool mAwake;
|
||||
bool mSetFirstResponder;
|
||||
|
||||
S32 mLayer;
|
||||
RectI mBounds;
|
||||
Point2I mMinExtent;
|
||||
StringTableEntry mLangTableName;
|
||||
LangTable *mLangTable;
|
||||
|
||||
static bool smDesignTime; ///< static GuiControl boolean that specifies if the GUI Editor is active
|
||||
/// @}
|
||||
|
||||
/// @name Design Time Editor Access
|
||||
/// @{
|
||||
static GuiEditCtrl *smEditorHandle; ///< static GuiEditCtrl pointer that gives controls access to editor-NULL if editor is closed
|
||||
/// @}
|
||||
|
||||
/// @name Keyboard Input
|
||||
/// @{
|
||||
GuiControl *mFirstResponder;
|
||||
static GuiControl *smPrevResponder;
|
||||
static GuiControl *smCurResponder;
|
||||
/// @}
|
||||
|
||||
enum horizSizingOptions
|
||||
{
|
||||
horizResizeRight = 0, ///< fixed on the left and width
|
||||
horizResizeWidth, ///< fixed on the left and right
|
||||
horizResizeLeft, ///< fixed on the right and width
|
||||
horizResizeCenter,
|
||||
horizResizeRelative ///< resize relative
|
||||
};
|
||||
enum vertSizingOptions
|
||||
{
|
||||
vertResizeBottom = 0, ///< fixed on the top and in height
|
||||
vertResizeHeight, ///< fixed on the top and bottom
|
||||
vertResizeTop, ///< fixed in height and on the bottom
|
||||
vertResizeCenter,
|
||||
vertResizeRelative ///< resize relative
|
||||
};
|
||||
|
||||
protected:
|
||||
/// @name Control State
|
||||
/// @{
|
||||
|
||||
S32 mHorizSizing; ///< Set from horizSizingOptions.
|
||||
S32 mVertSizing; ///< Set from vertSizingOptions.
|
||||
|
||||
StringTableEntry mConsoleVariable;
|
||||
StringTableEntry mConsoleCommand;
|
||||
StringTableEntry mAltConsoleCommand;
|
||||
|
||||
StringTableEntry mAcceleratorKey;
|
||||
|
||||
StringTableEntry mTooltip;
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Console
|
||||
/// The console variable collection of functions allows a console variable to be bound to the GUI control.
|
||||
///
|
||||
/// This allows, say, an edit field to be bound to '$foo'. The value of the console
|
||||
/// variable '$foo' would then be equal to the text inside the text field. Changing
|
||||
/// either changes the other.
|
||||
/// @{
|
||||
|
||||
/// Sets the value of the console variable bound to this control
|
||||
/// @param value String value to assign to control's console variable
|
||||
void setVariable(const char *value);
|
||||
|
||||
/// Sets the value of the console variable bound to this control
|
||||
/// @param value Integer value to assign to control's console variable
|
||||
void setIntVariable(S32 value);
|
||||
|
||||
/// Sets the value of the console variable bound to this control
|
||||
/// @param value Float value to assign to control's console variable
|
||||
void setFloatVariable(F32 value);
|
||||
|
||||
const char* getVariable(); ///< Returns value of control's bound variable as a string
|
||||
S32 getIntVariable(); ///< Returns value of control's bound variable as a integer
|
||||
F32 getFloatVariable(); ///< Returns value of control's bound variable as a float
|
||||
|
||||
public:
|
||||
/// Set the name of the console variable which this GuiObject is bound to
|
||||
/// @param variable Variable name
|
||||
void setConsoleVariable(const char *variable);
|
||||
|
||||
/// Set the name of the console function bound to, such as a script function
|
||||
/// a button calls when clicked.
|
||||
/// @param newCmd Console function to attach to this GuiControl
|
||||
void setConsoleCommand(const char *newCmd);
|
||||
const char * getConsoleCommand(); ///< Returns the name of the function bound to this GuiControl
|
||||
LangTable *getGUILangTable(void);
|
||||
const UTF8 *getGUIString(S32 id);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Editor
|
||||
/// These functions are used by the GUI Editor
|
||||
/// @{
|
||||
|
||||
/// Sets the size of the GuiControl
|
||||
/// @param horz Width of the control
|
||||
/// @param vert Height of the control
|
||||
void setSizing(S32 horz, S32 vert);
|
||||
|
||||
/// @}
|
||||
public:
|
||||
/// @name Initialization
|
||||
/// @{
|
||||
|
||||
DECLARE_CONOBJECT(GuiControl);
|
||||
GuiControl();
|
||||
virtual ~GuiControl();
|
||||
static void initPersistFields();
|
||||
/// @}
|
||||
|
||||
/// @name Accessors
|
||||
/// @{
|
||||
|
||||
const Point2I& getPosition() { return mBounds.point; } ///< Returns position of the control
|
||||
const Point2I& getExtent() { return mBounds.extent; } ///< Returns extents of the control
|
||||
const Point2I& getMinExtent() { return mMinExtent; } ///< Returns minimum size the control can be
|
||||
const S32 getLeft() { return mBounds.point.x; } ///< Returns the X position of the control
|
||||
const S32 getTop() { return mBounds.point.y; } ///< Returns the Y position of the control
|
||||
const S32 getWidth() { return mBounds.extent.x; } ///< Returns the width of the control
|
||||
const S32 getHeight() { return mBounds.extent.y; } ///< Returns the height of the control
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Flags
|
||||
/// @{
|
||||
|
||||
/// Sets the visibility of the control
|
||||
/// @param value True if object should be visible
|
||||
virtual void setVisible(bool value);
|
||||
inline bool isVisible() { return mVisible; } ///< Returns true if the object is visible
|
||||
|
||||
/// Sets the status of this control as active and responding or inactive
|
||||
/// @param value True if this is active
|
||||
void setActive(bool value);
|
||||
bool isActive() { return mActive; } ///< Returns true if this control is active
|
||||
|
||||
bool isAwake() { return mAwake; } ///< Returns true if this control is awake
|
||||
|
||||
/// @}
|
||||
|
||||
/// Get information about the size of a scroll line.
|
||||
///
|
||||
/// @param rowHeight The height, in pixels, of a row
|
||||
/// @param columnWidth The width, in pixels, of a column
|
||||
virtual void getScrollLineSizes(U32 *rowHeight, U32 *columnWidth);
|
||||
|
||||
/// Get information about the cursor.
|
||||
/// @param cursor Cursor information will be stored here
|
||||
/// @param showCursor Will be set to true if the cursor is visible
|
||||
/// @param lastGuiEvent GuiEvent containing cursor position and modifyer keys (ie ctrl, shift, alt etc)
|
||||
virtual void getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent);
|
||||
|
||||
/// @name Children
|
||||
/// @{
|
||||
|
||||
/// Adds an object as a child of this object.
|
||||
/// @param obj New child object of this control
|
||||
void addObject(SimObject *obj);
|
||||
|
||||
/// Removes a child object from this control.
|
||||
/// @param obj Object to remove from this control
|
||||
void removeObject(SimObject *obj);
|
||||
|
||||
GuiControl *getParent(); ///< Returns the control which owns this one.
|
||||
GuiCanvas *getRoot(); ///< Returns the root canvas of this control.
|
||||
/// @}
|
||||
|
||||
/// @name Coordinates
|
||||
/// @{
|
||||
|
||||
/// Translates local coordinates (wrt this object) into global coordinates
|
||||
///
|
||||
/// @param src Local coordinates to translate
|
||||
Point2I localToGlobalCoord(const Point2I &src);
|
||||
|
||||
/// Returns global coordinates translated into local space
|
||||
///
|
||||
/// @param src Global coordinates to translate
|
||||
Point2I globalToLocalCoord(const Point2I &src);
|
||||
/// @}
|
||||
|
||||
/// @name Resizing
|
||||
/// @{
|
||||
|
||||
/// Changes the size and/or position of this control
|
||||
/// @param newPosition New position of this control
|
||||
/// @param newExtent New size of this control
|
||||
virtual void resize(const Point2I &newPosition, const Point2I &newExtent);
|
||||
|
||||
/// Changes the position of this control
|
||||
/// @param newPosition New position of this control
|
||||
virtual void setPosition( const Point2I &newPosition );
|
||||
|
||||
/// Changes the size of this control
|
||||
/// @param newExtent New size of this control
|
||||
virtual void setExtent( const Point2I &newExtent );
|
||||
|
||||
/// Changes the X position of this control
|
||||
/// @param newXPosition New X Position of this control
|
||||
virtual void setLeft( S32 newLeft );
|
||||
|
||||
/// Changes the Y position of this control
|
||||
/// @param newYPosition New Y Position of this control
|
||||
virtual void setTop( S32 newTop );
|
||||
|
||||
/// Changes the width of this control
|
||||
/// @param newWidth New width of this control
|
||||
virtual void setWidth( S32 newWidth );
|
||||
|
||||
/// Changes the height of this control
|
||||
/// @param newHeight New Height of this control
|
||||
virtual void setHeight( S32 newHeight );
|
||||
|
||||
/// Called when a child control of the object is resized
|
||||
/// @param child Child object
|
||||
virtual void childResized(GuiControl *child);
|
||||
|
||||
/// Called when this objects parent is resized
|
||||
/// @param oldParentExtent The old size of the parent object
|
||||
/// @param newParentExtent The new size of the parent object
|
||||
virtual void parentResized(const Point2I &oldParentExtent, const Point2I &newParentExtent);
|
||||
/// @}
|
||||
|
||||
/// @name Rendering
|
||||
/// @{
|
||||
|
||||
/// Called when this control is to render itself
|
||||
/// @param offset The location this control is to begin rendering
|
||||
/// @param updateRect The screen area this control has drawing access to
|
||||
virtual void onRender(Point2I offset, const RectI &updateRect);
|
||||
|
||||
virtual bool renderTooltip(Point2I cursorPos);
|
||||
|
||||
/// Called when this control should render its children
|
||||
/// @param offset The location this control is to begin rendering
|
||||
/// @param updateRect The screen area this control has drawing access to
|
||||
void renderChildControls(Point2I offset, const RectI &updateRect);
|
||||
|
||||
/// Sets the area (local coordinates) this control wants refreshed each frame
|
||||
/// @param pos UpperLeft point on rectangle of refresh area
|
||||
/// @param ext Extent of update rect
|
||||
void setUpdateRegion(Point2I pos, Point2I ext);
|
||||
|
||||
/// Sets the update area of the control to encompass the whole control
|
||||
void setUpdate();
|
||||
/// @}
|
||||
|
||||
//child hierarchy calls
|
||||
void awaken(); ///< Called when this control and its children have been wired up.
|
||||
void sleep(); ///< Called when this control is no more.
|
||||
void preRender(); ///< Prerender this control and all its children.
|
||||
|
||||
/// @name Events
|
||||
///
|
||||
/// If you subclass these, make sure to call the Parent::'s versions.
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Called when this object is asked to wake up returns true if it's actually awake at the end
|
||||
virtual bool onWake();
|
||||
|
||||
/// Called when this object is asked to sleep
|
||||
virtual void onSleep();
|
||||
|
||||
/// Do special pre-render proecessing
|
||||
virtual void onPreRender();
|
||||
|
||||
/// Called when this object is removed
|
||||
virtual void onRemove();
|
||||
|
||||
/// Called when one of this objects children is removed
|
||||
virtual void onChildRemoved( GuiControl *child );
|
||||
|
||||
/// Called when this object is added to the scene
|
||||
bool onAdd();
|
||||
|
||||
/// Called when this object has a new child
|
||||
virtual void onChildAdded( GuiControl *child );
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Console
|
||||
/// @{
|
||||
|
||||
/// Returns the value of the variable bound to this object
|
||||
virtual const char *getScriptValue();
|
||||
|
||||
/// Sets the value of the variable bound to this object
|
||||
virtual void setScriptValue(const char *value);
|
||||
/// @}
|
||||
|
||||
/// @name Input (Keyboard/Mouse)
|
||||
/// @{
|
||||
|
||||
/// This function will return true if the provided coordinates (wrt parent object) are
|
||||
/// within the bounds of this control
|
||||
/// @param parentCoordPoint Coordinates to test
|
||||
virtual bool pointInControl(const Point2I& parentCoordPoint);
|
||||
|
||||
/// Returns true if the global cursor is inside this control
|
||||
bool cursorInControl();
|
||||
|
||||
/// Returns the control which the provided point is under, with layering
|
||||
/// @param pt Point to test
|
||||
/// @param initialLayer Layer of gui objects to begin the search
|
||||
virtual GuiControl* findHitControl(const Point2I &pt, S32 initialLayer = -1);
|
||||
|
||||
/// Lock the mouse within the provided control
|
||||
/// @param lockingControl Control to lock the mouse within
|
||||
void mouseLock(GuiControl *lockingControl);
|
||||
|
||||
/// Turn on mouse locking with last used lock control
|
||||
void mouseLock();
|
||||
|
||||
/// Unlock the mouse
|
||||
void mouseUnlock();
|
||||
|
||||
/// Returns true if the mouse is locked
|
||||
bool isMouseLocked();
|
||||
/// @}
|
||||
|
||||
|
||||
/// General input handler.
|
||||
virtual bool onInputEvent(const InputEvent &event);
|
||||
|
||||
/// @name Mouse Events
|
||||
/// These functions are called when the input event which is
|
||||
/// in the name of the function occurs.
|
||||
/// @{
|
||||
virtual void onMouseUp(const GuiEvent &event);
|
||||
virtual void onMouseDown(const GuiEvent &event);
|
||||
virtual void onMouseMove(const GuiEvent &event);
|
||||
virtual void onMouseDragged(const GuiEvent &event);
|
||||
virtual void onMouseEnter(const GuiEvent &event);
|
||||
virtual void onMouseLeave(const GuiEvent &event);
|
||||
|
||||
virtual bool onMouseWheelUp(const GuiEvent &event);
|
||||
virtual bool onMouseWheelDown(const GuiEvent &event);
|
||||
|
||||
virtual void onRightMouseDown(const GuiEvent &event);
|
||||
virtual void onRightMouseUp(const GuiEvent &event);
|
||||
virtual void onRightMouseDragged(const GuiEvent &event);
|
||||
|
||||
virtual void onMiddleMouseDown(const GuiEvent &event);
|
||||
virtual void onMiddleMouseUp(const GuiEvent &event);
|
||||
virtual void onMiddleMouseDragged(const GuiEvent &event);
|
||||
|
||||
/// Called when a mouseDown event occurs on a control and the GUI editor is active
|
||||
/// @param event the GuiEvent which caused the call to this function
|
||||
/// @param offset the offset which is representative of the units x and y that the editor takes up on screen
|
||||
virtual void onMouseDownEditor(const GuiEvent &event, Point2I offset);
|
||||
|
||||
/// Called when a rightMouseDown event occurs on a control and the GUI editor is active
|
||||
/// @param event the GuiEvent which caused the call to this function
|
||||
/// @param offset the offset which is representative of the units x and y that the editor takes up on screen
|
||||
virtual void onRightMouseDownEditor(const GuiEvent &event, Point2I offset);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Tabs
|
||||
/// @{
|
||||
|
||||
/// Find the first tab-accessable child of this control
|
||||
virtual GuiControl* findFirstTabable();
|
||||
|
||||
/// Find the last tab-accessable child of this control
|
||||
/// @param firstCall Set to true to clear the global previous responder
|
||||
virtual GuiControl* findLastTabable(bool firstCall = true);
|
||||
|
||||
/// Find previous tab-accessable control with respect to the provided one
|
||||
/// @param curResponder Current control
|
||||
/// @param firstCall Set to true to clear the global previous responder
|
||||
virtual GuiControl* findPrevTabable(GuiControl *curResponder, bool firstCall = true);
|
||||
|
||||
/// Find next tab-accessable control with regards to the provided control.
|
||||
///
|
||||
/// @param curResponder Current control
|
||||
/// @param firstCall Set to true to clear the global current responder
|
||||
virtual GuiControl* findNextTabable(GuiControl *curResponder, bool firstCall = true);
|
||||
/// @}
|
||||
|
||||
/// Returns true if the provided control is a child (grandchild, or greatgrandchild) of this one.
|
||||
///
|
||||
/// @param child Control to test
|
||||
virtual bool ControlIsChild(GuiControl *child);
|
||||
|
||||
/// @name First Responder
|
||||
/// A first responder is the control which reacts first, in it's responder chain, to keyboard events
|
||||
/// The responder chain is set for each parent and so there is only one first responder amongst it's
|
||||
/// children.
|
||||
/// @{
|
||||
|
||||
/// Sets the first responder for child controls
|
||||
/// @param firstResponder First responder for this chain
|
||||
virtual void setFirstResponder(GuiControl *firstResponder);
|
||||
|
||||
/// Sets up this control to be the first in it's group to respond to an input event
|
||||
/// @param value True if this should be a first responder
|
||||
virtual void makeFirstResponder(bool value);
|
||||
|
||||
/// Returns true if this control is a first responder
|
||||
bool isFirstResponder();
|
||||
|
||||
/// Sets this object to be a first responder
|
||||
void setFirstResponder();
|
||||
|
||||
/// Clears the first responder for this chain
|
||||
void clearFirstResponder();
|
||||
|
||||
/// Returns the first responder for this chain
|
||||
GuiControl *getFirstResponder() { return mFirstResponder; }
|
||||
|
||||
/// Occurs when the first responder for this chain is lost
|
||||
virtual void onLoseFirstResponder();
|
||||
/// @}
|
||||
|
||||
/// @name Keyboard Events
|
||||
/// @{
|
||||
|
||||
/// Adds the accelerator key for this object to the canvas
|
||||
void addAcceleratorKey();
|
||||
|
||||
/// Adds this control's accelerator key to the accelerator map, and
|
||||
/// recursively tells all children to do the same.
|
||||
virtual void buildAcceleratorMap();
|
||||
|
||||
/// Occurs when the accelerator key for this control is pressed
|
||||
///
|
||||
/// @param index Index in the acclerator map of the key
|
||||
virtual void acceleratorKeyPress(U32 index);
|
||||
|
||||
/// Occurs when the accelerator key for this control is released
|
||||
///
|
||||
/// @param index Index in the acclerator map of the key
|
||||
virtual void acceleratorKeyRelease(U32 index);
|
||||
|
||||
/// Happens when a key is depressed
|
||||
/// @param event Event descriptor (which contains the key)
|
||||
virtual bool onKeyDown(const GuiEvent &event);
|
||||
|
||||
/// Happens when a key is released
|
||||
/// @param event Event descriptor (which contains the key)
|
||||
virtual bool onKeyUp(const GuiEvent &event);
|
||||
|
||||
/// Happens when the same key that was pressed last press is pressed again
|
||||
/// @param event Event descriptor (which contains the key)
|
||||
virtual bool onKeyRepeat(const GuiEvent &event);
|
||||
/// @}
|
||||
|
||||
/// Sets the control profile for this control.
|
||||
///
|
||||
/// @see GuiControlProfile
|
||||
/// @param prof Control profile to apply
|
||||
void setControlProfile(GuiControlProfile *prof);
|
||||
|
||||
/// Occurs when this control performs its "action"
|
||||
virtual void onAction();
|
||||
|
||||
/// @name Peer Messaging
|
||||
/// Used to send a message to other GUIControls which are children of the same parent.
|
||||
///
|
||||
/// This is mostly used by radio controls.
|
||||
/// @{
|
||||
void messageSiblings(S32 message); ///< Send a message to all siblings
|
||||
virtual void onMessage(GuiControl *sender, S32 msg); ///< Receive a message from another control
|
||||
/// @}
|
||||
|
||||
/// @name Canvas Events
|
||||
/// Functions called by the canvas
|
||||
/// @{
|
||||
|
||||
/// Called if this object is a dialog, when it is added to the visible layers
|
||||
virtual void onDialogPush();
|
||||
|
||||
/// Called if this object is a dialog, when it is removed from the visible layers
|
||||
virtual void onDialogPop();
|
||||
/// @}
|
||||
|
||||
/// Renders justified text using the profile.
|
||||
///
|
||||
/// @note This should move into the graphics library at some point
|
||||
void renderJustifiedText(Point2I offset, Point2I extent, const char *text);
|
||||
|
||||
void inspectPostApply();
|
||||
void inspectPreApply();
|
||||
};
|
||||
|
||||
#endif
|
134
engine/gui/core/guiDefaultControlRender.cc
Executable file
134
engine/gui/core/guiDefaultControlRender.cc
Executable file
@ -0,0 +1,134 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (c) 2002 GarageGames.Com
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "dgl/dgl.h"
|
||||
#include "gui/core/guiDefaultControlRender.h"
|
||||
#include "gui/core/guiTypes.h"
|
||||
#include "core/color.h"
|
||||
#include "math/mRect.h"
|
||||
|
||||
static ColorI colorLightGray(192, 192, 192);
|
||||
static ColorI colorGray(128, 128, 128);
|
||||
static ColorI colorDarkGray(64, 64, 64);
|
||||
static ColorI colorWhite(255,255,255);
|
||||
static ColorI colorBlack(0,0,0);
|
||||
|
||||
void renderRaisedBox(RectI &bounds, GuiControlProfile *profile)
|
||||
{
|
||||
S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
|
||||
S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
|
||||
|
||||
dglDrawRectFill( bounds, profile->mFillColor);
|
||||
dglDrawLine(l, t, l, b - 1, profile->mBevelColorHL);
|
||||
dglDrawLine(l, t, r - 1, t, profile->mBevelColorHL);
|
||||
|
||||
dglDrawLine(l, b, r, b, profile->mBevelColorLL);
|
||||
dglDrawLine(r, b - 1, r, t, profile->mBevelColorLL);
|
||||
|
||||
dglDrawLine(l + 1, b - 1, r - 1, b - 1, profile->mBorderColor);
|
||||
dglDrawLine(r - 1, b - 2, r - 1, t + 1, profile->mBorderColor);
|
||||
}
|
||||
|
||||
void renderSlightlyRaisedBox(RectI &bounds, GuiControlProfile *profile)
|
||||
{
|
||||
S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
|
||||
S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
|
||||
|
||||
dglDrawRectFill( bounds, profile->mFillColor);
|
||||
dglDrawLine(l, t, l, b, profile->mBevelColorHL);
|
||||
dglDrawLine(l, t, r, t, profile->mBevelColorHL);
|
||||
dglDrawLine(l + 1, b, r, b, profile->mBorderColor);
|
||||
dglDrawLine(r, t + 1, r, b - 1, profile->mBorderColor);
|
||||
}
|
||||
|
||||
void renderLoweredBox(RectI &bounds, GuiControlProfile *profile)
|
||||
{
|
||||
S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
|
||||
S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
|
||||
|
||||
dglDrawRectFill( bounds, profile->mFillColor);
|
||||
|
||||
dglDrawLine(l, b, r, b, profile->mBevelColorHL);
|
||||
dglDrawLine(r, b - 1, r, t, profile->mBevelColorHL);
|
||||
|
||||
dglDrawLine(l, t, r - 1, t, profile->mBevelColorLL);
|
||||
dglDrawLine(l, t + 1, l, b - 1, profile->mBevelColorLL);
|
||||
|
||||
dglDrawLine(l + 1, t + 1, r - 2, t + 1, profile->mBorderColor);
|
||||
dglDrawLine(l + 1, t + 2, l + 1, b - 2, profile->mBorderColor);
|
||||
}
|
||||
|
||||
void renderSlightlyLoweredBox(RectI &bounds, GuiControlProfile *profile)
|
||||
{
|
||||
S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
|
||||
S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
|
||||
|
||||
dglDrawRectFill( bounds, profile->mFillColor);
|
||||
dglDrawLine(l, b, r, b, profile->mBevelColorHL);
|
||||
dglDrawLine(r, t, r, b - 1, profile->mBevelColorHL);
|
||||
dglDrawLine(l, t, l, b - 1, profile->mBorderColor);
|
||||
dglDrawLine(l + 1, t, r - 1, t, profile->mBorderColor);
|
||||
}
|
||||
|
||||
void renderBorder(RectI &bounds, GuiControlProfile *profile)
|
||||
{
|
||||
S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
|
||||
S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
|
||||
|
||||
switch(profile->mBorder)
|
||||
{
|
||||
case 1:
|
||||
dglDrawRect(bounds, profile->mBorderColor);
|
||||
break;
|
||||
case 2:
|
||||
dglDrawLine(l + 1, t + 1, l + 1, b - 2, profile->mBevelColorHL);
|
||||
dglDrawLine(l + 2, t + 1, r - 2, t + 1, profile->mBevelColorHL);
|
||||
dglDrawLine(r, t, r, b, profile->mBevelColorHL);
|
||||
dglDrawLine(l, b, r - 1, b, profile->mBevelColorHL);
|
||||
dglDrawLine(l, t, r - 1, t, profile->mBorderColorNA);
|
||||
dglDrawLine(l, t + 1, l, b - 1, profile->mBorderColorNA);
|
||||
dglDrawLine(l + 1, b - 1, r - 1, b - 1, profile->mBorderColorNA);
|
||||
dglDrawLine(r - 1, t + 1, r - 1, b - 2, profile->mBorderColorNA);
|
||||
break;
|
||||
case 3:
|
||||
dglDrawLine(l, b, r, b, profile->mBevelColorHL);
|
||||
dglDrawLine(r, t, r, b - 1, profile->mBevelColorHL);
|
||||
dglDrawLine(l + 1, b - 1, r - 1, b - 1, profile->mFillColor);
|
||||
dglDrawLine(r - 1, t + 1, r - 1, b - 2, profile->mFillColor);
|
||||
dglDrawLine(l, t, l, b - 1, profile->mBorderColorNA);
|
||||
dglDrawLine(l + 1, t, r - 1, t, profile->mBorderColorNA);
|
||||
dglDrawLine(l + 1, t + 1, l + 1, b - 2, profile->mBevelColorLL);
|
||||
dglDrawLine(l + 2, t + 1, r - 2, t + 1, profile->mBevelColorLL);
|
||||
break;
|
||||
case 4:
|
||||
dglDrawLine(l, t, l, b - 1, profile->mBevelColorHL);
|
||||
dglDrawLine(l + 1, t, r, t, profile->mBevelColorHL);
|
||||
dglDrawLine(l, b, r, b, profile->mBevelColorLL);
|
||||
dglDrawLine(r, t + 1, r, b - 1, profile->mBevelColorLL);
|
||||
dglDrawLine(l + 1, b - 1, r - 1, b - 1, profile->mBorderColor);
|
||||
dglDrawLine(r - 1, t + 1, r - 1, b - 2, profile->mBorderColor);
|
||||
break;
|
||||
case 5:
|
||||
renderFilledBorder( bounds, profile );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void renderFilledBorder( RectI &bounds, GuiControlProfile *profile )
|
||||
{
|
||||
renderFilledBorder( bounds, profile->mBorderColorHL, profile->mFillColor );
|
||||
}
|
||||
|
||||
void renderFilledBorder( RectI &bounds, ColorI &borderColor, ColorI &fillColor )
|
||||
{
|
||||
S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
|
||||
S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
|
||||
|
||||
RectI fillBounds = bounds;
|
||||
fillBounds.inset( 1, 1 );
|
||||
dglDrawRect( bounds, borderColor );
|
||||
dglDrawRectFill( fillBounds, fillColor );
|
||||
}
|
||||
|
19
engine/gui/core/guiDefaultControlRender.h
Executable file
19
engine/gui/core/guiDefaultControlRender.h
Executable file
@ -0,0 +1,19 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (c) 2002 GarageGames.Com
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _H_GUIDEFAULTCONTROLRENDER_
|
||||
#define _H_GUIDEFAULTCONTROLRENDER_
|
||||
|
||||
class GuiControlProfile;
|
||||
|
||||
void renderRaisedBox(RectI &bounds, GuiControlProfile *profile);
|
||||
void renderSlightlyRaisedBox(RectI &bounds, GuiControlProfile *profile);
|
||||
void renderLoweredBox(RectI &bounds, GuiControlProfile *profile);
|
||||
void renderSlightlyLoweredBox(RectI &bounds, GuiControlProfile *profile);
|
||||
void renderBorder(RectI &bounds, GuiControlProfile *profile);
|
||||
void renderFilledBorder( RectI &bounds, GuiControlProfile *profile );
|
||||
void renderFilledBorder( RectI &bounds, ColorI &borderColor, ColorI &fillColor );
|
||||
|
||||
#endif
|
160
engine/gui/core/guiTSControl.cc
Executable file
160
engine/gui/core/guiTSControl.cc
Executable file
@ -0,0 +1,160 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "gui/core/guiTSControl.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "sceneGraph/sceneLighting.h"
|
||||
#include "sceneGraph/sceneGraph.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiTSCtrl);
|
||||
|
||||
U32 GuiTSCtrl::smFrameCount = 0;
|
||||
|
||||
GuiTSCtrl::GuiTSCtrl()
|
||||
{
|
||||
mApplyFilterToChildren = true;
|
||||
|
||||
mCameraZRot = 0;
|
||||
mForceFOV = 0;
|
||||
|
||||
for(U32 i = 0; i < 16; i++)
|
||||
{
|
||||
mSaveModelview[i] = 0;
|
||||
mSaveProjection[i] = 0;
|
||||
}
|
||||
mSaveModelview[0] = 1;
|
||||
mSaveModelview[5] = 1;
|
||||
mSaveModelview[10] = 1;
|
||||
mSaveModelview[15] = 1;
|
||||
mSaveProjection[0] = 1;
|
||||
mSaveProjection[5] = 1;
|
||||
mSaveProjection[10] = 1;
|
||||
mSaveProjection[15] = 1;
|
||||
|
||||
mSaveViewport[0] = 0;
|
||||
mSaveViewport[1] = 0;
|
||||
mSaveViewport[2] = 2;
|
||||
mSaveViewport[3] = 2;
|
||||
}
|
||||
|
||||
void GuiTSCtrl::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
|
||||
addField("applyFilterToChildren", TypeBool, Offset(mApplyFilterToChildren, GuiTSCtrl));
|
||||
addField("cameraZRot", TypeF32, Offset(mCameraZRot, GuiTSCtrl));
|
||||
addField("forceFOV", TypeF32, Offset(mForceFOV, GuiTSCtrl));
|
||||
}
|
||||
|
||||
void GuiTSCtrl::consoleInit()
|
||||
{
|
||||
Con::addVariable("$TSControl::frameCount", TypeS32, &smFrameCount);
|
||||
}
|
||||
|
||||
void GuiTSCtrl::onPreRender()
|
||||
{
|
||||
setUpdate();
|
||||
}
|
||||
|
||||
bool GuiTSCtrl::processCameraQuery(CameraQuery *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void GuiTSCtrl::renderWorld(const RectI& /*updateRect*/)
|
||||
{
|
||||
}
|
||||
|
||||
bool GuiTSCtrl::project(const Point3F &pt, Point3F *dest)
|
||||
{
|
||||
GLdouble winx, winy, winz;
|
||||
GLint result = gluProject(pt.x, pt.y, pt.z,
|
||||
mSaveModelview, mSaveProjection, mSaveViewport,
|
||||
&winx, &winy, &winz);
|
||||
if(result == GL_FALSE || winz < 0 || winz > 1)
|
||||
return false;
|
||||
dest->set(winx, winy, winz);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GuiTSCtrl::unproject(const Point3F &pt, Point3F *dest)
|
||||
{
|
||||
GLdouble objx, objy, objz;
|
||||
GLint result = gluUnProject(pt.x, pt.y, pt.z,
|
||||
mSaveModelview, mSaveProjection, mSaveViewport,
|
||||
&objx, &objy, &objz);
|
||||
if(result == GL_FALSE)
|
||||
return false;
|
||||
dest->set(objx, objy, objz);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||
{
|
||||
if(SceneLighting::isLighting())
|
||||
return;
|
||||
|
||||
CameraQuery newCam = mLastCameraQuery;
|
||||
if(processCameraQuery(&newCam))
|
||||
mLastCameraQuery = newCam;
|
||||
|
||||
if(mForceFOV != 0)
|
||||
newCam.fov = mDegToRad(mForceFOV);
|
||||
|
||||
if(mCameraZRot)
|
||||
{
|
||||
MatrixF rotMat(EulerF(0, 0, mDegToRad(mCameraZRot)));
|
||||
newCam.cameraMatrix.mul(rotMat);
|
||||
}
|
||||
|
||||
// set up the camera and viewport stuff:
|
||||
F32 left, right, top, bottom;
|
||||
if (newCam.ortho)
|
||||
{
|
||||
left = -newCam.leftRight;
|
||||
right = newCam.leftRight;
|
||||
top = newCam.topBottom;
|
||||
bottom = -newCam.topBottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 wwidth = newCam.nearPlane * mTan(newCam.fov / 2);
|
||||
F32 wheight = F32(mBounds.extent.y) / F32(mBounds.extent.x) * wwidth;
|
||||
|
||||
F32 hscale = wwidth * 2 / F32(mBounds.extent.x);
|
||||
F32 vscale = wheight * 2 / F32(mBounds.extent.y);
|
||||
|
||||
left = (updateRect.point.x - offset.x) * hscale - wwidth;
|
||||
right = (updateRect.point.x + updateRect.extent.x - offset.x) * hscale - wwidth;
|
||||
top = wheight - vscale * (updateRect.point.y - offset.y);
|
||||
bottom = wheight - vscale * (updateRect.point.y + updateRect.extent.y - offset.y);
|
||||
}
|
||||
|
||||
dglSetViewport(updateRect);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
dglSetFrustum(left, right, bottom, top, newCam.nearPlane, (gClientSceneGraph ? (F64)gClientSceneGraph->getVisibleDistanceMod() : newCam.farPlane), newCam.ortho);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
newCam.cameraMatrix.inverse();
|
||||
dglMultMatrix(&newCam.cameraMatrix);
|
||||
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, mSaveProjection);
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, mSaveModelview);
|
||||
|
||||
mSaveViewport[0] = updateRect.point.x;
|
||||
mSaveViewport[1] = updateRect.point.y + updateRect.extent.y;
|
||||
mSaveViewport[2] = updateRect.extent.x;
|
||||
mSaveViewport[3] = -updateRect.extent.y;
|
||||
|
||||
renderWorld(updateRect);
|
||||
|
||||
if(mApplyFilterToChildren)
|
||||
renderChildControls(offset, updateRect);
|
||||
|
||||
smFrameCount++;
|
||||
}
|
73
engine/gui/core/guiTSControl.h
Executable file
73
engine/gui/core/guiTSControl.h
Executable file
@ -0,0 +1,73 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUITSCONTROL_H_
|
||||
#define _GUITSCONTROL_H_
|
||||
|
||||
#ifndef _GUICONTROL_H_
|
||||
#include "gui/core/guiControl.h"
|
||||
#endif
|
||||
#ifndef _MMATH_H_
|
||||
#include "math/mMath.h"
|
||||
#endif
|
||||
#ifndef _DGL_H_
|
||||
#include "dgl/dgl.h"
|
||||
#endif
|
||||
|
||||
struct CameraQuery
|
||||
{
|
||||
CameraQuery()
|
||||
{
|
||||
ortho = false;
|
||||
}
|
||||
|
||||
SimObject* object;
|
||||
F32 nearPlane;
|
||||
F32 farPlane;
|
||||
F32 fov;
|
||||
MatrixF cameraMatrix;
|
||||
|
||||
F32 leftRight;
|
||||
F32 topBottom;
|
||||
bool ortho;
|
||||
//Point3F position;
|
||||
//Point3F viewVector;
|
||||
//Point3F upVector;
|
||||
};
|
||||
|
||||
class GuiTSCtrl : public GuiControl
|
||||
{
|
||||
typedef GuiControl Parent;
|
||||
|
||||
protected:
|
||||
GLdouble mSaveModelview[16];
|
||||
GLdouble mSaveProjection[16];
|
||||
GLint mSaveViewport[4];
|
||||
|
||||
static U32 smFrameCount;
|
||||
F32 mCameraZRot;
|
||||
F32 mForceFOV;
|
||||
|
||||
bool mApplyFilterToChildren;
|
||||
|
||||
public:
|
||||
CameraQuery mLastCameraQuery;
|
||||
GuiTSCtrl();
|
||||
|
||||
void onPreRender();
|
||||
void onRender(Point2I offset, const RectI &updateRect);
|
||||
virtual bool processCameraQuery(CameraQuery *query);
|
||||
virtual void renderWorld(const RectI &updateRect);
|
||||
|
||||
static void initPersistFields();
|
||||
static void consoleInit();
|
||||
|
||||
bool project(const Point3F &pt, Point3F *dest); // returns screen space X,Y and Z for world space point
|
||||
bool unproject(const Point3F &pt, Point3F *dest); // returns world space point for X, Y and Z
|
||||
|
||||
DECLARE_CONOBJECT(GuiTSCtrl);
|
||||
};
|
||||
|
||||
#endif
|
371
engine/gui/core/guiTypes.cc
Executable file
371
engine/gui/core/guiTypes.cc
Executable file
@ -0,0 +1,371 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "platform/types.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/console.h"
|
||||
#include "dgl/gNewFont.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "gui/core/guiTypes.h"
|
||||
#include "dgl/gBitmap.h"
|
||||
#include "dgl/gTexManager.h"
|
||||
|
||||
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //
|
||||
IMPLEMENT_CONOBJECT(GuiCursor);
|
||||
|
||||
GuiCursor::GuiCursor()
|
||||
{
|
||||
mHotSpot.set(0,0);
|
||||
mRenderOffset.set(0.0f,0.0f);
|
||||
mExtent.set(1,1);
|
||||
}
|
||||
|
||||
GuiCursor::~GuiCursor()
|
||||
{
|
||||
}
|
||||
|
||||
void GuiCursor::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
addField("hotSpot", TypePoint2I, Offset(mHotSpot, GuiCursor));
|
||||
addField("renderOffset",TypePoint2F, Offset(mRenderOffset, GuiCursor));
|
||||
addField("bitmapName", TypeFilename, Offset(mBitmapName, GuiCursor));
|
||||
}
|
||||
|
||||
bool GuiCursor::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
Sim::getGuiDataGroup()->addObject(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiCursor::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
void GuiCursor::render(const Point2I &pos)
|
||||
{
|
||||
if (!mTextureHandle && mBitmapName && mBitmapName[0])
|
||||
{
|
||||
mTextureHandle = TextureHandle(mBitmapName, BitmapTexture);
|
||||
if(!mTextureHandle)
|
||||
return;
|
||||
mExtent.set(mTextureHandle.getWidth(), mTextureHandle.getHeight());
|
||||
}
|
||||
|
||||
// Render the cursor centered according to dimensions of texture
|
||||
S32 texWidth = mTextureHandle.getWidth();
|
||||
S32 texHeight = mTextureHandle.getWidth();
|
||||
|
||||
Point2I renderPos = pos;
|
||||
renderPos.x -= ( texWidth * mRenderOffset.x );
|
||||
renderPos.y -= ( texHeight * mRenderOffset.y );
|
||||
|
||||
dglClearBitmapModulation();
|
||||
dglDrawBitmap(mTextureHandle, renderPos);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(GuiControlProfile);
|
||||
|
||||
static EnumTable::Enums alignEnums[] =
|
||||
{
|
||||
{ GuiControlProfile::LeftJustify, "left" },
|
||||
{ GuiControlProfile::CenterJustify, "center" },
|
||||
{ GuiControlProfile::RightJustify, "right" }
|
||||
};
|
||||
static EnumTable gAlignTable(3, &alignEnums[0]);
|
||||
|
||||
static EnumTable::Enums charsetEnums[]=
|
||||
{
|
||||
{ TGE_ANSI_CHARSET, "ANSI" },
|
||||
{ TGE_SYMBOL_CHARSET, "SYMBOL" },
|
||||
{ TGE_SHIFTJIS_CHARSET, "SHIFTJIS" },
|
||||
{ TGE_HANGEUL_CHARSET, "HANGEUL" },
|
||||
{ TGE_HANGUL_CHARSET, "HANGUL" },
|
||||
{ TGE_GB2312_CHARSET, "GB2312" },
|
||||
{ TGE_CHINESEBIG5_CHARSET, "CHINESEBIG5" },
|
||||
{ TGE_OEM_CHARSET, "OEM" },
|
||||
{ TGE_JOHAB_CHARSET, "JOHAB" },
|
||||
{ TGE_HEBREW_CHARSET, "HEBREW" },
|
||||
{ TGE_ARABIC_CHARSET, "ARABIC" },
|
||||
{ TGE_GREEK_CHARSET, "GREEK" },
|
||||
{ TGE_TURKISH_CHARSET, "TURKISH" },
|
||||
{ TGE_VIETNAMESE_CHARSET, "VIETNAMESE" },
|
||||
{ TGE_THAI_CHARSET, "THAI" },
|
||||
{ TGE_EASTEUROPE_CHARSET, "EASTEUROPE" },
|
||||
{ TGE_RUSSIAN_CHARSET, "RUSSIAN" },
|
||||
{ TGE_MAC_CHARSET, "MAC" },
|
||||
{ TGE_BALTIC_CHARSET, "BALTIC" },
|
||||
};
|
||||
|
||||
#define NUMCHARSETENUMS (sizeof(charsetEnums) / sizeof(EnumTable::Enums))
|
||||
|
||||
static EnumTable gCharsetTable(NUMCHARSETENUMS, &charsetEnums[0]);
|
||||
|
||||
StringTableEntry GuiControlProfile::sFontCacheDirectory = "";
|
||||
|
||||
GuiControlProfile::GuiControlProfile(void) :
|
||||
mFontColor(mFontColors[BaseColor]),
|
||||
mFontColorHL(mFontColors[ColorHL]),
|
||||
mFontColorNA(mFontColors[ColorNA]),
|
||||
mFontColorSEL(mFontColors[ColorSEL])
|
||||
{
|
||||
mRefCount = 0;
|
||||
mBitmapArrayRects.clear();
|
||||
mBorderThickness = 1;
|
||||
mMouseOverSelected = false;
|
||||
mBitmapName = NULL;
|
||||
mFontCharset = TGE_ANSI_CHARSET;
|
||||
|
||||
GuiControlProfile *def = dynamic_cast<GuiControlProfile*>(Sim::findObject("GuiDefaultProfile"));
|
||||
if (def)
|
||||
{
|
||||
mTabable = def->mTabable;
|
||||
mCanKeyFocus = def->mCanKeyFocus;
|
||||
|
||||
mOpaque = def->mOpaque;
|
||||
mFillColor = def->mFillColor;
|
||||
mFillColorHL = def->mFillColorHL;
|
||||
mFillColorNA = def->mFillColorNA;
|
||||
|
||||
mBorder = def->mBorder;
|
||||
mBorderThickness = def->mBorderThickness;
|
||||
mBorderColor = def->mBorderColor;
|
||||
mBorderColorHL = def->mBorderColorHL;
|
||||
mBorderColorNA = def->mBorderColorNA;
|
||||
|
||||
mBevelColorHL = def->mBevelColorHL;
|
||||
mBevelColorLL = def->mBevelColorLL;
|
||||
|
||||
// default font
|
||||
mFontType = def->mFontType;
|
||||
mFontSize = def->mFontSize;
|
||||
mFontCharset = def->mFontCharset;
|
||||
|
||||
for(U32 i = 0; i < 10; i++)
|
||||
mFontColors[i] = def->mFontColors[i];
|
||||
|
||||
// default bitmap
|
||||
mBitmapName = def->mBitmapName;
|
||||
mTextOffset = def->mTextOffset;
|
||||
|
||||
// default sound
|
||||
mSoundButtonDown = def->mSoundButtonDown;
|
||||
mSoundButtonOver = def->mSoundButtonOver;
|
||||
|
||||
//used by GuiTextCtrl
|
||||
mModal = def->mModal;
|
||||
mAlignment = def->mAlignment;
|
||||
mAutoSizeWidth = def->mAutoSizeWidth;
|
||||
mAutoSizeHeight= def->mAutoSizeHeight;
|
||||
mReturnTab = def->mReturnTab;
|
||||
mNumbersOnly = def->mNumbersOnly;
|
||||
mCursorColor = def->mCursorColor;
|
||||
}
|
||||
}
|
||||
|
||||
GuiControlProfile::~GuiControlProfile()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GuiControlProfile::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
|
||||
addField("tab", TypeBool, Offset(mTabable, GuiControlProfile));
|
||||
addField("canKeyFocus", TypeBool, Offset(mCanKeyFocus, GuiControlProfile));
|
||||
addField("mouseOverSelected", TypeBool, Offset(mMouseOverSelected, GuiControlProfile));
|
||||
|
||||
addField("modal", TypeBool, Offset(mModal, GuiControlProfile));
|
||||
addField("opaque", TypeBool, Offset(mOpaque, GuiControlProfile));
|
||||
addField("fillColor", TypeColorI, Offset(mFillColor, GuiControlProfile));
|
||||
addField("fillColorHL", TypeColorI, Offset(mFillColorHL, GuiControlProfile));
|
||||
addField("fillColorNA", TypeColorI, Offset(mFillColorNA, GuiControlProfile));
|
||||
addField("border", TypeS32, Offset(mBorder, GuiControlProfile));
|
||||
addField("borderThickness",TypeS32, Offset(mBorderThickness, GuiControlProfile));
|
||||
addField("borderColor", TypeColorI, Offset(mBorderColor, GuiControlProfile));
|
||||
addField("borderColorHL", TypeColorI, Offset(mBorderColorHL, GuiControlProfile));
|
||||
addField("borderColorNA", TypeColorI, Offset(mBorderColorNA, GuiControlProfile));
|
||||
|
||||
addField("bevelColorHL", TypeColorI, Offset(mBevelColorHL, GuiControlProfile));
|
||||
addField("bevelColorLL", TypeColorI, Offset(mBevelColorLL, GuiControlProfile));
|
||||
|
||||
addField("fontType", TypeString, Offset(mFontType, GuiControlProfile));
|
||||
addField("fontSize", TypeS32, Offset(mFontSize, GuiControlProfile));
|
||||
addField("fontCharset", TypeEnum, Offset(mFontCharset, GuiControlProfile), 1, &gCharsetTable);
|
||||
addField("fontColors", TypeColorI, Offset(mFontColors, GuiControlProfile), 10);
|
||||
addField("fontColor", TypeColorI, Offset(mFontColors[BaseColor], GuiControlProfile));
|
||||
addField("fontColorHL", TypeColorI, Offset(mFontColors[ColorHL], GuiControlProfile));
|
||||
addField("fontColorNA", TypeColorI, Offset(mFontColors[ColorNA], GuiControlProfile));
|
||||
addField("fontColorSEL", TypeColorI, Offset(mFontColors[ColorSEL], GuiControlProfile));
|
||||
addField("fontColorLink", TypeColorI, Offset(mFontColors[ColorUser0], GuiControlProfile));
|
||||
addField("fontColorLinkHL", TypeColorI, Offset(mFontColors[ColorUser1], GuiControlProfile));
|
||||
|
||||
addField("justify", TypeEnum, Offset(mAlignment, GuiControlProfile), 1, &gAlignTable);
|
||||
addField("textOffset", TypePoint2I, Offset(mTextOffset, GuiControlProfile));
|
||||
addField("autoSizeWidth", TypeBool, Offset(mAutoSizeWidth, GuiControlProfile));
|
||||
addField("autoSizeHeight",TypeBool, Offset(mAutoSizeHeight, GuiControlProfile));
|
||||
addField("returnTab", TypeBool, Offset(mReturnTab, GuiControlProfile));
|
||||
addField("numbersOnly", TypeBool, Offset(mNumbersOnly, GuiControlProfile));
|
||||
addField("cursorColor", TypeColorI, Offset(mCursorColor, GuiControlProfile));
|
||||
|
||||
addField("bitmap", TypeFilename, Offset(mBitmapName, GuiControlProfile));
|
||||
|
||||
addField("soundButtonDown", TypeAudioProfilePtr, Offset(mSoundButtonDown, GuiControlProfile));
|
||||
addField("soundButtonOver", TypeAudioProfilePtr, Offset(mSoundButtonOver, GuiControlProfile));
|
||||
}
|
||||
|
||||
bool GuiControlProfile::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
Sim::getGuiDataGroup()->addObject(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
S32 GuiControlProfile::constructBitmapArray()
|
||||
{
|
||||
if(mBitmapArrayRects.size())
|
||||
return mBitmapArrayRects.size();
|
||||
|
||||
GBitmap *bmp = mTextureHandle.getBitmap();
|
||||
|
||||
//get the separator color
|
||||
ColorI sepColor;
|
||||
if ( !bmp || !bmp->getColor( 0, 0, sepColor ) )
|
||||
{
|
||||
Con::errorf("Failed to create bitmap array from %s for profile %s - couldn't ascertain seperator color!", mBitmapName, getName());
|
||||
AssertFatal( false, avar("Failed to create bitmap array from %s for profile %s - couldn't ascertain seperator color!", mBitmapName, getName()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//now loop through all the scroll pieces, and find the bounding rectangle for each piece in each state
|
||||
S32 curY = 0;
|
||||
|
||||
// ascertain the height of this row...
|
||||
ColorI color;
|
||||
mBitmapArrayRects.clear();
|
||||
while(curY < bmp->getHeight())
|
||||
{
|
||||
// skip any sep colors
|
||||
bmp->getColor( 0, curY, color);
|
||||
if(color == sepColor)
|
||||
{
|
||||
curY++;
|
||||
continue;
|
||||
}
|
||||
// ok, process left to right, grabbing bitmaps as we go...
|
||||
S32 curX = 0;
|
||||
while(curX < bmp->getWidth())
|
||||
{
|
||||
bmp->getColor(curX, curY, color);
|
||||
if(color == sepColor)
|
||||
{
|
||||
curX++;
|
||||
continue;
|
||||
}
|
||||
S32 startX = curX;
|
||||
while(curX < bmp->getWidth())
|
||||
{
|
||||
bmp->getColor(curX, curY, color);
|
||||
if(color == sepColor)
|
||||
break;
|
||||
curX++;
|
||||
}
|
||||
S32 stepY = curY;
|
||||
while(stepY < bmp->getHeight())
|
||||
{
|
||||
bmp->getColor(startX, stepY, color);
|
||||
if(color == sepColor)
|
||||
break;
|
||||
stepY++;
|
||||
}
|
||||
mBitmapArrayRects.push_back(RectI(startX, curY, curX - startX, stepY - curY));
|
||||
}
|
||||
// ok, now skip to the next seperation color on column 0
|
||||
while(curY < bmp->getHeight())
|
||||
{
|
||||
bmp->getColor(0, curY, color);
|
||||
if(color == sepColor)
|
||||
break;
|
||||
curY++;
|
||||
}
|
||||
}
|
||||
return mBitmapArrayRects.size();
|
||||
}
|
||||
|
||||
void GuiControlProfile::incRefCount()
|
||||
{
|
||||
if(!mRefCount++)
|
||||
{
|
||||
sFontCacheDirectory = Con::getVariable("$GUI::fontCacheDirectory");
|
||||
|
||||
//verify the font
|
||||
mFont = GFont::create(mFontType, mFontSize, sFontCacheDirectory);
|
||||
if (mFont.isNull())
|
||||
Con::errorf("Failed to load/create profile font (%s/%d)", mFontType, mFontSize);
|
||||
|
||||
//verify the bitmap
|
||||
mTextureHandle = TextureHandle(mBitmapName, BitmapKeepTexture);
|
||||
if (!(bool)mTextureHandle)
|
||||
Con::errorf("Failed to load profile bitmap (%s)",mBitmapName);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiControlProfile::decRefCount()
|
||||
{
|
||||
AssertFatal(mRefCount, "GuiControlProfile::decRefCount: zero ref count");
|
||||
if(!mRefCount)
|
||||
return;
|
||||
|
||||
if(!--mRefCount)
|
||||
{
|
||||
mFont = NULL;
|
||||
mTextureHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleType( GuiProfile, TypeGuiProfile, sizeof(GuiControlProfile*) )
|
||||
|
||||
ConsoleSetType( TypeGuiProfile )
|
||||
{
|
||||
GuiControlProfile *profile = NULL;
|
||||
if(argc == 1)
|
||||
Sim::findObject(argv[0], profile);
|
||||
|
||||
AssertWarn(profile != NULL, avar("GuiControlProfile: requested gui profile (%s) does not exist.", argv[0]));
|
||||
if(!profile)
|
||||
profile = dynamic_cast<GuiControlProfile*>(Sim::findObject("GuiDefaultProfile"));
|
||||
|
||||
AssertFatal(profile != NULL, avar("GuiControlProfile: unable to find specified profile (%s) and GuiDefaultProfile does not exist!", argv[0]));
|
||||
|
||||
GuiControlProfile **obj = (GuiControlProfile **)dptr;
|
||||
if((*obj) == profile)
|
||||
return;
|
||||
|
||||
if(*obj)
|
||||
(*obj)->decRefCount();
|
||||
|
||||
*obj = profile;
|
||||
(*obj)->incRefCount();
|
||||
}
|
||||
|
||||
ConsoleGetType( TypeGuiProfile )
|
||||
{
|
||||
static char returnBuffer[256];
|
||||
|
||||
GuiControlProfile **obj = (GuiControlProfile**)dptr;
|
||||
dSprintf(returnBuffer, sizeof(returnBuffer), "%s", *obj ? (*obj)->getName() : "");
|
||||
return returnBuffer;
|
||||
}
|
169
engine/gui/core/guiTypes.h
Executable file
169
engine/gui/core/guiTypes.h
Executable file
@ -0,0 +1,169 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUITYPES_H_
|
||||
#define _GUITYPES_H_
|
||||
|
||||
#ifndef _GFONT_H_
|
||||
#include "dgl/gFont.h"
|
||||
#endif
|
||||
#ifndef _COLOR_H_
|
||||
#include "core/color.h"
|
||||
#endif
|
||||
#ifndef _SIMBASE_H_
|
||||
#include "console/simBase.h"
|
||||
#endif
|
||||
#ifndef _GTEXMANAGER_H_
|
||||
#include "dgl/gTexManager.h"
|
||||
#endif
|
||||
#ifndef _PLATFORMAUDIO_H_
|
||||
#include "platform/platformAudio.h"
|
||||
#endif
|
||||
#ifndef _AUDIODATABLOCK_H_
|
||||
#include "audio/audioDataBlock.h"
|
||||
#endif
|
||||
|
||||
class GBitmap;
|
||||
|
||||
/// Represents a single GUI event.
|
||||
///
|
||||
/// This is passed around to all the relevant controls so they know what's going on.
|
||||
struct GuiEvent
|
||||
{
|
||||
U16 ascii; ///< ascii character code 'a', 'A', 'b', '*', etc (if device==keyboard) - possibly a uchar or something
|
||||
U8 modifier; ///< SI_LSHIFT, etc
|
||||
U8 keyCode; ///< for unprintables, 'tab', 'return', ...
|
||||
Point2I mousePoint; ///< for mouse events
|
||||
U8 mouseClickCount; ///< to determine double clicks, etc...
|
||||
};
|
||||
|
||||
class GuiCursor : public SimObject
|
||||
{
|
||||
private:
|
||||
typedef SimObject Parent;
|
||||
StringTableEntry mBitmapName;
|
||||
|
||||
Point2I mHotSpot;
|
||||
Point2F mRenderOffset;
|
||||
Point2I mExtent;
|
||||
TextureHandle mTextureHandle;
|
||||
|
||||
public:
|
||||
Point2I getHotSpot() { return mHotSpot; }
|
||||
Point2I getExtent() { return mExtent; }
|
||||
|
||||
DECLARE_CONOBJECT(GuiCursor);
|
||||
GuiCursor(void);
|
||||
~GuiCursor(void);
|
||||
static void initPersistFields();
|
||||
|
||||
bool onAdd(void);
|
||||
void onRemove();
|
||||
void render(const Point2I &pos);
|
||||
};
|
||||
|
||||
/// A GuiControlProfile is used by every GuiObject and is akin to a
|
||||
/// datablock. It is used to control information that does not change
|
||||
/// or is unlikely to change during execution of a program. It is also
|
||||
/// a level of abstraction between script and GUI control so that you can
|
||||
/// use the same control, say a button, and have it look completly different
|
||||
/// just with a different profile.
|
||||
class GuiControlProfile : public SimObject
|
||||
{
|
||||
private:
|
||||
typedef SimObject Parent;
|
||||
|
||||
public:
|
||||
S32 mRefCount; ///< Used to determine if any controls are using this profile
|
||||
bool mTabable; ///< True if this object is accessable from using the tab key
|
||||
|
||||
static StringTableEntry sFontCacheDirectory;
|
||||
bool mCanKeyFocus; ///< True if the object can be given keyboard focus (in other words, made a first responder @see GuiControl)
|
||||
bool mModal; ///< True if this is a Modeless dialog meaning it will pass input through instead of taking it all
|
||||
|
||||
bool mOpaque; ///< True if this object is not translucent
|
||||
ColorI mFillColor; ///< Fill color, this is used to fill the bounds of the control if it is opaque
|
||||
ColorI mFillColorHL; ///< This is used insetead of mFillColor if the object is highlited
|
||||
ColorI mFillColorNA; ///< This is used to instead of mFillColor if the object is not active or disabled
|
||||
|
||||
S32 mBorder; ///< For most controls, if mBorder is > 0 a border will be drawn, some controls use this to draw different types of borders however @see guiDefaultControlRender.cc
|
||||
S32 mBorderThickness; ///< Border thickness
|
||||
ColorI mBorderColor; ///< Border color, used to draw a border around the bounds if border is enabled
|
||||
ColorI mBorderColorHL; ///< Used instead of mBorderColor when the object is highlited
|
||||
ColorI mBorderColorNA; ///< Used instead of mBorderColor when the object is not active or disabled
|
||||
|
||||
ColorI mBevelColorHL; ///< Used for the high-light part of the bevel
|
||||
ColorI mBevelColorLL; ///< Used for the low-light part of the bevel
|
||||
|
||||
// font members
|
||||
StringTableEntry mFontType; ///< Font face name for the control
|
||||
S32 mFontSize; ///< Font size for the control
|
||||
enum {
|
||||
BaseColor = 0,
|
||||
ColorHL,
|
||||
ColorNA,
|
||||
ColorSEL,
|
||||
ColorUser0,
|
||||
ColorUser1,
|
||||
ColorUser2,
|
||||
ColorUser3,
|
||||
ColorUser4,
|
||||
ColorUser5,
|
||||
};
|
||||
ColorI mFontColors[10]; ///< Array of font colors used for drawText with escape characters for changing color mid-string
|
||||
ColorI& mFontColor; ///< Main font color
|
||||
ColorI& mFontColorHL; ///< Highlited font color
|
||||
ColorI& mFontColorNA; ///< Font color when object is not active/disabled
|
||||
ColorI& mFontColorSEL; ///< Font color when object/text is selected
|
||||
FontCharset mFontCharset; ///< Font character set
|
||||
|
||||
Resource<GFont> mFont; ///< Font resource
|
||||
|
||||
enum AlignmentType
|
||||
{
|
||||
LeftJustify,
|
||||
RightJustify,
|
||||
CenterJustify
|
||||
};
|
||||
|
||||
AlignmentType mAlignment; ///< Horizontal text alignment
|
||||
bool mAutoSizeWidth; ///< Auto-size the width-bounds of the control to fit it's contents
|
||||
bool mAutoSizeHeight; ///< Auto-size the height-bounds of the control to fit it's contents
|
||||
bool mReturnTab; ///< Used in GuiTextEditCtrl to specify if a tab-event should be simulated when return is pressed.
|
||||
bool mNumbersOnly; ///< For text controls, true if this should only accept numerical data
|
||||
bool mMouseOverSelected; ///< True if this object should be "selected" while the mouse is over it
|
||||
ColorI mCursorColor; ///< Color for the blinking cursor in text fields (for example)
|
||||
|
||||
Point2I mTextOffset; ///< Text offset for the control
|
||||
|
||||
// bitmap members
|
||||
StringTableEntry mBitmapName; ///< Bitmap file name for the bitmap of the control
|
||||
TextureHandle mTextureHandle; ///< Texture handle for the control
|
||||
Vector<RectI> mBitmapArrayRects; ///< Used for controls which use an array of bitmaps such as checkboxes
|
||||
|
||||
// sound members
|
||||
AudioProfile *mSoundButtonDown; ///< Sound played when the object is "down" ie a button is pushed
|
||||
AudioProfile *mSoundButtonOver; ///< Sound played when the mouse is over the object
|
||||
|
||||
public:
|
||||
DECLARE_CONOBJECT(GuiControlProfile);
|
||||
GuiControlProfile();
|
||||
~GuiControlProfile();
|
||||
static void initPersistFields();
|
||||
bool onAdd();
|
||||
|
||||
/// This method creates an array of bitmaps from one single bitmap with
|
||||
/// seperator color. The seperator color is whatever color is in pixel 0,0
|
||||
/// of the bitmap. For an example see darkWindow.png and some of the other
|
||||
/// UI textures. It returns the number of bitmaps in the array it created
|
||||
/// It also stores the sizes in the mBitmapArrayRects vector.
|
||||
S32 constructBitmapArray();
|
||||
|
||||
void incRefCount();
|
||||
void decRefCount();
|
||||
};
|
||||
DefineConsoleType( TypeGuiProfile)
|
||||
|
||||
#endif //_GUITYPES_H
|
Reference in New Issue
Block a user