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;
}
Beispiel #3
0
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;
}