Scrolling Bitmap Control
by Robert Brower · 04/14/2005 (2:55 pm) · 5 comments
Download Code File
1. Put guiScrollingBitmapCtrl.h and guiScrollingBitmapCtrl.cc in your engine/gui folder and add them to your project.
2. Put stars1.png in your starter.fps/client/ui folder.
3. Add the following text to the top of your mainMenuGui.gui file like this:
//--- OBJECT WRITE BEGIN ---
new GuiChunkedBitmapCtrl(MainMenuGui) {
profile = "GuiContentProfile";
horizSizing = "width";
vertSizing = "height";
position = "0 0";
extent = "640 480";
minExtent = "8 8";
visible = "1";
bitmap = "./background";
useVariable = "0";
tile = "0";
helpTag = "0";
// INSERT THIS TEXT HERE ->
new GuiScrollingBitmapCtrl() {
profile = "GuiDefaultProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "0 0";
extent = "1024 768";
minExtent = "1024 768";
visible = "1";
bitmap = "~/client/ui/stars1.png";
wrap = "1";
interval = "30";
xoffset = "1";
yoffset = "1";
};
// <- INSERT THIS TEXT HERE
***NOTES... Play with interval, xoffset, and yoffset to speed up or slow down the scrolling. Make sure you turn on wrap otherwise the image won't... wrap.
Good luck and enjoy,
Robert
1. Put guiScrollingBitmapCtrl.h and guiScrollingBitmapCtrl.cc in your engine/gui folder and add them to your project.
2. Put stars1.png in your starter.fps/client/ui folder.
3. Add the following text to the top of your mainMenuGui.gui file like this:
//--- OBJECT WRITE BEGIN ---
new GuiChunkedBitmapCtrl(MainMenuGui) {
profile = "GuiContentProfile";
horizSizing = "width";
vertSizing = "height";
position = "0 0";
extent = "640 480";
minExtent = "8 8";
visible = "1";
bitmap = "./background";
useVariable = "0";
tile = "0";
helpTag = "0";
// INSERT THIS TEXT HERE ->
new GuiScrollingBitmapCtrl() {
profile = "GuiDefaultProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "0 0";
extent = "1024 768";
minExtent = "1024 768";
visible = "1";
bitmap = "~/client/ui/stars1.png";
wrap = "1";
interval = "30";
xoffset = "1";
yoffset = "1";
};
// <- INSERT THIS TEXT HERE
***NOTES... Play with interval, xoffset, and yoffset to speed up or slow down the scrolling. Make sure you turn on wrap otherwise the image won't... wrap.
Good luck and enjoy,
Robert
About the author
#2
Cool control though, I've got 2 overlaid starfields at different speeds giving a nice parallax effect. :-) It's only until I can come up with a cooler front screen.. but the idea is nice.
08/07/2005 (12:08 pm)
There is a limit to the size of the image though... I got an error saying my image was longer than 2048 pixel high and it wasn't happy about it... Also wonder about the practicalities of using a really huge image for credits...Cool control though, I've got 2 overlaid starfields at different speeds giving a nice parallax effect. :-) It's only until I can come up with a cooler front screen.. but the idea is nice.
#3
Change:
if (mCurrXOffset >= texture->bitmapWidth)
{
mCurrXOffset = 0;
}
if (mCurrYOffset >= texture->bitmapHeight)
{
mCurrYOffset = 0 ;
}
to
if (mCurrXOffset >= texture->bitmapWidth)
{
mCurrXOffset -= texture->bitmapWidth;
}
if (mCurrYOffset >= texture->bitmapHeight)
{
mCurrYOffset -= texture->bitmapHeight;
}
After you recompile you can adjust the xOffset and yOffset to be 1 less than the height and width of the image and then the stars will go in the opposite direction.
08/25/2005 (3:09 pm)
I wasn't able to get the stars to go in the opposite direction at first. I was able to by changing the GuiScrollingBitmapCtrl::onRender in the guiScrollingBitmapCtrl.cc file. Change:
if (mCurrXOffset >= texture->bitmapWidth)
{
mCurrXOffset = 0;
}
if (mCurrYOffset >= texture->bitmapHeight)
{
mCurrYOffset = 0 ;
}
to
if (mCurrXOffset >= texture->bitmapWidth)
{
mCurrXOffset -= texture->bitmapWidth;
}
if (mCurrYOffset >= texture->bitmapHeight)
{
mCurrYOffset -= texture->bitmapHeight;
}
After you recompile you can adjust the xOffset and yOffset to be 1 less than the height and width of the image and then the stars will go in the opposite direction.
#4
I have modified your code for my study on bitmapCtrl in Torque and I have added mouse control on the bitmap viewed.
Here the code H :
And cpp code :
The script code is :
My target is realize a new MapHud for strategic game.
Bye !!
^_^
12/29/2008 (6:29 am)
Hi Robert !!!I have modified your code for my study on bitmapCtrl in Torque and I have added mouse control on the bitmap viewed.
Here the code H :
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef _GUISCROLLINGBITMAPCTRL_H_
#define _GUISCROLLINGBITMAPCTRL_H_
#ifndef _GUICONTROL_H_
#include "gui/core/guiControl.h"
#endif
#ifndef _GTEXMANAGER_H_
#include "dgl/gTexManager.h"
#endif
/// Renders a bitmap and scroll inside it.
class GuiScrollingBitmapCtrl : public GuiControl
{
private:
typedef GuiControl Parent;
protected:
StringTableEntry mBitmapName;
TextureHandle mTextureHandle;
Point2I startPoint;
bool mWrap;
S32 mCurrXOffset;
S32 mCurrYOffset;
Point2I mMouseDownPosition;
bool mLeftMouseDown;
bool mRightMouseDown;
public:
//creation methods
DECLARE_CONOBJECT(GuiScrollingBitmapCtrl);
GuiScrollingBitmapCtrl();
static void initPersistFields();
//Parental methods
bool onWake();
void onSleep();
void inspectPostApply();
void setBitmap(const char *name,bool resize = false);
void setBitmap(const TextureHandle &handle,bool resize = false);
void setMapPos(S32 x, S32 y);
void onMouseDown(const GuiEvent &);
void onMouseUp(const GuiEvent &event);
void onMouseDragged(const GuiEvent &event);
void onRightMouseDown(const GuiEvent &event);
void onRightMouseUp(const GuiEvent & event);
void onRightMouseDragged(const GuiEvent & event);
void onMouseMove(const GuiEvent &event);
bool onMouseWheelUp(const GuiEvent &event);
bool onMouseWheelDown(const GuiEvent &event);
S32 getWidth() const { return(mTextureHandle.getWidth()); }
S32 getHeight() const { return(mTextureHandle.getHeight()); }
void onRender(Point2I offset, const RectI &updateRect);
void setValue(S32 x, S32 y);
};
#endifAnd cpp code :
//-------------------------------------------------------------------------------------------------------------------------------//
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-------------------------------------------------------------------------------------------------------------------------------//
#include "console/console.h"
#include "console/consoleTypes.h"
#include "dgl/dgl.h"
#include "gui/controls/guiScrollingBitmapCtrl.h"
IMPLEMENT_CONOBJECT(GuiScrollingBitmapCtrl);
GuiScrollingBitmapCtrl::GuiScrollingBitmapCtrl(void)
{
mBitmapName = StringTable->insert("");
startPoint.set(0, 0);
mWrap = false;
mCurrXOffset = 0;
mCurrYOffset = 0;
}
void GuiScrollingBitmapCtrl::initPersistFields()
{
Parent::initPersistFields();
addGroup("Misc"); // MM: Added Group Header.
addField("bitmap", TypeFilename, Offset(mBitmapName, GuiScrollingBitmapCtrl));
addField("wrap", TypeBool, Offset(mWrap, GuiScrollingBitmapCtrl));
endGroup("Misc"); // MM: Added Group Footer.
}
ConsoleMethod( GuiScrollingBitmapCtrl, setValue, void, 4, 4, "(int xAxis, int yAxis)"
"Set the offset of the bitmap.")
{
object->setValue(dAtoi(argv[2]), dAtoi(argv[3]));
}
ConsoleMethod( GuiScrollingBitmapCtrl, setBitmap, void, 3, 3, "(string filename)"
"Set the bitmap displayed in the control. Note that it is limited in size, to 256x256.")
{
object->setBitmap(argv[2]);
}
ConsoleMethod( GuiScrollingBitmapCtrl, setMapPos, void, 4, 4, "(int X, int Y)"
"Set offset of the bitmap viewed.")
{
object->setMapPos(dAtoi(argv[2]), dAtoi(argv[3]));
}
bool GuiScrollingBitmapCtrl::onWake()
{
if (! Parent::onWake())
return false;
setActive(true);
setBitmap(mBitmapName);
mCurrXOffset = 0;
mCurrYOffset = 0;
return true;
}
void GuiScrollingBitmapCtrl::onSleep()
{
mTextureHandle = NULL;
Parent::onSleep();
}
void GuiScrollingBitmapCtrl::inspectPostApply()
{
// if the extent is set to (0,0) in the gui editor and appy hit, this control will
// set it's extent to be exactly the size of the bitmap (if present)
Parent::inspectPostApply();
if (!mWrap && (mBounds.extent.x == 0) && (mBounds.extent.y == 0) && mTextureHandle)
{
TextureObject *texture = (TextureObject *) mTextureHandle;
mBounds.extent.x = texture->bitmapWidth;
mBounds.extent.y = texture->bitmapHeight;
}
}
void GuiScrollingBitmapCtrl::setBitmap(const char *name, bool resize)
{
mBitmapName = StringTable->insert(name);
if (*mBitmapName) {
mTextureHandle = TextureHandle(mBitmapName, BitmapTexture, true);
// Resize the control to fit the bitmap
if (resize) {
TextureObject* texture = (TextureObject *) mTextureHandle;
mBounds.extent.x = texture->bitmapWidth;
mBounds.extent.y = texture->bitmapHeight;
Point2I extent = getParent()->getExtent();
parentResized(extent,extent);
}
}
else
mTextureHandle = NULL;
setUpdate();
}
void GuiScrollingBitmapCtrl::setBitmap(const TextureHandle &handle, bool resize)
{
mTextureHandle = handle;
// Resize the control to fit the bitmap
if (resize) {
TextureObject* texture = (TextureObject *) mTextureHandle;
mBounds.extent.x = texture->bitmapWidth;
mBounds.extent.y = texture->bitmapHeight;
Point2I extent = getParent()->getExtent();
parentResized(extent,extent);
}
}
void GuiScrollingBitmapCtrl::onRender(Point2I offset, const RectI &updateRect)
{
TextureObject* texture = (TextureObject *) mTextureHandle;
if (mTextureHandle)
{
dglClearBitmapModulation();
if(mWrap)
{
RectI srcRegion;
RectI dstRegion;
float xdone = ((float)mBounds.extent.x/(float)texture->bitmapWidth)+1;
float ydone = ((float)mBounds.extent.y/(float)texture->bitmapHeight)+1;
int xshift = startPoint.x%texture->bitmapWidth;
int yshift = startPoint.y%texture->bitmapHeight;
xshift += mCurrXOffset;
yshift += mCurrYOffset;
for(int y = 0; y < ydone; ++y)
for(int x = 0; x < xdone; ++x)
{
srcRegion.set(0,0,texture->bitmapWidth,texture->bitmapHeight);
dstRegion.set(((texture->bitmapWidth*x)+offset.x)-xshift,
((texture->bitmapHeight*y)+offset.y)-yshift,
texture->bitmapWidth,
texture->bitmapHeight);
dglDrawBitmapStretchSR(texture,dstRegion, srcRegion, false);
}
}
else
{
Point2I mTempOffset(0, 0);
mTempOffset.x += mCurrXOffset;
mTempOffset.y += mCurrYOffset;
RectI rect(mTempOffset, mBounds.extent);
dglDrawBitmapStretch(mTextureHandle, rect);
}
}
if (mProfile->mBorder || !mTextureHandle)
{
RectI rect(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
dglDrawRect(rect, mProfile->mBorderColor);
}
renderChildControls(offset, updateRect);
}
void GuiScrollingBitmapCtrl::setValue(S32 x, S32 y)
{
if (mTextureHandle)
{
TextureObject* texture = (TextureObject *) mTextureHandle;
x+=texture->bitmapWidth/2;
y+=texture->bitmapHeight/2;
}
while (x < 0)
x += 256;
startPoint.x = x % 256;
while (y < 0)
y += 256;
startPoint.y = y % 256;
}
void GuiScrollingBitmapCtrl::setMapPos(S32 x, S32 y)
{
mCurrXOffset = x;
mCurrYOffset = y;
}
void GuiScrollingBitmapCtrl::onMouseDown(const GuiEvent &event)
{
if (!mActive)
return;
Point2I curMousePos = globalToLocalCoord(event.mousePoint);
Con::executef(this, 3, "onMouseDown",
Con::getIntArg(curMousePos.x),
Con::getIntArg(curMousePos.y));
mLeftMouseDown = true;
}
void GuiScrollingBitmapCtrl::onMouseUp(const GuiEvent &event)
{
mLeftMouseDown = false;
Parent::onMouseUp(event);
}
void GuiScrollingBitmapCtrl::onMouseDragged(const GuiEvent &event)
{
if (!mActive)
return;
if (!mLeftMouseDown)
return;
Point2I curMousePos = globalToLocalCoord(event.mousePoint);
Con::executef(this, 3, "onMouseDragged",
Con::getIntArg(curMousePos.x),
Con::getIntArg(curMousePos.y));
}
void GuiScrollingBitmapCtrl::onRightMouseDown(const GuiEvent & event)
{
if (!mActive)
return;
mMouseDownPosition = event.mousePoint;
Point2I curMousePos = globalToLocalCoord(event.mousePoint);
Con::executef(this, 3, "onRightMouseDown",
Con::getIntArg(curMousePos.x),
Con::getIntArg(curMousePos.y));
mRightMouseDown = true;
}
void GuiScrollingBitmapCtrl::onRightMouseUp(const GuiEvent & event)
{
Con::executef(this, 1, "onRightMouseUp");
mRightMouseDown = false;
Parent::onRightMouseUp(event);
}
void GuiScrollingBitmapCtrl::onRightMouseDragged(const GuiEvent & event)
{
if (!mActive)
return;
if (!mRightMouseDown)
return;
Point2I deltaMousePosition = event.mousePoint - mMouseDownPosition;
Point2I curMousePos = globalToLocalCoord(event.mousePoint);
if (deltaMousePosition.x<0) mCurrXOffset = mCurrXOffset + 1;
if (deltaMousePosition.x>0) mCurrXOffset = mCurrXOffset - 1;
if (mCurrXOffset<0) mCurrXOffset = 0;
if (mCurrXOffset>1048) mCurrXOffset=1048;
if (deltaMousePosition.y<0) mCurrYOffset = mCurrYOffset + 1;
if (deltaMousePosition.y>0) mCurrYOffset = mCurrYOffset - 1;
if (mCurrYOffset<0) mCurrYOffset = 0;
if (mCurrYOffset>1048) mCurrYOffset=1048;
Con::executef(this, 3, "onRightMouseDragged",
Con::getIntArg(curMousePos.x),
Con::getIntArg(curMousePos.y));
}
void GuiScrollingBitmapCtrl::onMouseMove(const GuiEvent &event)
{
}
bool GuiScrollingBitmapCtrl::onMouseWheelUp(const GuiEvent &event)
{
mCurrYOffset -= 10;
if (mCurrYOffset<0) mCurrYOffset = 0;
return( true );
}
bool GuiScrollingBitmapCtrl::onMouseWheelDown(const GuiEvent &event)
{
mCurrYOffset += 10;
if (mCurrYOffset>1048) mCurrYOffset=1048;
return( true );
}The script code is :
//--- OBJECT WRITE BEGIN ---
new GuiControl(ScrollBitmapGui) {
canSaveDynamicFields = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "center";
VertSizing = "center";
Position = "0 0";
Extent = "1024 768";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
new GuiBitmapCtrl(BACKGROUND) {
canSaveDynamicFields = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "0 0";
Extent = "1024 768";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
bitmap = "./background.jpg";
wrap = "0";
new GuiScrollingBitmapCtrl(Map) {
canSaveDynamicFields = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "center";
VertSizing = "center";
Position = "12 16";
Extent = "1000 600";
MinExtent = "1000 600";
canSave = "1";
Visible = "1";
hovertime = "1000";
bitmap = "./themap.jpg"; // MAX DIM. => 2048 x 2048
wrap = "1";
};
new GuiButtonCtrl(BACKMENU) {
canSaveDynamicFields = "0";
Profile = "GuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "17 716";
Extent = "140 30";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "Canvas.popDialog(ScrollBitmapGui);";
hovertime = "1000";
text = "BACK";
groupNum = "-1";
buttonType = "PushButton";
};
};
};
//--- OBJECT WRITE END ---
function ScrollBitmapGui::onWake()
{
Map.setMapPos(524,524); // Set Initial Position of the map !!!
moveMap.pop();
}
function ScrollBitmapGui::onSleep(%this)
{
moveMap.push();
}
function Map::onMouseDown(%this, %MouseX, %MouseY, %width, %height)
{
echo("mouse X = " @ %MouseX);
echo("mouse Y = " @ %MouseY);
}
function Map::onMouseDragged(%this, %MouseX, %MouseY)
{
echo("mouse X" @ %MouseX);
echo("mouse Y" @ %MouseY);
}
function Map::onLeftMouseUp(%this)
{
}
function Map::onRightMouseDown(%this, %MouseX, %MouseY)
{
echo("mouse X" @ %MouseX);
echo("mouse Y" @ %MouseY);
Canvas.setCursor(MoveCursor);
}
function Map::onRightMouseDragged(%this, %MouseX, %MouseY)
{
echo("mouse X" @ %MouseX);
echo("mouse Y" @ %MouseY);
}
function Map::onRightMouseUp(%this)
{
Canvas.setCursor(DefaultCursor);
}My target is realize a new MapHud for strategic game.
Bye !!
^_^
#5
Indeed for TGEA is 1024x1024 I have converted the code for TGEA 1.7.0 :
the .H code :
The .CPP code :
And scripting :
That's all !!!
If anyone have ideas about eventual development write here ;-)
Bye
12/29/2008 (6:37 am)
Remember the limit of the bitmap on TGE is 2048X2048Indeed for TGEA is 1024x1024 I have converted the code for TGEA 1.7.0 :
the .H code :
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef _GUISCROLLINGBITMAPCTRL_H_
#define _GUISCROLLINGBITMAPCTRL_H_
#ifndef _GUICONTROL_H_
#include "gui/core/guiControl.h"
#endif
/// Renders a bitmap.
class GuiScrollingBitmapCtrl : public GuiControl
{
private:
typedef GuiControl Parent;
protected:
StringTableEntry mBitmapName;
GFXTexHandle mTextureHandle;
Point2I startPoint;
bool mWrap;
S32 mCurrXOffset;
S32 mCurrYOffset;
Point2I mMouseDownPosition;
bool mLeftMouseDown;
bool mRightMouseDown;
public:
//creation methods
DECLARE_CONOBJECT(GuiScrollingBitmapCtrl);
GuiScrollingBitmapCtrl();
static void initPersistFields();
//Parental methods
bool onWake();
void onSleep();
void inspectPostApply();
void setBitmap(const char *name,bool resize = false);
void setBitmap(GFXTexHandle &handle,bool resize = false);
void setMapPos(S32 x, S32 y);
void onMouseDown(const GuiEvent &);
void onMouseUp(const GuiEvent &event);
void onMouseDragged(const GuiEvent &event);
void onRightMouseDown(const GuiEvent &event);
void onRightMouseUp(const GuiEvent & event);
void onRightMouseDragged(const GuiEvent & event);
void onMouseMove(const GuiEvent &event);
bool onMouseWheelUp(const GuiEvent &event);
bool onMouseWheelDown(const GuiEvent &event);
void updateSizing();
void onRender(Point2I offset, const RectI &updateRect);
void setValue(S32 x, S32 y);
};
#endifThe .CPP code :
//-------------------------------------------------------------------------------------------------------------------------------//
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-------------------------------------------------------------------------------------------------------------------------------//
#include "console/console.h"
#include "console/consoleTypes.h"
#include "gfx/gfxDevice.h"
#include "gui/controls/guiScrollingBitmapCtrl.h"
IMPLEMENT_CONOBJECT(GuiScrollingBitmapCtrl);
GuiScrollingBitmapCtrl::GuiScrollingBitmapCtrl(void)
{
mBitmapName = StringTable->insert("");
startPoint.set(0, 0);
mWrap = false;
mCurrXOffset = 0;
mCurrYOffset = 0;
}
void GuiScrollingBitmapCtrl::initPersistFields()
{
Parent::initPersistFields();
addGroup("Misc"); // MM: Added Group Header.
addField("bitmap", TypeFilename, Offset(mBitmapName, GuiScrollingBitmapCtrl));
addField("wrap", TypeBool, Offset(mWrap, GuiScrollingBitmapCtrl));
endGroup("Misc"); // MM: Added Group Footer.
}
ConsoleMethod( GuiScrollingBitmapCtrl, setValue, void, 4, 4, "(int xAxis, int yAxis)"
"Set the offset of the bitmap.")
{
object->setValue(dAtoi(argv[2]), dAtoi(argv[3]));
}
ConsoleMethod( GuiScrollingBitmapCtrl, setBitmap, void, 3, 3, "(string filename)"
"Set the bitmap displayed in the control. Note that it is limited in size, to 256x256.")
{
object->setBitmap(argv[2]);
}
ConsoleMethod( GuiScrollingBitmapCtrl, setMapPos, void, 4, 4, "(int X, int Y)"
"Set offset of the bitmap viewed.")
{
object->setMapPos(dAtoi(argv[2]), dAtoi(argv[3]));
}
bool GuiScrollingBitmapCtrl::onWake()
{
if (! Parent::onWake())
return false;
setActive(true);
setBitmap(mBitmapName);
mCurrXOffset = 0;
mCurrYOffset = 0;
return true;
}
void GuiScrollingBitmapCtrl::onSleep()
{
mTextureHandle = NULL;
Parent::onSleep();
}
void GuiScrollingBitmapCtrl::inspectPostApply()
{
// if the extent is set to (0,0) in the gui editor and appy hit, this control will
// set it's extent to be exactly the size of the bitmap (if present)
Parent::inspectPostApply();
if (!mWrap && (getExtent().x == 0) && (getExtent().y == 0) && mTextureHandle)
{
setExtent( mTextureHandle->getWidth(), mTextureHandle->getHeight());
}
}
void GuiScrollingBitmapCtrl::updateSizing()
{
if(!getParent())
return;
// updates our bounds according to our horizSizing and verSizing rules
RectI fakeBounds( getPosition(), getParent()->getExtent());
parentResized( fakeBounds, fakeBounds);
}
void GuiScrollingBitmapCtrl::setBitmap(const char *name, bool resize)
{
mBitmapName = StringTable->insert(name);
if (*mBitmapName)
{
//mTextureHandle = TextureHandle(mBitmapName, BitmapTexture, true);
mTextureHandle.set(mBitmapName, &GFXDefaultGUIProfile);
// Resize the control to fit the bitmap
if( mTextureHandle && resize )
{
setExtent(mTextureHandle->getWidth(), mTextureHandle->getHeight());
updateSizing();
}
}
else
mTextureHandle = NULL;
setUpdate();
}
void GuiScrollingBitmapCtrl::setBitmap(GFXTexHandle &handle, bool resize)
{
mTextureHandle = handle;
// Resize the control to fit the bitmap
if (resize)
{
setExtent(mTextureHandle->getWidth(), mTextureHandle->getHeight());
updateSizing();
}
}
void GuiScrollingBitmapCtrl::onRender(Point2I offset, const RectI &updateRect)
{
GFXTextureObject* texture = mTextureHandle;
if (mTextureHandle)
{
GFX->getDrawUtil()->clearBitmapModulation();
if(mWrap)
{
RectI srcRegion;
RectI dstRegion;
float xdone = ((float)getExtent().x/(float)texture->mBitmapSize.x)+1;
float ydone = ((float)getExtent().y/(float)texture->mBitmapSize.y)+1;
int xshift = startPoint.x%texture->mBitmapSize.x;
int yshift = startPoint.y%texture->mBitmapSize.y;
xshift += mCurrXOffset;
yshift += mCurrYOffset;
for(int y = 0; y < ydone; ++y)
for(int x = 0; x < xdone; ++x)
{
srcRegion.set(0,0,texture->mBitmapSize.x,texture->mBitmapSize.y);
dstRegion.set( ((texture->mBitmapSize.x*x)+offset.x)-xshift,
((texture->mBitmapSize.y*y)+offset.y)-yshift,
texture->mBitmapSize.x,
texture->mBitmapSize.y);
GFX->getDrawUtil()->drawBitmapStretchSR(texture,dstRegion, srcRegion);
}
}
else
{
Point2I mTempOffset(0, 0);
mTempOffset.x += mCurrXOffset;
mTempOffset.y += mCurrYOffset;
RectI rect(mTempOffset, getExtent());
GFX->getDrawUtil()->drawBitmapStretch(mTextureHandle, rect);
}
}
if (mProfile->mBorder || !mTextureHandle)
{
RectI rect(offset.x, offset.y, getExtent().x, getExtent().y);
GFX->getDrawUtil()->drawRect(rect, mProfile->mBorderColor);
}
renderChildControls(offset, updateRect);
}
void GuiScrollingBitmapCtrl::setValue(S32 x, S32 y)
{
if (mTextureHandle)
{
x += mTextureHandle->getWidth() / 2;
y += mTextureHandle->getHeight() / 2;
}
while (x < 0)
x += 256;
startPoint.x = x % 256;
while (y < 0)
y += 256;
startPoint.y = y % 256;
}
void GuiScrollingBitmapCtrl::setMapPos(S32 x, S32 y)
{
mCurrXOffset = x;
mCurrYOffset = y;
}
void GuiScrollingBitmapCtrl::onMouseDown(const GuiEvent &event)
{
if (!mActive)
return;
Point2I curMousePos = globalToLocalCoord(event.mousePoint);
Con::executef(this, "onMouseDown",
Con::getIntArg(curMousePos.x),
Con::getIntArg(curMousePos.y));
mLeftMouseDown = true;
}
void GuiScrollingBitmapCtrl::onMouseUp(const GuiEvent &event)
{
mLeftMouseDown = false;
Parent::onMouseUp(event);
}
void GuiScrollingBitmapCtrl::onMouseDragged(const GuiEvent &event)
{
if (!mActive)
return;
if (!mLeftMouseDown)
return;
Point2I curMousePos = globalToLocalCoord(event.mousePoint);
Con::executef(this, "onMouseDragged",
Con::getIntArg(curMousePos.x),
Con::getIntArg(curMousePos.y));
}
void GuiScrollingBitmapCtrl::onRightMouseDown(const GuiEvent & event)
{
if (!mActive)
return;
mMouseDownPosition = event.mousePoint;
Point2I curMousePos = globalToLocalCoord(event.mousePoint);
Con::executef(this, "onRightMouseDown",
Con::getIntArg(curMousePos.x),
Con::getIntArg(curMousePos.y));
mRightMouseDown = true;
}
void GuiScrollingBitmapCtrl::onRightMouseUp(const GuiEvent & event)
{
Con::executef(this, "onRightMouseUp");
mRightMouseDown = false;
Parent::onRightMouseUp(event);
}
void GuiScrollingBitmapCtrl::onRightMouseDragged(const GuiEvent & event)
{
if (!mActive)
return;
if (!mRightMouseDown)
return;
Point2I deltaMousePosition = event.mousePoint - mMouseDownPosition;
Point2I curMousePos = globalToLocalCoord(event.mousePoint);
if (deltaMousePosition.x<0) mCurrXOffset = mCurrXOffset + 1;
if (deltaMousePosition.x>0) mCurrXOffset = mCurrXOffset - 1;
if (mCurrXOffset<0) mCurrXOffset = 0;
if (mCurrXOffset>224) mCurrXOffset=224;
if (deltaMousePosition.y<0) mCurrYOffset = mCurrYOffset + 1;
if (deltaMousePosition.y>0) mCurrYOffset = mCurrYOffset - 1;
if (mCurrYOffset<0) mCurrYOffset = 0;
if (mCurrYOffset>224) mCurrYOffset=224;
Con::executef(this, "onRightMouseDragged",
Con::getIntArg(curMousePos.x),
Con::getIntArg(curMousePos.y));
}
void GuiScrollingBitmapCtrl::onMouseMove(const GuiEvent &event)
{
}
bool GuiScrollingBitmapCtrl::onMouseWheelUp(const GuiEvent &event)
{
mCurrYOffset -= 10;
if (mCurrYOffset<0) mCurrYOffset = 0;
return( true );
}
bool GuiScrollingBitmapCtrl::onMouseWheelDown(const GuiEvent &event)
{
mCurrYOffset += 10;
if (mCurrYOffset>224) mCurrYOffset=224;
return( true );
}And scripting :
//--- OBJECT WRITE BEGIN ---
%guiContent = new GuiControl(ScrollBitmapGui) {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "1";
Profile = "GuiDefaultProfile";
HorizSizing = "center";
VertSizing = "center";
position = "0 0";
Extent = "1024 768";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
new GuiBitmapCtrl(BACKGROUND) {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 0";
Extent = "1024 768";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
bitmap = "scriptsAndAssets/client/ui/GarageGames.jpg";
wrap = "0";
new GuiScrollingBitmapCtrl(Map) {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "center";
VertSizing = "center";
position = "12 16";
Extent = "800 600";
MinExtent = "800 600";
canSave = "1";
Visible = "1";
hovertime = "1000";
bitmap = "scriptsAndAssets/client/ui/themap.jpg";
wrap = "1";
};
new GuiButtonCtrl(BACKMENU) {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "GuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "17 716";
Extent = "140 30";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "Canvas.popDialog(ScrollBitmapGui);";
hovertime = "1000";
text = "BACK";
groupNum = "-1";
buttonType = "PushButton";
useMouseEvents = "0";
};
};
};
//--- OBJECT WRITE END ---
function ScrollBitmapGui::onWake()
{
Map.setMapPos(124,124); // Set Initial Position of the map !!!
moveMap.pop();
}
function ScrollBitmapGui::onSleep(%this)
{
moveMap.push();
}
function Map::onMouseDown(%this, %MouseX, %MouseY, %width, %height)
{
echo("mouse X = " @ %MouseX);
echo("mouse Y = " @ %MouseY);
}
function Map::onMouseDragged(%this, %MouseX, %MouseY)
{
echo("mouse X" @ %MouseX);
echo("mouse Y" @ %MouseY);
}
function Map::onLeftMouseUp(%this)
{
}
function Map::onRightMouseDown(%this, %MouseX, %MouseY)
{
echo("mouse X" @ %MouseX);
echo("mouse Y" @ %MouseY);
Canvas.setCursor(MoveCursor);
}
function Map::onRightMouseDragged(%this, %MouseX, %MouseY)
{
echo("mouse X" @ %MouseX);
echo("mouse Y" @ %MouseY);
}
function Map::onRightMouseUp(%this)
{
Canvas.setCursor(DefaultCursor);
}That's all !!!
If anyone have ideas about eventual development write here ;-)
Bye

Torque Owner David Dougher
Pariah Games
I have a slightly different use for it though. Smoothly scrolling end credits when the game is over. Get your art team to make a long and very pretty looking screen credit roll and just run it in a window when your game is over.
You could do it with text scrolling but this seems like a much nicer solution.
Thanks for the resource!