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

📄 multiedit.c

📁 ucgui的3.98版本的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      r.x1 = r.x0 + CursorSize - 1;
    } else {
      r.x0 = x + xOff;
      r.x1 = r.x0 + CursorSize - 1;
    }
    r.y0 = y + yOff;
    r.y1 = r.y0 + FontSizeY - 1;
    if (pObj->Align == GUI_TA_RIGHT) {
      r.x0 += ScrollPosX << 1;
      r.x1 += ScrollPosX << 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;
}

/*********************************************************************
*
*       _SetText
*/
static void _SetText(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ * pObj, const char * pNew) {
  int NumCharsNew, NumCharsOld, NumBytesNew, NumBytesOld;
  char * pText;
  NumCharsNew = NumCharsOld = NumBytesNew = NumBytesOld = 0;
  if (pObj->hText) {
    pText  = (char*) GUI_ALLOC_h2p(pObj->hText);
    pText += GUI_UC__NumChars2NumBytes(pText, pObj->NumCharsPrompt);
    NumCharsOld = GUI__GetNumChars(pText);
    NumBytesOld = GUI_UC__NumChars2NumBytes(pText, NumCharsOld);
  }
  if (pNew) {
    NumCharsNew = GUI__GetNumChars(pNew);
    NumBytesNew = GUI_UC__NumChars2NumBytes(pNew, NumCharsNew);
  }
  if (_IsCharsAvailable(pObj, NumCharsNew - NumCharsOld)) {
    if (_IsSpaceInBuffer(pObj, NumBytesNew - NumBytesOld)) {
      pText  = (char*) GUI_ALLOC_h2p(pObj->hText);
      pText += GUI_UC__NumChars2NumBytes(pText, pObj->NumCharsPrompt);
      if (pNew) {
        strcpy(pText, pNew);
      } else {
        *pText = 0;
      }
      _SetCursorPos(hObj, pObj, pObj->NumCharsPrompt);
      _InvalidateNumChars(pObj);
      _InvalidateNumLines(pObj);
      _InvalidateTextSizeX(pObj);
      _InvalidateTextArea(hObj);
      _InvalidateCursorXY(pObj); /* Invalidate X/Y position */
    }
  }
}

/*********************************************************************
*
*       Private routines
*
**********************************************************************
*/
/*********************************************************************
*
*       MULTIEDIT_h2p
*/
#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL
MULTIEDIT_OBJ* MULTIEDIT_h2p(MULTIEDIT_HANDLE h) {
  MULTIEDIT_OBJ* p = (MULTIEDIT_OBJ*)GUI_ALLOC_h2p(h);
  if (p) {
    if (p->DebugId != MULTIEDIT_ID) {
      GUI_DEBUG_ERROROUT("MULTIEDIT.c: Wrong handle type or Object not init'ed");
      return 0;
    }
  }
  return p;
}
#endif

/*********************************************************************
*
*       Exported routines:  Callback
*
**********************************************************************
*/
/*********************************************************************
*
*       MULTIEDIT_Callback
*/
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_OBJ *)GUI_ALLOC_h2p(hObj); /* Don't use use WIDGET_H2P because WIDGET_INIT_ID() has not be called at this point */
  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:
      #if WIDGET_USE_PARENT_EFFECT
        WIDGET_SetEffect(pMsg->hWinSrc, pObj->Widget.pEffect);
      #endif
      _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
*
**********************************************************************
*/

/* Note: the parameters to a create function may vary.
         Some widgets may have multiple create functions */

