BScreen ColorForIndex behaving funny - is it me or Haiku?

I recently added highlighting support tp my simple markdown editor, but the coloring behaves in a funny, unexpected way.

The initial color is taken from the hash of the highlight label (so it is always the same color for same highlight types), and I calculate a color offset from that hash like so:

Then, in the derived custom BTextView itself, I do the actual highlighting and redraw, which works just fine when scrolling:

However, on resize, the colors change (!), which makes absolute 0 sense to me.
I tried all possible variations of blending and drawing modes, but since it works in normal circumstances e.g. for scrolling, the drawing itself is OK.
Also, I checked that the entire area is prepared correctly by BTextView before I redraw the highlight, so it cannot be a wrong overdrawing of the blending or such.

Any ideas? Or is it a bug in BTextView itself?

I donā€™t think the ColorForIndex method really makes any sense to use when not in indexed (e.g. 256-color) mode, it may just return bogus data in that case.

Yeah thatā€™s what I feared. However it does work and return suitable colors, the color is only derived once and working fine, also during redraw (on scrolling), just not on resizingā€¦ how can that redraw be different?

I was just searching for a quick and easy way to retrieve some standard colors without the need to configure my own - is there an alternative way to do that? Like a default Haiku palette/color scheme beyond the ui_colors?

A glance at the source code shows that if no palette is defined, it may just return bogus data from the stack, and perhaps resizing alters the stack frames here. Either way we should fix this and probably have it return a constant black instead.

There arenā€™t any colors beyond the ā€œui_colorsā€, but of course you can use ā€œtint_colorā€ and ā€œmix_colorā€ with these to get some more variants.

1 Like

ok thanks for the quick heads-up! That explains the odd behavior.
Will use well defined colors now.
The gradients are a pretty neat addition btw:)

What do you expect for palette colors?

We now have the hsl api So I could add such an api, what would the requirements be?

For Renga I have implemented XEP-0392: Consistent Color Generation :

https://pulkomandy.tk/gerrit/plugins/gitiles/renga/+/refs/heads/main/ui/TalkView.cpp#797

https://pulkomandy.tk/gerrit/plugins/gitiles/renga/+/refs/heads/main/ui/hsluv.c

This allows to get a set of colors with consistent visual lightness and saturation, but different hues. So you just pick two fixed values (depending on light/dark mode for example) and let the algorithm determine the third.

The HSL color space does not work as well for that, this is why XEP-0392 went with yet another colorspace.

1 Like

Cool let me try that. I guess Iā€™m just missing the indexed color palettes of my old and golden Amiga daysšŸ˜…

Seriously though Iā€™m still puzzled as to why the perfect valid color I derive with my algorithm is distorted although itā€™s copied into a new color and never changed againā€¦

Update: ok thatā€™s a really interesting proposal but way too much code for this simple task, Iā€™ll stick with a good set of default colors from a free Sublime theme:) Gonna pick this one probably:

For now Iā€™d be happy if rgb_color had a HEX constructor so I can use the way more common HEX colors without any hassle:)

If your hex code is #AABBCC, use make_color(0xAA, 0xBB, 0xCC). Does that really need a separate constructor? What would it construct from? An uint32? Then we need to worry about channel order and endianness. A string? Seems quite inefficient when the conversion is direct with just a bit of reformatting.

2 Likes

Ah thanks didnā€™t know about that one!
Yes it would be a convenience when working with outside values from templates etc., esp in the web world.

Anyway thereā€™s a handy stdlib function for that with std::hex or std::ul, see:
https://en.cppreference.com/w/cpp/io/manip/hex
Given that BString is also streamable, this should be good.

hmmm as I have feared this did not help. Please @PulkoMandy or @nephele if you have any idea Iā€™d be very delighted to fix this once and for all and leave the frustration in the old year :wink:

You can reproduce also with hiding the window and bringing it into view again, so it is a redraw issue. However, I do exactly the same thing in the only redraw method and the updated region is definitely correct, so Iā€™m out of ideas currentlyā€¦

(I even added a proper Invalidate call when creating/updating the highlight here:
senity/src/EditorTextView.cpp at 1837a827ed9a8b5ec553d96c17ea25030029fe6e Ā· sen-laboratories/senity Ā· GitHub)

tackled this issue again today and I have more and more suspection that this might be a bug in Haikuā€™s TextView rendering on Window resize or something with BView redraw.

I even tried posting a B_WINDOW_RESIZED message with the correct Window bounds and it was still behaving differently when resizing manually:

BMessage resizeMsg(B_WINDOW_RESIZED);
BRect windowBounds(Window()->Bounds());
resizeMsg.AddInt32("width", windowBounds.Width());

(I even tried increasing size by 1 to rule out any caching / optimization).

1 Like

still happening on latest nightly hrev58503 and I have not the slightest idea why:(
cc @PulkoMandy @nephele @waddlesplash

There is no need to cc people. We already receive forum notifications if we want to.

Sorry was just out of desperationā€¦

Hi grexe, I can check out your issue, but at the moment I donā€™t have any working desktop to do so. And on a phone this is quite hard to do. : )

1 Like

Itā€™s just looking more and more like a bug in BWindow/BView redraw on resize in combination with alpha drawing modes, as I have pretty much done everything I can from my side to rule out any bugs in my custom viewā€¦

You donā€™t want to subtract 1 there (or in the current code, that does the same).

On redraw, you call BTextView::Draw, which draws the text and the caret or selection if necessary. Then you do your own highlighting, possibly over a selection. In fact, the only way Iā€™ve found to have appā€™s highlights now is to add them to selected text.

So you have some color C. Selecting draws that part as 1-C. Highlighting with color H draws it as (1-C+H)/2. If you now unselect it, it becomes 1-(1-C+H)/2 (thereā€™s no full redraw, just an inversion of the affected area). If a part highlighted but not selected is redrawn, it shows the expected (C+H)/2. If that is selected now, it becomes 1-(C+H)/2.

You can workaround it with:

void EditorTextView::Draw(BRect updateRect) {
	int32 start, end;
	GetSelection(&start, &end);
	Select(start, start);
	BTextView::Draw(updateRect);

	// redraw text highlights if any inside updateRect
	[...]

	Select(start, end);
}

I donā€™t know if that would have ill effects, though.

Thereā€™s probably also a problem in BTextView or the scroll. Iā€™ve noticed the ā€œmarginā€ changing on first vertical resize or scroll, causing the appā€™s highlights to be slightly off.

1 Like