IGUIScrollBar::updateAbsolutePosition() call problem

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
U238
Posts: 14
Joined: Mon Aug 17, 2009 1:01 pm
Location: Taganrog, Russia

IGUIScrollBar::updateAbsolutePosition() call problem

Post by U238 »

Hi all. I got such problem.
I make gui for my application and need to draw some progressbars (rectangles) on one window. And those rectangles can be so many that I added scroll bar to be able to scroll them vertically. For that I define class CMEGUIAbilitiesParams and adding it to GUI environment throuth my CMEGUIFactory factory class. Then outside beginScene()-endScene() i refresh the element setting its size and position and at last resize the window to fit around the element with IGUIElement::setRelativePosition(...); (1), which calls IGUIElement::updateAbsolutePosition() for window children but the last function does not calling for updateAbsolutePosition() for children though pass (2) string in IGUIElement.h :(
So CMEGUIAbilitiesParams::scrollBar does not update its clipping rectangle with scrollBar->updateAbsolutePosition(...); and this scrollBar clip rectangle stays in the value it got in the init funcion. So it doesn't be refreshed, is clipped and so isn't visible at the screen.

If you understand anything, please help me image CMEGUIAbilitiesParams::scrollBar :)

Here is some code :roll:

Code: Select all

// rectangle drawing control (GUI element) 
class CMEGUIAbilitiesParams : public IGUIElement
{
...
	IGUIScrollBar *scrollBar;
public:
...
	bool init(...);
	bool refresh();
	virtual void draw();	
};

// GUI element factory needing to create rectangle drawing element
class CMEGUIFactory : public IGUIElementFactory 
{
public:
	virtual IGUIElement* addGUIElement( const c8 *typeName, IGUIElement *parent = 0 );
	virtual IGUIElement *addGUIElement( EGUI_ELEMENT_TYPE type, IGUIElement *parent = 0 );
	virtual s32 getCreatableGUIElementTypeCount() const;
	virtual EGUI_ELEMENT_TYPE getCreateableGUIElementType ( s32 idx ) const;
	virtual const c8 *getCreateableGUIElementTypeName( EGUI_ELEMENT_TYPE type ) const;
	virtual const c8 *getCreateableGUIElementTypeName( s32 idx ) const;
};

// base app class
class CMapEditor
{
	// GUI elements enumeration
	enum EMapEditorMenuEntries
	{
		...
		ememe_abilitiesWindow,
		ememe_abilities_params,
		...
		ememe_count
	};
	IGUIElement *entries[ememe_count];	// all GUI elements
	// functions for easy access to a GUI elements
	IGUIWindow *windows( EMapEditorMenuEntries e ) { return (IGUIWindow *)entries[e]; }
	CMEGUIAbilitiesParams *abilitiesParams() { return (CMEGUIAbilitiesParams *)entries[ememe_abilities_params]; }
...
private:
...
	void refreshAbilitiesWindow();	// refresh window containng rectangle control
	friend class CMEGUIAbilitiesParams;

};

// creating all GUI
bool CMapEditor::init( IrrlichtDevice * device )
{
	...
	entries[ememe_abilitiesWindow] = guiEnv->addWindow( rect<s32>( d, 3*d, d + x[6] + d, headerHeight + 290 ), false, L"Abilities", 0, ememe_abilitiesWindow );
	entries[ememe_abilities_params] = factory->addGUIElement( EGUI_ELEMENT_TYPE( eguiae_abilitiesParams ), entries[ememe_abilitiesWindow] );
	entries[ememe_abilities_params]->setRelativePosition( rect<s32>( x[1], y, x[6], y + 3*d ) );
	if( !abilitiesParams()->init( pp, ap ) )
		return false;
	refreshNeeded = true;	// tell that we need to resize window containing rectangle control
}

// actions making outside beginScene()-endScene()
bool CMapEditor::step()
{
	if( refreshNeeded )
		refreshAbilitiesWindow();
	return true;
}
// long chain - sense is that ot init calls refresh at least
bool CMEGUIAbilitiesParams::init( ... )
{
	rect<s32> r = getRelativePosition();
	scrollBar = pp1.editor->guiEnv->addScrollBar( false, 
		rect<s32>( r.getWidth() - d, 0, r.getWidth(), r.getHeight() ), this, -1 );
	if( scrollBar == 0 )
		return false;
	return switchTo( ... );
}
bool CMEGUIAbilitiesParams::switchTo(...)
{
	...
	return refresh();
}
// rectangle element position refresh
bool CMEGUIAbilitiesParams::refresh()
{
...
	// position element
	setRelativePosition( rect<s32>( d, headerHeight + d, 
		d + ( columns - 1 )*pp.gapX4 + columns*slotWidth + 2*d,
		( seenRows - 1 )*pp.gapY4 + seenRows*slotHeight + headerHeight + d ) );
...

	// position scroll bar on the element
	rect<s32> r = getRelativePosition();
	scrollBar->setRelativePosition( rect<s32>( r.LowerRightCorner.X - d, r.UpperLeftCorner.Y,
		r.LowerRightCorner.X, r.LowerRightCorner.Y ) );

}

// refresh window containng rectangle control
void CMapEditor::refreshAbilitiesWindow()
{
	abilitiesParams()->refresh();
	rect<s32> r = abilitiesParams()->getRelativePosition();

	s32 width = r.getWidth();
	s32 height = r.getHeight();

	r = windows( ememe_abilitiesWindow )->getRelativePosition();
	// ******************* (1) ******************* //
	windows( ememe_abilitiesWindow )->setRelativePosition( rect<s32>(
		r.UpperLeftCorner.X, r.UpperLeftCorner.Y,
		r.UpperLeftCorner.X + max( x[6], d + width ) + d, r.UpperLeftCorner.Y + height + headerHeight + 8*d ) );
	refreshNeeded = false;
}

int main()
{
	...
	CMapEditor mapEditor.init( device );
	while( device->run() )
	{
		driver->beginScene( true, true, SColor( 255, 100, 100, 150 ) );
		scMgr->drawAll();
		guiEnv->drawAll();

		driver->endScene();
		imapEditor.step();
	}
	...
}

// ================ iGUIElement.h ===================
//! Base class of all GUI elements.
class IGUIElement : public virtual io::IAttributeExchangingObject, public IEventReceiver
{
...
	virtual void updateAbsolutePosition()
	{
		...
		// update all children
		core::list<IGUIElement*>::Iterator it = Children.begin();
		for (; it != Children.end(); ++it)
		{
			(*it)->updateAbsolutePosition();// *************** (2) **************
		}
	}
...
U238
Posts: 14
Joined: Mon Aug 17, 2009 1:01 pm
Location: Taganrog, Russia

Post by U238 »

Hmm... nobody answered yet. Maybe too large message. I tried to describe the problem detalliert...

The thing is that parent function IGUIElement::updateAbsolutePosition() doesn't call for children IGUIElement::updateAbsolutePosition() though children number is greater then 0 (==1).

May be somebody knows what is the reason?
I using 1.4.2 Irrlicht version.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Is updateAbsolutePosition called at all? Maybe your draw() method just resets the refreshNeeded variable and the step() does not update then. Try to single step through your code, or call step() before the render loop.
Post Reply