aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2003-04-03 12:34:05 +0000
committernyamatongwe <devnull@localhost>2003-04-03 12:34:05 +0000
commit3d0117d9b355477ac4054d5a0a91772ab89a9e96 (patch)
tree0cfa2be9e2e8e5d4facfac54c62da3d91a31d7bc /src
parente22bcdbe06d78ab811ebc5a1623001133c10ea59 (diff)
downloadscintilla-mirror-3d0117d9b355477ac4054d5a0a91772ab89a9e96.tar.gz
CallTip can display up and down arrows and clicks are reported to
container. Calltip can be replaced while visible rather than needing a cancel and recreation to minimize flashing.
Diffstat (limited to 'src')
-rw-r--r--src/CallTip.cxx163
-rw-r--r--src/CallTip.h12
-rw-r--r--src/ScintillaBase.cxx14
-rw-r--r--src/ScintillaBase.h1
4 files changed, 147 insertions, 43 deletions
diff --git a/src/CallTip.cxx b/src/CallTip.cxx
index c83e2d2fd..2c91be5f4 100644
--- a/src/CallTip.cxx
+++ b/src/CallTip.cxx
@@ -18,6 +18,9 @@ CallTip::CallTip() {
inCallTipMode = false;
posStartCallTip = 0;
val = 0;
+ xUp = -100;
+ xDown = -100;
+ lineHeight = 1;
startHighlight = 0;
endHighlight = 0;
@@ -35,6 +38,8 @@ CallTip::~CallTip() {
val = 0;
}
+const int widthArrow = 14;
+
void CallTip::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(colourBG, want);
pal.WantFind(colourUnSel, want);
@@ -43,24 +48,96 @@ void CallTip::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(colourLight, want);
}
-void CallTip::PaintCT(Surface *surfaceWindow) {
- if (!val)
- return ;
+void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
+ int posStart, int posEnd, int ytext, PRectangle rcClient, bool highlight, bool draw) {
+ s += posStart;
+ int len = posEnd - posStart;
+ int maxEnd = 0;
+ int ends[10];
+ for (int i=0;i<len;i++) {
+ if (s[i] <= '\002') {
+ if (i > 0)
+ ends[maxEnd++] = i;
+ ends[maxEnd++] = i+1;
+ }
+ }
+ ends[maxEnd++] = len;
+ int startSeg = 0;
+ int xEnd;
+ for (int seg = 0; seg<maxEnd; seg++) {
+ int endSeg = ends[seg];
+ if (endSeg > startSeg) {
+ if (s[startSeg] <= '\002') {
+ xEnd = x + widthArrow;
+ if (draw) {
+ const int halfWidth = widthArrow / 2 - 3;
+ const int centreX = x + widthArrow / 2 - 1;
+ const int centreY = ytext - halfWidth - 1;
+ rcClient.left = x;
+ rcClient.right = xEnd;
+ surface->FillRectangle(rcClient, colourBG.allocated);
+ PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1);
+ surface->FillRectangle(rcClientInner, colourUnSel.allocated);
+
+ if (s[startSeg] == '\001') {
+ // Up arrow
+ Point pts[] = {
+ Point(centreX - halfWidth, centreY + halfWidth / 2),
+ Point(centreX + halfWidth, centreY + halfWidth / 2),
+ Point(centreX, centreY - halfWidth + halfWidth / 2),
+ };
+ surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
+ colourBG.allocated, colourBG.allocated);
+ } else {
+ // Down arrow
+ Point pts[] = {
+ Point(centreX - halfWidth, centreY - halfWidth / 2 + 1),
+ Point(centreX + halfWidth, centreY - halfWidth / 2 + 1),
+ Point(centreX, centreY + halfWidth - halfWidth / 2 + 1),
+ };
+ surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
+ colourBG.allocated, colourBG.allocated);
+ }
+ } else {
+ if (s[startSeg] == '\001') {
+ xUp = x+1;
+ } else {
+ xDown = x+1;
+ }
+ }
+ } else {
+ xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
+ if (draw) {
+ rcClient.left = x;
+ rcClient.right = xEnd;
+ surface->DrawTextNoClip(rcClient, font, ytext,
+ s+startSeg, endSeg - startSeg,
+ highlight ? colourSel.allocated : colourUnSel.allocated,
+ colourBG.allocated);
+ }
+ }
+ x = xEnd;
+ startSeg = endSeg;
+ }
+ }
+}
+
+int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
PRectangle rcClientPos = wCallTip.GetClientPosition();
PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
rcClientPos.bottom - rcClientPos.top);
PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
- surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
// To make a nice small call tip window, it is only sized to fit most normal characters without accents
- int lineHeight = surfaceWindow->Height(font);
int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font);
// For each line...
// Draw the definition in three parts: before highlight, highlighted, after highlight
int ytext = rcClient.top + ascent + 1;
+ rcClient.bottom = rcClient.top + lineHeight + 1;
char *chunkVal = val;
bool moreChunks = true;
+ int maxWidth = 0;
while (moreChunks) {
char *chunkEnd = strchr(chunkVal, '\n');
if (chunkEnd == NULL) {
@@ -76,36 +153,34 @@ void CallTip::PaintCT(Surface *surfaceWindow) {
int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset);
thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset);
thisEndHighlight -= chunkOffset;
- int x = 5;
- int xEnd = x + surfaceWindow->WidthText(font, chunkVal, thisStartHighlight);
- rcClient.left = x;
rcClient.top = ytext - ascent - 1;
- rcClient.right = xEnd;
- surfaceWindow->DrawTextNoClip(rcClient, font, ytext,
- chunkVal, thisStartHighlight,
- colourUnSel.allocated, colourBG.allocated);
- x = xEnd;
-
- xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisStartHighlight,
- thisEndHighlight - thisStartHighlight);
- rcClient.top = ytext;
- rcClient.left = x;
- rcClient.right = xEnd;
- surfaceWindow->DrawTextNoClip(rcClient, font, ytext,
- chunkVal + thisStartHighlight, thisEndHighlight - thisStartHighlight,
- colourSel.allocated, colourBG.allocated);
- x = xEnd;
-
- xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisEndHighlight,
- chunkLength - thisEndHighlight);
- rcClient.left = x;
- rcClient.right = xEnd;
- surfaceWindow->DrawTextNoClip(rcClient, font, ytext,
- chunkVal + thisEndHighlight, chunkLength - thisEndHighlight,
- colourUnSel.allocated, colourBG.allocated);
+
+ int x = 5;
+
+ DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight, ytext, rcClient, false, draw);
+ DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight, ytext, rcClient, true, draw);
+ DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength, ytext, rcClient, false, draw);
+
chunkVal = chunkEnd + 1;
ytext += lineHeight;
+ rcClient.bottom += lineHeight;
+ maxWidth = Platform::Maximum(maxWidth, x);
}
+ return maxWidth;
+}
+
+void CallTip::PaintCT(Surface *surfaceWindow) {
+ if (!val)
+ return;
+ PRectangle rcClientPos = wCallTip.GetClientPosition();
+ PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
+ rcClientPos.bottom - rcClientPos.top);
+ PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
+
+ surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
+
+ PaintContents(surfaceWindow, true);
+
// Draw a raised border around the edges of the window
surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
surfaceWindow->PenColour(colourShade.allocated);
@@ -116,9 +191,21 @@ void CallTip::PaintCT(Surface *surfaceWindow) {
surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
}
+void CallTip::MouseClick(Point pt) {
+ clickPlace = 0;
+ if (pt.y < lineHeight) {
+ if ((pt.x > xUp) && (pt.x < xUp + widthArrow - 2)) {
+ clickPlace = 1;
+ } else if ((pt.x > xDown) && (pt.x < xDown + widthArrow - 2)) {
+ clickPlace = 2;
+ }
+ }
+}
+
PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
const char *faceName, int size,
- int codePage_) {
+ int codePage_, Window &wParent) {
+ clickPlace = 0;
if (val)
delete []val;
val = new char[strlen(defn) + 1];
@@ -129,7 +216,7 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
Surface *surfaceMeasure = Surface::Allocate();
if (!surfaceMeasure)
return PRectangle();
- surfaceMeasure->Init(wCallTip.GetID());
+ surfaceMeasure->Init(wParent.GetID());
surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage);
surfaceMeasure->SetDBCSMode(codePage);
startHighlight = 0;
@@ -140,19 +227,17 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
font.Create(faceName, SC_CHARSET_DEFAULT, deviceHeight, false, false);
// Look for multiple lines in the text
// Only support \n here - simply means container must avoid \r!
- int width = 0;
int numLines = 1;
const char *newline;
const char *look = val;
+ xUp = -100;
+ xDown = -100;
+ int width = PaintContents(surfaceMeasure, false) + 5;
while ((newline = strchr(look, '\n')) != NULL) {
- int thisWidth = surfaceMeasure->WidthText(font, look, newline - look);
- width = Platform::Maximum(width, thisWidth);
look = newline + 1;
numLines++;
}
- int lastWidth = surfaceMeasure->WidthText(font, look, static_cast<int>(strlen(look)));
- width = Platform::Maximum(width, lastWidth) + 10;
- int lineHeight = surfaceMeasure->Height(font);
+ lineHeight = surfaceMeasure->Height(font);
// Extra line for border and an empty line at top and bottom
int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2;
delete surfaceMeasure;
diff --git a/src/CallTip.h b/src/CallTip.h
index 877d9f34e..ff61f32a5 100644
--- a/src/CallTip.h
+++ b/src/CallTip.h
@@ -15,9 +15,16 @@ class CallTip {
int endHighlight;
char *val;
Font font;
+ int xUp;
+ int xDown;
+ int lineHeight;
// Private so CallTip objects can not be copied
CallTip(const CallTip &) {}
CallTip &operator=(const CallTip &) { return *this; }
+ void DrawChunk(Surface *surface, int &x, const char *s,
+ int posStart, int posEnd, int ytext, PRectangle rcClient,
+ bool highlight, bool draw);
+ int PaintContents(Surface *surfaceWindow, bool draw);
public:
Window wCallTip;
@@ -30,6 +37,7 @@ public:
ColourPair colourShade;
ColourPair colourLight;
int codePage;
+ int clickPlace;
CallTip();
~CallTip();
@@ -39,9 +47,11 @@ public:
void PaintCT(Surface *surfaceWindow);
+ void MouseClick(Point pt);
+
/// Setup the calltip and return a rectangle of the area required.
PRectangle CallTipStart(int pos, Point pt, const char *defn,
- const char *faceName, int size, int codePage_);
+ const char *faceName, int size, int codePage_, Window &wParent);
void CallTipCancel();
diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx
index 62cdcdd74..27179bcdc 100644
--- a/src/ScintillaBase.cxx
+++ b/src/ScintillaBase.cxx
@@ -345,6 +345,13 @@ void ScintillaBase::AutoCompleteCompleted() {
pdoc->EndUndoAction();
}
+void ScintillaBase::CallTipClick() {
+ SCNotification scn;
+ scn.nmhdr.code = SCN_CALLTIPCLICK;
+ scn.position = ct.clickPlace;
+ NotifyParent(scn);
+}
+
void ScintillaBase::ContextMenu(Point pt) {
if (displayPopupMenu) {
bool writable = !WndProc(SCI_GETREADONLY, 0, 0);
@@ -528,14 +535,15 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
case SCI_CALLTIPSHOW: {
AutoCompleteCancel();
- if (!ct.wCallTip.Created()) {
+ //if (!ct.wCallTip.Created()) {
Point pt = LocationFromPosition(wParam);
pt.y += vs.lineHeight;
PRectangle rc = ct.CallTipStart(currentPos, pt,
reinterpret_cast<char *>(lParam),
vs.styles[STYLE_DEFAULT].fontName,
vs.styles[STYLE_DEFAULT].sizeZoomed,
- IsUnicodeMode());
+ IsUnicodeMode(),
+ wMain);
// If the call-tip window would be out of the client
// space, adjust so it displays above the text.
PRectangle rcClient = GetClientRectangle();
@@ -548,7 +556,7 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
CreateCallTipWindow(rc);
ct.wCallTip.SetPositionRelative(rc, wMain);
ct.wCallTip.Show();
- }
+ //}
}
break;
diff --git a/src/ScintillaBase.h b/src/ScintillaBase.h
index 9a9433dd7..152d49f53 100644
--- a/src/ScintillaBase.h
+++ b/src/ScintillaBase.h
@@ -71,6 +71,7 @@ protected:
void AutoCompleteMoveToCurrentWord();
static void AutoCompleteDoubleClick(void* p);
+ void CallTipClick();
virtual void CreateCallTipWindow(PRectangle rc) = 0;
virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0;