mso_vlist.c

来自「Zoran V966 DVD 解码 Soc芯片的源程序」· C语言 代码 · 共 841 行 · 第 1/2 页

C
841
字号
	UINT16 wScrollStartY		= 0;
	UINT16 wMaxScrollHeight	= 0;
	UINT16 wTemp				= 0;
	MS_AREA area;

	MS_DESCRIPTOR_VSCROLL_LIST* pScrollListDescriptor = (MS_DESCRIPTOR_VSCROLL_LIST*)pThis->mpDescriptor;

	MSO_VLIST __NEAR* pList = (MSO_VLIST __NEAR*)MS_FindObjectFromDescriptor((MSO_CONTAINER __NEAR*)pThis,
														(MS_DESCRIPTOR*)pScrollListDescriptor->mpDescriptorVList);
	// Background.
	OSDR_FillOsdSegBitmapFitArea(pScrollListDescriptor->mpBgBmp, pAbsArea);

	// Scrollbar background
	wScrollStartX = pThis->moArea.mwW - pScrollListDescriptor->mcXPadding - SCROLLBAR_WIDTH;

	area.msX 		= pAbsArea->msX + wScrollStartX;
	area.msY 		= pAbsArea->msY + pScrollListDescriptor->mcYPadding;
	area.mwW 	= SCROLLBAR_WIDTH;
	area.mwH 	= pThis->moArea.mwH - (pScrollListDescriptor->mcYPadding << 1);

	OSDR_FillOsdSegBitmapFitArea(pScrollListDescriptor->mpScrollbarBgBmp, (MS_AREA __NEAR*)&area);

	// Scrollbar
	wMaxScrollHeight = pThis->moArea.mwH - (pScrollListDescriptor->mcYPadding << 1);

	if(pList->moParam.mwTotalItems > pList->moParam.mcNumVisibleItems)
	{
		wScrollHeight = ((pList->moParam.mcNumVisibleItems * wMaxScrollHeight) / pList->moParam.mwTotalItems);
		wScrollStartY = ((wScrollHeight * pList->moParam.mwFirstDisplayItem) / pList->moParam.mcNumVisibleItems) + pScrollListDescriptor->mcYPadding;
		wScrollHeight = MAX(wScrollHeight, SCROLL_MIN_HEIGHT);
	}
	else
	{
		wScrollHeight	= wMaxScrollHeight;
		wScrollStartY	= pScrollListDescriptor->mcYPadding;
	}

	wTemp = wMaxScrollHeight + pScrollListDescriptor->mcYPadding;

	// Adjust scrollbar position.
	if(((wScrollStartY + wScrollHeight) > wTemp)
		|| ((pList->moParam.mwFirstDisplayItem + pList->moParam.mcNumVisibleItems) >= pList->moParam.mwTotalItems))
		wScrollStartY = wTemp - wScrollHeight;

	area.msX 		= pAbsArea->msX + wScrollStartX;
	area.msY 		= pAbsArea->msY + wScrollStartY;
	area.mwW 	= SCROLLBAR_WIDTH;
	area.mwH 	= wScrollHeight;

	return OSDR_FillOsdSegBitmapFitArea(pScrollListDescriptor->mpScrollbarBmp, (MS_AREA __NEAR*)&area);
}

