// CGUIexChatWindow.h
#ifndef ___CGUIEXCHATWINDOW_H
#define ___CGUIEXCHATWINDOW_H
/// Maximal lines of chat messages to keep in memory
#define CGUIEXCHATWINDOW_MAXLINES 5
#include <irrlicht.h>
#include <wchar.h>
namespace irr
{
namespace gui
{
// -------------------------------------------------
class CGUIexChatWindow : public irr::gui::IGUIElement
{
public:
CGUIexChatWindow(irr::gui::IGUIEnvironment *pGuiEnv,
irr::gui::IGUIFont *pFont,
irr::core::rect<irr::s32> rec);
~CGUIexChatWindow(void);
virtual bool OnEvent(irr::SEvent event);
void AddChatMessage(const wchar_t *text, irr::video::SColor color = irr::video::SColor(255,0,0,0));
void ScrollPosition(irr::s32 pixelLine);
private:
void Init(void);
void RecalculateScrollbar(void);
irr::gui::IGUIScrollBar *m_pScrollbar;
irr::core::array<irr::gui::IGUIStaticText*> m_aChatLines; // keeping the chat lines
irr::gui::IGUIStaticText *m_pDummyText; // just for the border
irr::gui::IGUIFont *m_pFont;
};
// -------------------------------------------------
} // namespace gui
} // namespace irr
#endif
///\file CGUIexChatWindow.cpp
/// Containing the CGUIexChatWindow class
///\class CGUIexChatWindow
/// Helper class for handling a chatbox with different line colors, scrolling and linebreaks.
/// Irrlicht addon class. Remember to use "new" and "delete" when creating or releasing an element of
/// this type. No add, no drop, no remove. Michael Koch 12/2005
/// Based on routines from CGUIexScrollWindow (which is itself based on CGUITextBox by MasterD)
#include "CGUIexChatWindow.h"
namespace irr
{
namespace gui
{
/// Constructor, setting itself as a child to the gui root element
// -------------------------------------------------
CGUIexChatWindow::CGUIexChatWindow(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_aChatLines.clear();
m_aChatLines.reallocate(CGUIEXCHATWINDOW_MAXLINES);
Init(); // Called once on creation
}
/// Destructor. The object is removing itself from the parent (the gui root element, that is)
// -------------------------------------------------
CGUIexChatWindow::~CGUIexChatWindow(void)
// -------------------------------------------------
{
Parent->removeChild(this);
}
/// Initializing internal elements.
// -------------------------------------------------
void CGUIexChatWindow::Init(void)
// -------------------------------------------------
{
m_pDummyText = Environment->addStaticText(L"",
irr::core::rect<irr::s32>(0, 0,
RelativeRect.getWidth(),
RelativeRect.getHeight()),
true, true, this, -1 , true);
m_pScrollbar = Environment->addScrollBar(false,
irr::core::rect<irr::s32>(RelativeRect.getWidth()-15,
0,
RelativeRect.getWidth(),
RelativeRect.getHeight()),
this);
}
/// Called if an event happened. Filter for our scrollbar
// -------------------------------------------------
bool CGUIexChatWindow::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 pixelLine = m_pScrollbar->getPos();
ScrollPosition(pixelLine); // Line is in pixels here
}
}
return true;
}
/// Adds a message to the chat window and checks for maximum lines reached. Takes care of scrolling.
// -------------------------------------------------
void CGUIexChatWindow::AddChatMessage(const wchar_t *text, video::SColor color)
// -------------------------------------------------
{
if (!wcslen(text)) return;
// set dimension to height of one line. will expand automatically when wordwrap happens
irr::core::rect<irr::s32> recBox(5, 0, RelativeRect.getWidth()-15, m_pFont->getDimension(L"G").Height);
irr::gui::IGUIStaticText *pLine = Environment->addStaticText(text, recBox, false, true, this, -1);
pLine->setOverrideColor(color);
m_aChatLines.push_back(pLine);
if (m_aChatLines.size()>CGUIEXCHATWINDOW_MAXLINES)
{
m_aChatLines[0]->remove();
m_aChatLines.erase(0);
}
RecalculateScrollbar();
}
/// Recalculates the range of the scrollbar, based on pixel height of all stored chatlines.
// -------------------------------------------------
void CGUIexChatWindow::RecalculateScrollbar(void)
// -------------------------------------------------
{
irr::s32 iPixelRows = 0;
for (irr::u32 i=0;i<m_aChatLines.size();i++)
{
iPixelRows += m_aChatLines[i]->getTextHeight();
}
m_pScrollbar->setMax(iPixelRows);
irr::s32 iFirstLine = RelativeRect.getHeight()-m_pFont->getDimension(L"G").Height;
if (iPixelRows > iFirstLine) ScrollPosition(iPixelRows-iFirstLine);
else ScrollPosition(0);
}
/// Scroll to a certain pixel line
// -------------------------------------------------
void CGUIexChatWindow::ScrollPosition(irr::s32 pixelLine)
// -------------------------------------------------
{
irr::s32 iSum = 0;
m_pScrollbar->setPos(pixelLine);
for (irr::u32 i=0;i<m_aChatLines.size();i++)
{
irr::u32 iSize = m_aChatLines[i]->getTextHeight();
iSum += iSize;
if (iSum < pixelLine) m_aChatLines[i]->setVisible(false);
else
{
m_aChatLines[i]->setVisible(true);
irr::core::rect<s32> pos;
pos = m_aChatLines[i]->getRelativePosition();
pos.UpperLeftCorner.Y = iSum - pixelLine - iSize;
pos.LowerRightCorner.Y = iSum - pixelLine;
m_aChatLines[i]->setRelativePosition(pos);
}
}
}
} // namespace gui
} // namespace irr