WindowResize() doesn't set the background color.

Posted by Twisol on Tue 24 Aug 2010 07:05 AM — 19 posts, 75,701 views.

USA #0
WindowResize() doesn't set the window's background color like WindowCreate() does, it just uses it in case the new size is bigger. This confused me for a good long while, because I'm trying to use WindowResize() to change the window's background color (for on-the-fly changing of the transparency color when that flag is set).

The background color is now one of the only things you can't change on the fly (with the notable exception of most hotspot callbacks). As far as I can tell, it's a one-liner change:

m_iBackgroundColour = BackgroundColour;



[EDIT] For the sake of completeness, this is what I'm doing:

WindowAPI.ColorKey = function(win, color)
  local x, y = WindowInfo(win._id, 1), WindowInfo(win._id, 2)
  local width, height = WindowInfo(win._id, 3), WindowInfo(win._id, 4)
  local pos, flags = WindowInfo(win._id, 7), WindowInfo(win._id, 8)
  
  -- (Un)set the transparency flag
  if color then
    flags = bit.bor(4, flags)
  else
    flags = bit.band(bit.neg(4), flags)
    color = 0
  end
  
  WindowPosition(win._id, x, y, pos, flags)
  return WindowResize(win._id, width, height, color)
end


I thought I'd try again at a generic miniwindow library, with my expectations set somewhat lower than before. :P
Amended on Tue 24 Aug 2010 07:08 AM by Twisol
Australia Forum Administrator #1
It's not a bug, it's by design.

I had that line there, and then I hit "delete".

After all:

  • Resizing a window should not necessarily change its background colour. In fact if you are using the "transparent" flag (4) then you may be surprised and disconcerted if resizing the window changes the transparency.
  • What does it matter anyway? You can always set part or all of the rectangle to any colour you like. The background colour is really just the initial background before you draw to the window, effectively an "initial default". Also it is used for the transparency.


However I am prepared if this really bothers anyone to add the flag Fiendish suggested, so that WindowCreate can optionally keep hotspots. Then you can indeed remake a window keeping everything the same except the dimensions, flags, and background colour.

Twisol said:

The background color is now one of the only things you can't change on the fly ...


Or the flags.
Australia Forum Administrator #2
And to be fair, it's called WindowResize not WindowReconfigure.
USA #3
Nick Gammon said:
*Resizing a window should not necessarily change its background colour. In fact if you are using the "transparent" flag (4) then you may be surprised and disconcerted if resizing the window changes the transparency.

I'll grant you that, but then why can't WindowResize() use the background color provided to WindowCreate()? I -would- be happier if there was just a WindowBackground() function, anyway; you can see the hackiness in the original post to make sure I only change the pertinent parameters.

Nick Gammon said:
*What does it matter anyway? [...] Also it is used for the transparency.

Yes, exactly.

Nick Gammon said:
Or the flags.

That's what WindowPosition() is for.

long CMiniWindow::Position(long Left, long Top, 
                           short Position, 
                           long Flags) 
  {
  m_Location.x           = Left     ;
  m_Location.y           = Top      ;
  m_iPosition            = Position ;
  m_iFlags               = Flags    ;

  return eOK;

  } // end of  CMiniWindow::Position
Amended on Tue 24 Aug 2010 07:25 AM by Twisol
Netherlands #4
Twisol said:

Nick Gammon said:
*Resizing a window should not necessarily change its background colour. In fact if you are using the "transparent" flag (4) then you may be surprised and disconcerted if resizing the window changes the transparency.

I'll grant you that, but then why can't WindowResize() use the background color provided to WindowCreate()? I -would- be happier if there was just a WindowBackground() function, anyway; you can see the hackiness in the original post to make sure I only change the pertinent parameters.

I can see situations where one might want to increase the size of their miniwindow, but not have the new area have the same shade as the background color configured for that window. On the other hand, two WindowRect() calls could fix any such color issue.

I guess I don't care either way, but I see the source of the confusion, and would tentatively support removing the transparency flag from here and using the one set in WindowCreate instead, as it only seems to clutter the API and add little functional meaning.

Twisol said:
Nick Gammon said:
*What does it matter anyway? [...] Also it is used for the transparency.

Yes, exactly.

Thanks for the chuckle. :)
USA #5
Worstje said:
I can see situations where one might want to increase the size of their miniwindow, but not have the new area have the same shade as the background color configured for that window. On the other hand, two WindowRect() calls could fix any such color issue.

I'd love to hear an example. I don't doubt it could be useful, and hence it should definitely be "possible", but I don't think it's nearly so prominent that it needs something more than your suggested two WindowRectOp() calls.

Worstje said:
I guess I don't care either way, but I see the source of the confusion, and would tentatively support removing the transparency flag from here and using the one set in WindowCreate instead, as it only seems to clutter the API and add little functional meaning.

Transparency flag from where? WindowResize() doesn't have one.

[EDIT] As an aside, I've long disliked the odd color-keying transparency miniwindows employ, and I'd love to see true alpha-channel support in miniwindows.
Amended on Tue 24 Aug 2010 07:57 AM by Twisol
Australia Forum Administrator #6
Twisol said:

