mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-09-08 02:54:56 -06:00
LineEdit optimizations
git-svn-id: svn://ultimatepp.org/upp/trunk@8108 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
88daad0aa4
commit
732b03a63d
6 changed files with 127 additions and 20 deletions
|
|
@ -9,7 +9,7 @@ uses
|
|||
uses(POSIX | LINUX | FREEBSD) PdfDraw;
|
||||
|
||||
file
|
||||
CtrlLib.h options PCH,
|
||||
CtrlLib.h options(BUILDER_OPTION) PCH,
|
||||
CtrlLib readonly separator,
|
||||
LabelBase.h,
|
||||
LabelBase.cpp,
|
||||
|
|
|
|||
|
|
@ -72,6 +72,17 @@ Size LineEdit::GetFontSize() const {
|
|||
return Size(max(fi['M'], fi['W']), fi.GetHeight());
|
||||
}
|
||||
|
||||
void LineEdit::SetRectSelection(int anchor, int cursor)
|
||||
{
|
||||
dorectsel = true;
|
||||
SetSelection(anchor, cursor);
|
||||
dorectsel = false;
|
||||
}
|
||||
|
||||
void LineEdit::SetRectSelection(const Rect& rect)
|
||||
{
|
||||
SetRectSelection(GetGPos(rect.top, rect.left), GetGPos(rect.bottom, rect.right));
|
||||
}
|
||||
|
||||
Rect LineEdit::GetRectSelection() const
|
||||
{
|
||||
|
|
@ -102,6 +113,7 @@ int LineEdit::RemoveRectSelection()
|
|||
WString txt;
|
||||
for(int i = rect.top; i <= rect.bottom; i++) {
|
||||
int l, h;
|
||||
CacheLinePos(i);
|
||||
GetRectSelection(rect, i, l, h);
|
||||
WString s = GetWLine(i);
|
||||
s.Remove(l - GetPos(i), h - l);
|
||||
|
|
@ -123,6 +135,7 @@ WString LineEdit::CopyRectSelection()
|
|||
Rect rect = GetRectSelection();
|
||||
for(int i = rect.top; i <= rect.bottom; i++) {
|
||||
int l, h;
|
||||
CacheLinePos(i);
|
||||
int pos = GetPos(i);
|
||||
GetRectSelection(rect, i, l, h);
|
||||
txt.Cat(GetWLine(i).Mid(l - pos, h - l));
|
||||
|
|
@ -142,6 +155,7 @@ int LineEdit::PasteRectSelection(const WString& s)
|
|||
int n = 0;
|
||||
for(int i = 0; i < cl.GetCount() && rect.top + i <= rect.bottom; i++) {
|
||||
int l, h;
|
||||
CacheLinePos(i);
|
||||
GetRectSelection(rect, i + rect.top, l, h);
|
||||
Remove(l, h - l);
|
||||
int nn = Insert(l, cl[i]);
|
||||
|
|
@ -165,7 +179,8 @@ void LineEdit::PasteColumn(const WString& text)
|
|||
RemoveSelection();
|
||||
Point p = t.TopLeft();
|
||||
pos = cursor;
|
||||
for(int i = 0; i < t.bottom - t.top + 1; i++) {
|
||||
for(int i = 0; i < t.bottom - t.top + 1; i++) {
|
||||
CacheLinePos(i + p.y);
|
||||
int l = GetGPos(i + p.y, p.x);
|
||||
pos = l + Insert(l, cl[i % cl.GetCount()]);
|
||||
}
|
||||
|
|
@ -175,6 +190,7 @@ void LineEdit::PasteColumn(const WString& text)
|
|||
Point p = GetColumnLine(cursor);
|
||||
pos = cursor;
|
||||
for(int i = 0; i < cl.GetCount(); i++) {
|
||||
CacheLinePos(i + p.y);
|
||||
int li = p.y + i;
|
||||
if(li < line.GetCount()) {
|
||||
int l = GetGPos(i + p.y, p.x);
|
||||
|
|
@ -481,20 +497,39 @@ void LineEdit::Layout() {
|
|||
|
||||
int LineEdit::GetGPos(int ln, int cl) const {
|
||||
ln = minmax(ln, 0, line.GetCount() - 1);
|
||||
WString txt = line[ln];
|
||||
const wchar *b = txt;
|
||||
const wchar *e = txt.End();
|
||||
const wchar *s = b;
|
||||
const String& stxt = line[ln].text;
|
||||
const char *s = stxt;
|
||||
const char *e = stxt.End();
|
||||
const char *b = s;
|
||||
int gl = 0;
|
||||
int wpos = 0;
|
||||
while(s < e) {
|
||||
if(*s == '\t')
|
||||
gl = (gl + tabsize) / tabsize * tabsize;
|
||||
else
|
||||
gl += 1 + IsCJKIdeograph(*s);
|
||||
if((byte)*s < 128)
|
||||
gl++;
|
||||
else {
|
||||
WString txt = FromUtf8(s, int(e - s));
|
||||
const wchar *b = txt;
|
||||
const wchar *e = txt.End();
|
||||
const wchar *s = b;
|
||||
while(s < e) {
|
||||
if(*s == '\t')
|
||||
gl = (gl + tabsize) / tabsize * tabsize;
|
||||
else
|
||||
gl += 1 + IsCJKIdeograph(*s);
|
||||
if(cl < gl) break;
|
||||
s++;
|
||||
}
|
||||
wpos = int(s - b);
|
||||
break;
|
||||
}
|
||||
if(cl < gl) break;
|
||||
s++;
|
||||
}
|
||||
return GetPos(ln, int(s - b));
|
||||
|
||||
return GetPos(ln, int(s - b) + wpos);
|
||||
}
|
||||
|
||||
Point LineEdit::GetColumnLine(int pos) const {
|
||||
|
|
|
|||
|
|
@ -87,12 +87,21 @@ int TextCtrl::RemoveRectSelection() { return 0; }
|
|||
WString TextCtrl::CopyRectSelection() { return Null; }
|
||||
int TextCtrl::PasteRectSelection(const WString& s) { return 0; }
|
||||
|
||||
void TextCtrl::CachePos(int pos) {
|
||||
void TextCtrl::CachePos(int pos)
|
||||
{
|
||||
int p = pos;
|
||||
cline = GetLinePos(p);
|
||||
cpos = pos - p;
|
||||
}
|
||||
|
||||
void TextCtrl::CacheLinePos(int linei)
|
||||
{
|
||||
if(linei >= 0 && linei < GetLineCount()) {
|
||||
cpos = GetPos(linei);
|
||||
cline = linei;
|
||||
}
|
||||
}
|
||||
|
||||
int TextCtrl::Load(Stream& in, byte charset) {
|
||||
Clear();
|
||||
line.Clear();
|
||||
|
|
@ -381,12 +390,15 @@ int TextCtrl::GetPos(int ln, int lpos) const {
|
|||
WString TextCtrl::GetW(int pos, int size) const
|
||||
{
|
||||
int i = GetLinePos(pos);
|
||||
WString r;
|
||||
WStringBuffer r;
|
||||
for(;;) {
|
||||
if(i >= line.GetCount()) break;
|
||||
WString ln = line[i++];
|
||||
int sz = min(ln.GetLength() - pos, size);
|
||||
r.Cat(ln.Mid(pos, sz));
|
||||
if(pos == 0 && sz == ln.GetLength())
|
||||
r.Cat(ln);
|
||||
else
|
||||
r.Cat(ln.Mid(pos, sz));
|
||||
size -= sz;
|
||||
if(size == 0) break;
|
||||
#ifdef PLATFORM_WIN32
|
||||
|
|
@ -402,6 +414,29 @@ WString TextCtrl::GetW(int pos, int size) const
|
|||
|
||||
String TextCtrl::Get(int pos, int size, byte charset) const
|
||||
{
|
||||
if(charset == CHARSET_UTF8) {
|
||||
int i = GetLinePos(pos);
|
||||
StringBuffer r;
|
||||
for(;;) {
|
||||
if(i >= line.GetCount()) break;
|
||||
int sz = min(line[i].GetLength() - pos, size);
|
||||
const String& ln = line[i++].text;
|
||||
if(pos == 0 && sz == ln.GetLength())
|
||||
r.Cat(ln);
|
||||
else
|
||||
r.Cat(ln.ToWString().Mid(pos, sz).ToString());
|
||||
size -= sz;
|
||||
if(size == 0) break;
|
||||
#ifdef PLATFORM_WIN32
|
||||
r.Cat('\r');
|
||||
#endif
|
||||
r.Cat('\n');
|
||||
size--;
|
||||
if(size == 0) break;
|
||||
pos = 0;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return FromUnicode(GetW(pos, size), charset);
|
||||
}
|
||||
|
||||
|
|
@ -420,19 +455,35 @@ int TextCtrl::Insert0(int pos, const WString& txt) {
|
|||
int i = GetLinePos(pos);
|
||||
DirtyFrom(i);
|
||||
int size = 0;
|
||||
WString ln;
|
||||
|
||||
WStringBuffer lnb;
|
||||
Vector<Ln> iln;
|
||||
for(const wchar *s = txt; s < txt.End(); s++)
|
||||
if(*s >= ' ' || *s == '\t') {
|
||||
ln.Cat(*s);
|
||||
const wchar *s = txt;
|
||||
while(s < txt.End())
|
||||
if(*s >= ' ') {
|
||||
const wchar *b = s;
|
||||
while(*s >= ' ') // txt is zero teminated...
|
||||
s++;
|
||||
int sz = int(s - b);
|
||||
lnb.Cat(b, sz);
|
||||
size += sz;
|
||||
}
|
||||
else
|
||||
if(*s == '\t') {
|
||||
lnb.Cat(*s);
|
||||
size++;
|
||||
s++;
|
||||
}
|
||||
else
|
||||
if(*s == '\n') {
|
||||
iln.Add(ln);
|
||||
iln.Add(WString(lnb));
|
||||
size++;
|
||||
ln.Clear();
|
||||
lnb.Clear();
|
||||
s++;
|
||||
}
|
||||
else
|
||||
s++;
|
||||
WString ln = lnb;
|
||||
|
||||
WString l = line[i];
|
||||
if(iln.GetCount()) {
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ public:
|
|||
Callback WhenSel;
|
||||
|
||||
void CachePos(int pos);
|
||||
void CacheLinePos(int linei);
|
||||
|
||||
enum { CHARSET_UTF8_BOM = 250 };
|
||||
enum { LE_DEFAULT, LE_CRLF, LE_LF };
|
||||
|
|
@ -311,6 +312,8 @@ public:
|
|||
Point GetIndexLine(int pos) const;
|
||||
int GetIndexLinePos(Point pos) const;
|
||||
|
||||
void SetRectSelection(int l, int h);
|
||||
void SetRectSelection(const Rect& rect);
|
||||
Rect GetRectSelection() const;
|
||||
bool GetRectSelection(const Rect& rect, int line, int& l, int &h);
|
||||
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ monospace glyphs `- the width of character is constant).&]
|
|||
[s5;:LineEdit`:`:GetGPos`(int`,int`)const: [@(0.0.255) int]_[* GetGPos]([@(0.0.255) int]_[*@3 l
|
||||
n], [@(0.0.255) int]_[*@3 cl])_[@(0.0.255) const]&]
|
||||
[s2;%% Returns `"graphical`" position of [%-*@3 ln] line and [%-*@3 cl]
|
||||
column. This takes into account any tabulator characters int
|
||||
the line.&]
|
||||
column. This takes into account any tabulator characters in the
|
||||
line.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:LineEdit`:`:GetMousePos`(Point`)const: [@(0.0.255) int]_[* GetMousePos]([_^Point^ Poin
|
||||
|
|
@ -85,6 +85,17 @@ 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])&]
|
||||
[s2;%% Sets rectangular selection.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:LineEdit`:`:SetRectSelection`(const Rect`&`): [@(0.0.255) void]_[* SetRectSelection](
|
||||
[@(0.0.255) const]_[_^Rect^ Rect][@(0.0.255) `&]_[*@3 rect])&]
|
||||
[s2;%% Same as SetRectSelection(GetGPos(rect.top, rect.left), GetGPos(rect.bottom,
|
||||
rect.right));&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:LineEdit`:`:GetRectSelection`(`)const: [_^Rect^ Rect]_[* GetRectSelection]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2;%% Returns rectangular selection (as `"graphical`").&]
|
||||
|
|
|
|||
|
|
@ -109,7 +109,14 @@ from not`-modified to modified (`"dirty`") or back.&]
|
|||
[s4; &]
|
||||
[s5;:TextCtrl`:`:CachePos`(int`): [@(0.0.255) void]_[* CachePos]([@(0.0.255) int]_[*@3 pos])&]
|
||||
[s2;%% This is specific optimization hint to the widget saying that
|
||||
following operations will be performed near after [%-*@3 pos].
|
||||
following operations will be performed near [%-*@3 pos]. Unlikely
|
||||
to be used in the client code.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:TextCtrl`:`:CacheLinePos`(int`): [@(0.0.255) void]_[* CacheLinePos]([@(0.0.255) int]_[*@3 l
|
||||
inei])&]
|
||||
[s2;%% This is specific optimization hint to the widget saying that
|
||||
following operations will be performed near line [%-*@3 linei].
|
||||
Unlikely to be used in the client code.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue