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

📄 textedit.h

📁 在ADS环境下MiniGUI的源码
💻 H
字号:
/*
** $Id: textedit.h,v 1.43 2004/10/06 02:47:09 snig Exp $ 
**
** textedit.h: header file of TextEdit control.
**
** Copyright (C) 2004 Feynman Software.
*/

#ifndef _TEXTEDIT_H
#define _TEXTEDIT_H


#ifdef __cplusplus
extern "C"
{
#endif


/* ---------------------- configuration options ----------------------- */

/* supports text selection */
#define _SELECT_SUPPORT     1
/* supports text undo/redo operations */
//#define _UNDO_SUPPORT       1

/* support title text */
#define _TITLE_SUPPORT          1

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

/* default base line height */
#define DEF_LINE_BASE_H         ( (GetWindowStyle(hWnd) & TES_BASELINE) ? 2 : 0 )
/* default line above height */
#define DEF_LINE_ABOVE_H        4
/* minimal line above height */
#define MIN_LINE_ABOVE_H        1
/* default line height */
#define DEF_LINE_HEIGHT         ( GetWindowFont(hWnd)->size + DEF_LINE_BASE_H + \
                                 DEF_LINE_ABOVE_H )

/* default line buffer size */ 
#define DEF_LINE_BUFFER_SIZE    128
/* default line step block size */
#define DEF_LINE_BLOCK_SIZE     32

/* default line seperator '\n' */
#define DEF_LINESEP             '\n'

#define CH_RN                   "\r\n"

/* default title length */
#define DEF_TITLE_LEN           63


/* draw text format */
#define TE_FORMAT  (DT_LEFT | DT_TOP | DT_NOCLIP | DT_EXPANDTABS) 

#ifdef _UNDO_SUPPORT
#define DEF_UNDO_DEPTH          3

/* undo operation types */
#define UNDO_OP_EDIT            1
#define UNDO_OP_ADD             2
#define UNDO_OP_DEL             3

#endif


typedef int (*TEITEM_DRAWSEL_FUNC) (HWND, HDC, int, int, const char*, int, int);

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

/* internal status flags */
#define TEST_SELECT     0x00000001L
#define TEST_FOCUSED    0x00000002L
#define TEST_TMP        0x00000004L
#define TEST_REPLACE    0x00000008L
#define TEST_MOVE       0x00000010L

/* ------------------------------- text document/buffer ------------------------ */

/* content type, reserved */
typedef enum {
    CT_TEXT,
    CT_BMP,
    CT_ICON,
} ContentType;

/* text format, reserved */
typedef enum {
    TF_PLAINTEXT,
    TF_RICHTEXT,
    TF_MEDIATEXT,
} TextFormat;

/* one text line (end with '\n') is a scrollview item */ 
/* structure of text node/line */
typedef struct _textnode
{
    list_t    list;            /* list element */
    StrBuffer content;
    //ContentType type;        /* text node content type, reserved */
    DWORD     addData;         /* for storing scrollview item handle */
} TextNode;

/* structure of a text mark, recording insert position or selection range */
typedef struct _textmark
{
    int       pos_lnOff;       /* mark offset in the text node*/
    TextNode  *curNode;        /* text node containing the mark*/
} TextMark;

/* structure of text document data */
typedef struct _textdoc
{
    list_t    queue;           /* text line/node head */

    /* setup field */
    unsigned char lnsep;       /* line seperator (default is "\n") */
    int       nDefLineSize;    /* default line buffer size*/
    int       nBlockSize;      /* line buffer block size */
    //TextFormat txtFormat;    /* text format, reserved */

    /* node init function executed when creating node */
    void      (*init_fn)     (struct _textdoc *, TextNode *, TextNode *);
    /* node change function executed when changing current insertion/selection node */
    void      (*change_fn)   (struct _textdoc *, BOOL bSel);
    /* node content change function executed when string content of a node is changed */
    void      (*change_cont) (struct _textdoc *, TextNode *node);
    /* node destroy function */
    void      (*del_fn)      (struct _textdoc *, TextNode *);
    void       *fn_data;       /* data passed to init_fn */

    /* status field */
    TextMark  insert;          /* cursor/insertion mark */
#ifdef _SELECT_SUPPORT
    TextMark  selection;       /* selection mark */
#endif

} TextDoc;

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

#ifdef _UNDO_SUPPORT

#define ACTION_COUNT    5

