Feature request: CodeEditorComponent with proportional font

I’ve been using the TextEditor for years, for things it wasn’t meant to, such as displaying megabyte-size text files, so I’m happy to see that the CodeEditorComponent does this much faster.

I replaced some TextEditor components with CodeEditorComponents, inadvertently using the same proportinally-spaced font, and this actually works quite well for display, as long as I don’t try to highlight or edit the text.

It seems the text rendering code already works sensibly with proportionally spaced fonts, and the only things that would need change are the highlightning x positions in CodeEditorComponent::CodeEditorLine::draw and the positions calculated in getCharacterBounds and getPositionAt. Ideally, the caret positioning logic should remember the x offset rather than the column when using up/down arrows, but that’s a minor thing.

These changes won’t cause a noticeable slowdown as they are generally only used a few times per refresh, and only for text lines actually shown.

I want this because I’d like to replace the TextEditor with the much faster CodeEditorComponent in my PILS programming system. When I work with code analysis (for the time being, it’s Delphi -> C#), I often happen to dump megabyte-sized indented syntax trees which is painfully slow with the former. I’m used to working with proportionally spaced fonts and find the monospaced fonts tiring to read, plus proportinal fonts are more compact and show more text in the same area.

By the way I had great trouble with crashes from premature deletion of the CodeDocument because, for obscure reasons related to the Component/refcount/weak-reference issue, PILS queues componens for deletion in the main loop rather than deleting them immediately. I ended up with a quite horrible hack replacing the supplied CodeDocument with another that gets queued for deletion by the destructor of a CodeEditorComponent. Since your :twisted: C++ aesthetics require me to pull such nasties, perhaps you could consider making the CodeDocument object and the lexer refcounted?

I’d never given any thought about using proportional fonts in that component, but it really does require just a few minor tweaks, and you want to send me a diff, I’ll certainly take a look at them.

Works for me now, except for two minor issues:

:? Up/Down arrow is still column-based rather than x-based so a bit of slinger will occur with proportional fonts.

This should probably be fixed but I’m not quite sure where and what to fix. Rather than storing the column index, a logical x should be stored and CodeEditorComponent::getPositionAt or similar logic should be used for positioning the caret on an adjacent line.

:twisted: I kept the tab expansion as-is though it doesn’t always make sense with proportional fonts. Indenting with tabs will work OK but midline tabs won’t produce nicely aligned rows.

This would require some refactoring which neither of us are fit for right now.

I haven’t got to terms with git yet but there are only 3 replacements - search for //beginchange and you’ll find them.

Based on v.1.54.13.

Please let me know if you check it in.

Thanks Ole! I’ll take a look through it today!

Hmm, sorry - doesn’t quite work for me… Just a few little niggles - the draw() changes looked ok (but should be broken out into a function), but the stuff in getPosition and getCharacterBounds is in the wrong place - that functionality belongs in the CodeEditorLine class, and should work by looking at the tokens, not by messing about with tab-character replacement in strings (with code that you copied and pasted twice - D.R.Y please!!) If I had a spare hour, I’d fix it for you, but am too busy right now!