]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/CallTip.cxx
This form of the event cloning patch survived my
[wxWidgets.git] / src / stc / scintilla / src / CallTip.cxx
1 // Scintilla source code edit control
2 /** @file CallTip.cxx
3 ** Code for displaying call tips.
4 **/
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.
7
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "Platform.h"
12
13 #include "Scintilla.h"
14 #include "CallTip.h"
15
16 CallTip::CallTip() {
17 wCallTip = 0;
18 inCallTipMode = false;
19 posStartCallTip = 0;
20 val = 0;
21 startHighlight = 0;
22 endHighlight = 0;
23
24 colourBG.desired = Colour(0xff, 0xff, 0xff);
25 colourUnSel.desired = Colour(0x80, 0x80, 0x80);
26 colourSel.desired = Colour(0, 0, 0x80);
27 colourShade.desired = Colour(0, 0, 0);
28 colourLight.desired = Colour(0xc0, 0xc0, 0xc0);
29 }
30
31 CallTip::~CallTip() {
32 font.Release();
33 wCallTip.Destroy();
34 delete []val;
35 val = 0;
36 }
37
38 void CallTip::RefreshColourPalette(Palette &pal, bool want) {
39 pal.WantFind(colourBG, want);
40 pal.WantFind(colourUnSel, want);
41 pal.WantFind(colourSel, want);
42 pal.WantFind(colourShade, want);
43 pal.WantFind(colourLight, want);
44 }
45
46 void CallTip::PaintCT(Surface *surfaceWindow) {
47 if (!val)
48 return ;
49 PRectangle rcClientPos = wCallTip.GetClientPosition();
50 PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
51 rcClientPos.bottom - rcClientPos.top);
52 PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
53
54 surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
55 // To make a nice small call tip window, it is only sized to fit most normal characters without accents
56 int lineHeight = surfaceWindow->Height(font);
57 int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font);
58
59 // For each line...
60 // Draw the definition in three parts: before highlight, highlighted, after highlight
61 int ytext = rcClient.top + ascent + 1;
62 char *chunkVal = val;
63 bool moreChunks = true;
64 while (moreChunks) {
65 char *chunkEnd = strchr(chunkVal, '\n');
66 if (chunkEnd == NULL) {
67 chunkEnd = chunkVal + strlen(chunkVal);
68 moreChunks = false;
69 }
70 int chunkOffset = chunkVal - val;
71 int chunkLength = chunkEnd - chunkVal;
72 int chunkEndOffset = chunkOffset + chunkLength;
73 int thisStartHighlight = Platform::Maximum(startHighlight, chunkOffset);
74 thisStartHighlight = Platform::Minimum(thisStartHighlight, chunkEndOffset);
75 thisStartHighlight -= chunkOffset;
76 int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset);
77 thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset);
78 thisEndHighlight -= chunkOffset;
79 int x = 5;
80 int xEnd = x + surfaceWindow->WidthText(font, chunkVal, thisStartHighlight);
81 rcClient.left = x;
82 rcClient.top = ytext - ascent - 1;
83 rcClient.right = xEnd;
84 surfaceWindow->DrawText(rcClient, font, ytext,
85 chunkVal, thisStartHighlight,
86 colourUnSel.allocated, colourBG.allocated);
87 x = xEnd;
88
89 xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisStartHighlight,
90 thisEndHighlight - thisStartHighlight);
91 rcClient.top = ytext;
92 rcClient.left = x;
93 rcClient.right = xEnd;
94 surfaceWindow->DrawText(rcClient, font, ytext,
95 chunkVal + thisStartHighlight, thisEndHighlight - thisStartHighlight,
96 colourSel.allocated, colourBG.allocated);
97 x = xEnd;
98
99 xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisEndHighlight,
100 chunkLength - thisEndHighlight);
101 rcClient.left = x;
102 rcClient.right = xEnd;
103 surfaceWindow->DrawText(rcClient, font, ytext,
104 chunkVal + thisEndHighlight, chunkLength - thisEndHighlight,
105 colourUnSel.allocated, colourBG.allocated);
106 chunkVal = chunkEnd + 1;
107 ytext += lineHeight;
108 }
109 // Draw a raised border around the edges of the window
110 surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
111 surfaceWindow->PenColour(colourShade.allocated);
112 surfaceWindow->LineTo(rcClientSize.right - 1, rcClientSize.bottom - 1);
113 surfaceWindow->LineTo(rcClientSize.right - 1, 0);
114 surfaceWindow->PenColour(colourLight.allocated);
115 surfaceWindow->LineTo(0, 0);
116 surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
117 }
118
119 PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
120 const char *faceName, int size) {
121 Surface surfaceMeasure;
122 surfaceMeasure.Init();
123 int deviceHeight = surfaceMeasure.DeviceHeightFont(size);
124 font.Create(faceName, SC_CHARSET_DEFAULT, deviceHeight, false, false);
125 if (val)
126 delete []val;
127 val = new char[strlen(defn) + 1];
128 if (!val)
129 return PRectangle();
130 strcpy(val, defn);
131 startHighlight = 0;
132 endHighlight = 0;
133 inCallTipMode = true;
134 posStartCallTip = pos;
135 // Look for multiple lines in the text
136 // Only support \n here - simply means container must avoid \r!
137 int width = 0;
138 int numLines = 1;
139 const char *newline;
140 const char *look = val;
141 while ((newline = strchr(look, '\n')) != NULL) {
142 int thisWidth = surfaceMeasure.WidthText(font, look, newline - look);
143 width = Platform::Maximum(width, thisWidth);
144 look = newline + 1;
145 numLines++;
146 }
147 int lastWidth = surfaceMeasure.WidthText(font, look, strlen(look));
148 width = Platform::Maximum(width, lastWidth) + 10;
149 int lineHeight = surfaceMeasure.Height(font);
150 // Extra line for border and an empty line at top and bottom
151 int height = lineHeight * numLines - surfaceMeasure.InternalLeading(font) + 2 + 2;
152 return PRectangle(pt.x -5, pt.y + 1, pt.x + width - 5, pt.y + 1 + height);
153 }
154
155 void CallTip::CallTipCancel() {
156 inCallTipMode = false;
157 if (wCallTip.Created()) {
158 wCallTip.Destroy();
159 }
160 }
161
162 void CallTip::SetHighlight(int start, int end) {
163 // Avoid flashing by checking something has really changed
164 if ((start != startHighlight) || (end != endHighlight)) {
165 startHighlight = start;
166 endHighlight = end;
167 if (wCallTip.Created()) {
168 wCallTip.InvalidateAll();
169 }
170 }
171 }