⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textedit.c

📁 MiniGUI for uCOS 移植实验全部源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        */
        lineidx = 0;
        while (1) {
            DrawTextEx2 (hdc, pLine, txtlen, &rc, indent, 
                    TE_FORMAT | DT_WORDBREAK | DT_CALCRECT, &fl);
            if (pLine + fl.nr_chars > pIns)
                break;
            else if (pLine + fl.nr_chars == pIns) {
                if (lineidx < linenr-1) {
                    pLine += fl.nr_chars;
                    lineidx ++;
                    indent = 0;
                }
                break;
            }
            pLine += fl.nr_chars;
            txtlen -= fl.nr_chars;
            rc.top += ptedata->nLineHeight;
            lineidx ++;
            indent = 0;
        }

        GetTabbedTextExtent(hdc, pLine, pIns - pLine, &txtsize);

        w = indent + txtsize.cx;
        h += ptedata->nLineHeight * lineidx;

        ptedata->des_caret_x = w;
        endh = (h < ptescr->nContY) ? h : h + ptedata->nLineHeight;
        scrolled_make_pos_visible (hWnd, ptescr, -1, endh-1);
#ifdef _SELECT_SUPPORT
        if (txtdoc->selection.curNode)
            mySetSelPos (w, h + ptedata->nLineAboveH);
        else
#endif
            mySetCaretPos (hWnd, w, h + ptedata->nLineAboveH);
    }
    else {
        SIZE txtsize;

        GetTabbedTextExtent(hdc, node->content.string, mark->pos_lnOff, &txtsize);
        ptedata->des_caret_x = txtsize.cx + indent;
        endh = (h < ptescr->nContY) ? h : h + ptedata->nLineHeight;
        scrolled_make_pos_visible (hWnd, ptescr, 
                        txtsize.cx + indent, endh-1);
#ifdef _SELECT_SUPPORT
        if (txtdoc->selection.curNode)
            mySetSelPos (txtsize.cx + indent, h + ptedata->nLineAboveH);
        else
#endif
            mySetCaretPos (hWnd, txtsize.cx + indent, h + ptedata->nLineAboveH);
    }

    ReleaseDC (hdc);
}

static void teOnChar (HWND hWnd, PTEDATA ptedata, WPARAM wParam)
{
    int chlen;
    unsigned char ch[2];
    //int linenr, old_linenr, indent = 0;
    TextNode *node;
    DWORD dwStyle = GetWindowStyle(hWnd);

    if (dwStyle & ES_READONLY) {
        Ping();
        return;
    }

    ch [0] = LOBYTE (wParam);
    ch [1] = HIBYTE (wParam);

    if (ch[1]) {
        chlen = 2;
    }
    else {
        chlen = 1;

        if ( ch[0] < 0x20 && ch[0] != '\b' && ch[0] != '\t'
                && ch[0] != '\n' && ch[0] != '\r' ) {
            return;
        }

        if (dwStyle & ES_UPPERCASE) {
            ch [0] = toupper (ch[0]);
        }
        else if (dwStyle & ES_LOWERCASE) {
            ch [0] = tolower (ch[0]);
        }

        //ENTER
        if (ch [0] == '\r') {
            ch [0] = ptedata->txtdoc.lnsep;
        }
    }
    //FIXME
 
    node = ptedata->txtdoc.insert.curNode;
    /*
    node = ptedata->txtdoc.insert.curNode;
    indent = teGetLineIndent (ptedata, node);
    old_linenr = NODE_LINENR(node);
    */

#if 0
    if (textdoc_insert_string (&ptedata->txtdoc, ch, chlen) < 0)
        return;
#else
    if (textdoc_insert_string (&ptedata->txtdoc, ch, chlen))
        REFRESH_NODE(node);
#endif

    /*
    linenr = get_line_nr(hWnd, ptedata, node, indent);
    if (linenr != old_linenr) {
        scrollview_set_item_height (hWnd, (HSVITEM)node->addData, 
                        ptedata->nLineHeight*linenr);
    }
    set_line_width (hWnd, ptedata, node, indent);
    */

    if (node != ptedata->txtdoc.insert.curNode) {
        node = ptedata->txtdoc.insert.curNode;
        //FIXME, optimize
        teNodeChange (&ptedata->txtdoc, FALSE);
        REFRESH_NODE(node);
    }

    teSetCaretPos (hWnd, ptedata);
    //REFRESH_NODE(node);
    //scrollview_refresh_content (&ptedata->svdata);
    NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CHANGE);
}

static void
teOnMouseDown (HWND hWnd, TextNode *node, POINT *pt, int item_y, BOOL bShift)
{
    PTEDATA ptedata = (PTEDATA)GetWindowAdditionalData2(hWnd);
    TextDoc *txtdoc = &ptedata->txtdoc;

    if (!node) return;

    if (!bShift) {
        txtdoc->insert.curNode = node;
        ptedata->curItemY = item_y;
    }
#ifdef _SELECT_SUPPORT
    else {
        txtdoc->selection.curNode = node;
        ptedata->selItemY = item_y;
    }
#endif

    set_caret_pos (hWnd, ptedata, node, pt->x, pt->y, bShift);
}