/*********************************************************************
*
*       MULTIEDIT_CreateEx
*/
MULTIEDIT_HANDLE MULTIEDIT_CreateEx(int x0, int y0, int xsize, int ysize, WM_HWIN hParent, int WinFlags, int ExFlags,
                                    int Id, int BufferSize, const char* pText)
{
  MULTIEDIT_HANDLE hObj;
  /* Create the window */
  WM_LOCK();
  if ((xsize == 0) && (ysize == 0) && (x0 == 0) && (y0 == 0)) {
    GUI_RECT Rect;
    WM_GetClientRectEx(hParent, &Rect);
    xsize = Rect.x1 - Rect.x0 + 1;
    ysize = Rect.y1 - Rect.y0 + 1;
  }
  hObj = WM_CreateWindowAsChild(x0, y0, xsize, ysize, hParent, WinFlags, &MULTIEDIT_Callback,
                                sizeof(MULTIEDIT_OBJ) - sizeof(WM_Obj));
  if (hObj) {
    int i;
    MULTIEDIT_OBJ * pObj;
    pObj = (MULTIEDIT_OBJ *)GUI_ALLOC_h2p(hObj); /* Don't use use WIDGET_H2P because WIDGET_INIT_ID() has not be called at this point */
    /* init widget specific variables */
    WIDGET__Init(&pObj->Widget, Id, WIDGET_STATE_FOCUSSABLE);
    /* init member variables */
    MULTIEDIT_INIT_ID(pObj);
    for (i = 0; i < NUM_DISP_MODES; i++) {
      pObj->aBkColor[i]  = _aDefaultBkColor[i];
      pObj->aColor[i]    = _aDefaultColor[i];
    }
    pObj->pFont          = _pDefaultFont;
    pObj->Flags          = ExFlags;
    pObj->CursorPosChar  = 0;
    pObj->CursorPosByte  = 0;
    pObj->HBorder        = 1;
    pObj->MaxNumChars    = 0;
    pObj->NumCharsPrompt = 0;
    pObj->BufferSize     = 0;
    pObj->hText          = 0;
    if (BufferSize > 0) {
      WM_HWIN hText;
      if ((hText = GUI_ALLOC_AllocZero(BufferSize)) != 0) {
        pObj->BufferSize = BufferSize;
        pObj->hText      = hText;
      } else {
        GUI_DEBUG_ERROROUT("MULTIEDIT_CreateEx failed to alloc buffer");
        WM_DeleteWindow(hObj);
        hObj = 0;
      }
    }
    MULTIEDIT_SetText(hObj, pText);
    _ManageScrollers(hObj);
  } else {
    GUI_DEBUG_ERROROUT_IF(hObj==0, "MULTIEDIT_CreateEx failed")
  }
  WM_UNLOCK();
  return hObj;
}

/*********************************************************************
*
*       Exported routines:  Various methods
*
**********************************************************************
*/
/*********************************************************************
*
*       MULTIEDIT_AddKey
*/
int MULTIEDIT_AddKey(MULTIEDIT_HANDLE hObj, U16 Key) {
  int r = 0;
  if (hObj) {
    WM_LOCK();
    r = _AddKey(hObj, Key);
    WM_UNLOCK();
  }
  return r;
}

/*********************************************************************
*
*       MULTIEDIT_AddText
*/
int MULTIEDIT_AddText(MULTIEDIT_HANDLE hObj, const char * s) {
  int Result;
  Result = 1;
  if (hObj && s) {
    MULTIEDIT_OBJ * pObj;
    WM_LOCK();
    pObj = MULTIEDIT_H2P(hObj);
    if (!pObj->hText) {
      _SetText(hObj, pObj, s);
    } else {
      char * pText;
      int NumCharsNew, NumCharsOld, NumBytesNew, NumBytesOld;
      pText = (char *)GUI_ALLOC_h2p(pObj->hText);
      NumCharsOld = GUI__GetNumChars(pText);
      NumBytesOld = GUI_UC__NumChars2NumBytes(pText, NumCharsOld);
      NumCharsNew = GUI__GetNumChars(s);
      if (pObj->MaxNumChars > 0) {
        if ((NumCharsOld + NumCharsNew) > pObj->MaxNumChars) {
          NumCharsNew = pObj->MaxNumChars - NumCharsOld;
        }
      }
      if (NumCharsNew > 0) {
        NumBytesNew = GUI_UC__NumChars2NumBytes(s, NumCharsNew);
        if (_IsSpaceInBuffer(pObj, NumBytesNew)) {
          pText = (char *)GUI_ALLOC_h2p(pObj->hText);
          memmove(pText + pObj->CursorPosByte + NumBytesNew, 
                  pText + pObj->CursorPosByte, 
                  NumBytesOld - pObj->CursorPosByte);
          memcpy(pText + pObj->CursorPosByte, s, NumBytesNew);
          *(pText + NumBytesOld + NumBytesNew) = 0;
          pObj->NumChars += NumCharsNew;
          _SetCursorPos(hObj, pObj, pObj->CursorPosChar + NumCharsNew);
          _InvalidateNumLines(pObj);
          _InvalidateTextSizeX(pObj);
          _InvalidateTextArea(hObj);
          _InvalidateCursorXY(pObj);
          _ClearCache(pObj);
          WM_NotifyParent(hObj, WM_NOTIFICATION_VALUE_CHANGED);
          Result = 0;

⌨️ 快捷键说明

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