News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Toolbar bitmap creator

Started by NoCforMe, September 23, 2023, 11:42:39 AM

Previous topic - Next topic

NoCforMe

My latest project, about halfway finished, is a tool to create bitmap images for toolbars. Sounds pretty simple, right? Well, maybe not so simple.

For years I've been creating toolbars for my programs by hand, using an image editor (Paint Shop Pro) and cobbling them together to make do. Let me tell you, none of these will ever win any design awards. Plus the process is a pain in the butt.

Needing a toolbar for a recent project, I decided to finally try to automate the process. The result is MakeToolbarBMP, which I present for your evaluation.

The process of creating the bitmap--basically piecing together smaller "tiles" into a strip--is not all that complicated. What is somewhat complex is resolving the bitmap palettes. The problem I ran into over and over again was this: I'd have several bitmap images to combine into a strip, either ones I created myself or ones I found online. Each image has a different palette (I'm talking about 256-color images here; 16-color images will often have identical palettes, though not necessarily, which will be the "standard" Windows colors). So combining them just doesn't work, or doesn't work well at all; colors needed by one "tile" are missing completely in another images's palette. The results are guaranteed to look crappy.

My first take on this was to try to re-use the palettes by substituting colors needed in other images. I quickly found this to be unworkable: even with 256 colors, you'll soon run out of available space.

But then I hit on the "Aha!" solution: creating a "universal" palette. The idea is to create a new master palette for all the images in a toolbar strip, with enough colors to at least approximate the colors in each "tile". So the first order of business here was to create such a palette and test it. I wrote a "UniPal" utility which programmatically creates a palette and displays it, and allows you to test color-matching. At first I just tried matching the search color against the palette colors (just comparing the 24 bits of R/G/B), which didn't work too well. Then I refined it and calculated the sum of differences between each corresponding color in search color and searchee: basically |r1-r0| + |g1-g0| + |b1-b0|. The smallest sum should be the best match.

Long story short, it works incredibly well. What the program does is to match each palette entry in each "tile" against the "master" palette to find the best match. Then it goes through each pixel in that tile and sets it to the new index in the master palette. (Remember that "pixels" in indexed bitmaps, like 16- and 256-color images, aren't actually pixels but indexes into the palette table.)

In fact, I'm rather proud of this feature. You can see how it works in the screenshot below. Notice the slight color difference between the two globe images. Mine (the one in the toolbar preview below) is a bit more yellowish. Not bad for a first pass; this can be improved by tweaking the palette, which is easy to generate. (I'm working on a tool which will allow easy creation of user-defined palettes for this purpose.)

I'm pretty happy with this project, except for a few things. Not thrilled with the user interface for selecting tile files: try it and see what you think. It's kinda clever, using a listbox with responsive slots you can click on to choose files. If this were a production program I think I'd want a control where I can drag and drop entries to rearrange them; thinking about creating a custom control to do this, since I don't know of any existing control that does this. That is definitely a non-trivial exercise!

Anyhow, this program will actually create bitmaps if you like. I've included a whole lot of bitmaps in the .zip you can play around with; these are all converted from Axialis icons, which look pretty nice. (You can see that Hutch used some of these in his projects.)

So if you do fool around with this let me know what you think. Oh, the transparency stuff is only half-implemented: you can see the effect on the toolbar preview, but it doesn't actually change the palette (the idea is to plug the transparent background color into the first palette entry). Also not any provision for loading external palettes yet. All coming soon.

Oh, and just to show that what seems simple often isn't, I haven't implemented tile deletion yet. If you think about it, this is a non-trivial problem: it's easy to delete entries at the end of the list, just zap them. But what if the user wants to delete an entry in the middle? Then what you should do is to slide all the entries up one notch, so as not to leave a hole in the list. That's gonna require a lot of shuffling pointers around and other bookkeeping. It's the next "feature" to be coded. (Unless someone can come up with some kind of genius idea of a better way to select files. Remember there can be up to 20 of these.)
Assembly language programming should be fun. That's why I do it.

Biterider

