drawstring+condense causes choppy listbox scroll

Hi!

I am currently developing a database app utilizing a listbox showing some records and notice the poor scrolling performance
while using g.drawingstring with condense.
I made a standalone example with a listbox out of the box with 200 row and 10-20 columns that prove this case. If you turn condense off (=0) the string
is not truncated but scrolling is good but if you turn it “on” (truncating the string), it seems like the additional computing time
is needed which makes the scrolling choppy.

Have you ever notice this issue and if so what can I do to solve it ?

yes, I noticed that slowdown and could reduce it somewhat by:

  • avoid focusring on listbox
  • avoid or at least reduce and optimize code in CellBackGroundPaint
  • avoid or reduce and optimize code in CellTextPaint

Indeed drawing a string condensed is slow, I’ve not measured how slow, but it is a slower than just drawing a string.

I’ve toyed with different techniques for trying to draw the string condensed on OS X and have discovered some interesting and overly complicated ways of doing it, but they all seem to come at the expense of performance.

The quickest way I found is to pre trim the string and use the regular drawstring function, but I realize that it’s not the most accurate or helpful way to do it.

[quote=160373:@Sam Rowlands]Indeed drawing a string condensed is slow, I’ve not measured how slow, but it is a slower than just drawing a string.

I’ve toyed with different techniques for trying to draw the string condensed on OS X and have discovered some interesting and overly complicated ways of doing it, but they all seem to come at the expense of performance.

The quickest way I found is to pre trim the string and use the regular drawstring function, but I realize that it’s not the most accurate or helpful way to do it.[/quote]

Hi Sam,

That’s what I have in mind too also caching some values ect. I am puzzled that this issue is so obvious but not
addressed by Xojo. I really dislike taking care of this but it’s also owing to the the fact we don’t have a native control.
So Instead of focusing on developing a project I need to intergrate a native ListBox or something. This is a pain.

make a new feedback case # 37802 but it seems there a a least a similar feedback since 2011 incl slow stringwidth speed.

So guys. The only cure I could find is to precalc the size of the string and put it into a dictionary
to cache it. You need to clear the dict with DeleteAllRows method for instance. If i dig more into the issue
it i may find some useful cocoa stuff but I doubt it somewhat as Sam is also good at it but didn’t post a solution.

Scrolling is smooth now :slight_smile:

[code]CellTextPaint()

static ellipseCharSize as integer = g.StringWidth(".")*3
static yPos as integer = (g.Height+g.TextAscent)/2

dim cellText as string = me.cell(row,column)
dim dictText as string = d.Lookup( cellText, “” )
if dictText.Len = 0 then
dim w as integer = g.StringWidth( cellText )
if w>=g.Width then
dictText = cellText.Left(g.Width\ellipseCharSize)+"…"
d.value(cellText) = dictText
g.drawstring dictText,0,yPos,0, false
else
g.drawstring cellText,0,yPos,0, false
d.value(cellText) = cellText
end if
else
g.drawstring dictText,0,yPos,0, false
end if
return true[/code]

made a workaround if you resize the columns.
example project attached. Works quite good.
Listbox with Cache

Solved it using a new cache logic!
I have now a smooth scrolling experience even if you resize the column.
It took me a day but this is really great!

listbox with cache reworked

In all honesty I didn’t post a solution as I’ve yet come across one that I find to be adequate. I have a clients app that at some point I will need to optimize this too (but it’s not in a listbox).

For my own application, I ended up using CGLayers, and at which point the only way to draw text is via Core Text. Which does allow me to condense text. You can see an example here https://twitter.com/Sam_Ohanaware/status/540355085054664704/photo/1

However for normal graphics in Xojo Core Text is roughly about as slow as normal text drawing, which means that the performance issue is probably a Core Text issue.

Hi Sam,

Have tried it using drawInRect in combination with NSString. That was an
approach before. It worked for sure but ended up being slower than the Xojo DrawString.

I’ve changed some things in the current example to make it possible to sort the columns. I think its ok
but to be honest I am somewhat feed up spending time for enhancing Xojo controls.
Wanna have a native listbox support. :slight_smile:
listbox /w cache

I was going check out your example but I have no twitter.(Oh my gosh…) Can you post/upload it somewhere else ?

Sure

Hey Sam,

Looking at your picture you posted above, do you know why drawstring to a picture object
result in a less sharp font string as you would draw it directly to an existing context with g.drawstring ?
I tried it passing the same parameter to the new Picture object I got from the “g” Graphics meaning
p.Grpahics.Textfont = g.TextFont
and so…

but the result isn’t the same.
Big questionmark over me head.

Disable font smoothing?

Declare Sub CGContextSetShouldSmoothFonts Lib "Cocoa" (C as integer, value as boolean) CGContextSetShouldSmoothFonts( g.handle( g.handleTypeCGContextRef ), false )

Before you draw your text to the graphics object.

strange, it doesn’t have an impact on when drawing to a picture object via p.graphics.drawstring although
i have used the p.graphics.handle

Are you drawing to a Retina display? In the image above I’m drawing to CGLayers (which are derived from the current context) and the declare works, but CGLayers use a different backing source than a Xojo image.

I’ve not tried using it with a Xojo picture, I have to confess.

It’s not a retina. I would say it doesn’t work for a xojo picture but I could
find a good way. I have disregarded caching the selected row and just
painted it as it is.
Thank you so much for your help. Would be cool of you could release the CGLayer stuff.

The trouble with CGLayers, is that to use them correctly you need to use OS drawing functions. I have an idea that would make it ‘easier’ for Xojo developers to work with them. If there is enough demand I can work on it.

The second thing is that under Yosemite, it’s possible to break them, losing any advantage. I’ve reported it as a bug to Apple, but they don’t seem to be working very hard to solve any of the bugs I’ve reported :frowning:

Hi Sam,

You don’t need to work up CGLayer if there’s a possible break but If Apple decides to sort out the bug I can imagine making it free available for the Xojo programers or as a community project if you like. I really like your attitude
to share your knowledge.

It’s a bit off-topic but I kudos for your piDogScrollerCanvas+Layers. I have seen the demo and
it looks pretty cool although I have some suggestions for your scroller behavior (a pageScroll and if you are
clicking in the knob->it should not scroll) which I have implemented in my own :
custom listbox w/ custom overlay scroller[/quote]

Hi Sam,

You don’t need to work up CGLayer if there’s a possible break but If Apple decides to sort out the bug I can imagine making it free available for the Xojo programers or as a community project if you like. I really like your attitude
to share your knowledge.

It’s a bit off-topic but I kudos for your piDogScrollerCanvas+Layers. I have seen the demo and
it looks pretty cool although I have some suggestions for your scroller behavior (a pageScroll and if you are
clicking in the knob->it should not scroll) which I have implemented in my own :

custom listbox w/ custom overlay scroller

Hi Rob,
I think you’re getting me confused with Jim :slight_smile:

Both Jim and I, have experience on similar subjects and have competing tools.

As for CGLayers, it seems that they might be a lost cause :frowning: I’ve run into more situations where they don’t work under Yosemite and as Apple don’t seem interested in fixing them, I’m now exploring alternative ways of accomplishing the same thing.