[Solved] Itemlist box help

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

Ninja
Quite a regular
Quite a regular
Posts: 86
Joined: Sun Aug 20, 2006 11:42

[Solved] Itemlist box help

Postby Ninja » Fri Aug 22, 2008 11:46

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
Last edited by Ninja on Sun Aug 31, 2008 19:44, edited 1 time in total.

earthsruler
Quite a regular
Quite a regular
Posts: 74
Joined: Mon Apr 28, 2008 23:21
Location: Australia

Postby earthsruler » Mon Aug 25, 2008 02:10

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.

daves
Home away from home
Home away from home
Posts: 253
Joined: Thu Feb 02, 2006 20:12

Postby daves » Mon Aug 25, 2008 13:30

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.

Ninja
Quite a regular
Quite a regular
Posts: 86
Joined: Sun Aug 20, 2006 11:42

Postby Ninja » Tue Aug 26, 2008 14:14

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

daves
Home away from home
Home away from home
Posts: 253
Joined: Thu Feb 02, 2006 20:12

Postby daves » Tue Aug 26, 2008 16:26

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>

Ninja
Quite a regular
Quite a regular
Posts: 86
Joined: Sun Aug 20, 2006 11:42

Postby Ninja » Tue Aug 26, 2008 16:53

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 :oops: but i'am unsure what i should put in there i tried a few variations and such but no joy :cry:

TIA

daves
Home away from home
Home away from home
Posts: 253
Joined: Thu Feb 02, 2006 20:12

Postby daves » Tue Aug 26, 2008 17:37

Make sure that this is really returning what you think:

Code: Select all

(*iter).getName()


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:
    set:pic image:01


My guess is that it doesn't and that would explain the garbage you see in the log.

Ninja
Quite a regular
Quite a regular
Posts: 86
Joined: Sun Aug 20, 2006 11:42

Postby Ninja » Wed Aug 27, 2008 21:56

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

Ninja
Quite a regular
Quite a regular
Posts: 86
Joined: Sun Aug 20, 2006 11:42

Postby Ninja » Thu Aug 28, 2008 15:46

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 :oops:
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

Ninja
Quite a regular
Quite a regular
Posts: 86
Joined: Sun Aug 20, 2006 11:42

Postby Ninja » Thu Aug 28, 2008 16:49

me again :D

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 :oops: if that makes sense.

TIA

daves
Home away from home
Home away from home
Posts: 253
Joined: Thu Feb 02, 2006 20:12

Postby daves » Thu Aug 28, 2008 19:09

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.

Ninja
Quite a regular
Quite a regular
Posts: 86
Joined: Sun Aug 20, 2006 11:42

Postby Ninja » Thu Aug 28, 2008 21:04

hi Daves

thanks for all the help so far really appreciate it

from what i can make out and adding this

Code: Select all

list_item->setSelected(true);


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

daves
Home away from home
Home away from home
Posts: 253
Joined: Thu Feb 02, 2006 20:12

Postby daves » Thu Aug 28, 2008 21:50

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

Ninja
Quite a regular
Quite a regular
Posts: 86
Joined: Sun Aug 20, 2006 11:42

Postby Ninja » Fri Aug 29, 2008 14:38

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

daves
Home away from home
Home away from home
Posts: 253
Joined: Thu Feb 02, 2006 20:12

Postby daves » Fri Aug 29, 2008 15:02

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.


Return to “Help”

Who is online

Users browsing this forum: No registered users and 3 guests