| |
|
|
Irrlicht Extension Class: CGUIexScrollWindow -- Section: Irrlicht --
Irrlicht - a 3D Engine
Irrlicht is made by Nikolaus Gebhardt (niko). It is free, cross-platform and open source.
http://irrlicht.sourceforge.net/
http://www.irrlicht3d.org/
It is said that Irrlicht can't easily be extended with own features (like, e.g. a window with a scroll bar - which is currently not within the standard functionality). This is not true, though.
Of course, as it is open source, one could fiddle with the engine code itself. Nothing wrong
with that. As soon as a new version of the engine is out, you'd probably have to re-do all your
personal changes. Although this is feasable, it isn't the way to go for me (being a lazy butt).
From the irrlicht forum and the nice CGUITextBox tutorial by MasterD I got another way of adding functionality to Irrlicht - without padding and recompiling the source.
The key is to derive an element (here: an GUI element) from an already existing one, add own things, then make it adding itself to the Irrlicht gui environment. The only drawback I found so far is that one can't use the engine's built in functions like irr::gui::IGUIEnvironment->irr::gui::IGUIEnvironment::addWindow and (object)->drop for creation/deletion. New and delete must be used instead.
The class presented here (CGUIexScrollWindow) was created while parsing through the above
mentioned CGUITextBox code, trying to understand what is happening there. While on it, I removed some features I didn't need and rewrote some code - just to do it my own way.
The scrollable window can be placed on the screen, stuffed with text, and will take care of user-invoked scrolling. Well, thats it. Code tested with Irrlicht 0.14.0.
How would the class be used?
First, add the source code (.h/.cpp) listed below to your project. Then, add a pointer to a CGUIexScrollWindow object to your code. Finally, create the ScrollWindow object with the new parameter, passing some basics to the constructor. When you are done, remove the ScrollWindow using delete. Like so (where pGUIEnv points to the Irrlicht GUI environment, and pFont to a font of your choice):
irr::gui::CGUIexScrollWindow *m_pHelpTextBox = NULL;
...
irr::core::rect<irr::s32> rDim(0,0,200,100);
m_pHelpTextBox = new irr::gui::CGUIexScrollWindow(pGUIEnv,pFont,rDim);
...do stuff, until the ScrollWindow isn't needed anymore...
delete(m_pHelpTextBox);
m_pHelpTextBox = NULL;
|
This new "GUI object" behaves just like the others (which are "built in"). And no need to tweak the engine source. You may want to use this - very basic - implementation to e.g. show a help screen with scrollable text. For more features, check the above mentioned CGUITextBox class.
// CGUIexScrollWindow.h
#ifndef ___CGUIEXSCROLLWINDOW_H
#define ___CGUIEXSCROLLWINDOW_H
#include <irrlicht.h>
#include <wchar.h>
namespace irr
{
namespace gui
{
// ------------------------------------------------------------------------------------------------
class CGUIexScrollWindow : public irr::gui::IGUIElement
{
public:
CGUIexScrollWindow(irr::gui::IGUIEnvironment *pGuiEnv,
irr::gui::IGUIFont *pFont,
irr::core::rect<irr::s32> rec);
~CGUIexScrollWindow();
virtual bool OnEvent(irr::SEvent event);
virtual void setText(const wchar_t* pText);
private:
void setVisibleText(irr::s32 iStartLine);
void Init(void);
irr::gui::IGUIScrollBar * m_pScrollbar;
irr::gui::IGUIStaticText * m_pStaticText; // keeping the text
irr::gui::IGUIStaticText * m_pDummyText; // just for the border
irr::gui::IGUIFont *m_pFont;
};
// ------------------------------------------------------------------------------------------------
} // namespace gui
} // namespace irr
#endif
|
///\file CGUIexScrollWindow.cpp
/// Containing the CGUIexScrollWindow class
///\class CGUIexScrollWindow
/// Helper class for a window with scroll bar. Based on http://www.irrforge.org/index.php/CGUITextBox .
/// Kudos to MasterD.
/// Irrlicht extension class. Remember to use "new" and "delete" when creating or releasing an element of
/// this type. No add, no drop, no remove. 12/2005 Michael Koch
#include "CGUIexScrollWindow.h"
namespace irr
{
namespace gui
{
/// Constructor, setting itself as a child to the gui root element
// ------------------------------------------------------------------------------------------------
CGUIexScrollWindow::CGUIexScrollWindow(irr::gui::IGUIEnvironment *pGuiEnv,
irr::gui::IGUIFont *pFont,
irr::core::rect<irr::s32> rec)
: IGUIElement(irr::gui::EGUIET_ELEMENT, pGuiEnv,
pGuiEnv->getRootGUIElement(), -1, rec)
// ------------------------------------------------------------------------------------------------
{
m_pFont = pFont;
m_pScrollbar = NULL;
m_pDummyText = NULL;
m_pStaticText = NULL;
Init(); // Called once on creation
}
/// Initializing internal elements.
// ------------------------------------------------------------------------------------------------
void CGUIexScrollWindow::Init(void)
// ------------------------------------------------------------------------------------------------
{
m_pDummyText = Environment->addStaticText(L"",
irr::core::rect<irr::s32>(0, 0,
RelativeRect.getWidth(),
RelativeRect.getHeight()),
true, true, this, -1 , true);
m_pStaticText = Environment->addStaticText(L"",
irr::core::rect<irr::s32>(5, 5,
RelativeRect.getWidth()-15-5,
RelativeRect.getHeight()-5),
false, true, this);
m_pScrollbar = Environment->addScrollBar(false,
irr::core::rect<irr::s32>(RelativeRect.getWidth()-15,
0,
RelativeRect.getWidth(),
RelativeRect.getHeight()),
this);
m_pStaticText->setOverrideFont(m_pFont);
setText(Text.c_str());
}
/// Destructor. The object is removing itself from the parent (the gui root element, that is)
// ------------------------------------------------------------------------------------------------
CGUIexScrollWindow::~CGUIexScrollWindow()
// ------------------------------------------------------------------------------------------------
{
Parent->removeChild(this);
}
/// Called if an event happened. Filter for our scrollbar
// ------------------------------------------------------------------------------------------------
bool CGUIexScrollWindow::OnEvent(irr::SEvent event)
// ------------------------------------------------------------------------------------------------
{
Parent->OnEvent(event);
if(event.EventType == EET_GUI_EVENT && event.GUIEvent.EventType == EGET_SCROLL_BAR_CHANGED)
{
IGUIScrollBar *bar = static_cast <irr::gui::IGUIScrollBar*> (event.GUIEvent.Caller);
if(bar == m_pScrollbar)
{
irr::s32 line = m_pScrollbar->getPos();
setVisibleText(line); // Line is in pixels here
}
}
return true;
}
/// Set new text to the window and calculate new scrollbar range (in pixels)
// ------------------------------------------------------------------------------------------------
void CGUIexScrollWindow::setText(const wchar_t* pText)
// ------------------------------------------------------------------------------------------------
{
m_pStaticText->setText(pText);
m_pScrollbar->setMax(m_pStaticText->getTextHeight() - m_pScrollbar->getRelativePosition().getHeight());
m_pScrollbar->setPos(0);
setVisibleText(0);
}
/// Called when scrolling applies
// ------------------------------------------------------------------------------------------------
void CGUIexScrollWindow::setVisibleText(irr::s32 iStartLine)
// ------------------------------------------------------------------------------------------------
{
// startLine is given in pixels
irr::core::rect<irr::s32> dim1 = m_pStaticText->getRelativePosition();
irr::core::rect<irr::s32> dim2(dim1.UpperLeftCorner.X,
- iStartLine,
dim1.LowerRightCorner.X,
m_pStaticText->getTextHeight() - iStartLine);
m_pStaticText->setRelativePosition(dim2);
}
} // namespace gui
} // namespace irr
|
|
|
|
|
|