/***************************************************************************************
*	Function	: 	VScrollListDisplayArrowFillOSDSeg
*
*	In		: 	pThis	=	Pointer to a MSO_VSCROLL_LIST object.
*
*				pAbsArea	=	Absolute area of pThis object.
*
*	Out		: 	None.
*
*	Return	:	TRUE if successful.
*
*	Desc 	:	Display function of the vertical scroll list with scroll arrow.
****************************************************************************************/
static BOOL _VScrollListArrowFillOSDSeg(MSO_OBJECT __NEAR* pThis, MS_AREA __NEAR* pAbsArea)
{
	MS_DESCRIPTOR_VSCROLL_LIST* pScrollListDescriptor = (MS_DESCRIPTOR_VSCROLL_LIST*)pThis->mpDescriptor;

	MSO_VLIST __NEAR* pList = (MSO_VLIST __NEAR*)MS_FindObjectFromDescriptor((MSO_CONTAINER __NEAR*)pThis,
																	(MS_DESCRIPTOR*)pScrollListDescriptor->mpDescriptorVList);
	if(MS_IS_VSLIST_DISPLAY_BG_BMP(pThis))
		OSDR_FillOsdSegBitmapFitArea(pScrollListDescriptor->mpBgBmp, pAbsArea);

	if(pList->moParam.mwTotalItems > pList->moParam.mcNumVisibleItems)
	{
		FORMATED_UNICODE_STRING oFormUniStr;

		oFormUniStr.mtFontIndex = FONT_0;

		if(0 != pList->moParam.mwFirstDisplayItem)
		{
			STR_GenerateUnicodeChar(PRIVATE_SYMBOL_ARROW_UP, oFormUniStr.mszUniStr, 0, UNISTR_LENGTH_MAX+1);
			OSDR_FormatUniString((FORMATED_UNICODE_STRING __NEAR*)&oFormUniStr);
			OSDR_FillOsdSegUniString((FORMATED_UNICODE_STRING __NEAR*)&oFormUniStr,
									pAbsArea,
									(pAbsArea->mwW >> 1),
									0,//(pScrollListDescriptor->mcYPadding + 2),
									ALIGN_H_CENTER,
									ALIGN_V_TOP,//ALIGN_V_BOTTOM,
									pScrollListDescriptor->mwTextColor);
		}

		if((pList->moParam.mwTotalItems - pList->moParam.mwFirstDisplayItem) > pList->moParam.mcNumVisibleItems)
		{
			STR_GenerateUnicodeChar(PRIVATE_SYMBOL_ARROW_DOWN, oFormUniStr.mszUniStr, 0, UNISTR_LENGTH_MAX+1);
			OSDR_FormatUniString((FORMATED_UNICODE_STRING __NEAR*)&oFormUniStr);
			OSDR_FillOsdSegUniString((FORMATED_UNICODE_STRING __NEAR*)&oFormUniStr,
									pAbsArea,
									(pAbsArea->mwW >> 1),
									(pAbsArea->mwH ),//- pScrollListDescriptor->mcYPadding),
									ALIGN_H_CENTER,
									ALIGN_V_BOTTOM,//ALIGN_V_TOP,
									pScrollListDescriptor->mwTextColor);
		}
	}
	return FALSE;
}

/***************************************************************************************
*	Function	: 	_VScrollListArrowOnSideFillOSDSeg
*
*	In		: 	pThis	=	Pointer to a MSO_VSCROLL_LIST object.
*
*				pAbsArea	=	Absolute area of pThis object.
*
*	Out		: 	None.
*
*	Return	:	TRUE if successful.
*
*	Desc 	:	Display function of the vertical scroll list with scroll arrow on the right side.
****************************************************************************************/
static BOOL _VScrollListArrowOnSideFillOSDSeg(MSO_OBJECT __NEAR* pThis, MS_AREA __NEAR* pAbsArea)
{
	MS_DESCRIPTOR_VSCROLL_LIST* pScrollListDescriptor = (MS_DESCRIPTOR_VSCROLL_LIST*)pThis->mpDescriptor;

	MSO_VLIST __NEAR* pList = (MSO_VLIST __NEAR*)MS_FindObjectFromDescriptor((MSO_CONTAINER __NEAR*)pThis,
																	(MS_DESCRIPTOR*)pScrollListDescriptor->mpDescriptorVList);
	if(MS_IS_VSLIST_DISPLAY_BG_BMP(pThis))
		OSDR_FillOsdSegBitmapFitArea(pScrollListDescriptor->mpBgBmp, pAbsArea);

	if(pList->moParam.mwTotalItems > pList->moParam.mcNumVisibleItems)
	{
		FORMATED_UNICODE_STRING oFormUniStr;
		oFormUniStr.mtFontIndex = FONT_0;

		if(0 != pList->moParam.mwFirstDisplayItem)
		{
			STR_GenerateUnicodeChar(PRIVATE_SYMBOL_ARROW_UP, oFormUniStr.mszUniStr, 0, UNISTR_LENGTH_MAX + 1);			
			OSDR_FormatUniString((FORMATED_UNICODE_STRING __NEAR*)&oFormUniStr);
			OSDR_FillOsdSegUniString((FORMATED_UNICODE_STRING __NEAR*)&oFormUniStr,
									pAbsArea,
									(pAbsArea->mwW - SCROLLBAR_WIDTH),
									0,
									ALIGN_H_CENTER,
									ALIGN_V_TOP,
									pScrollListDescriptor->mwTextColor);
		}

		if((pList->moParam.mwTotalItems - pList->moParam.mwFirstDisplayItem) > pList->moParam.mcNumVisibleItems)
		{
			STR_GenerateUnicodeChar(PRIVATE_SYMBOL_ARROW_DOWN, oFormUniStr.mszUniStr, 0, UNISTR_LENGTH_MAX+1);
			OSDR_FormatUniString((FORMATED_UNICODE_STRING __NEAR*)&oFormUniStr);
			OSDR_FillOsdSegUniString((FORMATED_UNICODE_STRING __NEAR*)&oFormUniStr,
									pAbsArea,
									(pAbsArea->mwW - SCROLLBAR_WIDTH),
									(pAbsArea->mwH - pScrollListDescriptor->mcYPadding),
									ALIGN_H_CENTER,
									ALIGN_V_BOTTOM,
									pScrollListDescriptor->mwTextColor);
		}
	}
	return FALSE;
}

