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

📄 wm.c

📁 成功移植到s3c44b0开发板上的ucos-ii和lwip
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (Style & WM_CF_BGND) {
      WM_BringToBottom(hWin);
    }
    if (Style & WM_CF_SHOW) {
      pWin->Status |= WM_SF_ISVIS;  /* Set Visibility flag */
      WM_InvalidateWindow(hWin);    /* Mark content as invalid */
    }
    WM__SendMsgNoData(hWin, WM_CREATE);
  }
  WM_UNLOCK();
  return hWin;
}

/*********************************************************************
*
*       WM_CreateWindow
*/
WM_HWIN WM_CreateWindow(int x0, int y0, int width, int height, U16 Style, WM_CALLBACK* cb, int NumExtraBytes) {
  return WM_CreateWindowAsChild(x0,y0,width,height, 0 /* No parent */,  Style, cb, NumExtraBytes);
}

/*********************************************************************
*
*       Delete window
*
**********************************************************************
*/
/*********************************************************************
*
*       WM_DeleteWindow
*/
void WM_DeleteWindow (WM_HWIN hWin) {
  WM_Obj* pWin;
  if (!hWin) {
    return;
  }
  WM_ASSERT_NOT_IN_PAINT();
  WM_LOCK();
  if (WM__IsWindow(hWin)) {
    pWin = WM_H2P(hWin);
    ResetNextDrawWin();              /* Make sure the window will no longer receive drawing messages */
  /* Make sure that focus is set to an existing window */
    if (WM__hWinFocus == hWin) {
      WM__hWinFocus = 0;
    }
    if (WM__hCapture == hWin) {
      WM__hCapture = 0;
    }
    /* check if critical handles are affected. If so, reset the window handle to 0 */
    _CheckCriticalHandles(hWin);
    /* Inform parent */
    WM_NotifyParent(hWin, WM_NOTIFICATION_CHILD_DELETED);
    /* Delete all children */
    _DeleteAllChildren(pWin->hFirstChild);
    #if WM_SUPPORT_NOTIFY_VIS_CHANGED
      WM__SendMsgNoData(hWin, WM_NOTIFY_VIS_CHANGED);             /* Notify window that visibility may have changed */
    #endif
    /* Send WM_DELETE message to window in order to inform window itself */
    WM__SendMsgNoData(hWin, WM_DELETE);     /* tell window about it */
    WM__DetachWindow(hWin);
    /* Remove window from window stack */
    WM__RemoveFromLinList(hWin);
    /* Handle transparency counter if necessary */
    #if WM_SUPPORT_TRANSPARENCY
      if (pWin->Status & WM_SF_HASTRANS) {
        WM__TransWindowCnt--;
      }
    #endif
    /* Make sure window is no longer counted as invalid */
    if (pWin->Status & WM_SF_INVALID) {
      WM__NumInvalidWindows--;
    }
  /* Free window memory */
    WM__NumWindows--;
    GUI_ALLOC_Free(hWin);
  /* Select a valid window */
    WM_SelectWindow(WM__FirstWin);
  } else {
    GUI_DEBUG_WARN("WM_DeleteWindow: Invalid handle");
  }
  WM_UNLOCK();
}

/*********************************************************************
*
*       WM_SelectWindow
*
*  Sets the active Window. The active Window is the one that is used for all
*  drawing (and text) operations.
*/
WM_HWIN WM_SelectWindow(WM_HWIN  hWin) {
  WM_HWIN hWinPrev;
  WM_Obj* pObj;

  WM_ASSERT_NOT_IN_PAINT();
  WM_LOCK();
  hWinPrev = GUI_Context.hAWin;
  if (hWin == 0) {
    hWin = WM__FirstWin;
  }
  /* Select new window */
  GUI_Context.hAWin = hWin;
  #if GUI_NUM_LAYERS > 1
  {
    WM_HWIN hTop;
    int LayerIndex;
    hTop = _GetTopLevelWindow(hWin);
    LayerIndex = _DesktopHandle2Index(hTop);
    if (LayerIndex >= 0) {
      GUI_SelectLayer(LayerIndex);
    }
  }
  #endif
  pObj = WM_H2P(hWin);
  LCD_SetClipRectMax();             /* Drawing operations will clip ... If WM is deactivated, allow all */
  GUI_Context.xOff = pObj->Rect.x0;
  GUI_Context.yOff = pObj->Rect.y0;
  WM_UNLOCK();
  return hWinPrev;
}

