~ubuntu-branches/ubuntu/wily/apparmor/wily

« back to all changes in this revision

Viewing changes to deprecated/management/profile-editor/src/wxStyledTextCtrl/CallTip.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2011-08-10 18:12:34 UTC
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20110810181234-b6obckg60cp99crg
Tags: upstream-2.7.0~beta1+bzr1774
ImportĀ upstreamĀ versionĀ 2.7.0~beta1+bzr1774

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
        rectUp = PRectangle(0,0,0,0);
22
 
        rectDown = PRectangle(0,0,0,0);
23
 
        lineHeight = 1;
24
 
        startHighlight = 0;
25
 
        endHighlight = 0;
26
 
 
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);
32
 
}
33
 
 
34
 
CallTip::~CallTip() {
35
 
        font.Release();
36
 
        wCallTip.Destroy();
37
 
        delete []val;
38
 
        val = 0;
39
 
}
40
 
 
41
 
const int widthArrow = 14;
42
 
 
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);
49
 
}
50
 
 
51
 
static bool IsArrowCharacter(char ch) {
52
 
        return (ch == 0) || (ch == '\001') || (ch == '\002');
53
 
}
54
 
 
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) {
58
 
        s += posStart;
59
 
        int len = posEnd - posStart;
60
 
        int maxEnd = 0;
61
 
        int ends[10];
62
 
        for (int i=0;i<len;i++) {
63
 
                if (IsArrowCharacter(s[i])) {
64
 
                        if (i > 0)
65
 
                                ends[maxEnd++] = i;
66
 
                        ends[maxEnd++] = i+1;
67
 
                }
68
 
        }
69
 
        ends[maxEnd++] = len;
70
 
        int startSeg = 0;
71
 
        int xEnd;
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;
77
 
                                offsetMain = xEnd;
78
 
                                rcClient.left = x;
79
 
                                rcClient.right = xEnd;
80
 
                                if (draw) {
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);
87
 
 
88
 
                                        if (s[startSeg] == '\001') {
89
 
                                                // Up arrow
90
 
                                                Point pts[] = {
91
 
                                                Point(centreX - halfWidth, centreY + halfWidth / 2),
92
 
                                                Point(centreX + halfWidth, centreY + halfWidth / 2),
93
 
                                                Point(centreX, centreY - halfWidth + halfWidth / 2),
94
 
                                                };
95
 
                                                surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
96
 
                                                                colourBG.allocated, colourBG.allocated);
97
 
                                        } else {
98
 
                                                // Down arrow
99
 
                                                Point pts[] = {
100
 
                                                Point(centreX - halfWidth, centreY - halfWidth / 2),
101
 
                                                Point(centreX + halfWidth, centreY - halfWidth / 2),
102
 
                                                Point(centreX, centreY + halfWidth - halfWidth / 2),
103
 
                                                };
104
 
                                                surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
105
 
                                                                colourBG.allocated, colourBG.allocated);
106
 
                                        }
107
 
                                }
108
 
                                if (s[startSeg] == '\001') {
109
 
                                        rectUp = rcClient;
110
 
                                } else if (s[startSeg] == '\002') {
111
 
                                        rectDown = rcClient;
112
 
                                }
113
 
                        } else {
114
 
                                xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
115
 
                                if (draw) {
116
 
                                        rcClient.left = x;
117
 
                                        rcClient.right = xEnd;
118
 
                                        surface->DrawTextNoClip(rcClient, font, ytext,
119
 
                                                                                s+startSeg, endSeg - startSeg,
120
 
                                                                                highlight ? colourSel.allocated : colourUnSel.allocated,
121
 
                                                                                colourBG.allocated);
122
 
                                }
123
 
                        }
124
 
                        x = xEnd;
125
 
                        startSeg = endSeg;
126
 
                }
127
 
        }
128
 
}
129
 
 
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);
135
 
 
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);
138
 
 
139
 
        // For each line...
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;
145
 
        int maxWidth = 0;
146
 
        while (moreChunks) {
147
 
                char *chunkEnd = strchr(chunkVal, '\n');
148
 
                if (chunkEnd == NULL) {
149
 
                        chunkEnd = chunkVal + strlen(chunkVal);
150
 
                        moreChunks = false;
151
 
                }
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;
162
 
 
163
 
                int x = 5;
164
 
 
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);
171
 
 
172
 
                chunkVal = chunkEnd + 1;
173
 
                ytext += lineHeight;
174
 
                rcClient.bottom += lineHeight;
175
 
                maxWidth = Platform::Maximum(maxWidth, x);
176
 
        }
177
 
        return maxWidth;
178
 
}
179
 
 
180
 
void CallTip::PaintCT(Surface *surfaceWindow) {
181
 
        if (!val)
182
 
                return;
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);
187
 
 
188
 
        surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
189
 
 
190
 
        offsetMain = 5;
191
 
        PaintContents(surfaceWindow, true);
192
 
 
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);
201
 
}
202
 
 
203
 
void CallTip::MouseClick(Point pt) {
204
 
        clickPlace = 0;
205
 
        if (rectUp.Contains(pt))
206
 
                clickPlace = 1;
207
 
        if (rectDown.Contains(pt))
208
 
                clickPlace = 2;
209
 
}
210
 
 
211
 
PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
212
 
                                 const char *faceName, int size,
213
 
                                 int codePage_, int characterSet, Window &wParent) {
214
 
        clickPlace = 0;
215
 
        if (val)
216
 
                delete []val;
217
 
        val = new char[strlen(defn) + 1];
218
 
        if (!val)
219
 
                return PRectangle();
220
 
        strcpy(val, defn);
221
 
        codePage = codePage_;
222
 
        Surface *surfaceMeasure = Surface::Allocate();
223
 
        if (!surfaceMeasure)
224
 
                return PRectangle();
225
 
        surfaceMeasure->Init(wParent.GetID());
226
 
        surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage);
227
 
        surfaceMeasure->SetDBCSMode(codePage);
228
 
        startHighlight = 0;
229
 
        endHighlight = 0;
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!
236
 
        int numLines = 1;
237
 
        const char *newline;
238
 
        const char *look = val;
239
 
        rectUp = PRectangle(0,0,0,0);
240
 
        rectDown = PRectangle(0,0,0,0);
241
 
        offsetMain = 5;
242
 
        int width = PaintContents(surfaceMeasure, false) + 5;
243
 
        while ((newline = strchr(look, '\n')) != NULL) {
244
 
                look = newline + 1;
245
 
                numLines++;
246
 
        }
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);
252
 
}
253
 
 
254
 
void CallTip::CallTipCancel() {
255
 
        inCallTipMode = false;
256
 
        if (wCallTip.Created()) {
257
 
                wCallTip.Destroy();
258
 
        }
259
 
}
260
 
 
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;
265
 
                endHighlight = end;
266
 
                if (wCallTip.Created()) {
267
 
                        wCallTip.InvalidateAll();
268
 
                }
269
 
        }
270
 
}