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

📄 textedit.c

📁 这是ARM嵌入式系统的实验教程中的MINIGUI的实验源代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
#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_SUPPORT

static 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 ();
}
#endif

static SVITEMOPS textedit_iops =
{
    NULL, NULL, teDrawItem
};

void textedit_set_draw_selected (HWND hWnd, TEITEM_DRAWSEL_FUNC drawSel)
{
    PTEDATA ptedata = (PTEDATA) GetWindowAdditionalData2 (hWnd);
    ptedata->drawSelected = drawSel;
    InvalidateRect (hWnd, NULL, TRUE);
}

/* --------------------------------------------------------------------------------- */

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;

    mark = GETMARK(bSel);

    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;

    teSetCaretPos (hWnd, ptedata);
#ifdef _SELECT_SUPPORT
    if (bSel)
        te_set_selection (hWnd, ptedata);
#endif
    return mark->pos_lnOff;
}

#ifdef _TITLE_SUPPORT
static 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);
}
#endif

static void textedit_reset_content (HWND hWnd, PTEDATA ptedata, const char *newtext)
{
    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);

    mySetCaretPos (hWnd, teGetLineIndent(ptedata, FIRSTNODE(txtdoc)), 
                    0 + ptedata->nLineAboveH);
}

#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;
    TextDoc *txtdoc = &ptedata->txtdoc;
    /*
    TextNode *node = txtdoc->insert.curNode;
    TextNode *nextnode = NULL;
    
    if (!BE_LAST_NODE(node))
        nextnode = TXTNODE_NEXT (node);
    */

    inserting = GetClipBoardDataLen (CBNAME_TEXT);
    txtBuffer = FixStrAlloc (inserting);
    GetClipBoardData (CBNAME_TEXT, txtBuffer, inserting);

    textdoc_insert_text (txtdoc, txtBuffer, inserting);

    FreeFixStr(txtBuffer);

    //FIXME
    //if (node != txtdoc->insert.curNode)
        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));
    */

    return inserting;
}
#endif

/*
 * initialize text edit object structure
 */
static int teInitData (HWND hWnd, PTEDATA ptedata)
{
    int pageval;
    TextDoc *txtdoc = &ptedata->txtdoc;

    /* 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;
    teResetData (ptedata);

    scrollview_set_itemops (&ptedata->svdata, (SVITEMOPS*)&textedit_iops);
    ptedata->drawSelected = 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);

    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 = malloc (sizeof(BKDATA)*ptedata->undo_depth);
    if (!ptedata->bkData)
        return -1;

    ptedata->undo_level = -1;
    ptedata->act_count = 0;

    return 0;
}

#endif

static int textedit_init (HWND hWnd, PTEDATA ptedata)
{
    if (!ptedata)
        return -1;

    if (BE_WRAP(hWnd))
        ShowScrollBar (hWnd, SB_HORZ, FALSE);

    teInitData (hWnd, ptedata);
    SetWindowAdditionalData2 (hWnd, (DWORD) ptedata);

    CreateCaret (hWnd, NULL, 1, ptedata->nLineHeight - ptedata->nLineAboveH);
    //SetFocus (hWnd);

    mySetCaretPos (hWnd, ptedata->des_caret_x, 0 + ptedata->nLineAboveH);

#ifdef _UNDO_SUPPORT
    if (te_init_undo (hWnd, ptedata) < 0)

⌨️ 快捷键说明

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