Odd issues when using bitmap.image in a Button

18 posts / 0 new
Last post
LyleHaze
LyleHaze's picture
Offline
Last seen: 1 year 4 months ago
Joined: 2011-05-26 03:58
Odd issues when using bitmap.image in a Button

This is my first usage of aiss images, and it's almost working as expected.

I have a horizonital layout group of five Buttons. Before now they used GA_Text labels and looked normal. To add images I replaced each GA_Text tag with the following:

  1. BUTTON_RenderImage, IIntuition->NewObject(BitMapClass, NULL,
  2. BITMAP_Screen, screen,
  3. BITMAP_Masking, TRUE,
  4. BITMAP_SourceFile, "tbimages:tapepause",
  5. BITMAP_SelectSourceFile, "tbimages:tapepause_s",
  6. BITMAP_DisabledSourceFile, "tbimages:tapepause_g",
  7. TAG_END),

Of course, slightly changing the filenames as needed.
You may assume that BitMapClass is properly opened and screen is a valid pointer
to struct Screen.

It works, in that I get all the graphics, but the weird part is that the first button
displays the BitMaps properly, and the next four display the images over a black
background instead of the usual grey scaled background.
I tried combinations, looked for differences, apparently I'm just missing it.
I have reviewed the code others have posted for loading AISS images, did not
see a significant difference. I have viewed the images in Multiview and they
are all properly grey there.

I'm just hoping someone has seen this and can suggest a fix.
I have an image available, but it's not hosted.. :(

Thanks!
LyleHaze

hypex
hypex's picture
Offline
Last seen: 1 month 2 weeks ago
Joined: 2011-09-09 16:20
Don't know if the following

Don't know if the following would affect it but I notice you call NewObject() directly instead of using BITMAP_GetClass(). (Which was depreciated somehow in V52.) Although you supply a BitMapClass how is generated? According to the API passing a class pointer is only for private classes. Is your BitMapClass a private class? Doesn't seem like it. :-)

From NewObject() API:
You specify a class either as a pointer (for a private class) or
by its ID string (for public classes). If the class pointer
is NULL, then the classID is used.

LyleHaze
LyleHaze's picture
Offline
Last seen: 1 year 4 months ago
Joined: 2011-05-26 03:58
I believe the document you

I believe the document you are quoting was written about the same time as the Reaction macros.
At one time that was considered easier, but it carries a lot of unnecessary overhead.

I open each class once as part of my startup routine.
I open libraries and devices there as well.

  1. BitMapBase = IIntuition->OpenClass("images/bitmap.image",52,&BitMapClass)
  2. if(NULL == BitMapBase)return(failopen("Could not open BitMap Class"));

This lets me gather all the "housekeeping" into a single OpenAll(), and close
with a CloseAll() later, which cuts down on clutter in main();

It should also improve performance, as each Class is opened once for the
life of the executable, instead of once per Instance of bitmap, or button,
or layout etc.

If my understanding is not correct, I hope someone will reply with better info.

Thanks,
LyleHaze

LyleHaze

thomas
thomas's picture
Offline
Last seen: 2 hours 24 min ago
Joined: 2011-05-16 14:23
Your understanding is

Your understanding is correct.

However, your description says that the first button shows correctly but the second and third and so on doesn't. For me this implies that you need at least two buttons for the problem to show. But your excerpt only shows one button. So it should be obvious that your mistake cannot be in this part of the code.

I would make some macros like these:

  1. #define TBImage(name, screen) BitMapObject, \
  2. BITMAP_Screen, (screen), \
  3. BITMAP_Masking, TRUE, \
  4. BITMAP_SourceFile, "tbimages:" name, \
  5. BITMAP_SelectSourceFile, "tbimages:" name "_s", \
  6. BITMAP_DisabledSourceFile, "tbimages:" name "_g", \
  7. EndObject
  8.  
  9. #define TBButton(name, id, screen) ButtonObject, \
  10. GA_ID, (id), \
  11. GA_RelVerify, TRUE, \
  12. BUTTON_RenderImage, TBImage(name, screen), \
  13. EndObject

Then I can define my tool bar like this:

  1. StartHGroup,
  2. LAYOUT_SpaceOuter, FALSE,
  3. LAYOUT_FixedVert, FALSE,
  4. LAYOUT_EvenSize, TRUE,
  5. LAYOUT_AddChild, TBButton("new", GID_NEW, scr),
  6. LAYOUT_AddChild, TBButton("open", GID_OPEN, scr),
  7. LAYOUT_AddChild, TBButton("save", GID_SAVE, scr),
  8. LAYOUT_AddChild, TBButton("saveas", GID_SAVEAS, scr),
  9. LAYOUT_AddChild, TBButton("tapeplay", GID_PLAY, scr),
  10. LAYOUT_AddChild, TBButton("tapepause", GID_PAUSE, scr),
  11. LAYOUT_AddChild, TBButton("tapestop", GID_STOP, scr),
  12. LAYOUT_AddChild, TBButton("taperew", GID_REWIND, scr),
  13. LAYOUT_AddChild, TBButton("tapeffw", GID_FORWARD, scr),
  14. LAYOUT_AddChild, TBButton("tapenext", GID_NEXT, scr),
  15. LAYOUT_AddChild, TBButton("tapelast", GID_BACK, scr),
  16. EndHGroup,

And I am sure that all buttons are defined in the same way.

broadblues
broadblues's picture
Offline
Last seen: 4 years 1 month ago
Joined: 2012-05-02 21:48
I have viewed the images in


I have viewed the images in Multiview and they
are all properly grey there.

They are transparant on a grey background. The images are actually black in the transparent areas, so that suggests an isue with masking.

Can you post the actual code that isn't working? That way we can spot the error.

Aslo note button.gadget will not dispose of your image, and in your example you don't save a pointer it. So you will have no way of disposing of it.

broadblues
broadblues's picture
Offline
Last seen: 4 years 1 month ago
Joined: 2012-05-02 21:48
Do you have

Do you have BUTTON_Transparent,TRUE set?

How I handle images and buttons

image loading:

  1. if(!(skapp->ap_LW.lw_Imgs[IMG_LW_LAYERADD]))
  2. {
  3. skapp->ap_LW.lw_Imgs[IMG_LW_LAYERADD] = (struct Image *)IIntuition->NewObject(BitmapClass,NULL,
  4. BITMAP_Masking,TRUE,
  5. BITMAP_SourceFile,"TBImages:layeradd",
  6. BITMAP_SelectSourceFile,"TBImages:layeradd_s",
  7. BITMAP_DisabledSourceFile,"TBimages:layeradd_g",
  8. BITMAP_Screen,skapp->ap_LW.lw_Screen,
  9. TAG_DONE);
  10. }

The images are added to an array of pointers. (named using an enum)

Adding to button:

  1. LAYOUT_AddChild,skapp->ap_LW.lw_Gads[GID_LW_LAYERADD] = (struct Gadget *)IIntuition->NewObject(ButtonClass, NULL,
  2. BUTTON_PushButton,FALSE,
  3. skapp->ap_LW.lw_Imgs[IMG_LW_LAYERADD]?BUTTON_RenderImage:TAG_IGNORE,skapp->ap_LW.lw_Imgs[IMG_LW_LAYERADD],
  4. skapp->ap_LW.lw_Imgs[IMG_LW_LAYERADD]?BUTTON_Transparent:TAG_IGNORE,TRUE,
  5. skapp->ap_LW.lw_Imgs[IMG_LW_LAYERADD]?TAG_IGNORE:GA_Text,"A",
  6. GA_ID,GID_LW_LAYERADD,
  7. GA_HintInfo,"Add a new layer to the project",
  8. GA_RelVerify,TRUE,
  9. TAG_END),

The above provides a text fall back if the button doesn't load. Means SketchBlock can carry on even it the wrong version of AISS is installed.

