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

434
engine/gui/core/guiArrayCtrl.cc Executable file
View File

@ -0,0 +1,434 @@
//-----------------------------------------------------------------------------
// 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])
{
char buf[16];
dSprintf(buf, sizeof(buf), "%d", getId());
Con::setVariable("$ThisControl", buf);
Con::evaluate(mConsoleCommand, false);
}
}
// Called when a cell is highlighted
void GuiArrayCtrl::onCellHighlighted(Point2I cell)
{
// Do nothing
}
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 );
onCellHighlighted(mMouseOverCell);
}
}
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);
onCellHighlighted(mMouseOverCell);
}
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);
}
onCellHighlighted(mMouseOverCell);
}
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);
}
}

79
engine/gui/core/guiArrayCtrl.h Executable file
View File

@ -0,0 +1,79 @@
//-----------------------------------------------------------------------------
// 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);
virtual void onCellHighlighted(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

1383
engine/gui/core/guiCanvas.cc Executable file

File diff suppressed because it is too large Load Diff

339
engine/gui/core/guiCanvas.h Executable file
View File

@ -0,0 +1,339 @@
//-----------------------------------------------------------------------------
// 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
#ifndef _PLATFORMINPUT_H_
#include "platform/platformInput.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();
/// Resizes the content control to match the canvas size.
void maintainSizing();
/// 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);
/// 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 bool tabNext(void);
/// Moves the first responder to the previous tabable control
virtual bool 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

1668
engine/gui/core/guiControl.cc Executable file

File diff suppressed because it is too large Load Diff

614
engine/gui/core/guiControl.h Executable file
View File

@ -0,0 +1,614 @@
//-----------------------------------------------------------------------------
// 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;
StringTableEntry mClassName;
StringTableEntry mSuperClassName;
public:
/// @name Control State
/// @{
GuiControlProfile *mProfile;
GuiControlProfile *mTooltipProfile;
S32 mTipHoverTime;
bool mVisible;
bool mActive;
bool mAwake;
bool mSetFirstResponder;
bool mCanSave;
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);
/// Overrides Parent Serialization to allow specific controls to not be saved (Dynamic Controls, etc)
void write(Stream &stream, U32 tabStop, U32 flags);
/// Returns boolean specifying if a control can be serialized
bool getCanSave();
/// Set serialization flag
void setCanSave(bool bCanSave);
/// Returns boolean as to whether any parent of this control has the 'no serialization' flag set.
bool getCanSaveParent();
/// @}
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 RectI& getBounds() { return mBounds; } ///< Returns the bounds 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 bounds of this control
/// @param newBounds New bounds of this control
virtual void setBounds( const RectI &newBounds );
/// 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, const char* tipText = NULL );
/// 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
virtual 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);
/// @}
/// @name Editor Mouse Events
///
/// These functions are called when the input event which is
/// in the name of the function occurs. Conversly from normal
/// mouse events, these have a boolean return value that, if
/// they return true, the editor will NOT act on them or be able
/// to respond to this particular event.
///
/// This is particularly useful for when writing controls so that
/// they may become aware of the editor and allow customization
/// of their data or appearance as if they were actually in use.
/// For example, the GuiTabBookCtrl catches on mouse down to select
/// a tab and NOT let the editor do any instant group manipulation.
///
/// @{
/// 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 bool onMouseDownEditor(const GuiEvent &event, Point2I offset) { return false; };
/// Called when a mouseUp 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 bool onMouseUpEditor(const GuiEvent &event, Point2I offset) { return false; };
/// 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 bool onRightMouseDownEditor(const GuiEvent &event, Point2I offset) { return false; };
/// Called when a mouseDragged 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 bool onMouseDraggedEditor(const GuiEvent &event, Point2I offset) { return false; };
/// @}
/// @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
virtual 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 a key is held down, resulting in repeated keystrokes.
/// @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

View File

