void CAniRoundedRect::Create (const CVector &vPos, const CVector &vSize, WORD wColor, DWORD dwOpacity, IAnimatron **retpAni) // Create // // Creates an element { CAniRoundedRect *pRect = new CAniRoundedRect; pRect->SetPropertyVector(PROP_POSITION, vPos); pRect->SetPropertyVector(PROP_SCALE, vSize); pRect->SetPropertyColor(PROP_COLOR, wColor); pRect->SetPropertyOpacity(PROP_OPACITY, dwOpacity); *retpAni = pRect; }
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; }
void CUIHelper::CreateSessionTitle (IHISession *pSession, CCloudService &Service, const CString &sTitle, const TArray<SMenuEntry> *pMenu, DWORD dwOptions, IAnimatron **retpControl) const // CreateSessionTitle // // Creates a session title bar, including: // // User icon // User name // Session title // Close button { int i; const CVisualPalette &VI = m_HI.GetVisuals(); const CG16bitFont &SubTitleFont = VI.GetFont(fontSubTitle); RECT rcRect; VI.GetWidescreenRect(m_HI.GetScreen(), &rcRect); // Create a sequencer to hold all the controls CAniSequencer *pRoot; CAniSequencer::Create(CVector(rcRect.left, rcRect.top - TITLE_BAR_HEIGHT), &pRoot); // Add the header, unless excluded if (!(dwOptions & OPTION_SESSION_NO_HEADER)) { // The user icon is centered CAniRoundedRect *pIcon = new CAniRoundedRect; pIcon->SetPropertyVector(PROP_POSITION, CVector(0, (TITLE_BAR_HEIGHT - ICON_HEIGHT) / 2)); pIcon->SetPropertyVector(PROP_SCALE, CVector(ICON_HEIGHT, ICON_WIDTH)); pIcon->SetPropertyColor(PROP_COLOR, CG16bitImage::RGBValue(128, 128, 128)); pIcon->SetPropertyOpacity(PROP_OPACITY, 255); pIcon->SetPropertyInteger(PROP_UL_RADIUS, ICON_CORNER_RADIUS); pIcon->SetPropertyInteger(PROP_UR_RADIUS, ICON_CORNER_RADIUS); pIcon->SetPropertyInteger(PROP_LL_RADIUS, ICON_CORNER_RADIUS); pIcon->SetPropertyInteger(PROP_LR_RADIUS, ICON_CORNER_RADIUS); pRoot->AddTrack(pIcon, 0); // The user name baseline is centered. CString sUsername; WORD wUsernameColor; if (Service.HasCapability(ICIService::canGetUserProfile)) { sUsername = Service.GetUsername(); wUsernameColor = VI.GetColor(colorTextDialogInput); } else { sUsername = CONSTLIT("Offline"); wUsernameColor = VI.GetColor(colorTextDialogLabel); } int y = (TITLE_BAR_HEIGHT / 2) - SubTitleFont.GetAscent(); IAnimatron *pName = new CAniText; pName->SetPropertyVector(PROP_POSITION, CVector(ICON_WIDTH + PADDING_LEFT, y)); pName->SetPropertyVector(PROP_SCALE, CVector(RectWidth(rcRect), RectHeight(rcRect))); pName->SetPropertyColor(PROP_COLOR, wUsernameColor); pName->SetPropertyFont(PROP_FONT, &SubTitleFont); pName->SetPropertyString(PROP_TEXT, sUsername); pRoot->AddTrack(pName, 0); y += SubTitleFont.GetHeight(); // Add the session title IAnimatron *pTitle = new CAniText; pTitle->SetPropertyVector(PROP_POSITION, CVector(ICON_WIDTH + PADDING_LEFT, y)); pTitle->SetPropertyVector(PROP_SCALE, CVector(RectWidth(rcRect), RectHeight(rcRect))); pTitle->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogTitle)); pTitle->SetPropertyFont(PROP_FONT, &SubTitleFont); pTitle->SetPropertyString(PROP_TEXT, sTitle); pRoot->AddTrack(pTitle, 0); } // Add command buttons at the bottom int yBottomBar = TITLE_BAR_HEIGHT + RectHeight(rcRect); // Add a close button. if (!(dwOptions & OPTION_SESSION_NO_CANCEL_BUTTON)) { // If we have an OK button, then the label is Cancel. CString sCloseLabel = ((dwOptions & OPTION_SESSION_OK_BUTTON) ? CONSTLIT("Cancel") : CONSTLIT("Close")); const CG16bitImage &CloseIcon = VI.GetImage(imageCloseIcon); IAnimatron *pCloseButton; VI.CreateImageButton(pRoot, CMD_CLOSE_SESSION, RectWidth(rcRect) - BUTTON_WIDTH, yBottomBar + (TITLE_BAR_HEIGHT - BUTTON_HEIGHT) / 2, &CloseIcon, sCloseLabel, 0, &pCloseButton); pSession->RegisterPerformanceEvent(pCloseButton, EVENT_ON_CLICK, CMD_CLOSE_SESSION); } // Add an OK button, if necessary if (dwOptions & OPTION_SESSION_OK_BUTTON) { const CG16bitImage &OKIcon = VI.GetImage(imageOKIcon); IAnimatron *pOKButton; VI.CreateImageButton(pRoot, CMD_OK_SESSION, (RectWidth(rcRect) - BUTTON_WIDTH) / 2, yBottomBar + (TITLE_BAR_HEIGHT - BUTTON_HEIGHT) / 2, &OKIcon, CONSTLIT("OK"), 0, &pOKButton); pSession->RegisterPerformanceEvent(pOKButton, EVENT_ON_CLICK, CMD_OK_SESSION); } // Add extensions button else if (dwOptions & OPTION_SESSION_ADD_EXTENSION_BUTTON) { const CG16bitImage &OKIcon = VI.GetImage(imageSlotIcon); IAnimatron *pOKButton; VI.CreateImageButton(pRoot, CMD_OK_SESSION, (RectWidth(rcRect) - BUTTON_WIDTH) / 2, yBottomBar + (TITLE_BAR_HEIGHT - BUTTON_HEIGHT) / 2, &OKIcon, CONSTLIT("Add Extension"), 0, &pOKButton); pSession->RegisterPerformanceEvent(pOKButton, EVENT_ON_CLICK, CMD_OK_SESSION); } // Add menu items, if necessary if (pMenu) { // Menu is to the left. int xMenu = 0; int yMenu = yBottomBar + (TITLE_BAR_HEIGHT - BUTTON_HEIGHT) / 2; for (i = 0; i < pMenu->GetCount(); i++) { const SMenuEntry &Entry = pMenu->GetAt(i); IAnimatron *pButton; int cyHeight; VI.CreateLink(pRoot, Entry.sCommand, xMenu, yMenu, Entry.sLabel, 0, &pButton, NULL, &cyHeight); yMenu += cyHeight; pSession->RegisterPerformanceEvent(pButton, EVENT_ON_CLICK, Entry.sCommand); } } // Done *retpControl = pRoot; }
void CTranscendenceWnd::SetAccountControls (const CMultiverseModel &Multiverse) // SetAccountControls // // Sets the user account controls { const CVisualPalette &VI = g_pHI->GetVisuals(); const CG16bitFont &MediumFont = VI.GetFont(fontMedium); const CG16bitFont &SubTitleFont = VI.GetFont(fontSubTitle); // Get the account state CString sUsername; CString sStatus; CMultiverseModel::EOnlineStates iState = Multiverse.GetOnlineState(&sUsername, &sStatus); CG32bitPixel rgbUsernameColor = VI.GetColor(colorTextDialogLabel); // Metrics int cxText = Max(SubTitleFont.MeasureText(sUsername), MediumFont.MeasureText(sStatus)); // Compute metrics RECT rcRect; VI.GetWidescreenRect(&rcRect); // Delete any existing controls m_Reanimator.DeleteElement(ID_ACCOUNT_CONTROLS); // Create a sequencer to hold all the controls. We will be a child of the // player bar animation, so we are relative to that. CAniSequencer *pRoot; CAniSequencer::Create(CVector(0, 0), &pRoot); pRoot->SetID(ID_ACCOUNT_CONTROLS); // The user icon is centered CAniRoundedRect *pIcon = new CAniRoundedRect; pIcon->SetPropertyVector(PROP_POSITION, CVector(0, (TITLE_BAR_HEIGHT - ICON_HEIGHT) / 2)); pIcon->SetPropertyVector(PROP_SCALE, CVector(ICON_HEIGHT, ICON_WIDTH)); pIcon->SetPropertyColor(PROP_COLOR, CG32bitPixel(128, 128, 128)); pIcon->SetPropertyOpacity(PROP_OPACITY, 255); pIcon->SetPropertyInteger(PROP_UL_RADIUS, ICON_CORNER_RADIUS); pIcon->SetPropertyInteger(PROP_UR_RADIUS, ICON_CORNER_RADIUS); pIcon->SetPropertyInteger(PROP_LL_RADIUS, ICON_CORNER_RADIUS); pIcon->SetPropertyInteger(PROP_LR_RADIUS, ICON_CORNER_RADIUS); pRoot->AddTrack(pIcon, 0); // The user name baseline is centered. int y = (TITLE_BAR_HEIGHT / 2) - SubTitleFont.GetAscent(); // Create a hot spot over the entire text region (so that the user can // click on the username to sign in). if (iState == CMultiverseModel::stateNoUser || iState == CMultiverseModel::stateOffline) { IAnimatron *pButton; VI.CreateHiddenButton(pRoot, CMD_ACCOUNT, ICON_WIDTH + (PADDING_LEFT / 2), y - (PADDING_LEFT / 2), cxText + PADDING_LEFT, SubTitleFont.GetHeight() + 2 * MediumFont.GetHeight() + PADDING_LEFT, 0, &pButton); pButton->AddListener(EVENT_ON_CLICK, m_pIntroSession, CMD_ACCOUNT); } // Username IAnimatron *pName = new CAniText; pName->SetPropertyVector(PROP_POSITION, CVector(ICON_WIDTH + PADDING_LEFT, y)); pName->SetPropertyVector(PROP_SCALE, CVector(RectWidth(rcRect), RectHeight(rcRect))); pName->SetPropertyColor(PROP_COLOR, rgbUsernameColor); pName->SetPropertyFont(PROP_FONT, &SubTitleFont); pName->SetPropertyString(PROP_TEXT, sUsername); pRoot->AddTrack(pName, 0); y += SubTitleFont.GetHeight(); // Status IAnimatron *pStatus = new CAniText; pStatus->SetPropertyVector(PROP_POSITION, CVector(ICON_WIDTH + PADDING_LEFT, y)); pStatus->SetPropertyVector(PROP_SCALE, CVector(RectWidth(rcRect), RectHeight(rcRect))); pStatus->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogLabel)); pStatus->SetPropertyFont(PROP_FONT, &MediumFont); pStatus->SetPropertyString(PROP_TEXT, sStatus); pRoot->AddTrack(pStatus, 0); y += MediumFont.GetHeight(); // If the user is signed in, add buttons to edit account and sign out. #ifndef STEAM_BUILD if (iState == CMultiverseModel::stateOnline) { int x = ICON_WIDTH + PADDING_LEFT; // Edit account IAnimatron *pButton; int cxLink; #ifdef EDIT_ACCOUNT VI.CreateLink(pRoot, CMD_ACCOUNT_EDIT, x, y, CONSTLIT("edit account"), CVisualPalette::OPTION_LINK_MEDIUM_FONT, &pButton, &cxLink); pButton->AddListener(EVENT_ON_CLICK, m_pIntroSession, CMD_ACCOUNT_EDIT); #else VI.CreateLink(pRoot, CMD_CHANGE_PASSWORD, x, y, CONSTLIT("change password"), CVisualPalette::OPTION_LINK_MEDIUM_FONT, &pButton, &cxLink); pButton->AddListener(EVENT_ON_CLICK, m_pIntroSession, CMD_CHANGE_PASSWORD); #endif x += cxLink; // Separator IAnimatron *pSep = new CAniText; pSep->SetPropertyVector(PROP_POSITION, CVector(x, y)); pSep->SetPropertyVector(PROP_SCALE, CVector(SMALL_LINK_SPACING, RectHeight(rcRect))); pSep->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogLabel)); pSep->SetPropertyFont(PROP_FONT, &MediumFont); pSep->SetPropertyString(PROP_TEXT, CONSTLIT("•")); pSep->SetPropertyString(PROP_TEXT_ALIGN_HORZ, ALIGN_CENTER); pRoot->AddTrack(pSep, 0); x += SMALL_LINK_SPACING; // Sign out VI.CreateLink(pRoot, CMD_SIGN_OUT, x, y, CONSTLIT("sign out"), CVisualPalette::OPTION_LINK_MEDIUM_FONT, &pButton, &cxLink); pButton->AddListener(EVENT_ON_CLICK, m_pIntroSession, CMD_SIGN_OUT); x += cxLink; } #endif // Add it to the existing sequencer IAnimatron *pPlayerBar = m_Reanimator.GetPerformance(ID_PLAYER_BAR_PERFORMANCE); if (pPlayerBar == NULL) return; CAniSequencer *pSeq = (CAniSequencer *)pPlayerBar; pSeq->AddTrack(pRoot, 0); }