diff options
Diffstat (limited to 'src/Editor.cxx')
| -rw-r--r-- | src/Editor.cxx | 157 | 
1 files changed, 123 insertions, 34 deletions
| diff --git a/src/Editor.cxx b/src/Editor.cxx index 06ed59144..cdbd81474 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -23,12 +23,14 @@  #include "Partitioning.h"  #include "CellBuffer.h"  #include "KeyMap.h" +#include "RunStyles.h"  #include "Indicator.h"  #include "XPM.h"  #include "LineMarker.h"  #include "Style.h"  #include "ViewStyle.h"  #include "CharClassify.h" +#include "Decoration.h"  #include "Document.h"  #include "Editor.h" @@ -2308,6 +2310,73 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin  	}  } +void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart, +                      PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under) { +	// Draw decorators +	const int posLineStart = pdoc->LineStart(line); +	const int lineStart = ll->LineStart(subLine); +	const int subLineStart = ll->positions[lineStart]; +	const int posLineEnd = posLineStart + lineEnd; + +	if (!under) { +		// Draw indicators +		// foreach indicator... +		for (int indicnum = 0, mask = 1 << pdoc->stylingBits; mask < 0x100; indicnum++) { +			if (!(mask & ll->styleBitsSet)) { +				mask <<= 1; +				continue; +			} +			int startPos = -1; +			// foreach style pos in line... +			for (int indicPos = lineStart; indicPos <= lineEnd; indicPos++) { +				// look for starts... +				if (startPos < 0) { +					// NOT in indicator run, looking for START +					if (indicPos < lineEnd && (ll->indicators[indicPos] & mask)) +						startPos = indicPos; +				} +				// ... or ends +				if (startPos >= 0) { +					// IN indicator run, looking for END +					if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) { +						// AT end of indicator run, DRAW it! +						PRectangle rcIndic( +							ll->positions[startPos] + xStart - subLineStart, +							rcLine.top + vsDraw.maxAscent, +							ll->positions[indicPos] + xStart - subLineStart, +							rcLine.top + vsDraw.maxAscent + 3); +						vsDraw.indicators[indicnum].Draw(surface, rcIndic, rcLine); +						// RESET control var +						startPos = -1; +					} +				} +			} +			mask <<= 1; +		} +	} + +	for (Decoration *deco=pdoc->decorations.root; deco; deco = deco->next) { +		if (under == (deco->indicator >= 16)) { +			int startPos = posLineStart + subLineStart; +			if (!deco->rs.ValueAt(startPos)) { +				startPos = deco->rs.EndRun(startPos); +			} +			while ((startPos < posLineEnd) && (deco->rs.ValueAt(startPos))) { +				int endPos = deco->rs.EndRun(startPos); +				if (endPos > posLineEnd) +					endPos = posLineEnd; +				PRectangle rcIndic( +					ll->positions[startPos - posLineStart] + xStart - subLineStart, +					rcLine.top + vsDraw.maxAscent, +					ll->positions[endPos - posLineStart] + xStart - subLineStart, +					rcLine.top + vsDraw.maxAscent + 3); +				vsDraw.indicators[deco->indicator].Draw(surface, rcIndic, rcLine); +				startPos = deco->rs.EndRun(endPos); +			} +		} +	} +} +  void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,                        PRectangle rcLine, LineLayout *ll, int subLine) { @@ -2486,6 +2555,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  		        drawWrapMarkEnd, wrapColour);  	} +	DrawIndicators(surface, vsDraw, line, xStart, rcLine, ll, subLine, lineEnd, true); +  	if (vsDraw.edgeState == EDGE_LINE) {  		int edgeX = theEdge * vsDraw.spaceWidth;  		rcSegment.left = edgeX + xStart; @@ -2651,40 +2722,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  		}  	} -	// Draw indicators -	// foreach indicator... -	for (int indicnum = 0, mask = 1 << pdoc->stylingBits; mask < 0x100; indicnum++) { -		if (!(mask & ll->styleBitsSet)) { -			mask <<= 1; -			continue; -		} -		int startPos = -1; -		// foreach style pos in line... -		for (int indicPos = lineStart; indicPos <= lineEnd; indicPos++) { -			// look for starts... -			if (startPos < 0) { -				// NOT in indicator run, looking for START -				if (indicPos < lineEnd && (ll->indicators[indicPos] & mask)) -					startPos = indicPos; -			} -			// ... or ends -			if (startPos >= 0) { -				// IN indicator run, looking for END -				if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) { -					// AT end of indicator run, DRAW it! -					PRectangle rcIndic( -						ll->positions[startPos] + xStart - subLineStart, -						rcLine.top + vsDraw.maxAscent, -						ll->positions[indicPos] + xStart - subLineStart, -						rcLine.top + vsDraw.maxAscent + 3); -					vsDraw.indicators[indicnum].Draw(surface, rcIndic, rcLine); -					// RESET control var -					startPos = -1; -				} -			} -		} -		mask <<= 1; -	} +	DrawIndicators(surface, vsDraw, line, xStart, rcLine, ll, subLine, lineEnd, false); +  	// End of the drawing of the current line  	if (!twoPhaseDraw) {  		DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd, @@ -3678,6 +3717,18 @@ void Editor::NotifyPainted() {  	NotifyParent(scn);  } +void Editor::NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt) { +	int mask = pdoc->decorations.AllOnFor(position); +	if ((click && mask) || pdoc->decorations.clickNotified) { +		SCNotification scn = {0}; +		pdoc->decorations.clickNotified = click; +		scn.nmhdr.code = click ? SCN_INDICATORCLICK : SCN_INDICATORRELEASE; +		scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); +		scn.position = position; +		NotifyParent(scn); +	} +} +  bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) {  	int marginClicked = -1;  	int x = 0; @@ -3798,11 +3849,13 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {  			anchor = MovePositionForInsertion(anchor, mh.position, mh.length);  			braces[0] = MovePositionForInsertion(braces[0], mh.position, mh.length);  			braces[1] = MovePositionForInsertion(braces[1], mh.position, mh.length); +			pdoc->decorations.InsertSpace(mh.position, mh.length);  		} else if (mh.modificationType & SC_MOD_DELETETEXT) {  			currentPos = MovePositionForDeletion(currentPos, mh.position, mh.length);  			anchor = MovePositionForDeletion(anchor, mh.position, mh.length);  			braces[0] = MovePositionForDeletion(braces[0], mh.position, mh.length);  			braces[1] = MovePositionForDeletion(braces[1], mh.position, mh.length); +			pdoc->decorations.DeleteRange(mh.position, mh.length);  		}  		if (cs.LinesDisplayed() < cs.LinesInDoc()) {  			// Some lines are hidden so may need shown. @@ -5116,6 +5169,8 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b  	if (processed)  		return; +	NotifyIndicatorClick(true, newPos, shift, ctrl, alt); +  	bool inSelMargin = PointInSelMargin(pt);  	if (shift & !inSelMargin) {  		SetSelection(newPos); @@ -5370,6 +5425,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {  		SetMouseCapture(false);  		int newPos = PositionFromLocation(pt);  		newPos = MovePositionOutsideChar(newPos, currentPos - newPos); +		NotifyIndicatorClick(false, newPos, false, false, false);  		if (inDragDrop) {  			int selStart = SelectionStart();  			int selEnd = SelectionEnd(); @@ -7079,6 +7135,39 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {  	case SCI_INDICGETFORE:  		return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fore.desired.AsLong() : 0; +	case SCI_SETINDICATORCURRENT: +		pdoc->decorations.SetCurrentIndicator(wParam); +		break; +	case SCI_GETINDICATORCURRENT: +		return pdoc->decorations.GetCurrentIndicator(); +	case SCI_SETINDICATORVALUE: +		pdoc->decorations.SetCurrentValue(wParam); +		break; +	case SCI_GETINDICATORVALUE: +		return pdoc->decorations.GetCurrentValue(); + +	case SCI_INDICATORFILLRANGE: +		pdoc->decorations.FillRange(wParam, pdoc->decorations.GetCurrentValue(), lParam); +		InvalidateRange(wParam, wParam + lParam); +		break; + +	case SCI_INDICATORCLEARRANGE: +		pdoc->decorations.FillRange(wParam, 0, lParam); +		InvalidateRange(wParam, wParam + lParam); +		break; + +	case SCI_INDICATORALLONFOR: +		return pdoc->decorations.AllOnFor(wParam); + +	case SCI_INDICATORVALUEAT: +		return pdoc->decorations.ValueAt(wParam, lParam); + +	case SCI_INDICATORSTART: +		return pdoc->decorations.Start(wParam, lParam); + +	case SCI_INDICATOREND: +		return pdoc->decorations.End(wParam, lParam); +  	case SCI_LINEDOWN:  	case SCI_LINEDOWNEXTEND:  	case SCI_PARADOWN: | 