The button it's self is cleaned up by the layout.gadget it's attached too when the window is disposed of, the images are disposed later:

  1. IIntuition->DisposeObject(lwin->lw_Window);
  2. lwin->lw_Window = NULL;
  3.  
  4. for(i = 0; i < IMG_LW_NUMIMGS; i++)
  5. {
  6. if((lwin->lw_Imgs[i]))
  7. {
  8. IIntuition->DisposeObject((Object *)lwin->lw_Imgs[i]);
  9. lwin->lw_Imgs[i] = NULL;
  10. }
  11. }

IN the above dispsosing the window cleans up all gadgets then the for loop cleans up alol the images.

LyleHaze
LyleHaze's picture
Offline
Last seen: 1 year 4 months ago
Joined: 2011-05-26 03:58
Thanks to all.. As this is my

Thanks to all..
As this is my first attempt at using aiss, or any images in gadgets, it's all quite helpful.
As my first attempt, I had not yet got around to handling a fallback in case the aiss image did not load, etc..

regarding the freeing of images, it does seem a bit surprising that _most_ of the GUI objects will self-dispose, but Images do not.

Again, big thanks for all the help.. As soon as I get a chance, I'll try to build up a complete framework for image handling.

LyleHaze

LyleHaze

hypex
hypex's picture
Offline
Last seen: 1 month 2 weeks ago
Joined: 2011-09-09 16:20
@LyleHaze It should also

@LyleHaze

It should also improve performance, as each Class is opened once for the
life of the executable, instead of once per Instance of bitmap, or button,
or layout etc.

I actually agree with your method here and would prefer to do it the same way myself. I only pointed it out as the API seeemd to be saying otherwise. It would be more efficient to pass a pointer than a string used to reopen a class anyway. I suppose passing a string seems safer. You can ofcourse then implement your own macros based on your pointer which would run more optimised. :-)

broadblues
broadblues's picture
Offline
Last seen: 4 years 1 month ago
Joined: 2012-05-02 21:48
@Lyle regarding the freeing

@Lyle


regarding the freeing of images, it does seem a bit surprising that _most_ of the GUI objects will self-dispose, but Images do not.

Gadgets are (usually) unique whereas Images can often be shared (between two windows in the sam app forexample), so it doesn't make sense for a gadget to autodispose it's image (unless it created it itself internally)

LyleHaze
LyleHaze's picture
Offline
Last seen: 1 year 4 months ago
Joined: 2011-05-26 03:58
I actually agree with your

I actually agree with your method here and would prefer to do

I'm glad you like it, but I can not take credit.
I learned a great deal from reading Trixies reaction guide on this website.
It made a lot of things easier to understand. HIghly recommended.

Thomas, Broadblues,
Thanks for your help. I have a working framework now and my apps will look better for it.

LyleHaze

LyleHaze

trixie
trixie's picture
Offline
Last seen: 4 months 4 weeks ago
Joined: 2011-02-03 13:58
@LyleHaze The guide you've

@LyleHaze

The guide you've linked above is Jim Tubbs' guide, not mine :-) I've only written the tutorial.

AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2

alfkil
alfkil's picture
Offline
Last seen: 2 years 7 months ago
Joined: 2011-05-10 22:02
Re: Odd issues when using bitmap.image in a Button

Has this issue with BITMAP_Masking been solved/confirmed? I seem to have an issue consisting in, that the exact same image loaded from different locations yield differences in masking abilities. It would be wonderful if these could somehow resolve.

LyleHaze
LyleHaze's picture
Offline
Last seen: 1 year 4 months ago
Joined: 2011-05-26 03:58
Re: Odd issues when using bitmap.image in a Button

Sadly, I cannot remember.
I'm sure my original issue was for Score, and the gadget graphics there are all good now, but the details of then vs now are forgotten.
Getting old sucks, but NOT getting old sucks even more.

LyleHaze

LyleHaze

alfkil
alfkil's picture
Offline
Last seen: 2 years 7 months ago
Joined: 2011-05-10 22:02
Re: Odd issues when using bitmap.image in a Button