/* backup data struct */
typedef struct _status_data
{
    DWORD     flags;        /* editor status */

    int       des_caret_x;  /* the desired caret x position, changed by mouse and <- , -> */

    int       caret_x;      /* caret x position in the virtual content window */
    int       caret_y;      /* caret y position in the virtual content window */
#ifdef _SELECT_SUPPORT
    int       sel_x;        /* selection point x position in the virtual content window */
    int       sel_y;        /* selection point y position in the virtual content window */
#endif

    TextNode  *maxNode;     /* node with the max length */
    int       maxLen;       /* max line length */
    TextNode  *secNode;     /* node with the second max length */
    int       secLen;       /* seconde max line length */

    int       curItemY;     /* y position of the current insertion node */
#ifdef _SELECT_SUPPORT
    int       selItemY;     /* y position of the selection node */
#endif
} STATDATA;
typedef STATDATA* PSTATDATA;

/* structure of backup text node/line */
typedef struct _bk_textnode
{
    list_t    list;         /* list element */
    StrBuffer content;      /* text content */
} BkNode;

typedef struct _backup_data
{
    STATDATA  statData;
    TextMark  bkIns;        /* backup insertion point */
    TextMark  bkSel;        /* backup selection point */
    int       opType;       /* operation type */
    list_t    bkQueue;      /* backup text nodes */
} BKDATA;
typedef BKDATA* PBKDATA;

#endif

/* structure of textedit control data */
typedef struct _tedata
{
    SVDATA    svdata;       /* scrollview object */
    TextDoc   txtdoc;       /* text document object */

    /* ----------------- properties ------------------- */

    int       nLineHeight;  /* line height */
    int       nLineAboveH;  /* height of above-line area */
    int       nLineBaseH;   /* height of base-line area */
    unsigned char lnChar;   /* the char used to represent line seperator */

#ifdef _TITLE_SUPPORT
    char      *title;       /* title text displayed before content text */
    int       titleIndent;  /* title indent */
#endif

    /* ----------------- status ----------------------- */

    /* don't move this field */
    DWORD     flags;        /* editor status */

    int       des_caret_x;  /* the desired caret x position, changed by mouse and <- , -> */

    int       caret_x;      /* caret x position in the virtual content window */
    int       caret_y;      /* caret y position in the virtual content window */
#ifdef _SELECT_SUPPORT
    int       sel_x;        /* selection point x position in the virtual content window */
    int       sel_y;        /* selection point y position in the virtual content window */
#endif

    TextNode  *maxNode;     /* node with the max length */
    int       maxLen;       /* max line length */
    TextNode  *secNode;     /* node with the second max length */
    int       secLen;       /* seconde max line length */

    int       curItemY;     /* y position of the current insertion node */
#ifdef _SELECT_SUPPORT
    int       selItemY;     /* y position of the selection node */
#endif

#ifdef _UNDO_SUPPORT
    BKDATA    *bkData;      /* backup status data */
    int       undo_level;   /* current undo level */
    int       cur_undo_depth; /* current undo depth */
    int       undo_depth;   /* depth of undo stack */
    int       act_count;    /* user action count */
#endif

    TEITEM_DRAWSEL_FUNC drawSelected;
} TEDATA;
typedef TEDATA* PTEDATA;


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

/* alloc for text node */
//TODO
static inline TextNode* textnode_alloc (void)
{
    return malloc (sizeof(TextNode));
}

static inline void textnode_free (TextNode * node)
{
    free (node);
}

#define ptescr          (&ptedata->svdata.scrdata)

/* gets the current caret position in the virtual content window */
#define myGetCaretPos(pt)  \
            ( (pt)->x = ptedata->caret_x, \
              (pt)->y = ptedata->caret_y )

#ifdef _SELECT_SUPPORT

#define myGetSelPos(pt) \
            ( (pt)->x = ptedata->sel_x, \
              (pt)->y = ptedata->sel_y )
#define mySetSelPos(x, y) \
        ( ptedata->sel_x = x >= 0 ? x : ptedata->sel_x, \
          ptedata->sel_y = y >= 0 ? y : ptedata->sel_y )

#endif


#define BE_WRAP(hWnd)     (GetWindowStyle(hWnd) & TES_AUTOWRAP)

#define BE_FIRST_NODE(node) \
           (node->list.prev == &txtdoc->queue)

#define BE_LAST_NODE(node) \
           (node->list.next == &txtdoc->queue)

#define FIRSTNODE(txtdoc) \
           (list_entry((txtdoc)->queue.next, TextNode, list))
