Пример #1
0
void CListSaveFilesTask::CreateFileEntry (CGameFile &GameFile, const CTimeDate &ModifiedTime, int yStart, IAnimatron **retpEntry, int *retcyHeight)

//	CreateFileEntry
//
//	Creates a display entry for the save file

	{
	const CVisualPalette &VI = m_HI.GetVisuals();
	const CG16bitFont &MediumFont = VI.GetFont(fontMedium);
	const CG16bitFont &SubTitleFont = VI.GetFont(fontSubTitle);

	int x = 0;
	int y = 0;
	int xText = x + ADVENTURE_ICON_WIDTH + ICON_SPACING_HORZ;
	int cxText = m_cxWidth - (ADVENTURE_ICON_WIDTH + 2 * ICON_SPACING_HORZ + SHIP_IMAGE_WIDTH);

	//	Start with a sequencer

	CAniSequencer *pRoot = new CAniSequencer;
	pRoot->SetPropertyVector(PROP_POSITION, CVector(0, yStart));

	//	Add the character name and current star system

	CString sHeading = strPatternSubst(CONSTLIT("%s — %s"), GameFile.GetPlayerName(), GameFile.GetSystemName());

	IAnimatron *pName = new CAniText;
	pName->SetPropertyVector(PROP_POSITION, CVector(xText, y));
	pName->SetPropertyVector(PROP_SCALE, CVector(10000, 1000));
	pName->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogInput));
	pName->SetPropertyFont(PROP_FONT, &SubTitleFont);
	pName->SetPropertyString(PROP_TEXT, sHeading);

	pRoot->AddTrack(pName, 0);
	y += SubTitleFont.GetHeight();

	//	Now add some additional information

	CShipClass *pClass = g_pUniverse->FindShipClass(GameFile.GetPlayerShip());
	CString sShipClass = (pClass ? pClass->GetName() : NULL_STR);
	CString sGenome = strCapitalize(GetGenomeName(GameFile.GetPlayerGenome()));

	CString sState;
	if (GameFile.IsGameResurrect())
		sState = strPatternSubst(CONSTLIT("Resurrect in the %s System"), GameFile.GetSystemName());
	else
		sState = strPatternSubst(CONSTLIT("Continue in the %s System"), GameFile.GetSystemName());

	CString sDesc;
	if (!sGenome.IsBlank() && !sShipClass.IsBlank())
		sDesc = strPatternSubst(CONSTLIT("%s — %s — %s"), sGenome, sShipClass, sState);
	else
		sDesc = sState;

	IAnimatron *pDesc = new CAniText;
	pDesc->SetPropertyVector(PROP_POSITION, CVector(xText, y));
	pDesc->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
	pDesc->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogInput));
	pDesc->SetPropertyFont(PROP_FONT, &MediumFont);
	pDesc->SetPropertyString(PROP_TEXT, sDesc);

	RECT rcLine;
	pDesc->GetSpacingRect(&rcLine);

	pRoot->AddTrack(pDesc, 0);
	y += RectHeight(rcLine);

	//	Adventure info

	CExtension *pAdventure = NULL;
	bool bHasAdventureIcon = false;

	if (g_pUniverse->FindExtension(GameFile.GetAdventure(), 0, &pAdventure))
		{
		//	Adventure icon

		CG16bitImage *pIcon;
		pAdventure->CreateIcon(ADVENTURE_ICON_WIDTH, ADVENTURE_ICON_HEIGHT, &pIcon);

		if (pIcon)
			{
			int xOffset = (ADVENTURE_ICON_WIDTH - pIcon->GetWidth()) / 2;
			IAnimatron *pIconAni = new CAniRect;
			pIconAni->SetPropertyVector(PROP_POSITION, CVector(x + xOffset, 0));
			pIconAni->SetPropertyVector(PROP_SCALE, CVector(pIcon->GetWidth(), pIcon->GetHeight()));
			pIconAni->SetFillMethod(new CAniImageFill(pIcon, true));

			pRoot->AddTrack(pIconAni, 0);

			bHasAdventureIcon = true;
			}

		//	Adventure name

		pName = new CAniText;
		pName->SetPropertyVector(PROP_POSITION, CVector(xText, y));
		pName->SetPropertyVector(PROP_SCALE, CVector(10000, 1000));
		pName->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogLabel));
		pName->SetPropertyFont(PROP_FONT, &MediumFont);
		pName->SetPropertyString(PROP_TEXT, pAdventure->GetName());

		pRoot->AddTrack(pName, 0);
		y += MediumFont.GetHeight();
		}

	//	Create an image of the ship class

	if (pClass)
		{
		const CObjectImageArray &ObjImage = pClass->GetImage();
		if (ObjImage.IsLoaded())
			{
			RECT rcRect = ObjImage.GetImageRect();
			CG16bitImage &Image = ObjImage.GetImage(NULL_STR);
			int cxImage = RectWidth(rcRect);
			int cyImage = RectHeight(rcRect);

			int cxNewWidth = Min(SHIP_IMAGE_WIDTH, cxImage);
			int cyNewHeight = cxNewWidth;

			CG16bitImage *pNewImage = new CG16bitImage;
			pNewImage->CreateFromImageTransformed(Image, 
					rcRect.left, 
					rcRect.top, 
					cxImage,
					cyImage,
					(Metric)cxNewWidth / cxImage,
					(Metric)cyNewHeight / cyImage,
					0.0);

			//	Position

			int xImage = x + m_cxWidth - SHIP_IMAGE_WIDTH + (SHIP_IMAGE_WIDTH - cxNewWidth) / 2;
			int yImage = (SHIP_IMAGE_HEIGHT - cyNewHeight) / 2;

			//	New image frame

			IAnimatron *pImageFrame = new CAniRect;
			pImageFrame->SetPropertyVector(PROP_POSITION, CVector(xImage, yImage));
			pImageFrame->SetPropertyVector(PROP_SCALE, CVector(cxNewWidth, cyNewHeight));
			pImageFrame->SetFillMethod(new CAniImageFill(pNewImage, true));

			pRoot->AddTrack(pImageFrame, 0);
			}
		}

	//	Extra information

	CString sEpitaph = GameFile.GetEpitaph();
	int iScore = GameFile.GetScore();
	CTimeDate LocalTime = ModifiedTime.ToLocalTime();
	CString sModifiedTime = LocalTime.Format("%d %B %Y %I:%M %p");
	CString sFilename = pathGetFilename(GameFile.GetFilespec());

	CString sGameType;
	if (GameFile.IsRegistered())
		sGameType = CONSTLIT("Registered");
	else if (GameFile.IsDebug())
		sGameType = CONSTLIT("Debug");
	else
		sGameType = CONSTLIT("Unregistered");

	CString sExtra;
	if (!sEpitaph.IsBlank())
		sExtra = strPatternSubst(CONSTLIT("Score %d — %s\n%s — %s — %s"), iScore, sEpitaph, sGameType, sModifiedTime, sFilename);
	else if (iScore > 0)
		sExtra = strPatternSubst(CONSTLIT("Score %d\n%s — %s — %s"), iScore, sGameType, sModifiedTime, sFilename);
	else
		sExtra = strPatternSubst(CONSTLIT("%s — %s — %s"), sGameType, sModifiedTime, sFilename);

	pDesc = new CAniText;
	pDesc->SetPropertyVector(PROP_POSITION, CVector(xText, y));
	pDesc->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
	pDesc->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogLabel));
	pDesc->SetPropertyFont(PROP_FONT, &MediumFont);
	pDesc->SetPropertyString(PROP_TEXT, sExtra);

	pDesc->GetSpacingRect(&rcLine);

	pRoot->AddTrack(pDesc, 0);
	y += RectHeight(rcLine);

	//	Done

	*retpEntry = pRoot;

	if (retcyHeight)
		*retcyHeight = (bHasAdventureIcon ? Max(ADVENTURE_ICON_HEIGHT, y) : y);
	}
