diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/EditView.cxx | 60 | ||||
| -rw-r--r-- | src/EditView.h | 9 | ||||
| -rw-r--r-- | src/Editor.cxx | 27 | ||||
| -rw-r--r-- | src/PerLine.cxx | 70 | ||||
| -rw-r--r-- | src/PerLine.h | 17 | 
5 files changed, 181 insertions, 2 deletions
| diff --git a/src/EditView.cxx b/src/EditView.cxx index b033c7cf6..c46a0fbcf 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -29,6 +29,7 @@  #include "RunStyles.h"  #include "ContractionState.h"  #include "CellBuffer.h" +#include "PerLine.h"  #include "KeyMap.h"  #include "Indicator.h"  #include "XPM.h" @@ -170,6 +171,7 @@ void DrawStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, PRec  const XYPOSITION epsilon = 0.0001f;	// A small nudge to avoid floating point precision issues  EditView::EditView() { +	ldTabstops = NULL;  	hideSelection = false;  	drawOverstrikeCaret = true;  	bufferedDraw = true; @@ -185,6 +187,11 @@ EditView::EditView() {  	posCache.SetSize(0x400);  } +EditView::~EditView() { +	delete ldTabstops; +	ldTabstops = NULL; +} +  bool EditView::SetTwoPhaseDraw(bool twoPhaseDraw) {  	const PhasesDraw phasesDrawNew = twoPhaseDraw ? phasesTwo : phasesOne;  	const bool redraw = phasesDraw != phasesDrawNew; @@ -203,6 +210,54 @@ bool EditView::LinesOverlap() const {  	return phasesDraw == phasesMultiple;  } +void EditView::ClearAllTabstops() { +	delete ldTabstops; +	ldTabstops = 0; +} + +int EditView::NextTabstopPos(int line, int x, int tabWidth) const { +	int next = GetNextTabstop(line, x); +	if (next > 0) +		return next; +	return ((((x + 2) / tabWidth) + 1) * tabWidth); +} + +bool EditView::ClearTabstops(int line) { +	LineTabstops *lt = static_cast<LineTabstops *>(ldTabstops); +	return lt && lt->ClearTabstops(line); +} + +bool EditView::AddTabstop(int line, int x) { +	if (!ldTabstops) { +		ldTabstops = new LineTabstops(); +	} +	LineTabstops *lt = static_cast<LineTabstops *>(ldTabstops); +	return lt && lt->AddTabstop(line, x); +} + +int EditView::GetNextTabstop(int line, int x) const { +	LineTabstops *lt = static_cast<LineTabstops *>(ldTabstops); +	if (lt) { +		return lt->GetNextTabstop(line, x); +	} else { +		return 0; +	} +} + +void EditView::LinesAddedOrRemoved(int lineOfPos, int linesAdded) { +	if (ldTabstops) { +		if (linesAdded > 0) { +			for (int line = lineOfPos; line < lineOfPos + linesAdded; line++) { +				ldTabstops->InsertLine(line); +			} +		} else { +			for (int line = (lineOfPos + -linesAdded) - 1; line >= lineOfPos; line--) { +				ldTabstops->RemoveLine(line); +			} +		} +	} +} +  void EditView::DropGraphics(bool freeObjects) {  	if (freeObjects) {  		delete pixmapLine; @@ -397,8 +452,9 @@ void EditView::LayoutLine(const EditModel &model, int line, Surface *surface, co  					XYPOSITION representationWidth = vstyle.controlCharWidth;  					if (ll->chars[ts.start] == '\t') {  						// Tab is a special case of representation, taking a variable amount of space -						representationWidth = -							((static_cast<int>((ll->positions[ts.start] + 2) / vstyle.tabWidth) + 1) * vstyle.tabWidth) - ll->positions[ts.start]; +						const int x = static_cast<int>(ll->positions[ts.start]); +						const int tabWidth = static_cast<int>(vstyle.tabWidth); +						representationWidth = static_cast<XYPOSITION>(NextTabstopPos(line, x, tabWidth) - ll->positions[ts.start]);  					} else {  						if (representationWidth <= 0.0) {  							XYPOSITION positionsRepr[256];	// Should expand when needed diff --git a/src/EditView.h b/src/EditView.h index 7d64aff90..18451104f 100644 --- a/src/EditView.h +++ b/src/EditView.h @@ -48,6 +48,7 @@ void DrawStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, PRec  class EditView {  public:  	PrintParameters printParameters; +	PerLine *ldTabstops;  	bool hideSelection;  	bool drawOverstrikeCaret; @@ -78,11 +79,19 @@ public:  	PositionCache posCache;  	EditView(); +	virtual ~EditView();  	bool SetTwoPhaseDraw(bool twoPhaseDraw);  	bool SetPhasesDraw(int phases);  	bool LinesOverlap() const; +	void ClearAllTabstops(); +	int NextTabstopPos(int line, int x, int tabWidth) const; +	bool ClearTabstops(int line); +	bool AddTabstop(int line, int x); +	int GetNextTabstop(int line, int x) const; +	void LinesAddedOrRemoved(int lineOfPos, int linesAdded); +  	void DropGraphics(bool freeObjects);  	void AllocateGraphics(const ViewStyle &vsDraw);  	void RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewStyle &vsDraw); diff --git a/src/Editor.cxx b/src/Editor.cxx index 7fb849114..1c1e38d65 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -29,6 +29,7 @@  #include "RunStyles.h"  #include "ContractionState.h"  #include "CellBuffer.h" +#include "PerLine.h"  #include "KeyMap.h"  #include "Indicator.h"  #include "XPM.h" @@ -1987,6 +1988,9 @@ void Editor::ClearAll() {  			pdoc->MarginClearAll();  		}  	} + +	view.ClearAllTabstops(); +  	sel.Clear();  	SetTopLine(0);  	SetVerticalScrollPos(); @@ -2457,6 +2461,9 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) {  			Redraw();  		}  	} +	if (mh.modificationType & SC_MOD_CHANGETABSTOPS) { +		Redraw(); +	}  	if (mh.modificationType & SC_MOD_LEXERSTATE) {  		if (paintState == painting) {  			CheckForChangeOutsidePaint( @@ -2520,6 +2527,7 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) {  			} else {  				cs.DeleteLines(lineOfPos, -mh.linesAdded);  			} +			view.LinesAddedOrRemoved(lineOfPos, mh.linesAdded);  		}  		if (mh.modificationType & SC_MOD_CHANGEANNOTATION) {  			int lineDoc = pdoc->LineFromPosition(mh.position); @@ -4813,6 +4821,8 @@ void Editor::SetDocPointer(Document *document) {  	view.llc.Deallocate();  	NeedWrapping(); +	view.ClearAllTabstops(); +  	pdoc->AddWatcher(this, 0);  	SetScrollBars();  	Redraw(); @@ -5983,6 +5993,23 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {  	case SCI_GETTABWIDTH:  		return pdoc->tabInChars; +	case SCI_CLEARTABSTOPS: +		if (view.ClearTabstops(static_cast<int>(wParam))) { +			DocModification mh(SC_MOD_CHANGETABSTOPS, 0, 0, 0, 0, static_cast<int>(wParam)); +			NotifyModified(pdoc, mh, NULL); +		} +		break; + +	case SCI_ADDTABSTOP: +		if (view.AddTabstop(static_cast<int>(wParam), static_cast<int>(lParam))) { +			DocModification mh(SC_MOD_CHANGETABSTOPS, 0, 0, 0, 0, static_cast<int>(wParam)); +			NotifyModified(pdoc, mh, NULL); +		} +		break; + +	case SCI_GETNEXTTABSTOP: +		return view.GetNextTabstop(static_cast<int>(wParam), static_cast<int>(lParam)); +  	case SCI_SETINDENT:  		pdoc->indentInChars = static_cast<int>(wParam);  		if (pdoc->indentInChars != 0) diff --git a/src/PerLine.cxx b/src/PerLine.cxx index 8b0dbc44b..8fd96cbed 100644 --- a/src/PerLine.cxx +++ b/src/PerLine.cxx @@ -7,6 +7,7 @@  #include <string.h> +#include <vector>  #include <algorithm>  #include "Platform.h" @@ -484,3 +485,72 @@ int LineAnnotation::Lines(int line) const {  	else  		return 0;  } + +LineTabstops::~LineTabstops() { +	Init(); +} + +void LineTabstops::Init() { +	for (int line = 0; line < tabstops.Length(); line++) { +		delete tabstops[line]; +	} +	tabstops.DeleteAll(); +} + +void LineTabstops::InsertLine(int line) { +	if (tabstops.Length()) { +		tabstops.EnsureLength(line); +		tabstops.Insert(line, 0); +	} +} + +void LineTabstops::RemoveLine(int line) { +	if (tabstops.Length() > line) { +		delete tabstops[line]; +		tabstops.Delete(line); +	} +} + +bool LineTabstops::ClearTabstops(int line) { +	if (line < tabstops.Length()) { +		TabstopList *tl = tabstops[line]; +		if (tl) { +			tl->clear(); +			return true; +		} +	} +	return false; +} + +bool LineTabstops::AddTabstop(int line, int x) { +	tabstops.EnsureLength(line + 1); +	if (!tabstops[line]) { +		tabstops[line] = new TabstopList(); +	} + +	TabstopList *tl = tabstops[line]; +	if (tl) { +		// tabstop positions are kept in order - insert in the right place +		std::vector<int>::iterator it = std::lower_bound(tl->begin(), tl->end(), x); +		// don't insert duplicates +		if (it == tl->end() || *it != x) { +			tl->insert(it, x); +			return true; +		} +	} +	return false; +} + +int LineTabstops::GetNextTabstop(int line, int x) const { +	if (line < tabstops.Length()) { +		TabstopList *tl = tabstops[line]; +		if (tl) { +			for (size_t i = 0; i < tl->size(); i++) { +				if ((*tl)[i] > x) { +					return (*tl)[i]; +				} +			} +		} +	} +	return 0; +} diff --git a/src/PerLine.h b/src/PerLine.h index 70d0023e4..4bf1c88fd 100644 --- a/src/PerLine.h +++ b/src/PerLine.h @@ -112,6 +112,23 @@ public:  	int Lines(int line) const;  }; +typedef std::vector<int> TabstopList; + +class LineTabstops : public PerLine { +	SplitVector<TabstopList *> tabstops; +public: +	LineTabstops() { +	} +	virtual ~LineTabstops(); +	virtual void Init(); +	virtual void InsertLine(int line); +	virtual void RemoveLine(int line); + +	bool ClearTabstops(int line); +	bool AddTabstop(int line, int x); +	int GetNextTabstop(int line, int x) const; +}; +  #ifdef SCI_NAMESPACE  }  #endif | 