Hi NoCforMe
Great tool. It looks very professional!   :cool:

I played with it a bit and it does what you wrote perfectly.

I noticed 2 small things in the handling that I would like to share.
When you select a new background color with the "Set 1st palette entry color" checkbox set, it doesn't show up the change right away. You have to uncheck the checkbox and check it again.
Secondly, it would be very practical to be able to drag and drop the files into the file list.

Again, compliments!  :thumbsup:

Do you plan to publish the sources at some point?

Biterider

Caché GB

Hi NoCforMe

This is awesome. Thanks for this. I will but it to go use some time soon.
Caché GB's 1 and 0-nly language:MASM

NoCforMe

Quote from: Biterider on September 23, 2023, 03:45:43 PMHi NoCforMe
Great tool. It looks very professional!  :cool:

I played with it a bit and it does what you wrote perfectly.

Thanks!

QuoteI noticed 2 small things in the handling that I would like to share.
When you select a new background color with the "Set 1st palette entry color" checkbox set, it doesn't show up the change right away. You have to uncheck the checkbox and check it again.

Yes, I fixed that shortly after I uploaded it here. Wait until the next version drops ...

QuoteSecondly, it would be very practical to be able to drag and drop the files into the file list.

That's funny; drag and drop is about the last thing I ever think about using in my daily "workflow", mainly because of how my desktop is usually set up: almost never with an app I could drop files into next to Explorer. But I know how to implement that, so i'll put it on the todo list.

QuoteDo you plan to publish the sources at some point?

Certainly, happy to share my work here.
Assembly language programming should be fun. That's why I do it.

NoCforMe

The project is about 98% complete. (I think. You never know.) New version attached below.

There's a companion program to the toolbar bitmap creator, UniPal, which creates the "universal" palettes used to create the bitmaps, which is a pretty crucial part of the process. I'm very happy with how UniPal turned out; it can create palettes with up to 32 entries, each of which is a run of color from dark to light. By creating short (8-element) entries, you can cram a lot of different colors into a palette, which makes a big difference when using certain toolbar images. Look at the sample palette "project" file, UniPal palette #2.upf, to see what this looks like.

Please play around with this and see what you think. Biterider, you'll be happy to see that the toolbar creator now uses drag and drop to add "tiles". It's actually so easy to implement that there's really no reason not to.

Possible future version: It occurs to me that maybe the UniPal functionality could be wrapped into the toolbar bitmap creator, so you wouldn't have to switch back and forth between them via palette files. What do you think? It would make the user interface a bit more complex, but it should be doable. Other than that, I can't think of any great improvements at the moment. Maybe one of you will come up with them ...
Assembly language programming should be fun. That's why I do it.

Biterider

Hi NoCforMe
Quote from: NoCforMe on September 30, 2023, 04:28:01 AMBiterider, you'll be happy to see that the toolbar creator now uses drag and drop to add "tiles"
:thumbsup:

In my opinion, it would be more user-friendly to include UniPal in the toolbar creator. If it is not too complicated, I am in favour of it.

Biterider

NoCforMe

#6
For those who are curious, here is the source for both programs (MakeToolbarBMP & UniPal). All the gory details.

Even though these programs are fairly small, they contain a lot of stuff, everything but the kitchen sink:

  • Drag-and-drop (in MakeToolbarBMP) to select bitmap tile files
  • A nonstandard (or as I like to say, brilliant) use of a humble listbox control as a file/palette entry selector
  • Simple but effective palette color matching code (MakeToolbarBMP)
  • "Command-line" opening of files (project files for UniPal) to allow Explorer file association
  • A project file parser (UniPal)
  • A hook procedure attached to the GetSaveFile() dialog to query control settings in the dialog
  • Custom Win32 controls for displaying various color thingies
  • Popup menus

You'll notice there are no resource files. Not a big fan of the resource compiler here; I only use it when absolutely necessary, like when I need to include a lot of bitmaps, icons, etc., and don't want to have a zillion files scattered about as part of the project. But here I create my own dialog memory templates (with my own dialog editor), so those are just .inc files. Menus I create on the fly inside the code. And I've embedded small bitmaps (the red 'X' clear button thingies) in the source, using a technique I learned from Fearless here.
Assembly language programming should be fun. That's why I do it.

