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

📄 multiedit.c

📁 成功移植到s3c44b0开发板上的ucos-ii和lwip
💻 C
📖 第 1 页 / 共 4 页
字号:
*   Find out if the current position of the cursor is still in the
*   visible area. If it is not, the scroll position is updated.
*   Needs to be called every time the cursor is move, wrap, font or
*   window size are changed.
*/
static void _CalcScrollPos(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
  int xCursor, yCursor;
  _GetCursorXY(hObj, pObj, &xCursor, &yCursor);
  yCursor /= GUI_GetYDistOfFont(pObj->pFont);
  WM_CheckScrollPos(&pObj->ScrollStateV, yCursor, 0, 0);       /* Vertical */
  WM_CheckScrollPos(&pObj->ScrollStateH, xCursor, 30, 30);     /* Horizontal */
  _SetScrollState(hObj);
}

/*********************************************************************
*
*       _GetTextSizeX
*
* Returns the width of the displayed text.
*/
static int _GetTextSizeX(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
  if (pObj->InvalidFlags & INVALID_TEXTSIZE) {
    pObj->TextSizeX = 0;
    if (pObj->hText) {
      int NumChars, xSizeLine;
      char *pText, *pLine;
      GUI_SetFont(pObj->pFont);
      pText = (char*) GUI_ALLOC_h2p(pObj->hText);
      do {
        NumChars = _WrapGetNumCharsDisp(hObj, pObj, pText);
        xSizeLine = 0;
        pLine = pText;
        while (NumChars--) {
          xSizeLine += _GetCharDistX(pObj, pLine);
          pLine     += GUI_UC_GetCharSize(pLine);
        }
        if (xSizeLine > pObj->TextSizeX) {
          pObj->TextSizeX = xSizeLine;
        }
        pText += _WrapGetNumBytesToNextLine(hObj, pObj, pText);
      } while (*pText);
    }
    pObj->InvalidFlags &= ~INVALID_TEXTSIZE;
  }
  return pObj->TextSizeX;
}

/*********************************************************************
*
*       _GetNumVisLines
*/
static int _GetNumVisLines(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ* pObj) {
  GUI_RECT Rect;
  WM_GetInsideRectExScrollbar(hObj, &Rect);
  return (Rect.y1 - Rect.y0 + 1) / GUI_GetYDistOfFont(pObj->pFont);
}

/*********************************************************************
*
*       _GetNumLines
*
* Calculates (if needed) and returns the number of lines
*/
static int _GetNumLines(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ * pObj) {
  if (pObj->InvalidFlags & INVALID_NUMLINES) {
    int NumLines = 0;
    if (pObj->hText) {
      int NumChars, NumBytes;
      char *pText;
      U16 Char;
      pText = (char*) GUI_ALLOC_h2p(pObj->hText);
      GUI_SetFont(pObj->pFont);
      do {
        NumChars = _WrapGetNumCharsDisp(hObj, pObj, pText);
        NumBytes = GUI_UC__NumChars2NumBytes(pText, NumChars);
        Char     = GUI_UC_GetCharCode(pText + NumBytes);
        if (Char) {
          NumLines++;
        }
        pText += _WrapGetNumBytesToNextLine(hObj, pObj, pText);
      } while (Char);
    }
    pObj->NumLines = NumLines + 1;
    pObj->InvalidFlags &= ~INVALID_NUMLINES;
  }
  return pObj->NumLines;
}

/*********************************************************************
*
*       _InvalidateNumLines
*
* Invalidates the number of lines
*/
static void _InvalidateNumLines(MULTIEDIT_OBJ * pObj) {
  pObj->InvalidFlags |= INVALID_NUMLINES;
}

/*********************************************************************
*
*       _InvalidateTextSizeX
*
* Calculates the TextSizeX
*/
static void _InvalidateTextSizeX(MULTIEDIT_OBJ * pObj) {
  pObj->InvalidFlags |= INVALID_TEXTSIZE;
}

/*********************************************************************
*
*       _CalcScrollParas
*
* Purpose:
*   Calculate page size ,number of items & position
*/
static void _CalcScrollParas(MULTIEDIT_HANDLE hObj) {
  MULTIEDIT_OBJ* pObj = MULTIEDIT_H2P(hObj);
  /* Calc vertical scroll parameters */
  pObj->ScrollStateV.NumItems = _GetNumLines(hObj, pObj);
  pObj->ScrollStateV.PageSize = _GetNumVisLines(hObj, pObj);
  /* Calc horizontal scroll parameters */
  pObj->ScrollStateH.NumItems = _GetTextSizeX(hObj, pObj);
  pObj->ScrollStateH.PageSize = _GetXSize(hObj, pObj);
  _CalcScrollPos(hObj, pObj);
}

