From 43deaf5e127a3bb92e1e2c72fa9cd8f8233578a9 Mon Sep 17 00:00:00 2001 From: nyamatongwe Date: Fri, 3 Jul 2009 05:48:47 +0000 Subject: Discontiguoues selection and virtual space initial commit. --- src/Selection.cxx | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 src/Selection.cxx (limited to 'src/Selection.cxx') diff --git a/src/Selection.cxx b/src/Selection.cxx new file mode 100644 index 000000000..224fafc69 --- /dev/null +++ b/src/Selection.cxx @@ -0,0 +1,345 @@ +// Scintilla source code edit control +/** @file Selection.cxx + ** Classes maintaining the selection. + **/ +// Copyright 2009 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include + +#include "Platform.h" + +#include "Scintilla.h" + +#include "Selection.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) { + if (insertion) { + if (position > startChange) { + position += length; + } + } else { + if (position > startChange) { + int endDeletion = startChange + length; + if (position > endDeletion) { + position -= length; + } else { + position = startChange; + } + } + } +} + +bool SelectionPosition::operator <(const SelectionPosition &other) const { + if (position == other.position) + return virtualSpace < other.virtualSpace; + else + return position < other.position; +} + +bool SelectionPosition::operator >(const SelectionPosition &other) const { + if (position == other.position) + return virtualSpace > other.virtualSpace; + else + return position > other.position; +} + +bool SelectionPosition::operator <=(const SelectionPosition &other) const { + if (position == other.position && virtualSpace == other.virtualSpace) + return true; + else + return other > *this; +} + +bool SelectionPosition::operator >=(const SelectionPosition &other) const { + if (position == other.position && virtualSpace == other.virtualSpace) + return true; + else + return *this > other; +} + +int SelectionRange::Length() const { + if (anchor > caret) { + return anchor.Position() - caret.Position(); + } else { + return caret.Position() - anchor.Position(); + } +} + +bool SelectionRange::Contains(int pos) const { + if (anchor > caret) + return (pos >= caret.Position()) && (pos <= anchor.Position()); + else + return (pos >= anchor.Position()) && (pos <= caret.Position()); +} + +bool SelectionRange::Contains(SelectionPosition sp) const { + if (anchor > caret) + return (sp >= caret) && (sp <= anchor); + else + return (sp >= anchor) && (sp <= caret); +} + +bool SelectionRange::ContainsCharacter(int posCharacter) const { + if (anchor > caret) + return (posCharacter >= caret.Position()) && (posCharacter < anchor.Position()); + else + return (posCharacter >= anchor.Position()) && (posCharacter < caret.Position()); +} + +bool SelectionRange::Intersect(int start, int end, SelectionPosition &selStart, SelectionPosition &selEnd) const { + SelectionPosition spEnd(end, 100000); // Large amount of virtual space + SelectionPosition first; + SelectionPosition last; + if (anchor > caret) { + first = caret; + last = anchor; + } else { + first = anchor; + last = caret; + } + if ((first < spEnd) && (last.Position() > start)) { + if (start > first.Position()) + selStart = SelectionPosition(start); + else + selStart = first; + if (spEnd < last) + selEnd = SelectionPosition(end); + else + selEnd = last; + return true; + } else { + return false; + } +} + +bool SelectionRange::Trim(SelectionPosition startPos, SelectionPosition endPos) { + SelectionPosition startRange = startPos; + SelectionPosition endRange = endPos; + if (startPos > endPos) { + startRange = endPos; + endRange = startPos; + } + SelectionPosition start = Start(); + SelectionPosition end = End(); + PLATFORM_ASSERT(start <= end); + PLATFORM_ASSERT(startRange <= endRange); + if ((startRange <= end) && (endRange >= start)) { + if ((start > startRange) && (end < endRange)) { + // Completely covered by range -> empty at start + end = start; + } else if ((start < startRange) && (end > endRange)) { + // Completely covers range -> empty at start + end = start; + } else if (start <= startRange) { + // Trim end + end = startRange; + } else { // + PLATFORM_ASSERT(end >= endRange); + // Trim start + start = endRange; + } + if (anchor > caret) { + caret = start; + anchor = end; + } else { + anchor = start; + caret = end; + } + return Empty(); + } else { + return false; + } +} + +// If range is all virtual collapse to start of virtual space +void SelectionRange::MinimizeVirtualSpace() { + if (caret.Position() == anchor.Position()) { + int virtualSpace = caret.VirtualSpace(); + if (virtualSpace > anchor.VirtualSpace()) + virtualSpace = anchor.VirtualSpace(); + caret.SetVirtualSpace(virtualSpace); + anchor.SetVirtualSpace(virtualSpace); + } +} + +void Selection::Allocate() { + if (nRanges >= allocated) { + size_t allocateNew = (allocated + 1) * 2; + SelectionRange *rangesNew = new SelectionRange[allocateNew]; + for (size_t r=0; r ranges[i].Start().Position()) && (pos <= ranges[i].End().Position())) + return true; + } + return false; +} + +int Selection::VirtualSpaceFor(int pos) const { + int virtualSpace = 0; + for (size_t i=0; i