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

📄 wm.c

📁 成功移植到s3c44b0开发板上的ucos-ii和lwip
💻 C
📖 第 1 页 / 共 4 页
字号:
*
* Detaches the given window. The window still exists, it keeps all
* children, but it is no longer visible since it is taken out of
* the tree of the desktop window.
*/
void WM__DetachWindow(WM_HWIN hWin) {
  WM_Obj* pWin;
  WM_HWIN hParent;
  pWin = WM_H2P(hWin);
  hParent = pWin->hParent;
  if (hParent) {
    WM__RemoveWindowFromList(hWin);
    /* Clear area used by this window */
    WM_InvalidateArea(&pWin->Rect);
    pWin->hParent = 0;
  }
}


/*********************************************************************
*
*       _DeleteAllChildren
*/
static void _DeleteAllChildren(WM_HWIN hChild) {
  while (hChild) {
    WM_Obj* pChild = WM_H2P(hChild);
    WM_HWIN hNext = pChild->hNext;
    WM_DeleteWindow(hChild);
    hChild = hNext;
  }
}

/*********************************************************************
*
*             Module internal routines
*
**********************************************************************
*/
/*********************************************************************
*
*       WM__Client2Screen
*/
void WM__Client2Screen(const WM_Obj* pWin, GUI_RECT *pRect) {
  GUI_MoveRect(pRect, pWin->Rect.x0, pWin->Rect.y0);
}

/*********************************************************************
*
*       WM__IsWindow
*/
int WM__IsWindow(WM_HWIN hWin) {
  WM_HWIN iWin;
  for (iWin = WM__FirstWin; iWin; iWin = WM_H2P(iWin)->hNextLin) {
    if (iWin == hWin) {
      return 1;
    }
  }
  return 0;
}

/*********************************************************************
*
*         WM__InvalidateAreaBelow

  Params: pRect  Rectangle in Absolute coordinates
*/
void WM__InvalidateAreaBelow(const GUI_RECT* pRect, WM_HWIN StopWin) {
  GUI_USE_PARA(StopWin);
  WM_InvalidateArea(pRect);      /* Can be optimized to spare windows above */
}

/*********************************************************************
*
*       WM_RemoveFromLinList
*/
void WM__RemoveFromLinList(WM_HWIN hWin) {
  WM_Obj* piWin;
  WM_HWIN hiWin;
  WM_HWIN hNext;
  for (hiWin = WM__FirstWin; hiWin; ) {
    piWin = WM_H2P(hiWin);
    hNext = piWin->hNextLin;
    if (hNext == hWin) {
      piWin->hNextLin = WM_H2P(hWin)->hNextLin;
      break;
    }
    hiWin = hNext;
  }
}

/*********************************************************************
*
*       _AddToLinList
*/
static void _AddToLinList(WM_HWIN hNew) {
  WM_Obj* pFirst;
  WM_Obj* pNew;
  if (WM__FirstWin) {
    pFirst = WM_H2P(WM__FirstWin);
    pNew   = WM_H2P(hNew);
    pNew->hNextLin = pFirst->hNextLin;
    pFirst->hNextLin = hNew;
  } else {
    WM__FirstWin = hNew;
  }
}

/*********************************************************************
*
*       WM__RectIsNZ
*
   Check if the rectangle has some content (is non-zero)
   Returns 0 if the Rectangle has no content, else 1.
*/
int WM__RectIsNZ(const GUI_RECT* pr) {
  if (pr->x0 > pr->x1)
    return 0;
  if (pr->y0 > pr->y1)
    return 0;
  return 1;
}

/*********************************************************************
*
*        _Findy1
*
*/
static void _Findy1(WM_HWIN iWin, GUI_RECT* pRect, GUI_RECT* pParentRect) {
  WM_Obj* pWin;
  for (; iWin; iWin = pWin->hNext) { 
    int Status = (pWin = WM_H2P(iWin))->Status;
    /* Check if this window affects us at all */    
    if (Status & WM_SF_ISVIS) {
      GUI_RECT rWinClipped;               /* Window rect, clipped to part inside of ancestors */
      if (pParentRect) {
        GUI__IntersectRects(&rWinClipped, &pWin->Rect, pParentRect);
      } else {
        rWinClipped = pWin->Rect;
      }
      /* Check if this window affects us at all */    
      if (GUI_RectsIntersect(pRect, &rWinClipped)) {
        if ((Status & WM_SF_HASTRANS) == 0) {
          if (pWin->Rect.y0 > pRect->y0) {
            ASSIGN_IF_LESS(pRect->y1, rWinClipped.y0 - 1);      /* Check upper border of window */
          } else {
            ASSIGN_IF_LESS(pRect->y1, rWinClipped.y1);        /* Check lower border of window */
          }
        } else {
          /* Check all children*/ 
          WM_HWIN hChild;
          WM_Obj* pChild;
          for (hChild = pWin->hFirstChild; hChild; hChild = pChild->hNext) {
            pChild = WM_H2P(hChild);
            _Findy1(hChild, pRect, &rWinClipped);
          }
        }
      }
    }
  }
}