@ -0,0 +1,517 @@
//-----------------------------------------------------------------------------
// 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;
// DAW:
case -1:
// Draw a simple sizable border with corners
// Taken from the 'Skinnable GUI Controls in TGE' resource by Justin DuJardin
if(profile->mBitmapArrayRects.size() >= 8)
{
dglClearBitmapModulation();
RectI destRect;
RectI stretchRect;
RectI* mBitmapBounds = profile->mBitmapArrayRects.address();
// DAW: Indices into the bitmap array
enum
{
BorderTopLeft = 0,
BorderTop,
BorderTopRight,
BorderLeft,
//Fill,
BorderRight,
BorderBottomLeft,
BorderBottom,
BorderBottomRight,
NumBitmaps
};
// Draw all corners first.
//top left border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x,bounds.point.y),mBitmapBounds[BorderTopLeft]);
//top right border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x + bounds.extent.x - mBitmapBounds[BorderTopRight].extent.x,bounds.point.y),mBitmapBounds[BorderTopRight]);
//bottom left border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x,bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottomLeft].extent.y),mBitmapBounds[BorderBottomLeft]);
//bottom right border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(
bounds.point.x + bounds.extent.x - mBitmapBounds[BorderBottomRight].extent.x,
bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottomRight].extent.y),
mBitmapBounds[BorderBottomRight]);
// End drawing corners
// Begin drawing sides and top stretched borders
//start with top line stretch
destRect.point.x = bounds.point.x + mBitmapBounds[BorderTopRight].extent.x;
destRect.extent.x = bounds.extent.x - mBitmapBounds[BorderTopRight].extent.x - mBitmapBounds[BorderTopLeft].extent.x;
destRect.extent.y = mBitmapBounds[BorderTop].extent.y;
destRect.point.y = bounds.point.y;
//stretch it
stretchRect = mBitmapBounds[BorderTop];
stretchRect.inset(1,0);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//bottom line stretch
destRect.point.x = bounds.point.x + mBitmapBounds[BorderBottomRight].extent.x;
destRect.extent.x = bounds.extent.x - mBitmapBounds[BorderBottomRight].extent.x - mBitmapBounds[BorderBottomLeft].extent.x;
destRect.extent.y = mBitmapBounds[BorderBottom].extent.y;
destRect.point.y = bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottom].extent.y;
//stretch it
stretchRect = mBitmapBounds[BorderBottom];
stretchRect.inset(1,0);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//left line stretch
destRect.point.x = bounds.point.x;
destRect.extent.x = mBitmapBounds[BorderLeft].extent.x;
destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTopLeft].extent.y - mBitmapBounds[BorderBottomLeft].extent.y;
destRect.point.y = bounds.point.y + mBitmapBounds[BorderTopLeft].extent.y;
//stretch it
stretchRect = mBitmapBounds[BorderLeft];
stretchRect.inset(0,1);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//left line stretch
destRect.point.x = bounds.point.x + bounds.extent.x - mBitmapBounds[BorderRight].extent.x;
destRect.extent.x = mBitmapBounds[BorderRight].extent.x;
destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTopRight].extent.y - mBitmapBounds[BorderBottomRight].extent.y;
destRect.point.y = bounds.point.y + mBitmapBounds[BorderTopRight].extent.y;
//stretch it
stretchRect = mBitmapBounds[BorderRight];
stretchRect.inset(0,1);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
// End drawing sides and top stretched borders
break;
}
case -2:
// Draw a simple sizable border with corners that is filled in
renderSizableBitmapBordersFilled(bounds, 1, profile);
break;
case -3:
// Draw a simple fixed height border with center fill horizontally.
renderFixedBitmapBordersFilled( bounds, 1, profile );
break;
}
}
void renderFilledBorder( RectI &bounds, GuiControlProfile *profile )
{
renderFilledBorder( bounds, profile->mBorderColor, 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 );
}
// DAW: Render out the sizable bitmap borders based on a multiplier into the bitmap array
// Based on the 'Skinnable GUI Controls in TGE' resource by Justin DuJardin
void renderSizableBitmapBordersFilled(RectI &bounds, S32 baseMultiplier, GuiControlProfile *profile)
{
// DAW: Indices into the bitmap array
S32 NumBitmaps = 9;
S32 BorderTopLeft = NumBitmaps * baseMultiplier - NumBitmaps;
S32 BorderTop = 1 + BorderTopLeft;
S32 BorderTopRight = 2 + BorderTopLeft;
S32 BorderLeft = 3 + BorderTopLeft;
S32 Fill = 4 + BorderTopLeft;
S32 BorderRight = 5 + BorderTopLeft;
S32 BorderBottomLeft = 6 + BorderTopLeft;
S32 BorderBottom = 7 + BorderTopLeft;
S32 BorderBottomRight = 8 + BorderTopLeft;
dglClearBitmapModulation();
if(profile->mBitmapArrayRects.size() >= (NumBitmaps * baseMultiplier))
{
RectI destRect;
RectI stretchRect;
RectI* mBitmapBounds = profile->mBitmapArrayRects.address();
// Draw all corners first.
//top left border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x,bounds.point.y),mBitmapBounds[BorderTopLeft]);
//top right border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x + bounds.extent.x - mBitmapBounds[BorderTopRight].extent.x,bounds.point.y),mBitmapBounds[BorderTopRight]);
//bottom left border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x,bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottomLeft].extent.y),mBitmapBounds[BorderBottomLeft]);
//bottom right border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(
bounds.point.x + bounds.extent.x - mBitmapBounds[BorderBottomRight].extent.x,
bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottomRight].extent.y),
mBitmapBounds[BorderBottomRight]);
// End drawing corners
// Begin drawing sides and top stretched borders
//start with top line stretch
destRect.point.x = bounds.point.x + mBitmapBounds[BorderTopRight].extent.x;
destRect.extent.x = bounds.extent.x - mBitmapBounds[BorderTopRight].extent.x - mBitmapBounds[BorderTopLeft].extent.x;
destRect.extent.y = mBitmapBounds[BorderTop].extent.y;
destRect.point.y = bounds.point.y;
//stretch it
stretchRect = mBitmapBounds[BorderTop];
stretchRect.inset(1,0);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//bottom line stretch
destRect.point.x = bounds.point.x + mBitmapBounds[BorderBottomRight].extent.x;
destRect.extent.x = bounds.extent.x - mBitmapBounds[BorderBottomRight].extent.x - mBitmapBounds[BorderBottomLeft].extent.x;
destRect.extent.y = mBitmapBounds[BorderBottom].extent.y;
destRect.point.y = bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottom].extent.y;
//stretch it
stretchRect = mBitmapBounds[BorderBottom];
stretchRect.inset(1,0);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//left line stretch
destRect.point.x = bounds.point.x;
destRect.extent.x = mBitmapBounds[BorderLeft].extent.x;
destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTopLeft].extent.y - mBitmapBounds[BorderBottomLeft].extent.y;
destRect.point.y = bounds.point.y + mBitmapBounds[BorderTopLeft].extent.y;
//stretch it
stretchRect = mBitmapBounds[BorderLeft];
stretchRect.inset(0,1);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//left line stretch
destRect.point.x = bounds.point.x + bounds.extent.x - mBitmapBounds[BorderRight].extent.x;
destRect.extent.x = mBitmapBounds[BorderRight].extent.x;
destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTopRight].extent.y - mBitmapBounds[BorderBottomRight].extent.y;
destRect.point.y = bounds.point.y + mBitmapBounds[BorderTopRight].extent.y;
//stretch it
stretchRect = mBitmapBounds[BorderRight];
stretchRect.inset(0,1);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//fill stretch
destRect.point.x = bounds.point.x + mBitmapBounds[BorderLeft].extent.x;
destRect.extent.x = (bounds.extent.x) - mBitmapBounds[BorderLeft].extent.x - mBitmapBounds[BorderRight].extent.x;
destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTop].extent.y - mBitmapBounds[BorderBottom].extent.y;
destRect.point.y = bounds.point.y + mBitmapBounds[BorderTop].extent.y;
//stretch it
stretchRect = mBitmapBounds[Fill];
stretchRect.inset(1,1);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
// End drawing sides and top stretched borders
}
}
// DAW: Render out the sizable bitmap borders based on a multiplier into the bitmap array
// Based on the 'Skinnable GUI Controls in TGE' resource by Justin DuJardin
void renderSizableBitmapBordersFilledIndex(RectI &bounds, S32 startIndex, GuiControlProfile *profile)
{
// DAW: Indices into the bitmap array
S32 NumBitmaps = 9;
S32 BorderTopLeft = startIndex;
S32 BorderTop = 1 + BorderTopLeft;
S32 BorderTopRight = 2 + BorderTopLeft;
S32 BorderLeft = 3 + BorderTopLeft;
S32 Fill = 4 + BorderTopLeft;
S32 BorderRight = 5 + BorderTopLeft;
S32 BorderBottomLeft = 6 + BorderTopLeft;
S32 BorderBottom = 7 + BorderTopLeft;
S32 BorderBottomRight = 8 + BorderTopLeft;
dglClearBitmapModulation();
if(profile->mBitmapArrayRects.size() >= (startIndex + NumBitmaps))
{
RectI destRect;
RectI stretchRect;
RectI* mBitmapBounds = profile->mBitmapArrayRects.address();
// Draw all corners first.
//top left border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x,bounds.point.y),mBitmapBounds[BorderTopLeft]);
//top right border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x + bounds.extent.x - mBitmapBounds[BorderTopRight].extent.x,bounds.point.y),mBitmapBounds[BorderTopRight]);
//bottom left border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x,bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottomLeft].extent.y),mBitmapBounds[BorderBottomLeft]);
//bottom right border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(
bounds.point.x + bounds.extent.x - mBitmapBounds[BorderBottomRight].extent.x,
bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottomRight].extent.y),
mBitmapBounds[BorderBottomRight]);
// End drawing corners
// Begin drawing sides and top stretched borders
//start with top line stretch
destRect.point.x = bounds.point.x + mBitmapBounds[BorderTopLeft].extent.x;
destRect.extent.x = bounds.extent.x - mBitmapBounds[BorderTopRight].extent.x - mBitmapBounds[BorderTopLeft].extent.x;
destRect.extent.y = mBitmapBounds[BorderTop].extent.y;
destRect.point.y = bounds.point.y;
//stretch it
stretchRect = mBitmapBounds[BorderTop];
stretchRect.inset(1,0);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//bottom line stretch
destRect.point.x = bounds.point.x + mBitmapBounds[BorderBottomLeft].extent.x;
destRect.extent.x = bounds.extent.x - mBitmapBounds[BorderBottomRight].extent.x - mBitmapBounds[BorderBottomLeft].extent.x;
destRect.extent.y = mBitmapBounds[BorderBottom].extent.y;
destRect.point.y = bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottom].extent.y;
//stretch it
stretchRect = mBitmapBounds[BorderBottom];
stretchRect.inset(1,0);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//left line stretch
destRect.point.x = bounds.point.x;
destRect.extent.x = mBitmapBounds[BorderLeft].extent.x;
destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTopLeft].extent.y - mBitmapBounds[BorderBottomLeft].extent.y;
destRect.point.y = bounds.point.y + mBitmapBounds[BorderTopLeft].extent.y;
//stretch it
stretchRect = mBitmapBounds[BorderLeft];
stretchRect.inset(0,1);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//left line stretch
destRect.point.x = bounds.point.x + bounds.extent.x - mBitmapBounds[BorderRight].extent.x;
destRect.extent.x = mBitmapBounds[BorderRight].extent.x;
destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTopRight].extent.y - mBitmapBounds[BorderBottomRight].extent.y;
destRect.point.y = bounds.point.y + mBitmapBounds[BorderTopRight].extent.y;
//stretch it
stretchRect = mBitmapBounds[BorderRight];
stretchRect.inset(0,1);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
//fill stretch
destRect.point.x = bounds.point.x + mBitmapBounds[BorderLeft].extent.x;
destRect.extent.x = (bounds.extent.x) - mBitmapBounds[BorderLeft].extent.x - mBitmapBounds[BorderRight].extent.x;
destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTop].extent.y - mBitmapBounds[BorderBottom].extent.y;
destRect.point.y = bounds.point.y + mBitmapBounds[BorderTop].extent.y;
//stretch it
stretchRect = mBitmapBounds[Fill];
stretchRect.inset(1,1);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
// End drawing sides and top stretched borders
}
}
// DAW: Render out the fixed bitmap borders based on a multiplier into the bitmap array
// It renders left and right caps, with a sizable fill area in the middle to reach
// the x extent. It does not stretch in the y direction.
void renderFixedBitmapBordersFilled(RectI &bounds, S32 baseMultiplier, GuiControlProfile *profile)
{
// DAW: Indices into the bitmap array
S32 NumBitmaps = 3;
S32 BorderLeft = NumBitmaps * baseMultiplier - NumBitmaps;
S32 Fill = 1 + BorderLeft;
S32 BorderRight = 2 + BorderLeft;
dglClearBitmapModulation();
if(profile->mBitmapArrayRects.size() >= (NumBitmaps * baseMultiplier))
{
RectI destRect;
RectI stretchRect;
RectI* mBitmapBounds = profile->mBitmapArrayRects.address();
// Draw all corners first.
//left border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x,bounds.point.y),mBitmapBounds[BorderLeft]);
//right border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x + bounds.extent.x - mBitmapBounds[BorderRight].extent.x,bounds.point.y),mBitmapBounds[BorderRight]);
// End drawing corners
// Begin drawing fill
//fill stretch
destRect.point.x = bounds.point.x + mBitmapBounds[BorderLeft].extent.x;
destRect.extent.x = (bounds.extent.x) - mBitmapBounds[BorderLeft].extent.x - mBitmapBounds[BorderRight].extent.x;
destRect.extent.y = mBitmapBounds[Fill].extent.y;
destRect.point.y = bounds.point.y;
//stretch it
stretchRect = mBitmapBounds[Fill];
stretchRect.inset(1,0);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
// End drawing fill
}
}
// DAW: Render out the fixed bitmap borders based on a multiplier into the bitmap array
// It renders left and right caps, with a sizable fill area in the middle to reach
// the x extent. It does not stretch in the y direction.
void renderFixedBitmapBordersFilledIndex(RectI &bounds, S32 startIndex, GuiControlProfile *profile)
{
// DAW: Indices into the bitmap array
S32 NumBitmaps = 3;
S32 BorderLeft = startIndex;
S32 Fill = 1 + startIndex;
S32 BorderRight = 2 + startIndex;
dglClearBitmapModulation();
if(profile->mBitmapArrayRects.size() >= (startIndex + NumBitmaps))
{
RectI destRect;
RectI stretchRect;
RectI* mBitmapBounds = profile->mBitmapArrayRects.address();
// Draw all corners first.
//left border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x,bounds.point.y),mBitmapBounds[BorderLeft]);
//right border
dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x + bounds.extent.x - mBitmapBounds[BorderRight].extent.x,bounds.point.y),mBitmapBounds[BorderRight]);
// End drawing corners
// Begin drawing fill
//fill stretch
destRect.point.x = bounds.point.x + mBitmapBounds[BorderLeft].extent.x;
destRect.extent.x = (bounds.extent.x) - mBitmapBounds[BorderLeft].extent.x - mBitmapBounds[BorderRight].extent.x;
destRect.extent.y = mBitmapBounds[Fill].extent.y;
destRect.point.y = bounds.point.y;
//stretch it
stretchRect = mBitmapBounds[Fill];
stretchRect.inset(1,0);
//draw it
dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
// End drawing fill
}
}

