editors: modification marks for lines support, part 2

This commit is contained in:
Vadim Lopatin 2015-02-02 12:10:37 +03:00
parent e7fe0e818c
commit 9194cecd12
3 changed files with 58 additions and 47 deletions

View File

@ -458,6 +458,7 @@ class EditableContent {
/// call listener to say that whole content is replaced e.g. by loading from file /// call listener to say that whole content is replaced e.g. by loading from file
void notifyContentReplaced() { void notifyContentReplaced() {
clearEditMarks();
TextRange rangeBefore; TextRange rangeBefore;
TextRange rangeAfter; TextRange rangeAfter;
// notify about content change // notify about content change
@ -532,6 +533,7 @@ class EditableContent {
/// clear content /// clear content
void clear() { void clear() {
clearUndo(); clearUndo();
clearEditMarks();
_lines.length = 0; _lines.length = 0;
} }
@ -704,7 +706,7 @@ class EditableContent {
} }
/// inserts or removes lines, removes text in range /// inserts or removes lines, removes text in range
protected void replaceRange(TextRange before, TextRange after, dstring[] newContent) { protected void replaceRange(TextRange before, TextRange after, dstring[] newContent, EditStateMark[] marks = null) {
dstring firstLineBefore = line(before.start.line); dstring firstLineBefore = line(before.start.line);
dstring lastLineBefore = before.singleLine ? firstLineBefore : line(before.end.line); dstring lastLineBefore = before.singleLine ? firstLineBefore : line(before.end.line);
dstring firstLineHead = before.start.pos > 0 && before.start.pos <= firstLineBefore.length ? firstLineBefore[0..before.start.pos] : ""d; dstring firstLineHead = before.start.pos > 0 && before.start.pos <= firstLineBefore.length ? firstLineBefore[0..before.start.pos] : ""d;
@ -720,6 +722,10 @@ class EditableContent {
removeLines(before.start.line + 1, linesBefore - linesAfter); removeLines(before.start.line + 1, linesBefore - linesAfter);
} }
for (int i = after.start.line; i <= after.end.line; i++) { for (int i = after.start.line; i <= after.end.line; i++) {
if (marks) {
if (i - after.start.line < marks.length)
_editMarks[i] = marks[i - after.start.line];
}
dstring newline = newContent[i - after.start.line]; dstring newline = newContent[i - after.start.line];
if (i == after.start.line && i == after.end.line) { if (i == after.start.line && i == after.end.line) {
dchar[] buf; dchar[] buf;
@ -926,9 +932,10 @@ class EditableContent {
TextRange rangeBefore = op.newRange; TextRange rangeBefore = op.newRange;
dstring[] oldcontent = op.content; dstring[] oldcontent = op.content;
dstring[] newcontent = op.oldContent; dstring[] newcontent = op.oldContent;
EditStateMark[] newmarks = op.oldEditMarks;
TextRange rangeAfter = op.range; TextRange rangeAfter = op.range;
//Log.d("Undoing op rangeBefore=", rangeBefore, " contentBefore=`", oldcontent, "` rangeAfter=", rangeAfter, " contentAfter=`", newcontent, "`"); //Log.d("Undoing op rangeBefore=", rangeBefore, " contentBefore=`", oldcontent, "` rangeAfter=", rangeAfter, " contentAfter=`", newcontent, "`");
replaceRange(rangeBefore, rangeAfter, newcontent); replaceRange(rangeBefore, rangeAfter, newcontent, newmarks);
handleContentChange(op, rangeBefore, rangeAfter, this); handleContentChange(op, rangeBefore, rangeAfter, this);
return true; return true;
} }

View File

@ -317,55 +317,59 @@ class Window {
static immutable int PERFORMANCE_LOGGING_THRESHOLD_MS = 20; static immutable int PERFORMANCE_LOGGING_THRESHOLD_MS = 20;
void onDraw(DrawBuf buf) { void onDraw(DrawBuf buf) {
bool needDraw = false; try {
bool needLayout = false; bool needDraw = false;
bool animationActive = false; bool needLayout = false;
checkUpdateNeeded(needDraw, needLayout, animationActive); bool animationActive = false;
if (needLayout || animationActive)
needDraw = true;
long ts = std.datetime.Clock.currStdTime;
if (animationActive && lastDrawTs != 0) {
animate(ts - lastDrawTs);
// layout required flag could be changed during animate - check again
checkUpdateNeeded(needDraw, needLayout, animationActive); checkUpdateNeeded(needDraw, needLayout, animationActive);
} if (needLayout || animationActive)
lastDrawTs = ts; needDraw = true;
if (needLayout) { long ts = std.datetime.Clock.currStdTime;
long measureStart = currentTimeMillis; if (animationActive && lastDrawTs != 0) {
measure(); animate(ts - lastDrawTs);
long measureEnd = currentTimeMillis; // layout required flag could be changed during animate - check again
if (measureEnd - measureStart > PERFORMANCE_LOGGING_THRESHOLD_MS) { checkUpdateNeeded(needDraw, needLayout, animationActive);
debug(DebugRedraw) Log.d("measure took ", measureEnd - measureStart, " ms");
} }
layout(); lastDrawTs = ts;
long layoutEnd = currentTimeMillis; if (needLayout) {
if (layoutEnd - measureEnd > PERFORMANCE_LOGGING_THRESHOLD_MS) { long measureStart = currentTimeMillis;
debug(DebugRedraw) Log.d("layout took ", layoutEnd - measureEnd, " ms"); measure();
long measureEnd = currentTimeMillis;
if (measureEnd - measureStart > PERFORMANCE_LOGGING_THRESHOLD_MS) {
debug(DebugRedraw) Log.d("measure took ", measureEnd - measureStart, " ms");
}
layout();
long layoutEnd = currentTimeMillis;
if (layoutEnd - measureEnd > PERFORMANCE_LOGGING_THRESHOLD_MS) {
debug(DebugRedraw) Log.d("layout took ", layoutEnd - measureEnd, " ms");
}
//checkUpdateNeeded(needDraw, needLayout, animationActive);
} }
//checkUpdateNeeded(needDraw, needLayout, animationActive); long drawStart = currentTimeMillis;
} // draw main widget
long drawStart = currentTimeMillis; _mainWidget.onDraw(buf);
// draw main widget
_mainWidget.onDraw(buf);
PopupWidget modal = modalPopup(); PopupWidget modal = modalPopup();
// draw popups // draw popups
foreach(p; _popups) { foreach(p; _popups) {
if (p is modal) { if (p is modal) {
// TODO: get shadow color from theme // TODO: get shadow color from theme
buf.fillRect(Rect(0, 0, buf.width, buf.height), 0xD0404040); buf.fillRect(Rect(0, 0, buf.width, buf.height), 0xD0404040);
}
p.onDraw(buf);
} }
p.onDraw(buf); long drawEnd = currentTimeMillis;
debug(DebugRedraw) {
if (drawEnd - drawStart > PERFORMANCE_LOGGING_THRESHOLD_MS)
Log.d("draw took ", drawEnd - drawStart, " ms");
}
if (animationActive)
scheduleAnimation();
_actionsUpdateRequested = false;
} catch (Exception e) {
Log.e("Exception inside winfow.onDraw: ", e);
} }
long drawEnd = currentTimeMillis;
debug(DebugRedraw) {
if (drawEnd - drawStart > PERFORMANCE_LOGGING_THRESHOLD_MS)
Log.d("draw took ", drawEnd - drawStart, " ms");
}
if (animationActive)
scheduleAnimation();
_actionsUpdateRequested = false;
} }
/// after drawing, call to schedule redraw if animation is active /// after drawing, call to schedule redraw if animation is active

View File

@ -196,8 +196,8 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
protected uint _leftPaneLineNumberColor = 0x4060D0; protected uint _leftPaneLineNumberColor = 0x4060D0;
protected uint _leftPaneLineNumberBackgroundColor = 0xF0F0F0; protected uint _leftPaneLineNumberBackgroundColor = 0xF0F0F0;
protected uint _iconsPaneWidth = 16; protected uint _iconsPaneWidth = 16;
protected uint _foldingPaneWidth = 16; protected uint _foldingPaneWidth = 12;
protected uint _modificationMarksPaneWidth = 8; protected uint _modificationMarksPaneWidth = 4;
/// when true, call measureVisibileText on next layout /// when true, call measureVisibileText on next layout
protected bool _contentChanged = true; protected bool _contentChanged = true;
@ -249,7 +249,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
buf.fillRect(rc, 0xFFD040); buf.fillRect(rc, 0xFFD040);
} else if (m == EditStateMark.saved) { } else if (m == EditStateMark.saved) {
// modified, not saved // modified, not saved
buf.fillRect(rc, 0x80FF60); buf.fillRect(rc, 0x20C020);
} }
} }
} }