/*********************************************************************
*
*        _Findx0
*/
static int _Findx0(WM_HWIN hWin, GUI_RECT* pRect, GUI_RECT* pParentRect) {
  WM_Obj* pWin;
  int r = 0;
  for (; hWin; hWin = pWin->hNext) { 
    int Status = (pWin = WM_H2P(hWin))->Status;
    if (Status & WM_SF_ISVIS) {           /* If window is not visible, it can be safely ignored */
      GUI_RECT rWinClipped;               /* Window rect, clipped to part inside of ancestors */
      if (pParentRect) {
        GUI__IntersectRects(&rWinClipped, &pWin->Rect, pParentRect);
      } else {
        rWinClipped = pWin->Rect;
      }
      /* Check if this window affects us at all */    
      if (GUI_RectsIntersect(pRect, &rWinClipped)) {
        if ((Status & WM_SF_HASTRANS) == 0) {
          pRect->x0 = rWinClipped.x1+1;
          r = 1;
        } else {
          /* Check all children */
          WM_HWIN hChild;
          WM_Obj* pChild;
          for (hChild = pWin->hFirstChild; hChild; hChild = pChild->hNext) {
            pChild = WM_H2P(hChild);
            if (_Findx0(hChild, pRect, &rWinClipped)) {
              r = 1;
            }
          }
        }
      }
    }
  }
  return r;
}

/*********************************************************************
*
*        _Findx1
*/
static void _Findx1(WM_HWIN hWin, GUI_RECT* pRect, GUI_RECT* pParentRect) {
  WM_Obj* pWin;
  for (; hWin; hWin = pWin->hNext) { 
    int Status = (pWin = WM_H2P(hWin))->Status;
    if (Status & WM_SF_ISVIS) {           /* If window is not visible, it can be safely ignored */
      GUI_RECT rWinClipped;               /* Window rect, clipped to part inside of ancestors */
      if (pParentRect) {
        GUI__IntersectRects(&rWinClipped, &pWin->Rect, pParentRect);
      } else {
        rWinClipped = pWin->Rect;
      }
      /* Check if this window affects us at all */    
      if (GUI_RectsIntersect(pRect, &rWinClipped)) {
        if ((Status & WM_SF_HASTRANS) == 0) {
          pRect->x1 = rWinClipped.x0-1;
        } else {
          /* Check all children */
          WM_HWIN hChild;
          WM_Obj* pChild;
          for (hChild = pWin->hFirstChild; hChild; hChild = pChild->hNext) {
            pChild = WM_H2P(hChild);
            _Findx1(hChild, pRect, &rWinClipped);
          }
        }
      }
    }
  }
}

/*********************************************************************
*
*       Sending messages
*
**********************************************************************
*/
/*********************************************************************
*
*       WM_SendMessage
*/
void WM_SendMessage(WM_HWIN hWin, WM_MESSAGE* pMsg) {
  if (hWin) {
    WM_Obj* pWin;
    WM_LOCK();
    pWin = WM_H2P(hWin);
    if (pWin->cb != NULL) {
      pMsg->hWin = hWin;
      (*pWin->cb)(pMsg);
    }
    WM_UNLOCK();
  }
}

/*********************************************************************
*
*       WM__SendMsgNoData
*/
void WM__SendMsgNoData(WM_HWIN hWin, U8 MsgId) {
  WM_MESSAGE Msg;
  Msg.hWin  = hWin;
  Msg.MsgId = MsgId;
  WM_SendMessage(hWin, &Msg);
}

/*********************************************************************
*
*       WM__GetClientRectWin
*
  Get client rectangle in windows coordinates. This means that the
  upper left corner is always at (0,0). 
*/
void WM__GetClientRectWin(const WM_Obj* pWin, GUI_RECT* pRect) {
  pRect->x0 = pRect->y0 = 0;
  pRect->x1 = pWin->Rect.x1 - pWin->Rect.x0;
  pRect->y1 = pWin->Rect.y1 - pWin->Rect.y0;
}

/*********************************************************************
*
*       WM__GetInvalidRectAbs
*/
static void WM__GetInvalidRectAbs(WM_Obj* pWin, GUI_RECT* pRect) {
  *pRect = pWin->InvalidRect;
}

