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

📄 multiedit.c

📁 ucgui的3.98版本的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        x = 0;
      }
    }

    if (pObj->Flags & MULTIEDIT_SF_PASSWORD) {
      while (--WrapChars > 0) {
        Char   = GUI_UC_GetCharCode(pLine);
        SizeX += _GetCharDistX(pObj, pLine);
        if (!Char || (SizeX > x)) {
          break;
        }
        pLine += GUI_UC_GetCharSize(pLine);
      }
      CursorPosChar = GUI_UC__NumBytes2NumChars(pText, pLine - pText);
    } else {
      CursorPosChar = GUI_UC__NumBytes2NumChars(pText, pLine - pText) + GUI__GetCursorPosChar(pLine, x, WrapChars);
    }
  }
  _SetCursorPos(hObj, pObj, CursorPosChar);
}

/*********************************************************************
*
*       _MoveCursorUp
*/
static void _MoveCursorUp(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
  int xPos, yPos;
  _GetCursorXY(hObj, pObj, &xPos, &yPos);
  yPos -= GUI_GetYDistOfFont(pObj->pFont);
  _SetCursorXY(hObj, pObj, xPos, yPos);
}

/*********************************************************************
*
*       _MoveCursorDown
*/
static void _MoveCursorDown(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
  int xPos, yPos;
  _GetCursorXY(hObj, pObj, &xPos, &yPos);
  yPos += GUI_GetYDistOfFont(pObj->pFont);
  _SetCursorXY(hObj, pObj, xPos, yPos);
}

/*********************************************************************
*
*       _MoveCursor2NextLine
*/
static void _MoveCursor2NextLine(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
  int xPos, yPos;
  _GetCursorXY(hObj, pObj, &xPos, &yPos);
  yPos += GUI_GetYDistOfFont(pObj->pFont);
  _SetCursorXY(hObj, pObj, 0, yPos);
}

/*********************************************************************
*
*       _MoveCursor2LineEnd
*/
static void _MoveCursor2LineEnd(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
  int xPos, yPos;
  _GetCursorXY(hObj, pObj, &xPos, &yPos);
  _SetCursorXY(hObj, pObj, 0x7FFF, yPos);
}

/*********************************************************************
*
*       _MoveCursor2LinePos1
*/
static void _MoveCursor2LinePos1(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
  int xPos, yPos;
  _GetCursorXY(hObj, pObj, &xPos, &yPos);
  _SetCursorXY(hObj, pObj, 0, yPos);
}

/*********************************************************************
*
*       _IsOverwriteAtThisChar
*/
static int _IsOverwriteAtThisChar(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
  int r = 0;
  if (pObj->hText && !(pObj->Flags & MULTIEDIT_CF_INSERT)) {
    const char *pText;
    int CurPos, Line1, Line2;
    U16 Char;
    pText  = (const char *)GUI_ALLOC_h2p(pObj->hText);
    Line1  = pObj->CursorLine;
    CurPos = _CalcNextValidCursorPos(hObj, pObj, pObj->CursorPosChar + 1, 0, 0);
    Line2  = _GetCursorLine(hObj, pObj, pText, CurPos);
    pText += pObj->CursorPosByte;
    Char   = GUI_UC_GetCharCode(pText);
    if (Char) {
      if ((Line1 == Line2) || (pObj->Flags & MULTIEDIT_SF_PASSWORD)) {
        r = 1;
      } else {
        if (Char != '\n') {
          if ((Char != ' ') || (pObj->WrapMode == GUI_WRAPMODE_CHAR)) {
            r = 1;
          }
        }
      }
    }
  }
  return r;
}