/***************************************************************************************
* 	Public functions
****************************************************************************************/

/***************************************************************************************
*	Function	:	OVLIST_CreatAndAddItem
*
*	In		:	pThis		=	Pointer to the MSO_VLIST object.
*
*				pDescriptor	=	Pointer to a descriptor for the new object. The object to be created
*								would be based on this descriptor.
*
*				bEnd 		= 	The new item would be added at the end if TRUE.
*
*				bSetFocus	=	Set focus to the created item if TRUE.
*
*	Out		:	None.
*
*	Return	:	Pointer to the added item.
*
*	Desc		: 	Creates and adds items to the MSO_VLIST.
****************************************************************************************/
MSO_OBJECT __NEAR* OVLIST_CreatAndAddItem(MSO_OBJECT __NEAR* pThis, MS_DESCRIPTOR* pDescriptor, BOOL bEnd, BOOL bSetFocus)
{
	MSO_VLIST __NEAR* 	pList	 		= (MSO_VLIST __NEAR*)pThis;
	MSO_OBJECT __NEAR* 	pLastObj		= NULL;
	MSO_OBJECT __NEAR* 	pNewObject 	= NULL;
	MSO_OBJECT __NEAR* 	pTempObj;
	INT16 sStartPos = 0;

	if(MS_IS_OFFSET_FIRSTITEM(pThis))
		sStartPos = ((0 != pList->moParam.mcItemOffset) ? pList->moParam.mcItemOffset : DEFAULT_OFFSET);

	if((NULL == pThis) || (NULL == pDescriptor))
		return NULL;

	// Find the highest Y position for a vertical list if we are adding an item at the end
	if(TRUE == bEnd)
	{
		pTempObj = ((MSO_CONTAINER __NEAR*)pThis)->mpOlist;

		while(NULL != pTempObj)
		{
			// Find item with the highest Y
			if(sStartPos <= pTempObj->moArea.msY)
			{
				pLastObj 	= pTempObj;
				sStartPos = pTempObj->moArea.msY;
			}

			pTempObj = pTempObj->mpNext;
		}

		// We have the start Y position of the last item and it's pointer. Calculate the start position for the new item
		if(NULL != pLastObj)
			sStartPos += pLastObj->moArea.mwH + pList->moParam.mcItemOffset;

		// Check if the new item is within scope of the list's area
		if(sStartPos >= (pThis->moArea.mwH))
		{
			MSO_OBJECT __NEAR* pObj = ((MSO_CONTAINER __NEAR*)pThis)->mpOlist;
			MSO_OBJECT __NEAR* pIterObj;
			UINT16 wRemovedItemH;

			// We are out of scope. Which means we will have to remove the first item.
			// Find the first item. i.e. an item with Y = 0
			while(NULL != pObj)
			{
				if(0 == pObj->moArea.msY)
					break;
				pObj = pObj->mpNext;
			}

			// Add the new item to the list.
			pNewObject  = MS_CreateAndAddObject(pDescriptor, (MSO_CONTAINER __NEAR*)pThis);

			// Position the new item correctly.
			pNewObject->moArea.msX 	= 0;
			pNewObject->moArea.msY 	= sStartPos;
			pNewObject->moArea.mwW 	= pThis->moArea.mwW;

			wRemovedItemH = pObj->moArea.mwH;

			// Remove the first item.
			MS_RemoveObject(pObj);
			pObj = NULL;

			pIterObj = ((MSO_CONTAINER __NEAR*)pThis)->mpOlist;

			// Re-position all items in the list vertically.
			while(NULL != pIterObj)
			{
				pIterObj->moArea.msY -= wRemovedItemH + pList->moParam.mcItemOffset;
				pIterObj = pIterObj->mpNext;
			}
		}
		else // We are within scope
		{
			// Add the item to the list.
			pNewObject  = MS_CreateAndAddObject(pDescriptor, (MSO_CONTAINER __NEAR*)pThis);

			// Position the new item correctly.
			pNewObject->moArea.msX 	= 0;
			pNewObject->moArea.msY 	= sStartPos;
			pNewObject->moArea.mwW 	= pThis->moArea.mwW;
		}
	}
	else // Add item at the start of the list.
	{
		UINT16 wHeight;

		pTempObj = ((MSO_CONTAINER __NEAR*)pThis)->mpOlist;

		while(NULL != pTempObj)
		{
			// Find item with the highest Y
			if(sStartPos <= pTempObj->moArea.msY)
			{
				pLastObj 	= pTempObj;
				sStartPos	= pTempObj->moArea.msY;
			}

			pTempObj = pTempObj->mpNext;
		}

		wHeight =  pDescriptor->moArea.mwH + pList->moParam.mcItemOffset;

		// Find out if we need to remove the last object.
		if((sStartPos + wHeight) >= (pThis->moArea.mwH))
		{
			// We need to remove the last item.
			MS_RemoveObject(pLastObj);
			pLastObj = NULL;
		}

		// Add the new item to the list.
		pNewObject = MS_CreateAndAddObject(pDescriptor, (MSO_CONTAINER __NEAR*)pThis);

		// The new item should be displayed as the first item in the list.
		pNewObject->moArea.msX 	= 0;
		pNewObject->moArea.msY 	= 0;
		pNewObject->moArea.mwW 	= pThis->moArea.mwW;

		// Re-position the new item within the list. i.e bring it to the head position.
		pTempObj = ((MSO_CONTAINER __NEAR*)pThis)->mpOlist;

		// Get the previous item
		while(pNewObject != pTempObj->mpNext)
			pTempObj = pTempObj->mpNext;

		if(pTempObj != pNewObject)
		{
			pTempObj->mpNext 	= pNewObject->mpNext;
			pNewObject->mpNext 	= ((MSO_CONTAINER __NEAR*)pThis)->mpOlist;

			((MSO_CONTAINER __NEAR*)pThis)->mpOlist = pNewObject;
		}

		// Push rest of the items in the list down by wHeight pixels.
		pTempObj = ((MSO_CONTAINER __NEAR*)pThis)->mpOlist;

		// Skip the first item since it is already positioned correctly.
		pTempObj = pTempObj->mpNext;

		while(NULL != pTempObj)
		{
			pTempObj->moArea.msY += wHeight;
			pTempObj = pTempObj->mpNext;
		}
	}
	if(TRUE == bSetFocus)
		MS_ScreenSetFocusObject(pNewObject);

	return pNewObject;
}
/****************************************************************************************************
*	Function	: 	VlistGetRelativeItemIndex
*
* 	In		:	pContainer:	a pointer to the container containing the object to which
*				the operation is to be applied
*			:	pObject:	it is object in the container
*
* 	Out 		:	None
*
* 	Return	:	It will return index value according msY value of the object in cotainer.
*
* 	Desc	:	This function  is use for Nav. when changeOsd (such as Audio page(change choice set))
*                          the order of object in container will be changed. but their Area not change.
*
****************************************************************************************************/
static UINT16 VlistGetRelativeItemIndex(MSO_OBJECT __NEAR *pObject, MSO_CONTAINER __NEAR *pContainer)
{

         MSO_OBJECT __NEAR* pTempObject;
         UINT16 wIndex;
         MS_ASSERT(MS_IsContainer(pContainer));
         MS_ASSERT(pObject != NULL);
         MS_ASSERT (!MS_IsContentFrozen(pContainer));

         pTempObject = pContainer->mpOlist;
         wIndex  = 0;
         while (NULL != pTempObject)
         {
                   if (MS_IsInvisible(pTempObject) || !MS_IsFocusable(pTempObject))
                   {
                            pTempObject = pTempObject->mpNext;
                            continue;
                   }
                   if (pObject ->moArea.msY > pTempObject->moArea.msY)
                            wIndex++;
			pTempObject = pTempObject->mpNext;
         }

         return wIndex;   

}

