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; | 