#ifdef _SELECT_SUPPORT

static void get_selected_rect (PTEDATA ptedata, RECT *rcSel)
{
    TextDoc *txtdoc = &ptedata->txtdoc;

    rcSel->left = 0;
    rcSel->right = 0;
    if (ptedata->curItemY < ptedata->selItemY) {
        rcSel->top = ptedata->curItemY;
        rcSel->bottom = ptedata->selItemY + NODE_HEIGHT(txtdoc->selection.curNode);
    }
    else {
        rcSel->top = ptedata->selItemY;
        rcSel->bottom = ptedata->curItemY + NODE_HEIGHT(txtdoc->insert.curNode);
    }

}

/*
 * te_unselect_all : unselects the selected parts
 * Params          : bChange - whether to change the insertion point to the
 *                             position of the selection point
 */
static void te_unselect_all (HWND hWnd, PTEDATA ptedata, BOOL bChange)
{
    TextDoc *txtdoc = &ptedata->txtdoc;
    RECT rcSel;
    POINT pt;

    get_selected_rect (ptedata, &rcSel);

    if (bChange) {
        txtdoc->insert = txtdoc->selection;
        ptedata->curItemY = ptedata->selItemY;
        myGetSelPos (&pt);
    }

    txtdoc->selection.curNode = NULL;
    scrollview_unselect_all (&ptedata->svdata);
    scrolled_refresh_rect (ptescr, &rcSel);

    if (bChange) {
        mySetCaretPos (hWnd, pt.x, pt.y);
        ptedata->des_caret_x = pt.x;
    }
}

static int
te_set_selection (HWND hWnd, PTEDATA ptedata)
{
    TextDoc *txtdoc = &ptedata->txtdoc;
    TextMark *markStart, *markEnd;
    TextNode *node;
    RECT rcSel;

    markStart = get_start_mark (ptedata);
    markEnd = (markStart == &txtdoc->insert) ? 
                              &txtdoc->selection : &txtdoc->insert;

    node = markStart->curNode;
    while (node) {
        SELECT_NODE (node, TRUE);
        if (node == markEnd->curNode)
            break;
        node = TXTNODE_NEXT (node);
    }

    get_selected_rect (ptedata, &rcSel);
    scrolled_refresh_rect (ptescr, &rcSel);
    check_caret ();

    return 0;
}

static int te_select_all (HWND hWnd, PTEDATA ptedata)
{
    TextMark *selection = &ptedata->txtdoc.selection;
    TextMark *insertion = &ptedata->txtdoc.insert;
    TextNode *last;

    if (selection->curNode) {
        te_unselect_all (hWnd, ptedata, TRUE);
    }

    insertion->pos_lnOff = 0;
    insertion->curNode = FIRSTNODE(&ptedata->txtdoc);
    ptedata->curItemY = 0;
    teSetCaretPos (hWnd, ptedata);

    last = LASTNODE(&ptedata->txtdoc);
    selection->curNode = last;
    selection->pos_lnOff = last->content.txtlen;
    ptedata->selItemY = scrollview_get_total_item_height (&ptedata->svdata) 
                        - NODE_HEIGHT(last);
    //FIXME, optimize
    teSetCaretPos (hWnd, ptedata);

    return te_set_selection (hWnd, ptedata);
}

#endif

/*
 * te_set_position : Sets insertion or selection position
 * Params          : mark - insertion or selection point
 */
static TextNode*
te_set_position (HWND hWnd, PTEDATA ptedata, TextMark *mark, 
                 int line, int char_pos, int *item_y, int *newpos)
{
    TextNode *markNode;
    int *pos_chars;
    int nr_chars;

    if (char_pos < 0)
        return NULL;
    if ( !(markNode = get_node_by_idx (ptedata, line, item_y)) )
        return NULL;
    if (char_pos > markNode->content.txtlen)
        return NULL;

    pos_chars = ALLOCATE_LOCAL (markNode->content.txtlen * sizeof(int));
    nr_chars = GetTextMCharInfo (GetWindowFont (hWnd),
                    markNode->content.string, markNode->content.txtlen, pos_chars);

    if (char_pos > nr_chars) {
        DEALLOCATE_LOCAL (pos_chars);
        return NULL;
    }

    if (char_pos == nr_chars)
        char_pos = markNode->content.txtlen;
    else
        char_pos = pos_chars[char_pos];

    DEALLOCATE_LOCAL (pos_chars);

    if (newpos)
        *newpos = char_pos;
    return markNode;
}

