diff options
author | nyamatongwe <devnull@localhost> | 2003-04-03 12:34:05 +0000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2003-04-03 12:34:05 +0000 |
commit | 3d0117d9b355477ac4054d5a0a91772ab89a9e96 (patch) | |
tree | 0cfa2be9e2e8e5d4facfac54c62da3d91a31d7bc /src | |
parent | e22bcdbe06d78ab811ebc5a1623001133c10ea59 (diff) | |
download | scintilla-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.cxx | 163 | ||||
-rw-r--r-- | src/CallTip.h | 12 | ||||
-rw-r--r-- | src/ScintillaBase.cxx | 14 | ||||
-rw-r--r-- | src/ScintillaBase.h | 1 |
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; |