/*********************************************************************
*
*       _ManageAutoScrollV
*/
static void _ManageAutoScrollV(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
  if (pObj->Flags & MULTIEDIT_SF_AUTOSCROLLBAR_V) {
    char IsRequired = _GetNumVisLines(hObj, pObj) < _GetNumLines(hObj, pObj);
    if (WM_SetScrollbarV(hObj, IsRequired) != IsRequired) {
      _InvalidateNumLines(pObj);
      _InvalidateTextSizeX(pObj);
      _InvalidateCursorXY(pObj);
      _ClearCache(pObj);
    }
  }
}

/*********************************************************************
*
*       _ManageScrollers
*
* Function:
* If autoscroll mode is enabled, add or remove the horizonatal and
* vertical scrollbars as required.
* Caution: This routine should not be called as reaction to a message
* From the child, as this could lead to a recursion problem
*/
static void _ManageScrollers(MULTIEDIT_HANDLE hObj) {
  MULTIEDIT_OBJ* pObj;
  pObj = MULTIEDIT_H2P(hObj);
  /* 1. Step: Check if vertical scrollbar is required */
  _ManageAutoScrollV(hObj, pObj);
  /* 2. Step: Check if horizontal scrollbar is required */
  if (pObj->Flags & MULTIEDIT_SF_AUTOSCROLLBAR_H) {
    char IsRequired;
    IsRequired = (_GetXSize(hObj, pObj) < _GetTextSizeX(hObj, pObj));
    if (WM_SetScrollbarH(hObj, IsRequired) != IsRequired) {
      /* 3. Step: Check vertical scrollbar again if horizontal has changed */
      _ManageAutoScrollV(hObj, pObj);
    }
  }
  _CalcScrollParas(hObj);
}

/*********************************************************************
*
*       _Invalidate
*/
static void _Invalidate(MULTIEDIT_HANDLE hObj) {
  _ManageScrollers(hObj);
  WM_Invalidate(hObj);
}

/*********************************************************************
*
*       _InvalidateTextArea
*
* Invalidates the text area only
*/
static void _InvalidateTextArea(MULTIEDIT_HANDLE hObj) {
  GUI_RECT rInsideRect;
  _ManageScrollers(hObj);
  WM_GetInsideRectExScrollbar(hObj, &rInsideRect);
  WM_InvalidateRect(hObj, &rInsideRect);
}

/*********************************************************************
*
*       _InvalidateCursorPos
*
* Sets the position of the cursor to an invalid value
*/
static int _InvalidateCursorPos(MULTIEDIT_OBJ * pObj) {
  int Value;
  Value = pObj->CursorPosChar;
  pObj->CursorPosChar = 0xffff;
  return Value;
}

/*********************************************************************
*
*       _SetFlag
*/
static void _SetFlag(MULTIEDIT_HANDLE hObj, int OnOff, U8 Flag) {
  if (hObj) {
    MULTIEDIT_OBJ * pObj;
    WM_LOCK();
    pObj = MULTIEDIT_H2P(hObj);
    if (OnOff) {
      pObj->Flags |= Flag;
    } else {
      pObj->Flags &= ~Flag;
    }
    _InvalidateTextArea(hObj);
    WM_UNLOCK();
  }
}

/*********************************************************************
*
*       _CalcNextValidCursorPos
*
* Purpose:
*   Calculates the next valid cursor position of the desired position.
*
* Parameters:
*   hObj, pObj    : Obvious
*   CursorPosChar : New character position of the cursor
*   pCursorPosByte: Pointer to save the cursorposition in bytes. Used to abolish further calculations. Could be 0.
*   pCursorLine   : Pointer to save the line number of the cursor. Used to abolish further calculations. Could be 0.
*/
static int _CalcNextValidCursorPos(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj, int CursorPosChar, int * pCursorPosByte, int * pCursorLine) {
  if (pObj->hText) {
    char *pNextLine, *pCursor, *pText;
    int CursorLine, NumChars, CursorPosByte;
    pText    = (char*) GUI_ALLOC_h2p(pObj->hText);
    NumChars = _GetNumChars(pObj);
    /* Set offset in valid range */
    if (CursorPosChar < pObj->NumCharsPrompt) {
      CursorPosChar = pObj->NumCharsPrompt;
    }
    if (CursorPosChar > NumChars) {
      CursorPosChar = NumChars;
    }
    CursorPosByte = GUI_UC__NumChars2NumBytes(pText, CursorPosChar);
    CursorLine    = _GetCursorLine(hObj, pObj, pText, CursorPosChar);
    pCursor       = pText + CursorPosByte;
    pNextLine     = _GetpLine(hObj, pObj, CursorLine);
    if (pNextLine > pCursor) {
      if (pObj->CursorPosChar < CursorPosChar) {
        pCursor = pNextLine;
      } else {
        char *pPrevLine;
        int NumChars;
        pPrevLine  = _GetpLine(hObj, pObj, CursorLine - 1);
        NumChars   = _WrapGetNumCharsDisp(hObj, pObj, pPrevLine);
        pPrevLine += GUI_UC__NumChars2NumBytes(pPrevLine, NumChars);
        pCursor = pPrevLine;
      }
      CursorPosChar = GUI_UC__NumBytes2NumChars(pText, pCursor - pText);
      CursorPosByte = GUI_UC__NumChars2NumBytes(pText, CursorPosChar);
      CursorLine    = _GetCursorLine(hObj, pObj, pText, CursorPosChar);
    }
    if (pCursorPosByte) {
      *pCursorPosByte = CursorPosByte;
    }
    if (pCursorLine) {
      *pCursorLine = CursorLine;
    }
    return CursorPosChar;
  }
  return 0;
}

/*********************************************************************
*
*       _SetCursorPos
*
* Sets a new cursor position.
*/
static void _SetCursorPos(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj, int CursorPosChar) {
  int CursorPosByte, CursorLine;
  CursorPosChar = _CalcNextValidCursorPos(hObj, pObj, CursorPosChar, &CursorPosByte, &CursorLine);
  /* Assign value and recalc whatever necessary */
  if (pObj->CursorPosChar != CursorPosChar) {
    /* Save values */
    pObj->CursorPosByte = CursorPosByte;
    pObj->CursorPosChar = CursorPosChar;
    pObj->CursorLine = CursorLine;
    _InvalidateCursorXY(pObj); /* Invalidate X/Y position */
    _CalcScrollPos(hObj, pObj);
  }
}

/*********************************************************************
*
*       _SetWrapMode
*/
static int _SetWrapMode(MULTIEDIT_HANDLE hObj, GUI_WRAPMODE WrapMode) {
  int r;
  r = 0;
  if (hObj) {
    MULTIEDIT_OBJ * pObj;
    WM_LOCK();
    pObj = MULTIEDIT_H2P(hObj);
    r = pObj->WrapMode;
    if (pObj->WrapMode != WrapMode) {
      int Position;
      pObj->WrapMode = WrapMode;
      _ClearCache(pObj);
      _InvalidateNumLines(pObj);
      _InvalidateTextSizeX(pObj);
      _InvalidateTextArea(hObj);
      Position = _InvalidateCursorPos(pObj);
      _SetCursorPos(hObj, pObj, Position);
    }
    WM_UNLOCK();
  }
  return r;
}

/*********************************************************************
*
*       _SetCursorXY
*
* Sets the cursor position from window coordinates.
*/
static void _SetCursorXY(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj, int x, int y) {
  int CursorPosChar = 0;
  if ((x < 0) || (y < 0)) {
    return;
  }
  if (pObj->hText) {
    char *pLine, *pText;
    int CursorLine, WrapChars;
    int SizeX = 0;
    U16 Char;
    GUI_SetFont(pObj->pFont);
    CursorLine = y / GUI_GetFontDistY();
    pLine      = _GetpLine(hObj, pObj, CursorLine);
    pText      = (char*) GUI_ALLOC_h2p(pObj->hText);
    WrapChars  = _WrapGetNumCharsDisp(hObj, pObj, pLine);
    Char       = GUI_UC__GetCharCode(pLine + GUI_UC__NumChars2NumBytes(pLine, WrapChars));
    if (pObj->Flags & MULTIEDIT_SF_PASSWORD) {
      if (!Char) {
        WrapChars++;
      }
    } else {
      if (!Char || (Char == '\n') || ((Char == ' ') && (pObj->WrapMode == GUI_WRAPMODE_WORD))) {
        WrapChars++;
      }
    }
    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);
  }
  _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

⌨️ 快捷键说明

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