#define LASTNODE(txtdoc) \
           (list_entry((txtdoc)->queue.prev, TextNode, list))

#define NODE_LINENR(node) \
        ( scrollview_get_item_height((HSVITEM)(node)->addData) / ptedata->nLineHeight )

#define NODE_HEIGHT(node) \
        (scrollview_get_item_height((HSVITEM)(node)->addData))

#define NODE_INDEX(node) \
        (scrollview_get_item_index(hWnd, (HSVITEM)(node)->addData))

static inline int teGetLineIndent (PTEDATA ptedata, TextNode *node)
{
#ifdef _TITLE_SUPPORT
    if (node && node->list.prev == &ptedata->txtdoc.queue) {
        return ptedata->titleIndent;
    }
#endif
    return 0;
}

#define TXTNODE_NEXT(node) \
            ( ((node)->list.next == &txtdoc->queue) ? NULL : \
                list_entry((node)->list.next, TextNode, list) )

#define TXTNODE_PREV(node) \
            ( ((node)->list.prev == &txtdoc->queue) ? NULL : \
                list_entry((node)->list.prev, TextNode, list) )

 
#ifdef _SELECT_SUPPORT
static BOOL textnode_is_selected (TextDoc *txtdoc, TextNode *node)
{
    if (!txtdoc->selection.curNode)
        return FALSE;

    return scrollview_is_item_selected ((HSVITEM)node->addData);
}

#define NODE_IS_SELECTED(node) \
            scrollview_is_item_selected ((HSVITEM)node->addData)

#define SELECT_NODE(node, bsel) \
            scrollview_select_item (&ptedata->svdata, (HSVITEM)(node)->addData, bsel)

#endif


#define is_rn_sep(pIns) (txtdoc->lnsep == '\n' && *(pIns) == '\r' && *(pIns+1) == '\n')

#define check_caret() \
            if (txtdoc->selection.curNode) { \
                if (txtdoc->selection.curNode == txtdoc->insert.curNode && \
                      txtdoc->selection.pos_lnOff == txtdoc->insert.pos_lnOff) { \
                    ShowCaret (hWnd); \
                    txtdoc->selection.curNode = NULL; \
                } \
                else \
                    HideCaret (hWnd); \
            } \
            else \
                ShowCaret (hWnd);

#define REFRESH_NODE(node) \
            scrollview_refresh_item(&ptedata->svdata, (HSVITEM)(node)->addData)

static int
textdoc_insert_string_ex (TextDoc *txtdoc, TextNode *enode, int insert_pos,
                          const char* newtext, int len);

static inline int
textdoc_insert_string_ex_2 (TextDoc *txtdoc, TextNode *enode, int insert_pos,
                          const char* newtext, int len)
{
    TextNode *node;
    BOOL bDel;
    int ret;

    /* If in selection mode, left change_cont to be called by delete_selection */
    bDel = (txtdoc->selection.curNode && !enode) ? TRUE : FALSE;
    node = enode ? enode : txtdoc->insert.curNode;

    /* must use enode here */
    ret = textdoc_insert_string_ex (txtdoc, enode, insert_pos, newtext, len);
    if (!enode)
        txtdoc->insert.pos_lnOff = ret;

    if (!bDel && txtdoc->change_cont) {
        txtdoc->change_cont (txtdoc, node);
    }

    return !bDel;
    //return txtdoc->insert.pos_lnOff;
}

#define textdoc_insert_string(txtdoc, newtext, len)  \
             textdoc_insert_string_ex_2(txtdoc, NULL, 0, newtext, len)


#ifdef _SELECT_SUPPORT
    #define GETMARK(cond)     ( (cond) ? (&txtdoc->selection) : \
                                      (&txtdoc->insert) )
    #define SETITEMY(cond, item_y)    \
                if (cond) \
                    ptedata->selItemY = item_y; \
                else \
                    ptedata->curItemY = item_y;

#else
    #define GETMARK(cond)     (&txtdoc->insert)
    #define SETITEMY(cond, item_y)    \
                    ptedata->curItemY = item_y;
#endif

#ifdef _UNDO_SUPPORT
    #define BACKUP_STDATA(stdata) \
                memcpy (stdata, (void*)&ptedata->flags, sizeof(STATDATA));
    #define UNDO_STDATA(stdata) \
                memcpy ((void*)&ptedata->flags, stdata, sizeof(STATDATA));
#endif


#ifdef __cplusplus
}
#endif  /* __cplusplus */

#endif  /* _TEXTEDIT_H */

⌨️ 快捷键说明

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