[Scummvm-devel] New GUI thoughts in the Wiki
Max Horn
max at quendi.de
Sat Nov 19 09:05:15 CET 2005
Am 19.11.2005 um 15:50 schrieb Marcus Comstedt:
>
> Max Horn <max at quendi.de> writes:
>
> [...]
>> For briefness I'll just talk about DLE's in the following :-).
>>
>> in OSystem:
>> DLE_ID appendElementToDisplayList(DLE e);
> ^^^^^
> Should probably be DLE& e :)
No, I wrote DLE on purpose -- because this is just a *sketch* and it
just means to roughly outline which data would be passed where,
etc.. :-). Whether to use DLE, const DLE &, DLE & or DLE * -- we'll
see :-)
That said, we probably should document the result of this discussion
in the Wiki, too :-).
[...]
> For this dirty-flag to be meaningful, you'd have to be able to combine
> multiple DL modifications without an incremental redraw in between.
> Otherwise you can just replace "mark as dirty" with "redraw". But
> I suppose we'd have some kind of transaction system similar to what
> we have today (everything done between two copyRectToOverlay() goes to
> the screen as one unit).
The dirty flag is just that -- a dirty flag. It's a single bit/bool
present for every DLE :-). There is not even a need for
"transactions" here. Rather, the display list would probably
processed inside updateScreen(). Just as you guessed (i.e. similar to
copyRectToOverlay / copyRectToScreen).
>
>> 6) If the GUI is designed carefully as to reduce overlap, this means
>> we get a relatively low redraw count
>> 7) Making it possible to modify a DLE in-place could be used to speed
>> up in-place modifications. Typical example: A button which switches
>> between active, clicked, and disabled. By using
>> updateElementInDisplayList, ideally only the button has to be redrawn
>> (assuming nothing else covers it); if we handle text via DLEs, too,
>> then the button and the text have to be redraw, which is still quite
>> moderate.
>
> Yes, if you avoid exposing the background, you'll save a lot with the
> algorithm above. However, while the updateElementInDisplayList would
> be ok for button, maybe we need to find a more general solution.
> Consider a slider for example.
Indeed. I thought about sliders/scrollbars right after sending my
mail :-).
> +------------------------------
> | A
> | +-----------------+
> | | B |C| |
> | +-----------------+
>
> A is the GUI background, which is large and covered by lots of GUI
> elements. If it becomes dirty, we'll have to redraw everything.
> B is the slider background, which is much smaller, and only covered by
> C, the slider knob.
Indeed.
> If we drag the knob, we expose a portion of B which was not previously
> visible, so it needs to be redrawn anyway (updateElementInDisplayList
> will not help us here). However, if the check described in 4) above
> only checks the bounding boxes, it will determine that A was also
> covered by C, and flag it as dirty. Unless B is semi-transparent,
> that's not really necessary. So we can tweak step 4) a bit: If, when
> scanning the DL for DLEs that were covered by the removed DLE, we find
> one which actually has the _entire_ bounding box of the removed DLE
> inside its own bounding box (and which is not semi-transparent), then
> we can terminate the scan (after marking that DLE, and those covering
> it, as dirty) and ignore the bounding boxes of any "deeper" DLEs.
> Since C is completely contained in B, only B and C would be redrawn
> when the knob moves.
And since the DL is sorted in z-order, we can just stop looking
through the DL. Neat.
In fact, the nature of our usage of the DL (for a GUI) means that
almost all (if not all) pairs of DLEs will either not overlap at all,
or one of the two will be completely contained in the other. So it
makes a lot of sense to take advantage of this to get efficient
algorithms and efficient redrawing.
So at first, this all sounds like a very good plan. And I like it.
However, it's not quite as simple as it sounds here... because not
all DLEs are covering their full area. Transparency effects etc.
partially break this approach. This is most obvious for a "text DLE",
but also for bitmaps, which usually would employ transparency at the
corners (think rounded rectangles, as seen in the concept drafts of
the GUI design).
One possible solution would be to not allow transparency. If we
restrict ourselves to single colored backgrounds, we can achieve this
by adding a "background_color" attribute to every DLE, and when
redrawing it (or portions of it), the corresponding area is first
filled with the background color. Or for bitmaps, we could simply not
allow transparency for them.
As long as we only allow 1 bit transparency, we could also rely on
the client code to take care of proper usage itself. E.g. for
buttons, the pressed / non-pressed versions would precisely cover
each other anyway, so no harm would be done if we ignored any
transparency issues for them. The story is a bit different when full
8 bit alpha blending is used, of course, because we don't want to
alpha blend a button with an older version of itself.
[... explanation how to get rid of updateElementInDisplayList by
using insertElementInDisplayListBefore ...]
Alternate suggestion: We keep updateElementInDisplayList, but
implement it by using insertElementInDisplayListBefore as you
described. This way we can drop the restrictions imposed on it. If
the size / position or type of the DLE change this way,
Makes sense, too. We could still keep updateElementInDisplayList
around for convenience, implementing it using
insertElementInDisplayListBefore.
Cheers,
Max
More information about the Scummvm-devel
mailing list