Since we have icons in trunk/src/icons/MxN/*.png, why can’t we have tango icons for buttons?
Actually, forget it. It’s because we don’t want to screw around with preferences just before the release of 3.1.
So here’s a different question: since we’re going to go to tango anyway, why can’t we just substitute tango icons for the ones we have so that the transition to scalable icons will just seem like a natural progression.
If we had a complete set which followed the guidelines and looked good, then
we could swap them in for the old 16x16 icons, as that’s pretty low-risk. But
I don’t think that it’s a good idea to add the multi-size icon support right
before releasing 3.1.
Oh, that’s really too bad, because the default toolbar icons on most
platforms are not 16x16 like we have now. They’re either 22x22 or 24x24,
so if you’re making a 16x16 set only, those won’t be in use very long.
Currently, when you specify an image for a toolbar button, you specify a specific instance of an image that is a specific size.
What I envisage is that when specifying toolbar images, you specify the name of an ‘Icon Family’ instead. An Icon Family is the set of all icons with the same name in each of the Tango sizes (well, our expanded set of sizes). The actual size of the icon would be specified by a Global preference. You change the size in the preference and presto, all the toolbars icons resize.
I had a little demo of this running and it worked great.
The drawbacks will be with modules that specify custom toolbar icons of varying sizes and do not want them all to be the same size.
The code I wrote for Icon Family’s neatly handles non-Tango images also. It uses the specified image name as a base icon and generates the Tango sizes from it by scaling. This would allow all existing modules to have auto-resizing toolbars, even if they use custom images.
24x24 is a strange case. Toolbar icons are 24x24 in Windows, and were once
that size in GNOME. For Windows, the right thing to do is to take the 22x22
icons and add a 1px transparent border around them, which can be done on
the fly—thus there would be no need for a 24x24 directory. However, there
is one icon which (on Windows) we need at startup when we call
setIconImages() to set the app icons. Again, in this case the sole difference
between the 22x22 app icon and the 24x24 one is a 1px transparent border,
so I could just create that at load-time, and then we wouldn’t need the
24x24 size at all.
If you don;t want to handle it on the fly, then there are two options to handle this.
Create the 24x24 image with the border, call it vassal24.png and put it in the icons/scalable folder.
I will add an extra method to my 3.2 software that allows you to request a non-standard sized icon. You’ll do something like IconFactory.getSizedIcon(“Vassal24”, 24) instead of the normal IconFactory.getIcon(“Vassal24”, IconFamily.SMALL). My software checks if a scalable icon is already the correct size and will just return the base icon.
If you don’t like that, I would just put it in the images directory and load it as we do now.
It’s ok building the 24x24 image at startup, as we’re loading the 22x22 image
anyway. (In fact, it will probably be faster to build the 24x24 image than
to read it from disk, since when building it all of the operations will
occur in memory.)
What I’d really like is to be able to request icons using the named Tango
sizes (large, medium, small, extra small) rather than numbers, and receive
24x24 icons when I request “small” on Windows, but 22x22 icons when I
request “small” everywhere else.
I’m thinking now that we really shouldn’t define directories for sizes
other than the standard ones, as doing so might encourage people to
create icons at weird sizes.
I’ve removed the 24x24 icon directory, and replaced it by a block of code
in VASSAL.tools.ApplicationIcons which creates the 24x24 app icon from the
22x22 one. (In 3.2, we can move these 7 lines into some icon support class,
since they’d be needed for all 24x24 icons in Windows.)
That still leaves the issue of the 256x256 icon. The only reason it exists
is that MS recommends that there be a 256x256 app icon. Nothing else uses
it—the 256x256 icon for the Mac is in the ICNS file, and it won’t be used
on Linux. We’re not likely to have any other 256x256 icons, as no icon used
internally would ever be used at that size. (A 256x256 button?!) So for this
one I’m inclined to remove the 256x256 icon directory and stash this icon
in images/. It’s a one-off, so there’s no good reason for it to complicate
our icon library.
This is only stage 1 of the Icon code to allow developers to access Icons we have loaded directly into Vassal.
I haven’t written te bit that allows developers to load their own Icon Families into a module. (That bit isn’t needed until we modify LaunchButton to use Icon Families). At that point, we can give people a gently reminder that scalable icons ‘ought’ to be svg.
However, as far as the software is concerned, there is no reason for the scalable icon to be svg. A bitmap icon will be scaled just as happily, with satisfactory results. Similiarly a size icon could be a tweaked svg icon.
In fact, if you provide Icons in all 4 of the Tango sizes, there is no need to include a scalable icon at all as it will never be used.
Oh, yes, I guess so.
I thought the reason to use a TreeMap was to allow you to traverse the keys in a sorted order?
Stage 1 doesn’t use this, but later, we will need to generate a list of available Icons in a Icon Family Picker. Since this only will only happen in the Editor, it makes sense to just sort the Family names in the IconFamilyPicker.
Yes, you are correct.
I wonder sometimes about the usefulness of the Singleton pattern. Only one instance of IconFactory will ever be created and I certainly don’t want the call to get an Icon to be
I’d like to. I think this is a point on which we should try to educate
our module designers. In the long run, the more vector graphics are created
and the more vector graphics expertise is built up among our module designers,
Which one? Is that really the plural of “family” for you, or is it a typo?
I’m curious now.
Oh, right. I was thinking of a LinkedHashMap, not a TreeMap.
I think there could be some threading problems here if you don’t use a
ConcurrentHashMap, BTW. What will happen if two different threads request
a BufferedImage at the same time?
That’s actually not what I was suggesting. I don’t like the verbosity
of getInstance(). What I do like is having a single internal object keep
the state, and to have that be a singleton. What I was suggesting is that
the IconFactory class act as a cover for an inner private class. (If that
doesn’t make sense, I’ll show you what I mean in a day or two.)
I was being lazy, iconFamilies is correct Australian english also.
Yes, I hadn’t considered threading yet. I will fix.
Ok, I know what you mean (I think). The getInstance() calls will be internal. Does it need to be an inner private class, or will private instance variables of IconFactory do? That’s the way I’ve seen it done in other parts of Vassal.
How far will SVG support be extended (i.e into module trait componernts)?
While most of us generally receive bmp/gifs/png from publishers, therefore making this moot, unless we are creating are own images or the few lucky of us with acces to the publisher svg’s, I could see the possibility where controlling the svg and placing its parts in layers we could then open up different parts of a “built game piece” to scaling etc…
I cant think of any good reason why I’d do this (yet) but given enough time I’d come up with some hair brained scheme to use it in some way for no other reason but that I can