using System.Collections.Generic;
using System;
using System.Text;
using System.Drawing;
namespace FastColoredTextBoxNS
{
///
/// Line of text
///
public class Line : IList
{
protected List chars;
public string FoldingStartMarker { get; set; }
public string FoldingEndMarker { get; set; }
///
/// Text of line was changed
///
public bool IsChanged { get; set; }
///
/// Time of last visit of caret in this line
///
/// This property can be used for forward/backward navigating
public DateTime LastVisit { get; set; }
///
/// Background brush.
///
public Brush BackgroundBrush { get; set;}
///
/// Unique ID
///
public int UniqueId { get; private set; }
///
/// Count of needed start spaces for AutoIndent
///
public int AutoIndentSpacesNeededCount
{
get;
set;
}
internal Line(int uid)
{
this.UniqueId = uid;
chars = new List();
}
///
/// Clears style of chars, delete folding markers
///
public void ClearStyle(StyleIndex styleIndex)
{
FoldingStartMarker = null;
FoldingEndMarker = null;
for (int i = 0; i < Count; i++)
{
Char c = this[i];
c.style &= ~styleIndex;
this[i] = c;
}
}
///
/// Text of the line
///
public virtual string Text
{
get{
StringBuilder sb = new StringBuilder(Count);
foreach(Char c in this)
sb.Append(c.c);
return sb.ToString();
}
}
///
/// Clears folding markers
///
public void ClearFoldingMarkers()
{
FoldingStartMarker = null;
FoldingEndMarker = null;
}
///
/// Count of start spaces
///
public int StartSpacesCount
{
get
{
int spacesCount = 0;
for (int i = 0; i < Count; i++)
if (this[i].c == ' ')
spacesCount++;
else
break;
return spacesCount;
}
}
public int IndexOf(Char item)
{
return chars.IndexOf(item);
}
public void Insert(int index, Char item)
{
chars.Insert(index, item);
}
public void RemoveAt(int index)
{
chars.RemoveAt(index);
}
public Char this[int index]
{
get
{
return chars[index];
}
set
{
chars[index] = value;
}
}
public void Add(Char item)
{
chars.Add(item);
}
public void Clear()
{
chars.Clear();
}
public bool Contains(Char item)
{
return chars.Contains(item);
}
public void CopyTo(Char[] array, int arrayIndex)
{
chars.CopyTo(array, arrayIndex);
}
///
/// Chars count
///
public int Count
{
get { return chars.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(Char item)
{
return chars.Remove(item);
}
public IEnumerator GetEnumerator()
{
return chars.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return chars.GetEnumerator() as System.Collections.IEnumerator;
}
public virtual void RemoveRange(int index, int count)
{
if (index >= Count)
return;
chars.RemoveRange(index, Math.Min(Count - index, count));
}
public virtual void TrimExcess()
{
chars.TrimExcess();
}
public virtual void AddRange(IEnumerable collection)
{
chars.AddRange(collection);
}
}
public struct LineInfo
{
List cutOffPositions;
//Y coordinate of line on screen
internal int startY;
internal int bottomPadding;
//indent of secondary wordwrap strings (in chars)
internal int wordWrapIndent;
///
/// Visible state
///
public VisibleState VisibleState;
public LineInfo(int startY)
{
cutOffPositions = null;
VisibleState = VisibleState.Visible;
this.startY = startY;
bottomPadding = 0;
wordWrapIndent = 0;
}
///
/// Positions for wordwrap cutoffs
///
public List CutOffPositions
{
get
{
if (cutOffPositions == null)
cutOffPositions = new List();
return cutOffPositions;
}
}
///
/// Count of wordwrap string count for this line
///
public int WordWrapStringsCount
{
get
{
switch (VisibleState)
{
case VisibleState.Visible:
if (cutOffPositions == null)
return 1;
else
return cutOffPositions.Count + 1;
case VisibleState.Hidden: return 0;
case VisibleState.StartOfHiddenBlock: return 1;
}
return 0;
}
}
internal int GetWordWrapStringStartPosition(int iWordWrapLine)
{
return iWordWrapLine == 0 ? 0 : CutOffPositions[iWordWrapLine - 1];
}
internal int GetWordWrapStringFinishPosition(int iWordWrapLine, Line line)
{
if (WordWrapStringsCount <= 0)
return 0;
return iWordWrapLine == WordWrapStringsCount - 1 ? line.Count - 1 : CutOffPositions[iWordWrapLine] - 1;
}
///
/// Gets index of wordwrap string for given char position
///
public int GetWordWrapStringIndex(int iChar)
{
if (cutOffPositions == null || cutOffPositions.Count == 0) return 0;
for (int i = 0; i < cutOffPositions.Count; i++)
if (cutOffPositions[i] >/*>=*/ iChar)
return i;
return cutOffPositions.Count;
}
}
public enum VisibleState: byte
{
Visible, StartOfHiddenBlock, Hidden
}
public enum IndentMarker
{
None,
Increased,
Decreased
}
}