View File

@ -0,0 +1,23 @@
//-----------------------------------------------------------------------------
// 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 );
void renderSizableBitmapBordersFilled(RectI &bounds, S32 baseMultiplier, GuiControlProfile *profile); // DAW: Added
void renderSizableBitmapBordersFilledIndex(RectI &bounds, S32 startIndex, GuiControlProfile *profile);
void renderFixedBitmapBordersFilled(RectI &bounds, S32 baseMultiplier, GuiControlProfile *profile); // DAW: Added
void renderFixedBitmapBordersFilled(RectI &bounds, S32 startIndex, GuiControlProfile *profile);
#endif

163
engine/gui/core/guiTSControl.cc Executable file
View File

@ -0,0 +1,163 @@
//-----------------------------------------------------------------------------
// 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;
mLastCameraQuery.cameraMatrix.identity();
}
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
View 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

383
engine/gui/core/guiTypes.cc Executable file
View File

@ -0,0 +1,383 @@
//-----------------------------------------------------------------------------
// 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/gFont.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;
mProfileForChildren = NULL;
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;
mProfileForChildren = def->mProfileForChildren;
}
}
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));
addField("profileForChildren", TypeSimObjectPtr, Offset(mProfileForChildren, 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();
// Make sure the texture exists.
if( !bmp )
return 0;
//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 separation 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);
// If we've got a special border, make sure it's usable.
if( mBorder == -1 || mBorder == -2 )
constructBitmapArray();
}
}
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() ? (*obj)->getName() : (*obj)->getIdString() : "");
return returnBuffer;
}

170
engine/gui/core/guiTypes.h Executable file
View File

@ -0,0 +1,170 @@
//-----------------------------------------------------------------------------
// 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
GuiControlProfile* mProfileForChildren; ///< Profile used with children controls (such as the scroll bar on a popup menu) when defined.
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