A cyklus zde proběhne jen při změně velikosti - protože se změní velikost bufferu. Buffer řeším přes pole akcí vykreslení řádků. Při updatování řádku přidám jeho index do akce drawBuffer. Vtip je v tom, že nemusím složitě větvit - stačí se pokusit před a po provedení zmapování kláves přidat do akce vykreslení řádku na cursorTop pozici. Pokud řádek nebyl změněn, pole bool zajistí, že se nic zbytečného nepřidá... Čeho je tam hodně, je pomocných int proměnných a pak 3 akce. Kód je ale přesto dost krátký a poměrně svyžný. OOP jsem neporušil - nevím - dle mého to lépe vyřešit nešlo...
private int
top = 0,
width = 0,
halfWidth = 0,
cursorTop = 0,
cursorLeft = 0,
difference = 0,
charTopCount = 0,
charLeftCount = 0;
bool[] previousRow;
Dictionary<int, char[]> source = new Dictionary<int, char[]>();
Action<Graphics>
drawFullBuffer,
drawBuffer;
Action<Graphics>[] buffer;
public SizeF CharSize { get; private set; }
private int PreviousRow
{
set
{
int index = value;
if(!previousRow[index])
{
drawBuffer += graphics =>
{
buffer[index](graphics);
previousRow[index] = false;
};
previousRow[index] = true;
}
}
}
public int CursorLeft
{
get { return cursorLeft; }
private set
{
if(value < difference * width)
{
if(top > 0 || cursorTop > 0)
{
CursorTop--;
cursorLeft = charLeftCount + difference * halfWidth - 1;
}
}
else if(value < charLeftCount + difference * halfWidth)
cursorLeft = value;
else
{
cursorLeft = difference * width;
CursorTop++;
}
}
}
public int CursorTop
{
get { return cursorTop; }
private set
{
if(value < 0)
{
if(top > 0)
top--;
}
else if(value < charTopCount)
cursorTop = value;
else
top++;
}
}