static void DrawWindowRecursive(const UIWindow &wnd, DrawingContext &dc, bool topMostPass, bool insideTopMost) { insideTopMost |= wnd.GetTopMost(); if (!wnd.GetVisible() || (insideTopMost && !topMostPass)) return; // skip window and all its children dc.PushTransform(Vector2(wnd.GetX(), wnd.GetY())); if (insideTopMost == topMostPass) wnd.Draw(dc); // topmost windows escape parents' clip bool clipChildren = wnd.GetClipChildren() && (!topMostPass || insideTopMost); if (clipChildren) { math::RectInt clip; clip.left = 0; clip.top = 0; clip.right = (int)wnd.GetWidth(); clip.bottom = (int)wnd.GetHeight(); dc.PushClippingRect(clip); } for (UIWindow *w = wnd.GetFirstChild(); w; w = w->GetNextSibling()) DrawWindowRecursive(*w, dc, topMostPass, wnd.GetTopMost() || insideTopMost); if (clipChildren) dc.PopClippingRect(); dc.PopTransform(); }
bool LayoutManager::ProcessPointer(float x, float y, float z, Msg msg, int button, PointerType pointerType, unsigned int pointerID) { #ifndef NDEBUG _lastPointerLocation[pointerID] = Vector2(x, y); #endif if(UIWindow *captured = GetCapture(pointerID) ) { // calc relative mouse position and route message to captured window for(UIWindow *wnd = captured; _desktop.Get() != wnd; wnd = wnd->GetParent() ) { assert(wnd); x -= wnd->GetX(); y -= wnd->GetY(); } if( ProcessPointerInternal(captured, x, y, z, msg, button, pointerType, pointerID, true) || ProcessPointerInternal(captured, x, y, z, msg, button, pointerType, pointerID, false)) return true; } else { // handle all children of the desktop recursively; offer to topmost windows first if( ProcessPointerInternal(_desktop.Get(), x, y, z, msg, button, pointerType, pointerID, true) || ProcessPointerInternal(_desktop.Get(), x, y, z, msg, button, pointerType, pointerID, false)) return true; } if( _hotTrackWnd.Get() ) { _hotTrackWnd->OnMouseLeave(); _hotTrackWnd.Set(nullptr); } return false; }
HRESULT UIButtonGroup::Draw(DK_IMAGE drawingImg) { if (!m_bIsVisible) return S_OK; HRESULT hr(S_OK); DK_IMAGE imgSelf; int left = m_iLeft, top = m_iTop, right = m_iLeft + m_iWidth, bottom = m_iTop + m_iHeight; DK_RECT rcSelf={left, top, right, bottom}; RTN_HR_IF_FAILED(CropImage( drawingImg, rcSelf, &imgSelf )); CTpGraphics grf(imgSelf); ValidChildBtnShown(); int iSize = GetChildrenCount(); for (int i = 0; i < iSize; i++) { UIWindow* pWin = GetChildByIndex(i); if (pWin && pWin->IsVisible()) { DebugPrintf(DLC_GUI_VERBOSE, "%s: Drawing Child %d / %d : %s, (%d, %d)-(%d, %d), %s ...", GetClassName(), i, iSize, pWin->GetClassName(), pWin->GetX(), pWin->GetY(), pWin->GetWidth(), pWin->GetHeight(), pWin->GetText()); hr = pWin->Draw(imgSelf); if (!SUCCEEDED(hr)) { DebugPrintf(DLC_GUI_VERBOSE, "Draw child failed"); } } else { DebugPrintf(DLC_ERROR, "%s: FAILED to get child %d/%d !!!", GetClassName(), i, iSize); } } if (m_btnsDirection == BGD_Horizontal) { DrawTopLine(grf); DrawBottomLine(grf); } DrawSplitLine(grf); if (m_currentFocusedIndex >= 0 && (unsigned int)m_currentFocusedIndex < GetChildrenCount()) { DrawFocusedSymbol(imgSelf); } return hr; }
bool LayoutManager::ProcessPointerInternal(UIWindow* wnd, float x, float y, float z, Msg msg, int buttons, PointerType pointerType, unsigned int pointerID, bool topMostPass, bool insideTopMost) { insideTopMost |= wnd->GetTopMost(); if (!wnd->GetEnabled() || !wnd->GetVisible() || (insideTopMost && !topMostPass)) return false; bool pointerInside = (x >= 0 && x < wnd->GetWidth() && y >= 0 && y < wnd->GetHeight()); if( (pointerInside || !wnd->GetClipChildren()) && GetCapture(pointerID) != wnd ) { // route message to each child in reverse order until someone process it for(UIWindow *w = wnd->GetLastChild(); w; w = w->GetPrevSibling() ) { #ifndef NDEBUG WindowWeakPtr wp(w); #endif if( ProcessPointerInternal(w, x - w->GetX(), y - w->GetY(), z, msg, buttons, pointerType, pointerID, topMostPass, insideTopMost) ) { return true; } assert(wp.Get()); } } if( insideTopMost == topMostPass && (pointerInside || GetCapture(pointerID) == wnd) ) { // window is captured or the pointer is inside the window WindowWeakPtr wp(wnd); bool msgProcessed = false; switch( msg ) { case Msg::PointerDown: msgProcessed = wnd->OnPointerDown(x, y, buttons, pointerType, pointerID); break; case Msg::PointerUp: case Msg::PointerCancel: msgProcessed = wnd->OnPointerUp(x, y, buttons, pointerType, pointerID); break; case Msg::PointerMove: msgProcessed = wnd->OnPointerMove(x, y, pointerType, pointerID); break; case Msg::MOUSEWHEEL: msgProcessed = wnd->OnMouseWheel(x, y, z); break; case Msg::TAP: msgProcessed = wnd->OnTap(x, y); break; default: assert(false); } // if window did not process the message, it should not destroy itself assert(msgProcessed || wp.Get()); if( wp.Get() && msgProcessed ) { switch( msg ) { case Msg::PointerDown: case Msg::TAP: SetFocusWnd(wnd); // may destroy wnd default: break; } if( wp.Get() && wnd != _hotTrackWnd.Get() ) { if( _hotTrackWnd.Get() ) _hotTrackWnd->OnMouseLeave(); // may destroy wnd if( wp.Get() && wnd->GetVisibleCombined() && wnd->GetEnabledCombined() ) { _hotTrackWnd.Set(wnd); _hotTrackWnd->OnMouseEnter(x, y); } } } return msgProcessed; } return false; }