📄 textedit.c
字号:
#endif node = mark->curNode; pIns = node->content.string + mark->pos_lnOff; if (kcode == SCANCODE_CURSORBLOCKRIGHT) { if (*pIns == '\0') return; else if (*pIns == txtdoc->lnsep || is_rn_sep(pIns)) { curnode = TXTNODE_NEXT(node); set_current_node (txtdoc, curnode, bShift, FALSE);#ifdef _SELECT_SUPPORT if (bShift) { SELECT_NODE(node, (NODE_IS_SELECTED(curnode) ? FALSE : TRUE) ); SELECT_NODE(curnode, TRUE); ptedata->selItemY += NODE_HEIGHT(node); } else#endif ptedata->curItemY += NODE_HEIGHT(node); } else { mark->pos_lnOff += CHLENNEXT(pIns, (node->content.string + node->content.txtlen - pIns)); } } else if (kcode == SCANCODE_CURSORBLOCKLEFT) { len = -1; if (pIns == node->content.string) { if (BE_FIRST_NODE(node)) return; else { curnode = TXTNODE_PREV(node); set_current_node (txtdoc, curnode, bShift, FALSE);#ifdef _SELECT_SUPPORT if (bShift) { SELECT_NODE(node, (NODE_IS_SELECTED(curnode) ? FALSE : TRUE) ); SELECT_NODE(curnode, TRUE); ptedata->selItemY -= NODE_HEIGHT(TXTNODE_PREV(node)); } else#endif ptedata->curItemY -= NODE_HEIGHT(TXTNODE_PREV(node)); mark->pos_lnOff = TXTNODE_PREV(node)->content.txtlen - 1; } } else { mark->pos_lnOff -= CHLENPREV(node->content.string, pIns); } } else if (kcode == SCANCODE_HOME || kcode == SCANCODE_END) { myGetCaretPos (&pt); pt.y -= ptedata->curItemY; pt.x = (kcode == SCANCODE_HOME)? 0 : scrolled_get_contwidth (ptescr) - 1; if (node) ptedata->des_caret_x = pt.x; teOnMouseDown (hWnd, node, &pt, ptedata->curItemY, bShift); goto SFRETURN; } teSetCaretPos (hWnd, ptedata);SFRETURN:#ifdef _SELECT_SUPPORT if (bShift) { REFRESH_NODE(mark->curNode); check_caret (); }#endif}#ifdef _SELECT_SUPPORTstatic void te_cursor_move (HWND hWnd, PTEDATA ptedata, POINT *pt){ int item_h; TextDoc *txtdoc = &ptedata->txtdoc; TextMark *selection = &txtdoc->selection; TextNode *curnode; POINT oldpt, newpt; /* begin to select */ if (!selection->curNode) { begin_selection (ptedata); return; } curnode = selection->curNode; item_h = scrollview_get_item_height (curnode->addData); if (pt->y >= ptedata->selItemY + item_h) { TextNode *next = TXTNODE_NEXT (curnode); if (next) { selection->curNode = next; ptedata->selItemY += item_h; } else { if (selection->pos_lnOff != curnode->content.txtlen) { selection->pos_lnOff = curnode->content.txtlen; REFRESH_NODE(curnode); check_caret (); } return; } //FIXME pt->y = ptedata->selItemY + item_h + ptedata->nLineHeight/2; } else if (pt->y < ptedata->selItemY) { TextNode *prev = TXTNODE_PREV (curnode); if (prev) { selection->curNode = prev; item_h = scrollview_get_item_height ((HSVITEM)prev->addData); ptedata->selItemY -= item_h; } else { if (selection->pos_lnOff != 0) { selection->pos_lnOff = 0; REFRESH_NODE(curnode); check_caret (); } return; } pt->y = ptedata->selItemY - ptedata->nLineHeight/2; } if (ptedata->flags & TEST_MOVE) { /* int step; step = pt->y - ptescr->nContY - ptescr->visibleHeight; step = step > ptedata->nLineHeight ? 6 : 3; */ scrolled_make_pos_visible (hWnd, ptescr, pt->x, pt->y); } pt->y -= ptedata->selItemY; /* moves to a new line */ if (curnode && selection->curNode != curnode) { /* moves off the current selected line */ if (NODE_IS_SELECTED(selection->curNode)) SELECT_NODE(curnode, FALSE); else SELECT_NODE(selection->curNode, TRUE); REFRESH_NODE(curnode); } myGetSelPos (&oldpt); set_caret_pos (hWnd, ptedata, selection->curNode, pt->x, pt->y, TRUE); myGetSelPos (&newpt); if (oldpt.x != newpt.x || oldpt.y != newpt.y) REFRESH_NODE(selection->curNode); check_caret ();}#endifstatic SVITEMOPS textedit_iops ={ NULL, NULL, teDrawItem};void textedit_set_draw_selected (HWND hWnd, ED_DRAWSEL_FUNC drawSel){ PTEDATA ptedata = (PTEDATA) GetWindowAdditionalData2 (hWnd); ptedata->drawSelected = drawSel; InvalidateRect (hWnd, NULL, TRUE);}void textedit_set_caret_func (HWND hWnd, int (*getcaretwidth) (HWND, int) ){ PTEDATA ptedata = (PTEDATA) GetWindowAdditionalData2 (hWnd); ptedata->getCaretWidth = getcaretwidth;}void textedit_refresh_caret (HWND hWnd){ mySetCaretPos (hWnd, -1, -1);}/* --------------------------------------------------------------------------------- */static int textedit_get_pos_ex (HWND hWnd, int *line_pos, int *char_pos, BOOL bSel){ PTEDATA ptedata = (PTEDATA) GetWindowAdditionalData2 (hWnd); TextDoc *txtdoc = &ptedata->txtdoc; int nr_chars = 0; TextMark *mark; mark = GETMARK(bSel); if (!mark->curNode) return -1; if (line_pos) { *line_pos = NODE_INDEX(mark->curNode); } if (char_pos) { nr_chars = GetTextMCharInfo (GetWindowFont (hWnd), mark->curNode->content.string, mark->pos_lnOff, NULL); *char_pos = nr_chars; } return mark->pos_lnOff;}int textedit_get_caretpos (HWND hWnd, int *line_pos, int *char_pos){ return textedit_get_pos_ex (hWnd, line_pos, char_pos, FALSE);}int textedit_get_selpos (HWND hWnd, int *line_pos, int *char_pos){ return textedit_get_pos_ex (hWnd, line_pos, char_pos, TRUE);}static int textedit_set_pos_ex (HWND hWnd, int line_pos, int char_pos, BOOL bSel){ PTEDATA ptedata = (PTEDATA) GetWindowAdditionalData2 (hWnd); TextDoc *txtdoc = &ptedata->txtdoc; int item_y, newpos; TextMark *mark; TextNode *node; if ( !(mark = GETMARK(bSel)) ) return -1; if ( !(node = te_set_position (hWnd, ptedata, mark, line_pos, char_pos, &item_y, &newpos)) ) return -1;#ifdef _SELECT_SUPPORT /* unselect the former seleted before mark is changed */ if (txtdoc->selection.curNode) { te_unselect_all (hWnd, ptedata, TRUE); }#endif SETITEMY(bSel, item_y); mark->pos_lnOff = newpos; mark->curNode = node;#ifdef _SELECT_SUPPORT if (bSel) te_set_selection (hWnd, ptedata); else#endif teSetCaretPos (hWnd, ptedata); return mark->pos_lnOff;}#ifdef _TITLE_SUPPORTstatic int textedit_get_titletext (HWND hWnd, PTEDATA ptedata, int tlen, char *buffer){ int len, title_len; if (!ptedata->title) return -1; title_len = strlen (ptedata->title); if (!buffer) return title_len; if (tlen >= 0) len = (tlen > DEF_TITLE_LEN) ? DEF_TITLE_LEN : tlen; else len = DEF_TITLE_LEN; strncpy (buffer, ptedata->title, len); buffer[len] = '\0'; return title_len;}static int textedit_set_titletext (HWND hWnd, PTEDATA ptedata, int tlen, const char *newtitle){ int len; HDC hdc; if (!ptedata->title || !newtitle) return -1; if (tlen >= 0) len = (tlen > DEF_TITLE_LEN) ? DEF_TITLE_LEN : tlen; else len = DEF_TITLE_LEN; strncpy (ptedata->title, newtitle, len); ptedata->title[len] = '\0'; hdc = GetClientDC (hWnd); SelectFont (hdc, GetWindowFont(hWnd)); ptedata->titleIndent = teGetTitleIndent (hWnd, ptedata, hdc); ReleaseDC (hWnd); mySetCaretPos (hWnd, ptedata->titleIndent, 0 + ptedata->nLineAboveH); return strlen (ptedata->title);}#endifstatic voidtextedit_reset_content (HWND hWnd, PTEDATA ptedata, const char *newtext, BOOL bLast){ TextDoc *txtdoc = &ptedata->txtdoc; scrollview_reset_content (hWnd, &ptedata->svdata); teResetData (ptedata); scrollview_freeze (hWnd, &ptedata->svdata, TRUE); textdoc_settext (txtdoc, newtext); scrollview_freeze (hWnd, &ptedata->svdata, FALSE); if ( bLast && !(GetWindowStyle(hWnd) & ES_READONLY) ) { TextNode *node = LASTNODE(txtdoc); txtdoc->insert.curNode = node; txtdoc->insert.pos_lnOff = node->content.txtlen; teNodeChange (txtdoc, FALSE); teSetCaretPos (hWnd, ptedata); } else { mySetCaretPos (hWnd, teGetLineIndent(ptedata, FIRSTNODE(txtdoc)), 0 + ptedata->nLineAboveH); }}int textedit_insert_text (HWND hWnd, const char* text, int len){ PTEDATA ptedata = (PTEDATA)GetWindowAdditionalData2 (hWnd); TextDoc *txtdoc = &ptedata->txtdoc; int ret; /* TextNode *node = txtdoc->insert.curNode; TextNode *nextnode = NULL; if (!BE_LAST_NODE(node)) nextnode = TXTNODE_NEXT (node); */ if (!text || len <= 0) return -1; ret = textdoc_insert_text (txtdoc, text, len); teNodeChange (txtdoc, FALSE); teSetCaretPos (hWnd, ptedata); //FIXME REFRESH_NODE(txtdoc->insert.curNode); /* if (set_line_size (hWnd, ptedata, node) < 0) REFRESH_NODE(node); if (nextnode) set_line_size (hWnd, ptedata, TXTNODE_PREV(nextnode)); else set_line_size (hWnd, ptedata, LASTNODE(txtdoc)); */ NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CHANGE); return ret;}#ifdef _CLIPBOARD_SUPPORT/* * textedit_insert_cbtext : inserts clipboard texts into the current insertion point */static int textedit_insert_cbtext (HWND hWnd, PTEDATA ptedata){ int inserting; unsigned char *txtBuffer; inserting = GetClipBoardDataLen (CBNAME_TEXT); txtBuffer = FixStrAlloc (inserting); GetClipBoardData (CBNAME_TEXT, txtBuffer, inserting); textedit_insert_text (hWnd, txtBuffer, inserting); FreeFixStr(txtBuffer); return inserting;}#endif/* * initialize text edit object structure */static int teInitData (HWND hWnd, PTEDATA ptedata){ int pageval; TextDoc *txtdoc = &ptedata->txtdoc;/* HDC hdc = GetClientDC (hWnd); ptedata->mem_dc = CreateCompatibleDC (hdc); ReleaseDC (hdc);*/ /* init scrollview object */ scrollview_init (hWnd, &ptedata->svdata); /* change default move_content function */ ptedata->svdata.scrdata.move_content = textedit_set_svlist; ptedata->nLineHeight = DEF_LINE_HEIGHT; ptedata->nLineAboveH = DEF_LINE_ABOVE_H; ptedata->nLineBaseH = DEF_LINE_BASE_H;#ifdef _TITLE_SUPPORT if (GetWindowStyle(hWnd) & ES_TITLE) { ptedata->title = FixStrAlloc (DEF_TITLE_LEN+1); ptedata->title[0] = '\0'; ptedata->titleIndent = 0; } else { ptedata->title = NULL; ptedata->titleIndent = 0; }#endif scrolled_set_scrollval (ptescr, 0, ptedata->nLineHeight); pageval = (ptescr->visibleHeight / ptedata->nLineHeight ) * ptedata->nLineHeight; scrolled_set_scrollpageval (ptescr, 0, pageval); ptedata->lnChar = 0; ptedata->caretShape = ED_CARETSHAPE_LINE; teResetData (ptedata); scrollview_set_itemops (&ptedata->svdata, (SVITEMOPS*)&textedit_iops); ptedata->drawSelected = NULL; ptedata->getCaretWidth = NULL; /* init text document object */ INIT_LIST_HEAD(&txtdoc->queue); memset (&txtdoc->insert, 0, sizeof(txtdoc->insert));#ifdef _SELECT_SUPPORT txtdoc->selection.curNode = NULL;#endif textdoc_reset (hWnd, txtdoc);//FIXME, where to put? SetWindowAdditionalData2 (hWnd, (DWORD) ptedata); scrollview_freeze (hWnd, &ptedata->svdata, TRUE); textdoc_settext (txtdoc, GetWindowCaption(hWnd)); scrollview_freeze (hWnd, &ptedata->svdata, FALSE); return 0;}#ifdef _UNDO_SUPPORT/*static void teUndoBackup (TextDoc *txtdoc){ PTEDATA ptedata = (PTEDATA)GetWindowAdditionalData2 ((HWND)txtdoc->fn_data); TextNode *curnode = txtdoc->insert.curNode; if ( (ptedata->act_count %= ACTION_COUNT) == 0 ) { BACKUP_DATA(); ptedata->bkIns = txtdoc->insert; ptedata->bkSel = txtdoc->selection; testr_free (ptedata->bkBuff); free (ptedata->bkBuff); ptedata->bkBuff = testr_dup (&curnode->content); printf ("back up : %s\n", ptedata->bkBuff->string); ptedata->act_count = 0; } ptedata->act_count ++;}*/static int te_init_undo (HWND hWnd, PTEDATA ptedata){ ptedata->undo_depth = DEF_UNDO_DEPTH; ptedata->bkData = calloc (1, sizeof(BKDATA)*ptedata->undo_depth); if (!ptedata->bkData) return -1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -