void HKWidgetRenderer::Render(const HKWidget &widget, const MFMatrix &worldTransform)
{
	MFVector widgetColour = widget.GetColour();
	MFVector size = widget.GetSize();
	size.x -= padding.x + padding.z;
	size.y -= padding.y + padding.w;

	if(colour.w > 0.f)
	{
		float borderWidth = border.x + border.z;
		float borderHeight = border.y + border.w;
		MFPrimitive_DrawUntexturedQuad(padding.x + border.x, padding.y + border.y, size.x - borderWidth, size.y - borderHeight, colour*widgetColour, worldTransform);
	}

	if(border.x > 0.f) // left
		MFPrimitive_DrawUntexturedQuad(padding.x, padding.y, border.x, size.y, borderColour*widgetColour, worldTransform);
	if(border.y > 0.f) // top
		MFPrimitive_DrawUntexturedQuad(padding.x, padding.y, size.x, border.y, borderColour*widgetColour, worldTransform);
	if(border.z > 0.f) // right
		MFPrimitive_DrawUntexturedQuad(size.x - border.z + padding.x, padding.y, border.z, size.y, borderColour*widgetColour, worldTransform);
	if(border.w > 0.f) // bottom
		MFPrimitive_DrawUntexturedQuad(padding.x, padding.y + size.y - border.w, size.x, border.w, borderColour*widgetColour, worldTransform);

	if(pImage)
	{
		if(margin9Cell > 0.f)
		{
			// 9 cell stuff...
		}
		else
		{
			// draw the background image centered in the box
			MFMaterial_SetMaterial(pImage);

			float offset = 0;
			float tc = MFRenderer_GetTexelCenterOffset();
			if(tc > 0.f)
			{
				if(size.x == texWidth && size.y == texHeight)
					offset = tc;
			}

			MFPrimitive_DrawQuad(padding.x - offset, padding.y - offset, size.x, size.y, widgetColour, 0, 0, 1, 1, worldTransform);
		}
	}
}
Beispiel #2
0
HKWidget *HKUserInterface::CreateWidget(const char *pWidgetType)
{
	HKWidgetFactory::FactoryType *pType;
	HKWidget *pWidget = pFactory->Create(pWidgetType, &pType);
	if(!pWidget)
		return NULL;

	HKWidgetRenderer *pRenderer = pRendererFactory->Create(pWidgetType);
	while(!pRenderer && pType->pParent)
	{
		pType = pType->pParent;
		pRenderer = pRendererFactory->Create(pType->typeName);
	}
	if(pRenderer)
		pWidget->SetRenderer(pRenderer);

	return pWidget;
}
Beispiel #3
0
void HKWidgetRendererLabel::Render(const HKWidget &widget, const MFMatrix &worldTransform)
{
	HKWidgetRenderer::Render(widget, worldTransform);

	HKWidgetLabel &label = (HKWidgetLabel&)widget;

	MFString l = label.GetText();
	if(!l.IsEmpty())
	{
		MFFont *pFont = label.GetFont();
		float height = label.GetTextHeight();
		float shadowDepth = label.GetShadowDepth();
		const MFVector &size = widget.GetSize();
		const MFVector &colour = widget.GetColour();
		const MFVector &textColour = label.GetTextColour();
		MFFontJustify j = label.GetTextJustification();
		const char *pString = l.CStr();

		if(shadowDepth > 0.f)
			MFFont_DrawTextJustified(pFont, pString, MakeVector(shadowDepth, shadowDepth), size.x, size.y, j, height, MFVector::black, -1, worldTransform);
		MFFont_DrawTextJustified(pFont, pString, MFVector::zero, size.x, size.y, j, height, textColour * colour, -1, worldTransform);
	}
}
Beispiel #4
0
void HKWidgetListbox::ArrangeChildren()
{
	// early out?
	int numChildren = GetNumChildren();
	if(numChildren == 0)
		return;

	MFVector pPos = orientation == Horizontal ? MakeVector(padding.x + scrollOffset, padding.y) : MakeVector(padding.x, padding.y + scrollOffset);
	MFVector pSize = MakeVector(size.x - (padding.x + padding.z), size.y - (padding.y + padding.w));

	contentSize = 0.f;

	for(int a=0; a<numChildren; ++a)
	{
		HKWidget *pWidget = GetChild(a);
		if(pWidget->GetVisible() == Gone)
			continue;

		const MFVector &cMargin = pWidget->GetLayoutMargin();
		const MFVector &cSize = pWidget->GetSize();

		MFVector tPos = pPos + MakeVector(cMargin.x, cMargin.y);
		MFVector tSize = MFMax(pSize - MakeVector(cMargin.x + cMargin.z, cMargin.y + cMargin.w), MFVector::zero);

		if(orientation == Horizontal)
		{
			float itemSize = cSize.x + cMargin.x + cMargin.z;
			contentSize += itemSize;
			pPos.x += itemSize;
			pWidget->SetPosition(tPos);
			pWidget->SetHeight(tSize.y);
		}
		else
		{
			float itemSize = cSize.y + cMargin.y + cMargin.w;
			contentSize += itemSize;
			pPos.y += itemSize;
			pWidget->SetPosition(tPos);
			pWidget->SetWidth(tSize.x);
		}
	}
}
void HKWidgetLayoutLinear::ArrangeChildren()
{
	bool bFitWidth = bAutoWidth && GetHAlign() != Align_Fill; // fitFlags & FitContentHorizontal
	bool bFitHeight = bAutoHeight && GetVAlign() != VAlign_Fill; // fitFlags & FitContentVertical

	// early out?
	int numChildren = GetNumChildren();
	if(numChildren == 0)
	{
		if(bFitWidth || bFitHeight)
		{
			// resize the layout
			MFVector newSize = GetSize();
			if(bFitWidth)
				newSize.x = padding.x + padding.z;
			if(bFitHeight)
				newSize.y = padding.y + padding.w;
			Resize(newSize);
		}
		return;
	}

	// calculate weight and fit
	float totalWeight = 0.f;
	MFVector fit = MakeVector(padding.x + padding.z, padding.y + padding.w);
	for(int a=0; a<numChildren; ++a)
	{
		HKWidget *pWidget = GetChild(a);
		if(pWidget->GetVisible() == Gone)
			continue;

		const MFVector &cSize = pWidget->GetSizeWithMargin();

		if(orientation == Horizontal)
		{
			if(pWidget->GetHAlign() == Align_Fill) // fill horizontally
				totalWeight += pWidget->GetLayoutWeight();
			else
				fit.x += cSize.x;

			fit.y = MFMax(fit.y, cSize.y + padding.y + padding.w);
		}
		else
		{
			if(pWidget->GetVAlign() == VAlign_Fill) // fill vertically
				totalWeight += pWidget->GetLayoutWeight();
			else
				fit.y += cSize.y;

			fit.x = MFMax(fit.x, cSize.x + padding.x + padding.z);
		}
	}

	if(bFitWidth || bFitHeight)
	{
		// resize the layout
		MFVector newSize = size;
		if(bFitWidth)
			newSize.x = fit.x;
		if(bFitHeight)
			newSize.y = fit.y;
		Resize(newSize);
	}

	MFVector pPos = MakeVector(padding.x, padding.y);
	MFVector pSize = MakeVector(size.x - (padding.x + padding.z), size.y - (padding.y + padding.w));

	MFVector slack = MFMax(size - fit, MFVector::zero);

	for(int a=0; a<numChildren; ++a)
	{
		HKWidget *pWidget = GetChild(a);
		if(pWidget->GetVisible() == Gone)
			continue;

		const MFVector &cMargin = pWidget->GetLayoutMargin();
		const MFVector &cSize = pWidget->GetSize();

		MFVector tPos = pPos + MakeVector(cMargin.x, cMargin.y);
		MFVector tSize = MFMax(pSize - MakeVector(cMargin.x + cMargin.z, cMargin.y + cMargin.w), MFVector::zero);

		Align align = pWidget->GetHAlign();
		VAlign valign = pWidget->GetVAlign();

		MFVector newSize = cSize;

		if(orientation == Horizontal)
		{
			if(align == Align_Fill) // fill horizontally
			{
				// this widget fills available empty space in the parent container
				newSize.x = slack.x * (pWidget->GetLayoutWeight() / totalWeight);
				pPos.x += newSize.x;
				newSize.x = MFMax(0.f, newSize.x - cMargin.x - cMargin.z);
			}
			else
			{
				pPos.x += cSize.x + cMargin.x + cMargin.z;
			}

			switch(valign)
			{
			case VAlign_None:
			case VAlign_Top:
				pWidget->SetPosition(tPos);
				break;
			case VAlign_Center:
				pWidget->SetPosition(tPos + MakeVector(0, MFMax(tSize.y - cSize.y, 0.f) * 0.5f));
				break;
			case VAlign_Bottom:
				pWidget->SetPosition(tPos + MakeVector(0, MFMax(tSize.y - cSize.y, 0.f)));
				break;
			case VAlign_Fill:
				pWidget->SetPosition(tPos);
				newSize.y = tSize.y;
				break;
			default:
				MFUNREACHABLE;
			}
		}
		else
		{
			if(valign == VAlign_Fill) // fill vertically
			{
				// this widget fills available empty space in the parent container
				newSize.y = slack.y * (pWidget->GetLayoutWeight() / totalWeight);
				pPos.y += newSize.y;
				newSize.y = MFMax(0.f, newSize.y - cMargin.y - cMargin.w);
			}
			else
			{
				pPos.y += cSize.y + cMargin.y + cMargin.w;
			}

			switch(align)
			{
				case Align_None:
				case Align_Left:
					pWidget->SetPosition(tPos);
					break;
				case Align_Center:
					pWidget->SetPosition(tPos + MakeVector(MFMax(tSize.x - cSize.x, 0.f) * 0.5f, 0));
					break;
				case Align_Right:
					pWidget->SetPosition(tPos + MakeVector(MFMax(tSize.x - cSize.x, 0.f), 0));
					break;
				case Align_Fill:
					pWidget->SetPosition(tPos);
					newSize.x = tSize.x;
					break;
				default:
					MFUNREACHABLE;
			}
		}

		ResizeChild(pWidget, newSize);
	}
}
void HKWidgetLayoutFrame::ArrangeChildren()
{
	bool bFitWidth = bAutoWidth && GetHAlign() != Align_Fill; // fitFlags & FitContentHorizontal
	bool bFitHeight = bAutoHeight && GetVAlign() != VAlign_Fill; // fitFlags & FitContentVertical

	// early out?
	int numChildren = GetNumChildren();
	if(numChildren == 0)
	{
		if(bFitWidth || bFitHeight)
		{
			// resize the layout
			MFVector newSize = GetSize();
			if(bFitWidth)
				newSize.x = padding.x + padding.z;
			if(bFitHeight)
				newSize.y = padding.y + padding.w;
			Resize(newSize);
		}
		return;
	}

	if(bFitWidth || bFitHeight)
	{
		// fit to largest child in each dimension
		MFVector fit = MFVector::zero;
		for(int a=0; a<numChildren; ++a)
		{
			HKWidget *pWidget = GetChild(a);
			const MFVector &cSize = pWidget->GetSizeWithMargin();

			fit.x = MFMax(fit.x, cSize.x + padding.x + padding.z);
			fit.y = MFMax(fit.y, cSize.y + padding.y + padding.w);
		}

		// resize the layout
		MFVector newSize = GetSize();
		if(bFitWidth)
			newSize.x = fit.x;
		if(bFitHeight)
			newSize.y = fit.y;
		Resize(newSize);
	}

	MFVector cPos = MakeVector(padding.x, padding.y);
	MFVector cSize = MakeVector(size.x - (padding.x + padding.z), size.y - (padding.y + padding.w));

	for(int a=0; a<numChildren; ++a)
	{
		HKWidget *pWidget = GetChild(a);

		const MFVector &cMargin = pWidget->GetLayoutMargin();
		const MFVector &size = pWidget->GetSize();
		MFVector tPos = cPos + MakeVector(cMargin.x, cMargin.y);
		MFVector tSize = cSize - MakeVector(cMargin.x + cMargin.z, cMargin.y + cMargin.w);

		switch(pWidget->GetLayoutJustification())
		{
		case TopLeft:
			pWidget->SetPosition(tPos);
			break;
		case TopCenter:
			pWidget->SetPosition(tPos + MakeVector((tSize.x - size.x) * 0.5f, 0));
			break;
		case TopRight:
			pWidget->SetPosition(tPos + MakeVector(tSize.x - size.x, 0));
			break;
		case TopFill:
			pWidget->SetPosition(tPos);
			ResizeChild(pWidget, MakeVector(tSize.x, size.y));
			break;
		case CenterLeft:
			pWidget->SetPosition(tPos + MakeVector(0, (tSize.y - size.y) * 0.5f));
			break;
		case Center:
			pWidget->SetPosition(tPos + MakeVector((tSize.x - size.x) * 0.5f, (tSize.y - size.y) * 0.5f));
			break;
		case CenterRight:
			pWidget->SetPosition(tPos + MakeVector(tSize.x - size.x, (tSize.y - size.y) * 0.5f));
			break;
		case CenterFill:
			pWidget->SetPosition(tPos + MakeVector(0, (tSize.y - size.y) * 0.5f));
			ResizeChild(pWidget, MakeVector(tSize.x, size.y));
			break;
		case BottomLeft:
			pWidget->SetPosition(tPos + MakeVector(0, tSize.y - size.y));
			break;
		case BottomCenter:
			pWidget->SetPosition(tPos + MakeVector((tSize.x - size.x) * 0.5f, tSize.y - size.y));
			break;
		case BottomRight:
			pWidget->SetPosition(tPos + MakeVector(tSize.x - size.x, tSize.y - size.y));
			break;
		case BottomFill:
			pWidget->SetPosition(tPos + MakeVector(0, tSize.y - size.y));
			ResizeChild(pWidget, MakeVector(tSize.x, size.y));
			break;
		case FillLeft:
			pWidget->SetPosition(tPos);
			ResizeChild(pWidget, MakeVector(size.x, tSize.y));
			break;
		case FillCenter:
			pWidget->SetPosition(tPos + MakeVector((tSize.x - size.x) * 0.5f, 0));
			ResizeChild(pWidget, MakeVector(size.x, tSize.y));
			break;
		case FillRight:
			pWidget->SetPosition(tPos + MakeVector(tSize.x - size.x, 0));
			ResizeChild(pWidget, MakeVector(size.x, tSize.y));
			break;
		case Fill:
			pWidget->SetPosition(tPos);
			ResizeChild(pWidget, tSize);
			break;
		case None:
			// this widget has absolute coordinates..
		default:
			break;
		}
	}
}
Beispiel #7
0
void HKUserInterface::OnInputEvent(HKInputManager &manager, const HKInputManager::EventInfo &ev)
{
	HKWidget *pFocusWidget = pFocusList[ev.pSource->sourceID];

	if(ev.pSource->device == IDD_Mouse || ev.pSource->device == IDD_TouchPanel)
	{
		// positional events will be sent to the hierarchy
		MFVector pos = { ev.hover.x, ev.hover.y, 0.f, 1.f };
		MFVector dir = { 0.f, 0.f, 1.f, 1.f };

		MFVector localPos;

		HKWidget *pWidget = NULL;
		if(pFocusWidget)
		{
			pWidget = pFocusWidget->IntersectWidget(pos, dir, &localPos);
			if(!pWidget)
				pWidget = pFocusWidget;
		}
		else
		{
			pWidget = pRoot->IntersectWidget(pos, dir, &localPos);
		}

		// update the down widget
		if(ev.ev == HKInputManager::IE_Down)
			pDownOver[ev.pSource->sourceID] = pWidget;
		else if(ev.ev == HKInputManager::IE_Tap)
		{
			// if we receive a tap event, check that it was on the same widget we recorded the down event for
			if(pDownOver[ev.pSource->sourceID] != pWidget)
				return;
		}

		// check if the hover has changed
		HKWidget *pHover = pHoverList[ev.pSource->sourceID];
		if(pHover != pWidget)
		{
			pHoverList[ev.pSource->sourceID] = pWidget;

			if(pHover)
			{
				HKWidgetInputEvent ie(pHover, ev.pSource);
				pHover->OnHoverOut(*pHover, ie);
			}

			if(pWidget)
			{
				HKWidgetInputEvent ie(pWidget, ev.pSource);
				pWidget->OnHoverOver(*pWidget, ie);
			}
		}

		if(pWidget)
		{
			HKInputManager::EventInfo transformedEv = ev;
			LocaliseInput(transformedEv, pWidget, localPos);

			// send the input event
			if(pWidget->InputEvent(manager, transformedEv))
				return;
		}
	}
	else if(pFocusWidget)
	{
		// non-positional events
		pFocusWidget->InputEvent(manager, ev);
	}
}