As an aside, I've long disliked the odd color-keying transparency miniwindows employ, and I'd love to see true alpha-channel support in miniwindows.


As I think I mentioned elsewhere, that could be done, at a considerable hit for speed. Since to do that on a pixel-by-pixel alpha channel means that each each pixel has to be multiplied by the alpha channel amount, per pixel, based on the value of the original, the value of the alpha pixel, and the value of the miniwindow pixel. Multiply that by the thousands of pixels, even for a 100 x 100 pixel window, and that takes time.
USA #7
Nick Gammon said:

Twisol said:

As an aside, I've long disliked the odd color-keying transparency miniwindows employ, and I'd love to see true alpha-channel support in miniwindows.


As I think I mentioned elsewhere, that could be done, at a considerable hit for speed. Since to do that on a pixel-by-pixel alpha channel means that each each pixel has to be multiplied by the alpha channel amount, per pixel, based on the value of the original, the value of the alpha pixel, and the value of the miniwindow pixel. Multiply that by the thousands of pixels, even for a 100 x 100 pixel window, and that takes time.


Yeah, that wouldn't be a drop-in change. I suspect using DirectX instead of GDI might help a bit, though I don't know the details. If I remember right, though, the GDI API is a bit lacking in places, forcing you to use cumbersome per-pixel approaches.
Australia Forum Administrator #8
Twisol said:

Yeah, that wouldn't be a drop-in change. I suspect using DirectX instead of GDI might help a bit, though I don't know the details. If I remember right, though, the GDI API is a bit lacking in places, forcing you to use cumbersome per-pixel approaches.


Well I don't know how well it would work with Wine, or the Windows emulators under Mac, etc.

This is starting to take us into the realms of a graphical client, and I seem to recall some opposition to that in the mudstandards forum.

I mean, for showing the output of what is purely a text-based MUD (and MUDs are text, right?) then why do you really need to have alpha-channel fading in of miniwindows? WoW has that for chat channels, but the chat is transparent over a "picture" background (like, your 3D view of the world). I can't see a huge use for semi-transparent text over other text. It would be kind-of unreadable.
Australia Forum Administrator #9
Twisol said:

Nick Gammon said:
*What does it matter anyway? [...] Also it is used for the transparency.

Yes, exactly.


You are creating hypothetical problems here and then trying to solve them. You want to have a miniwindow that has hotspots that you want to keep (so you can't use WindowCreate) but a background colour you want to change *and* you are using transparency, so you have found a condition that the current API doesn't handle.

Look, I have seen plenty of APIs that handle every conceivable situation, but are unusably complex.

Give me a concrete example of where you need to use transparency, need to change the background colour, and need to keep hotspots (and not just for some generic library, but an actual real-world example) and I will be interested, maybe. Remember all this support is done for free.
Australia Forum Administrator #10
Twisol said:

I thought I'd try again at a generic miniwindow library, with my expectations set somewhat lower than before. :P


So the addition of a couple of new functions has lowered your expectations? Don't use them then.
Netherlands #11
In Twisol's defence... I don't think his lowering his expectations has anything to do with you adding new features/functions, on the contrary. It has everything to do however with his failed former attempt that was a bit too idealistic in nature, thus making it hard to be finished in anything other than a disappointment.

So this time, he has set realistic expectations, and far more likely to be smiling when he finishes work on it. :)

(Why do I know all this? Been there, done that. That's all I'll say on the subject.)
USA Global Moderator #12
Quote:
(and MUDs are text, right?)

Not in my universe. :)

Quote:
I can't see a huge use for semi-transparent text over other text. It would be kind-of unreadable.

Regardless of the content of the miniwindow (it may not contain text, after all), I think that window transparency is a stupid feature in any user interface for exactly that reason. Blending anything that you're meant to look at with anything else that you're meant to look at just makes everything hard to look at. Alpha blended drop shadows on the other hand are awesome, though significantly less delightful in a context that generally mandates black backgrounds and not putting things on top of each other.
Amended on Tue 24 Aug 2010 02:48 PM by Fiendish
USA #13
Nick Gammon said:

Twisol said:

Yeah, that wouldn't be a drop-in change. I suspect using DirectX instead of GDI might help a bit, though I don't know the details. If I remember right, though, the GDI API is a bit lacking in places, forcing you to use cumbersome per-pixel approaches.

Well I don't know how well it would work with Wine, or the Windows emulators under Mac, etc.

Just fine, most likely. Wine supports several rather graphically-intense games. Anyways, this is getting off-topic.

Nick Gammon said:
I mean, for showing the output of what is purely a text-based MUD (and MUDs are text, right?) then why do you really need to have alpha-channel fading in of miniwindows?

I'm not thinking of it so much for the end result, but for compositing windows together (using WindowImageFromWindow and such).

Nick Gammon said:
Look, I have seen plenty of APIs that handle every conceivable situation, but are unusably complex.

Give me a concrete example of where you need to use transparency, need to change the background colour, and need to keep hotspots (and not just for some generic library, but an actual real-world example) and I will be interested, maybe.