/****************************************************************************************************
*	Function	: 	VlistSetFocusToRelativeItem
*
* 	In		:	pThis:	a pointer to the container containing the object to which
*				the operation is to be applied
* 				wIndex:  the index of item in Vlist
*
* 	Out 		:	None
*
* 	Return	:	It will return index value according msY value of the object in cotainer.
*
* 	Desc	:	Set focus to according index
*
****************************************************************************************************/
static BOOL VlistSetFocusToRelativeItem(MSO_OBJECT __NEAR *pThis, UINT16 wIndex)
{
	MSO_VLIST __NEAR* 			pList = (MSO_VLIST __NEAR*)pThis;
	MSO_OBJECT __NEAR* 			pObject;
	UINT16						wCount = 0;

	if (wIndex >= pList ->moParam.mwTotalItems)
		return FALSE;
	pList ->moParam.mwFirstDisplayItem = (wIndex/pList->moParam.mcNumVisibleItems) * pList->moParam.mcNumVisibleItems;
	MS_SendOperation((MSO_OBJECT __NEAR*)MS_GetParentPtr(pList), MS_OP_REFRESH, 0);
	pObject = MS_GetObjectListPtr(pList);
	while(NULL != pObject)
	{
		if (wCount == (wIndex%pList->moParam.mcNumVisibleItems))
			break;
		pObject = pObject->mpNext;
		wCount++;
	}
	
	MS_ScreenSetFocusObject(pObject);
	return TRUE;
}

⌨️ 快捷键说明

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