t2 engine svn checkout

This commit is contained in:
loop 2024-01-07 04:36:33 +00:00
commit ff569bd2ae
988 changed files with 394180 additions and 0 deletions

2132
shell/shellFancyArray.cc Normal file

File diff suppressed because it is too large Load diff

324
shell/shellFancyArray.h Normal file
View file

@ -0,0 +1,324 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#ifndef _SHELLFANCYARRAY_H_
#define _SHELLFANCYARRAY_H_
#ifndef _GUITYPES_H_
#include "gui/guiTypes.h"
#endif
#ifndef _SHELLSCROLLCTRL_H_
#include "shell/shellScrollCtrl.h"
#endif
//------------------------------------------------------------------------------
class VirtualScrollContentCtrl : public GuiScrollContentCtrl
{
private:
typedef GuiScrollContentCtrl Parent;
public:
GuiControl* mVirtualContent;
DECLARE_CONOBJECT(VirtualScrollContentCtrl);
VirtualScrollContentCtrl();
bool onAdd();
void addObject( SimObject* obj );
void removeObject( SimObject* obj );
};
//------------------------------------------------------------------------------
class VirtualScrollCtrl : public ShellScrollCtrl
{
private:
typedef ShellScrollCtrl Parent;
public:
DECLARE_CONOBJECT(VirtualScrollCtrl);
VirtualScrollCtrl();
void setVirtualContent( GuiControl* control );
GuiControl* getVirtualContent();
bool onAdd();
void addObject( SimObject* obj );
};
//------------------------------------------------------------------------------
class ShellFancyArray : public GuiControl
{
private:
typedef GuiControl Parent;
protected:
// Bitmap defines for the header:
enum BitmapIndices
{
BmpLeft,
BmpCenter,
BmpRight,
BmpCount
};
enum BitmapStates
{
StateNormal,
StatePressed,
StateRollover,
StateCount
};
RectI mBmpBounds[BmpCount * StateCount];
StringTableEntry mHeaderBitmap;
TextureHandle mTexHeader;
StringTableEntry mSortArrowBitmap;
TextureHandle mTexSortArrow;
StringTableEntry mBarBase;
TextureHandle mTexCellSelected;
TextureHandle mTexCellRollover;
// Field stuff:
StringTableEntry mFieldBase;
TextureHandle mTexLeftTop;
TextureHandle mTexCenterTop;
TextureHandle mTexRightTop;
TextureHandle mTexLeftCenter;
TextureHandle mTexCenter;
TextureHandle mTexRightCenter;
TextureHandle mTexLeftBottom;
TextureHandle mTexCenterBottom;
TextureHandle mTexRightBottom;
// Do not change after construction:
enum ColumnFlags
{
Column_Numeric = BIT(0),
Column_Center = BIT(1),
Column_Right = BIT(2),
Column_Icon = BIT(3),
};
struct ColumnInfo
{
StringTableEntry name;
S32 width;
S32 minWidth;
S32 maxWidth;
S32 key;
BitSet32 flags;
};
bool mFixedHorizontal;
Vector<ColumnInfo> mColumnInfoList;
S32 mNumColumns;
S32 mRowHeight;
S32 mHeaderHeight;
S32 mGlowOffset;
S32 mMinColumnWidth;
Point2I mStartScrollRgn;
Resource<GFont> mFont;
Resource<GFont> mHeaderFont;
StringTableEntry mHeaderFontType;
S32 mHeaderFontSize;
GuiCursor* mDefaultCursor;
GuiCursor* mResizeCursor;
GuiCursor* mRepositionCursor;
ColorI mHeaderFontColor;
ColorI mHeaderFontColorHL;
ColorI mSeparatorColor;
bool mDrawCellSeparators;
bool mHeaderSort;
bool mAllowReposition;
bool mNoSelect;
// State variables:
S32 mNumRows;
S32 mSelectedRow;
S32 mMouseOverRow;
S32 mMouseOverColumn;
Point2I mScrollPanePos;
enum ColumnState
{
None,
Resizing,
Repositioning,
Sorting,
SecondarySorting, // For derived classes
};
ColumnState mColumnState;
S32 mActiveColumn;
Point2I mDragAnchor;
// Sorting variables:
S32 mSortColumnKey;
S32 mSecondarySortColumnKey;
S32 mSortInc;
S32 mSecondarySortInc;
// Column resizing work variables:
S32 mAbsResizeLeftMargin;
S32 mAbsResizeRightMargin;
bool mResizeFixedColumn;
S32 mResizeColumnOrigSize;
// Column reposition work variables:
S32 mRepositionColumnTo;
Point2I mRepositionCursorPos;
void determineRepositionColumn( Point2I pt );
bool getColumnScrollViewRect( RectI &rect );
bool getRowScrollViewRect( RectI &rect );
void setMouseOverRow( S32 row );
void setMouseOverColumn( S32 column, S32 xPos = 0 );
S32 findColumn( S32 key );
void drawColumn( Point2I offset, RectI clipRect, bool hasRowScrollRect, RectI rowScrollRect, S32 column );
public:
DECLARE_CONOBJECT(ShellFancyArray);
ShellFancyArray();
bool onAdd();
void onRemove();
static void initPersistFields();
static void consoleInit();
bool onWake();
void onSleep();
void setFixedHorizontal() { mFixedHorizontal = true; }
void clearColumns();
void addColumn( S32 key, const char* name, S32 defaultWidth, S32 minWidth, S32 maxWidth, const char* flags = NULL );
S32 getNumColumns() { return( mNumColumns ); }
virtual void clearList();
virtual void updateList();
bool pointInColumn( bool inHeader, Point2I pt, S32 &column, bool &inResizeRgn, bool &resizeLeft );
bool getScrollRect( RectI &rect );
void setSortColumnKey( S32 newKey );
void setSortInc( bool newSortInc ) { mSortInc = newSortInc; sort(); }
void setSecondarySortColumnKey( S32 newKey );
void setSecondarySortInc( bool newSortInc ) { mSecondarySortInc = newSortInc; sort(); }
virtual void sort();
void selectCell( S32 row, S32 column );
S32 getSelectedRow() { return( mSelectedRow ); }
void setNumRows( S32 numRows );
U32 getNumRows() { return( mNumRows ); }
S32 getGlowOffset() { return( mGlowOffset ); }
S32 getHeaderHeight() { return( mHeaderHeight ); }
S32 getRowHeight() { return( mRowHeight ); }
S32 getNoScrollWidth();
S32 getNoScrollHeight() { return( mHeaderHeight + ( mRowHeight * mStartScrollRgn.y ) ); }
S32 getColumnKey( S32 index );
S32 getColumnWidth( S32 index );
S32 getSortColumnKey() { return( mSortColumnKey ); }
bool getSortIncreasing() { return( mSortInc ); }
S32 getSecondarySortColumnKey() { return( mSecondarySortColumnKey ); }
bool getSecondarySortIncreasing() { return( mSecondarySortInc ); }
virtual void onHeaderAction( S32 column );
virtual void onSecondaryHeaderAction( S32 column );
virtual void onCellSelected( S32 row, S32 column );
void forceFillScrollRegion();
void scrollSelectedRowVisible();
void computeFixedResizingVals();
void resizeFixedColumn( const GuiEvent &event );
void resizeScrollColumn( const GuiEvent &event );
Point2I getScrollPos() { return mScrollPanePos; }
void setScrollPos( Point2I newPos ) { mScrollPanePos = newPos; }
Point2I getScrollExtent();
void onMouseDown( const GuiEvent& event );
void onMouseUp( const GuiEvent& event );
void onMouseMove( const GuiEvent& event );
void onMouseDragged( const GuiEvent& event );
void onMouseEnter( const GuiEvent &event );
void onMouseLeave( const GuiEvent &event );
void onRightMouseDown( const GuiEvent &event );
void onRightMouseUp( const GuiEvent &event );
bool onMouseWheelUp( const GuiEvent &event );
bool onMouseWheelDown( const GuiEvent &event );
bool onKeyDown( const GuiEvent& event );
void resize( const Point2I &newPos, const Point2I &newExtent );
void onRenderColumnHeader( Point2I offset, RectI clipRect, S32 column, bool mouseOver );
virtual void onRenderCell( Point2I offset, Point2I cell, bool selected, bool mouseOver );
void onRender( Point2I offset, const RectI &updateRect, GuiControl* firstResponder );
};
//------------------------------------------------------------------------------
class ShellFancyArrayScrollCtrl : public GuiControl
{
private:
typedef GuiControl Parent;
protected:
ShellFancyArray* mArray;
VirtualScrollCtrl* mScrollView;
GuiControl* mVirtualContent;
Point2I mPrevArrayPos;
Point2I mPrevArrayExtent;
Point2I mPrevContentPos;
bool mFixedHorizontal;
StringTableEntry mVSpacerBitmap;
StringTableEntry mHSpacerBitmap;
TextureHandle mTexVSpacer;
TextureHandle mTexHSpacer;
public:
DECLARE_CONOBJECT(ShellFancyArrayScrollCtrl);
ShellFancyArrayScrollCtrl();
static void initPersistFields();
bool onAdd();
void addObject( SimObject* obj );
void removeObject( SimObject* obj );
bool onWake();
void onSleep();
void setVirtualContent( GuiControl* control ) { mVirtualContent = control; }
void positionChildren();
void resize( const Point2I &newPos, const Point2I &newExtent );
void onPreRender();
void onRender( Point2I offset, const RectI &updateRect, GuiControl* firstResponder );
};
#endif // _SHELL_FANCYARRAY_H

