]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/CallTip.cxx
80fd55d7b85dc9cdd178cf42fb4203fe065116b2
1 // Scintilla source code edit control
3 ** Code for displaying call tips.
5 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
13 #include "Scintilla.h"
18 inCallTipMode
= false;
21 rectUp
= PRectangle(0,0,0,0);
22 rectDown
= PRectangle(0,0,0,0);
27 colourBG
.desired
= ColourDesired(0xff, 0xff, 0xff);
28 colourUnSel
.desired
= ColourDesired(0x80, 0x80, 0x80);
29 colourSel
.desired
= ColourDesired(0, 0, 0x80);
30 colourShade
.desired
= ColourDesired(0, 0, 0);
31 colourLight
.desired
= ColourDesired(0xc0, 0xc0, 0xc0);
41 const int widthArrow
= 14;
43 void CallTip::RefreshColourPalette(Palette
&pal
, bool want
) {
44 pal
.WantFind(colourBG
, want
);
45 pal
.WantFind(colourUnSel
, want
);
46 pal
.WantFind(colourSel
, want
);
47 pal
.WantFind(colourShade
, want
);
48 pal
.WantFind(colourLight
, want
);
51 static bool IsArrowCharacter(char ch
) {
52 return (ch
== 0) || (ch
== '\001') || (ch
== '\002');
55 void CallTip::DrawChunk(Surface
*surface
, int &x
, const char *s
,
56 int posStart
, int posEnd
, int ytext
, PRectangle rcClient
,
57 bool highlight
, bool draw
) {
59 int len
= posEnd
- posStart
;
62 for (int i
=0;i
<len
;i
++) {
63 if (IsArrowCharacter(s
[i
])) {
72 for (int seg
= 0; seg
<maxEnd
; seg
++) {
73 int endSeg
= ends
[seg
];
74 if (endSeg
> startSeg
) {
75 if (IsArrowCharacter(s
[startSeg
])) {
76 xEnd
= x
+ widthArrow
;
79 rcClient
.right
= xEnd
;
81 const int halfWidth
= widthArrow
/ 2 - 3;
82 const int centreX
= x
+ widthArrow
/ 2 - 1;
83 const int centreY
= (rcClient
.top
+ rcClient
.bottom
) / 2;
84 surface
->FillRectangle(rcClient
, colourBG
.allocated
);
85 PRectangle
rcClientInner(rcClient
.left
+1, rcClient
.top
+1, rcClient
.right
-2, rcClient
.bottom
-1);
86 surface
->FillRectangle(rcClientInner
, colourUnSel
.allocated
);
88 if (s
[startSeg
] == '\001') {
91 Point(centreX
- halfWidth
, centreY
+ halfWidth
/ 2),
92 Point(centreX
+ halfWidth
, centreY
+ halfWidth
/ 2),
93 Point(centreX
, centreY
- halfWidth
+ halfWidth
/ 2),
95 surface
->Polygon(pts
, sizeof(pts
) / sizeof(pts
[0]),
96 colourBG
.allocated
, colourBG
.allocated
);
100 Point(centreX
- halfWidth
, centreY
- halfWidth
/ 2),
101 Point(centreX
+ halfWidth
, centreY
- halfWidth
/ 2),
102 Point(centreX
, centreY
+ halfWidth
- halfWidth
/ 2),
104 surface
->Polygon(pts
, sizeof(pts
) / sizeof(pts
[0]),
105 colourBG
.allocated
, colourBG
.allocated
);
108 if (s
[startSeg
] == '\001') {
110 } else if (s
[startSeg
] == '\002') {
114 xEnd
= x
+ surface
->WidthText(font
, s
+startSeg
, endSeg
- startSeg
);
117 rcClient
.right
= xEnd
;
118 surface
->DrawTextNoClip(rcClient
, font
, ytext
,
119 s
+startSeg
, endSeg
- startSeg
,
120 highlight
? colourSel
.allocated
: colourUnSel
.allocated
,
130 int CallTip::PaintContents(Surface
*surfaceWindow
, bool draw
) {
131 PRectangle rcClientPos
= wCallTip
.GetClientPosition();
132 PRectangle
rcClientSize(0, 0, rcClientPos
.right
- rcClientPos
.left
,
133 rcClientPos
.bottom
- rcClientPos
.top
);
134 PRectangle
rcClient(1, 1, rcClientSize
.right
- 1, rcClientSize
.bottom
- 1);
136 // To make a nice small call tip window, it is only sized to fit most normal characters without accents
137 int ascent
= surfaceWindow
->Ascent(font
) - surfaceWindow
->InternalLeading(font
);
140 // Draw the definition in three parts: before highlight, highlighted, after highlight
141 int ytext
= rcClient
.top
+ ascent
+ 1;
142 rcClient
.bottom
= ytext
+ surfaceWindow
->Descent(font
) + 1;
143 char *chunkVal
= val
;
144 bool moreChunks
= true;
147 char *chunkEnd
= strchr(chunkVal
, '\n');
148 if (chunkEnd
== NULL
) {
149 chunkEnd
= chunkVal
+ strlen(chunkVal
);
152 int chunkOffset
= chunkVal
- val
;
153 int chunkLength
= chunkEnd
- chunkVal
;
154 int chunkEndOffset
= chunkOffset
+ chunkLength
;
155 int thisStartHighlight
= Platform::Maximum(startHighlight
, chunkOffset
);
156 thisStartHighlight
= Platform::Minimum(thisStartHighlight
, chunkEndOffset
);
157 thisStartHighlight
-= chunkOffset
;
158 int thisEndHighlight
= Platform::Maximum(endHighlight
, chunkOffset
);
159 thisEndHighlight
= Platform::Minimum(thisEndHighlight
, chunkEndOffset
);
160 thisEndHighlight
-= chunkOffset
;
161 rcClient
.top
= ytext
- ascent
- 1;
165 DrawChunk(surfaceWindow
, x
, chunkVal
, 0, thisStartHighlight
,
166 ytext
, rcClient
, false, draw
);
167 DrawChunk(surfaceWindow
, x
, chunkVal
, thisStartHighlight
, thisEndHighlight
,
168 ytext
, rcClient
, true, draw
);
169 DrawChunk(surfaceWindow
, x
, chunkVal
, thisEndHighlight
, chunkLength
,
170 ytext
, rcClient
, false, draw
);
172 chunkVal
= chunkEnd
+ 1;
174 rcClient
.bottom
+= lineHeight
;
175 maxWidth
= Platform::Maximum(maxWidth
, x
);
180 void CallTip::PaintCT(Surface
*surfaceWindow
) {
183 PRectangle rcClientPos
= wCallTip
.GetClientPosition();
184 PRectangle
rcClientSize(0, 0, rcClientPos
.right
- rcClientPos
.left
,
185 rcClientPos
.bottom
- rcClientPos
.top
);
186 PRectangle
rcClient(1, 1, rcClientSize
.right
- 1, rcClientSize
.bottom
- 1);
188 surfaceWindow
->FillRectangle(rcClient
, colourBG
.allocated
);
191 PaintContents(surfaceWindow
, true);
193 // Draw a raised border around the edges of the window
194 surfaceWindow
->MoveTo(0, rcClientSize
.bottom
- 1);
195 surfaceWindow
->PenColour(colourShade
.allocated
);
196 surfaceWindow
->LineTo(rcClientSize
.right
- 1, rcClientSize
.bottom
- 1);
197 surfaceWindow
->LineTo(rcClientSize
.right
- 1, 0);
198 surfaceWindow
->PenColour(colourLight
.allocated
);
199 surfaceWindow
->LineTo(0, 0);
200 surfaceWindow
->LineTo(0, rcClientSize
.bottom
- 1);
203 void CallTip::MouseClick(Point pt
) {
205 if (rectUp
.Contains(pt
))
207 if (rectDown
.Contains(pt
))
211 PRectangle
CallTip::CallTipStart(int pos
, Point pt
, const char *defn
,
212 const char *faceName
, int size
,
213 int codePage_
, int characterSet
, Window
&wParent
) {
217 val
= new char[strlen(defn
) + 1];
221 codePage
= codePage_
;
222 Surface
*surfaceMeasure
= Surface::Allocate();
225 surfaceMeasure
->Init(wParent
.GetID());
226 surfaceMeasure
->SetUnicodeMode(SC_CP_UTF8
== codePage
);
227 surfaceMeasure
->SetDBCSMode(codePage
);
230 inCallTipMode
= true;
231 posStartCallTip
= pos
;
232 int deviceHeight
= surfaceMeasure
->DeviceHeightFont(size
);
233 font
.Create(faceName
, characterSet
, deviceHeight
, false, false);
234 // Look for multiple lines in the text
235 // Only support \n here - simply means container must avoid \r!
238 const char *look
= val
;
239 rectUp
= PRectangle(0,0,0,0);
240 rectDown
= PRectangle(0,0,0,0);
242 int width
= PaintContents(surfaceMeasure
, false) + 5;
243 while ((newline
= strchr(look
, '\n')) != NULL
) {
247 lineHeight
= surfaceMeasure
->Height(font
);
248 // Extra line for border and an empty line at top and bottom
249 int height
= lineHeight
* numLines
- surfaceMeasure
->InternalLeading(font
) + 2 + 2;
250 delete surfaceMeasure
;
251 return PRectangle(pt
.x
- offsetMain
, pt
.y
+ 1, pt
.x
+ width
- offsetMain
, pt
.y
+ 1 + height
);
254 void CallTip::CallTipCancel() {
255 inCallTipMode
= false;
256 if (wCallTip
.Created()) {
261 void CallTip::SetHighlight(int start
, int end
) {
262 // Avoid flashing by checking something has really changed
263 if ((start
!= startHighlight
) || (end
!= endHighlight
)) {
264 startHighlight
= start
;
266 if (wCallTip
.Created()) {
267 wCallTip
.InvalidateAll();