[haiku-development] Re: Set*UIColor Version 3 Patch
- From: looncraz <looncraz@xxxxxxxxxxx>
- To: haiku-development@xxxxxxxxxxxxx
- Date: Sat, 7 Nov 2015 09:28:42 -0600
On 11/7/2015 04:01, Axel Dörfler wrote:
Hi looncraz,
Yes, but there is literally no other place it can be done more
appropriately, and it enables the top view to update with layout view
colors (which, usually, will be system colors, but may be custom
colors [previously not possible]).
I'd doubt that :-)
Haiku added the layout API, and we're free to solve things cleanly here.
If an application that uses the layout API does not work correctly, it
surely can be fixed, too.
Only when using the builder on a window itself can the layout API do the
trick, otherwise there's no external way to access a window's top view.
It could be done BView::SetLayout, but then we're testing for every view
in the hierarchy when we know the exact point which it needs to be set
is when the window itself has SetLayout called. Unless, of course, the
top view were to default to system colors OR layouts created a parent
view OR the window's top view was made accessible to layouts in some way.
It's all about having the top view adopt the colors used by the layout
view so we don't have a white window background and not blindly using
system colors, limiting adoption of the layout API to just those who
want to use system colors.
I'd only automatically resize applications that are using the layout
API. Everything else should only act manually - I don't see how a
blacklist is needed there.
That is the fall-back plan, but plenty of existing apps already have a
horrible behavior with large fonts, and a few can handle changing font
sizes with ease without layouts. The blacklist could be as simple as a
list that forces listed applications to use a set font size
(appsig:fontsize\n), the app_server would maintain the list and when an
app is created it would send the fonts with that overridden size when
called upon doing so.
My current state in fontaware is experimenting with this almost entirely
on the client side, since it's easier to change :p
I think a BWindow flag B_FONT_AWARE would be appropriate. When set, the
default behavior would be to set the font on all attached views. If
using a layout, InvalidateLayout(), otherwise ResizeToPreferred() on
each view. Then, each BView/window will respond to B_FONTS_UPDATED, see
if the font size changed (to be included in the message), and move
children around as needed (except when a layout is present).
A more in depth method which won't require as much work on the part of
applications, which would probably also work best, but definitely more
work, would be to have BViews keep a snapshot of original placement and
sizes at a starting font size. They need a their original frame,
original spacing from other objects (perimeter), a cached resizing mode,
and starting font size all stored. When a font size is changed, the
hierarchy is rebuilt from the bottom-most view down. Since most/all
system interface objects use ResizeToPreferred() properly, we can rely
upon that to to create the new sizes, starting from the end node and
working back, propagating resizes, and maintaining spacing, as we go.
One thing I'd have to do is create two scaling factors for the spacing,
width would be based on the relative change in a string's width, and
height would be based on the font height ratio (who would have guessed?
;-) ).
| Window ______________|
|[TopView ]|
|[ [ Inner View ]|
|[ [BTextControl [textview] ]|
| [BButton] [BButton] |
Here, the bottom-most view is the textview for BTextControl, so it'd
scale first, followed by BTextControl (which would need to maintain its
relative divider size), then the buttons, which would scale, and move
relative to the rest, and the InnerView, which would to the same. The
top view would then resize to fit its contents, the window would adopt
that new size, and then all resizing modes are restored and, finally,
resized hooks are manually called.
This should work with apps that don't have good font handling as well,
so we'd need a list of applications that will start at a set font size,
then will have their fonts sizes updated. The same list as above would
then become a compatibility adaptation list, mostly for the closed
source apps people can't fix, or ones too unwieldy to fix (unless I get
around to it ;-)).
So the list would need quite a few optional entries
AppSig
#AppVersion = <-"2.0.1"
@MaxFontSizes = plain:14, bold:16, fixed:14, menu:18
@ForcedColor = *:default
@StartFontSizes = *:12
This would have the application, with a version less than, or equal to,
2.0.1, start with all font sizes of 12, only use default colors (ignore
user customized colors), then it would rescale to the given font sizes
after the fact, IF the system font sizes are that size or larger.
Obviously, one option is simply @ForcedFontSizes, which will result in
the application ALWAYS using the set font sizes (ignoring any user
choices entirely).
It would be better to be able to do this for each window independently,
but that's really not needed.
The idea would be to also allow applications to access these
capabilities, and to be able to set their own colors and fonts as they
see fit. Right now, I added the following to BApplication
bool FontUpdatesEnabled() const
void SetFontUpdatesEnabled();
bool ColorUpdatesEnabled() const
void SetColorUpdatesEnabled();
SetAppColors(const BColorMap* colors) ;
SetAppFont(font_which which, const BFont* font);
// a NULL font will use system fonts
Obviously, this requires quit a bit of reworking in the app_server as
well as the client side, but I'm not shy about stirring the pot for the
desired results ;-)
The advantages to this, I think, are pretty obvious. There are many
applications which do not like my 18pt font sizes, and a few that simply
don't like customized colors (though the open source ones will be
getting a visit from me ;-) ). If I could force them to use 14pt or so,
they become usable once again.
To properly resize apps using the layout API, however, the spacing
constants must be evaluated at layout computation time, not when the
values are set, as it is now.
That explains a little bit of what I've seen, I'll see about addressing
that (since layout enabled views should require no fancy effort).
I'm really impressed how well it worked (even with legacy apps) when I
simply iterated through, set font sizes, then called ResizeToPreferred()
with no other work. Naturally, views would then step onto each other,
but it let me see exactly what should be needed to be done to support
all applications.
As always, I love to be shown the error of my ways, don't be shy!
--The loon
Other related posts: