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

📄 multiedit.c

📁 成功移植到s3c44b0开发板上的ucos-ii和lwip
💻 C
📖 第 1 页 / 共 4 页
字号:
*
* 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) {
  if (_IsOverwriteAtThisChar(hObj, pObj)) {
    const char *pText;
    pText  = (const char *)GUI_ALLOC_h2p(pObj->hText);
    pText += pObj->CursorPosByte;
    return _GetCharDistX(pObj, pText);
  } else {
    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;
  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;
      }
    }
    /* 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)) {
    _GetCursorXY(hObj, pObj, &x, &y);
    r.x0 = x + xOff;
    r.y0 = y + yOff;
    r.x1 = r.x0 + _GetCursorSizeX(hObj, pObj) - 1;
    r.y1 = r.y0 + FontSizeY - 1;
    GUI_InvertRect(r.x0, r.y0, r.x1, r.y1);
  }
  WM_SetUserClipRect(prOldClip);
  /* Draw the 3D effect (if configured) */
  WIDGET__EFFECT_DrawDown(&pObj->Widget);
}

/*********************************************************************
*
*       _OnTouch
*/
static void _OnTouch(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj, WM_MESSAGE*pMsg) {
  int Notification;
  const GUI_PID_STATE* pState = (const GUI_PID_STATE*)pMsg->Data.p;
  if (pMsg->Data.p) {  /* Something happened in our area (pressed or released) */
    if (pState->Pressed) {
      int Effect, xPos, yPos;
      Effect = pObj->Widget.pEffect->EffectSize;
      xPos   = pState->x + pObj->ScrollStateH.v - Effect - pObj->HBorder;
      yPos   = pState->y + pObj->ScrollStateV.v * GUI_GetYDistOfFont(pObj->pFont) - Effect;
      _SetCursorXY(hObj, pObj, xPos, yPos);
      _Invalidate(hObj);
      Notification = WM_NOTIFICATION_CLICKED;
    } else {
      Notification = WM_NOTIFICATION_RELEASED;
    }
  } else {
    Notification = WM_NOTIFICATION_MOVED_OUT;
  }
  WM_NotifyParent(hObj, Notification);
}

/*********************************************************************
*
*       _AddKey
*
* Returns: 1 if Key has been consumed
*          0 else 
*/
static int _AddKey(MULTIEDIT_HANDLE hObj, U16 Key) {
  int r = 0;               /* Key has not been consumed */
  MULTIEDIT_OBJ* pObj;
  pObj = MULTIEDIT_H2P(hObj);
  switch (Key) {
  case GUI_KEY_UP:
    _MoveCursorUp(hObj, pObj);
    r = 1;               /* Key has been consumed */
    break;
  case GUI_KEY_DOWN:
    _MoveCursorDown(hObj, pObj);
    r = 1;               /* Key has been consumed */
    break;
  case GUI_KEY_RIGHT:
    _SetCursorPos(hObj, pObj, pObj->CursorPosChar + 1);
    r = 1;               /* Key has been consumed */
    break;
  case GUI_KEY_LEFT:
    _SetCursorPos(hObj, pObj, pObj->CursorPosChar - 1);
    r = 1;               /* Key has been consumed */
    break;
  case GUI_KEY_END:
    _MoveCursor2LineEnd(hObj, pObj);
    r = 1;               /* Key has been consumed */
    break;
  case GUI_KEY_HOME:
    _MoveCursor2LinePos1(hObj, pObj);
    r = 1;               /* Key has been consumed */
    break;
  case GUI_KEY_BACKSPACE:
    if (!(pObj->Flags & MULTIEDIT_SF_READONLY)) {
      if (pObj->CursorPosChar > pObj->NumCharsPrompt) {
        _SetCursorPos(hObj, pObj, pObj->CursorPosChar - 1);
        _DeleteChar(hObj, pObj);
      }
      r = 1;               /* Key has been consumed */
    }
    break;
  case GUI_KEY_DELETE:
    if (!(pObj->Flags & MULTIEDIT_SF_READONLY)) {
      _DeleteChar(hObj, pObj);
      r = 1;               /* Key has been consumed */
    }
    break;
  case GUI_KEY_INSERT:
    if (!(pObj->Flags & MULTIEDIT_CF_INSERT)) {
      pObj->Flags |= MULTIEDIT_CF_INSERT;
    } else {
      pObj->Flags &= ~MULTIEDIT_CF_INSERT;
    }
    r = 1;               /* Key has been consumed */
    break;
  case GUI_KEY_ENTER:
    if (pObj->Flags & MULTIEDIT_SF_READONLY) {
      _MoveCursor2NextLine(hObj, pObj);
    } else {
      if (_InsertChar(hObj, pObj, (U8)('\n'))) {
        if (pObj->Flags & MULTIEDIT_SF_PASSWORD) {
          _SetCursorPos(hObj, pObj, pObj->CursorPosChar + 1);
        } else {
          _MoveCursor2NextLine(hObj, pObj);
        }
      }
    }
    r = 1;               /* Key has been consumed */
    break;
  case GUI_KEY_ESCAPE:
    break;
  default:
    if (!(pObj->Flags & MULTIEDIT_SF_READONLY) && (Key >= 0x20)) {
      if (_IsOverwriteAtThisChar(hObj, pObj)) {
        _DeleteChar(hObj, pObj);
      }
      if (_InsertChar(hObj, pObj, Key)) {
        _SetCursorPos(hObj, pObj, pObj->CursorPosChar + 1);
      }
      r = 1;               /* Key has been consumed */
    }
  }
  _InvalidateTextArea(hObj);
  return r;
}

