editors refactoring

This commit is contained in:
Vadim Lopatin 2014-04-22 16:58:31 +04:00
parent bf8864da1a
commit 28774a9ba6
1 changed files with 88 additions and 56 deletions

View File

@ -387,6 +387,11 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
protected EditableContent _content;
protected Rect _clientRc;
protected int _lineHeight;
protected Point _scrollPos;
protected bool _fixedFont;
protected int _spaceWidth;
protected int _tabSize = 4;
this(string ID) {
super(ID);
@ -456,6 +461,63 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
abstract protected TextPosition clientToTextPos(Point pt);
abstract protected void ensureCaretVisible();
abstract protected Point measureVisibleText();
protected void updateFontProps() {
FontRef font = font();
_fixedFont = false;
_spaceWidth = font.textSize(" "d).x;
int mwidth = font.textSize("M"d).x;
int iwidth = font.textSize("i"d).x;
if (mwidth == iwidth)
_fixedFont = true;
_lineHeight = font.height;
}
/// override to update scrollbars - if necessary
protected void updateScrollbars() {
}
protected void correctCaretPos() {
if (_caretPos.line >= _content.length)
_caretPos.line = _content.length - 1;
if (_caretPos.line < 0)
_caretPos.line = 0;
dstring currentLine = _content[_caretPos.line];
if (_caretPos.pos > currentLine.length)
_caretPos.pos = cast(int)currentLine.length;
if (_caretPos.pos < 0)
_caretPos.pos = 0;
}
private int[] _lineWidthBuf;
protected int calcLineWidth(dstring s) {
int w = 0;
if (_fixedFont) {
int tabw = _tabSize * _spaceWidth;
// version optimized for fixed font
for (int i = 0; i < s.length; i++) {
if (s[i] == '\t') {
w += _spaceWidth;
w = (w + tabw - 1) / tabw * tabw;
} else {
w += _spaceWidth;
}
}
} else {
// variable pitch font
if (_lineWidthBuf.length < s.length)
_lineWidthBuf.length = s.length;
int charsMeasured = font.measureText(s, _lineWidthBuf, int.max);
if (charsMeasured > 0)
w = _lineWidthBuf[charsMeasured - 1];
}
return w;
}
protected void updateSelectionAfterCursorMovement(TextPosition oldCaretPos, bool selecting) {
if (selecting) {
if (oldCaretPos == _selectionRange.start) {
@ -560,7 +622,7 @@ class EditLine : EditWidgetBase {
}
override bool onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter) {
measureText();
measureVisibleText();
_caretPos = rangeAfter.end;
invalidate();
return true;
@ -598,7 +660,24 @@ class EditLine : EditWidgetBase {
return res;
}
protected void measureText() {
override protected void ensureCaretVisible() {
//_scrollPos
Rect rc = textPosToClient(_caretPos);
if (rc.left < 0) {
// scroll left
_scrollPos.x -= -rc.left + _clientRc.width / 4;
if (_scrollPos.x < 0)
_scrollPos.x = 0;
invalidate();
} else if (rc.left >= _clientRc.width - 10) {
// scroll right
_scrollPos.x += (rc.left - _clientRc.width) + _clientRc.width / 4;
invalidate();
}
updateScrollbars();
}
override protected Point measureVisibleText() {
FontRef font = font();
//Point sz = font.textSize(text);
_measuredText = text;
@ -606,11 +685,13 @@ class EditLine : EditWidgetBase {
int charsMeasured = font.measureText(_measuredText, _measuredTextWidths, int.max);
_measuredTextSize.x = charsMeasured > 0 ? _measuredTextWidths[charsMeasured - 1]: 0;
_measuredTextSize.y = font.height;
return _measuredTextSize;
}
/// measure
override void measure(int parentWidth, int parentHeight) {
measureText();
updateFontProps();
measureVisibleText();
measuredContent(parentWidth, parentHeight, _measuredTextSize.x, _measuredTextSize.y);
}
@ -745,9 +826,6 @@ class EditBox : EditWidgetBase, OnScrollHandler {
addChild(_vscrollbar);
}
protected int _lineHeight;
protected Point _scrollPos;
protected int _firstVisibleLine;
protected int _maxLineWidth;
@ -756,34 +834,6 @@ class EditBox : EditWidgetBase, OnScrollHandler {
protected int[][] _visibleLinesMeasurement; // char positions for visible lines
protected int[] _visibleLinesWidths; // width (in pixels) of visible lines
protected bool _fixedFont;
protected int _spaceWidth;
protected int _tabSize = 4;
private int[] _lineWidthBuf;
protected int calcLineWidth(dstring s) {
int w = 0;
if (_fixedFont) {
int tabw = _tabSize * _spaceWidth;
// version optimized for fixed font
for (int i = 0; i < s.length; i++) {
if (s[i] == '\t') {
w += _spaceWidth;
w = (w + tabw - 1) / tabw * tabw;
} else {
w += _spaceWidth;
}
}
} else {
// variable pitch font
if (_lineWidthBuf.length < s.length)
_lineWidthBuf.length = s.length;
int charsMeasured = font.measureText(s, _lineWidthBuf, int.max);
if (charsMeasured > 0)
w = _lineWidthBuf[charsMeasured - 1];
}
return w;
}
protected void updateMaxLineWidth() {
// find max line width. TODO: optimize!!!
int maxw;
@ -797,7 +847,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
_maxLineWidth = maxw;
}
protected Point measureVisibleText() {
override protected Point measureVisibleText() {
Point sz;
FontRef font = font();
_lineHeight = font.height;
@ -820,7 +870,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
return sz;
}
protected void updateScrollbars() {
override protected void updateScrollbars() {
int visibleLines = _clientRc.height / _lineHeight; // fully visible lines
if (visibleLines < 1)
visibleLines = 1;
@ -852,7 +902,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
}
protected void ensureCaretVisible() {
override protected void ensureCaretVisible() {
if (_caretPos.line >= _content.length)
_caretPos.line = _content.length - 1;
if (_caretPos.line < 0)
@ -941,18 +991,6 @@ class EditBox : EditWidgetBase, OnScrollHandler {
return res;
}
protected void correctCaretPos() {
if (_caretPos.line >= _content.length)
_caretPos.line = _content.length - 1;
if (_caretPos.line < 0)
_caretPos.line = 0;
dstring currentLine = _content[_caretPos.line];
if (_caretPos.pos > currentLine.length)
_caretPos.pos = cast(int)currentLine.length;
if (_caretPos.pos < 0)
_caretPos.pos = 0;
}
override protected bool handleAction(Action a) {
TextPosition oldCaretPos = _caretPos;
dstring currentLine = _content[_caretPos.line];
@ -1164,13 +1202,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
int hsbheight = _hscrollbar.measuredHeight;
int vsbwidth = _vscrollbar.measuredWidth;
FontRef font = font();
_fixedFont = false;
_spaceWidth = font.textSize(" "d).x;
int mwidth = font.textSize("M"d).x;
int iwidth = font.textSize("i"d).x;
if (mwidth == iwidth)
_fixedFont = true;
updateFontProps();
updateMaxLineWidth();