/*********************************************************************
*
*       _GetCursorSizeX
*
* Returns the width of the cursor to be draw according to the
* insert mode flag and the cursor position.
*/
static int _GetCursorSizeX(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj, int * pIsRTL) {
  if (_IsOverwriteAtThisChar(hObj, pObj)) {
    #if (GUI_SUPPORT_ARABIC)
      if (pObj->Flags & MULTIEDIT_SF_PASSWORD) {
        const char *pText;
        pText  = (const char *)GUI_ALLOC_h2p(pObj->hText);
        pText += pObj->CursorPosByte;
        return _GetCharDistX(pObj, pText);
      } else {
        const char * pText;
        U16 Prev = 0, Char, Next = 0, Glyph;
        pText = (const char *)GUI_ALLOC_h2p(pObj->hText);
        if (pObj->CursorPosChar) {
          int NumChars = pObj->CursorPosChar;
          while (--NumChars) {
            pText += GUI_UC_GetCharSize(pText);
          }
          Prev = GUI_UC__GetCharCodeInc(&pText);
          Char = GUI_UC__GetCharCodeInc(&pText);
        } else {
          pText += pObj->CursorPosByte;
          Char = GUI_UC__GetCharCodeInc(&pText);
        }
        if (pObj->CursorPosChar < (pObj->NumChars - 1)) {
          Next = GUI_UC_GetCharCode(pText);
        }
        Glyph = GUI__GetPresentationForm(Char, Next, Prev, 0);
        if (Char != 0x20) {
          *pIsRTL = GUI__IsArabicCharacter(Char) ? 1 : 0;
        } else {
          *pIsRTL = GUI__IsArabicCharacter(Prev) ? 1 : 0;
        }
        return GUI_GetCharDistX(Glyph);
      }
    #else
      const char *pText;
      *pIsRTL = 0;
      pText  = (const char *)GUI_ALLOC_h2p(pObj->hText);
      pText += pObj->CursorPosByte;
      return _GetCharDistX(pObj, pText);
    #endif
  } else {
    #if (GUI_SUPPORT_ARABIC)
      const char * pText;
      U16 Prev = 0, Char;
      pText = (const char *)GUI_ALLOC_h2p(pObj->hText);
      if (pObj->CursorPosChar) {
        int NumChars = pObj->CursorPosChar;
        while (--NumChars) {
          pText += GUI_UC_GetCharSize(pText);
        }
        Prev = GUI_UC__GetCharCodeInc(&pText);
        Char = GUI_UC_GetCharCode(pText);
      } else {
        pText += pObj->CursorPosByte;
        Char = GUI_UC_GetCharCode(pText);
      }
      if (Char != 0x20) {
        *pIsRTL = GUI__IsArabicCharacter(Char) ? 1 : 0;
      } else {
        *pIsRTL = GUI__IsArabicCharacter(Prev) ? 1 : 0;
      }
    #endif
    return 2;
  }
}

/*********************************************************************
*
*       static code, buffer management
*
**********************************************************************
*/
/*********************************************************************
*
*       _IncrementBuffer
*
* Increments the buffer size by AddBytes.
*/
static int _IncrementBuffer(MULTIEDIT_OBJ* pObj, unsigned AddBytes) {
  WM_HMEM hNew;
  int NewSize;
  NewSize = pObj->BufferSize + AddBytes;
  hNew    = GUI_ALLOC_Realloc(pObj->hText, NewSize);
  if (hNew) {
    if (!(pObj->hText)) {
      char* pText;
      pText  = (char*) GUI_ALLOC_h2p(hNew);
      *pText = 0;
    }
    pObj->BufferSize = NewSize;
    pObj->hText = hNew;
    return 1;
  }
  return 0;
}

/*********************************************************************
*
*       _IsSpaceInBuffer
*
* Checks the available space in the buffer. If there is not enough
* space left this function attempts to get more.
*
* Returns:
*  1 = requested space is available
*  0 = failed to get enough space
*/
static int _IsSpaceInBuffer(MULTIEDIT_OBJ* pObj, int BytesNeeded) {
  int NumBytes = 0;
  if (pObj->hText) {
    NumBytes = strlen((char*)GUI_ALLOC_h2p(pObj->hText));
  }
  BytesNeeded = (BytesNeeded + NumBytes + 1) - pObj->BufferSize;
  if (BytesNeeded > 0) {
    if (!_IncrementBuffer(pObj, BytesNeeded + MULTIEDIT_REALLOC_SIZE)) {
      return 0;
    }
  }
  return 1;
}

