Page 1 of 2

Setting an ImageButton's image - With no imageset!

Posted: Mon May 07, 2007 14:16
by Bagheera
Howdy. I'd like to change the property of an ImageButton normal/hover/pushed or disabled images in C++ code, however, the textures that I use are end-user supplied. For example: Dirt.jpg. These images are not part of any image files.

To clarify: My application will come with a folder called textures, which starts out empty. If the user places 3 textures in that folder, on the next run my application should display 3 image buttons, one for each texture. Each button should be clickable.

How can I accomplish this?

Posted: Mon May 07, 2007 14:37
by Rackle
I'm a novice when it comes to the imagery but here goes anyway.

A button is composed of 9 image parts: 1 for each corner (top-left, top-right, bottom-left, bottom-right), 1 for each edge (top, right, bottom, left), and 1 for the center. These different parts are used to generate buttons of any size; imagine a 4x2 button and a 6x3 button.

The corners are constant; they are copied from the imagery as is. The edges are stretched to fill the gap between two corners; the top and bottom edges are stretched horizontally while the left and right edges are stretched vertically. The middle is stretched both vertically and horizontally.

If you want to specify a single image part then it would have to be the middle part, which is stretched to create a button of the appropriate dimensions.

Hope this helps (and hope that I'm not too wrong).

Posted: Mon May 07, 2007 14:51
by Bagheera
How do I do that? What is the syntax?

Posted: Mon May 07, 2007 15:02
by Pompei2
Hi,

I suggest you to first find out how to load your textures into CEGUI::Image's and then create an imageset containing all these images. Then you have an imageset you can use to display the imagebuttons.

If you want them to have a button-frame around the texture, I recommend you to read the falagard skinning tutorial part 1 (and maybe part 2), then create a new look'n'feel that is a button where, like rackle says, you leave the "middle" part as a property that can be set from within the code. You could now (in code) set this property to the images from the imageset you created in code.

Posted: Mon May 07, 2007 15:16
by ldb
Bagheera wrote:How do I do that? What is the syntax?


well, this may or may not work for all the different parts rackle described (the 9 different images that make up the widget look), but it works for me to set an image at run-time, and im sure its just an issue of getting the right window property to set. anyway, some code:

first i create an image set in code like this:

Code: Select all

ImagesetManager::getSingleton().createImagesetFromImageFile("SelfImage1", "me1.jpg");


then, to set the image of the widget, i do this:

Code: Select all

Window* me = static_cast<Window*>(mWindow->getChild("CreditsWindow/SelfImage"));
me->setProperty("Image", "set:SelfImage1 image:full_image");


my guess is that the first parameter to setProperty will contain the particular property of the widget you wish to set. im just setting the Image property to the entire image contained in my SelfImage1 imageset.

notice the property "Image" specifies which image set to use with the set:SelfImage1 in the second paramter. the image:full_image part is, my guess, how you specify which rectangle of pixels to use within the imageset (which in this case is the entire image).

Posted: Mon May 07, 2007 15:29
by Rackle
Widget Galore wrote:/* StaticImage */
ImagesetManager::getSingleton().createImagesetFromImageFile("ImageForStaticImage", "GPN-2000-001437.tga");
DefaultWindow* staticImage = static_cast<DefaultWindow*>(winMgr.getWindow("StaticImage"));
staticImage->setProperty("Image", "set:ImageForStaticImage image:full_image"); // "full_image" is a default name from CEGUIImageset::Imageset()


That's the code to specify an image file for a StaticImage widget. To adapt it to a PushButton you first need to know what properties it supports. Property Set lists these: NormalImage, DisabledImage, HoverImage, PushedImage. These may also be useful: HorzImageFormatting, VertImageFormatting.

Give this code a twirl:

Code: Select all

ImagesetManager::getSingleton().createImagesetFromImageFile("PushButtonNormal", "Textures/PushButtonNormal.tga");
PushButton* pushButton = static_cast<PushButton*>(winMgr.getWindow("MyPushButton"));
pushButton->setProperty("NormalImage", "set:PushButtonNormal image:full_image");

Posted: Mon May 07, 2007 15:54
by Bagheera

Code: Select all

   CEGUI::PushButton *IB = (CEGUI::PushButton*)wmgr.createWindow("WindowsLook/Button", "IB");
   wmgr.getWindow((CEGUI::utf8*)"Root/ToolBarWindow")->addChildWindow(IB);
   IB->setPosition(CEGUI::UVector2(CEGUI::UDim(0.0, 0), CEGUI::UDim(0.0, 0)));
   IB->setSize(CEGUI::UVector2(CEGUI::UDim(0.8, 0), CEGUI::UDim(0.5, 0)));   
   CEGUI::ImagesetManager::getSingleton().createImagesetFromImageFile("PushButtonNormal", "Dirt.jpg");
   IB->setProperty("NormalImage", "set:PushButtonNormal image:full_image");


Tried this, then I ran it in debug and it threw an excpetion at the setProperty line.

Posted: Mon May 07, 2007 16:25
by Rackle
This snippet is from Widget Galore, the Button section:

Code: Select all

/* Button */
PushButton* btnClose = static_cast<PushButton*>(winMgr.getWindow("btnClose"));
btnClose->setText("Exit");
CEGUI::ImagesetManager::getSingleton().createImagesetFromImageFile("PushButtonNormal", "GPN-2000-001437.tga");
btnClose->setProperty("NormalImage", "set:PushButtonNormal image:full_image");

I added the last two lines and transformed the text PushButton into an image PushButton. My feeling is that the image from createImagesetFromImageFile() is not found. I changed the name from "GPN-2000-001437.tga" to "GPN-2000-001437_.tga" and received an exception: DefaultResourceProvider::load - GPN-2000-001437_.tga does not exist.

I suspect that you do not catch Cegui exceptions:

Code: Select all

try
{
   ...
}
catch(Exception &e)
{
   #if defined( __WIN32__ ) || defined( _WIN32 )
      MessageBox(NULL, e.getMessage().c_str(), "Error initializing the demo", MB_OK | MB_ICONERROR | MB_TASKMODAL);
   #else
      std::cerr << "Error initializing the demo:" << e.getMessage().c_str() << "\n";
   #endif
}

Posted: Mon May 07, 2007 16:27
by Levia
What exception is logged in the CEGUI.log file?

Posted: Mon May 07, 2007 17:00
by Bagheera
I use Ogre so all exceptions are caught. I'm getting CEGUI: Unkown Object Exception, and the log file includes:

07/05/2007 19:52:03 (Error) Exception: There is no Property named 'NormalImage' available in the set.

Posted: Mon May 07, 2007 17:26
by Pompei2
Are you using TaharezLook ?

Posted: Mon May 07, 2007 17:33
by Bagheera
No, I'm using WindowsLook. You're saying there's no NormalImage property for a Button in WindowsLook? I just checked and it exists in both Taharez and WindowsLook.

Posted: Mon May 07, 2007 17:35
by Levia
Yup. There is no NormalImage property for Button in WindowsLook..the others dont exist either. Should be easily doable though.

Posted: Mon May 07, 2007 17:48
by ldb
what about just trying the Normal property?

actually, whats a WindowsLook/SystemButton ?

it has <ImageProperty name="NormalImage">

Posted: Mon May 07, 2007 18:03
by Bagheera
I tried the SystemButton widget and it works fine. Thanks for all your help guys!