669
shell/shellFancyTextList.cc Normal file
View file

@ -0,0 +1,669 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#include "dgl/dgl.h"
#include "Shell/shellFancyTextList.h"
#include "GUI/guiCanvas.h"
#include "console/consoleTypes.h"
//------------------------------------------------------------------------------
// Static stuff for sorting:
//------------------------------------------------------------------------------
static S32 sSortColumn;
static bool sSortInc;
//------------------------------------------------------------------------------
static const char* getColumn( U32 column, const char* text )
{
U32 ct = column;
while ( ct-- )
{
text = dStrchr( text, '\t' );
if ( !text )
return( "" );
text++;
}
return( text );
}
//------------------------------------------------------------------------------
static S32 QSORT_CALLBACK fancyListRowCompare( const void* a, const void* b )
{
ShellFancyTextList::Entry* entryA = (ShellFancyTextList::Entry*) a;
ShellFancyTextList::Entry* entryB = (ShellFancyTextList::Entry*) b;
S32 result = dStricmp( getColumn( sSortColumn, entryA->text ), getColumn( sSortColumn, entryB->text ) );
return( sSortInc ? result : -result );
}
//------------------------------------------------------------------------------
static S32 QSORT_CALLBACK fancyListRowNumCompare( const void* a, const void* b )
{
ShellFancyTextList::Entry* entryA = (ShellFancyTextList::Entry*) a;
ShellFancyTextList::Entry* entryB = (ShellFancyTextList::Entry*) b;
const char* aCol = getColumn( sSortColumn, entryA->text );
const char* bCol = getColumn( sSortColumn, entryB->text );
char* aBuf = new char[dStrlen( aCol ) + 1];
char* bBuf = new char[dStrlen( bCol ) + 1];
dStrcpy( aBuf, aCol );
dStrcpy( bBuf, bCol );
char* ptr = dStrchr( aBuf, '\t' );
if ( ptr )
*ptr = '\0';
ptr = dStrchr( bBuf, '\t' );
if ( ptr )
*ptr = '\0';
S32 result = dAtoi( aBuf ) - dAtoi( bBuf );
if ( result == 0 )
return( dStricmp( entryA->text, entryB->text ) );
delete [] aBuf;
delete [] bBuf;
return( sSortInc ? result : -result );
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(ShellFancyTextList);
//------------------------------------------------------------------------------
ShellFancyTextList::ShellFancyTextList() : ShellFancyArray()
{
mAllowReposition = false; // Repositioning columns currently not supported for this class.
mStyleList = NULL;
}
//------------------------------------------------------------------------------
ShellFancyTextList::~ShellFancyTextList()
{
for ( StyleSet* walk = mStyleList; walk; walk = walk->next )
walk->font = NULL;
mStyleList = NULL;
mResourceChunker.freeBlocks();
}
//------------------------------------------------------------------------------
static S32 cFTLGetSelectedId( SimObject* obj, S32, const char** )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLGetSelectedId is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
return( ftl->getSelectedId() );
}
//------------------------------------------------------------------------------
static void cFTLSelectRowById( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLSelectRowById is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
ftl->selectRowById( dAtoi( argv[2] ) );
}
//------------------------------------------------------------------------------
static void cFTLClearSelection( SimObject* obj, S32, const char** )
{
AssertFatal( dynamic_cast<ShellFancyArray*>( obj ), "Object passed to cFTLClearSelection is not a ShellFancyArray!" );
ShellFancyArray* array = static_cast<ShellFancyArray*>( obj );
array->selectCell( -1, -1 );
}
//------------------------------------------------------------------------------
static void cFTLClear( SimObject* obj, S32, const char** )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLClear is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
ftl->clearList();
}
//------------------------------------------------------------------------------
static void cFTLAddRow( SimObject* obj, S32 argc, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLAddRow is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
if ( argc == 4 )
ftl->addEntry( dAtoi( argv[2] ), argv[3] );
else
ftl->insertEntry( dAtoi( argv[2] ), argv[3], dAtoi( argv[4] ) );
}
//------------------------------------------------------------------------------
static void cFTLSetRowById( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLSetRowById is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
ftl->setEntry( dAtoi( argv[2] ), argv[3] );
}
//------------------------------------------------------------------------------
static S32 cFTLGetRowId( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLGetRowId is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
return( ftl->getRowId( dAtoi( argv[2] ) ) );
}
//------------------------------------------------------------------------------
static void cFTLRemoveRowById( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLRemoveRowById is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
ftl->removeEntry( dAtoi( argv[2] ) );
}
//------------------------------------------------------------------------------
static const char* cFTLGetRowTextById( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLGetRowTextById is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
return( ftl->getText( ftl->findEntryById( dAtoi( argv[2] ) ) ) );
}
//------------------------------------------------------------------------------
static void cFTLRemoveRowByIndex( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLRemoveRowByIndex is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
ftl->removeEntryByIndex( dAtoi( argv[2] ) );
}
//------------------------------------------------------------------------------
static S32 cFTLFindById( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLFindById is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
return( ftl->findEntryById( dAtoi( argv[2] ) ) );
}
//------------------------------------------------------------------------------
static const char* cFTLGetRowText( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLGetRowText is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
return( ftl->getText( dAtoi( argv[2] ) ) );
}
//------------------------------------------------------------------------------
static S32 cFTLFindText( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLFindText is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
return( ftl->findEntryByText( argv[2] ) );
}
//------------------------------------------------------------------------------
static void cFTLSort( SimObject* obj, S32 argc, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLSort is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
if ( argc > 2 )
{
S32 key = ftl->getColumnKey( dAtoi( argv[2] ) );
ftl->setSortColumnKey( key );
if ( argc > 3 )
ftl->setSortInc( dAtob( argv[3] ) );
}
ftl->sort();
}
//------------------------------------------------------------------------------
static bool cFTLAddStyle( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLAddStyle is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
ColorI fontColor, fontColorHL, fontColorSEL;
fontColor.set( 0, 0, 0, 255 );
fontColorHL.set( 0, 0, 0, 255 );
fontColorSEL.set( 0, 0, 0, 255 );
S32 r, g, b, a;
S32 args = dSscanf( argv[5], "%d %d %d %d", &r, &g, &b, &a );
fontColor.red = r;
fontColor.green = g;
fontColor.blue = b;
if ( args == 4 )
fontColor.alpha = a;
args = dSscanf( argv[6], "%d %d %d %d", &r, &g, &b, &a );
fontColorHL.red = r;
fontColorHL.green = g;
fontColorHL.blue = b;
if ( args == 4 )
fontColorHL.alpha = a;
args = dSscanf( argv[7], "%d %d %d %d", &r, &g, &b, &a );
fontColorSEL.red = r;
fontColorSEL.green = g;
fontColorSEL.blue = b;
if ( args == 4 )
fontColorSEL.alpha = a;
return( ftl->addStyleSet( dAtoi( argv[2] ), argv[3], dAtoi( argv[4] ), fontColor, fontColorHL, fontColorSEL ) );
}
//------------------------------------------------------------------------------
static void cFTLSetRowStyle( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLSetRowStyle is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
ftl->setEntryStyle( dAtoi( argv[2] ), dAtoi( argv[3] ) );
}
//------------------------------------------------------------------------------
static void cFTLSetRowStyleById( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLSetRowStyleById is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
ftl->setEntryStyle( ftl->findEntryById( dAtoi( argv[2] ) ), dAtoi( argv[3] ) );
}
//------------------------------------------------------------------------------
static S32 cFTLGetRowStyle( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLGetRowStyle is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
return( ftl->getEntryStyle( dAtoi( argv[2] ) ) );
}
//------------------------------------------------------------------------------
static S32 cFTLGetRowStyleById( SimObject* obj, S32, const char** argv )
{
AssertFatal( dynamic_cast<ShellFancyTextList*>( obj ), "Object passed to cFTLGetRowStyleById is not a ShellFancyTextList!" );
ShellFancyTextList* ftl = static_cast<ShellFancyTextList*>( obj );
return( ftl->getEntryStyle( ftl->findEntryById( dAtoi( argv[2] ) ) ) );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::consoleInit()
{
Con::addCommand( "ShellFancyTextList", "getSelectedId", cFTLGetSelectedId, "fancytextlist.getSelectedId()", 2, 2 );
Con::addCommand( "ShellFancyTextList", "setSelectedById", cFTLSelectRowById, "fancytextlist.setSelectedById( id )", 3, 3 );
Con::addCommand( "ShellFancyTextList", "clearSelection", cFTLClearSelection, "fancytextlist.clearSelection()", 2, 2);
Con::addCommand( "ShellFancyTextList", "clear", cFTLClear, "fancytextlist.clear()", 2, 2 );
Con::addCommand( "ShellFancyTextList", "addRow", cFTLAddRow, "fancytextlist.addRow( id, text{, index } )", 4, 5 );
Con::addCommand( "ShellFancyTextList", "setRowById", cFTLSetRowById, "fancytextlist.setRowById( id, text )", 4, 4 );
Con::addCommand( "ShellFancyTextList", "getRowId", cFTLGetRowId, "fancytextlist.getRowId( index )", 3, 3 );
Con::addCommand( "ShellFancyTextList", "removeRowById", cFTLRemoveRowById, "fancytextlist.removeRowById( id )", 3, 3 );
Con::addCommand( "ShellFancyTextList", "getRowTextById", cFTLGetRowTextById, "fancytextlist.getRowTextById( id )", 3, 3 );
Con::addCommand( "ShellFancyTextList", "getRowNumById", cFTLFindById, "fancytextlist.getRowNumById( id )", 3, 3 );
Con::addCommand( "ShellFancyTextList", "getRowText", cFTLGetRowText, "fancytextlist.getRowText( index )", 3, 3 );
Con::addCommand( "ShellFancyTextList", "removeRow", cFTLRemoveRowByIndex, "fancytextlist.removeRow( index )", 3, 3 );
Con::addCommand( "ShellFancyTextList", "findTextIndex", cFTLFindText, "fancytextlist.findTextIndex( text )", 3, 3 );
Con::addCommand( "ShellFancyTextList", "sort", cFTLSort, "fancytextlist.sort( { column{, increasing} } )", 2, 4 );
Con::addCommand( "ShellFancyTextList", "addStyle", cFTLAddStyle, "fancytextlist.addStyle( id, fontType, fontSize, fontColor, fontColorHL, fontColorSEL )", 8, 8 );
Con::addCommand( "ShellFancyTextList", "setRowStyle", cFTLSetRowStyle, "fancytextlist.setRowStyle( row, style )", 4, 4 );
Con::addCommand( "ShellFancyTextList", "setRowStyleById", cFTLSetRowStyleById, "fancytextlist.setRowStyleById( id, style )", 4, 4 );
Con::addCommand( "ShellFancyTextList", "getRowStyle", cFTLGetRowStyle, "fancytextlist.getRowStyle( row )", 3, 3 );
Con::addCommand( "ShellFancyTextList", "getRowStyleById", cFTLGetRowStyleById, "fancytextlist.getRowStyleById( id )", 3, 3 );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::initPersistFields()
{
Parent::initPersistFields();
}
//------------------------------------------------------------------------------
const char* ShellFancyTextList::getScriptValue()
{
return( NULL );
}
//------------------------------------------------------------------------------
U32 ShellFancyTextList::getNumEntries()
{
return( mList.size() );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::clearList()
{
while ( mList.size() )
removeEntry( mList[0].id );
mSelectedRow = -1;
mMouseOverRow = -2;
mMouseOverColumn = -1;
setNumRows( 0 );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::addEntry( U32 id, const char* text )
{
Entry newEntry;
newEntry.text = dStrdup( text );
newEntry.id = id;
newEntry.active = true;
newEntry.styleId = 0;
mList.push_back( newEntry );
setNumRows( mList.size() );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::insertEntry( U32 id, const char* text, S32 index )
{
Entry newEntry;
newEntry.text = dStrdup( text );
newEntry.id = id;
newEntry.active = true;
newEntry.styleId = 0;
mList.insert( &mList[index], newEntry );
setNumRows( mList.size() );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::removeEntry( U32 id )
{
S32 index = findEntryById( id );
removeEntryByIndex( index );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::removeEntryByIndex( S32 index )
{
if ( index < 0 || index >= mList.size() )
return;
dFree( mList[index].text );
mList.erase( index );
setNumRows( mList.size() );
selectCell( -1, -1 );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::setEntry( U32 id, const char* text )
{
S32 index = findEntryById( id );
if ( index == -1 )
addEntry( id, text );
else
{
dFree( mList[index].text );
mList[index].text = dStrdup( text );
}
setUpdate();
}
//------------------------------------------------------------------------------
void ShellFancyTextList::setEntryActive( U32 id, bool active )
{
S32 index = findEntryById( id );
if ( index == -1 )
return;
if ( mList[index].active != active )
{
mList[index].active = active;
setUpdate();
}
}
//------------------------------------------------------------------------------
S32 ShellFancyTextList::findEntryById( U32 id )
{
for ( U32 i = 0; i < mList.size(); i++ )
if ( mList[i].id == id )
return i;
return -1;
}
//------------------------------------------------------------------------------
S32 ShellFancyTextList::findEntryByText( const char* text )
{
for ( U32 i = 0; i < mList.size(); i++ )
if ( dStrcmp( mList[i].text, text ) == 0 )
return i;
return -1;
}
//------------------------------------------------------------------------------
bool ShellFancyTextList::isEntryActive( U32 id )
{
S32 index = findEntryById( id );
if ( index == -1 )
return( false );
return( mList[index].active );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::selectRowById( U32 id )
{
selectCell( findEntryById( id ), 0 );
}
//------------------------------------------------------------------------------
U32 ShellFancyTextList::getSelectedId()
{
if ( mSelectedRow == -1 || mSelectedRow >= mList.size() )
return( InvalidId );
return( mList[mSelectedRow].id );
}
//------------------------------------------------------------------------------
U32 ShellFancyTextList::getRowId( S32 index )
{
if ( index == -1 || index >= mList.size() )
return( InvalidId );
return( mList[index].id );
}
//------------------------------------------------------------------------------
const char* ShellFancyTextList::getText( S32 index )
{
if ( index == -1 || index >= mList.size() )
return( "" );
return( mList[index].text );
}
//------------------------------------------------------------------------------
bool ShellFancyTextList::addStyleSet( U32 id, const char* fontType, U32 fontSize, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL )
{
// Make sure the id isn't taken already:
if ( id == 0 )
{
Con::warnf( ConsoleLogEntry::General, "ShellFancyTextList::addStyleSet - style id 0 is reserved for the default!" );
return( false );
}
if ( getStyleSet( id ) != NULL )
{
Con::warnf( ConsoleLogEntry::General, "ShellFancyTextList::addStyleSet - style id %d used already!", id );
return( false );
}
// Add the new style set:
StyleSet* newStyle;
newStyle = constructInPlace( (StyleSet*) mResourceChunker.alloc( sizeof( StyleSet ) ) );
newStyle->fontType = StringTable->insert( fontType );
newStyle->fontSize = fontSize;
if ( mAwake )
newStyle->font = GFont::create( newStyle->fontType, newStyle->fontSize );
newStyle->id = id;
newStyle->fontColor = fontColor;
newStyle->fontColorHL = fontColorHL;
newStyle->fontColorSEL = fontColorSEL;
newStyle->next = mStyleList;
mStyleList = newStyle;
return( true );
}
//------------------------------------------------------------------------------
const ShellFancyTextList::StyleSet* ShellFancyTextList::getStyleSet( U32 id )
{
if ( id )
{
for ( StyleSet* walk = mStyleList; walk; walk = walk->next )
{
if ( walk->id == id )
return( walk );
}
}
return( NULL );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::setEntryStyle( S32 index, U32 styleId )
{
if ( index < 0 || index >= mList.size() )
return;
if ( mList[index].styleId != styleId )
{
mList[index].styleId = styleId;
setUpdate();
}
}
//------------------------------------------------------------------------------
U32 ShellFancyTextList::getEntryStyle( S32 index )
{
if ( index < 0 || index >= mList.size() )
return( 0 );
return( mList[index].styleId );
}
//------------------------------------------------------------------------------
void ShellFancyTextList::onCellSelected( S32 row, S32 /*column*/ )
{
Con::executef( this, 3, "onSelect", Con::getIntArg( mList[row].id ), mList[row].text );
if ( mConsoleCommand[0] )
Con::evaluate( mConsoleCommand, false );
}
//------------------------------------------------------------------------------
bool ShellFancyTextList::onWake()
{
if ( !Parent::onWake() )
return false;
// Set the row height based on the font:
if ( mFont )
mRowHeight = mFont->getHeight() + 3;
// Get all of the style fonts:
for ( StyleSet* walk = mStyleList; walk; walk = walk->next )
walk->font = GFont::create( walk->fontType, walk->fontSize );
return true;
}
//------------------------------------------------------------------------------
void ShellFancyTextList::onSleep()
{
Parent::onSleep();
// Release all of the style fonts:
for ( StyleSet* walk = mStyleList; walk; walk = walk->next )
walk->font = NULL;
}
//------------------------------------------------------------------------------
void ShellFancyTextList::updateList()
{
if ( mNumRows != mList.size() )
setNumRows( mList.size() );
setUpdate();
}
//------------------------------------------------------------------------------
void ShellFancyTextList::sort()
{
if ( mSortColumnKey == -1 )
return;
mNumRows = mList.size();
sSortColumn = findColumn( mSortColumnKey );
sSortInc = mSortInc;
U32 selId = getSelectedId();
if ( mNumRows > 1 )
{
if ( mColumnInfoList[sSortColumn].flags.test( Column_Numeric ) )
dQsort( (void*) &(mList[0]), mNumRows, sizeof(Entry), fancyListRowNumCompare );
else
dQsort( (void*) &(mList[0]), mNumRows, sizeof(Entry), fancyListRowCompare );
}
selectRowById( selId );
setUpdate();
}
//------------------------------------------------------------------------------
void ShellFancyTextList::onRenderCell( Point2I offset, Point2I cell, bool selected, bool mouseOver )
{
ColumnInfo* ci = &mColumnInfoList[cell.x];
Entry* entry = &mList[cell.y];
// Let the parent take care of the basics:
Parent::onRenderCell( offset, cell, selected, mouseOver );
// Draw the text ( if there is any ):
const char* text = getColumn( cell.x, entry->text );
if ( text[0] )
{
const char* temp = dStrchr( text, '\t' );
U32 textLen = temp ? ( temp - text ) : dStrlen( text );
char* drawText = new char[textLen + 4];
dStrncpy( drawText, text, textLen );
drawText[textLen] = '\0';
if ( ci->flags.test( Column_Icon ) )
{
char buf[64];
dSprintf( buf, sizeof( buf ), "gui/%s.png", drawText );
TextureHandle tex = TextureHandle( buf, BitmapTexture );
if ( tex )
{
Point2I drawPt = offset;
if ( ci->width > tex.getWidth() )
drawPt.x += ( ci->width - tex.getWidth() ) / 2;
if ( mRowHeight > tex.getHeight() )
drawPt.y += ( mRowHeight - tex.getHeight() ) / 2;
dglDrawBitmap( tex, drawPt );
tex = NULL;
}
}
else
{
Resource<GFont> drawFont = NULL;
ColorI drawColor;
const StyleSet* style = getStyleSet( entry->styleId );
if ( bool( style ) )
{
drawFont = style->font;
drawColor = entry->active ? ( selected ? style->fontColorSEL : ( mouseOver ? style->fontColorHL : style->fontColor ) ) : mProfile->mFontColorNA;
}
else
{
// Fall back to the default:
drawFont = mFont;
drawColor = entry->active ? ( selected ? mProfile->mFontColorSEL : ( mouseOver ? mProfile->mFontColorHL : mProfile->mFontColor ) ) : mProfile->mFontColorNA;
}
S32 textWidth = drawFont->getStrWidth( drawText );
Point2I textStart;
if ( ci->flags.test( Column_Center ) )
textStart.x = offset.x + getMax( 4, ( ci->width - textWidth ) / 2 );
else if ( ci->flags.test( Column_Right ) )
textStart.x = offset.x + getMax( 4, ci->width - textWidth );
else
textStart.x = offset.x + 4;
textStart.y = offset.y + ( ( mRowHeight - ( drawFont->getHeight() - 2 ) ) / 2 );
dglSetBitmapModulation( drawColor );
dglDrawText( drawFont, textStart, drawText, mProfile->mFontColors );
delete [] drawText;
}
}
}

108
shell/shellFancyTextList.h Normal file
View file

@ -0,0 +1,108 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#ifndef _SHELLFANCYTEXTLIST_H_
#define _SHELLFANCYTEXTLIST_H_
#ifndef _SHELLFANCYARRAY_H_
#include "Shell/shellFancyArray.h"
#endif
class ShellFancyTextList : public ShellFancyArray
{
private:
typedef ShellFancyArray Parent;
protected:
enum
{
InvalidId = 0xFFFFFFFF
};
// Emulate a text list ( to some extent ):
public:
struct Entry
{
char* text;
U32 id;
bool active;
U32 styleId;
};
struct StyleSet
{
U32 id;
StringTableEntry fontType;
U32 fontSize;
Resource<GFont> font;
ColorI fontColor;
ColorI fontColorHL;
ColorI fontColorSEL;
StyleSet* next;
StyleSet()
{
id = 0;
fontSize = 0;
font = NULL;
fontColor.set( 0, 0, 0, 255 );
fontColorHL.set( 0, 0, 0, 255 );
fontColorSEL.set( 0, 0, 0, 255 );
next = NULL;
};
};
protected:
Vector<Entry> mList;
DataChunker mResourceChunker;
StyleSet* mStyleList;
const StyleSet* getStyleSet( U32 id );
public:
DECLARE_CONOBJECT(ShellFancyTextList);
ShellFancyTextList();
~ShellFancyTextList();
static void consoleInit();
static void initPersistFields();
const char* getScriptValue();
U32 getNumEntries();
void clearList();
void addEntry( U32 id, const char* text );
void insertEntry( U32 id, const char* text, S32 index );
void removeEntry( U32 id );
void removeEntryByIndex( S32 id );
void setEntry( U32 id, const char* text );
void setEntryActive( U32 id, bool active );
S32 findEntryById( U32 id );
S32 findEntryByText( const char* text );
bool isEntryActive( U32 id );
void selectRowById( U32 id );
U32 getSelectedId();
U32 getRowId( S32 index );
const char* getText( S32 index );
bool addStyleSet( U32 id, const char* fontName, U32 fontSize, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL );
void setEntryStyle( S32 index, U32 styleId );
U32 getEntryStyle( S32 index );
void onCellSelected( S32 row, S32 column );
bool onWake();
void onSleep();
void updateList();
void sort();
void onRenderCell( Point2I offset, Point2I cell, bool selected, bool mouseOver );
};
#endif // _SHELL_FANCYTEXTLIST_H

512
shell/shellScrollCtrl.cc Normal file
View file

@ -0,0 +1,512 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#include "GUI/guiCanvas.h"
#include "console/consoleTypes.h"
#include "Shell/shellScrollCtrl.h"
#include "dgl/dgl.h"
IMPLEMENT_CONOBJECT(ShellScrollCtrl);
//------------------------------------------------------------------------------
ShellScrollCtrl::ShellScrollCtrl() : GuiScrollCtrl()
{
mGlowOffset = 4;
mBorderThickness = mGlowOffset;
dMemset( mBarBounds, 0, sizeof( mBarBounds ) );
mTexVBar = NULL;
mTexHBar = NULL;
mTexVButtons = NULL;
mTexVThumb = NULL;
mTexHButtons = NULL;
mTexHThumb = NULL;
mTexCorner = NULL;
mFieldBase = StringTable->insert( "gui/shll_field" );
mTexLeftTop = NULL;
mTexCenterTop = NULL;
mTexRightTop = NULL;
mTexLeftCenter = NULL;
mTexCenter = NULL;
mTexRightCenter = NULL;
mTexLeftBottom = NULL;
mTexCenterBottom = NULL;
mTexRightBottom = NULL;
mMouseOverRegion = None;
}
//------------------------------------------------------------------------------
void ShellScrollCtrl::initPersistFields()
{
Parent::initPersistFields();
addField( "fieldBase", TypeString, Offset( mFieldBase, ShellScrollCtrl ) );
}
//------------------------------------------------------------------------------
bool ShellScrollCtrl::onWake()
{
// Set the default profile on start-up:
if ( !mProfile )
{
SimObject *obj = Sim::findObject("NewScrollCtrlProfile");
if ( obj )
mProfile = dynamic_cast<GuiControlProfile*>( obj );
}
// NOTE: Not using Parent here on purpose.
if ( !GuiControl::onWake() )
return false;
AssertFatal( size(), "ShellScrollCtrl created without content!" );
mBitmapBounds = new RectI[BtnCount * BtnStateCount];
AssertFatal( mBitmapBounds, "Failed to allocate memory for bitmap array!" );
char buf[256];
if ( mProfile->mBitmapBase[0] )
{
bool result;
dSprintf( buf, sizeof( buf ), "%s_vertfield.png", mProfile->mBitmapBase );
mTexVBar = TextureHandle( buf, BitmapKeepTexture );
if ( mTexVBar )
{
result = createBitmapArray( mTexVBar.getBitmap(), mBarBounds, BarStateCount, 3 );
AssertFatal( result, "Failed to create vertical bar bitmap array for ShellScrollCtrl!" );
}
dSprintf( buf, sizeof( buf ), "%s_horzfield.png", mProfile->mBitmapBase );
mTexHBar = TextureHandle( buf, BitmapKeepTexture );
if ( mTexHBar )
{
result = createBitmapArray( mTexHBar.getBitmap(), &mBarBounds[BarHLeft * BarStateCount], BarStateCount, 3 );
AssertFatal( result, "Failed to create horizontal bar bitmap array for ShellScrollCtrl!" );
}
dSprintf( buf, sizeof( buf ), "%s_vertbuttons.png", mProfile->mBitmapBase );
mTexVButtons = TextureHandle( buf, BitmapKeepTexture );
if ( mTexVButtons )
{
result = createBitmapArray( mTexVButtons.getBitmap(), mBitmapBounds, BtnStateCount, 2 );
AssertFatal( result, "Failed to create vertical button bitmap array for ShellScrollCtrl!" );
}
dSprintf( buf, sizeof( buf ), "%s_vertbar.png", mProfile->mBitmapBase );
mTexVThumb = TextureHandle( buf, BitmapKeepTexture );
if ( mTexVThumb )
{
result = createBitmapArray( mTexVThumb.getBitmap(), &mBitmapBounds[VThumbTop * BtnStateCount], BtnStateCount, 3 );
AssertFatal( result, "Failed to create vertical thumb bitmap array for ShellScrollCtrl!" );
}
dSprintf( buf, sizeof( buf ), "%s_horzbuttons.png", mProfile->mBitmapBase );
mTexHButtons = TextureHandle( buf, BitmapKeepTexture );
if ( mTexHButtons )
{
result = createBitmapArray( mTexHButtons.getBitmap(), &mBitmapBounds[LeftBtn * BtnStateCount], BtnStateCount, 2 );
AssertFatal( result, "Failed to create horizontal button bitmap array for ShellScrollCtrl!" );
}
dSprintf( buf, sizeof( buf ), "%s_horzbar.png", mProfile->mBitmapBase );
mTexHThumb = TextureHandle( buf, BitmapKeepTexture );
if ( mTexHThumb )
{
result = createBitmapArray( mTexHThumb.getBitmap(), &mBitmapBounds[HThumbLeft * BtnStateCount], BtnStateCount, 3 );
AssertFatal( result, "Failed to create horizontal thumb bitmap array for ShellScrollCtrl!" );
}
dSprintf( buf, sizeof( buf ), "%s_scale.png", mProfile->mBitmapBase );
mTexCorner = TextureHandle( buf, BitmapKeepTexture );
if ( mTexCorner )
{
result = createBitmapArray( mTexCorner.getBitmap(), &mBitmapBounds[Corner * BtnStateCount], BtnStateCount, 1 );
AssertFatal( result, "Failed to create corner bitmap array for ShellScrollCtrl!" );
}
}
if ( mFieldBase[0] )
{
dSprintf( buf, sizeof( buf ), "%s_TL.png", mFieldBase );
mTexLeftTop = TextureHandle( buf, BitmapTexture );
dSprintf( buf, sizeof( buf ), "%s_TM.png", mFieldBase );
mTexCenterTop = TextureHandle( buf, BitmapTexture );
dSprintf( buf, sizeof( buf ), "%s_TR.png", mFieldBase );
mTexRightTop = TextureHandle( buf, BitmapTexture );
dSprintf( buf, sizeof( buf ), "%s_ML.png", mFieldBase );
mTexLeftCenter = TextureHandle( buf, BitmapTexture );
dSprintf( buf, sizeof( buf ), "%s_MM.png", mFieldBase );
mTexCenter = TextureHandle( buf, BitmapTexture );
dSprintf( buf, sizeof( buf ), "%s_MR.png", mFieldBase );
mTexRightCenter = TextureHandle( buf, BitmapTexture );
dSprintf( buf, sizeof( buf ), "%s_BL.png", mFieldBase );
mTexLeftBottom = TextureHandle( buf, BitmapTexture );
dSprintf( buf, sizeof( buf ), "%s_BM.png", mFieldBase );
mTexCenterBottom = TextureHandle( buf, BitmapTexture );
dSprintf( buf, sizeof( buf ), "%s_BR.png", mFieldBase );
mTexRightBottom = TextureHandle( buf, BitmapTexture );
}
//init
if ( mTexVBar && mTexVButtons && mTexVThumb )
{
mBaseThumbSize = mBitmapBounds[VThumbTop * BtnStateCount].extent.y +
mBitmapBounds[VThumbBottom * BtnStateCount].extent.y - ( 2 * mGlowOffset );
mScrollBarThickness = mBarBounds[BarVCenter * BarStateCount].extent.x;
mScrollBarArrowBtnLength = mBitmapBounds[UpBtn * BtnStateCount].extent.y - ( 2 * mGlowOffset );
}
// Ensure minimum extents:
U32 temp;
bool needResize = false;
if ( mTexLeftTop && mTexRightTop )
{
temp = mTexLeftTop.getWidth() + mTexRightTop.getWidth() + ( 2 * mBorderThickness );
if ( mMinExtent.x < temp )
{
mMinExtent.x = temp;
needResize = true;
}
}
if ( mTexLeftTop && mTexLeftBottom )
{
temp = mTexLeftTop.getHeight() + mTexLeftBottom.getHeight() + ( 2 * mBorderThickness );
if ( mMinExtent.y < temp )
{
mMinExtent.y = temp;
needResize = true;
}
}
if ( needResize )
resize( mBounds.point, mBounds.extent );
computeSizes();
return true;
}
//------------------------------------------------------------------------------
void ShellScrollCtrl::onSleep()
{
Parent::onSleep();
mTexVBar = NULL;
mTexHBar = NULL;
mTexVButtons = NULL;
mTexVThumb = NULL;
mTexHButtons = NULL;
mTexHThumb = NULL;
mTexCorner = NULL;
mTexLeftTop = NULL;
mTexCenterTop = NULL;
mTexRightTop = NULL;
mTexLeftCenter = NULL;
mTexCenter = NULL;
mTexRightCenter = NULL;
mTexLeftBottom = NULL;
mTexCenterBottom = NULL;
mTexRightBottom = NULL;
mMouseOverRegion = None;
}
//------------------------------------------------------------------------------
void ShellScrollCtrl::onMouseUp( const GuiEvent &event )
{
Parent::onMouseUp( event );
onMouseMove( event );
}
//------------------------------------------------------------------------------
void ShellScrollCtrl::onMouseMove( const GuiEvent &event )
{
Region oldRegion = mMouseOverRegion;
Point2I curMousePos = globalToLocalCoord( event.mousePoint );
mMouseOverRegion = findHitRegion( curMousePos );
// Play button over sound:
if ( mActive && mMouseOverRegion != oldRegion && mProfile->mSoundButtonOver
&& ( mMouseOverRegion == UpArrow || mMouseOverRegion == DownArrow || mMouseOverRegion == LeftArrow || mMouseOverRegion == RightArrow ) )
{
F32 pan = (F32(event.mousePoint.x)/ F32(Canvas->mBounds.extent.x)*2.0f-1.0f)*0.8f;
AUDIOHANDLE handle = alxCreateSource(mProfile->mSoundButtonOver);
alxSourcef(handle, AL_PAN, pan);
alxPlay(handle);
}
setUpdate();
}
//------------------------------------------------------------------------------
void ShellScrollCtrl::onMouseEnter( const GuiEvent &event )
{
onMouseMove( event );
}
//------------------------------------------------------------------------------
void ShellScrollCtrl::onMouseLeave( const GuiEvent &/*event*/ )
{
mMouseOverRegion = None;
setUpdate();
}
//------------------------------------------------------------------------------
void ShellScrollCtrl::drawBorder( const Point2I &offset, bool /*isFirstResponder*/ )
{
RectI r( offset, mBounds.extent );
r.point += Point2I( mBorderThickness, mBorderThickness );
r.extent -= Point2I( ( 2 * mBorderThickness ), ( 2 * mBorderThickness ) );
// Draw border:
if ( mProfile->mBorder )
{
dglDrawRect( r, mProfile->mBorderColor );
r.point += Point2I( 1, 1 );
r.extent -= Point2I( 2, 2 );
}
// Temporary hacky focus effect:
//if ( isFirstResponder )
//{
// dglDrawRect( r, ColorI( 255, 255, 0 ) );
// r.point += Point2I( 1, 1 );
// r.extent -= Point2I( 2, 2 );
//}
// Draw field background:
if ( mHasVScrollBar )
r.extent.x -= mScrollBarThickness;
if ( mHasHScrollBar )
r.extent.y -= ( mScrollBarThickness + 1 );
if ( mTexLeftTop && mTexCenterTop && mTexRightTop && mTexLeftCenter && mTexCenter && mTexRightCenter
&& mTexLeftBottom && mTexCenterBottom && mTexRightBottom )
{
dglClearBitmapModulation();
RectI drawRect = r;
U32 stretchWidth = r.extent.x - mTexLeftTop.getWidth() - mTexRightTop.getWidth();
U32 topEdgeHeight = mTexLeftTop.getHeight();
if ( topEdgeHeight > ( r.extent.y - mTexLeftBottom.getHeight() ) )
topEdgeHeight = r.extent.y - mTexLeftBottom.getHeight();
// Draw upper left corner:
drawRect.extent.x = mTexLeftTop.getWidth();
drawRect.extent.y = topEdgeHeight;
dglDrawBitmapStretch( mTexLeftTop, drawRect );
// Draw upper center edge:
drawRect.point.x += drawRect.extent.x;
drawRect.extent.x = stretchWidth;
if ( drawRect.extent.x > 0 )
dglDrawBitmapStretch( mTexCenterTop, drawRect );
// Draw upper right corner:
drawRect.point.x += drawRect.extent.x;
drawRect.extent.x = mTexRightTop.getWidth();
dglDrawBitmapStretch( mTexRightTop, drawRect );
drawRect.point.x = r.point.x;
drawRect.point.y += drawRect.extent.y;
drawRect.extent.y = r.extent.y - drawRect.extent.y - mTexLeftBottom.getHeight();
if ( drawRect.extent.y > 0 )
{
// Draw center left edge:
drawRect.extent.x = mTexLeftCenter.getWidth();
dglDrawBitmapStretch( mTexLeftCenter, drawRect );
// Draw center:
drawRect.point.x += drawRect.extent.x;
drawRect.extent.x = stretchWidth;
if ( drawRect.extent.x > 0 )
dglDrawBitmapStretch( mTexCenter, drawRect );
// Draw center right edge:
drawRect.point.x += drawRect.extent.x;
drawRect.extent.x = mTexRightCenter.getWidth();
dglDrawBitmapStretch( mTexRightCenter, drawRect );
}
// Draw bottom left corner:
drawRect.point.x = r.point.x;
drawRect.point.y += drawRect.extent.y;
dglDrawBitmap( mTexLeftBottom, drawRect.point );
// Draw bottom center edge:
drawRect.point.x += mTexLeftBottom.getWidth();
drawRect.extent.x = stretchWidth;
drawRect.extent.y = mTexCenterBottom.getHeight();
if ( drawRect.extent.x > 0 )
dglDrawBitmapStretch( mTexCenterBottom, drawRect );
// Draw bottom right corner:
drawRect.point.x += drawRect.extent.x;
dglDrawBitmap( mTexRightBottom, drawRect.point );
}
}
//------------------------------------------------------------------------------
void ShellScrollCtrl::drawVScrollBar( const Point2I &offset )
{
if ( !mTexVBar || !mTexVButtons || !mTexVThumb )
return;
RectI drawRect;
drawRect.point = offset + mUpArrowRect.point - Point2I( mGlowOffset, mGlowOffset );
dglClearBitmapModulation();
// Draw the up arrow button:
U32 state = mVBarEnabled ? ( mMouseOverRegion == UpArrow ? ( stateDepressed ? StatePressed : StateRollover ) : StateNormal ) : StateDisabled;
U32 bitmap = UpBtn * BtnStateCount + state;
dglDrawBitmapSR( mTexVButtons, drawRect.point, mBitmapBounds[bitmap] );
// Draw the scroll bar:
state = mVBarEnabled ? BarNormal : BarDisabled;
// Draw top edge:
drawRect.point += Point2I( mGlowOffset, mGlowOffset );
drawRect.point.y += mScrollBarArrowBtnLength;
bitmap = BarVTop * BarStateCount + state;
dglDrawBitmapSR( mTexVBar, drawRect.point, mBarBounds[bitmap] );
// Draw the center section:
drawRect.point.y += mBarBounds[bitmap].extent.y;
drawRect.extent.x = mScrollBarThickness;
drawRect.extent.y = mDownArrowRect.point.y - mScrollBarArrowBtnLength - mBarBounds[bitmap].extent.y - mBarBounds[BarStateCount * BarVBottom].extent.y;
if ( drawRect.extent.y > 0 )
{
bitmap = BarVCenter * BarStateCount + state;
dglDrawBitmapStretchSR( mTexVBar, drawRect, mBarBounds[bitmap] );
}
// Draw the bottom edge:
drawRect.point.y += drawRect.extent.y;
bitmap = BarVBottom * BarStateCount + state;
dglDrawBitmapSR( mTexVBar, drawRect.point, mBarBounds[bitmap] );
// Draw the thumb (if enabled):
if ( mVBarEnabled )
{
drawRect.point.y = offset.y + mVThumbPos;
drawRect.point -= Point2I( mGlowOffset, mGlowOffset );
state = ( mMouseOverRegion == VertThumb ) ? ( stateDepressed ? StatePressed : StateRollover ) : StateNormal;
// Draw top cap:
bitmap = VThumbTop * BtnStateCount + state;
dglDrawBitmapSR( mTexVThumb, drawRect.point, mBitmapBounds[bitmap] );
// Draw center section:
drawRect.point.y += mBitmapBounds[bitmap].extent.y;
drawRect.extent.y = mVThumbSize - mBitmapBounds[bitmap].extent.y - mBitmapBounds[VThumbBottom * BtnStateCount].extent.y + ( 2 * mGlowOffset );
if ( drawRect.extent.y > 0 )
{
bitmap = VThumb * BtnStateCount + state;
drawRect.extent.x = mBitmapBounds[bitmap].extent.x;
dglDrawBitmapStretchSR( mTexVThumb, drawRect, mBitmapBounds[bitmap] );
}
// Draw the bottom cap:
drawRect.point.y += drawRect.extent.y;
bitmap = VThumbBottom * BtnStateCount + state;
dglDrawBitmapSR( mTexVThumb, drawRect.point, mBitmapBounds[bitmap] );
}
// Draw the down button:
drawRect.point = offset + mDownArrowRect.point - Point2I( mGlowOffset, mGlowOffset );
state = mVBarEnabled ? ( mMouseOverRegion == DownArrow ? ( stateDepressed ? StatePressed : StateRollover ) : StateNormal ) : StateDisabled;
bitmap = DownBtn * BtnStateCount + state;
dglDrawBitmapSR( mTexVButtons, drawRect.point, mBitmapBounds[bitmap] );
}
//------------------------------------------------------------------------------
void ShellScrollCtrl::drawHScrollBar( const Point2I &offset )
{
if ( !mTexHBar || !mTexHButtons || !mTexHThumb )
return;
RectI drawRect;
drawRect.point = offset + mLeftArrowRect.point - Point2I( mGlowOffset, mGlowOffset );
dglClearBitmapModulation();
// Draw the left arrow button:
U32 state = mHBarEnabled ? ( mMouseOverRegion == LeftArrow ? ( stateDepressed ? StatePressed : StateRollover ) : StateNormal ) : StateDisabled;
U32 bitmap = LeftBtn * BtnStateCount + state;
dglDrawBitmapSR( mTexHButtons, drawRect.point, mBitmapBounds[bitmap] );
// Draw the scroll bar:
state = mHBarEnabled ? BarNormal : BarDisabled;
// Draw left edge:
drawRect.point += Point2I( mScrollBarArrowBtnLength + mGlowOffset, mGlowOffset );
bitmap = BarHLeft * BarStateCount + state;
dglDrawBitmapSR( mTexHBar, drawRect.point, mBarBounds[bitmap] );
// Draw the center section:
drawRect.point.x += mBarBounds[bitmap].extent.x;
drawRect.extent.x = mRightArrowRect.point.x - mScrollBarArrowBtnLength - mBarBounds[bitmap].extent.x - mBarBounds[BarHRight * BarStateCount].extent.x;
if ( drawRect.extent.x > 0 )
{
drawRect.extent.y = mScrollBarThickness;
bitmap = BarHCenter * BarStateCount + state;
dglDrawBitmapStretchSR( mTexHBar, drawRect, mBarBounds[bitmap] );
}
// Draw the right edge:
drawRect.point.x += drawRect.extent.x;
bitmap = BarHRight * BarStateCount + state;
dglDrawBitmapSR( mTexHBar, drawRect.point, mBarBounds[bitmap] );
// Draw the thumb (if enabled):
if ( mHBarEnabled )
{
drawRect.point.x = offset.x + mHThumbPos;
drawRect.point -= Point2I( mGlowOffset, mGlowOffset );
state = ( mMouseOverRegion == HorizThumb ) ? ( stateDepressed ? StatePressed : StateRollover ) : StateNormal;
// Draw left cap:
bitmap = HThumbLeft * BtnStateCount + state;
dglDrawBitmapSR( mTexHThumb, drawRect.point, mBitmapBounds[bitmap] );
// Draw center section:
drawRect.point.x += mBitmapBounds[bitmap].extent.x;
drawRect.extent.x = mHThumbSize - mBitmapBounds[bitmap].extent.x - mBitmapBounds[HThumbRight * BtnStateCount].extent.x + ( 2 * mGlowOffset );
if ( drawRect.extent.x > 0 )
{
bitmap = HThumb * BtnStateCount + state;
drawRect.extent.y = mBitmapBounds[bitmap].extent.y;
dglDrawBitmapStretchSR( mTexHThumb, drawRect, mBitmapBounds[bitmap] );
}
// Draw the right cap:
drawRect.point.x += drawRect.extent.x;
bitmap = HThumbRight * BtnStateCount + state;
dglDrawBitmapSR( mTexHThumb, drawRect.point, mBitmapBounds[bitmap] );
}
// Draw the right button:
drawRect.point = offset + mRightArrowRect.point - Point2I( mGlowOffset, mGlowOffset );
state = mHBarEnabled ? ( mMouseOverRegion == RightArrow ? ( stateDepressed ? StatePressed : StateRollover ) : StateNormal ) : StateDisabled;
bitmap = RightBtn * BtnStateCount + state;
dglDrawBitmapSR( mTexHButtons, drawRect.point, mBitmapBounds[bitmap] );
}
//------------------------------------------------------------------------------
void ShellScrollCtrl::drawScrollCorner( const Point2I &offset )
{
if ( mTexCorner )
{
Point2I drawPos = offset + mRightArrowRect.point - Point2I( mGlowOffset, mGlowOffset );
drawPos.x += mRightArrowRect.extent.x;
dglClearBitmapModulation();
dglDrawBitmapSR( mTexCorner, drawPos, mBitmapBounds[Corner * BtnStateCount + StateDisabled] );
}
}

119
shell/shellScrollCtrl.h Normal file
View file

@ -0,0 +1,119 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#ifndef _SHELLSCROLLCTRL_H_
#define _SHELLSCROLLCTRL_H_
#ifndef _GUISCROLLCTRL_H_
#include "GUI/guiScrollCtrl.h"
#endif
class ShellScrollCtrl : public GuiScrollCtrl
{
private:
typedef GuiScrollCtrl Parent;
protected:
enum BarIndices
{
BarVTop = 0,
BarVCenter,
BarVBottom,
BarHLeft,
BarHCenter,
BarHRight,
BarCount
};
enum BarStates
{
BarNormal = 0,
BarDisabled,
BarStateCount
};
RectI mBarBounds[BarCount * BarStateCount];
TextureHandle mTexVBar;
TextureHandle mTexHBar;
enum BtnIndices
{
UpBtn = 0,
DownBtn,
VThumbTop,
VThumb,
VThumbBottom,
LeftBtn,
RightBtn,
HThumbLeft,
HThumb,
HThumbRight,
Corner,
BtnCount
};
enum BtnStates
{
StateNormal = 0,
StatePressed,
StateRollover,
StateDisabled,
BtnStateCount
};
TextureHandle mTexVButtons;
TextureHandle mTexVThumb;
TextureHandle mTexHButtons;
TextureHandle mTexHThumb;
TextureHandle mTexCorner;
public:
StringTableEntry mFieldBase;
protected:
TextureHandle mTexLeftTop;
TextureHandle mTexCenterTop;
TextureHandle mTexRightTop;
TextureHandle mTexLeftCenter;
TextureHandle mTexCenter;
TextureHandle mTexRightCenter;
TextureHandle mTexLeftBottom;
TextureHandle mTexCenterBottom;
TextureHandle mTexRightBottom;
Region mMouseOverRegion;
U32 mGlowOffset;
//bool calcChildExtents( Point2I* pos, Point2I* ext );
public:
DECLARE_CONOBJECT(ShellScrollCtrl);
ShellScrollCtrl();
static void initPersistFields();
bool onWake();
void onSleep();
U32 getGlowOffset() { return( mGlowOffset); }
void onMouseUp( const GuiEvent &event );
void onMouseMove( const GuiEvent &event );
void onMouseEnter( const GuiEvent &event );
void onMouseLeave( const GuiEvent &event );
void drawBorder( const Point2I &offset, bool isFirstResponder );
void drawVScrollBar( const Point2I &offset );
void drawHScrollBar( const Point2I &offset );
void drawScrollCorner( const Point2I &offset );
};
#endif // _SHELL_SCROLLCTRL_H

124
shell/shellTextEditCtrl.cc Normal file
View file

@ -0,0 +1,124 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#include "shell/shellTextEditCtrl.h"
#include "console/consoleTypes.h"
#include "dgl/dgl.h"
IMPLEMENT_CONOBJECT(ShellTextEditCtrl);
//------------------------------------------------------------------------------
ShellTextEditCtrl::ShellTextEditCtrl() : GuiTextEditCtrl()
{
dMemset( mBitmapBounds, 0, sizeof( mBitmapBounds ) );
mTexField = NULL;
mGlowOffset.set( 9, 9 );
}
//------------------------------------------------------------------------------
void ShellTextEditCtrl::initPersistFields()
{
Parent::initPersistFields();
addField( "glowOffset", TypePoint2I, Offset( mGlowOffset, ShellTextEditCtrl ) );
}
//------------------------------------------------------------------------------
bool ShellTextEditCtrl::onWake()
{
// Set the default profile on start-up:
if ( !mProfile )
{
SimObject *obj = Sim::findObject("NewTextEditProfile");
if ( obj )
mProfile = dynamic_cast<GuiControlProfile*>( obj );
}
if ( !Parent::onWake() )
return false;
mTexField = mProfile->mTextureHandle;
if ( mTexField )
{
bool result = createBitmapArray( mTexField.getBitmap(), mBitmapBounds, StateCount, BmpCount );
AssertFatal( result, "ShellTextEditCtrl failed to create bitmap array!" );
// Set minimum extents:
mMinExtent.x = mBitmapBounds[StateCount * BmpLeft].extent.x + mBitmapBounds[StateCount * BmpRight].extent.x;
mMinExtent.y = mBitmapBounds[StateCount * BmpLeft].extent.y;
resize( mBounds.point, mBounds.extent );
}
return true;
}
//------------------------------------------------------------------------------
void ShellTextEditCtrl::onSleep()
{
Parent::onSleep();
mTexField = NULL;
}
//------------------------------------------------------------------------------
void ShellTextEditCtrl::onRender( Point2I offset, const RectI &updateRect, GuiControl* firstResponder )
{
// Draw the bitmap background:
RectI drawRect( offset, mBounds.extent );
if ( mTexField )
{
// Differentiate between normal and active:
U32 state;
if ( mActive )
{
state = ( firstResponder == this ) ? StateActive : StateNormal;
dglClearBitmapModulation();
}
else
{
state = StateNormal;
dglSetBitmapModulation( ColorI( 128, 128, 128 ) );
}
// Draw the left edge:
U32 bitmap = StateCount * BmpLeft + state;
dglDrawBitmapSR( mTexField, drawRect.point, mBitmapBounds[bitmap] );
// Draw the center section:
bitmap = StateCount * BmpCenter + state;
drawRect.point.x += mBitmapBounds[bitmap].extent.x;
drawRect.extent.x = mBounds.extent.x - mBitmapBounds[StateCount * BmpLeft].extent.x - mBitmapBounds[StateCount * BmpRight].extent.x;
drawRect.extent.y = mBitmapBounds[bitmap].extent.y;
if ( drawRect.extent.x > 0 )
dglDrawBitmapStretchSR( mTexField, drawRect, mBitmapBounds[bitmap] );
// Draw the right edge:
bitmap = StateCount * BmpRight + state;
drawRect.point.x += drawRect.extent.x;
dglDrawBitmapSR( mTexField, drawRect.point, mBitmapBounds[bitmap] );
}
// Draw the text:
drawRect.point.y = offset.y + mGlowOffset.y;
drawRect.extent.y -= ( 2 * mGlowOffset.y );
drawRect.point.x = offset.x + mBitmapBounds[BmpLeft].extent.x;
RectI clipRect( drawRect.point, drawRect.extent );
if ( clipRect.intersect( updateRect ) )
{
dglSetClipRect( clipRect );
DrawText( drawRect, ( firstResponder == this ) );
}
// Draw border (if any):
if ( mProfile->mBorder )
dglDrawRect( RectI( offset, mBounds.extent ), mProfile->mBorderColor );
}

54
shell/shellTextEditCtrl.h Normal file
View file

@ -0,0 +1,54 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#ifndef _SHELLTEXTEDITCTRL_H_
#define _SHELLTEXTEDITCTRL_H_
#ifndef _GUITEXTEDITCTRL_H_
#include "GUI/guiTextEditCtrl.h"
#endif
class ShellTextEditCtrl : public GuiTextEditCtrl
{
private:
typedef GuiTextEditCtrl Parent;
protected:
enum BitmapIndices
{
BmpLeft,
BmpCenter,
BmpRight,
BmpCount
};
enum BitmapStates
{
StateNormal,
StateActive,
StateCount
};
RectI mBitmapBounds[BmpCount * StateCount];
TextureHandle mTexField;
Point2I mGlowOffset;
public:
DECLARE_CONOBJECT(ShellTextEditCtrl);
ShellTextEditCtrl();
static void initPersistFields();
bool onWake();
void onSleep();
void onRender( Point2I offset, const RectI &updateRect, GuiControl *firstResponder );
};
#endif // _SHELL_TEXTEDITCTRL_H