Re: TextArea GUI Element [v1.0]
Posted: Tue Jan 14, 2014 10:44 am
Fixed minor bug, thanks to Necris for reporting
Official forum of the Irrlicht Engine
https://irrlicht.sourceforge.io/forum/
Thanks for reporting the bug. Do you have some code to reproduce this bug easy?Dreadstew wrote:I get a bug when using your code.
If you enter lines that wrap scrolling no longer works properly. startIndex isn't large enough to deal with all the lines and when it changes from 1 to 0 and back to 1 instead of scrolling it jumps a lot of lines.
I don't think your variables startIndex or maxLines have the correct values when you enter text that wraps.
Your usage of lines.size() also causes issues because there are effectively more lines to scroll through when there is wrapped texts.
If you could fix it I would love you forever lol. I spent a whole night trying to fix it but I suck lol.
Code: Select all
#include <irrlicht.h>
#include "driverChoice.h"
#include <string>
#include "Line.h"
#include "TextArea.h"
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
using namespace std;
using namespace irr;
class MyEventReceiver : public IEventReceiver
{
public:
// We'll create a struct to record info on the mouse state
struct SMouseState
{
core::position2di Position;
bool LeftButtonDown;
bool RightButtonDown;
SMouseState()
{
LeftButtonDown = false;
RightButtonDown = false;
}
} MouseState;
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember the mouse state
if (event.EventType == irr::EET_MOUSE_INPUT_EVENT)
{
switch(event.MouseInput.Event)
{
case EMIE_LMOUSE_PRESSED_DOWN:
MouseState.LeftButtonDown = true;
break;
case EMIE_LMOUSE_LEFT_UP:
MouseState.LeftButtonDown = false;
break;
case EMIE_RMOUSE_PRESSED_DOWN:
MouseState.RightButtonDown = true;
break;
case EMIE_RMOUSE_LEFT_UP:
MouseState.RightButtonDown = false;
break;
case EMIE_MOUSE_MOVED:
MouseState.Position.X = event.MouseInput.X;
MouseState.Position.Y = event.MouseInput.Y;
break;
default:
// We won't use the wheel
break;
}
}
// Remember whether each key is down or up
// trigger pressed only once somehow
if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
if (!KeyIsDown[event.KeyInput.Key]) {
//key was released
KeyIsPressed[event.KeyInput.Key] = true;
}
}
// for chatbox scroll event
//if (event.EventType == EET_MOUSE_INPUT_EVENT && event.MouseInput.Event == EMIE_MOUSE_WHEEL) {
// mouseWheel += event.MouseInput.Wheel;
// mousePosition = core::position2di(event.MouseInput.X, event.MouseInput.Y);
//}
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
virtual bool IsKeyPressed(EKEY_CODE keyCode) const
{
return KeyIsPressed[keyCode];
}
virtual void resetKeyPressed(EKEY_CODE keyCode)
{
KeyIsPressed[keyCode] = false;
}
const SMouseState & GetMouseState(void) const
{
return MouseState;
}
//float getMouseWheel() {
// return mouseWheel;
//}
//void resetMouseWheel() {
// mouseWheel = 0;
//}
//core::position2di getMousePosition() {
// return mousePosition;
//}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsPressed[i] = false;
//mouseWheel = 0;
//mousePosition = core::position2di(0,0);
}
private:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
bool KeyIsPressed[KEY_KEY_CODES_COUNT];
//float mouseWheel;
core::position2di mousePosition;
};
int screenWidth = 640;
int screenHeight = 440;
int main()
{
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
cout << "couldn't do driver thing" << endl;
MyEventReceiver receiver;
IrrlichtDevice *device =
createDevice(driverType, core::dimension2d<u32>(screenWidth, screenHeight), 16, false, false, false, &receiver);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
gui::IGUIEnvironment* environment = device->getGUIEnvironment();
TextArea* textArea = new TextArea(environment, environment->getRootGUIElement());
textArea->setDimension(200,110);
textArea->setMaxLines(10);
textArea->setAlignment(TextArea::LEFT);
textArea->setPosition(core::vector2di(10,270));
textArea->drop();
//the code that fills the textArea with lines that get wrapped, which causes a scrolling bug
//when startIndex changes from 1 to 0 and back to 1, many lines are skipped past when scrolling
//startIndex range of values it can be doesn't seem to be big enough when there are wrapped lines
//startIndex range of values are controlled by variable maxLines and call to lines.size()
//there is no accounting for wrapped lines, which take multiple lines to display, in the calculation
for (int i = 0; i < 20; i++) {
string testline = "this is a test, this is a test, this is a test, this is a test, this is a test, this is a test, this is a test, this is a test, this is a test.";
testline += i;
Line* line = new Line();
line->addString(testline, video::SColor(255, 0, 0, 0));
textArea->addLine(line);
}
while ( device->run() )
{
driver->beginScene(true, true, 0);
smgr->drawAll();
environment->drawAll();
driver->endScene();
}
device->drop();
}
Code: Select all
TextArea* chatBox = new TextArea(env, m_wnd, m_irr_id);
Code: Select all
m_wnd = env->addWindow(...)