Jump to content
Tom F

Changing TToolButton image and using transparency

Recommended Posts

I'm going to have a light style and dark style in our D11, VCL, app.  

Question 1: What's the recommended way to handle TToolButton 32x32 images being different in an app where the user can switch between a light and dark style?   

 

What would be a good way to change a TToolButton's image from an image that is designed for a light style and an image that is designed for a dark style?

 

Perhaps if I have two TImageLists, can I just do this Toolbar1.Images := ImageList1 or  Toolbar1.Images := ImageList2; ???

Or perhaps I can change the ToolButton image as in ToolButton1.ImageIndex := 8 or ToolButton1.ImageIndex := 2; ???

 

Is some sort of refresh necessary to force an assignment like the above to be applied?  (I can have the user shut down the program if it's necessary for the assignment to occur before the toolbar is created, doing it in in TForm.Create before the TForm's TFrame is created?)

 

Question 2:  Transparency! Should I use it? I'm wondering whether I ought to just have our graphics designer create two sets of buttons not using transparency, hardwiring the button image's background to either a light or dark color rather than relying on transparency.

And I wonder that because I'm having trouble understanding how alpha colors work. 

https://docwiki.embarcadero.com/RADStudio/Sydney/en/Image_List_Editor says: 

Quote

If you add an image (using the Add button) to the image list, you can - during the current invocation of the ImageList editor - alter properties of the selected image using the Transparent Color, Fill Color, and Options controls. However, once the ImageList editor is closed, these properties are fixed. If you select this image during new invocations of the ImageList editor, the Transparent Color, Fill Color, and Options controls are grayed and you cannot change any properties of the image.

 

So I created a TBitMap with a green circle and reddish background that I want to be transparent. This is it (and attached as circle2.bmp.)

 

image.png.c4254888791815e831d307ce472ec583.png

 

But when I add the image in the ImageList editor, the circle has a red tinge remains around it in the editor and button.


image.thumb.png.e321d09327dd867a448d2ab2d89983d5.png
 

 

 

Have you faced either of the two issues above?

 

 

circle2.bmp

Edited by Tom F

Share this post


Link to post
3 hours ago, Tom F said:

So I created a TBitMap with a green circle and reddish background that I want to be transparent.

That is not a good idea, even with something like 32 × 32 pixels. You should always have an alpha layer, where pixels are neither entirely black or "not there", but something in between. So that it doesn't matter which background they're on:

 

image.thumb.png.ec17dedc11f4e63eebee1cd01c41ad87.png

 

Here it is getting more obvious:

image.thumb.png.45fcaaadb5634c9b23605a5853bfd822.png

 

In our VCL applications, we're using png files. Theyre small, lossless and support alpha channel.

 

If you can, you could even consider vector graphics like SVG. That way, you won't even have to worry about supplying different resolutions for different displays.

Share this post


Link to post

Even if you leave png or bmp as image source you should move to ImageCollection and VirtualImageList to support various DPIs your users could use. You can also watch this video:

 

Share this post


Link to post

I'm always wary of "just trying it" because I worry that my testing might fail to uncover some problem context that I wasn't aware of.

 

But, I answered my OP question #1 here by, um,  just trying it. The line below causes the VCL to refresh all Toobar buttons with the contents of the ImageList.

ToolBar.Images := ImageList;

So, if my user switches from a Light to a Dark style, I can use the above code to switch to a different set of toolbar icons.

I asked my OP question #2  very poorly. I know very little about image files, alpha channels, etc.

Here's the question rephrased:

I am going to hire a graphics designer to design 32x32 icons for a toolbar similar the DIY-designed 16x16 ones below.

 

image.png.abe9e6239dc5a38643c56faae33c1864.png

 

Since we are going to allow the user to select a light or dark VCL style, is my thinking correct that we probably need a second set of similar icons, but designed for dark styles, especially if our icons us a lot of transparency for their background. Otherwise, on a dark style, using icons that work on a light style like the above looks terrible, like this:

 

image.png.8fa84e71e8b07265a11174102a800d81.png

 

I will be adding the files that the graphic designer delivers to two ImageLists used by a Toolbar and its ToolButtons.  We are not going to support different DPIs at the current time.

 

I plan to ask the designer for the same icon twice, one icon that looks good on a light background and one that looks good on a dark background.

 

What else do I need to ask the designer given the above scenario?  What file type, what about transparency?  When adding these files to the ImageList, how do the Transparent Color and Fill Color fields (below) come into play?  How do I avoid the kind of red shadow shown below from occurring? (The source file for the image below is in the OP as circle2.bmp.)

 

