Neil et al
I've been doing quite a lot more work on autocompletion
to address some
cosmetic issues, and also the speed of display of large
lists. With the
exception of (1) and (2), these changes affect the
Windows build only,
although I've pushed some code down from
AutoComplete.cxx into the platform
specific ListBoxX implementations in order to speed up
the list population.
Specifically the changes are:
1) I've added SCI_AUTOCSET/GETMAXHEIGHT to allow
one to configure the number
of visible rows. The motivation for this is that the number
of visible rows
is currently hard-coded at 5, which I find a bit cramped.
The default is
still 5 so existing behaviour is maintained.
2) I've added SCI_AUTOCSET/GETMAXWIDTH to allow
one to configure the maximum
"width" of the list, where the width is expressed as a
maximum number of
characters. Of course this is an inaccurate measure
with proportional fonts,
but it is better than nothing. This is to allow one to
prevent Scintilla
showing a a ridiculously wide list, which can happen if
the auto-completion
choices include very lengthy "words". The default
setting is 0, which allows
Scintilla to auto-calcluate the width based on the widest
item as before
(though see below), thus maintaining existing behaviour.
[Regarding the choice of names for the new messages,
I'm not terribly happy
with MAXHEIGHT and MAXWIDTH since these imply
maximum pixel dimensions. I'm
open to other suggestions]
3) The calculation of the width of the widest item is now
based on the space
required to draw the actual text of the widest item,
rather than an estimate
based on the average character width. This is still not
perfect, because the
widest item is selected based on the number of
characters. However it
reduces the problem I was frequently seeing of the text
of items being
truncated.
4) Contributing to the problem of the list being
incorrectly sized (2) was
the hard-coding of extra spacing to allow for the size of
the window frame,
with this having only including a border for the height
and not the width.
I've changed this to use the AdjustWindowRect() API to
correctly account for
the frame, regardless of display settings.
5) Another cosmetic improvement is that ellipsis are
now drawn if an item
has to be truncated, e.g. because it exceeds the new
maximum width.
6) The list is now a "popup" window rather than a child.
This means it is
not clipped to the Scintilla window, which is important
when working in a
small window in a multi-window IDE. It also fixes the
cosmetic issue of the
left edge being clipped when an autocompletion list is
opened after typing a
character or two at the left edge of even a large window.
And believe me,
the activation/focus issues were pretty difficult to deal
with when making
this change :-).
7) The list now has a minimum and maximum tracking
sizes when resized by the
user to prevent it being made too small or larger than
necessary. Also it
disallows resizing that would hide the caret (i.e. if the
list is below the
caret, you can't resize the list by dragging the top edge
up). Unfortunately
the list is still flickers a bit on resize, but it is no worse
than it was
before and if anything slightly better.
8) The list box uses LBS_NOINTEGRALHEIGHT in
order to avoid leaving an
undrawn area when the user resizes the window to an
intermediate size.
9) The auto-completion list was very slow to populate for
large lists such
as one might have in an IDE when the user requests an
autocompletion list
without having typed a prefix when all global types are
syntactically valid.
By way of example I was finding it could take Scintilla in
excess of 1.5
seconds to populate a list with about 33k items in it. Of
course one might
question the usefulness of a list with 30,000 items in it,
but if the user
requests such a list with a shortcut key then they
should get it because it
is very annoying when commands sometimes work and
sometimes not. Anyway I've
managed to cut this time by almost 90% by storing the
item strings
externally rather than in the ListBox control itself and
some other
optimisations. Its still not really quite fast enough, but I
don't think it
can be made much faster using the old ListBox control
which is quite slow to
populate - in fact I found that commenting out the
SendMessage(LB_...) in my
code cut the time down to ~50mS. To address this
properly we need to switch
over to using the newer SysListView32 control because
it supports a
"virtual" mode (LVS_OWNERDATA) where one
populates it by sending it a single
message telling it how many items there are, and it
calls back to get
display information for the visible items. Or alternatively
just implement a
completely custom list - its not that far away already. I
haven't had time
to make this change yet, but to facilitate it (and for other
performance
reasons) I have reorganised the code so that the entire
list is set through
one ListBox class method call rather than the
AutoComplete class appending
all the items individually.
Lastly, a question. Does anyone have an opinion, for the
Windows platform,
on whether or not the image associated with an
autocompletion list entry
should be highlighted along with a selected item?
Currently it is
highlighted, but the native controls do not normally do
this, just
highlighting the text.
I've attached a zip containing the complete source files
that I have
modified.
Regards
Blair McGlashan
http://www.object-arts.com
Logged In: YES
user_id=1148040
Looks nice, but i have problems compiling this. :-/
scintilla\win32>mingw32-make
g++ -DNDEBUG -W -Wall -pedantic -I ../include -I ../src -Os
-fno-exceptions -fn
o-rtti -mno-cygwin -c ScintillaWin.cxx
g++ -DNDEBUG -W -Wall -pedantic -I ../include -I ../src -Os
-fno-exceptions -fn
o-rtti -mno-cygwin -c ../src/ScintillaBase.cxx
../src/ScintillaBase.cxx: In member function `void
ScintillaBase::AutoCompleteSt
art(int, const char*)':
../src/ScintillaBase.cxx:269: error: no matching function
for call to `AutoCompl
ete::Show(bool)'
../src/AutoComplete.h:60: note: candidates are: void
AutoComplete::Show()
../src/ScintillaBase.cxx: In member function `void
ScintillaBase::AutoCompleteCo
mpleted()':
../src/ScintillaBase.cxx:324: error: no matching function
for call to `AutoCompl
ete::Show(bool)'
../src/AutoComplete.h:60: note: candidates are: void
AutoComplete::Show()
mingw32-make: *** [ScintillaBase.o] Error 1
I am using Scintilla 162 and the current version of the
MinGW Compiler under Windows XP.
Logged In: NO
Have you synchronised the latest from CVS? This change
builds on the previous change (accepted into CVS, but not in
the original 1.62 release) which added the
AutoComplete::Show() member function.
Logged In: YES
user_id=1148040
Thanks for the fast answer.
Now it works. :)
AutoCompletion is now much better!
Logged In: YES
user_id=48836
Second attempt attached, modified as per Neil's comments
(dependencies on SString.h and Scintilla.h removed, unicode
string width fixed. Also:
1) Centres the current nearest match if below mid-point
2) Does not highlight the image on selection
3) Paint is double-buffered to avoid flicker on resize/scrolling
4) Couple of minor resizing issues fixed.
2nd version of modified files, replaces original
Logged In: YES
user_id=1148040
Hi Blair,
resizing is better now, but now i have problems with
scrolling. If i scroll down the first time, the list looks
like this: http://www.future-coding.de/temp/error.png
And the behavior of the list is bad. If I open the list and
type something it selects an item, but in most cases it does
not select an other item after that.
I want to handle the codecompletion like those in Visual
Studio, Delphi or those in many other IDE's.
And it is possible to change the Font seperatly for the
codecompletion? Would be great. :)
Bye
Logged In: YES
user_id=48836
Thanks for your comment:
Regarding the repaint issue on resizing, I don't experience
this issue running on Windows Server 2003, but you
prompted me to try it on Windows 2000, and I was able to
reproduce it. It appears to be related to whether list box
smooth scrolling is enabled - turning it on in 2k3 produced
the same effect. I'll take a look and sort that out.
Regarding the selection issue, I can find no problem with
that. Can you elaborate or provide steps to reproduce?
I'd like the auto-completion list to be at least comparable to
that in VS.NET (or better, since the list is resizable), which is
why I am working on it, but I have no current intention to
make a change to allow the font to be configured separately.
Please go ahead and make such a change if you want it.
Regards
Blair
Logged In: YES
user_id=12579
I still see some flicker possiblybecause some drawing is
done outside WM_PAINT upon key events. One way to avoid
flicker, depending on card/driver is to avoid touching any
pixel twice by using ExtTextOut to draw both the item
rectangle and the text in one go.
Rectangles are semi-inclusive and should be subdivided using
the same value:
rcImage.right = rcBox.left;
Logged In: YES
user_id=12579
Black blobs, similar to ganxta's example, can be caused by
items that don't have an icon as the icon area is not filled
then.
Logged In: YES
user_id=1148040
Hi,
it's easy to reproduce the selection stuff, just take this
items for the list:
abs absolute function test abstest
So I use this code to start autocompletion (it's Delphi):
Scintilla.AutoCShow(0, 'abs absolute function test abstest');
If I start the autocompletion, i cant select the item
abstest by typing. If i write abs it selects abs (right),
but if i enter the letter t of abstest it aborts (should
select abstest). What is wrong?
And what's about a seperatly font for the codecompletion?
regards
Chris
Logged In: YES
user_id=48836
Responding to Chris (ganxta):
Re incremental search (selection). Quoting from the docs for
SCI_AUTOCSHOW "The list of words should be in sorted
order.". This is because the search is done by a binary chop,
so it won't find the item if the list is not ordered. This is not
something I've changed.
Re font: As I said, not something I have plans to implement
at present, so you will have to do it yourself if you need it. I
believe there is a spare predefined style number that could be
used (Neil?).
Regards
Blair
Logged In: YES
user_id=1148040
Ah, no it works. Thanks. :)
Maybe I can try to implement the font stuff. Is there a
style number for this? If not, i will try to implement this.
regards
Chris
Logged In: YES
user_id=48836
Neil, Chris
Thanks for your feedback.
I've fixed the redrawing issues associated with smooth
scrolling and maybe some other cases where
WM_DRAWITEM is sent outside of WM_PAINT. Turned out
to be a stupid mistake in erasing the wrong rectangle. I've
also addressed the one case where I think flickering might
still be possible (which is when the selection changes and is
re-centred at the same time). Please let me know of any
other cases.
I've attached the single revised file to be used to replace
PlatWin.cxx in the previous zip.
Chris: It might be possible to use style number 38 for the list
text style, which is in the predefined range, but currently
unused as far as I can tell. Neil would have to confirm that its
unused and that consuming such as scarce resource as a
predefined style number would be acceptable, otherwise
specific SCI_xxx messages could be added to set the font
characteristics. Depending on Neil's response (and if he
accepts my autocompletion changes :-)) I might have a go at
it in thanks for your help with testing. I notice from the
archives that it is a FAQ.
Regards
Blair
Logged In: YES
user_id=1148040
Hi,
The redrawing issues doesn't appear any longer. Good work. :)
For my own use I choosed Style Number 126 for the
CodeCompletion (and 125 for CallTips).
38 seems to be unused, but what should be used for CallTips?
regards
Chris
Logged In: YES
user_id=12579
Lexers already use styles 125 and 126. HTML uses 125 for PHP
comments and 126 for PHP variables within strings.
Why do you dislike using the font of the text? For the
autocompletion list it may be possible to send WM_SETFONT to
the list as that is what is done internally. I'm going to
want more justification before allocating one of the few
available style IDs for this.
Logged In: YES
user_id=12579
Modification committed with minor changes for warnings and
layout.
Logged In: YES
user_id=48836
Neil
Thanks for accepting the changes.
Regarding the styles of autocompletion list and calltips, I
would agree with you that it makes sense for these to use
the same font as the text, especially the former. Oh the other
hand using a style allows for control over the colours as well
though, in a way that is consistent with other styles making
it easier to manage for config dialogs, etc. Have you thought
about using style numbers outside the valid range for the
configuration of styles that cannot be used in the main text
(e.g. margins, autocompletion, calltips)? These style
numbers could start from 128 or higher (or be negative), and
so not impinge on the number of styles available for use by
lexers.
Regards
Blair
Logged In: YES
user_id=12579
A well implemented addition that used ID numbers >= 256
would be good but it would have to do something about
minimizing the amount of style realization overhead so that
this doesn't result in extra slowness.