History: Scrolling Message
Source of version: 3 (current)
Copy to clipboard
{maketoc}
!!Introduction
This is a very simple class that was written in less than 2 hours but is very useful in providing a simple, cool effect. This class is inspired by another code snippet - ((Simple text)). So I took some of the code and merged it with my own and... tadaa... here we are!
The class basically will have 3 lines of messages which can be added by calling the ''addText()'' member function. So the old lines (the original line 1, 2 and 3) will be scrolled down and line 3 will be slowly faded out and new comes at the top. Of course you do not have to limit to 3 lines of messages - feel free to increase or decrease the number as the source code is extremely simple ;)
!!Usage
Firstly, you have to call ''init()'' prior to using the class. I didn't include it in the constructor because Ogre may not have been initialized yet.
And then in any of the FrameListener's ''frameStarted()'', call loop member function for example:
{CODE(wrap="1", colors="c++")}mScrollingMessage.loop(evt.timeSinceLastFrame);{CODE}
Since this is a singleton, you can call the class anywhere and add text to it, eg:
{CODE(wrap="1", colors="c++")}ScrollingMessage::getSingleton().addText("Hello Moto!");{CODE}
That's all about it.
__ScrollingMessage.h__
{CODE(wrap="1", colors="c++")}#pragma once
#include <Ogre.h>
class ScrollingMessage : public Ogre::Singleton<ScrollingMessage>
{
protected:
Ogre::OverlayContainer* mPanel;
Ogre::Overlay* mOverlay;
Ogre::OverlayElement* mTextBox[3];
Ogre::Real mTimeToGo;
bool mJustAdded;
// all are in pixel
enum { POSITION_TOP_X = 5, POSITION_TOP_Y = 30, SPACING = 30 };
public:
ScrollingMessage();
void init();
void addText(const Ogre::String& text);
void loop(Ogre::Real time);
};{CODE}
__ScrollingMessage.cpp__
{CODE(wrap="1", colors="c++")}#include "ScrollingMessage.h"
using namespace Ogre;
template<> ScrollingMessage* Singleton<ScrollingMessage>::ms_Singleton = 0;
ScrollingMessage::ScrollingMessage()
{
mTimeToGo = 0.0;
mJustAdded = false;
}
void ScrollingMessage::init()
{
mOverlay = OverlayManager::getSingleton().create("ScrollingOverlay");
mPanel = static_cast<OverlayContainer*>(OverlayManager::getSingleton().createOverlayElement("Panel", "container1"));
mPanel->setMetricsMode(GMM_PIXELS);
mPanel->setDimensions(800, 400);
mPanel->setPosition(5, 30);
// now create the text...
String name;
for (int i = 0; i < 3; ++i) {
name = "ScrollingMessage"+StringConverter::toString(i);
mTextBox[i] = OverlayManager::getSingleton().createOverlayElement("TextArea", name);
mTextBox[i]->setMetricsMode(Ogre::GMM_PIXELS);
mTextBox[i]->setDimensions(20, 5);
mTextBox[i]->setWidth(20);
mTextBox[i]->setHeight(5);
mTextBox[i]->setPosition(POSITION_TOP_X, POSITION_TOP_Y+i*SPACING);
mTextBox[i]->setParameter("font_name", "StarWars");
mTextBox[i]->setParameter("char_height", "16");
mTextBox[i]->setColour(ColourValue::White);
mTextBox[i]->setCaption(" ");
mPanel->addChild(mTextBox[i]);
}
mOverlay->add2D(mPanel);
mOverlay->show();
}
void ScrollingMessage::addText(const String& text)
{
// first swap the content...
mTextBox[2]->setCaption(mTextBox[1]->getCaption());
mTextBox[1]->setCaption(mTextBox[0]->getCaption());
mTextBox[0]->setCaption(text);
// but hide the first textbox first...
mTextBox[0]->hide();
// and move the others to upper coordinate...
mTextBox[1]->setPosition(POSITION_TOP_X, POSITION_TOP_Y);
mTextBox[2]->setPosition(POSITION_TOP_X, POSITION_TOP_Y+SPACING);
mTimeToGo = 1.5; // 1.5 seconds...
mJustAdded = true;
}
void ScrollingMessage::loop(Real time)
{
if (mJustAdded) {
mTimeToGo -= time;
if (mTimeToGo <= 1.0)
mTextBox[0]->show();
if (mTimeToGo < 1e-3) {
mTimeToGo = 0.0;
mJustAdded = false;
}
// scroll the textbox by this much..
Real progress = (1.5-mTimeToGo)/1.5;
Real y = POSITION_TOP_Y+SPACING*progress;
mTextBox[1]->setPosition(POSITION_TOP_X, y);
mTextBox[1]->setColour(ColourValue(1,1,1,1.0-progress/4));
mTextBox[2]->setPosition(POSITION_TOP_X, y+SPACING);
mTextBox[2]->setColour(ColourValue(1,1,1,1.0-progress*progress));
}
}{CODE}