Пример #2
0
void CTranscendenceWnd::CreateNewsAnimation (CMultiverseNewsEntry *pEntry, IAnimatron **retpAnimatron)

//	CreateNewsAnimation
//
//	Creates animation of a Multiverse news entry.

	{
	int iDuration = 600;
	int iInitialFade = 30;
	int iEndFade = 30;

	//	Compute some metrics for the pane based on the entry information

	int cxInnerPane = NEWS_PANE_WIDTH - (2 * NEWS_PANE_PADDING_X);

	CG32bitImage *pImage = pEntry->LoadImageHandoff();
	int cyImage = (pImage ? pImage->GetHeight() : 0);

	TArray<CString> TitleLines;
	m_Fonts.SubTitle.BreakText(pEntry->GetTitle(), cxInnerPane, &TitleLines);
	int cyTitle = m_Fonts.SubTitle.GetHeight() * TitleLines.GetCount();

	TArray<CString> BodyLines;
	m_Fonts.Medium.BreakText(pEntry->GetBody(), cxInnerPane, &BodyLines);
	int cyBody = m_Fonts.Medium.GetHeight() * BodyLines.GetCount();

	TArray<CString> FooterLines;
	m_Fonts.MediumHeavyBold.BreakText(pEntry->GetCallToActionText(), cxInnerPane, &FooterLines);
	int cyFooter = m_Fonts.MediumHeavyBold.GetHeight() * FooterLines.GetCount();

	int cyPane = cyImage
			+ cyTitle
			+ NEWS_PANE_INNER_SPACING_Y
			+ cyBody
			+ NEWS_PANE_INNER_SPACING_Y
			+ cyFooter
			+ NEWS_PANE_PADDING_Y;

	int xPane = m_rcIntroMain.left + (RectWidth(m_rcIntroMain) / 2) + (RectWidth(m_rcIntroMain) / 6);
	int yPane = m_rcIntroMain.top + ((RectHeight(m_rcIntroMain) - cyPane) / 2);

	//	Create sequencer to hold everything The origin of the sequencer is
	//	at the top-center of the pane.

	CAniSequencer *pSeq = new CAniSequencer;
	pSeq->SetPropertyVector(PROP_POSITION, CVector(xPane, yPane));

	int xLeft = -NEWS_PANE_WIDTH / 2;

	//	Create a button that will respond to clicks on the news pane

	CAniButton *pButton = new CAniButton;
	pButton->SetPropertyVector(PROP_POSITION, CVector(xLeft, 0));
	pButton->SetPropertyVector(PROP_SCALE, CVector(NEWS_PANE_WIDTH, cyPane));
	pButton->SetStyle(STYLE_DOWN, NULL);
	pButton->SetStyle(STYLE_HOVER, NULL);
	pButton->SetStyle(STYLE_NORMAL, NULL);
	pButton->SetStyle(STYLE_DISABLED, NULL);
	pButton->SetStyle(STYLE_TEXT, NULL);
	pButton->AddListener(EVENT_ON_CLICK, m_pIntroSession, CMD_OPEN_NEWS);

	pSeq->AddTrack(pButton, 0);

	//	Create the background

	CAniRoundedRect *pPane = new CAniRoundedRect;
	pPane->SetPropertyVector(PROP_POSITION, CVector(xLeft, 0));
	pPane->SetPropertyVector(PROP_SCALE, CVector(NEWS_PANE_WIDTH, cyPane));
	pPane->SetPropertyColor(PROP_COLOR, RGB_NEWS_PANE_BACKGROUND);
	pPane->SetPropertyOpacity(PROP_OPACITY, 64);
	pPane->SetPropertyInteger(PROP_UL_RADIUS, NEWS_PANE_CORNER_RADIUS);
	pPane->SetPropertyInteger(PROP_UR_RADIUS, NEWS_PANE_CORNER_RADIUS);
	pPane->SetPropertyInteger(PROP_LL_RADIUS, NEWS_PANE_CORNER_RADIUS);
	pPane->SetPropertyInteger(PROP_LR_RADIUS, NEWS_PANE_CORNER_RADIUS);
	pPane->AnimateLinearFade(iDuration, iInitialFade, iEndFade, 64);

	pSeq->AddTrack(pPane, 0);

	//	Add the content

	int yPos = 0;
	int xInnerLeft = -(cxInnerPane / 2);

	//	Create the image

	if (pImage)
		{
		//	If the image is wide enough to hit the rounded corners, then we
		//	need to mask it out.

		if (pImage->GetWidth() > (NEWS_PANE_WIDTH - 2 * NEWS_PANE_CORNER_RADIUS))
			{
			//	Create a mask the size of the pane and apply it to the image
			//	(We own the image so we can modify it).

			CG8bitImage PaneMask;
			PaneMask.CreateRoundedRect(NEWS_PANE_WIDTH, cyPane, NEWS_PANE_CORNER_RADIUS);
			pImage->IntersectMask(0, 
					0, 
					PaneMask.GetWidth(), 
					PaneMask.GetHeight(), 
					PaneMask,
					(pImage->GetWidth() - PaneMask.GetWidth()) / 2,
					0);
			}

		//	Create an animatron

		CAniRect *pRect = new CAniRect;
		pRect->SetPropertyVector(PROP_POSITION, CVector(-pImage->GetWidth() / 2, yPos));
		pRect->SetPropertyVector(PROP_SCALE, CVector(pImage->GetWidth(), pImage->GetHeight()));
		pRect->SetFillMethod(new CAniImageFill(pImage, true));
		pRect->AnimateLinearFade(iDuration, iInitialFade, iEndFade);

		pSeq->AddTrack(pRect, 0);

		yPos += cyImage;
		}

	//	Create the title

	IAnimatron *pText;
	CAniText::Create(pEntry->GetTitle(),
			CVector(xInnerLeft, yPos),
			&m_Fonts.SubTitle,
			CG16bitFont::AlignCenter,
			m_Fonts.rgbTitleColor,
			&pText);
	pText->SetPropertyVector(PROP_SCALE, CVector(cxInnerPane, cyPane));
	pText->AnimateLinearFade(iDuration, iInitialFade, iEndFade);
	pSeq->AddTrack(pText, 0);

	yPos += cyTitle + NEWS_PANE_INNER_SPACING_Y;

	//	Create the text

	CAniText::Create(pEntry->GetBody(),
			CVector(xInnerLeft, yPos),
			&m_Fonts.Medium,
			CG16bitFont::AlignCenter,
			m_Fonts.rgbTitleColor,
			&pText);
	pText->SetPropertyVector(PROP_SCALE, CVector(cxInnerPane, cyPane));
	pText->AnimateLinearFade(iDuration, iInitialFade, iEndFade);
	pSeq->AddTrack(pText, 0);

	yPos += cyBody + NEWS_PANE_INNER_SPACING_Y;

	//	Create the call to action

	CAniText::Create(pEntry->GetCallToActionText(),
			CVector(xInnerLeft, yPos),
			&m_Fonts.MediumHeavyBold,
			CG16bitFont::AlignCenter,
			m_Fonts.rgbTitleColor,
			&pText);
	pText->SetPropertyVector(PROP_SCALE, CVector(cxInnerPane, cyPane));
	pText->AnimateLinearFade(iDuration, iInitialFade, iEndFade);
	pSeq->AddTrack(pText, 0);

	//	Remember the URL to open when the user clicks

	m_sNewsURL = pEntry->GetCallToActionURL();

	//	Done

	*retpAnimatron = pSeq;
	}