strcat(string, "</a>");
}
else
- strcat(string, type._class.string);
+ strcat(string, type._class.string);
}
}
break;
DocPrintType(param, string, false, fullName);
if(param.next) strcat(string, ", ");
}
- strcat(string, ")");
+ strcat(string, ")");
}
else*/
{
DocPrintType(param, string, false, fullName);
if(param.next) strcat(string, ", ");
}
- strcat(string, ")");
+ strcat(string, ")");
}
else*/
{
case subClassType:
strcat(string, "subclass(");
strcat(string, type._class ? type._class.string : "int");
- strcat(string, ")");
+ strcat(string, ")");
break;
default:
printf("");
{
contents = new char[len+1];
file.Read(contents, 1, len);
- contents[len] = '\0';
+ contents[len] = '\0';
}
delete file;
}
for(c = 0; contents[c]; c++)
if(!isspace(contents[c])) break;
if(!contents[c])
- delete contents;
+ delete contents;
}
if(editing && !contents)
contents = CopyString($"[Add Text]");
else
f.Printf("<TD valign=top height=22>%s</TD>", desc);
delete desc;
- }
+ }
f.Printf("</TR>\n");
}
}
}
f.Printf("</FONT></BODY></HTML>\n");
- }
+ }
}
class APIPageClass : APIPage
dataClass = base.dataType._class ? base.dataType._class.registered : null;
}
else
- dataClass = base;
+ dataClass = base;
f.Printf("<TR>");
f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a><img valign=center src=\"%s\"> %s</TD>", item, iconNames[typeEnumValue], item.name);
else
f.Printf(", ");
f.Printf("<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", deriv, deriv.name);
- }
+ }
}
if(!first)
f.Printf("<br><br>\n");
}
}
f.Printf("</FONT></BODY></HTML>\n");
- }
+ }
}
class APIPageMethod : APIPage
}
}
f.Printf("</FONT></BODY></HTML>\n");
- }
+ }
}
class APIPageFunction : APIPage
}
}
f.Printf("</FONT></BODY></HTML>\n");
- }
+ }
}
static void AddNameSpace(DataRow parentRow, Module module, NameSpace mainNameSpace, NameSpace comNameSpace, char * parentName, bool showPrivate)
if(!functionsRow) { functionsRow = row.AddRow(); functionsRow.SetData(null, APIPage { $"Functions", page = page }); functionsRow.collapsed = true; functionsRow.icon = mainForm.icons[typeMethod]; functionsRow.tag = 2; };
fnRow = functionsRow.AddRow(); fnRow.SetData(null, APIPageFunction { name, function = fn }); fnRow.icon = mainForm.icons[typeMethod]; fnRow.tag = (int)fn;
}
- }
+ }
}
}
}
if(!definesRow) { definesRow = row.AddRow(); definesRow.SetData(null, APIPage { $"Definitions", page = page }); definesRow.collapsed = true; definesRow.icon = mainForm.icons[typeData]; definesRow.tag = 3; };
defRow = definesRow.AddRow(); defRow.SetData(null, APIPage { name, page = page }); defRow.icon = mainForm.icons[typeData]; defRow.tag = (int)def;
}
- }
+ }
}
}
}
NamedLink item;
for(item = enumeration.values.first; item; item = item.next)
{
- DataRow mRow;
+ DataRow mRow;
if(!enumRow) { enumRow = row.AddRow(); enumRow.SetData(null, APIPage { $"Enumeration Values", page = page }); enumRow.collapsed = true; enumRow.icon = mainForm.icons[typeEnumValue]; enumRow.tag = 8; }
- mRow = enumRow.AddRow(); mRow.SetData(null, APIPage { item.name, page = page }); mRow.icon = mainForm.icons[typeEnumValue];
+ mRow = enumRow.AddRow(); mRow.SetData(null, APIPage { item.name, page = page }); mRow.icon = mainForm.icons[typeEnumValue];
mRow.tag = (int)item;
}
}
parent.subBlocks.Add(textBlock);
}
- edit = false;
+ edit = false;
if(created)
{
ComputeMinSizes();
bool OnLeftButtonDown(int x, int y, Modifiers mods)
{
- if(edit)
- {
- // Update overLink
- HTMLView::OnMouseMove(x, y, mods);
- if(textBlock && overLink == textBlock.parent)
- {
- selPosition = curPosition = TextPosFromPoint(x, y, &textBlock);
- PositionCaret(true);
- }
- else
- {
- SaveEdit();
- HTMLView::OnLeftButtonDown(x, y, mods);
- }
- return true;
- }
- return HTMLView::OnLeftButtonDown(x, y, mods);
- }
+ bool result = true;
- bool OnLeftButtonUp(int x, int y, Modifiers mods)
- {
- if(!edit || !textBlock || clickedLink != textBlock.parent)
+ if(edit && (!textBlock || overLink != textBlock.parent))
{
- HTMLView::OnLeftButtonUp(x, y, mods);
- if(edit)
- {
- selPosition = curPosition = TextPosFromPoint(x, y, &textBlock);
- PositionCaret(true);
- }
- }
- return true;
- }
-
- // Returns true if it needs scrolling
- /*
- bool FindMouse(int px, int py, int * tx, int * ty, EditLine * tline, bool half)
- {
- int w;
- int c;
- int x, y;
- EditLine line;
- bool needHScroll = false;
-
- if(py < 0)
- {
- if(this.viewY > 0)
- {
- y = this.viewY-1;
- line = this.viewLine ? (void *)this.viewLine.prev : null;
- }
- else
- {
- y = 0;
- line = (void *)this.lines.first;
- }
+ SaveEdit();
+ HTMLView::OnLeftButtonDown(x, y, mods);
+ selPosition = curPosition = 0;
+ selBlock = textBlock;
+ Update(null);
}
else
- {
- py = Min(py, clientSize.h);
- py /= this.space.h;
- py = Min(py, this.lineCount);
- y = this.viewY;
- for(c = 0, line = this.viewLine; (line != (void *)this.lines.last && c<py); line = line.next, c++)
- {
- y++;
- }
- }
-
- if( (px >= clientSize.w || px < clientSize.w/2) && this.viewX)
- needHScroll = true;
- px = Max(px,0);
- px = Min(px,clientSize.w+this.space.w);
+ result = HTMLView::OnLeftButtonDown(x, y, mods);
- if(tx && line)
+ if(!edit && clickedLink)
{
- *tx = AdjustXPosition(line, px + viewX, half, null, MAXINT, 0);
- }
-
- if(tline) *tline = line;
- if(ty) *ty = y;
-
- // Prevent divide by 0 from non valid this.font
- if(!this.space.h)
- return (y < this.viewY) || needHScroll;
- else
- return (y < this.viewY || y >= this.viewY + clientSize.h / this.space.h) || needHScroll;
- return false;
- }
-*/
-/*
- bool OnLeftButtonDown(int mx, int my, Modifiers mods)
- {
- int x,y;
- EditLine line;
-
- if(style.noSelect) return true;
-
- if(!mods.isActivate)
- {
- Capture();
- mouseSelect = true;
- }
-
- mouseX = mx - XOFFSET;
- mouseY = my;
-
- FindMouse(mouseX, mouseY, &x, &y, &line, true);
-
- if(!style.readOnly)
- {
- if(wordSelect)
- mouseMove = false;
- else if(IsMouseOnSelection() && !mods.isActivate)
+ ReleaseCapture();
+ if(clickedLink == overLink && clickedLink.href)
{
- DirtyLine(this.y);
- mouseMove = true;
- dropX = x;
- dropY = y;
- dropLine = line;
+ if(OnOpen(clickedLink.href))
+ Update(null);
}
}
- if(!mouseMove && !wordSelect && (!mods.isActivate || style.multiLine))
+ if(edit)
{
- if(mods.shift && !mods.isActivate)
- {
- this.x = x;
- this.y = y;
- this.line = line;
- DirtyAll();
- }
- else
+ // Update overLink
+ if(textBlock && overLink == textBlock.parent)
{
- SelDirty();
- DirtyLine(this.y);
- this.x = x;
- this.y = y;
- this.line = line;
- DirtyLine(this.y);
- this.selLine = this.line;
- this.selX = this.x;
- this.selY = this.y;
- //Deselect();
+ selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
+ selBlock = textBlock;
+ PositionCaret(true);
+ selecting = true;
+ Update(null);
}
- ComputeColumn();
}
-
- UpdateDirty();
- UpdateCaretPosition(true);
- return true;
+ return result;
}
-*/
-/*
+
bool OnLeftButtonUp(int x, int y, Modifiers mods)
{
- timer.Stop();
-
- mouseSelect = false;
- wordSelect = false;
-
- x -= XOFFSET;
-
- ReleaseCapture();
- if(!style.readOnly)
+ if(!edit || !textBlock || clickedLink != textBlock.parent)
{
- if(mouseMove)
- {
- EditLine line;
- FindMouse(mouseX, mouseY, &x, &y, &line, true);
-
- dropX = x;
- dropY = y;
- dropLine = line;
-
- mouseMove = IsMouseOnSelection();
-
- if(!mouseMove)
- {
- int size = SelSize();
- if(size)
- {
- char * text = new char[size+1];
- if(text)
- {
- int moveX = 0;
- GetSel(text, false);
-
- if(Max(selY, this.y) == dropY)
- {
- if(this.x > selX)
- {
- if(this.dropX > this.selX)
- moveX = this.x - this.selX;
- }
- else
- {
- if(this.dropX > this.x)
- moveX = this.selX - this.x;
- }
- }
- DelSel(null);
- this.dropX -= moveX;
- this.selX = this.x = this.dropX;
- this.selY = this.y = this.dropY;
- this.selLine = this.line = this.dropLine;
- AddS(text);
- SetViewToCursor(true);
- delete text;
- Modified();
- }
- }
- }
- else
- {
- SelDirty();
- DirtyLine(this.y);
- this.x = x;
- this.y = y;
- this.line = line;
- ComputeColumn();
- DirtyLine(this.y);
- Deselect();
- UpdateDirty();
- }
- }
- else
+ HTMLView::OnLeftButtonUp(x, y, mods);
+ if(edit)
{
- EditLine line;
- mouseX = x;
- mouseY = y;
-
- FindMouse(mouseX, mouseY, &x, &y, &line, true);
-
- NotifyDropped(master, this, x, y);
+ selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
+ selBlock = textBlock;
+ PositionCaret(true);
+ Update(null);
}
}
- mouseMove = false;
+ else
+ ReleaseCapture();
+ selecting = false;
return true;
}
+ bool selecting;
- bool OnMouseMove(int mx, int my, Modifiers mods)
+ bool OnMouseMove(int x, int y, Modifiers mods)
{
- int x,y;
- EditLine line;
- bool needScroll;
-
- if(mods != -1 && mods.isSideEffect)
- {
- SetSelectCursor();
- return true;
- }
- if(style.noSelect) return true;
- if(wordSelect) return true;
- mouseX = mx - XOFFSET;
- mouseY = my;
-
- needScroll = FindMouse(this.mouseX, this.mouseY, &x, &y, &line, true);
-
- if(this.mouseMove || this.mouseSelect)
+ if(edit && selecting)
{
- if(!needScroll)
- timer.Stop();
- else
- {
- if(needScroll)
- timer.Start();
- if(mods != -1 &&
- ((style.hScroll) || (style.vScroll)))
- return true;
- }
- }
-
- if(this.mouseMove)
- {
- DirtyLine(this.dropY);
- this.dropX = x;
- this.dropY = y;
- DirtyLine(this.dropY);
- this.dropLine = line;
- SetViewToCursor(true);
- }
- else if(this.mouseSelect)
- {
- DirtyLine(this.selY);
- DirtyLine(this.y);
- this.x = x;
- this.y = y;
- ComputeColumn();
- DirtyLine(this.y);
- this.line = line;
- SetViewToCursor(true);
- UpdateDirty();
+ curPosition = TextPosFromPoint(x, y, &textBlock, true);
+ PositionCaret(true);
+ Update(null);
}
- SetSelectCursor();
- return true;
+ return HTMLView::OnMouseMove(x, y, mods);
}
bool OnLeftDoubleClick(int mx, int my, Modifiers mods)
{
- int x,y;
- EditLine line;
-
- mx -= XOFFSET;
-
- if(style.noSelect) return true;
- FindMouse(mx, my, &x, &y, &line, false);
- if(!NotifyDoubleClick(master, this, line, mods))
- return false;
- if(x < line.count)
+ if(edit && textBlock)
{
int c;
int start = -1;
int numBytes;
- for(c = x; c >= 0; c--)
+
+ selPosition = curPosition = TextPosFromPoint(mx, my, &textBlock, false);
+ selBlock = textBlock;
+ for(c = curPosition; c >= 0; c--)
{
unichar ch;
- while(c > 0 && !UTF8_IS_FIRST(line.buffer[c])) c--;
- ch = UTF8_GET_CHAR(line.buffer + c, numBytes);
- if(!IS_ALUNDER(ch))
+ while(c > 0 && !UTF8_IS_FIRST(textBlock.text[c])) c--;
+ ch = UTF8GetChar(textBlock.text + c, &numBytes);
+ if(!CharMatchCategories(ch, letters|numbers|marks|connector))
break;
start = c;
}
if(start != -1)
{
- for(c = start; c<line.count; c += numBytes)
+ for(c = start; c < textBlock.textLen; c += numBytes)
{
- unichar ch = UTF8_GET_CHAR(line.buffer + c, numBytes);
- if(!IS_ALUNDER(ch))
+ unichar ch = UTF8GetChar(textBlock.text + c, &numBytes);
+ if(!CharMatchCategories(ch, letters|numbers|marks|connector))
break;
}
- SelDirty();
- DirtyLine(this.y);
- this.y = y;
- DirtyLine(this.y);
- this.selX = start;
- this.x = c;
- ComputeColumn();
- this.line = this.selLine = line;
- this.wordSelect = (c != start);
- UpdateDirty();
+ selPosition = start;
+ curPosition = c;
+
+ PositionCaret(true);
+ Update(null);
+ return false;
}
}
return true;
}
-*/
+
bool OnOpen(char * href)
{
if(!strncmp(href, "api://", 6))
else
{
block.parent.subBlocks.Insert(block, newBlock);
- startY += th;
- }
+ startY += block.prev.height;
+ }
newBlock.startX = startX;
newBlock.startY = startY;
newBlock.text = new0 char[1];
if(!strcmp(textBlock.text, $"[Add Text]"))
{
textBlock.text[0] = 0;
- textBlock.textLen = 0;
+ textBlock.textLen = 0;
}
strcpy(editString, href + 7);
selPosition = curPosition = 0;
+ selBlock = textBlock;
// dialog.Create();
edit = true;
- PositionCaret(true);
+ // PositionCaret(true);
}
return true;
}
- Block textBlock;
char * text;
- int curPosition, selPosition;
+
+ void DeleteSelection()
+ {
+ if(textBlock != selBlock || curPosition != selPosition)
+ {
+ if(textBlock == selBlock)
+ {
+ // Within same block
+ int start = Min(curPosition, selPosition);
+ int end = Max(curPosition, selPosition);
+ memmove(textBlock.text + start, textBlock.text + end, textBlock.textLen - end);
+ textBlock.textLen -= end-start;
+ textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
+ curPosition = start;
+ selPosition = start;
+ }
+ else
+ {
+ int startSel, endSel;
+ Block startSelBlock = null, endSelBlock = null, b, next;
+
+ NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
+
+ startSelBlock.text = renew startSelBlock.text char[startSel + endSelBlock.textLen - endSel + 1];
+ memcpy(startSelBlock.text + startSel, endSelBlock.text + endSel, endSelBlock.textLen - endSel + 1);
+
+ startSelBlock.textLen = startSel + endSelBlock.textLen - endSel;
+ for(b = startSelBlock.next; b; b = next)
+ {
+ bool isEnd = b == endSelBlock;
+ next = GetNextBlock(b);
+ b.parent.subBlocks.Remove(b);
+ delete b;
+ if(isEnd)
+ break;
+ }
+ textBlock = startSelBlock;
+ selBlock = startSelBlock;
+ curPosition = startSel;
+ selPosition = startSel;
+ }
+ ComputeMinSizes();
+ ComputeSizes();
+ PositionCaret(true);
+ Update(null);
+ }
+ }
+
+ String GetSelectionString()
+ {
+ String selection = null;
+ if(textBlock == selBlock)
+ {
+ // Within same block
+ int start = Min(curPosition, selPosition);
+ int end = Max(curPosition, selPosition);
+ int len = end - start;
+ selection = new char[len + 1];
+ memcpy(selection, textBlock.text + start, len);
+ selection[len] = 0;
+ }
+ else
+ {
+ int startSel, endSel;
+ Block startSelBlock = null, endSelBlock = null, b;
+ int totalLen = 0;
+
+ NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
+
+ // Compute length
+ for(b = startSelBlock; b; b = GetNextBlock(b))
+ {
+ int start = (b == startSelBlock) ? startSel : 0;
+ int end = (b == endSelBlock) ? endSel : b.textLen;
+ int len = end - start;
+ totalLen += len;
+ if(b == endSelBlock)
+ break;
+ else if(b.type == TEXT)
+ totalLen++;
+ }
+
+ selection = new char[totalLen + 1];
+ totalLen = 0;
+ for(b = startSelBlock; b; b = GetNextBlock(b))
+ {
+ int start = (b == startSelBlock) ? startSel : 0;
+ int end = (b == endSelBlock) ? endSel : b.textLen;
+ int len = end - start;
+ memcpy(selection + totalLen, b.text + start, len);
+ totalLen += len;
+ if(b == endSelBlock)
+ break;
+ else if(b.type == TEXT)
+ selection[totalLen++] = '\n';
+ }
+ selection[totalLen] = 0;
+ }
+ return selection;
+ }
+
+ void CopySelection()
+ {
+ String s = GetSelectionString();
+ if(s)
+ {
+ int len = strlen(s);
+ ClipBoard cb { };
+ if(cb.Allocate(len + 1))
+ {
+ memcpy(cb.text, s, len + 1);
+ cb.Save();
+ }
+ delete cb;
+ delete s;
+ }
+ }
bool OnKeyDown(Key key, unichar ch)
{
case escape:
OnLeftButtonDown(0,0,0);
return false;
+ case Key { end, shift = true }:
case end:
- selPosition = curPosition = textBlock.textLen;
+ curPosition = textBlock.textLen;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
PositionCaret(true);
Update(null);
break;
+ case Key { home, shift = true }:
case home:
- selPosition = curPosition = 0;
+ curPosition = 0;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
PositionCaret(true);
Update(null);
break;
+ case Key { home, ctrl = true, shift = true }:
case ctrlHome:
- selPosition = curPosition = 0;
+ curPosition = 0;
while(textBlock.prev)
textBlock = textBlock.prev.prev;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
PositionCaret(true);
Update(null);
return false;
+ case Key { end, ctrl = true, shift = true }:
case ctrlEnd:
while(textBlock.next && textBlock.next.next)
textBlock = textBlock.next.next;
- selPosition = curPosition = textBlock.textLen;
+ curPosition = textBlock.textLen;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
PositionCaret(true);
Update(null);
return false;
return HTMLView::OnKeyDown(key, ch);
return true;
}
+
bool OnKeyHit(Key key, unichar ch)
{
if(edit)
{
switch(key)
{
+ case Key { up, shift = true }:
case up:
{
if(caretY == textBlock.startY)
if(textBlock.prev)
{
textBlock = textBlock.prev.prev;
- selPosition = curPosition = Min(curPosition, textBlock.textLen);
+ curPosition = Min(curPosition, textBlock.textLen);
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
+ Update(null);
PositionCaret(false);
caretY = MAXINT;
}
len = curPosition - startPos;
display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
}
- selPosition = curPosition;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
+ Update(null);
+
PositionCaret(false);
return false;
}
{
int c = textPos - 1;
while(c > 0 && text[c] == ' ') c--;
- selPosition = curPosition = c + 1;
+ curPosition = c + 1;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
+ Update(null);
}
else
- selPosition = curPosition = textBlock.textLen;
+ {
+ curPosition = textBlock.textLen;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
+ Update(null);
+ }
PositionCaret(false);
return false;
}
}
return false;
}
+ case Key { down, shift = true }:
case down:
{
int tw = 0, th = 0;
len = curPosition - startPos;
display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
}
- selPosition = curPosition;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
+ Update(null);
PositionCaret(false);
return false;
}
}
if(sy > caretY)
{
- selPosition = curPosition = textBlock.textLen;
+ curPosition = textBlock.textLen;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
+ Update(null);
PositionCaret(false);
return false;
}
{
textBlock = textBlock.next.next;
selPosition = curPosition = Min(curPosition, textBlock.textLen);
+ selBlock = textBlock;
PositionCaret(false);
}*/
break;
}
- #define IS_ALUNDER(ch) ((ch) == '_' || isalnum((ch)))
+ case Key { right, shift = true, ctrl = true }:
case ctrlRight:
{
- // SELECTION CTRL-RIGHT
- /*
bool foundAlpha = false;
bool found = false;
Block line, lastLine;
int c;
for(c = start; c < line.textLen; c++)
{
- if(IS_ALUNDER(line.text[c]))
+ char ch = line.text[c];
+ bool isAlUnder = CharMatchCategories(ch, letters|numbers|marks|connector);
+ if(key.shift ? isAlUnder : !isAlUnder)
{
foundAlpha = true;
lastC = c;
else if(foundAlpha)
{
found = true;
+ if(!key.shift)
+ {
+ curPosition = c;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
+ Update(null);
+ textBlock = line;
+ PositionCaret(true);
+ }
break;
}
}
+ // No next word found,
if(!found && (c != curPosition || line != textBlock))
{
found = true;
lastLine = line;
lastC = line.textLen-1;
- break;
- }
- }
- if(found)
- {
- selPosition = curPosition = lastC+1;
- textBlock = lastLine;
- PositionCaret(true);
- }
- */
-
- bool foundAlpha = false;
- bool found = false;
- Block line;
-
- for(line = textBlock; (line && !found); line = line.next ? line.next.next : null)
- {
- int start = (line == textBlock) ? curPosition : 0;
- int c;
- for(c = start; c < line.textLen; c++)
- {
- if(!IS_ALUNDER(line.text[c]))
- foundAlpha = true;
- else if(foundAlpha)
+ if(key.shift)
+ break;
+ else
{
- found = true;
- selPosition = curPosition = c;
+ curPosition = line.textLen;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
+ Update(null);
+
textBlock = line;
PositionCaret(true);
- break;
}
}
- // No next word found,
- if(!found && (c != curPosition || line != textBlock))
- {
- found = true;
- selPosition = curPosition = line.textLen;
- textBlock = line;
- PositionCaret(true);
- }
- foundAlpha = true;
+ if(!key.shift)
+ foundAlpha = true;
+ }
+ if(key.shift && found)
+ {
+ curPosition = lastC+1;
+ textBlock = lastLine;
+ PositionCaret(true);
+ Update(null);
}
break;
}
+ case Key { left, ctrl = true, shift = true }:
case ctrlLeft:
{
bool foundAlpha = false;
if(line == textBlock) start = curPosition-1; else start = line.textLen-1;
for(c = start; c>=0; c--)
{
- if(IS_ALUNDER(line.text[c]))
+ if(CharMatchCategories(line.text[c], letters|numbers|marks|connector))
{
foundAlpha = true;
lastC = c;
if(foundAlpha)
{
textBlock = lastLine;
- selPosition = curPosition = lastC;
+ curPosition = lastC;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
PositionCaret(true);
+ Update(null);
}
break;
}
+ case Key { right, shift = true }:
case right:
if(curPosition < textBlock.textLen)
{
curPosition += UTF8_NUM_BYTES(textBlock.text[curPosition]);
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
PositionCaret(true);
- selPosition = curPosition;
+ Update(null);
}
else if(textBlock.next && textBlock.next.next)
{
textBlock = textBlock.next.next;
- selPosition = curPosition = 0;
+ curPosition = 0;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
PositionCaret(true);
+ Update(null);
}
break;
+ case Key { left, shift = true }:
case left:
if(curPosition > 0)
{
while(curPosition > 0 && !UTF8_IS_FIRST(textBlock.text[--curPosition]));
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
PositionCaret(true);
- selPosition = curPosition;
+ Update(null);
}
else if(textBlock.prev)
{
textBlock = textBlock.prev.prev;
- selPosition = curPosition = textBlock.textLen;
+ curPosition = textBlock.textLen;
+ if(!key.shift)
+ {
+ selPosition = curPosition;
+ selBlock = textBlock;
+ }
PositionCaret(true);
+ Update(null);
}
break;
case backSpace:
- if(curPosition)
+ if(textBlock == selBlock && curPosition == selPosition)
{
- int c = curPosition;
- int nb = 1;
- while(c > 0 && !UTF8_IS_FIRST(textBlock.text[--c])) nb++;
- memmove(textBlock.text + curPosition - nb, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
- textBlock.textLen -= nb;
- textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
- curPosition -= nb;
- selPosition = curPosition;
+ if(curPosition)
{
- //Clear(html.block);
- //CreateForms(html.block);
+ int c = curPosition;
+ int nb = 1;
+ while(c > 0 && !UTF8_IS_FIRST(textBlock.text[--c])) nb++;
+ memmove(textBlock.text + curPosition - nb, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
+ textBlock.textLen -= nb;
+ textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
+ curPosition -= nb;
+ selPosition = curPosition;
+ selBlock = textBlock;
+
ComputeMinSizes();
ComputeSizes();
- //PositionForms();
+ PositionCaret(true);
+ Update(null);
}
- PositionCaret(true);
- Update(null);
- }
- else if(textBlock.prev)
- {
- Block prev = textBlock.prev, prevBlock = textBlock.prev.prev;
- prevBlock.text = renew prevBlock.text char[prevBlock.textLen + textBlock.textLen + 1];
- memcpy(prevBlock.text + prevBlock.textLen, textBlock.text, textBlock.textLen + 1);
-
- selPosition = curPosition = prevBlock.textLen;
- prevBlock.textLen += textBlock.textLen;
- textBlock.parent.subBlocks.Remove(prev);
- delete prev;
- textBlock.parent.subBlocks.Remove(textBlock);
- delete textBlock;
- textBlock = prevBlock;
-
+ else if(textBlock.prev)
{
- //Clear(html.block);
- //CreateForms(html.block);
+ Block prev = textBlock.prev, prevBlock = textBlock.prev.prev;
+ prevBlock.text = renew prevBlock.text char[prevBlock.textLen + textBlock.textLen + 1];
+ memcpy(prevBlock.text + prevBlock.textLen, textBlock.text, textBlock.textLen + 1);
+
+ selPosition = curPosition = prevBlock.textLen;
+ selBlock = textBlock;
+ prevBlock.textLen += textBlock.textLen;
+ textBlock.parent.subBlocks.Remove(prev);
+ if(prev == selBlock)
+ {
+ selBlock = textBlock;
+ selPosition = curPosition;
+ }
+ delete prev;
+ textBlock.parent.subBlocks.Remove(textBlock);
+ if(textBlock == selBlock)
+ {
+ selBlock = prevBlock;
+ selPosition = curPosition;
+ }
+ delete textBlock;
+ textBlock = prevBlock;
+
ComputeMinSizes();
ComputeSizes();
- //PositionForms();
+ PositionCaret(true);
+ Update(null);
}
- PositionCaret(true);
- Update(null);
}
+ else
+ DeleteSelection();
break;
case del:
- if(textBlock.textLen > curPosition)
+ if(textBlock != selBlock || curPosition != selPosition)
+ DeleteSelection();
+ else if(textBlock.textLen > curPosition)
{
int nb = UTF8_NUM_BYTES(textBlock.text[curPosition]);
memmove(textBlock.text + curPosition, textBlock.text + curPosition + nb, textBlock.textLen - curPosition + 1 - nb + 1);
textBlock.textLen -= nb;
textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
- {
- //Clear(html.block);
- //CreateForms(html.block);
- ComputeMinSizes();
- ComputeSizes();
- //PositionForms();
- }
+
+ ComputeMinSizes();
+ ComputeSizes();
+
PositionCaret(true);
Update(null);
}
textBlock.textLen += nextBlock.textLen;
textBlock.parent.subBlocks.Remove(next);
+ if(next == selBlock)
+ {
+ selBlock = textBlock;
+ selPosition = curPosition;
+ }
delete next;
- textBlock.parent.subBlocks.Remove(nextBlock);
- delete nextBlock;
-
+ textBlock.parent.subBlocks.Remove(nextBlock);
+ if(nextBlock == selBlock)
{
- //Clear(html.block);
- //CreateForms(html.block);
- ComputeMinSizes();
- ComputeSizes();
- //PositionForms();
+ selBlock = textBlock;
+ selPosition = curPosition;
}
+ delete nextBlock;
+
+ ComputeMinSizes();
+ ComputeSizes();
PositionCaret(true);
Update(null);
}
break;
case enter:
{
- Block block { type = BR, parent = textBlock.parent, font = textBlock.font };
- Block newBlock { type = TEXT, parent = textBlock.parent, font = textBlock.font };
- int startY = textBlock.startY, startX = textBlock.startX;
int tw = 0, th = 0;
+ Block block;
+ Block newBlock;
+ int startY, startX;
+
+ DeleteSelection();
+
+ block = { type = BR, parent = textBlock.parent, font = textBlock.font };
+ newBlock = { type = TEXT, parent = textBlock.parent, font = textBlock.font };
+ startY = textBlock.startY;
+ startX = textBlock.startX;
display.FontExtent(textBlock.font.font, " ", 1, null, &th);
textBlock.parent.subBlocks.Insert(textBlock, block);
newBlock.startY = startY;
newBlock.startX = startX;
selPosition = curPosition = 0;
- {
- //Clear(html.block);
- //CreateForms(html.block);
- ComputeMinSizes();
- ComputeSizes();
- //PositionForms();
- }
+
+ ComputeMinSizes();
+ ComputeSizes();
+
textBlock = newBlock;
+ selBlock = textBlock;
PositionCaret(true);
Update(null);
break;
}
+ case ctrlX:
+ case Key { del, shift = true }:
+ // Cut
+ CopySelection();
+ DeleteSelection();
+ break;
+ case ctrlC:
+ case ctrlInsert:
+ // Copy
+ CopySelection();
+ break;
case shiftInsert:
case ctrlV:
{
char * text = clipBoard.memory;
char ch;
int start = 0;
- Block parent = textBlock.parent;
- FontEntry font = textBlock.font;
+ Block parent;
+ FontEntry font;
+
+ DeleteSelection();
+
+ parent = textBlock.parent;
+ font = textBlock.font;
+
for(c = 0; ; c++)
{
ch = text[c];
textBlock.textLen += len;
curPosition += len;
selPosition = curPosition;
+ selBlock = textBlock;
if(!ch) break;
{
Block block { type = BR, parent = parent, font = font };
newBlock.startY = startY;
newBlock.startX = startX;
selPosition = curPosition = 0;
+ selBlock = textBlock;
textBlock = newBlock;
}
if(ch == '\r' && text[c+1] == '\n') c++;
int len = UTF32toUTF8Len(&ch, 1, string, 5);
int c;
+ DeleteSelection();
+
textBlock.text = renew textBlock.text char[textBlock.textLen + len + 1];
memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
curPosition++;
}
selPosition = curPosition;
+ selBlock = textBlock;
{
//Clear(html.block);
int len = curPosition - startPos;
display.FontExtent(textBlock.font.font, text + startPos, len, &tw, null);
sx += tw;
- break;
+ break;
}
sy += th;
sx = textBlock.startX;
else if(sy - scroll.y < 0)
{
scrollPos.y = sy;
- doScroll = true;
+ doScroll = true;
}
if(sx - scroll.x + 10 > clientSize.w)
{
else if(sx - scroll.x < 10)
{
scrollPos.x = sx - 10;
- doScroll = true;
+ doScroll = true;
}
if(doScroll)
scroll = scrollPos;
}
// Returns a character offset into the TextBlock from a window coordinate
- int TextPosFromPoint(int px, int py, Block * block)
+ int TextPosFromPoint(int px, int py, Block * block, bool half)
{
Block parentBlock = this.textBlock.parent;
Block textBlock;
{
numBytes = UTF8_NUM_BYTES(ch);
display.FontExtent(textBlock.font.font, text + c, numBytes, &w, &th);
- if(/*py >= sy && */py < sy + th && /*px >= sx-w/2-space && */px < sx + w -w/2-space)
+ if(/*py >= sy && */py < sy + th && /*px >= sx-w/2-space && */px < sx + (half ? w/2 : w) -space)
break;
sx += w;
}