/*********************************************************************
*
*       Invalidation functions
*
**********************************************************************
*/
/*********************************************************************
*
*       WM_InvalidateRect
*
*  Invalidate a section of the window. The optional rectangle
*  contains client coordinates, which are independent of the
*  position of the window on the logical desktop area.
*/
void WM_InvalidateRect(WM_HWIN hWin, const GUI_RECT*pRect) {
  GUI_RECT r;
  WM_Obj* pWin;
  int Status;
  if (hWin) {
    WM_LOCK();
    pWin = WM_H2P(hWin);
    Status = pWin->Status;
    if (Status & WM_SF_ISVIS) {
      r = pWin->Rect;
      if (pRect) {
        GUI_RECT rPara;
        rPara = *pRect;
        WM__Client2Screen(pWin, &rPara);
        GUI__IntersectRect(&r, &rPara);
      }
      if (WM__ClipAtParentBorders(&r, hWin)) {      /* Optimization that saves invalidation if window area is not visible ... Not required */
        if ((Status & (WM_SF_HASTRANS | WM_SF_CONST_OUTLINE)) == WM_SF_HASTRANS) {
          WM__InvalidateAreaBelow(&r, hWin);        /* Can be optimized to spare windows above */
        } else {
          _Invalidate1Abs(hWin, &r);
        }
      }
    }
    WM_UNLOCK();
  }
}

/*********************************************************************
*
*        WM_InvalidateWindow
*
  Invalidates an entire window.
*/
void WM_InvalidateWindow(WM_HWIN hWin) {
  WM_InvalidateRect(hWin, NULL);
}

/*********************************************************************
*
*        WM_InvalidateArea

  Invalidate a certain section of the display. One main reason for this is
  that the top window has been moved or destroyed.
  The coordinates given are absolute coordinates (desktop coordinates)
*/
void WM_InvalidateArea(const GUI_RECT* pRect) {
  WM_HWIN   hWin;
  WM_LOCK();
  /* Iterate over all windows */
  for (hWin = WM__FirstWin; hWin; hWin = WM_H2P(hWin)->hNextLin) {
    _Invalidate1Abs(hWin, pRect);
  }
  WM_UNLOCK();
}

/*********************************************************************
*
*       manage windows stack
*
**********************************************************************
*/
/*********************************************************************
*
*       WM_CreateWindowAsChild
*/
WM_HWIN WM_CreateWindowAsChild( int x0, int y0, int width, int height
                               ,WM_HWIN hParent, U16 Style, WM_CALLBACK* cb
                               ,int NumExtraBytes) {
  WM_Obj* pWin;
  WM_HWIN hWin;
  WM_ASSERT_NOT_IN_PAINT();
  WM_LOCK();
  Style |= WM__CreateFlags;
  /* Default parent is Desktop 0 */
  if (!hParent) {
    if (WM__NumWindows) {
    #if GUI_NUM_LAYERS == 1
      hParent = WM__ahDesktopWin[0];
    #else
      hParent = WM__ahDesktopWin[GUI_Context.SelLayer];
    #endif
    }
  }
  if (hParent == WM_UNATTACHED) {
    hParent = WM_HWIN_NULL;
  }  
  if (hParent) {
    WM_Obj* pParent = WM_H2P(hParent);
    x0 += pParent->Rect.x0;
    y0 += pParent->Rect.y0;
    if (width==0) {
      width = pParent->Rect.x1 - pParent->Rect.x0+1;
    }
    if (height==0) {
      height = pParent->Rect.y1 - pParent->Rect.y0+1;
    }
  }
  if ((hWin = (WM_HWIN) GUI_ALLOC_AllocZero(NumExtraBytes + sizeof(WM_Obj))) == 0) {
    GUI_DEBUG_ERROROUT("WM_CreateWindow: No memory to create window");
  } else {
    WM__NumWindows++;
    pWin = WM_H2P(hWin);
    pWin->Rect.x0 = x0;
    pWin->Rect.y0 = y0;
    pWin->Rect.x1 = x0 + width - 1;
    pWin->Rect.y1 = y0 + height - 1;
    pWin->cb = cb;
    /* Copy the flags which can simply be accepted */
    pWin->Status |= (Style & (WM_CF_SHOW |
                              WM_SF_MEMDEV |
                              WM_CF_MEMDEV_ON_REDRAW |
                              WM_SF_STAYONTOP |
                              WM_SF_CONST_OUTLINE |
                              WM_SF_HASTRANS |
                              WM_CF_ANCHOR_RIGHT |
                              WM_CF_ANCHOR_BOTTOM |
                              WM_CF_ANCHOR_LEFT |
                              WM_CF_ANCHOR_TOP |
                              WM_CF_LATE_CLIP));
    /* Add to linked lists */
    _AddToLinList(hWin);
    WM__InsertWindowIntoList(hWin, hParent);
    /* Activate window if WM_CF_ACTIVATE is specified */
    if (Style & WM_CF_ACTIVATE) {
      WM_SelectWindow(hWin);  /* This is not needed if callbacks are being used, but it does not cost a lot and makes life easier ... */
    }
    /* Handle the Style flags, one at a time */
    #if WM_SUPPORT_TRANSPARENCY
      if (Style & WM_SF_HASTRANS) {
        WM__TransWindowCnt++;          /* Increment counter for transparency windows */
      }
    #endif

⌨️ 快捷键说明

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