void Editor::addLogMessage(char const* text, uint64 timestamp, uint32 type) { int len = getTextLength(); POINT ptCaret = toPoint(caret); POINT ptSelStart = toPoint(selStart); if (lines.length() == 1 && lines[0].timestamp == 0) lines.pop(); else if (lines.length() > 1024) { lines.remove(0, 1); ptCaret.y--; ptSelStart.y--; } int pos = 0; while (true) { if (text[pos] == '\r' || text[pos] == '\n' || text[pos] == 0) { Line& ln = lines.push(); ln.text = WideString(text, pos); for (int i = 0; i < ln.text.length(); i++) if (ln.text[i] == '\t') ln.text.replace(i, 1, WideString(" ") * (settings->tabSize - (i % settings->tabSize))); ln.ctx = type; ln.timestamp = timestamp; if (text[pos] == 0) break; pos++; if ((text[pos] == '\r' || text[pos] == '\n') && text[pos - 1] != text[pos]) pos++; text += pos; pos = 0; } else pos++; } if (selStart == caret && caret == len) selStart = caret = getTextLength(); else { caret = fromPoint(ptCaret); selStart = fromPoint(ptSelStart); } updateExtent(); updateCaret(); }
void Editor::setCursor(int line, int col) { POINT pt; pt.x = col; pt.y = line; selStart = caret = fromPoint(pt); updateCaret(); }
int Editor::toolHitTest(POINT pt, ToolInfo* ti) { if (!running || running->getDebugLevel() < 0) return -1; pt.x = (pt.x + chSize.cx / 2 - LeftMargin()) / chSize.cx + scrollPos.x; pt.y = pt.y / chSize.cy + scrollPos.y; fixPoint(pt); int offset = fromPoint(pt); int sela = (selStart < caret ? selStart : caret); int selb = (selStart > caret ? selStart : caret); if (offset < sela || offset >= selb) { int ptStart = wordEnd(lines[pt.y].text.c_str(), pt.x, -1); int ptEnd = wordEnd(lines[pt.y].text.c_str(), pt.x, 1); int offset = fromPoint(pt); sela = offset - (pt.x - ptStart); selb = offset + (ptEnd - pt.x); } int index = -1; if (offset >= sela && offset < selb) { String text(substring(sela, selb)); lua_State* L = running->getEngine()->lock(); int res = luae::getvalue(L, running->getDebugLevel(), text); if (res != luae::eFail && !lua_isnil(L, -1)) { ti->text = luae::towstring(L, -1, true); lua_pop(L, 1); POINT pta = toPoint(sela); POINT ptb = toPoint(selb); int x0 = (pta.y == pt.y ? pta.x : 0); int x1 = (ptb.y == pt.y ? ptb.x : lines[pt.y].text.length()); ti->rc.top = (pt.y - scrollPos.y) * chSize.cy; ti->rc.bottom = (pt.y + 1 - scrollPos.y) * chSize.cy; ti->rc.left = (x0 - scrollPos.x) * chSize.cx + LeftMargin(); ti->rc.right = (x1 - scrollPos.x) * chSize.cx + LeftMargin(); index = sela; } else if (res != luae::eFail) lua_pop(L, 1); running->getEngine()->unlock(); } return index; }
void Editor::selectLine(int line) { if (line < 0 || line >= lines.length()) return; POINT pt; pt.x = 0; pt.y = line; selStart = fromPoint(pt); caret = selStart + lines[line].text.length(); updateCaret(); }
void MarkCorPatch(const Mat &src, Mat &dst, int patch_radius, NymphOffset off, std::vector<NymphPoint> ¢ers) { src.copyTo(dst); Mat flags(src.rows, src.cols, CV_8UC1, Scalar::all(0)); for (auto& pt : centers) { pt.row += off.row; pt.col += off.col; flags.at<uchar>(pt.row, pt.col) = 1; } int patch_size = patch_radius * 2 + 1; int dirmap[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} }; int linemap[3][2] = { // {from, to} {-1, -1}, {-1, 1}, {1, 1} }; for (auto& pt : centers) { for (int i = 0; i < 4; ++i) { int tmp_row = pt.row + dirmap[i][0] * patch_size, tmp_col = pt.col + dirmap[i][1] * patch_size; if (tmp_row < 0 || tmp_row >= flags.rows || tmp_col < 0 || tmp_col >= flags.cols || flags.at<uchar>(tmp_row, tmp_col) == 0) { Point fromPoint( pt.col + linemap[dirmap[i][1] + 1][0] * patch_radius, pt.row + linemap[dirmap[i][0] + 1][0] * patch_radius ); Point toPoint( pt.col + linemap[dirmap[i][1] + 1][1] * patch_radius, pt.row + linemap[dirmap[i][0] + 1][1] * patch_radius ); line(dst, fromPoint, toPoint, Scalar(0, 0, 255), 2); } } } }
void Editor::toggleBreakpoint(int y) { if (lines[y].breakpoint >= 0) lines[y].breakpoint = 1 - lines[y].breakpoint; else if (!running) lines[y].breakpoint = 1; else { while (y < lines.length() && lines[y].breakpoint < 0) y++; if (y >= lines.length()) return; lines[y].breakpoint = 1; POINT ncp; ncp.x = 0; ncp.y = y; selStart = caret = fromPoint(ncp); placeCaret(); } getParent()->notify(EN_SETBREAKPOINT, y, (uint32) this); invalidate(); }
/*! Returns the minimum distance from this ray to \a point, or equivalently the length of a line perpendicular to this ray which passes through \a point. If \a point is on the ray, then this function will return zero. \sa point() */ qreal QRay3D::distanceTo(const QVector3D &point) const { qreal t = fromPoint(point); return (point - (m_origin + t * m_direction)).length(); }
void CCxImageCtrl::OnLButtonUp(UINT nFlags, CPoint point) { CPoint imagePoint(point); ClientToImage(imagePoint); if(m_bCaptureWasSet&&m_hImage.IsInside(imagePoint.x,imagePoint.y)) { CPoint lefttop(m_RefPoint), rightbottom(point); ClientToImage(lefttop); ClientToImage(rightbottom); switch(GetState()) { case CCxImageCtrl::IS_Move: SetCursor(AfxGetApp()->LoadCursor(IDC_HANDCATCHCURSOR1)); break; case CCxImageCtrl::IS_Crop: SaveImageToUndo(); m_hImage.Crop(CRect(lefttop,rightbottom)); // [Tue 7/6/2004] //m_bCurrentImageWasSave = false; m_bIsSaved = false; Refresh(); break; case CCxImageCtrl::IS_TextMove: case CCxImageCtrl::IS_Text: m_bIsSaved = false; break; case CCxImageCtrl::IS_Pen: CPoint fromPoint(m_RefPoint), toPoint(point); ClientToImage(fromPoint); ClientToImage(toPoint); m_hImage.DrawLine(fromPoint.x, toPoint.x, m_hImage.GetHeight()-fromPoint.y,m_hImage.GetHeight()-toPoint.y,GetPenColor()); // [Tue 7/6/2004] //m_bCurrentImageWasSave = false; m_bIsSaved = false; break; } } if(m_bCaptureWasSet) { ReleaseCapture(); Invalidate(FALSE); m_bCaptureWasSet = FALSE; } CWnd::OnLButtonUp(nFlags, point); }
void CCxImageCtrl::OnMouseMove(UINT nFlags, CPoint point) { CPoint imagePoint(point); ClientToImage(imagePoint); CRect clientRect; GetClientRect(&clientRect); if(m_hImage.IsInside(imagePoint.x,imagePoint.y) || (GetState()==CCxImageCtrl::IS_TextMove && m_bCaptureWasSet)) { switch(GetState()) { case CCxImageCtrl::IS_Move: if(m_bCaptureWasSet) { SCROLLINFO si = {0}; if(m_dwWidth>clientRect.Width()) { GetScrollInfo(SB_HORZ,&si); m_nHScrollPos = m_RefScroll.cx - point.x + m_RefPoint.x; if(m_nHScrollPos<si.nMin) m_nHScrollPos = si.nMin; if(m_nHScrollPos>si.nMax) m_nHScrollPos = si.nMax; SetScrollPos(SB_HORZ,m_RefScroll.cx - point.x + m_RefPoint.x); Invalidate(FALSE); } if(m_dwHeight>clientRect.Height()) { GetScrollInfo(SB_VERT,&si); m_nVScrollPos = m_RefScroll.cy - point.y + m_RefPoint.y; if(m_nVScrollPos<si.nMin) m_nVScrollPos = si.nMin; if(m_nVScrollPos>si.nMax) m_nVScrollPos = si.nMax; SetScrollPos(SB_VERT,m_RefScroll.cy - point.y + m_RefPoint.y); Invalidate(FALSE); } } break; case CCxImageCtrl::IS_Crop: if(m_bCaptureWasSet) { m_CropActivePoint = point; ClientToImage(m_CropActivePoint); ImageToClient(m_CropActivePoint); Invalidate(FALSE); } break; case CCxImageCtrl::IS_TextMove: if (m_pTextComment != NULL) { if (!m_bCaptureWasSet) { if (!m_pTextComment->GetRectangle().PtInRect(imagePoint)) { SetState(IS_Text); SetCursor(AfxGetApp()->LoadCursor(IDC_TEXTCURSOR)); } } else { m_RefPoint = imagePoint; m_RefPoint.Offset(m_RefOffset); m_hImage.Copy(m_hImageBuffer); m_pTextComment->SetPosition(m_RefPoint, GetDC()); m_pTextComment->DrawText(m_hImage, CPaintDC(GetDesktopWindow())); Invalidate(false); } } break; case CCxImageCtrl::IS_Text: if (m_pTextComment != NULL) { if (m_pTextComment->GetRectangle().PtInRect(imagePoint)) { SetState(IS_TextMove); SetCursor(AfxGetApp()->LoadCursor(IDC_HANDCATCHCURSOR2)); Invalidate(false); } } break; case CCxImageCtrl::IS_Pen: { // Draw Line if(m_bCaptureWasSet) { CPoint fromPoint(m_RefPoint), toPoint(point); ClientToImage(fromPoint); ClientToImage(toPoint); m_hImage.DrawLine(fromPoint.x, toPoint.x, m_hImage.GetHeight()-fromPoint.y,m_hImage.GetHeight()-toPoint.y,GetPenColor()); //and remember new position [4/7/2004] m_RefScroll = CSize(m_nHScrollPos,m_nVScrollPos); m_RefPoint = point; Invalidate(FALSE); } } break; } } CWnd::OnMouseMove(nFlags, point); }
uint32 Editor::onMessage(uint32 message, uint32 wParam, uint32 lParam) { switch (message) { case WM_DESTROY: delete target; target = NULL; break; case WM_SETCURSOR: if (LOWORD(lParam) == HTCLIENT) { POINT pt; GetCursorPos(&pt); ScreenToClient(hWnd, &pt); if (pt.x < LeftMargin()) SetCursor(cursors[cArrow]); else if (selStart != caret) { pt.x = (pt.x - LeftMargin()) / chSize.cx + scrollPos.x; pt.y = pt.y / chSize.cy + scrollPos.y; if (pt.y < 0 || pt.y >= lines.length() || pt.x < 0 || pt.x >= lines[pt.y].text.length()) SetCursor(cursors[cBeam]); else { int offset = fromPoint(pt); int sela = (selStart < caret ? selStart : caret); int selb = (selStart < caret ? caret : selStart); if (offset >= sela && offset < selb) SetCursor(cursors[cArrow]); else SetCursor(cursors[cBeam]); } } else SetCursor(cursors[cBeam]); } else SetCursor(cursors[cArrow]); return TRUE; case WM_ERASEBKGND: return TRUE; case WM_PAINT: paint(); return 0; case WM_SIZE: if (hBitmap) { int wd = LOWORD(lParam); int ht = HIWORD(lParam); if (wd < 10) wd = 10; if (ht < 10) ht = 10; hBitmap = CreateCompatibleBitmap(hDC, wd, ht); SelectObject(hDC, hBitmap); } updateExtent(); return 0; case WM_SETFOCUS: placeCaret(); invalidate(); getParent()->notify(EN_FOCUSED, (uint32) this, 0); return 0; case WM_KILLFOCUS: DestroyCaret(); updateCaret(); invalidate(); return 0; case WM_LBUTTONDBLCLK: { POINT pt = paramToPoint(lParam); fixPoint(pt); int ptStart = wordEnd(lines[pt.y].text.c_str(), pt.x, -1); int ptEnd = wordEnd(lines[pt.y].text.c_str(), pt.x, 1); int offset = fromPoint(pt); selStart = offset - (pt.x - ptStart); caret = offset + (ptEnd - pt.x); updateCaret(); } return 0; case WM_LBUTTONDOWN: if (int(GET_X_LPARAM(lParam)) < int(settings->bpOffset - scrollPos.x * chSize.cx)) { POINT pt = paramToPoint(lParam); toggleBreakpoint(pt.y); } else { POINT pt = paramToPoint(lParam); int offset = fromPoint(pt); int sela = (selStart < caret ? selStart : caret); int selb = (selStart > caret ? selStart : caret); if (offset >= sela && offset < selb) { dragop = 1; uint32 fx = DoDragDropEx(CF_UNICODETEXT, CreateGlobalText(getSelection()), DROPEFFECT_MOVE | DROPEFFECT_COPY, hWnd); if (fx == DROPEFFECT_NONE) dragop = 0; //else if (fx != DROPEFFECT_COPY && dragop != 2) // replace(sela, selb, ""); } else SetCapture(hWnd); if (dragop == 0) { caret = offset; if (!(wParam & MK_SHIFT)) selStart = caret; } dragop = 0; if (GetFocus() != hWnd) SetFocus(hWnd); updateCaret(); } return 0; case WM_RBUTTONDOWN: if (int(GET_X_LPARAM(lParam)) >= int(settings->bpOffset - scrollPos.x * chSize.cx)) { POINT pt = paramToPoint(lParam); int offset = fromPoint(pt); int sela = (selStart < caret ? selStart : caret); int selb = (selStart > caret ? selStart : caret); if (offset < sela || offset >= selb) caret = selStart = offset; if (GetFocus() != hWnd) SetFocus(hWnd); updateCaret(); } return 0; case WM_MOUSEMOVE: if (GetCapture() == hWnd && (wParam & MK_LBUTTON)) { POINT pt = paramToPoint(lParam); caret = fromPoint(pt); updateCaret(); } return 0; case WM_LBUTTONUP: ReleaseCapture(); return 0; case WM_CHAR: if (iswprint(wParam) && (GetAsyncKeyState(VK_CONTROL) & 0x8000) == 0) { if (caret == selStart && !insertMode && caret < getTextLength()) replace(caret, caret + 1, WideString((wchar_t) wParam)); else replace(selStart, caret, WideString((wchar_t) wParam)); } return 0; case WM_VSCROLL: { SCROLLINFO si; memset(&si, 0, sizeof si); si.cbSize = sizeof si; si.fMask = SIF_ALL; GetScrollInfo(hWnd, SB_VERT, &si); switch (LOWORD(wParam)) { case SB_TOP: si.nPos = si.nMin; break; case SB_BOTTOM: si.nPos = si.nMax; break; case SB_LINEUP: si.nPos--; break; case SB_LINEDOWN: si.nPos++; break; case SB_PAGEUP: si.nPos -= si.nPage; break; case SB_PAGEDOWN: si.nPos += si.nPage; break; case SB_THUMBTRACK: si.nPos = si.nTrackPos; break; } doScroll(scrollPos.x, si.nPos); } return 0; case WM_HSCROLL: { SCROLLINFO si; memset(&si, 0, sizeof si); si.cbSize = sizeof si; si.fMask = SIF_ALL; GetScrollInfo(hWnd, SB_HORZ, &si); switch (LOWORD(wParam)) { case SB_LEFT: si.nPos = si.nMin; break; case SB_RIGHT: si.nPos = si.nMax; break; case SB_LINELEFT: si.nPos--; break; case SB_LINERIGHT: si.nPos++; break; case SB_PAGELEFT: si.nPos -= si.nPage; break; case SB_PAGERIGHT: si.nPos += si.nPage; break; case SB_THUMBTRACK: si.nPos = si.nTrackPos; break; } doScroll(si.nPos, scrollPos.y); } return 0; case WM_MOUSEWHEEL: { int step; SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &step, 0); if (step < 0) step = 3; scrollAccum.y += GET_WHEEL_DELTA_WPARAM(wParam) * step; doScroll(scrollPos.x, scrollPos.y - scrollAccum.y / WHEEL_DELTA); scrollAccum.y %= WHEEL_DELTA; } return 0; case WM_MOUSEHWHEEL: { scrollAccum.x += GET_WHEEL_DELTA_WPARAM(wParam) * 4; doScroll(scrollPos.x + scrollAccum.x / WHEEL_DELTA, scrollPos.y); scrollAccum.x %= WHEEL_DELTA; } return 0; case WM_DRAGOVER: { if (running || settings->mode) return TRUE; POINT pt = paramToPoint(lParam); dropPos = fromPoint(pt); RECT rc; GetClientRect(hWnd, &rc); int xto = scrollPos.x; if (pt.x < 10) xto--; else if (pt.x > rc.right - 10) xto++; int yto = scrollPos.y; if (pt.y < 10) yto--; else if (pt.y > rc.bottom - 10) yto++; doScroll(xto, yto); int sela = (selStart < caret ? selStart : caret); int selb = (selStart > caret ? selStart : caret); if (dropPos > sela && dropPos < selb) return TRUE; else { fixPoint(pt); CreateCaret(hWnd, NULL, 2, chSize.cy); SetCaretPos((pt.x - scrollPos.x) * chSize.cx + LeftMargin(), (pt.y - scrollPos.y) * chSize.cy); ShowCaret(hWnd); } } return 0; case WM_DRAGLEAVE: dropPos = 0; updateCaret(); return 0; case WM_DRAGDROP: if (running || settings->mode) return DROPEFFECT_NONE; if (dragop) { dragop = 2; int sela = (selStart < caret ? selStart : caret); int selb = (selStart > caret ? selStart : caret); if (dropPos < sela || dropPos > selb) { WideString text = getSelection(); if (lParam != DROPEFFECT_COPY) { replace(sela, selb, L""); if (dropPos > selb) dropPos -= (selb - sela); caret = replace(dropPos, dropPos, text, NULL, true); } else caret = replace(dropPos, dropPos, text); selStart = dropPos; } } else { caret = replace(dropPos, dropPos, GetGlobalTextWide((HGLOBAL) wParam)); selStart = dropPos; return DROPEFFECT_COPY; } return lParam; case WM_SYSKEYDOWN: case WM_KEYDOWN: onKey(wParam); return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_EDIT_UNDO: { bool glue = true; bool first = true; while (glue && historyPos > 0) { HistoryItem& h = history[--historyPos]; replace(h.begin, h.end, h.text, &h); glue = h.glue; h.glue = !first; first = false; } } break; case ID_EDIT_REDO: { bool glue = true; bool first = true; while (glue && historyPos < history.length()) { HistoryItem& h = history[historyPos++]; replace(h.begin, h.end, h.text, &h); glue = h.glue; h.glue = !first; first = false; } } break; case ID_EDIT_SELECTALL: selStart = 0; caret = getTextLength(); updateCaret(); break; case ID_EDIT_COPY: if (caret != selStart) SetClipboard(CF_UNICODETEXT, CreateGlobalText(getSelection())); else { POINT pt = toPoint(caret); pt.x = 0; int start = fromPoint(pt); if (pt.y < lines.length() - 1) pt.y++; else pt.x = lines[pt.y].text.length(); int end = fromPoint(pt); if (pCopyLine) pCopyLine->Release(); pCopyLine = SetClipboard(CF_UNICODETEXT, CreateGlobalText(substring(start, end))); if (pCopyLine) pCopyLine->AddRef(); } break; case ID_EDIT_CUT: if (caret != selStart) { SetClipboard(CF_UNICODETEXT, CreateGlobalText(getSelection())); replace(selStart, caret, L""); } else { POINT pt = toPoint(caret); POINT save = pt; pt.x = 0; int start = fromPoint(pt); if (pt.y < lines.length() - 1) pt.y++; else pt.x = lines[pt.y].text.length(); int end = fromPoint(pt); if (pCopyLine) pCopyLine->Release(); pCopyLine = SetClipboard(CF_UNICODETEXT, CreateGlobalText(substring(start, end))); if (pCopyLine) pCopyLine->AddRef(); replace(start, end, L""); caret = selStart = fromPoint(save); updateCaret(); } break; case ID_EDIT_PASTE: { ClipboardReader reader(CF_UNICODETEXT); if (reader.getData()) { if (OleIsCurrentClipboard(pCopyLine) == S_OK) { POINT pt = toPoint(caret); pt.x = 0; caret = selStart = fromPoint(pt); } selStart = caret = replace(selStart, caret, GetGlobalTextWide(reader.getData())); updateCaret(); } } break; case ID_DEBUG_BREAKPOINT: { POINT pt = toPoint(caret); toggleBreakpoint(pt.y); } break; default: return M_UNHANDLED; } return 0; } return M_UNHANDLED; }
int Editor::replace(int ibegin, int iend, WideString cstr, HistoryItem* mod, bool glue) { if (running || settings->mode) return iend; wchar_t const* str = cstr.c_str(); if (ibegin > iend) { int tmp = ibegin; ibegin = iend; iend = tmp; } POINT begin = toPoint(ibegin); POINT end = toPoint(iend); POINT oldEnd = end; if (mod) { mod->begin = ibegin; mod->end = ibegin + getlength(str); mod->text = substring(ibegin, iend); } else { HistoryItem h; h.begin = ibegin; h.end = ibegin + getlength(str); h.text = substring(ibegin, iend); h.glue = glue; bool push = true; if (historyPos < history.length()) history.resize(historyPos); else if (historyPos > 0 && h.text.empty() && h.end == h.begin + 1 && !h.glue) { HistoryItem& p = history[historyPos - 1]; if (p.text.empty() && h.begin == p.end) { push = false; p.end = h.end; } } if (push) { if (history.length() >= 256) { for (int i = 1; i < history.length(); i++) history[i - 1] = history[i]; history[history.length() - 1] = h; if (origHistory >= 0) origHistory--; } else history.push(h); } historyPos = history.length(); if (historyPos < origHistory) origHistory = -1; } if (begin.y == end.y) { Line ln = lines[begin.y]; lines.insert(begin.y + 1, ln); end.y = begin.y + 1; } lines[begin.y].text.resize(begin.x); int curLine = begin.y; int curPos = 0; while (str[curPos]) { if (str[curPos] == '\r' || str[curPos] == '\n') { if (curLine == begin.y) lines[curLine].text.append(str, curPos); else if (curLine < end.y) lines[curLine].text = WideString(str, curPos); else { Line& ln = lines.insert(curLine); ln.text = WideString(str, curPos); end.y++; } untabify(lines[curLine].text); if ((str[curPos + 1] == '\r' || str[curPos + 1] == '\n') && str[curPos] != str[curPos + 1]) curPos++; str = str + curPos + 1; curPos = 0; curLine++; } else curPos++; } if (curLine < end.y) { if (curLine == begin.y) lines[curLine].text += str; else lines[curLine].text = str; untabify(lines[curLine].text); int ex = lines[curLine].text.length(); lines[curLine].text += lines[end.y].text.substring(end.x); if (lines[end.y].breakpoint > 0) lines[curLine].breakpoint = 1; lines.remove(curLine + 1, end.y - curLine); end.y = curLine; end.x = ex; } else { lines[end.y].text.replace(0, end.x, str); end.x = wcslen(str); untabify(lines[end.y].text); } caret = selStart = fromPoint(end); updateCtx(begin.y, end.y); updateExtent(); updateCaret(); getParent()->notify(EN_MODIFIED, (uint32) this, 0); return caret; }
void Editor::updateFocus() { focus.clear(); //if (caret != selStart) // return; POINT pt = toPoint(caret); int ctx = lines[pt.y].ctx; int ctxType = lines[pt.y].ctxType; wchar_t const* text = lines[pt.y].text.c_str(); int pos = 0; while (pos < pt.x && text[pos]) { if (ctx) { if (text[pos] == ']') { pos++; int count = 0; while (text[pos] == '=' && count < ctxType) pos++, count++; if (text[pos] == ']' && count == ctxType) { pos++; ctx = 0; ctxType = 0; } } else pos++; } else { if (text[pos] == '[') { pos++; while (text[pos] == '=') pos++, ctxType++; if (text[pos] == '[') { pos++; ctx = ctxString; } else ctxType = 0; } else if (text[pos] == '-' && text[pos + 1] == '-') { pos += 2; if (text[pos] == '[') { pos++; while (text[pos] == '=') pos++, ctxType++; if (text[pos] == '[') { pos++; ctx = ctxComment; } else return; } else return; } else if (text[pos] == '"' || text[pos] == '\'') { wchar_t end = text[pos++]; while (text[pos] && text[pos] != end) { if (text[pos] == '\\') pos++; if (text[pos]) pos++; } if (text[pos]) pos++; } else pos++; } } if (pos > pt.x || ctx) return; if (text[pt.x] == '[') { int pos = pt.x + 1; while (text[pos] == '=') pos++; if (text[pos] == '[') return; } int start = pt.x; int type = 0; WideString kw; if (isBracket(lines[pt.y].text[pt.x])) type = 1; else { int end = start; while (start > 0 && iswalpha(lines[pt.y].text[start - 1])) start--; while (iswalpha(lines[pt.y].text[end])) end++; kw = lines[pt.y].text.substring(start, end); if (keywords.has(kw)) type = -1; } if (type == 0 && pt.x > 0 && isBracket(lines[pt.y].text[pt.x - 1])) { start = pt.x - 1; type = 1; } pt.x = start; if (type == 1) { int stack = 1; wchar_t fwd = lines[pt.y].text[start]; wchar_t rev = isBracket(fwd); bool forward = (fwd == '(' || fwd == '[' || fwd == '{'); while (stack > 0) { WideString brk = (forward ? nextKey(pt, true) : prevKey(pt, true)); if (brk.length() == 0 || pt.y < 0 || pt.y >= lines.length()) break; if (brk[0] == fwd) stack++; else if (brk[0] == rev) stack--; } if (stack == 0) { focus.push(FocusWord(fromPoint(pt), 1)); pt = toPoint(caret); pt.x = start; focus.push(FocusWord(fromPoint(pt), 1)); } } else if (type == -1 && kwInGraph.has(kw)) { Array<WideString> stk; stk.push(kw); POINT save = pt; while (stk.length() && pt.y < lines.length()) { WideString next = nextKey(pt, false); if (next.length() == 0) break; if (inKwGraph(stk.top(), next)) { if (stk.length() == 1) focus.push(FocusWord(fromPoint(pt), next.length())); stk.top() = next; } else if (kwBegin.has(next)) stk.push(next); if (kwEnd.has(stk.top())) stk.pop(); } pt = save; stk.clear(); stk.push(kw); while (stk.length() && pt.y >= 0) { WideString prev = prevKey(pt, false); if (prev.length() == 0) break; if (inKwGraph(prev, stk.top())) { if (stk.length() == 1) focus.push(FocusWord(fromPoint(pt), prev.length())); stk.top() = prev; } else if (kwEnd.has(prev)) stk.push(prev); if (kwBegin.has(stk.top()) && (stk.top() != L"do" || stk.length() > 1)) stk.pop(); } if (focus.length()) { pt = toPoint(caret); pt.x = start; focus.push(FocusWord(fromPoint(pt), kw.length())); } } focus.sort(); }