Adding a scrollbar in a list box
Adding a scrollbar in a list box
I know that when there are more and more items (texts) in the list box, the scroll bar will appear.
But, if I add a large button in the list box, there will be no scroll bar.
How can I add a scrollbar in a list box and hardcode its height?
Which API should I use?
But, if I add a large button in the list box, there will be no scroll bar.
How can I add a scrollbar in a list box and hardcode its height?
Which API should I use?
Currently you can't force it to be there. The corresponding calculation is happening in CGUIListBox::recalculateItemHeight().
So easiest solution might be to copy that code, rename the class, change it in that copy and then add your own listbox element.
So easiest solution might be to copy that code, rename the class, change it in that copy and then add your own listbox element.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Do you mean I should change CGUIListBox to IGUIListBox?
So, after I change that, where should I paste to? I cannot find IGUIListBox.cpp
Also, after pasting the code to a correct place, how can I use that API to make the scroll bar appear where the list box has a large button?
Code: Select all
void CGUIListBox::recalculateItemHeight()
{
IGUISkin* skin = Environment->getSkin();
if (Font != skin->getFont())
{
if (Font)
Font->drop();
Font = skin->getFont();
if ( 0 == ItemHeightOverride )
ItemHeight = 0;
if (Font)
{
if ( 0 == ItemHeightOverride )
ItemHeight = Font->getDimension(L"A").Height + 4;
Font->grab();
}
}
TotalItemHeight = ItemHeight * Items.size();
ScrollBar->setMax(TotalItemHeight - AbsoluteRect.getHeight());
s32 minItemHeight = ItemHeight > 0 ? ItemHeight : 1;
ScrollBar->setSmallStep ( minItemHeight );
ScrollBar->setLargeStep ( 2*minItemHeight );
if ( TotalItemHeight <= AbsoluteRect.getHeight() )
ScrollBar->setVisible(false);
else
ScrollBar->setVisible(true);
}
Also, after pasting the code to a correct place, how can I use that API to make the scroll bar appear where the list box has a large button?
No, I mean you make an own class out of it. Whatever the name (MyCGUIListBox for example).
And that could look identical otherwise except that ScrollBar->setVisible would always be set to true for example.
So the idea is: Create your own class (in your own project). As basis to make it easier copy over the Irrlicht-class which does already nearly everything you need (except for example different scrollbar behaviour).
Read the code, understand what it does and then add your own changes.
I must admit I don't really get what you mean with "adding a large Button to a listbox". If you want to add it _in_ the element then you have to code it in your own element. But I have no idea for what you would want a button in a listbox.
And that could look identical otherwise except that ScrollBar->setVisible would always be set to true for example.
So the idea is: Create your own class (in your own project). As basis to make it easier copy over the Irrlicht-class which does already nearly everything you need (except for example different scrollbar behaviour).
Read the code, understand what it does and then add your own changes.
I must admit I don't really get what you mean with "adding a large Button to a listbox". If you want to add it _in_ the element then you have to code it in your own element. But I have no idea for what you would want a button in a listbox.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Sorry, I still don't get what a button has to do with a listbox. A listbox contains text not buttons - I just don't get the connection here. Or are you talking about clipping and the listbox is the parent of the button? Maybe tell what you are trying to do. Could be there is a better way to do it once I get what this is about.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Hm, I understand. And no - using a listbox for that is probably not such a good idea. A list box is really there for text and maybe some icons.
This would be a new gui-element. I have no such element, but maybe it could be written the following way: Your gui-element would contain 2 major subElements. An IGUIStaticText (without border, without text and without background drawing - so it would be invisible) and a IGUIScrollBar. All buttons would be placed on the IGUIStaticText, so they are childs of that. Then if you move the scrollbar the position of the IGUIStatictext should be updated. You can catch the scrollbar-events in the OnEvent function of your gui-element. As the invisible statictext is clipped automatically by the parent (the element itself) you would only see buttons which are within the size of your gui-element.
This might sound a little complicated to you at first - but it's something I'm sure you can manage when you put a little work into it. You start by deriving your class from IGUIElement. You might take a look at the code of the checkboxclass in the other thread as example which also just is a new gui-element. You can also look into the listbox implementation how it's done there. And once you know how to write own gui-elements you are getting a lot more flexible in what you can do in your game.
Just ask when you get stuck - we can help you with your first gui-element :-)
This would be a new gui-element. I have no such element, but maybe it could be written the following way: Your gui-element would contain 2 major subElements. An IGUIStaticText (without border, without text and without background drawing - so it would be invisible) and a IGUIScrollBar. All buttons would be placed on the IGUIStaticText, so they are childs of that. Then if you move the scrollbar the position of the IGUIStatictext should be updated. You can catch the scrollbar-events in the OnEvent function of your gui-element. As the invisible statictext is clipped automatically by the parent (the element itself) you would only see buttons which are within the size of your gui-element.
This might sound a little complicated to you at first - but it's something I'm sure you can manage when you put a little work into it. You start by deriving your class from IGUIElement. You might take a look at the code of the checkboxclass in the other thread as example which also just is a new gui-element. You can also look into the listbox implementation how it's done there. And once you know how to write own gui-elements you are getting a lot more flexible in what you can do in your game.
Just ask when you get stuck - we can help you with your first gui-element :-)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
OK.
You mean I should attach a scrollbar to a static text field.
But I don't know how to change the visible region of IGUIStaticText triggered by an event.
E.g. to make things simpler, press down arrow key to move the visible region downward instead of using scrollbar. Can I do this?
Could you give me some hints?
You mean I should attach a scrollbar to a static text field.
But I don't know how to change the visible region of IGUIStaticText triggered by an event.
E.g. to make things simpler, press down arrow key to move the visible region downward instead of using scrollbar. Can I do this?
Could you give me some hints?
No, I don't mean that. I mean you should write your own gui-element and attach a statictext + a scrollbar to that. Structure would approximately like that:wsw1231 wrote:OK.
You mean I should attach a scrollbar to a static text field.
Code: Select all
CMyScrollingArea : public irr::gui::IGUIElement
{
virtual bool OnEvent (const SEvent &event);
irr::gui::IGUIScrollBar * myScrollBar;
irr::gui::IGUIStaticText * myBackGround;
};
And to catch the scrolling events your CMyScrollingArea class can override OnEvent and handle the events there. If you want to use keyboard-buttons instead - they are handled very similar. Also catch the button-events in the OnEvent of CMyScrollingArea and set the position of myBackGround correspondingly.
Note that as mention in the last post you can set myBackGround to values which make it completely invisible - it is just a container to move your buttons easier. Alternatively you could work completely without that statictext and instead keep all your buttons in an array and move all button positions whenever you want to scroll. Which solution you prefer is up to you.
Just moving the buttons might even be better, so alternatively your class could look like this:
Code: Select all
CMyScrollingArea : public irr::gui::IGUIElement
{
virtual bool OnEvent (const SEvent &event);
irr::gui::IGUIScrollBar * myScrollBar;
irr::core::array<IGUIButton*> myButtons;
};
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Thanks for your advice.CuteAlien wrote:No, I don't mean that. I mean you should write your own gui-element and attach a statictext + a scrollbar to that. Structure would approximately like that:wsw1231 wrote:OK.
You mean I should attach a scrollbar to a static text field.
All your buttons would be added to myBackGround (which should be sufficiently large). And because myBackGround is automatically clipped to it's parent (CMyScrollingArea) all you have to do on scrolling-events is to change the position of myBackGround.Code: Select all
CMyScrollingArea : public irr::gui::IGUIElement { virtual bool OnEvent (const SEvent &event); irr::gui::IGUIScrollBar * myScrollBar; irr::gui::IGUIStaticText * myBackGround; };
And to catch the scrolling events your CMyScrollingArea class can override OnEvent and handle the events there. If you want to use keyboard-buttons instead - they are handled very similar. Also catch the button-events in the OnEvent of CMyScrollingArea and set the position of myBackGround correspondingly.
Note that as mention in the last post you can set myBackGround to values which make it completely invisible - it is just a container to move your buttons easier. Alternatively you could work completely without that statictext and instead keep all your buttons in an array and move all button positions whenever you want to scroll. Which solution you prefer is up to you.
Just moving the buttons might even be better, so alternatively your class could look like this:
Please try to write the code to actually move the buttons yourself.Code: Select all
CMyScrollingArea : public irr::gui::IGUIElement { virtual bool OnEvent (const SEvent &event); irr::gui::IGUIScrollBar * myScrollBar; irr::core::array<IGUIButton*> myButtons; };
But I think the first approach may be more suitable in my case because I want to make the buttons clipped if they are outside of the "area" (i.e. IGUIStaticText)
You mention that I should change the position of the IGUIStaticText.
Do you mean
Code: Select all
IGUIStaticText * text = guienv->addStaticText(L"",
rect<s32>(10,10,50,50), true);
IGUIButton* button = guienv->addButton(rect<s32>(100,100,130,130), text, -1, L"hahaha");
text->setRelativePosition(core::rect<s32>(20,20,140,140));
So, which API should I use to change the position of IGUIStaticText (i.e. visible region instead of the whole rectangle) while keeping that of the button unchanged?
Well, you need to change both... how would you scroll buttons otherwise if they would stay on their place? If you want another button on the same place as an old button before scrolling (I think you talk about that - correct me if I guessed wrong), then move by the size of the gap between your buttons.wsw1231 wrote: Both the positions of the IGUIStaticText and button will be changed if I use the above code.
So, which API should I use to change the position of IGUIStaticText (i.e. visible region instead of the whole rectangle) while keeping that of the button unchanged?
And clipping would work in both solutions. Because childs are clipped against your gui-element.
edit: It won't work that way without an own gui-element! Start with that.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
........
My idea is as follows:
You can image that the black box is the IGUIStaticText and the red box is the button. The above picture shows that the button is outside of the IGUIStaticText, which means it is clipped.
Now, what I want to do is to change the visible region of IGUIStaticText so that I can see the red box in the black box.
However, what
does is that the whole IGUIStaticText position will change and since the button is the child of it, so it will also be changed.
This is NOT what I want.
I just want to visible region to be changed only but it seems there is no API to do so
My idea is as follows:
You can image that the black box is the IGUIStaticText and the red box is the button. The above picture shows that the button is outside of the IGUIStaticText, which means it is clipped.
Now, what I want to do is to change the visible region of IGUIStaticText so that I can see the red box in the black box.
However, what
Code: Select all
text->setRelativePosition(core::rect<s32>(20,20,140,140));
This is NOT what I want.
I just want to visible region to be changed only but it seems there is no API to do so
As I wrote - you need an own gui-element. I can only repeat that. Then you have 2(!) areas. One (invisible) to move and one for clipping. Although you could fake it with 2 statictexts above each other as well (but that's just more work in the long run - create an own gui-element, that will get simpler, cleaner and more flexible).
You might notice that in your shot you actually moved the red marker. Which means - you moved the button into the non-clipped area (the behind a second static-text is simply that you can easy move more than one button at a time, you don't really need it as my second solution showed).
You might notice that in your shot you actually moved the red marker. Which means - you moved the button into the non-clipped area (the behind a second static-text is simply that you can easy move more than one button at a time, you don't really need it as my second solution showed).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code: Select all
CMyScrollingArea : public irr::gui::IGUIElement
{
virtual bool OnEvent (const SEvent &event);
irr::gui::IGUIScrollBar * myScrollBar;
irr::core::array<IGUIButton*> myButtons;
};
If so, I think I get what you mean now.