mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
Multiline cursor
This commit is contained in:
parent
70f4f0fbe2
commit
5210c590fb
5 changed files with 97 additions and 54 deletions
|
|
@ -1093,6 +1093,8 @@ bool CodeEditor::Key(dword code, int count) {
|
|||
Replace();
|
||||
return true;
|
||||
}
|
||||
if(IsRectSelection())
|
||||
return LineEdit::Key(code, count);
|
||||
switch(code) {
|
||||
case K_SHIFT_CTRL_UP:
|
||||
SwapUpDown(true);
|
||||
|
|
@ -1137,7 +1139,8 @@ bool CodeEditor::Key(dword code, int count) {
|
|||
case K_SHIFT_CTRL_TAB:
|
||||
return LineEdit::Key(K_TAB, count);
|
||||
case K_ENTER:
|
||||
IndentInsert('\n', count);
|
||||
if(!IsRectSelection())
|
||||
IndentInsert('\n', count);
|
||||
return true;
|
||||
}
|
||||
bool sel = code & K_SHIFT;
|
||||
|
|
|
|||
|
|
@ -132,33 +132,8 @@ bool LineEdit::GetRectSelection(const Rect& rect, int line, int64& l, int64& h)
|
|||
return false;
|
||||
}
|
||||
|
||||
void LineEdit::RectSelectionChar(int c)
|
||||
{
|
||||
Rect rect = GetRectSelection();
|
||||
if(rect.GetWidth())
|
||||
RemoveRectSelection();
|
||||
WString txt;
|
||||
for(int i = rect.top; i <= rect.bottom; i++) {
|
||||
int64 l, h;
|
||||
CacheLinePos(i);
|
||||
GetRectSelection(rect, i, l, h);
|
||||
WString s = GetWLine(i);
|
||||
s.Insert(int(l - GetPos64(i)), c);
|
||||
txt.Cat(s);
|
||||
txt.Cat('\n');
|
||||
}
|
||||
int l = GetPos32(rect.top);
|
||||
int h = GetPos32(rect.bottom) + GetLineLength(rect.bottom);
|
||||
if(h < GetLength32())
|
||||
h++;
|
||||
Remove((int)l, int(h - l));
|
||||
Insert((int)l, txt);
|
||||
anchor = (int)GetGPos(rect.top, rect.left + 1);
|
||||
cursor = (int)GetGPos(rect.bottom, rect.left + 1);
|
||||
PlaceCaret0();
|
||||
}
|
||||
|
||||
int LineEdit::RemoveRectSelection()
|
||||
int LineEdit::RectSelectionOp(Event<int, Rect, int64, int64, WString&> op, Event<Rect&> changesel)
|
||||
{
|
||||
Rect rect = GetRectSelection();
|
||||
WString txt;
|
||||
|
|
@ -167,7 +142,7 @@ int LineEdit::RemoveRectSelection()
|
|||
CacheLinePos(i);
|
||||
GetRectSelection(rect, i, l, h);
|
||||
WString s = GetWLine(i);
|
||||
s.Remove(int(l - GetPos64(i)), int(h - l));
|
||||
op(i, rect, l, h, s);
|
||||
txt.Cat(s);
|
||||
txt.Cat('\n');
|
||||
}
|
||||
|
|
@ -177,12 +152,63 @@ int LineEdit::RemoveRectSelection()
|
|||
h++;
|
||||
Remove((int)l, int(h - l));
|
||||
Insert((int)l, txt);
|
||||
changesel(rect);
|
||||
anchor = (int)GetGPos(rect.top, rect.left);
|
||||
cursor = (int)GetGPos(rect.bottom, rect.left);
|
||||
PlaceCaret0();
|
||||
return cursor;
|
||||
}
|
||||
|
||||
void LineEdit::RectSelectionChar(int c)
|
||||
{
|
||||
if(GetRectSelection().GetWidth())
|
||||
RemoveRectSelection();
|
||||
int p = -1; // position after insertion, because of '\t' and double size chars cannot do just left+1
|
||||
RectSelectionOp(
|
||||
[&](int i, Rect rect, int64 l, int64 h, WString& s) {
|
||||
int x = GetColumnLine(l).x;
|
||||
int cursor;
|
||||
if(x < rect.left) {
|
||||
s.Cat(' ', rect.left - x);
|
||||
s.Cat(c);
|
||||
if(p < 0)
|
||||
p = GetPos(i) + s.GetCount();
|
||||
}
|
||||
else {
|
||||
s.Insert(int(l - GetPos64(i)), c);
|
||||
if(p < 0) // first time the position is unchanged after whole text is replaced
|
||||
p = l + 1;
|
||||
}
|
||||
|
||||
},
|
||||
[&](Rect& r) { r.left = GetColumnLine(p).x; }
|
||||
);
|
||||
}
|
||||
|
||||
void LineEdit::RectSelectionBackspace()
|
||||
{
|
||||
Rect r = GetRectSelection();
|
||||
if(r.GetWidth())
|
||||
RemoveRectSelection();
|
||||
else
|
||||
if(r.left > 0)
|
||||
RectSelectionOp(
|
||||
[&](int i, Rect rect, int64 l, int64 h, WString& s) {
|
||||
int p = int(l - GetPos64(i));
|
||||
if(GetColumnLine(l).x == rect.left && p - 1 < s.GetCount())
|
||||
s.Remove(p - 1, 1);
|
||||
},
|
||||
[&](Rect& r) { r.left--; }
|
||||
);
|
||||
}
|
||||
|
||||
int LineEdit::RemoveRectSelection()
|
||||
{
|
||||
return RectSelectionOp(
|
||||
[&](int i, Rect, int64 l, int64 h, WString& s) { s.Remove(int(l - GetPos64(i)), int(h - l)); }
|
||||
);
|
||||
}
|
||||
|
||||
WString LineEdit::CopyRectSelection()
|
||||
{
|
||||
WString txt;
|
||||
|
|
@ -204,20 +230,23 @@ WString LineEdit::CopyRectSelection()
|
|||
int LineEdit::PasteRectSelection(const WString& s)
|
||||
{
|
||||
Vector<WString> cl = Split(s, '\n', false);
|
||||
Rect rect = GetRectSelection();
|
||||
int64 pos = cursor;
|
||||
int n = 0;
|
||||
for(int i = 0; i < cl.GetCount() && rect.top + i <= rect.bottom; i++) {
|
||||
int64 l, h;
|
||||
CacheLinePos(i);
|
||||
GetRectSelection(rect, i + rect.top, l, h);
|
||||
Remove((int)l, int(h - l));
|
||||
int nn = Insert((int)l, cl[i]);
|
||||
n += nn;
|
||||
pos = l + nn;
|
||||
int cursor0 = cursor;
|
||||
if(cl.GetCount() == 1)
|
||||
PasteColumn(cl[0]);
|
||||
else {
|
||||
Rect rect = GetRectSelection();
|
||||
int64 pos = cursor;
|
||||
for(int i = 0; i < cl.GetCount() && rect.top + i <= rect.bottom; i++) {
|
||||
int64 l, h;
|
||||
CacheLinePos(i);
|
||||
GetRectSelection(rect, i + rect.top, l, h);
|
||||
Remove((int)l, int(h - l));
|
||||
int nn = Insert((int)l, cl[i]);
|
||||
pos = l + nn;
|
||||
}
|
||||
PlaceCaret(pos);
|
||||
}
|
||||
PlaceCaret(pos);
|
||||
return n;
|
||||
return cursor - cursor0;
|
||||
}
|
||||
|
||||
void LineEdit::PasteColumn(const WString& text)
|
||||
|
|
@ -655,8 +684,8 @@ void LineEdit::Paint0(Draw& w)
|
|||
if(!IsNull(vline))
|
||||
rw.DrawRect(caretpos.x, y, 1, fsz.cy, vline);
|
||||
}
|
||||
if(rectsel && rect.left == rect.right && i >= rect.top && i <= rect.bottom)
|
||||
rw.DrawRect(rect.left * fsz.cx - scx, y, 2, fsz.cy, Blend(color[PAPER_SELECTED], color[PAPER_NORMAL]));
|
||||
// if(rectsel && rect.left == rect.right && i >= rect.top && i <= rect.bottom)
|
||||
// rw.DrawRect(rect.left * fsz.cx - scx, y, 2, fsz.cy, Blend(color[PAPER_SELECTED], color[PAPER_NORMAL]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1078,6 +1107,8 @@ void LineEdit::MoveTextEnd(bool sel) {
|
|||
bool LineEdit::InsertChar(dword key, int count, bool canow) {
|
||||
if(key == K_TAB && !processtab)
|
||||
return false;
|
||||
if(findarg(key, '\n', K_ENTER) >= 0 && IsRectSelection())
|
||||
return true;
|
||||
if(filter && key >= 32 && key < K_CHAR_LIM)
|
||||
key = (*filter)(key);
|
||||
if(!IsReadOnly() && (key >= 32 && key < K_CHAR_LIM || key == '\t' || key == '\n' ||
|
||||
|
|
@ -1273,6 +1304,8 @@ bool LineEdit::Key(dword key, int count) {
|
|||
case K_CTRL_A:
|
||||
SelectAll();
|
||||
break;
|
||||
case K_ALT_KEY|K_KEYUP:
|
||||
return IsRectSelection(); // prevent opening menu on Alt+Click
|
||||
default:
|
||||
dorectsel = false;
|
||||
if(IsReadOnly())
|
||||
|
|
@ -1282,6 +1315,10 @@ bool LineEdit::Key(dword key, int count) {
|
|||
DeleteChar();
|
||||
break;
|
||||
case K_BACKSPACE:
|
||||
if(IsRectSelection()) {
|
||||
RectSelectionBackspace();
|
||||
break;
|
||||
}
|
||||
case K_SHIFT|K_BACKSPACE:
|
||||
Backspace();
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -378,6 +378,8 @@ protected:
|
|||
void SyncFont();
|
||||
bool IsDoubleChar(int ch) const;
|
||||
void RectSelectionChar(int c);
|
||||
void RectSelectionBackspace();
|
||||
int RectSelectionOp(Event<int, Rect, int64, int64, WString&> op, Event<Rect&> changesel = Null);
|
||||
|
||||
struct RefreshDraw;
|
||||
friend class TextCtrl;
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ t]_[*@3 p])_[@(0.0.255) const]&]
|
|||
[s2;%% Get the the offset of character placed at [%-*@3 p].&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:LineEdit`:`:GetColumnLine`(int`)const: [_^Point^ Point]_[* GetColumnLine]([@(0.0.255) i
|
||||
nt]_[*@3 pos])_[@(0.0.255) const]&]
|
||||
[s5;:Upp`:`:LineEdit`:`:GetColumnLine`(int64`)const: Point [* GetColumnLine](int64
|
||||
[*@3 pos]) [@(0.0.255) const]&]
|
||||
[s2;%% Returns the line and column for the character at [%-*@3 pos]
|
||||
accounting for any tabulators. Column is x member of resulting
|
||||
Point, line is y.&]
|
||||
|
|
@ -77,8 +77,8 @@ oint]_[*@3 pos])_[@(0.0.255) const]&]
|
|||
Does account for tabulators.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:LineEdit`:`:GetIndexLine`(int`)const: [_^Point^ Point]_[* GetIndexLine]([@(0.0.255) in
|
||||
t]_[*@3 pos])_[@(0.0.255) const]&]
|
||||
[s5;:Upp`:`:LineEdit`:`:GetIndexLine`(int64`)const: Point [* GetIndexLine](int64
|
||||
[*@3 pos]) [@(0.0.255) const]&]
|
||||
[s2;%% Returns the line and index of character in the line for the
|
||||
given [%-*@3 pos]. Does not account for tabulators.&]
|
||||
[s3; &]
|
||||
|
|
@ -89,8 +89,8 @@ oint]_[*@3 pos])_[@(0.0.255) const]&]
|
|||
Does not account for tabulators.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:LineEdit`:`:SetRectSelection`(int`,int`): [@(0.0.255) void]_[* SetRectSelection]([@(0.0.255) i
|
||||
nt]_[*@3 l], [@(0.0.255) int]_[*@3 h])&]
|
||||
[s5;:Upp`:`:LineEdit`:`:SetRectSelection`(int64`,int64`): [@(0.0.255) void]
|
||||
[* SetRectSelection](int64 [*@3 l], int64 [*@3 h])&]
|
||||
[s2;%% Sets rectangular selection.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
|
|
@ -105,9 +105,10 @@ onst]&]
|
|||
[s2;%% Returns rectangular selection (as `"graphical`").&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:LineEdit`:`:GetRectSelection`(const Rect`&`,int`,int`&`,int`&`): [@(0.0.255) bool]_
|
||||
[* GetRectSelection]([@(0.0.255) const]_[_^Rect^ Rect][@(0.0.255) `&]_[*@3 rect],
|
||||
[@(0.0.255) int]_[*@3 line], [@(0.0.255) int`&]_[*@3 l], [@(0.0.255) int]_`&[*@3 h])&]
|
||||
[s5;:Upp`:`:LineEdit`:`:GetRectSelection`(const Rect`&`,int`,int64`&`,int64`&`): [@(0.0.255) b
|
||||
ool] [* GetRectSelection]([@(0.0.255) const] Rect[@(0.0.255) `&] [*@3 rect],
|
||||
[@(0.0.255) int] [*@3 line], int64[@(0.0.255) `&] [*@3 l], int64[@(0.0.255) `&]
|
||||
[*@3 h])&]
|
||||
[s2;%% Returns lower and upper limits [%-*@3 l] [%-*@3 h] of characters
|
||||
of [%-*@3 line] that are in rectangular selection [%-*@3 rect]. Returns
|
||||
false when line is not in selection.&]
|
||||
|
|
@ -217,7 +218,7 @@ the text).&]
|
|||
[s5;:LineEdit`:`:PasteColumn`(const WString`&`): [@(0.0.255) void]_[* PasteColumn]([@(0.0.255) c
|
||||
onst]_[_^WString^ WString][@(0.0.255) `&]_[*@3 text])&]
|
||||
[s2;%% Pastes lines of [%-*@3 text] into actual graphical column of
|
||||
text.&]
|
||||
text. Returns final cursor position.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:LineEdit`:`:PasteColumn`(`): [@(0.0.255) void]_[* PasteColumn]()&]
|
||||
|
|
|
|||
|
|
@ -1073,7 +1073,7 @@ bool AssistEditor::Key(dword key, int count)
|
|||
bool b = CodeEditor::Key(key, count);
|
||||
if(b && search.HasFocus())
|
||||
SetFocus();
|
||||
if(IsReadOnly())
|
||||
if(IsReadOnly() || IsRectSelection())
|
||||
return b;
|
||||
if(assist.IsOpen()) {
|
||||
bool (*test)(int c) = include_assist ? isincludefnchar : isaid;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue