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