/*********************************************************************
*
*       WM_GetActiveWindow
*/
WM_HWIN WM_GetActiveWindow(void) {
  return GUI_Context.hAWin;
}


/*********************************************************************
*
*       IVR calculation
*
**********************************************************************

IVRs are invalid rectangles. When redrawing, only the portion of the
window which is
  a) within the window-rectangle
  b) not covered by an other window
  c) marked as invalid
  is actually redrawn. Unfortunately, this section is not always
  rectangular. If the window is partially covered by an other window,
  it consists of the sum of multiple rectangles. In all drawing
  operations, we have to iterate over every one of these rectangles in
  order to make sure the window is drawn completly.
Function works as follows:
  STEP 1: - Set upper left coordinates to next pixel. If end of line (right border), goto next line -> (r.x0, r.y0)
  STEP 2: - Check if we are done, return if we are.
  STEP 3: - If we are at the left border, find max. heigtht (r.y1) by iterating over windows above
  STEP 4: - Find x0 for the given y0, y1 by iterating over windows above
  STEP 5: - If r.x0 out of right border, this stripe is done. Set next stripe and goto STEP 2
  STEP 6: - Find r.x1. We have to Iterate over all windows which are above
*/

/*********************************************************************
*
*       _FindNext_IVR
*/
#if WM_SUPPORT_OBSTRUCT
static int _FindNext_IVR(void) {
  WM_HMEM hParent;
  GUI_RECT r;
  WM_Obj* pAWin;
  WM_Obj* pParent;
  r = _ClipContext.CurRect;  /* temps  so we do not have to work with pointers too much */
  /*
     STEP 1:
       Set the next position which could be part of the next IVR
       This will be the first unhandle pixel in reading order, i.e. next one to the right
       or next one down if we are at the right border.
  */
  if (_ClipContext.Cnt == 0) {       /* First IVR starts in upper left */
    r.x0 = _ClipContext.ClientRect.x0;
    r.y0 = _ClipContext.ClientRect.y0;
  } else {
    r.x0 = _ClipContext.CurRect.x1+1;
    r.y0 = _ClipContext.CurRect.y0;
    if (r.x0 > _ClipContext.ClientRect.x1) {
NextStripe:  /* go down to next stripe */
      r.x0 = _ClipContext.ClientRect.x0;
      r.y0 = _ClipContext.CurRect.y1+1;
    }
  }
  /*
     STEP 2:
       Check if we are done completely.
  */
  if (r.y0 >_ClipContext.ClientRect.y1) {
    return 0;
  }
  /* STEP 3:
       Find out the max. height (r.y1) if we are at the left border.
       Since we are using the same height for all IVRs at the same y0,
       we do this only for the leftmost one.
  */
  pAWin = WM_H2P(GUI_Context.hAWin);
  if (r.x0 == _ClipContext.ClientRect.x0) {
    r.y1 = _ClipContext.ClientRect.y1;
    r.x1 = _ClipContext.ClientRect.x1;
    /* Iterate over all windows which are above */
    /* Check all siblings above (Iterate over Parents and top siblings (hNext) */
    for (hParent = GUI_Context.hAWin; hParent; hParent = pParent->hParent) {
      pParent = WM_H2P(hParent);
      _Findy1(pParent->hNext, &r, NULL);
    }
    /* Check all children */
    _Findy1(pAWin->hFirstChild, &r, NULL);
  }
  /* 
    STEP 4
      Find out x0 for the given y0, y1 by iterating over windows above.
      if we find one that intersects, adjust x0 to the right.
  */
Find_x0:
  r.x1 = r.x0;
  /* Iterate over all windows which are above */
  /* Check all siblings above (siblings of window, siblings of parents, etc ...) */
  #if 0   /* This is a planned, but not yet released optimization */
    if (Status & WM_SF_DONT_CLIP_SIBLINGS)
    {
      hParent = pAWin->hParent;
    } else
  #endif
  {
    hParent = GUI_Context.hAWin;
  }
  for (; hParent; hParent = pParent->hParent) {
    pParent = WM_H2P(hParent);
    if (_Findx0(pParent->hNext, &r, NULL)) {
      goto Find_x0;
    }
  }
  /* Check all children */
  if (_Findx0(pAWin->hFirstChild, &r, NULL)) {
    goto Find_x0;
  }
  /* 
   STEP 5:
     If r.x0 out of right border, this stripe is done. Set next stripe and goto STEP 2
     Find out x1 for the given x0, y0, y1
  */
  r.x1 = _ClipContext.ClientRect.x1;
  if (r.x1 < r.x0) {/* horizontal border reached ? */
    _ClipContext.CurRect = r;
    goto NextStripe;
  }    
  /* 
   STEP 6:
     Find r.x1. We have to Iterate over all windows which are above
  */
  /* Check all siblings above (Iterate over Parents and top siblings (hNext) */
  #if 0   /* This is a planned, but not yet released optimization */
    if (Status & WM_SF_DONT_CLIP_SIBLINGS)
    {
      hParent = pAWin->hParent;
    } else
  #endif
  {
    hParent = GUI_Context.hAWin;
  }
  for (; hParent; hParent = pParent->hParent) {
    pParent = WM_H2P(hParent);
    _Findx1(pParent->hNext, &r, NULL);
  }
  /* Check all children */
  _Findx1(pAWin->hFirstChild, &r, NULL);
  /* We are done. Return the rectangle we found in the _ClipContext. */
  if (_ClipContext.Cnt >200) {
    return 0;  /* error !!! This should not happen !*/
  }
  _ClipContext.CurRect = r;
  return 1;  /* IVR is valid ! */
}

#else

static int _FindNext_IVR(void) {
  if (_ClipContext.Cnt ==0) {
    _ClipContext.CurRect = GUI_Context.pAWin->Rect;
    return 1;  /* IVR is valid ! */
  }
  return 0;  /* Nothing left to draw */
}
#endif

/*********************************************************************
*
*       WM_GetNextIVR

  Sets the next clipping rectangle. If a valid one has
  been found (and set), 1 is returned in order to indicate
  that the drawing operation needs to be executed.
  Returning 0 signals that we have iterated over all
  rectangles.

  Returns: 0 if no valid rectangle is found
           1 if rectangle has been found
*/
int  WM__GetNextIVR(void) {
  #if GUI_SUPPORT_CURSOR
    static char _CursorHidden;
  #endif
  /* If WM is not active, we have no rectangles to return */
  if (WM_IsActive==0) {
    return 0;
  }
  if (_ClipContext.EntranceCnt > 1) {
    _ClipContext.EntranceCnt--;
    return 0;
  }
  #if GUI_SUPPORT_CURSOR
    if (_CursorHidden) {
      _CursorHidden = 0;
      (*GUI_CURSOR_pfTempUnhide) ();
    }
  #endif
  ++_ClipContext.Cnt;
  /* Find next rectangle and use it as ClipRect */
  if (!_FindNext_IVR()) {
    _ClipContext.EntranceCnt--;  /* This search is over ! */
    return 0;        /* Could not find an other one ! */
  }
  WM__ActivateClipRect();
  /* Hide cursor if necessary */
  #if GUI_SUPPORT_CURSOR
    if (GUI_CURSOR_pfTempHide) {
      _CursorHidden = (*GUI_CURSOR_pfTempHide) ( &_ClipContext.CurRect);
    }
  #endif
  return 1;
}