NoCforMe

Interesting little detail about making palettes (at least I think so):

When I got the first version of the toolbar creator working, my palette started with a sequence of grays, 16 colors ranging from black to white. Except that it never quite reached white: I started with 0, for black, and added 16 to each element. So the sequence for each color went (in hex):

00, 10, 20, 30, 40 ... C0, D0, E0, F0

Hex F0 (full color: F0F0F0) isn't quite white. Scratched my head a while, then came with: aha! what if I use 17 as the increment rather than 16? Turns out this gives a perfect sequence starting with 0 and ending with FF (255), the maximum value.

But look at the sequence it creates:

00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF

and the full palette values go from 000000 111111 222222 333333 ... to DDDDDD EEEEEE FFFFFF.

So 17 is a magic number here!

Now the numbers aren't a nice "even" sequence (000000, 101010, etc.) but who cares?

BTW, I tried to figure out how to do the same thing with the 8-element sequences so they'd end up with pure white. Couldn't come up with a number that works, and then realized I actually don't want to do this. Why? Because it would simply create totally redundant entries (white), which would be a waste of space. As it is there's exactly one pure white entry at the end of the black-to-white sequence, which is as it should be. The other ending values are all slight shades of whatever color they started out as.
Assembly language programming should be fun. That's why I do it.

NoCforMe

Quote from: Biterider on September 30, 2023, 05:23:44 AMIn my opinion, it would be more user-friendly to include UniPal in the toolbar creator. If it is not too complicated, I am in favour of it.

Yes, you're absolutely right. Ugh. Lotsa work. This won't happen for a while, until I get some bug reports and fix them. But it's on the list.
Assembly language programming should be fun. That's why I do it.

fearless

The create bitmap from memory I got from Vortex: https://www.masmforum.com/board/index.php?topic=16267.msg134453#msg134453

NoCforMe

OK, I'll give you both credit for it.
Assembly language programming should be fun. That's why I do it.

Biterider

Hi NoCforMe
I had a quick look at the source code yesterday. I must say that it is quite well organised and cleanly written.  :thumbsup:
Also not exceptionally long for the functionality it offers. 

Thanks for sharing!

Biterider

NoCforMe

Finally, I got the "integrated" version done. This is the toolbar creator (formerly known as MakeToolbarBMP) with the palette editor (UniPal) rolled into it. I must say I'm pretty pleased with it. (The motivation for this came from Biterider.)

So please try this out, see what you think. I believe the user interface should be pretty intuitive (but isn't what programmers always think about their creations?). Try clicking on things to see what happens. If anything is confusing or doesn't make sense please let me know.

It's not perfect: I wish there was an easy way to rearrange the bitmap "tiles". I did add an insert function to this list, but it would be nice if you could slide the listbox entries around to rearrange things. (I have plans for a custom control that would do this, but it's not going to happen any time soon.)

I like the overall look of this, which I would call a kind of classic Vista-looking creation. Especially like my "toolstrips", which I invented after getting frustrated with using Windows' toolbars; they can easily accomodate any kind of custom control. Oh, and please check out the Palette Settings dialog, especially the "special colors" functions; these coordinate with the dropper tool in the tile preview window. I'll explain how this works in detail in a follow-up post, as well as posting source code.
Assembly language programming should be fun. That's why I do it.

Biterider

Hi NoCforMe
It looks pretty good.  :thumbsup:
Playing around with palette settings (pressed entry 11 (Blue 1/4) of the selection listbox) and got a GPF at 

00405C43 89 02                mov        dword ptr [edx],eax 

where edx is pointing to an invalid page.

Biterider



NoCforMe

My first bug report ... ahem. Sorry 'bout that. I'm looking at the code but I can't reproduce the error just yet.

"Other than that, Mrs. Lincoln, how d'you like my user interface?"**

**Sorry, USAn joke ...
Assembly language programming should be fun. That's why I do it.