Canvas over textarea on Windows

I think this is an old “problem”, I remember something about it in the dusty corners of my brain, but I don’t recall a solution.

I have a canvas, laid over a textarea. The canvas is the same size. It basically draws “invisible” characters like spaces over the textarea, so that you can see what’s a space, what’s a non-breaking space, what’s an en-space, etc. Works fine on Mac of course. On Windows, it flashes up for just a second, then disappears. I think it’s falling behind the textarea control, or maybe it’s just getting overpainted somehow. I dunno.

I’ve tried refreshing it when the user changes the selection, etc., but don’t have it working yet. The textarea just seems to overwrite the canvas (z-order is theoretically ok).

Any ideas?

Overlapping controls is a recipe for flicker on Windows

[quote=193647:@Micah Bly]I think this is an old “problem”, I remember something about it in the dusty corners of my brain, but I don’t recall a solution.

I have a canvas, laid over a textarea. The canvas is the same size. It basically draws “invisible” characters like spaces over the textarea, so that you can see what’s a space, what’s a non-breaking space, what’s an en-space, etc. Works fine on Mac of course. On Windows, it flashes up for just a second, then disappears. I think it’s falling behind the textarea control, or maybe it’s just getting overpainted somehow. I dunno.

I’ve tried refreshing it when the user changes the selection, etc., but don’t have it working yet. The textarea just seems to overwrite the canvas (z-order is theoretically ok).

Any ideas?[/quote]

On PC text controls tend to mess up the Z-Order. I do not know if it is a built in animation or an outright bug but for instance TextFields take over any control laid over them when the mouse passes over. <https://xojo.com/issue/38290>

If what you want to do is to show invisible characters, as Word does, such as carriage return like ¶, space as ? etc, I would simply use a ReplaceAll to add the symbol just before the character when “show invisible” is toggled, for instance
if ShowInvisible then
Me.Text = ReplaceAll(Me.text, endofline, endofline+¶)
else
Me.Text = ReplaceAll(Me.text, endofline+¶, endofline)
end if
This does not disrupt too much wrapping and justification, and is easy to implement.

Hi Michel,

Actually, I’ve been doing that for a few years now, and people pretty much hate it. There are several problems: if you double click on a word, it no longer selects just that word, because the control doesn’t know that whatever character you used to represent a “space” is in fact a space. Similarly, wrapping no longer works, because the symbol you use for space is not in fact a space. There are some other issues, but those are the big ones.

It’s a real shame, because the canvas works perfectly on the mac, and lets double-click select a word, and keeps the wrapping working, etc.

Norman: Anything like double-triple-super-buffered offscreen controls that I could deploy to make this work? Or do I just need to surrender?

[quote=193710:@Micah Bly]
Norman: Anything like double-triple-super-buffered offscreen controls that I could deploy to make this work? Or do I just need to surrender?[/quote]
Yup - move those folks to OS X :slight_smile:
All kidding aside this is more an issue with the Win32 controls themselves than anything else
Windows doesn’t composite like OS X does - so you have flicker issues.
.Net is more like OS X in how it composites and that takes care of a lot of the issues for you (as you’ve noticed on OS X)
We dont have a .Net based framework though

But FYI the code editor in the IDE, while oriented to writing program code, could be made to do just about anything and it IS based on the open sourced Text Input Canvas
The BEST thing about this is because it IS a canvas you can draw whatever you want however you want where ever you want
so your popovers could just be pictures that you composite (which is what you’re trying to do with 2 controls) then removing the “overlay” which has the special marker & draw
(FYI BKeeney’s Formatted Text Control uses it)

Its more work BUT you can make that work and it won’t flicker because … HEY ITS a canvas you can double buffer this thing !

This would basically amount to a rewrite of that portion of your program (and I have no idea how big or small a job that is for you)

It may be so big that, for Windows, this is just something you don’t do

But thats your call
Overlapped controls just won’t work on Windows

[quote=193710:@Micah Bly]Hi Michel,

Actually, I’ve been doing that for a few years now, and people pretty much hate it. There are several problems: if you double click on a word, it no longer selects just that word, because the control doesn’t know that whatever character you used to represent a “space” is in fact a space. Similarly, wrapping no longer works, because the symbol you use for space is not in fact a space. There are some other issues, but those are the big ones.

It’s a real shame, because the canvas works perfectly on the mac, and lets double-click select a word, and keeps the wrapping working, etc.

Norman: Anything like double-triple-super-buffered offscreen controls that I could deploy to make this work? Or do I just need to surrender?[/quote]

You have not quite read what I wrote. You do not replace space by dot alone. You replace space by space+dot+space (or thin space &u2009), so double click works as usual. Same thing for Endofline. replace EndOfLine by ¶+EndofLine and return is still there. Same thing for Tab, which is replaced by space+?+Tab. None of that will modify sensibly the text formatting. It is simple, and I believe that is the way Word works.

There may be a way with the canvas, though. I just tried the first part : place a canvas over the TextArea, double buffer it. In TextChange, put

Canvas1.Invalidate

In Canvas1.Paint:

TextArea1.DrawInto(g,0,0)

Then you do your stuff with the characters.

Hi Michel,

Thanks for the clarification, and the additional suggestion. The drawinto one kind of works, but you run into trouble with the canvas overdrawing the cursor and selected text from the textarea. That doesn’t get transferred with the .drawinto. close, but no cigar.

For the thinspace-dot-thinspace idea, that probably would work, especially if one used zero width non-joiner instead of thinspace, but there are a couple of problems for my situation: it makes the cursor action odd. I would have to tell the cursor to jump 3 to the right on every right-cursor, instead of one, if it encounters are package of 3 “visible space” characters. And then, no space characters, and that includes ZWJ and ZWNJ characters, are out of scope for actual usage, so there would be risk that when “cleaning” the invisible characters out (for copy/paste, or for saving, or whatever), we could eat a character that actually had semantic meaning in the source text. And that would be “bad”. But I will still hold this as a backup plan, thanks!

Norman: I have downloaded that, and I think we need to start over with that. We have some other needs that we have not been able to accomplish with the current textarea, and we were planning to go to a canvas-based control anyway. Two questions:

  1. any documentation or basic sample projects available? I see note from BKS that there basically is no documentation, but has anyone come up with anything in the meanwhile (since release)?
  2. any idea if this handles right-to-left text correctly? Or is it so low-level that we would be rolling that ourselves anyway?

[quote=193821:@Micah Bly]
Norman: I have downloaded that, and I think we need to start over with that. We have some other needs that we have not been able to accomplish with the current textarea, and we were planning to go to a canvas-based control anyway. Two questions:

  1. any documentation or basic sample projects available? I see note from BKS that there basically is no documentation, but has anyone come up with anything in the meanwhile (since release)?
  • none that I’m aware of
    ask questions and we’ll answer them :slight_smile:
  1. any idea if this handles right-to-left text correctly? Or is it so low-level that we would be rolling that ourselves anyway?[/quote]
    Since its a canvas you draw everything so thats up to you
    The reason this was created was so the various input mechanisms on the various OSes would work correctly
    For instance on OS X if you open TextEdit and type an “e” and just press & hold you get the variations pane to select one from
    With the old keyboard handling you could not make that work but in the text input canvas you can