/*********************************************************************
*
*       _MULTIEDIT_Callback
*/
static void _MULTIEDIT_Callback (WM_MESSAGE *pMsg) {
  MULTIEDIT_HANDLE hObj;
  MULTIEDIT_OBJ* pObj;
  WM_SCROLL_STATE ScrollState;
  hObj = pMsg->hWin;
  /* Let widget handle the standard messages */
  if (WIDGET_HandleActive(hObj, pMsg) == 0) {
    return;
  }
  pObj = MULTIEDIT_H2P(hObj);
  switch (pMsg->MsgId) {
  case WM_NOTIFY_CLIENTCHANGE:
    _InvalidateCursorXY(pObj);
    _InvalidateNumLines(pObj);
    _InvalidateTextSizeX(pObj);
    _ClearCache(pObj);
    _CalcScrollParas(hObj);
    break;
  case WM_SIZE:
    _InvalidateCursorXY(pObj);
    _InvalidateNumLines(pObj);
    _InvalidateTextSizeX(pObj);
    _ClearCache(pObj);
    _Invalidate(hObj);
    break;
  case WM_NOTIFY_PARENT:
    switch (pMsg->Data.v) {
    case WM_NOTIFICATION_VALUE_CHANGED:
      if (pMsg->hWinSrc  == WM_GetScrollbarV(hObj)) {
        WM_GetScrollState(pMsg->hWinSrc, &ScrollState);
        pObj->ScrollStateV.v = ScrollState.v;
        WM_InvalidateWindow(hObj);
        WM_NotifyParent(hObj, WM_NOTIFICATION_SCROLL_CHANGED);
      } else if (pMsg->hWinSrc == WM_GetScrollbarH(hObj)) {
        WM_GetScrollState(pMsg->hWinSrc, &ScrollState);
        pObj->ScrollStateH.v = ScrollState.v;
        WM_InvalidateWindow(hObj);
        WM_NotifyParent(hObj, WM_NOTIFICATION_SCROLL_CHANGED);
      }
      break;
    case WM_NOTIFICATION_SCROLLBAR_ADDED:
      _SetScrollState(hObj);
      break;
    }
    break;
  case WM_PAINT:
    _MULTIEDIT_Paint(hObj, pObj);
    return;
  case WM_TOUCH:
    _OnTouch(hObj, pObj, pMsg);
    break;
  case WM_DELETE:
    GUI_ALLOC_FreePtr(&pObj->hText);
    break;
  case WM_KEY:
    if (((const WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt >0) {
      int Key = ((const WM_KEY_INFO*)(pMsg->Data.p))->Key;
      /* Leave code for test purpose
      switch (Key) {
      case '1': Key = GUI_KEY_LEFT;  break;
      case '2': Key = GUI_KEY_UP;    break;
      case '3': Key = GUI_KEY_RIGHT; break;
      case '4': Key = GUI_KEY_DOWN;  break;
      }
      */
      if (_AddKey(hObj, Key)) {
        return;
      }
    } else {
      if (!(pObj->Flags & MULTIEDIT_SF_READONLY)) {
        return;                /* Key release is consumed (not sent to parent) */
      }
    }
  }
  WM_DefaultProc(pMsg);
}

/*********************************************************************
*
*       Exported routines:  Create
*
**********************************************************************
*/

⌨️ 快捷键说明

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