Sure, staying healthy is the only option ;).

The issue I'm pressing, is the fact that

    string imagePath = "tbimages:" + iconName;

yields an icon with masking, whereas

    string imagePath = "Icons/" + iconName;

(refering in this instance to the exact same file just placed differently) yields an icon without.

The entire code snippet:

  1. void ReactionSpeedBar::addButton (int buttonId, string buttonText, string iconName)
  2. {
  3. struct Screen *screen = IIntuition->LockPubScreen("Spotless");
  4. if (!screen ) screen = IIntuition->LockPubScreen(0);
  5.  
  6. string imagePath = "tbimages:" + iconName;
  7. string selectedPath = imagePath + "_s";
  8. string disabledPath = imagePath + "_g";
  9.  
  10. Object *image = BitMapObject,
  11. BITMAP_Screen, screen,
  12. BITMAP_Masking, true,
  13. BITMAP_SourceFile, strdup(imagePath.c_str()),
  14. BITMAP_SelectSourceFile, strdup(selectedPath.c_str()),
  15. BITMAP_DisabledSourceFile, strdup(disabledPath.c_str()),
  16. EndMember;
  17.  
  18. struct Node *node = ISpeedBar->AllocSpeedButtonNode((uint16)buttonId,
  19. SBNA_Text, strdup(buttonText.c_str()),
  20. SBNA_Image, image,
  21. SBNA_Enabled, true,
  22. // SBNA_Spacing, 2,
  23. // SBNA_Highlight, SBH_RECESS,
  24. TAG_DONE);
  25.  
  26. if (node) {
  27. addNode (node);
  28. }
  29. }
broadblues
broadblues's picture
Offline
Last seen: 4 years 1 month ago
Joined: 2012-05-02 21:48
Re: Odd issues when using bitmap.image in a Button

Are you 100% sure the file is the same? Load it inot MultiView(er) and test if both locatsions have an alpha channel.

As secondary comment, why are you doing strdup(somestring.c_str()) all over the place? Surely the result string.c_str() is not going out of scope so need to dup it. Using strdup() without saving the result and free()ing it will be leeking memory?

alfkil
alfkil's picture
Offline
Last seen: 2 years 7 months ago
Joined: 2011-05-10 22:02
Re: Odd issues when using bitmap.image in a Button

The files are 100% identical. I confirm this by running

diff tbimages:file Icons/file

The reason I am running strdup is, that apparently there are problems with CopyText attributes in some classes. I know it is probably unnecessary in some cases, but for generic purposes it has just been added all over the place. To remedy the memory loss, I am going to add some kind of garbage collection to avoid having to keep track of the excess strings.

broadblues
broadblues's picture
Offline
Last seen: 4 years 1 month ago
Joined: 2012-05-02 21:48
Re: Odd issues when using bitmap.image in a Button

I think only ListBrowser has that CopyText issue, in the case above the text does not need to persist and is not copied.

I would think if where you do need text to persist beyond the function scope you would be better altering the scope of your string object? Would seem more C++ in style.

WRT to the original point of images rendering without alpha, may be run Snoopy whilst starting the app with the tbimages: and the local paths and see if any obvious anomalies show up. The path shouldn't make any difference and doesn't in any of my own apps, so something odd is going on.

alfkil
alfkil's picture
Offline
Last seen: 2 years 7 months ago
Joined: 2011-05-10 22:02
Re: Odd issues when using bitmap.image in a Button

I think, that there is definitely a better way to handle string transfers in this context. I just haven't gotten to the point, where I want the perfection of that aspect to guide my transactions in coding space.

I am not too much of a fan of Snoopy. It doesn't strike me as the good solution to snoop around in system calls to solve coding issues. My theory is, that to solve a coding issue, you need to think conceptually rather than try and keep track of the procedures. It has actually helped me get past some real issues, so I think I am gonna stick to that theory for the time being.

Best of all.

Log in or register to post comments