It's not about using them at the same time. I'm just writing an object-based wrapper API for miniwindows, and I'm trying to make it simple. The problem I have is that the MUSHclient API right now handles too many things within singular functions. This bug (now feature-request) stems primarily from me trying to make my Window.new function smaller, ideally to Window.new(width,height). Everything else can be managed afterwards.

Nick Gammon said:
Remember all this support is done for free.

Ouch. It's a one-liner change, surely this can't be about the effort involved to do this. Did I say something wrong?

I'm not doing any plugins right now. In fact, I haven't for months. All my MUSHclient time has been focused on libraries (some of which worked out, some of which didn't), and the source code. I don't, strictly speaking, need to work on this window API. But I want to make miniwindows approachable.

Is it any skin off my back if this isn't done? No. Unlike the sensi-hotspot thread, I'm not working on anything that would require this. It would just make my API that much cleaner.

Can I write this myself into the client? Sure I could. Is that useful to everyone else? Not really. I need to discuss it here, and if we decide it's good, then I have no problem providing a patch. But after all the other effort I've put into my fork - don't get me wrong, I understand your reasons - I'm not going to add any more new features until I know what their future will be.

Worstje said:
In Twisol's defence... I don't think his lowering his expectations has anything to do with you adding new features/functions, on the contrary. It has everything to do however with his failed former attempt that was a bit too idealistic in nature, thus making it hard to be finished in anything other than a disappointment.

So this time, he has set realistic expectations, and far more likely to be smiling when he finishes work on it. :)

(Why do I know all this? Been there, done that. That's all I'll say on the subject.)

You nailed it, Worstje. Thanks!

Nick, just to clarify, the recent functions actually spurred me to try again. I was (and am) sure that the new functions would let me simplify my API even more (WindowMoveHotspot for the WIN).
Amended on Tue 24 Aug 2010 03:45 PM by Twisol
USA #14
You can still keep your library's APIs simple while working around whatever you want to work around in MUSHclient's API. When asked for a concrete use case, I don't think it's really an answer to say that you're trying to keep some API simple; just push the feature to the API if you have to. Or keep it simple and don't handle certain cases (perhaps with a warning).

I don't understand why you think the underlying API affects your API. Even if the MUSHclient API were utterly nasty, you can still write a nice API on top of it, even if it goes through many contortions under the hood. A nasty core API would affect the implementation under the hood of your API, sure, but not the API itself.
USA #15
David Haley said:
You can still keep your library's APIs simple while working around whatever you want to work around in MUSHclient's API. When asked for a concrete use case, I don't think it's really an answer to say that you're trying to keep some API simple; just push the feature to the API if you have to. Or keep it simple and don't handle certain cases (perhaps with a warning).

I don't understand why you think the underlying API affects your API. Even if the MUSHclient API were utterly nasty, you can still write a nice API on top of it, even if it goes through many contortions under the hood. A nasty core API would affect the implementation under the hood of your API, sure, but not the API itself.


Oh, sure, I agree. But there's literally no way to change the transparency color once you've created the window, without recreating the window. And recreating the window (and all the work it entails to keep everything else the same) is too much work just to remove one parameter from Window.new(). When the underlying API literally can't do something, you can't reasonably expect a wrapper API to do it.

Like I said, it's no skin off my back if nothing's done. I simply see a problem, and I thought we might be able to find a reasonable solution.


By the way, I -did- go through a lot of contortions with the miniwidget library project. There are very real barriers to making a nice wrapper API. Just like Nick said, this is all done for free, and there's a tipping point where so much effort is involved for not enough gain.
Australia Forum Administrator #16
Twisol said:

Ouch. It's a one-liner change, surely this can't be about the effort involved to do this. Did I say something wrong?


You filed as a bug report something that is behaving exactly as documented, and therefore is not a bug. From the documentation for WindowResize:

WindowResize docs said:

This resizes an existing miniwindow of the given name.

If the new size is larger than the existing size the BackgroundColour is used to fill any newly exposed area.

...

Any existing hotspots, images, and fonts are preserved. All other window parameters for this miniwindow are unchanged.


(my emphasis)

It is done exactly this way so that you can have a colour to fill any area that is larger than the original. The "background colour" of the original miniwindow may be being used for transparency purposes, and you may not want the new area to be transparent.

This was done with careful consideration, and not an omission of a "one line change" that would improve it.


USA #17
*sigh* Yes, I'm not arguing your logic. Clearly I just misunderstood, or thought the documentation was confusing/inspecific/<other>, or something. WindowPosition affects the flags, I figured WindowResize would affect the background color.

Lets not keep referring to the OP intent every step of the way, please. Things change over the course of a discussion. I posted to bring up an issue for discussion. It's extremely discouraging when my early remarks are held against me. My very second post agreed with your logic.

Nnngh. I'm going to stop here.
Amended on Tue 24 Aug 2010 09:20 PM by Twisol
Australia Forum Administrator #18
Twisol said:

But there's literally no way to change the transparency color once you've created the window, without recreating the window.


I've added a new flag to WindowCreate that lets you keep the hotspots, as you seem to want, if I read it correctly, and also Fiendish suggested.