/*********************************************************************
*
*       _IsCharsAvailable
*
* Checks weither the maximum number of characters is reached or not.
*
* Returns:
*  1 = requested number of chars is available
*  0 = maximum number of chars have reached
*/
static int _IsCharsAvailable(MULTIEDIT_OBJ* pObj, int CharsNeeded) {
  if ((CharsNeeded > 0) && (pObj->MaxNumChars > 0)) {
    int NumChars = 0;
    if (pObj->hText) {
      NumChars = _GetNumChars(pObj);
    }
    if ((CharsNeeded + NumChars) > pObj->MaxNumChars) {
      return 0;
    }
  }
  return 1;
}

/*********************************************************************
*
*       static code, string manipulation routines
*
**********************************************************************
*/
/*********************************************************************
*
*       _DeleteChar
*
* Deletes a character at the current cursor position and moves
* all bytes after the cursor position.
*/
static void _DeleteChar(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
  if (pObj->hText) {
    unsigned CursorOffset;
    char* s;
    s = (char*) GUI_ALLOC_h2p(pObj->hText);
    CursorOffset = pObj->CursorPosByte;
    if (CursorOffset < strlen(s)) {
      char *pCursor, *pLine, *pEndLine;
      int CursorLine, NumChars, NumBytes;
      pCursor    = s + CursorOffset;
      CursorLine = pObj->CursorLine;
      pLine      = _GetpLine(hObj, pObj, CursorLine);
      NumChars   = _WrapGetNumCharsDisp(hObj, pObj, pLine);
      pEndLine   = pLine + GUI_UC__NumChars2NumBytes(pLine, NumChars);
      pLine      = pLine + _WrapGetNumBytesToNextLine(hObj, pObj, pLine);
      if (pCursor == pEndLine) {
        NumBytes = pLine - pEndLine;
      } else {
        NumBytes = GUI_UC_GetCharSize(pCursor);
      }
      NumChars = GUI_UC__NumBytes2NumChars(pCursor, NumBytes);
      strcpy(pCursor, pCursor + NumBytes);
      WM_NotifyParent(hObj, WM_NOTIFICATION_VALUE_CHANGED);
      pObj->NumChars -= NumChars;
      _InvalidateNumLines(pObj);
      _InvalidateTextSizeX(pObj);
      _InvalidateCursorXY(pObj); /* Invalidate X/Y position */
      _ClearCache(pObj);
      pObj->CursorLine = _GetCursorLine(hObj, pObj, s, pObj->CursorPosChar);
    }
  }
}

/*********************************************************************
*
*       _InsertChar
*
* Create space at the current cursor position and inserts a character.
*/
static int _InsertChar(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj, U16 Char) {
  if (_IsCharsAvailable(pObj, 1)) {
    int BytesNeeded;
    BytesNeeded = GUI_UC__CalcSizeOfChar(Char);
    if (_IsSpaceInBuffer(pObj, BytesNeeded)) {
      int CursorOffset;
      char* pText;
      pText = (char*) GUI_ALLOC_h2p(pObj->hText);
      CursorOffset = pObj->CursorPosByte;
      pText += CursorOffset;
      memmove(pText + BytesNeeded, pText, strlen(pText) + 1);
      GUI_UC_Encode(pText, Char);
      WM_NotifyParent(hObj, WM_NOTIFICATION_VALUE_CHANGED);
      pObj->NumChars += 1;
      _InvalidateNumLines(pObj);
      _InvalidateTextSizeX(pObj);
      _ClearCache(pObj);
      return 1;
    }
  }
  return 0;
}