image.png.3815c6bf2b6f312d904191146aeaa83f.png

I want to be able to give my designer clear instructions on the format of their deliverable. Something like: "We want you to deliver color, 32x32 png files with an alpha channel for transparency"

 

Are png files the file of choice for a project like this or does another file type work better?

Is there anything else I need to tell the designer?

Am I over-thinking this?

 




 

Edited by Tom F

Share this post


Link to post

I solved this issue by changing my icons to Material Designs Webfont and providing them to my application using Icon Fonts Image list.

When the style changes I just update the .FontColor property of the image list to TStyleManager.ActiveStyle.GetStyleFontColor(sfWindowTextNormal). This way I can be certain that whatever is selected, my toolbar and popup menu icons are always visible.

 

As an extra, if you are fine with the monochrome look, you can spare the fee of the designer.

Share this post


Link to post

I solved these issues abandoning tradional icons (BMP,PNG) to SVG. I started too from Google Material Design SVG icons but with a different approach because I needed icons not present in these libraries (some I drew, others I took from other online free libraries). So now I've several SVG sprites (some Google MD some customized) all designed 24x24 with black as the main color and I pick images from these sprites (for buttons, imagelists etc). SVG are pure XML so it's not difficult to change on the fly size or color (you have just to change an xml attribute or xml node), so, when I need SVG for dark theme or I need to use the sysop accent color I just change black stuff in the desired color. For me now is easy to reach something like this:

 

svgsamples.thumb.png.b1046cf4b5b758f2b9cda93e2dcae811.png

I started these "revolution" on my apps about 4 years ago to approach both HIDPI monitors and dark mode and it was quite a lot of work; in that period SVG it wasn't as fashionable as now so I had to build some internal components myself to do this job. Now it seems that there are even opensource solutions that help to solve these problems.

 

SVG is scalabale and is a text file. I don't like EMB approach of virtual image lists in which you have to provide several rastered icons for different sizes: Material desing base icons are 24x24 so if my app is 100% zoomed it uses this size, if the zoom is 150% ii switches to 36x36, if the zoom is 357% it uses 85x85 and so on, so the SVG images are rendered always of correct size for every zoom applied.

 

I've categorized all my SVGs and each of them has a name like "confirm", "cancel", "exit", "print" etc. I've inerithed the components in which I need SVG stuff (buttons, images, ecc) adding a property in which I provide at design time just the SVG name and then all is solved at runtime as the program needs (style, size, zoom etc). In this way if I want to change/update an image  I just modify the SVG sprite.

 

  • Like 1

Share this post


Link to post
6 hours ago, Tom F said:

What tools are you using to show the SVG files?

As I wrote in the previous post, when I migrated to SVG there was no plenty of tools like now.

 

I started with RiverSoftSVG component library and I based my internal libraries on that. In my applications, before SVG, I used PNG stored in resource files and loaded at runtime in TPngImageLists (it was all dinamic something like I'm doing now with SVG). To do a progressive migration I used RiverSoft to render SVG as PNG to mantain the same structure. RiverSoft was good enough to render material icons but has limitations on complex SVG so at the same time I used Delphi SVG (very good library it uses DirectX) to render complex logos and big SVG images. Now I've replaced Delphi SVG with Skia4Delphi and I'm planning to replace also RiverSoftSVG with it making Skia my internal reference for images and animations.

 

Starting for scratch I think I will evaluate SVGIconImageList and maybe I will use it in the future because it has a similar approach to mine. When I started, I tested it but it was very crude and terrible in rendering certain icons. Now it has evolved exponentially and if I'm not mistaken now you can choose also Skia as SVG rendere engine. 

 

Skia and SVGIconImageList are open source, RiverSoftSVG and DelphiSVG are commercial tools.

 

 

  • Like 1

Share this post


Link to post

To be able to manage that I took outline SVG icons.

Every style has colors for the font included, so I take the normal text color for the outline color:  <Style>.GetStyleFontColor(sfWindowTextNormal)

With Riversoft's SVG Library I can iterate through the elements of the SVG's (runtime, loaded into SVGImagelists or SVGDocuments) and change the pen/brush color. (Or anything else, like text for calendar etc...)

Maybe other libs can offer the same, I don't know. Some of them are storing the SVG as text AFAIK, I would not take such a lib.

Some of them will need extra libraries installed on the client machine, which is a joke for just showing SVG icons. Maybe if you have a drawing app or similar..

 

 

Also, themes are overrated. An average user will never use it except you will force him to use it.

99% the theme users are Developers.

Also, dark themes are not good for the eye, contrary to belief.

 

Edited by Attila Kovacs

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×