A simple MMORPG for Torque 1.4
by CodingChris · in Torque Game Engine · 06/16/2006 (8:15 am) · 22 replies
I've read Dreamer's "Advanced MMORPG" In milestone 3 when I click Start Mission or Join Server Torque freezed. Dreamer said "It's a Torque 1.4 bug" He says there is a version for Torque 1.4 on mydreamrpg.com, but I cannot find this tutorial. This there another one, maybe not from Dreamer?
About the author
#3
A few Teams work/will try to build a free Kit for Torque, but actually is unfortunately no one avaliable. :(
06/20/2006 (10:58 pm)
Free? He sell his kit for 100$ as i know ^^A few Teams work/will try to build a free Kit for Torque, but actually is unfortunately no one avaliable. :(
#4
06/21/2006 (9:58 am)
Is there a fix for this bug? Dreamer said it is. There must be a fix for this or why haven't you this problem?
#5
Since this is a private forum I will share with you my guiTextEditCtrl.cc file which contains the relevant fixes as well as a few others.
06/21/2006 (10:14 am)
The problem with the password field is a known bug in TGE 1.4Since this is a private forum I will share with you my guiTextEditCtrl.cc file which contains the relevant fixes as well as a few others.
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "console/consoleTypes.h"
#include "console/console.h"
#include "dgl/dgl.h"
#include "gui/core/guiCanvas.h"
#include "gui/controls/guiMLTextCtrl.h"
#include "gui/controls/guiTextEditCtrl.h"
#include "gui/core/guiDefaultControlRender.h"
#include "core/frameAllocator.h"
IMPLEMENT_CONOBJECT(GuiTextEditCtrl);
U32 GuiTextEditCtrl::smNumAwake = 0;
GuiTextEditCtrl::GuiTextEditCtrl()
{
mInsertOn = true;
mBlockStart = 0;
mBlockEnd = 0;
mCursorPos = 0;
mCursorOn = false;
mNumFramesElapsed = 0;
mDragHit = false;
mTabComplete = false;
mScrollDir = 0;
mUndoBlockStart = 0;
mUndoBlockEnd = 0;
mUndoCursorPos = 0;
mPasswordText = false;
mSinkAllKeyEvents = false;
mActive = true;
mTextOffsetReset = true;
mHistoryDirty = false;
mHistorySize = 0;
mHistoryLast = -1;
mHistoryIndex = 0;
mHistoryBuf = NULL;
mValidateCommand = StringTable->insert("");
mEscapeCommand = StringTable->insert( "" );
mPasswordMask = StringTable->insert( "*" );
mDeniedSound = dynamic_cast<AudioProfile*>( Sim::findObject( "InputDeniedSound" ) );
mEditCursor = NULL;
}
GuiTextEditCtrl::~GuiTextEditCtrl()
{
//delete the history buffer if it exists
if (mHistoryBuf)
{
for (S32 i = 0; i < mHistorySize; i++)
delete [] mHistoryBuf[i];
delete [] mHistoryBuf;
}
}
void GuiTextEditCtrl::initPersistFields()
{
Parent::initPersistFields();
addField("validate", TypeString, Offset(mValidateCommand, GuiTextEditCtrl));
addField("escapeCommand", TypeString, Offset(mEscapeCommand, GuiTextEditCtrl));
addField("historySize", TypeS32, Offset(mHistorySize, GuiTextEditCtrl));
addField("password", TypeBool, Offset(mPasswordText, GuiTextEditCtrl));
addField("tabComplete", TypeBool, Offset(mTabComplete, GuiTextEditCtrl));
addField("deniedSound", TypeAudioProfilePtr, Offset(mDeniedSound, GuiTextEditCtrl));
addField("sinkAllKeyEvents", TypeBool, Offset(mSinkAllKeyEvents, GuiTextEditCtrl));
addField("password", TypeBool, Offset(mPasswordText, GuiTextEditCtrl));
addField("passwordMask", TypeString, Offset(mPasswordMask, GuiTextEditCtrl));
}Continued in next post
#6
06/21/2006 (10:16 am)
bool GuiTextEditCtrl::onAdd()
{
if ( ! Parent::onAdd() )
return false;
//create the history buffer
if ( mHistorySize > 0 )
{
mHistoryBuf = new UTF8*[mHistorySize];
for ( S32 i = 0; i < mHistorySize; i++ )
{
mHistoryBuf[i] = new UTF8[GuiTextCtrl::MAX_STRING_LENGTH + 1];
mHistoryBuf[i][0] = '[[4fc501f607efb]]';
}
}
setText(mText);
return true;
}
void GuiTextEditCtrl::onStaticModified(const char* slotName)
{
if(!dStricmp(slotName, "text"))
setText(mText);
}
bool GuiTextEditCtrl::onWake()
{
if (! Parent::onWake())
return false;
// If this is the first awake text edit control, enable keyboard translation
if (smNumAwake == 0)
Platform::enableKeyboardTranslation();
++smNumAwake;
return true;
}
void GuiTextEditCtrl::onSleep()
{
Parent::onSleep();
// If this is the last awake text edit control, disable keyboard translation
--smNumAwake;
if (smNumAwake == 0)
Platform::disableKeyboardTranslation();
}
void GuiTextEditCtrl::execConsoleCallback()
{
// Execute the console command!
if ( mConsoleCommand[0] )
{
char buf[16];
dSprintf( buf, sizeof( buf ), "%d", getId() );
Con::setVariable( "$ThisControl", buf );
Con::evaluate( mConsoleCommand, false );
}
// Update the console variable:
UTF8 buffer[1024];
mTextBuffer.get(buffer, 1024);
if ( mConsoleVariable[0] )
Con::setVariable( mConsoleVariable, (char*)buffer );
}
void GuiTextEditCtrl::updateHistory( StringBuffer *inTxt, bool moveIndex )
{
FrameTemp<UTF8> textString(inTxt->length()*3 + 1);
inTxt->get(textString, inTxt->length()*3 + 1);
UTF8 *txt = textString;
if(!txt)
return;
if(!mHistorySize)
return;
// see if it's already in
if(mHistoryLast == -1 || dStrcmp((const UTF8*)txt, (const UTF8*)mHistoryBuf[mHistoryLast]))
{
if(mHistoryLast == mHistorySize-1) // we're at the history limit... shuffle the pointers around:
{
UTF8 *first = mHistoryBuf[0];
for(U32 i = 0; i < mHistorySize - 1; i++)
mHistoryBuf[i] = mHistoryBuf[i+1];
mHistoryBuf[mHistorySize-1] = first;
if(mHistoryIndex > 0)
mHistoryIndex--;
}
else
mHistoryLast++;
inTxt->get(mHistoryBuf[mHistoryLast], GuiTextCtrl::MAX_STRING_LENGTH);
mHistoryBuf[mHistoryLast][GuiTextCtrl::MAX_STRING_LENGTH] = '[[4fc501f607efb]]';
}
if(moveIndex)
mHistoryIndex = mHistoryLast + 1;
}
void GuiTextEditCtrl::getText( char *dest )
{
if ( dest )
mTextBuffer.get((UTF8*)dest, GuiTextCtrl::MAX_STRING_LENGTH+1);
}
void GuiTextEditCtrl::setText( const char *txt )
{
if(txt && txt[0] != 0){
Parent::setText( txt );
mTextBuffer.set( txt );
}
else
mTextBuffer.set( "" );
mCursorPos = mTextBuffer.length();
}
void GuiTextEditCtrl::reallySetCursorPos( const S32 newPos )
{
S32 charCount = mTextBuffer.length();
S32 realPos = newPos > charCount ? charCount : newPos < 0 ? 0 : newPos;
if ( realPos != mCursorPos )
{
mCursorPos = realPos;
setUpdate();
}
}
S32 GuiTextEditCtrl::setCursorPos( const Point2I &offset )
{
Point2I ctrlOffset = localToGlobalCoord( Point2I( 0, 0 ) );
S32 charCount = mTextBuffer.length();
S32 charLength = 0;
S32 curX;
curX = offset.x - ctrlOffset.x;
setUpdate();
//if the cursor is too far to the left
if ( curX < 0 )
return -1;
//if the cursor is too far to the right
if ( curX >= ctrlOffset.x + mBounds.extent.x )
return -2;
curX = offset.x - mTextOffset.x;
S32 count=0;
if(mTextBuffer.length())
{
for(count=0; count<mTextBuffer.length(); count++)
{
//bank060104 "*" password textselect mod
// Apply password masking char size
if(mPasswordText)
charLength += mFont->getCharXIncrement( mPasswordMask[0] );
else
// Or else just count the actual size.
charLength += mFont->getCharXIncrement( mTextBuffer.getChar(count) );
if ( charLength > curX )
break;
}
}
return count;
}
void GuiTextEditCtrl::onMouseDown( const GuiEvent &event )
{
mDragHit = false;
//undo any block function
mBlockStart = 0;
mBlockEnd = 0;
//find out where the cursor should be
S32 pos = setCursorPos( event.mousePoint );
// if the position is to the left
if ( pos == -1 )
mCursorPos = 0;
else if ( pos == -2 ) //else if the position is to the right
mCursorPos = mTextBuffer.length();
else //else set the mCursorPos
mCursorPos = pos;
//save the mouseDragPos
mMouseDragStart = mCursorPos;
// lock the mouse
mouseLock();
//set the drag var
mDragHit = true;
//let the parent get the event
setFirstResponder();
}Continued in next post
#7
06/21/2006 (10:18 am)
void GuiTextEditCtrl::onMouseDragged( const GuiEvent &event )
{
S32 pos = setCursorPos( event.mousePoint );
// if the position is to the left
if ( pos == -1 )
mScrollDir = -1;
else if ( pos == -2 ) // the position is to the right
mScrollDir = 1;
else // set the new cursor position
{
mScrollDir = 0;
mCursorPos = pos;
}
// update the block:
mBlockStart = getMin( mCursorPos, mMouseDragStart );
mBlockEnd = getMax( mCursorPos, mMouseDragStart );
if ( mBlockStart < 0 )
mBlockStart = 0;
if ( mBlockStart == mBlockEnd )
mBlockStart = mBlockEnd = 0;
//let the parent get the event
Parent::onMouseDragged(event);
}
void GuiTextEditCtrl::onMouseUp(const GuiEvent &event)
{
event;
mDragHit = false;
mScrollDir = 0;
mouseUnlock();
}
void GuiTextEditCtrl::saveUndoState()
{
//save the current state
mUndoText.set(&mTextBuffer);
mUndoBlockStart = mBlockStart;
mUndoBlockEnd = mBlockEnd;
mUndoCursorPos = mCursorPos;
}Continued in next post
#8
06/21/2006 (10:20 am)
Bool GuiTextEditCtrl::onKeyDown(const GuiEvent &event)
{
S32 stringLen = mTextBuffer.length();
setUpdate();
// Ugly, but now I'm cool like MarkF.
if(event.keyCode == KEY_BACKSPACE)
goto dealWithBackspace;
if (event.modifier & SI_SHIFT)
{
switch (event.keyCode)
{
case KEY_TAB:
if ( mTabComplete )
{
Con::executef( this, 2, "onTabComplete", "1" );
return( true );
}
case KEY_HOME:
mBlockStart = 0;
mBlockEnd = mCursorPos;
mCursorPos = 0;
return true;
case KEY_END:
mBlockStart = mCursorPos;
mBlockEnd = stringLen;
mCursorPos = stringLen;
return true;
case KEY_LEFT:
if ((mCursorPos > 0) & (stringLen > 0))
{
//if we already have a selected block
if (mCursorPos == mBlockEnd)
{
mCursorPos--;
mBlockEnd--;
if (mBlockEnd == mBlockStart)
{
mBlockStart = 0;
mBlockEnd = 0;
}
}
else {
mCursorPos--;
mBlockStart = mCursorPos;
if (mBlockEnd == 0)
{
mBlockEnd = mCursorPos + 1;
}
}
}
return true;
case KEY_RIGHT:
if (mCursorPos < stringLen)
{
if ((mCursorPos == mBlockStart) && (mBlockEnd > 0))
{
mCursorPos++;
mBlockStart++;
if (mBlockStart == mBlockEnd)
{
mBlockStart = 0;
mBlockEnd = 0;
}
}
else
{
if (mBlockEnd == 0)
{
mBlockStart = mCursorPos;
mBlockEnd = mCursorPos;
}
mCursorPos++;
mBlockEnd++;
}
}
return true;
}
}
else if (event.modifier & SI_CTRL)
{
switch(event.keyCode)
{
// Added UNIX emacs key bindings - just a little hack here...
// BJGTODO: Add vi bindings.
// Ctrl-B - move one character back
case KEY_B:
{ GuiEvent new_event;
new_event.modifier = 0;
new_event.keyCode = KEY_LEFT;
return(onKeyDown(new_event));
}
// Ctrl-F - move one character forward
case KEY_F:
{ GuiEvent new_event;
new_event.modifier = 0;
new_event.keyCode = KEY_RIGHT;
return(onKeyDown(new_event));
}
// Ctrl-A - move to the beginning of the line
case KEY_A:
{ GuiEvent new_event;
new_event.modifier = 0;
new_event.keyCode = KEY_HOME;
return(onKeyDown(new_event));
}
// Ctrl-E - move to the end of the line
case KEY_E:
{ GuiEvent new_event;
new_event.modifier = 0;
new_event.keyCode = KEY_END;
return(onKeyDown(new_event));
}
// Ctrl-P - move backward in history
case KEY_P:
{ GuiEvent new_event;
new_event.modifier = 0;
new_event.keyCode = KEY_UP;
return(onKeyDown(new_event));
}
// Ctrl-N - move forward in history
case KEY_N:
{ GuiEvent new_event;
new_event.modifier = 0;
new_event.keyCode = KEY_DOWN;
return(onKeyDown(new_event));
}
// Ctrl-D - delete under cursor
case KEY_D:
{ GuiEvent new_event;
new_event.modifier = 0;
new_event.keyCode = KEY_DELETE;
return(onKeyDown(new_event));
}
case KEY_U:
{ GuiEvent new_event;
new_event.modifier = SI_CTRL;
new_event.keyCode = KEY_DELETE;
return(onKeyDown(new_event));
}
// End added UNIX emacs key bindings
case KEY_C:
case KEY_X:
// Don't copy/cut password field!
if(mPasswordText)
return true;
UTF8 buf[GuiTextCtrl::MAX_STRING_LENGTH + 1];
if (mBlockEnd > 0)
{
//save the current state
saveUndoState();
//copy the text to the clipboard
StringBuffer tmp = mTextBuffer.substring(mBlockStart, mBlockEnd - mBlockStart);
FrameTemp<UTF8> clipBuff((mBlockEnd-mBlockStart) * 3 + 1);
tmp.get(clipBuff, (mBlockEnd-mBlockStart) * 3 + 1);
Platform::setClipboard((char*)(UTF8*)clipBuff);
//if we pressed ctrl-x, we need to cut the selected text from the control...
if (event.keyCode == KEY_X)
{
mTextBuffer.cut(mBlockStart, mBlockEnd - mBlockStart);
mCursorPos = mBlockStart;
}
mBlockStart = 0;
mBlockEnd = 0;
}
return true;Continued in next post
#9
06/21/2006 (10:22 am)
case KEY_V:
{
UTF8 buf[GuiTextCtrl::MAX_STRING_LENGTH + 1];
//first, make sure there's something in the clipboard to copy...
const char *temp = (const char*)Platform::getClipboard();
UTF8 *clipBuf = (UTF8*)GuiMLTextCtrl::stripControlChars(temp);
if (dStrlen(clipBuf) <= 0)
return true;
//save the current state
saveUndoState();
//delete anything hilited
if (mBlockEnd > 0)
{
mTextBuffer.cut(mBlockStart, mBlockEnd - mBlockStart);
mCursorPos = mBlockStart;
mBlockStart = 0;
mBlockEnd = 0;
}
StringBuffer tmp(clipBuf);
S32 pasteLen = tmp.length();
if ((stringLen + pasteLen) > mMaxStrLen)
{
pasteLen = mMaxStrLen - stringLen;
// Trim down to be pasteLen long.
tmp.cut(pasteLen, tmp.length() - pasteLen);
}
if (mCursorPos == stringLen)
{
mTextBuffer.append(tmp);
}
else
{
mTextBuffer.insert(mCursorPos, tmp);
}
mCursorPos += tmp.length();
return true;
}
case KEY_Z:
if (! mDragHit)
{
StringBuffer tempBuffer;
S32 tempBlockStart;
S32 tempBlockEnd;
S32 tempCursorPos;
//save the current
tempBuffer.set(&mTextBuffer);
tempBlockStart = mBlockStart;
tempBlockEnd = mBlockEnd;
tempCursorPos = mCursorPos;
//restore the prev
mTextBuffer.set(&mUndoText);
mBlockStart = mUndoBlockStart;
mBlockEnd = mUndoBlockEnd;
mCursorPos = mUndoCursorPos;
//update the undo
mUndoText.set(&tempBuffer);
mUndoBlockStart = tempBlockStart;
mUndoBlockEnd = tempBlockEnd;
mUndoCursorPos = tempCursorPos;
return true;
}
case KEY_DELETE:
case KEY_BACKSPACE:
//save the current state
saveUndoState();
//delete everything in the field
mTextBuffer.set("");
mCursorPos = 0;
mBlockStart = 0;
mBlockEnd = 0;
execConsoleCallback();
return true;
}
}
else
{
switch(event.keyCode)
{
case KEY_ESCAPE:
if ( mEscapeCommand[0] )
{
Con::evaluate( mEscapeCommand );
return( true );
}
return( Parent::onKeyDown( event ) );
case KEY_RETURN:
case KEY_NUMPADENTER:
//first validate
if (mProfile->mReturnTab)
{
onLoseFirstResponder();
}
updateHistory(&mTextBuffer, true);
mHistoryDirty = false;
//next exec the alt console command
if ( mAltConsoleCommand[0] )
{
char buf[16];
dSprintf( buf, sizeof( buf ), "%d", getId() );
Con::setVariable( "$ThisControl", buf );
Con::evaluate( mAltConsoleCommand, false );
}
if (mProfile->mReturnTab)
{
GuiCanvas *root = getRoot();
if (root)
{
root->tabNext();
return true;
}
}
return true;
case KEY_UP:
{
if(mHistoryDirty)
{
updateHistory(&mTextBuffer, false);
mHistoryDirty = false;
}
mHistoryIndex--;
if(mHistoryIndex >= 0 && mHistoryIndex <= mHistoryLast)
setText((char*)mHistoryBuf[mHistoryIndex]);
else if(mHistoryIndex < 0)
mHistoryIndex = 0;
return true;
}
case KEY_DOWN:
if(mHistoryDirty)
{
updateHistory(&mTextBuffer, false);
mHistoryDirty = false;
}
mHistoryIndex++;
if(mHistoryIndex > mHistoryLast)
{
mHistoryIndex = mHistoryLast + 1;
setText("");
}
else
setText((char*)mHistoryBuf[mHistoryIndex]);
return true;
case KEY_LEFT:
mBlockStart = 0;
mBlockEnd = 0;
if (mCursorPos > 0)
{
mCursorPos--;
}
return true;
case KEY_RIGHT:
mBlockStart = 0;
mBlockEnd = 0;
if (mCursorPos < stringLen)
{
mCursorPos++;
}
return true;
case KEY_BACKSPACE:
dealWithBackspace:
//save the current state
saveUndoState();
if (mBlockEnd > 0)
{
mTextBuffer.cut(mBlockStart, mBlockEnd-mBlockStart);
mCursorPos = mBlockStart;
mBlockStart = 0;
mBlockEnd = 0;
mHistoryDirty = true;
// Execute the console command!
execConsoleCallback();
}
else if (mCursorPos > 0)
{
mTextBuffer.cut(mCursorPos-1, 1);
mCursorPos--;
mHistoryDirty = true;
// Execute the console command!
execConsoleCallback();
}
return true;
case KEY_DELETE:
//save the current state
saveUndoState();
if (mBlockEnd > 0)
{
mHistoryDirty = true;
mTextBuffer.cut(mBlockStart, mBlockEnd-mBlockStart);
mCursorPos = mBlockStart;
mBlockStart = 0;
mBlockEnd = 0;
// Execute the console command!
execConsoleCallback();
}
else if (mCursorPos < stringLen)
{
mHistoryDirty = true;
mTextBuffer.cut(mCursorPos, 1);
// Execute the console command!
execConsoleCallback();
}
return true;
case KEY_INSERT:
mInsertOn = !mInsertOn;
return true;
case KEY_HOME:
mBlockStart = 0;
mBlockEnd = 0;
mCursorPos = 0;
return true;
case KEY_END:
mBlockStart = 0;
mBlockEnd = 0;
mCursorPos = stringLen;
return true;
}
}Continued in next post
#10
06/21/2006 (10:23 am)
switch ( event.keyCode )
{
case KEY_TAB:
if ( mTabComplete )
{
Con::executef( this, 2, "onTabComplete", "0" );
return( true );
}
case KEY_UP:
case KEY_DOWN:
case KEY_ESCAPE:
return Parent::onKeyDown( event );
}
if ( mFont->isValidChar( event.ascii ) )
{
// Get the character ready to add to a UTF8 string.
UTF16 conv[2] = { event.ascii, 0 };
StringBuffer convertedChar(conv);
#if 0
{
UTF8 pony[10];
convertedChar.get(pony, 10);
Con::printf("Got key '%s' (0x%x)", pony, event.ascii );
}
#endif
//see if it's a number field
if ( mProfile->mNumbersOnly )
{
if (event.ascii == '-')
{
//a minus sign only exists at the beginning, and only a single minus sign
if ( mCursorPos != 0 )
{
playDeniedSound();
return true;
}
if ( mInsertOn && ( mTextBuffer.getChar(0) == '-' ) )
{
playDeniedSound();
return true;
}
}
// BJTODO: This is probably not unicode safe.
else if ( event.ascii < '0' || event.ascii > '9' )
{
playDeniedSound();
return true;
}
}
//save the current state
saveUndoState();
//delete anything highlighted
if ( mBlockEnd > 0 )
{
mTextBuffer.cut(mBlockStart, mBlockEnd-mBlockStart);
mCursorPos = mBlockStart;
mBlockStart = 0;
mBlockEnd = 0;
}
if ( ( mInsertOn && ( stringLen < mMaxStrLen ) ) ||
( !mInsertOn && ( mCursorPos < mMaxStrLen ) ) )
{
if ( mCursorPos == stringLen )
{
mTextBuffer.append(convertedChar);
mCursorPos++;
}
else
{
if ( mInsertOn )
{
mTextBuffer.insert(mCursorPos, convertedChar);
mCursorPos++;
}
else
{
mTextBuffer.cut(mCursorPos, 1);
mTextBuffer.insert(mCursorPos, convertedChar);
mCursorPos++;
}
}
}
else
playDeniedSound();
//reset the history index
mHistoryDirty = true;
//execute the console command if it exists
execConsoleCallback();
return true;
}
//not handled - pass the event to it's parent
// Or eat it if that's appropriate.
if (mSinkAllKeyEvents)
return true;
return Parent::onKeyDown( event );
}Continued in next post
#11
06/21/2006 (10:24 am)
void GuiTextEditCtrl::setFirstResponder()
{
Parent::setFirstResponder();
Platform::enableKeyboardTranslation();
}
void GuiTextEditCtrl::onLoseFirstResponder()
{
Platform::disableKeyboardTranslation();
//first, update the history
updateHistory( &mTextBuffer, true );
//execute the validate command
if ( mValidateCommand[0] )
Con::evaluate( mValidateCommand, false );
// Redraw the control:
setUpdate();
}
void GuiTextEditCtrl::parentResized(const Point2I &oldParentExtent, const Point2I &newParentExtent)
{
Parent::parentResized( oldParentExtent, newParentExtent );
mTextOffsetReset = true;
}
void GuiTextEditCtrl::onRender(Point2I offset, const RectI & /*updateRect*/)
{
RectI ctrlRect( offset, mBounds.extent );
//if opaque, fill the update rect with the fill color
if ( mProfile->mOpaque )
dglDrawRectFill( ctrlRect, mProfile->mFillColor );
//if there's a border, draw the border
if ( mProfile->mBorder )
renderBorder( ctrlRect, mProfile );
drawText( ctrlRect, isFirstResponder() );
}
void GuiTextEditCtrl::onPreRender()
{
if ( isFirstResponder() )
{
U32 timeElapsed = Platform::getVirtualMilliseconds() - mTimeLastCursorFlipped;
mNumFramesElapsed++;
if ( ( timeElapsed > 500 ) && ( mNumFramesElapsed > 3 ) )
{
mCursorOn = !mCursorOn;
mTimeLastCursorFlipped = Platform::getVirtualMilliseconds();
mNumFramesElapsed = 0;
setUpdate();
}
//update the cursor if the text is scrolling
if ( mDragHit )
{
if ( ( mScrollDir < 0 ) && ( mCursorPos > 0 ) )
mCursorPos--;
else if ( ( mScrollDir > 0 ) && ( mCursorPos < (S32) mTextBuffer.length() ) )
mCursorPos++;
}
}
}Continued in Next Post
#12
06/21/2006 (10:25 am)
void GuiTextEditCtrl::drawText( const RectI &drawRect, bool isFocused )
{
StringBuffer textBuffer;
Point2I drawPoint = drawRect.point;
Point2I paddingLeftTop, paddingRightBottom;
// Just a little sanity.
if(mCursorPos > mTextBuffer.length())
mCursorPos = mTextBuffer.length();
// Apply password masking (make the masking char optional perhaps?)
if(mPasswordText)
{
//fixed
for(U32 i = 0; i<mTextBuffer.length(); i++)
textBuffer.append(StringBuffer(mPasswordMask));
}
else
{
// Or else just copy it over.
textBuffer.set(&mTextBuffer);
}
paddingLeftTop.set(( mProfile->mTextOffset.x != 0 ? mProfile->mTextOffset.x : 3 ), mProfile->mTextOffset.y);
paddingRightBottom = paddingLeftTop;
// Center vertically:
drawPoint.y += ( ( drawRect.extent.y - paddingLeftTop.y - paddingRightBottom.y - mFont->getHeight() ) / 2 ) + paddingLeftTop.y;
// Align horizontally:
S32 textWidth;
{
FrameTemp<UTF8> widthTemp(textBuffer.length()*3+1);
textBuffer.get(widthTemp, textBuffer.length()*3+1);
textWidth = mFont->getStrWidth( widthTemp );
}
if ( drawRect.extent.x - paddingLeftTop.x > textWidth )
{
switch( mProfile->mAlignment )
{
case GuiControlProfile::RightJustify:
drawPoint.x += ( drawRect.extent.x - textWidth - paddingRightBottom.x );
break;
case GuiControlProfile::CenterJustify:
drawPoint.x += ( ( drawRect.extent.x - textWidth ) / 2 );
break;
default:
case GuiControlProfile::LeftJustify :
drawPoint.x += paddingLeftTop.x;
break;
}
}
else
drawPoint.x += paddingLeftTop.x;
ColorI fontColor = mActive ? mProfile->mFontColor : mProfile->mFontColorNA;
// now draw the text
Point2I cursorStart, cursorEnd;
mTextOffset.y = drawPoint.y;
if ( mTextOffsetReset )
{
mTextOffset.x = drawPoint.x;
mTextOffsetReset = false;
}
if ( drawRect.extent.x - paddingLeftTop.x > textWidth )
mTextOffset.x = drawPoint.x;
else
{
// Alignment affects large text
if ( mProfile->mAlignment == GuiControlProfile::RightJustify
|| mProfile->mAlignment == GuiControlProfile::CenterJustify )
{
if ( mTextOffset.x + textWidth < (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x)
mTextOffset.x = (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x - textWidth;
}
}
// calculate the cursor
if ( isFocused )
{
// Where in the string are we?
//StringBuffer preCursor = mTextBuffer.substring(0, mCursorPos);
StringBuffer preCursor = textBuffer.substring(0, mCursorPos);
S32 cursorOffset=0, charWidth=0;
//UTF16 tempChar = mTextBuffer.getChar(mCursorPos);
UTF16 tempChar = textBuffer.getChar(mCursorPos);
// Alright, we want to terminate things momentarily.
if(mCursorPos > 0)
{
FrameTemp<UTF8> cursorTemp(preCursor.length()*3+1);
preCursor.get(cursorTemp, preCursor.length()*3+1);
cursorOffset = mFont->getStrWidth(cursorTemp);
}
else
cursorOffset = 0;
if ( tempChar )
charWidth = mFont->getCharWidth( tempChar );
else
charWidth = paddingRightBottom.x;
if( mTextOffset.x + cursorOffset + charWidth >= (drawRect.point.x + drawRect.extent.x) - paddingLeftTop.x )
{
// Cursor somewhere beyond the textcontrol,
// skip forward roughly 25% of the total width (if possible)
S32 skipForward = drawRect.extent.x / 4;
if ( cursorOffset + skipForward > textWidth )
mTextOffset.x = (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x - textWidth;
else
mTextOffset.x -= skipForward;
}
else if( mTextOffset.x + cursorOffset < drawRect.point.x + paddingLeftTop.x )
{
// Cursor somewhere before the textcontrol
// skip backward roughly 25% of the total width (if possible)
S32 skipBackward = drawRect.extent.x / 4;
if ( cursorOffset - skipBackward < 0 )
mTextOffset.x = drawRect.point.x + paddingLeftTop.x;
else
mTextOffset.x += skipBackward;
}
cursorStart.x = mTextOffset.x + cursorOffset;
cursorEnd.x = cursorStart.x;
S32 cursorHeight = mFont->getHeight();
if ( cursorHeight < drawRect.extent.y )
{
cursorStart.y = drawPoint.y;
cursorEnd.y = cursorStart.y + cursorHeight;
}
else
{
cursorStart.y = drawRect.point.y;
cursorEnd.y = cursorStart.y + drawRect.extent.y;
}
}
//draw the text
if ( !isFocused )
mBlockStart = mBlockEnd = 0;
//also verify the block start/end
if ((mBlockStart > textBuffer.length() || (mBlockEnd > textBuffer.length()) || (mBlockStart > mBlockEnd)))
mBlockStart = mBlockEnd = 0;
UTF16 temp;
Point2I tempOffset = mTextOffset;
//draw the portion before the highlight
if ( mBlockStart > 0 )
{
StringBuffer preBuffer = textBuffer.substring(0, mBlockStart);
FrameTemp<UTF8> preString(preBuffer.length()*3+1);
preBuffer.get(preString, preBuffer.length()*3+1);
dglSetBitmapModulation( fontColor );
dglDrawText( mFont, tempOffset, preString, mProfile->mFontColors );
tempOffset.x += mFont->getStrWidth( (const UTF8*)preString );
}
//draw the hilighted portion
if ( mBlockEnd > 0 )
{
StringBuffer highlightBuff = textBuffer.substring(mBlockStart, mBlockEnd-mBlockStart);
FrameTemp<UTF8> highlightTemp(highlightBuff.length()*3 + 1);
highlightBuff.get(highlightTemp, highlightBuff.length()*3 + 1);
S32 highlightWidth = mFont->getStrWidth( highlightTemp );
dglDrawRectFill( Point2I( tempOffset.x, drawRect.point.y ),
Point2I( tempOffset.x + highlightWidth, drawRect.point.y + drawRect.extent.y - 1),
mProfile->mFillColorHL );
dglSetBitmapModulation( mProfile->mFontColorHL );
dglDrawText( mFont, tempOffset, highlightTemp, mProfile->mFontColors );
tempOffset.x += highlightWidth;
}
//draw the portion after the highlite
if(mBlockEnd < mTextBuffer.length())
{
//StringBuffer finalBuff = mTextBuffer.substring(mBlockEnd, mTextBuffer.length() - mBlockEnd);
StringBuffer finalBuff = textBuffer.substring(mBlockEnd, mTextBuffer.length() - mBlockEnd);
FrameTemp<UTF8> finalTemp(finalBuff.length()*3 + 1);
finalBuff.get(finalTemp, finalBuff.length()*3 + 1);
dglSetBitmapModulation( fontColor );
dglDrawText( mFont, tempOffset, finalTemp, mProfile->mFontColors );
}
//draw the cursor
if ( isFocused && mCursorOn )
dglDrawLine( cursorStart, cursorEnd, mProfile->mCursorColor );
}Continued in Next Post
#13
That should fix the password fields problem.
And just so you get the information from the horses mouth so to speak. The original plan for the kit was to release the Advanced Tutorial series as a patch that would be free and then there would be a paid version with more features. However the community did not respond well to the idea so I rolled all of those new features into a single paid patch kit. The MMOKit is a selling product with literally hundreds of more features than you can get by doing the tutorials. However I do still have the tutorials, they are still free for members of the site. For some reason they don't seem to be posted at the moment, and I am looking into why (I think it may be an access control or permissions problem), anyways sorry about that.
Regards,
Dreamer
06/21/2006 (10:26 am)
bool GuiTextEditCtrl::hasText()
{
return (mTextBuffer.length());
}
void GuiTextEditCtrl::playDeniedSound()
{
if ( mDeniedSound )
{
AUDIOHANDLE handle = alxCreateSource( mDeniedSound );
alxPlay( handle );
}
}
bool GuiTextEditCtrl::initCursors()
{
if ( mEditCursor == NULL )
{
SimObject *obj;
obj = Sim::findObject("TextEditCursor");
mEditCursor = dynamic_cast<GuiCursor*>(obj);
return( mEditCursor != NULL );
}
else
return(true);
}
void GuiTextEditCtrl::getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent)
{
showCursor = true;
if( initCursors() )
{
Point2I mousePos = lastGuiEvent.mousePoint;
RectI winRect = mBounds;
winRect.point = localToGlobalCoord( winRect.point );
if( winRect.pointInRect( mousePos ) )
cursor = mEditCursor;
else
cursor = NULL;
}
}
const char *GuiTextEditCtrl::getScriptValue()
{
FrameTemp<UTF8> temp(mTextBuffer.length() * 3 + 1);
mTextBuffer.get(temp, mTextBuffer.length() * 3 + 1);
return StringTable->insert((const char*)(UTF8*)temp);
}
void GuiTextEditCtrl::setScriptValue(const char *value)
{
mTextBuffer.set(value);
mCursorPos = mTextBuffer.length() - 1;
}
ConsoleMethod( GuiTextEditCtrl, getText, const char*, 2, 2, "textEditCtrl.getText()" )
{
argc; argv;
if( !object->hasText() )
return StringTable->insert("");
char *retBuffer = Con::getReturnBuffer( GuiTextEditCtrl::MAX_STRING_LENGTH );
object->getText( retBuffer );
return retBuffer;
}
ConsoleMethod( GuiTextEditCtrl, getCursorPos, S32, 2, 2, "textEditCtrl.getCursorPos()" )
{
argc; argv;
return( object->getCursorPos() );
}
ConsoleMethod( GuiTextEditCtrl, setCursorPos, void, 3, 3, "textEditCtrl.setCursorPos( newPos )" )
{
argc;
object->reallySetCursorPos( dAtoi( argv[2] ) );
}That should fix the password fields problem.
And just so you get the information from the horses mouth so to speak. The original plan for the kit was to release the Advanced Tutorial series as a patch that would be free and then there would be a paid version with more features. However the community did not respond well to the idea so I rolled all of those new features into a single paid patch kit. The MMOKit is a selling product with literally hundreds of more features than you can get by doing the tutorials. However I do still have the tutorials, they are still free for members of the site. For some reason they don't seem to be posted at the moment, and I am looking into why (I think it may be an access control or permissions problem), anyways sorry about that.
Regards,
Dreamer
#14
06/25/2006 (4:59 am)
Thanks a lot.
#15
1>------ Build started: Project: Torque Demo, Configuration: Debug Win32 ------
1>Compiling...
1>guiTextEditCtrl.cc
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(335) : error C2143: syntax error : missing ';' before 'GuiTextEditCtrl::onKeyDown'
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(335) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(336) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(336) : error C2556: 'int GuiTextEditCtrl::onKeyDown(const GuiEvent &)' : overloaded function differs only by return type from 'bool GuiTextEditCtrl::onKeyDown(const GuiEvent &)'
1> c:\torque\sdk\engine\gui\controls\guitexteditctrl.h(100) : see declaration of 'GuiTextEditCtrl::onKeyDown'
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(336) : error C2371: 'GuiTextEditCtrl::onKeyDown' : redefinition; different basic types
1> c:\torque\sdk\engine\gui\controls\guitexteditctrl.h(100) : see declaration of 'GuiTextEditCtrl::onKeyDown'
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(433) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(441) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(449) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(457) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(465) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(473) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(481) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(488) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>Creating browse information file...
1>Microsoft Browse Information Maintenance Utility Version 8.00.50727
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Build log was saved at "file://c:\Torque\SDK\engine\out.VC8.DEBUG\BuildLog.htm"
1>Torque Demo - 13 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 6 up-to-date, 0 skipped ==========
Please help me!
Thanks!
06/25/2006 (9:11 am)
Visual C++ 2005 Express makes error with this new code:1>------ Build started: Project: Torque Demo, Configuration: Debug Win32 ------
1>Compiling...
1>guiTextEditCtrl.cc
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(335) : error C2143: syntax error : missing ';' before 'GuiTextEditCtrl::onKeyDown'
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(335) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(336) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(336) : error C2556: 'int GuiTextEditCtrl::onKeyDown(const GuiEvent &)' : overloaded function differs only by return type from 'bool GuiTextEditCtrl::onKeyDown(const GuiEvent &)'
1> c:\torque\sdk\engine\gui\controls\guitexteditctrl.h(100) : see declaration of 'GuiTextEditCtrl::onKeyDown'
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(336) : error C2371: 'GuiTextEditCtrl::onKeyDown' : redefinition; different basic types
1> c:\torque\sdk\engine\gui\controls\guitexteditctrl.h(100) : see declaration of 'GuiTextEditCtrl::onKeyDown'
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(433) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(441) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(449) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(457) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(465) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(473) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(481) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>c:\torque\sdk\engine\gui\controls\guitexteditctrl.cc(488) : error C2264: 'GuiTextEditCtrl::onKeyDown' : error in function definition or declaration; function not called
1>Creating browse information file...
1>Microsoft Browse Information Maintenance Utility Version 8.00.50727
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Build log was saved at "file://c:\Torque\SDK\engine\out.VC8.DEBUG\BuildLog.htm"
1>Torque Demo - 13 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 6 up-to-date, 0 skipped ==========
Please help me!
Thanks!
#16
07/04/2006 (6:29 am)
Why don't somebody answer?
#17
07/15/2006 (6:19 am)
Maybe because it appears you're running into quite basic errors. Maybe you should get some programming experience, buy a couple of books and try write a few simple programs? Learn to walk before you run so to speak.
#18
@Anders Jacobsen: Why so agressive? Learn to behave you, befor you post.
07/16/2006 (11:08 pm)
@Inge Siebmanns: In the code above are a few errors. Havent check it completly, but "Bool GuiTextEditCtrl::onKeyDown(const GuiEvent &event)" schould be "bool GuiTextEditCtrl::onKeyDown(const GuiEvent &event)".@Anders Jacobsen: Why so agressive? Learn to behave you, befor you post.
#19
07/17/2006 (7:23 am)
Now it all works in milestone 3, tanks a lot. (Now I will work on the others) I hope they work... If not I will post.
#20
07/17/2006 (7:30 am)
Ohh, there is an error/question: How create an Account???
Torque 3D Owner Jonathon Stevens
There is now an MMO Kit that you can purchase at www.mydreamrpg.com which is in active development and gives you a ton of MMO related features.