/*********************************************************************
*
*       WM__InitIVRSearch

  This routine is called from the clipping level
  (the WM_ITERATE_START macro) when starting an iteration over the
  visible rectangles.

  Return value:
    0 : There is no valid rectangle (nothing to do ...)
    1 : There is a valid rectangle
*/
int WM__InitIVRSearch(const GUI_RECT* pMaxRect) {
  GUI_RECT r;
  WM_Obj* pAWin;
  GUI_ASSERT_LOCK();   /* GUI_LOCK must have been "called" before entering this (normally done indrawing routine) */
   /* If WM is not active -> nothing to do, leave cliprect alone */
  if (WM_IsActive==0) {
    WM__ActivateClipRect();
    return 1;
  }
  /* If we entered multiple times, leave Cliprect alone */
  if (++_ClipContext.EntranceCnt > 1)
    return 1;
  pAWin = WM_H2P(GUI_Context.hAWin);
  _ClipContext.Cnt        = -1;
 /* When using callback mechanism, it is legal to reduce drawing
    area to the invalid area ! */
  if (WM__PaintCallbackCnt) {
    WM__GetInvalidRectAbs(pAWin, &r);
  } else {  /* Not using callback mechanism, therefor allow entire rectangle */
    if (pAWin->Status & WM_SF_ISVIS) {
      r = pAWin->Rect;
    } else {
      --_ClipContext.EntranceCnt;
      return 0;  /* window is not even visible ! */
    }
  }
  /* If the drawing routine has specified a rectangle, use it to reduce the rectangle */
  if (pMaxRect) {
    GUI__IntersectRect(&r, pMaxRect);
  }
  /* If user has reduced the cliprect size, reduce the rectangle */
  if (GUI_Context.WM__pUserClipRect) {
    WM_Obj* pWin = pAWin;
    GUI_RECT rUser = *(GUI_Context.WM__pUserClipRect);
    #if WM_SUPPORT_TRANSPARENCY
      if (WM__hATransWindow) {
        pWin = WM_H2P(WM__hATransWindow);
      }   
    #endif
    WM__Client2Screen(pWin, &rUser);
    GUI__IntersectRect(&r, &rUser);
  }
  /* For transparent windows, we need to further reduce the rectangle */
  #if WM_SUPPORT_TRANSPARENCY
    if (WM__hATransWindow) {
      if (WM__ClipAtParentBorders(&r, WM__hATransWindow) == 0) {
        --_ClipContext.EntranceCnt;
        return 0;           /* Nothing to draw */
      }
    }
  #endif
  /* Iterate over all ancestors and clip at their borders. If there is no visible part, we are done */
  if (WM__ClipAtParentBorders(&r, GUI_Context.hAWin) == 0) {
    --_ClipContext.EntranceCnt;
    return 0;           /* Nothing to draw */
  }
  /* Store the rectangle and find the first rectangle of the area */
  _ClipContext.ClientRect = r;
  return WM__GetNextIVR();
}

/*********************************************************************
*
*       WM_SetDefault
*
  This routine sets the defaults for WM and the layers below.
  It is used before a drawing routine is called in order to
  make sure that defaults are set (in case the default settings
  had been altered before by the application)
*/
void WM_SetDefault(void) {
  GL_SetDefault();
  GUI_Context.WM__pUserClipRect = NULL;   /* No add. clipping */
}

/*********************************************************************
*
*       _Paint1
*/
static void _Paint1(WM_HWIN hWin, WM_Obj* pWin) {
  int Status = pWin->Status;
  /* Send WM_PAINT if window is visible and a callback is defined */
  if ((pWin->cb != NULL)  && (Status & WM_SF_ISVIS)) {
    WM_MESSAGE Msg;
    WM__PaintCallbackCnt++;
    if (Status & WM_SF_LATE_CLIP) {
      Msg.hWin   = hWin;
      Msg.MsgId  = WM_PAINT;
      Msg.Data.p = (GUI_RECT*)&pWin->InvalidRect;

⌨️ 快捷键说明

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