static int
TE_OnMouseDown (HWND hWnd, HSVITEM hsvi, POINT* pt, int item_y, BOOL bShift)
{
    PTEDATA ptedata = (PTEDATA)GetWindowAdditionalData2(hWnd);
    TextNode *node = NULL;
#ifdef _SELECT_SUPPORT
    TextDoc *txtdoc = &ptedata->txtdoc;
    //TextNode *org_node =  txtdoc->insert.curNode;
    TextMark *selection = &txtdoc->selection;
#endif

    /* note that hsvi may be null */
    if (hsvi)
        node = (TextNode*)scrollview_get_item_adddata (hsvi);

#ifdef _SELECT_SUPPORT
    if (selection->curNode) {
        te_unselect_all (hWnd, ptedata, !bShift);
    }
#endif

    if (!bShift) {
        if (node)
            ptedata->des_caret_x = pt->x;
        teOnMouseDown (hWnd, node, pt, item_y, bShift);
        ShowCaret (hWnd);
        NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CLICKED);
        //FIXME
        //NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CHANGE);
    }
#ifdef _SELECT_SUPPORT
    else {
        teOnMouseDown (hWnd, node, pt, item_y, bShift);
        te_set_selection (hWnd, ptedata);
    }
#endif

    return 0;
}

#ifdef _SELECT_SUPPORT
static void begin_selection (PTEDATA ptedata)
{
    ptedata->txtdoc.selection = ptedata->txtdoc.insert;
    ptedata->selItemY = ptedata->curItemY;
    ptedata->sel_x = ptedata->caret_x;
    ptedata->sel_y = ptedata->caret_y;
    SELECT_NODE(ptedata->txtdoc.selection.curNode, TRUE);
}
#endif

static void
te_cursor_updown (HWND hWnd, PTEDATA ptedata, int len, BOOL bShift)
{
    TextDoc *txtdoc = &ptedata->txtdoc;
    TextNode *node;
    TextMark *mark;
    int item_y;
    POINT pt;

#ifdef _SELECT_SUPPORT
    TextNode *org_node;

    if (!bShift && txtdoc->selection.curNode) {
        te_unselect_all (hWnd, ptedata, TRUE);
    }

    mark = bShift ? &txtdoc->selection : &txtdoc->insert;

    if (bShift && !mark->curNode) {
        begin_selection (ptedata);
    }
    node = mark->curNode;
    org_node = mark->curNode;
    item_y = bShift ? ptedata->selItemY : ptedata->curItemY;
#else
    mark = &txtdoc->insert;
    node = mark->curNode;
    item_y = ptedata->curItemY;
#endif

#ifdef _SELECT_SUPPORT
    if (bShift) {
        myGetSelPos (&pt);
    }
    else
#endif
        myGetCaretPos (&pt);

    pt.y += len * ptedata->nLineHeight;
    pt.x = ptedata->des_caret_x;

    if (len == 1) {  // go to next line
        if (pt.y >= item_y + NODE_HEIGHT(node)) {
            // go to next node
            if (BE_LAST_NODE(node))
                return;
            item_y += NODE_HEIGHT(node);
            node = TXTNODE_NEXT(node);
        }
    }
    else if (len == -1) {
        if (pt.y < item_y) {
            // go to previous node
            if (BE_FIRST_NODE(node))
                return;
            node = TXTNODE_PREV(node);
            item_y -= NODE_HEIGHT(node);
        }
    }
    else {
        //TODO
        return;
    }
    pt.y -= item_y;

    teOnMouseDown (hWnd, node, &pt, item_y, bShift);
    te_make_caret_visible (hWnd, ptedata, bShift);

#ifdef _SELECT_SUPPORT
    if (bShift) {
        if(NODE_IS_SELECTED(node)) {
            if (node != org_node)
                SELECT_NODE(org_node, FALSE);
        }
        else {
            SELECT_NODE(node, TRUE);
        }
        if (node != org_node)
            REFRESH_NODE(org_node);
        REFRESH_NODE(node);
        check_caret();
    }
#endif
}

/*
 * te_cursor_shift : process shift keys, including left and right arrow, Home,
 *                   End keys.
 * Params          : bShift - Whether shift key is in pressed status
 */ 
static void
te_cursor_shift (HWND hWnd, PTEDATA ptedata, int kcode, BOOL bShift)
{
    TextDoc *txtdoc = &ptedata->txtdoc;
    TextNode *node, *curnode;
    unsigned char *pIns;
    int len;
    POINT pt;
    TextMark *mark;

#ifdef _SELECT_SUPPORT
    /* unselect the selected first */
    if (!bShift && txtdoc->selection.curNode) {
        te_unselect_all (hWnd, ptedata, TRUE);
    }

    mark = bShift ? &txtdoc->selection : &txtdoc->insert;

    if (bShift && !mark->curNode) {
        begin_selection (ptedata);
    }
#else
    mark = &txtdoc->insert;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -