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

📄 multiedit.c

📁 ucgui的3.98版本的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      } else {
        int xSize;
        const char *p;
        int NumChars = 0, NumCharsToNextLine;
        xSize = _GetXSize(hObj, pObj);
        p = pLine;
        while (pLine < pCursor) {
          NumChars++;
          pLine += GUI_UC_GetCharSize(pLine);
        }
        NumCharsToNextLine = _WrapGetNumCharsDisp(hObj, pObj, p);
        x = GUI__GetCursorPosX(p, NumChars, NumCharsToNextLine);
        if (pObj->Align == GUI_TA_RIGHT) {
          x += xSize - GUI__GetLineDistX(p, NumCharsToNextLine);
        }
      }
    }
    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:
*   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 */
  if (pObj->Align == GUI_TA_RIGHT) {
    xCursor = _GetXSize(hObj, pObj) - xCursor;
  }
  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;
        if (pObj->Flags & MULTIEDIT_SF_PASSWORD) {
          while (NumChars--) {
            xSizeLine += _GetCharDistX(pObj, pLine);
            pLine     += GUI_UC_GetCharSize(pLine);
          }
        } else {
          xSizeLine += GUI__GetLineDistX(pLine, NumChars);
        }
        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++;
      }
    }
    if (pObj->Align == GUI_TA_RIGHT) {
      x -= _GetXSize(hObj, pObj) - GUI__GetLineDistX(pLine, WrapChars);
      x -= pObj->ScrollStateH.v << 1;
      if (x < 0) {

⌨️ 快捷键说明

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