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

📄 multiedit.c

📁 成功移植到s3c44b0开发板上的ucos-ii和lwip
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
*********************************************************************************************************
*                                                uC/GUI
*                        Universal graphic software for embedded applications
*
*                       (c) Copyright 2002, Micrium Inc., Weston, FL
*                       (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
*
*              礐/GUI is protected by international copyright laws. Knowledge of the
*              source code may not be used to write a similar product. This file may
*              only be used in accordance with a license and should not be redistributed
*              in any way. We appreciate your understanding and fairness.
*
----------------------------------------------------------------------
File        : MULTIEDIT.c
Purpose     : Implementation of MULTIEDIT widget
---------------------------END-OF-HEADER------------------------------
*/

#include <stdlib.h>
#include <string.h>
#include "MULTIEDIT.h"
#include "WIDGET.h"
#include "WM_Intern.h"

#if GUI_WINSUPPORT

/*********************************************************************
*
*       Private config defaults
*
**********************************************************************
*/

/* Define default fonts */
#ifndef MULTIEDIT_FONT_DEFAULT
  #define MULTIEDIT_FONT_DEFAULT &GUI_Font13_1
#endif

/* Define colors */
#ifndef MULTIEDIT_BKCOLOR0_DEFAULT
  #define MULTIEDIT_BKCOLOR0_DEFAULT   GUI_WHITE
#endif

#ifndef MULTIEDIT_BKCOLOR1_DEFAULT
  #define MULTIEDIT_BKCOLOR1_DEFAULT   0xC0C0C0
#endif

#ifndef MULTIEDIT_TEXTCOLOR0_DEFAULT
  #define MULTIEDIT_TEXTCOLOR0_DEFAULT GUI_BLACK
#endif

#ifndef MULTIEDIT_TEXTCOLOR1_DEFAULT
  #define MULTIEDIT_TEXTCOLOR1_DEFAULT GUI_BLACK
#endif

/* Define character for password mode */
#define MULTIEDIT_PASSWORD_CHAR   '*'

/*********************************************************************
*
*       Object definition
*
**********************************************************************
*/

#define NUM_DISP_MODES 2

#define INVALID_NUMCHARS (1 << 0)
#define INVALID_NUMLINES (1 << 1)
#define INVALID_TEXTSIZE (1 << 2)
#define INVALID_CURSORXY (1 << 3)
#define INVALID_LINEPOSB (1 << 4)

typedef struct {
  WIDGET Widget;
  GUI_COLOR aBkColor[NUM_DISP_MODES];
  GUI_COLOR aColor[NUM_DISP_MODES];
  WM_HMEM hText;
  U16 MaxNumChars;         /* Maximum number of characters including the prompt */            
  U16 NumChars;            /* Number of characters (text and prompt) in object */                    
  U16 NumCharsPrompt;      /* Number of prompt characters */
  U16 NumLines;            /* Number of text lines needed to show all data */
  U16 TextSizeX;           /* Size in X of text depending of wrapping mode */
  U16 BufferSize;
  U16 CursorLine;          /* Number of current cursor line */
  U16 CursorPosChar;       /* Character offset number of cursor */
  U16 CursorPosByte;       /* Byte offset number of cursor */
  U16 CursorPosX;          /* Cursor position in X */
  U16 CursorPosY;          /* Cursor position in Y */
  U16 CacheLinePosByte;    /*  */
  U16 CacheLineNumber;     /*  */
  U16 CacheFirstVisibleLine;
  U16 CacheFirstVisibleByte;
  WM_SCROLL_STATE ScrollStateV;
  WM_SCROLL_STATE ScrollStateH;
  const GUI_FONT GUI_UNI_PTR * pFont;
  U8 Flags;
  U8 InvalidFlags;         /* Flags to save validation status */
  U8 EditMode;
  U8 HBorder;
  GUI_WRAPMODE WrapMode;
  #if GUI_DEBUG_LEVEL >1
    int DebugId;
  #endif
} MULTIEDIT_OBJ;

/*********************************************************************
*
*       Static data
*
**********************************************************************
*/

static GUI_COLOR _aDefaultBkColor[2] = {
  MULTIEDIT_BKCOLOR0_DEFAULT,
  MULTIEDIT_BKCOLOR1_DEFAULT,
};

static GUI_COLOR _aDefaultColor[2] = {
  MULTIEDIT_TEXTCOLOR0_DEFAULT,
  MULTIEDIT_TEXTCOLOR1_DEFAULT,
};

static const GUI_FONT GUI_UNI_PTR * _pDefaultFont = MULTIEDIT_FONT_DEFAULT;

/*********************************************************************
*
*       Macros for internal use
*
**********************************************************************
*/

#define MULTIEDIT_ID 0x8793   /* Magic numer, should be unique if possible */

#define MULTIEDIT_H2P(h) (MULTIEDIT_OBJ*) WM_H2P(h)

#define MULTIEDIT_REALLOC_SIZE  16

#if GUI_DEBUG_LEVEL > 1
  #define MULTIEDIT_ASSERT_IS_VALID_PTR(p) DEBUG_ERROROUT_IF(p->DebugId != MULTIEDIT_ID, "MULTIEDIT.c: Wrong handle type or Object not init'ed")
  #define MULTIEDIT_INIT_ID(p)   p->DebugId = MULTIEDIT_ID
  #define MULTIEDIT_DEINIT_ID(p) p->DebugId = MULTIEDIT_ID+1
#else
  #define MULTIEDIT_ASSERT_IS_VALID_PTR(p)
  #define MULTIEDIT_INIT_ID(p)
  #define MULTIEDIT_DEINIT_ID(p)
#endif

/*********************************************************************
*
*       static code, helper functions
*
**********************************************************************
*/

/*********************************************************************
*
*       _InvalidateNumChars
*
* Invalidates the number of characters including the prompt
*/
static void _InvalidateNumChars(MULTIEDIT_OBJ * pObj) {
  pObj->InvalidFlags |= INVALID_NUMCHARS;
}

/*********************************************************************
*
*       _GetNumChars
*
* Calculates (if needed) and returns the number of characters including the prompt
*/
static int _GetNumChars(MULTIEDIT_OBJ * pObj) {
  if (pObj->InvalidFlags & INVALID_NUMCHARS) {
    char * pText;
    pText = (char*) GUI_ALLOC_h2p(pObj->hText);
    pObj->NumChars = GUI__GetNumChars(pText);
    pObj->InvalidFlags &= ~INVALID_NUMCHARS;
  }
  return pObj->NumChars;
}

/*********************************************************************
*
*       _GetXSize
*
* Returns the x size for displaying text.
*/
static int _GetXSize(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ* pObj) {
  GUI_RECT Rect;
  WM_GetInsideRectExScrollbar(hObj, &Rect);
  return Rect.x1 - Rect.x0 - (pObj->HBorder * 2) - 1;
}

/*********************************************************************
*
*       _GetNumCharsInPrompt
*/
static int _GetNumCharsInPrompt(const MULTIEDIT_OBJ* pObj, const char GUI_UNI_PTR * pText) {
  char *pString, *pEndPrompt;
  int r = 0;
  pString = (char*) GUI_ALLOC_h2p(pObj->hText);
  pEndPrompt = pString + GUI_UC__NumChars2NumBytes(pString, pObj->NumCharsPrompt);
  if (pText < pEndPrompt) {
    r = GUI_UC__NumBytes2NumChars(pText, pEndPrompt - pText);
  }
  return r;
}

/*********************************************************************
*
*       _NumChars2XSize
*/
static int _NumChars2XSize(const char GUI_UNI_PTR * pText, int NumChars) {
  int xSize = 0;
  U16 Char;
  while (NumChars--) {
    Char   = GUI_UC__GetCharCodeInc(&pText);
    xSize += GUI_GetCharDistX(Char);
  }
  return xSize;
}

/*********************************************************************
*
*       _WrapGetNumCharsDisp
*/
static int _WrapGetNumCharsDisp(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ* pObj, const char GUI_UNI_PTR * pText) {
  int xSize, r;
  xSize = _GetXSize(hObj, pObj);
  if (pObj->Flags & MULTIEDIT_SF_PASSWORD) {
    int NumCharsPrompt;
    NumCharsPrompt = _GetNumCharsInPrompt(pObj, pText);
    r = GUI__WrapGetNumCharsDisp(pText, xSize, pObj->WrapMode);
    if (r >= NumCharsPrompt) {
      int x;
      switch (pObj->WrapMode) {
      case GUI_WRAPMODE_NONE:
        r = GUI__GetNumChars(pText);
        break;
      default:
        r = NumCharsPrompt;
        x = _NumChars2XSize(pText, NumCharsPrompt);
        pText += GUI_UC__NumChars2NumBytes(pText, NumCharsPrompt);
        while (GUI_UC__GetCharCodeInc(&pText) != 0) {
          x += GUI_GetCharDistX(MULTIEDIT_PASSWORD_CHAR);
          if (r && (x > xSize)) {
            break;
          }
          r++;
        }
        break;
      }
    }
  } else {
    r = GUI__WrapGetNumCharsDisp(pText, xSize, pObj->WrapMode);
  }
  return r;
}

/*********************************************************************
*
*       _WrapGetNumBytesToNextLine
*/
static int _WrapGetNumBytesToNextLine(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ* pObj, const char* pText) {
  int xSize, r;
  xSize = _GetXSize(hObj, pObj);
  if (pObj->Flags & MULTIEDIT_SF_PASSWORD) {
    int NumChars, NumCharsPrompt;
    NumCharsPrompt = _GetNumCharsInPrompt(pObj, pText);
    NumChars = _WrapGetNumCharsDisp(hObj, pObj, pText);
    r        = GUI_UC__NumChars2NumBytes(pText, NumChars);
    if (NumChars < NumCharsPrompt) {
      if (*(pText + r) == '\n') {
        r++;
      }
    }
  } else {
    r = GUI__WrapGetNumBytesToNextLine(pText, xSize, pObj->WrapMode);
  }
  return r;
}

/*********************************************************************
*
*       _GetCharDistX
*/
static int _GetCharDistX(const MULTIEDIT_OBJ* pObj, const char* pText) {
  int r;
  if ((pObj->Flags & MULTIEDIT_SF_PASSWORD) && (_GetNumCharsInPrompt(pObj, pText) == 0)) {
    r = GUI_GetCharDistX(MULTIEDIT_PASSWORD_CHAR);
  } else {
    U16 c;
    c = GUI_UC_GetCharCode(pText);
    r = GUI_GetCharDistX(c);
  }
  return r;
}

/*********************************************************************
*
*       _DispString
*/
static void _DispString(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ* pObj, const char* pText, GUI_RECT* pRect) {
  int NumCharsDisp;
  NumCharsDisp = _WrapGetNumCharsDisp(hObj, pObj, pText);
  if (pObj->Flags & MULTIEDIT_SF_PASSWORD) {
    int x, NumCharsPrompt, NumCharsLeft = 0;
    NumCharsPrompt = _GetNumCharsInPrompt(pObj, pText);
    if (NumCharsDisp < NumCharsPrompt) {
      NumCharsPrompt = NumCharsDisp;
    } else {
      NumCharsLeft = NumCharsDisp - NumCharsPrompt;
    }
    GUI_DispStringInRectMax(pText, pRect, GUI_TA_LEFT, NumCharsPrompt);
    x = pRect->x0 + _NumChars2XSize(pText, NumCharsPrompt);
    if (NumCharsLeft) {
      GUI_DispCharAt(MULTIEDIT_PASSWORD_CHAR, x, pRect->y0);
      GUI_DispChars(MULTIEDIT_PASSWORD_CHAR, NumCharsLeft - 1);
    }
  } else {
    GUI_DispStringInRectMax(pText, pRect, GUI_TA_LEFT, NumCharsDisp);
  }  
}

/*********************************************************************
*
*       static code, cursor routines
*
**********************************************************************
*/
/*********************************************************************
*
*       _GetpLine
*
* Returns a pointer to the beginning of the line with the
* given line number.
*/
static char * _GetpLine(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj, unsigned LineNumber) {
  char * pText, * pLine;
  pText = (char*) GUI_ALLOC_h2p(pObj->hText);
  if ((unsigned)pObj->CacheLineNumber != LineNumber) {
    if (LineNumber > (unsigned)pObj->CacheLineNumber) {
      /* If new line number > cache we can start with old pointer */
      int OldNumber = pObj->CacheLineNumber;
      pLine = pText + pObj->CacheLinePosByte;
      pObj->CacheLineNumber  = LineNumber;
      LineNumber -= OldNumber;
    } else {
      /* If new line number < cache we need to start with first byte */
      pLine = pText;
      pObj->CacheLineNumber  = LineNumber;
    }
    while (LineNumber--) {
      pLine += _WrapGetNumBytesToNextLine(hObj, pObj, pLine);
    }
    pObj->CacheLinePosByte = pLine - pText;
  }
  return pText + pObj->CacheLinePosByte;
}

/*********************************************************************
*
*       _ClearCache
*
* Clears the cached position of the linenumber and the first byte
* of the line which holds the cursor.
*/
static void _ClearCache(MULTIEDIT_OBJ* pObj) {
  pObj->CacheLineNumber = 0;
  pObj->CacheLinePosByte = 0;
  pObj->CacheFirstVisibleByte = 0;
  pObj->CacheFirstVisibleLine = 0;
}

/*********************************************************************
*
*       _GetCursorLine
*
* Returns the line number of the cursor position.
*/
static int _GetCursorLine(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ* pObj, const char* pText, int CursorPosChar) {
  const char *pCursor;
  const char *pEndLine;
  int NumChars, ByteOffsetNewCursor, LineNumber = 0;
  ByteOffsetNewCursor = GUI_UC__NumChars2NumBytes(pText, CursorPosChar);
  pCursor = pText + ByteOffsetNewCursor;
  if (pObj->CacheLinePosByte < ByteOffsetNewCursor) {
    /* If cache pos < new position we can use it as start position */
    pText      += pObj->CacheLinePosByte;
    LineNumber += pObj->CacheLineNumber;
  }
  while (*pText && (pCursor > pText)) {
    NumChars = _WrapGetNumCharsDisp(hObj, pObj, pText);
    pEndLine = pText + GUI_UC__NumChars2NumBytes(pText, NumChars);
    pText   += _WrapGetNumBytesToNextLine(hObj, pObj, pText);
    if (pCursor <= pEndLine) {
      if ((pCursor == pEndLine) && (pEndLine == pText) && *pText) {
        LineNumber++;
      }
      break;
    }
    LineNumber++;
  }
  return LineNumber;
}

/*********************************************************************
*
*       _GetCursorXY
*/
static void _GetCursorXY(MULTIEDIT_HANDLE hObj, /*const*/ MULTIEDIT_OBJ* pObj, int* px, int* py) {
  if (pObj->InvalidFlags & INVALID_CURSORXY) {
    int CursorLine = 0, x = 0;
    GUI_SetFont(pObj->pFont);
    if (pObj->hText) {
      const char *pLine;
      const char *pCursor;
      pLine      = (const char *)GUI_ALLOC_h2p(pObj->hText);
      pCursor    = pLine + pObj->CursorPosByte;
      CursorLine = pObj->CursorLine;
      pLine      = _GetpLine(hObj, pObj, CursorLine);
      while (pLine < pCursor) {
        x     += _GetCharDistX(pObj, pLine);
        pLine += GUI_UC_GetCharSize(pLine);
      }
    }
    pObj->CursorPosX = x;
    pObj->CursorPosY = CursorLine * GUI_GetFontDistY();
    pObj->InvalidFlags &= ~INVALID_CURSORXY;
  }
  *px = pObj->CursorPosX;
  *py = pObj->CursorPosY;
}

/*********************************************************************
*
*       _InvalidateCursorXY
*/
static void _InvalidateCursorXY(MULTIEDIT_OBJ * pObj) {
  pObj->InvalidFlags |= INVALID_CURSORXY;
}

/*********************************************************************
*
*       _SetScrollState
*/
static void _SetScrollState(WM_HWIN hObj) {
  MULTIEDIT_OBJ* pObj = MULTIEDIT_H2P(hObj);
  WIDGET__SetScrollState(hObj, &pObj->ScrollStateV, &pObj->ScrollStateH);
}

/*********************************************************************
*
*       _CalcScrollPos
*
* Purpose:

⌨️ 快捷键说明

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