Page 1 of 2
[Solved] Itemlist box help
Posted: Fri Aug 22, 2008 11:46
by Ninja
Hi Guys
on my main ui screen i have a image button that i would like users to be able to change sort of like an avatar kind of thing anyways when you press the button a list box appears and is filled in with image names available from a imageset like so
Code: Select all
bool myUI::PicSelect( const CEGUI::EventArgs& e)
{
using namespace CEGUI;
WindowManager& winMgr = WindowManager::getSingleton();
if (!winMgr.isWindowPresent("picselectwindow"))
Window* setup = winMgr.loadWindowLayout("picselect.layout");
ItemListbox* Pic_names = static_cast<ItemListbox*>(
winMgr.getWindow( "Pic_names"));
// get ptr to named imageset - don't forget this throws if imageset is not present
Imageset* imageset = ImagesetManager::getSingleton().getImageset( "pic" );
// get iterator to iterate over defined images.
Imageset::ImageIterator iter = imageset->getIterator();
while ( !iter.isAtEnd() )
{
// create new list item
ItemEntry* list_item = static_cast<ItemEntry*>(
WindowManager::getSingleton().createWindow( "TaharezLook/ListboxItem" ));
// set text on this item to whatever name the image has
list_item->setText( (*iter).getName() );
// add this item to the listbox
Pic_names->addChildWindow( list_item );
// advance iterator
++iter;
}
WindowManager::getSingleton().getWindow("Pic_cancel")->
subscribeEvent(PushButton::EventClicked, Event::Subscriber(&myUI::PicCancel, this));
WindowManager::getSingleton().getWindow("Pilot_OK")->
subscribeEvent(PushButton::EventClicked, Event::Subscriber(&myUI::PicOK, this));
WindowManager::getSingleton().getWindow("picselectwindow")->
subscribeEvent(FrameWindow::EventCloseClicked,
Event::Subscriber(&myUI::CloseWindowButton, this));
if (winMgr.isWindowPresent("background_wnd"))
{
Window* background = winMgr.getWindow("background_wnd");
background->addChildWindow("picselectwindow");
}
// event was handled
return true;
}
this works ok in the sense that it populates the listbox with the image names but i cant seem to find out how to change the image ie i can hightlight the image name i would like but the code that i need for the PicOK button i cant seem to work out
Code: Select all
bool myUI::PicOK(const CEGUI::EventArgs& e)
{
// code goes here from picOK button
return true;
}
could some kind soul point me in the right direction please
TIA
Posted: Mon Aug 25, 2008 02:10
by earthsruler
I don't have much time so ill be brief.
it sound like in the 'OK' callback you want to change the buttons image.
try:
Code: Select all
CEGUI::Window* imageButton = CEGUI::WindowManager::getSingleton().getwindow("myImageButtonName");
imageButton.setProperty("Image", "set: image:" );
set is the image set name
image is the name of the image in the image set you want so if you wanted to do it for an imageset named "IconSet" and the image "FileIcon" it would look like:
Code: Select all
imageButton.setProperty("Image", "set:IconSet image:FileIcon" );
Some more Properties can be found here:
http://www.cegui.org.uk/wiki/index.php/SetProperty
Best Link Ever.
HTH
ER.
Posted: Mon Aug 25, 2008 13:30
by daves
yep earthruler has posted the basic call that you need. Of course you need to ensure that this is performed on a window for which the "Image" is a valid property. There are several such window types. You should be able to browse down the list of window types that earthruler has provided and try a few (e.g. StaticImage). You'll see the properties that apply to that window type.
Posted: Tue Aug 26, 2008 14:14
by Ninja
Hi Guys
Thanks very much for your answers so far
i know have
Code: Select all
bool myUI::PicOK(const CEGUI::EventArgs& e)
{
CEGUI::Window* imageButton = CEGUI::WindowManager::getSingleton().getWindow("pic_field");
imageButton->setProperty("NormalImage", "set:pic image:01" );
//now we chose an image close the image select window
CEGUI::WindowManager::getSingleton().destroyWindow( "pilotselectwindow" );
return true;
}
and this does set the image to 01 as its supposed to however what i need is for the images that have been populated into the list box by this part
Code: Select all
ItemListbox* Pic_names = static_cast<ItemListbox*>(
winMgr.getWindow( "Pic_names"));
// get ptr to named imageset - don't forget this throws if imageset is not present
Imageset* imageset = ImagesetManager::getSingleton().getImageset( "pic" );
// get iterator to iterate over defined images.
Imageset::ImageIterator iter = imageset->getIterator();
while ( !iter.isAtEnd() )
{
// create new list item
ItemEntry* list_item = static_cast<ItemEntry*>(
WindowManager::getSingleton().createWindow( "TaharezLook/ListboxItem" ));
// set text on this item to whatever name the image has
list_item->setText( (*iter).getName() );
// add this item to the listbox
Pic_names->addChildWindow( list_item );
// advance iterator
++iter;
}
so for example in the list box there would be 01,02 etc,etc name of the images that are stored in the imageset i tried in the picok function this
Code: Select all
bool myUI::PicOK(const CEGUI::EventArgs& e)
{
using namespace CEGUI;
WindowManager& winMgr = WindowManager::getSingleton();
ItemListbox* Pic_names = static_cast<ItemListbox*>(
winMgr.getWindow( "Pic_names"));
// get ptr to named imageset - don't forget this throws if imageset is not present
Imageset* imageset = ImagesetManager::getSingleton().getImageset( "pic" );
// get iterator to iterate over defined images.
Imageset::ImageIterator iter = imageset->getIterator();
while ( !iter.isAtEnd() )
{
// create new list item
ItemEntry* list_item = static_cast<ItemEntry*>(
WindowManager::getSingleton().createWindow( "TaharezLook/ListboxItem" ));
// set text on this item to whatever name the image has
list_item->setText( (*iter).getName() );
// add this item to the listbox
Pic_names->addChildWindow( list_item );
CEGUI::Window* imageButton = CEGUI::WindowManager::getSingleton().getWindow("pic_field");
imageButton->setProperty("NormalImage", (*iter).getName() );
// advance iterator
++iter;
}
//now we chose an image close the image select window
CEGUI::WindowManager::getSingleton().destroyWindow( "pilotselectwindow" );
return true;
}
but in the cegui.log it sayed
ImagesetManager::getImageset - No Imageset named 'ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̅¸0Ù' is present in the system.
TIA
Posted: Tue Aug 26, 2008 16:26
by daves
A couple things come to mind:
1] Did you define the imageset "pic" in your "scheme" file? Imagesets can be defined as part of your "scheme" and loaded on startup. They can also be created dynamically. Which are you doing?
2] The log message looks like its printing out garbage. Perform some of the basic debug tasks that allow you to isolate the line of appliication code that results in this cegui log error message (there are only a couple places within your code that could be at the source of this - e.g. getImageset). Step through your code, comment out sections of your code, isolate down to the "culprit line" within your own code. This will be a good learning process for you.
3] You dont check the return from Imageset* imageset = ImagesetManager::getSingleton().getImageset( "pic" ); Nor do you have this embedded within a try/catch block. How do you know that it is finding your imageset named "pic"?
To the extent that you compile CEGUI from source then If you step through your code then that gives you additional debug capabilities.
Scheme file example (notiice "pic" and "pic.imageset"):
Code: Select all
<GUIScheme Name="SVTLookSkin">
<Imageset Name="SVTLook" Filename="SVTLook.imageset" />
<Imageset Name="pic" Filename="pic.imageset" />
Sample pic.imageset
Code: Select all
<?xml version="1.0" ?>
<Imageset Name="pic" Imagefile="pic.png" NativeHorzRes="512" NativeVertRes="512" AutoScaled="true">
<Image Name="StatusIndicator" XPos="82" YPos="86" Width="20" Height="20" />
<Image Name="Image2" XPos="22" YPos="86" Width="20" Height="20" />
</Imageset>
Posted: Tue Aug 26, 2008 16:53
by Ninja
HI Daves
the imageset i'am calling is a diffrent one to the main one i set in the resource groups section and no i didnt do it like you sayed above should I ?
and my imageset file looks like
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<Imageset Name="pic" Imagefile="pic.tga" NativeHorzRes="1024" NativeVertRes="768" AutoScaled="true" >
<Image Name="Default" XPos="15" YPos="12" Width="96" Height="96" />
<Image Name="01" XPos="122" YPos="12" Width="96" Height="96" />
<Image Name="02" XPos="232" YPos="12" Width="96" Height="96" />
<Image Name="03" XPos="343" YPos="12" Width="96" Height="96" />
<Image Name="04" XPos="453" YPos="12" Width="96" Height="96" />
</Imageset>
the Names all get populated fine in the listbox i think it has something to do with this part
Code: Select all
CEGUI::Window* imageButton = CEGUI::WindowManager::getSingleton().getWindow("pic_field");
imageButton->setProperty("NormalImage", (*iter).getName() );
as the (*iter).getName() dosnt actually set the imageset and the name that i choose in the listbox thats what i have put it down to so far anyways
but i'am unsure what i should put in there i tried a few variations and such but no joy
TIA
Posted: Tue Aug 26, 2008 17:37
by daves
Make sure that this is really returning what you think:
Create a local string and copy that value into the string...
The image property you are trying to set should evaluate to something of the following form:
My guess is that it doesn't and that would explain the garbage you see in the log.
Posted: Wed Aug 27, 2008 21:56
by Ninja
Hi Daves
ok think i'am getting closer here now thanks to your help i know have
Code: Select all
bool myUI::PicOK(const CEGUI::EventArgs& e)
{
using namespace CEGUI;
WindowManager& winMgr = WindowManager::getSingleton();
ItemListbox* Pic_names = static_cast<ItemListbox*>(
winMgr.getWindow( "Pic_names"));
// get ptr to named imageset - don't forget this throws if imageset is not present
Imageset* imageset = ImagesetManager::getSingleton().getImageset( "pic" );
// get iterator to iterate over defined images.
Imageset::ImageIterator iter = imageset->getIterator();
while ( !iter.isAtEnd() )
{
// create new list item
ItemEntry* list_item = static_cast<ItemEntry*>(
WindowManager::getSingleton().createWindow( "TaharezLook/ListboxItem" ));
// set text on this item to whatever name the image has
list_item->setText( (*iter).getName() );
// add this item to the listbox
Pic_names->addChildWindow( list_item );
CEGUI::String pic = (*iter).getName();
CEGUI::Window* imageButton = CEGUI::WindowManager::getSingleton().getWindow("pic_field");
imageButton->setProperty("NormalImage", "set: name:" + pic );
// advance iterator
++iter;
}
//now we chose an image close the image select window
CEGUI::WindowManager::getSingleton().destroyWindow( "picselectwindow" );
return true;
}
which in the error log gives me
ImagesetManager::getImageset - No Imageset named 'name:03' is present in the system.
so if i'am correct here the string is parsing the name of the image ok so i tried it like
Code: Select all
bool myUI::PicOK(const CEGUI::EventArgs& e)
{
using namespace CEGUI;
WindowManager& winMgr = WindowManager::getSingleton();
ItemListbox* Pic_names = static_cast<ItemListbox*>(
winMgr.getWindow( "Pic_names"));
// get ptr to named imageset - don't forget this throws if imageset is not present
Imageset* imageset = ImagesetManager::getSingleton().getImageset( "pic" );
// get iterator to iterate over defined images.
Imageset::ImageIterator iter = imageset->getIterator();
while ( !iter.isAtEnd() )
{
// create new list item
ItemEntry* list_item = static_cast<ItemEntry*>(
WindowManager::getSingleton().createWindow( "TaharezLook/ListboxItem" ));
// set text on this item to whatever name the image has
list_item->setText( (*iter).getName() );
// add this item to the listbox
Pic_names->addChildWindow( list_item );
CEGUI::String pic = (*iter).getName();
CEGUI::Window* imageButton = CEGUI::WindowManager::getSingleton().getWindow("pic_field");
imageButton->setProperty("NormalImage", "set:pic name:" + pic );
// advance iterator
++iter;
}
//now we chose an image close the image select window
CEGUI::WindowManager::getSingleton().destroyWindow( "picselectwindow" );
return true;
}
and that throws me this error
Imageset::getImage - The Image named 'ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌpic' could not be found in Imageset 'pic'.
could you point me in the direction for this i think logic problem
TIA
Posted: Thu Aug 28, 2008 15:46
by Ninja
hiya
sorry got carried away and didnt answer your questions above
1] Did you define the imageset "pic" in your "scheme" file? Imagesets can be defined as part of your "scheme" and loaded on startup. They can also be created dynamically. Which are you doing?
2] The log message looks like its printing out garbage. Perform some of the basic debug tasks that allow you to isolate the line of appliication code that results in this cegui log error message (there are only a couple places within your code that could be at the source of this - e.g. getImageset). Step through your code, comment out sections of your code, isolate down to the "culprit line" within your own code. This will be a good learning process for you.
3] You dont check the return from Imageset* imageset = ImagesetManager::getSingleton().getImageset( "pic" ); Nor do you have this embedded within a try/catch block. How do you know that it is finding your imageset named "pic"?
1, I defined the imageset in the scheme file
2, Trying to do that
3, have now added the try and catch blocks but i did think of that before hand and changed pic to pic1 and got the no imageset named pic1 present in the system error so i assumed that was working ok
TIA
Posted: Thu Aug 28, 2008 16:49
by Ninja
me again
I now have
Code: Select all
bool myUI::PicOK(const CEGUI::EventArgs& e)
{
using namespace CEGUI;
WindowManager& winMgr = WindowManager::getSingleton();
ItemListbox* Pic_names = static_cast<ItemListbox*>(
winMgr.getWindow( "Pic_names"));
// get ptr to named imageset - don't forget this throws if imageset is not present
Imageset* imageset = ImagesetManager::getSingleton().getImageset( "pic" );
// get iterator to iterate over defined images.
Imageset::ImageIterator iter = imageset->getIterator();
while ( !iter.isAtEnd() )
{
if (imageset->getName() == "pic")
{
// create new list item
ItemEntry* list_item = static_cast<ItemEntry*>(
WindowManager::getSingleton().createWindow( "TaharezLook/ListboxItem" ));
// set text on this item to whatever name the image has
list_item->setText( (*iter).getName() );
// add this item to the listbox
Pic_names->addChildWindow( list_item );
String setProperty = "set:" + imageset->getName() + " image:" + (*iter).getName();
CEGUI::Window* imageButton = CEGUI::WindowManager::getSingleton().getWindow("pilotpic_field");
imageButton->setProperty("NormalImage", setProperty );
// advance iterator
++iter;
}
else
{
MessageBox(NULL, "Oh Oh didnt find the imageset !", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
}
}
catch (CEGUI::Exception& e)
{
fprintf(stderr,"CEGUI Exception occured: %s", e.getMessage().c_str());
return true;
}
//now we chose an image close the image select window
CEGUI::WindowManager::getSingleton().destroyWindow( "picselectwindow" );
return true;
}
and it works well kind off it will give me a list ok but no matter what name i select it will only set one picture and from the looks of it it will set the last pic in the list dosnt matter if i choose pic 01 or 02 it will allways display pic 03
if that makes sense.
TIA
Posted: Thu Aug 28, 2008 19:09
by daves
Grats, you've made it past a couple of technical issues within your code. Let us know how you fare with the last bits of your code. If you still need help let us know and we can provide additional ideas.
The specific mechanism that you are describing is something that we have implemented in our own application and you are indeed very close to having it do exactly what you want.
Posted: Thu Aug 28, 2008 21:04
by Ninja
hi Daves
thanks for all the help so far really appreciate it
from what i can make out and adding this
seems to confirm my suspicions that pic 03 is the selected image when running the code as the text is highlighted with the selection brush so if i'am right my code dosnt check for a selection change
could you point me in the right direction please i looked at the set properties page again but no joy so kinda stuck of what i should do
TIA
Posted: Thu Aug 28, 2008 21:50
by daves
A quick look at the documentation for the ItemListBox shows that there is an
EventSelectionChanged event that you can subscribe 2. I would think this would do it.
Try it out and let us know. Simply subscribe for this event (on your Pic_names window) as you do for other events.
See the following API as well:
http://www.cegui.org.uk/api_reference/c ... stbox.html
Posted: Fri Aug 29, 2008 14:38
by Ninja
hi Daves
To keep things simple and make sure i was doing things correctly at present i have the following
from pressing the image button on the main screen it brings up this page
Code: Select all
bool mainUI::picselect( const CEGUI::EventArgs& e)
{
using namespace CEGUI;
try
{
WindowManager& winMgr = WindowManager::getSingleton();
if (!winMgr.isWindowPresent("picselectwindow"))
Window* picsetup = winMgr.loadWindowLayout("picselect.layout");
// get ptr to named imageset - don't forget this throws if imageset is not present
Imageset* imageset = ImagesetManager::getSingleton().getImageset( "pic" );
ItemListbox* pic_names = static_cast<ItemListbox*>(winMgr.getWindow( "pic_names"));
Editbox* pic_txt = static_cast<Editbox*>(winMgr.getWindow( "pic_txt"));
imageset->getName();
// get iterator to iterate over defined images.
Imageset::ImageIterator iter = imageset->getIterator();
while ( !iter.isAtEnd() )
{
if (imageset->getName() == "pic")
{
// create new list item
ItemEntry* list_item = static_cast<ItemEntry*>(
WindowManager::getSingleton().createWindow( "TaharezLook/ListboxItem" ));
// set text on this item to whatever name the image has
list_item->setText( (*iter).getName() );
// add this item to the listbox
pic_names->addChildWindow( list_item );
list_item->setSelected(true);
list_item->subscribeEvent(CEGUI::ItemEntry::EventSelectionChanged,
CEGUI::Event::Subscriber(&mainUI::PicOK, this));
// advance iterator
++iter;
}
else
{
MessageBox(NULL, "Oh Oh didnt find the imageset !", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
}
if (winMgr.isWindowPresent("background_wnd"))
{
Window* background = winMgr.getWindow("background_wnd");
background->addChildWindow("picselectwindow");
}
}
catch (CEGUI::Exception& e)
{
fprintf( stderr, "CEGUI error: %s\n", e.getMessage( ).c_str( ) );
return true;
}
// event was handled
return true;
}
then when i select a list item
Code: Select all
bool mainUI::PicOK(const CEGUI::EventArgs& args)
{
using namespace CEGUI;
WindowManager& winMgr = WindowManager::getSingleton();
Editbox* pic_txt = static_cast<Editbox*>(winMgr.getWindow( "pic_txt"));
CEGUI::ItemEntry* list_item =
(CEGUI::ItemEntry*)((const CEGUI::WindowEventArgs&)args).window;
// was the item selected?
if (list_item->isSelected())
pic_txt->setText("pic:- " + setProperty);
else
pic_txt->setText("None");
return true;
}
and in my class i have relating to the above
Code: Select all
CEGUI::String setProperty;
CEGUI::String& getName() const;
which should change the pic_txt (an editBox i added) to the selected item
and indeed it does change the text from none to "pic" but dosnt give the name of the item so i tried in the subscribe event changing "this" to (*iter)
but then i get
error C2661: 'CEGUI::SubscriberSlot::SubscriberSlot' : no overloaded function takes 2 arguments
can you see where i going wrong here obviously when this part works i need to change the bool mainUI::PicOK section so it aculay changes the image on the main image button
sorry to be a PITA as you properbly guessed i still pretty new to programming but your help has been great
TIA
Posted: Fri Aug 29, 2008 15:02
by daves
EventSelectionChanged is an event on an ItemListbox, not one of the elements within it. So you need to subscribe to this event on the pic_names window as follows:
Ninja wrote: ItemListbox* pic_names = static_cast<ItemListbox*>(winMgr.getWindow( "pic_names"));
pic_names ->subscribeEvent(CEGUI::ItemEntry::EventSelectionChanged,
CEGUI::Event::Subscriber(&mainUI::PicOK, this));
not within the loop as your code depicts.