/*********************************************************************
*
*       static code
*
**********************************************************************
*/
/*********************************************************************
*
*       _MULTIEDIT_Paint
*/
static void _MULTIEDIT_Paint(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ * pObj) {
  int ScrollPosX, ScrollPosY, EffectSize, HBorder, IsRTL = 0;
  int x, y, xOff, yOff, ColorIndex, FontSizeY;
  GUI_RECT r, rClip;
  const GUI_RECT *prOldClip;
  /* Init some values */
  GUI_SetFont(pObj->pFont);
  FontSizeY  = GUI_GetFontDistY();
  ScrollPosX = pObj->ScrollStateH.v;
  ScrollPosY = pObj->ScrollStateV.v;
  EffectSize = pObj->Widget.pEffect->EffectSize;
  HBorder    = pObj->HBorder;
  xOff       = EffectSize + HBorder - ScrollPosX;
  yOff       = EffectSize - ScrollPosY * FontSizeY;
  ColorIndex = ((pObj->Flags & MULTIEDIT_SF_READONLY) ? 1 : 0);
  /* Set colors and draw the background */
  LCD_SetBkColor(pObj->aBkColor[ColorIndex]);
  LCD_SetColor(pObj->aColor[ColorIndex]);
  GUI_Clear();
  /* Draw the text if necessary */
  rClip.x0 = EffectSize + HBorder;
  rClip.y0 = EffectSize;
  rClip.x1 = WM_GetWindowSizeX(hObj) - EffectSize - HBorder - 1;
  rClip.y1 = WM_GetWindowSizeY(hObj) - EffectSize - 1;
  prOldClip = WM_SetUserClipRect(&rClip);
  if (pObj->hText) {
    const char* pText;
    int Line = 0;
    int xSize       = _GetXSize(hObj, pObj);
    int NumVisLines = _GetNumVisLines(hObj, pObj);
    /* Get the text */
    pText = (const char *)GUI_ALLOC_h2p(pObj->hText);
    /* Set the rectangle for drawing */
    r.x0 = xOff;
    r.y0 = EffectSize;
    r.x1 = xSize + EffectSize + HBorder - 1;
    r.y1 = pObj->Widget.Win.Rect.y1 - pObj->Widget.Win.Rect.y0 + 1;
    /* Use cached position of first visible byte if possible */
    if (ScrollPosY >= pObj->CacheFirstVisibleLine) {
      if (pObj->CacheFirstVisibleByte) {
        pText += pObj->CacheFirstVisibleByte;
        Line   = pObj->CacheFirstVisibleLine;
      }
    }
    if (pObj->Align == GUI_TA_RIGHT) {
      r.x0 += ScrollPosX;
      r.x1 += ScrollPosX;
    }
    /* Do the drawing of the text */
    do {
      /* Cache the position of the first visible byte and the depending line number */
      if (pObj->CacheFirstVisibleLine != ScrollPosY) {
        if (Line == ScrollPosY) {
          pObj->CacheFirstVisibleByte = pText - (const char *)GUI_ALLOC_h2p(pObj->hText);
          pObj->CacheFirstVisibleLine = ScrollPosY;
        }
      }
      /* Draw it */
      if ((Line >= ScrollPosY) && ((Line - ScrollPosY) <= NumVisLines)) {
        _DispString(hObj, pObj, pText, &r);
        r.y0 += FontSizeY;  /* Next line */
      }
      pText += _WrapGetNumBytesToNextLine(hObj, pObj, pText);
      Line++;
    } while (GUI_UC_GetCharCode(pText) && ((Line - ScrollPosY) <= NumVisLines));
  }
  /* Draw cursor if necessary */
  if (WM_HasFocus(hObj)) {
    int CursorSize;
    _GetCursorXY(hObj, pObj, &x, &y);
    CursorSize = _GetCursorSizeX(hObj, pObj, &IsRTL);
    if (IsRTL) {
      r.x0 = x + xOff - CursorSize;

⌨️ 快捷键说明

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