TextWindow::TextWindow(C4Rect &rtBounds, size_t iPicWdt, size_t iPicHgt, size_t iPicPadding, size_t iMaxLines, size_t iMaxTextLen, const char *szIndentChars, bool fAutoGrow, const C4Facet *pOverlayPic, int iOverlayBorder, bool fMarkup) : Control(rtBounds), pLogBuffer(NULL), fDrawBackground(true), fDrawFrame(true), iPicPadding(iPicPadding) { // calc client rect UpdateOwnPos(); // create content scroll window pClientWindow = new ScrollWindow(this); pClientWindow->SetBounds(GetContainedClientRect()); // create content multiline label pLogBuffer = new MultilineLabel(pClientWindow->GetContainedClientRect(), iMaxLines, iMaxTextLen, szIndentChars, fAutoGrow, fMarkup); // add to scroll window pClientWindow->AddElement(pLogBuffer); // update scrolling (for empty buffer) pClientWindow->SetClientHeight(1); // create content picture, if desired C4Rect rcContentSize = pClientWindow->GetClientRect(); if (iPicWdt && iPicHgt) { C4Rect rcImage; rcImage.x = std::max<int32_t>(rcContentSize.GetMiddleX() - iPicWdt/2, 0); rcImage.y = 0; rcImage.Wdt = std::min<size_t>(iPicWdt, rcContentSize.Wdt); rcImage.Hgt = iPicHgt * rcImage.Wdt / iPicWdt; rcContentSize.y += rcImage.Hgt + iPicPadding; if (pOverlayPic) pTitlePicture = new OverlayPicture(rcImage, false, *pOverlayPic, iOverlayBorder); else pTitlePicture = new Picture(rcImage, false); pClientWindow->AddElement(pTitlePicture); } else pTitlePicture = NULL; // update size UpdateSize(); }
void C4Menu::InitSize() { C4GUI::Element *pLast = pClientWindow->GetLast(); // Size calculation int Width, Height; Width=Columns*ItemWidth; Height=Lines*ItemHeight; VisibleCount = Columns*Lines; bool fBarNeeded; if (HasPortrait()) Width += C4MN_DlgPortraitWdt + C4MN_DlgPortraitIndent; // dialogs have auto-enlarge vertically if (pLast && Style == C4MN_Style_Dialog) { Height = std::max<int>(Height, pLast->GetBounds().y + pLast->GetBounds().Hgt + C4MN_DlgLineMargin); fBarNeeded = false; } else fBarNeeded = pLast && pLast->GetBounds().y + pLast->GetBounds().Hgt > pClientWindow->GetBounds().Hgt; // add dlg margins Width += GetMarginLeft() + GetMarginRight() + pClientWindow->GetMarginLeft() + pClientWindow->GetMarginRight(); Height += GetMarginTop() + GetMarginBottom() + pClientWindow->GetMarginTop() + pClientWindow->GetMarginBottom(); if (fBarNeeded) Width += C4GUI_ScrollBarWdt; SetBounds(C4Rect(rcBounds.x, rcBounds.y, Width, Height)); pClientWindow->SetScrollBarEnabled(fBarNeeded); UpdateOwnPos(); }
void Element::UpdatePos() { // update own fields UpdateOwnPos(); // notify container if (pParent) pParent->ElementPosChanged(this); }
MultilineLabel::MultilineLabel(const C4Rect &rcBounds, int32_t iMaxLines, int32_t iMaxBuf, const char *szIndentChars, bool fAutoGrow, bool fMarkup) // ctor : Element(), Lines(iMaxBuf, iMaxLines, rcBounds.Wdt, szIndentChars, fAutoGrow, fMarkup), fMarkup(fMarkup) { // set bounds this->rcBounds = rcBounds; // update height (min height) UpdateOwnPos(); }
void ScrollWindow::SetScrollBarEnabled(bool fToVal, bool noAutomaticPositioning) { if (fHasBar == fToVal) return; pScrollBar->SetVisibility(fHasBar = fToVal); // in some cases the windows will already care for the correct positioning themselves (see C4ScriptGuiWindow) if (!noAutomaticPositioning) UpdateOwnPos(); }
void WoodenLabel::SetIcon(const C4Facet &rfctIcon) { // set icon fctIcon = rfctIcon; // realign text to left for set icons if (fctIcon.Surface) iAlign = ALeft; else iAlign = ACenter; UpdateOwnPos(); }
Label::Label(const char *szLblText, const C4Rect &rcBounds, int32_t iAlign, DWORD dwFClr, CStdFont *pFont, bool fMakeReadableOnBlack, bool fAutosize, bool fMarkup) : Element(), dwFgClr(dwFClr), iAlign(iAlign), pFont(pFont), cHotkey(0), fAutosize(fAutosize), fMarkup(fMarkup), pClickFocusControl(NULL) { // make color readable if (fMakeReadableOnBlack) MakeColorReadableOnBlack(dwFgClr); this->rcBounds = rcBounds; // default font if (!this->pFont) this->pFont = &::GraphicsResource.TextFont; // set x0 UpdateOwnPos(); // update text SetText(szLblText); }
C4GameOverDlg::C4GameOverDlg() : C4GUI::Dialog( (C4GUI::GetScreenWdt() < 800) ? (C4GUI::GetScreenWdt()-10) : Min<int32_t>(C4GUI::GetScreenWdt()-150, 800), (C4GUI::GetScreenHgt() < 600) ? (C4GUI::GetScreenHgt()-10) : Min<int32_t>(C4GUI::GetScreenHgt()-150, 600), LoadResStr("IDS_TEXT_EVALUATION"), false), pNetResultLabel(NULL), fIsNetDone(false), fHasNextMissionButton(false) { is_shown = true; // assume dlg will be shown, soon UpdateOwnPos(); // indents / sizes int32_t iDefBtnHeight = 32; int32_t iIndentX1=10; int32_t iIndentY1=6, iIndentY2=0; // main screen components C4GUI::ComponentAligner caMain(GetClientRect(), 0,iIndentY1,true); int32_t iMainTextWidth = caMain.GetWidth() - 6*iIndentX1; caMain.GetFromBottom(iIndentY2); // lower button-area C4GUI::ComponentAligner caBottom(caMain.GetFromBottom(iDefBtnHeight+iIndentY1*2), iIndentX1,0); int32_t iBottomButtonSize = caBottom.GetInnerWidth(); iBottomButtonSize = Min<int32_t>(iBottomButtonSize/2-2*iIndentX1, C4GUI::GetRes()->CaptionFont.GetTextWidth("Quit it, baby! And some.")*2); // goal display const C4IDList &rGoals = Game.RoundResults.GetGoals(); const C4IDList &rFulfilledGoals = Game.RoundResults.GetFulfilledGoals(); if (rGoals.GetNumberOfIDs()) { C4GoalDisplay *pGoalDisplay = new C4GoalDisplay(caMain.GetFromTop(C4GUI_IconExHgt)); pGoalDisplay->SetGoals(rGoals, rFulfilledGoals, C4GUI_IconExHgt); AddElement(pGoalDisplay); // goal display may have resized itself; adjust component aligner caMain.ExpandTop(C4GUI_IconExHgt - pGoalDisplay->GetBounds().Hgt); } // league/network result, present or pending fIsNetDone = false; bool fHasNetResult = Game.RoundResults.HasNetResult(); const char *szNetResult = NULL; if (Game.Parameters.isLeague() || fHasNetResult) { if (fHasNetResult) szNetResult = Game.RoundResults.GetNetResultString(); else szNetResult = LoadResStr("IDS_TEXT_LEAGUEWAITINGFOREVALUATIO"); pNetResultLabel = new C4GUI::Label("", caMain.GetFromTop(C4GUI::GetRes()->TextFont.GetLineHeight()*2, iMainTextWidth), ACenter, C4GUI_Caption2FontClr, NULL, false, false, true); AddElement(pNetResultLabel); // only add label - contents and fIsNetDone will be set in next update } else { // otherwise, network is always done fIsNetDone = true; } // extra evaluation string area const char *szCustomEvaluationStrings = Game.RoundResults.GetCustomEvaluationStrings(); if (szCustomEvaluationStrings && *szCustomEvaluationStrings) { int32_t iMaxHgt = caMain.GetInnerHeight() / 3; // max 1/3rd of height for extra data C4GUI::MultilineLabel *pCustomStrings = new C4GUI::MultilineLabel(caMain.GetFromTop(0 /* resized later*/, iMainTextWidth), 0,0, " ", true, true); pCustomStrings->AddLine(szCustomEvaluationStrings, &C4GUI::GetRes()->TextFont, C4GUI_MessageFontClr, true, false, NULL); C4Rect rcCustomStringBounds = pCustomStrings->GetBounds(); if (rcCustomStringBounds.Hgt > iMaxHgt) { // Buffer too large: Use a scrollbox instead delete pCustomStrings; rcCustomStringBounds.Hgt = iMaxHgt; C4GUI::TextWindow *pCustomStringsWin = new C4GUI::TextWindow(rcCustomStringBounds, 0,0,0, 0,0," ",true, NULL,0, true); pCustomStringsWin->SetDecoration(false, false, NULL, false); pCustomStringsWin->AddTextLine(szCustomEvaluationStrings, &C4GUI::GetRes()->TextFont, C4GUI_MessageFontClr, true, false, NULL); caMain.ExpandTop(-iMaxHgt); AddElement(pCustomStringsWin); } else { // buffer size OK: Reserve required space caMain.ExpandTop(-rcCustomStringBounds.Hgt); AddElement(pCustomStrings); } } // player list area C4GUI::ComponentAligner caPlayerArea(caMain.GetAll(), iIndentX1,0); iPlrListCount = 1; bool fSepTeamLists = false; if (Game.Teams.GetTeamCount() == 2 && !Game.Teams.IsAutoGenerateTeams()) { // exactly two predefined teams: Use two player list boxes; one for each team iPlrListCount = 2; fSepTeamLists = true; } ppPlayerLists = new C4PlayerInfoListBox *[iPlrListCount]; for (int32_t i=0; i<iPlrListCount; ++i) { ppPlayerLists[i] = new C4PlayerInfoListBox(caPlayerArea.GetGridCell(i,iPlrListCount,0,1), C4PlayerInfoListBox::PILBM_Evaluation, fSepTeamLists ? Game.Teams.GetTeamByIndex(i)->GetID() : 0); /*if (fSepTeamLists) not necessary and popping up on too much area ppPlayerLists[i]->SetToolTip(FormatString(LoadResStr("IDS_DESC_TEAM"), Game.Teams.GetTeamByIndex(i)->GetName()).getData()); else ppPlayerLists[i]->SetToolTip(LoadResStr("IDS_DESC_LISTOFPLAYERSWHOPARTICIPA"));*/ //ppPlayerLists[i]->SetCustomFont(&Game.GraphicsResource.FontTooltip, 0xff000000); - display black on white? ppPlayerLists[i]->SetSelectionDiabled(true); ppPlayerLists[i]->SetDecoration(false, NULL, true, false); AddElement(ppPlayerLists[i]); } // add buttons C4GUI::CallbackButton<C4GameOverDlg> *btnExit; pBtnExit = btnExit = new C4GUI::CallbackButton<C4GameOverDlg>(LoadResStr("IDS_BTN_ENDROUND"), caBottom.GetGridCell(0,2, 0,1, iBottomButtonSize, -1, true), &C4GameOverDlg::OnExitBtn); btnExit->SetToolTip(LoadResStr("IDS_DESC_ENDTHEROUND")); AddElement(btnExit); C4GUI::CallbackButton<C4GameOverDlg> *btnContinue; pBtnContinue = btnContinue = new C4GUI::CallbackButton<C4GameOverDlg>(LoadResStr("IDS_BTN_CONTINUEGAME"), caBottom.GetGridCell(1,2, 0,1, iBottomButtonSize, -1, true), &C4GameOverDlg::OnContinueBtn); btnContinue->SetToolTip(LoadResStr("IDS_DESC_CONTINUETHEROUNDWITHNOFUR")); AddElement(btnContinue); // convert continue button to "next mission" button if available if (Game.NextMission) { // not available for regular replay and network clients, obviously // it is available for films though, so you can create cinematics for adventures if (Game.Control.isCtrlHost() || (Game.C4S.Head.Film == 2)) { fHasNextMissionButton = true; btnContinue->SetText(Game.NextMissionText.getData()); btnContinue->SetToolTip(Game.NextMissionDesc.getData()); } } // updates pSec1Timer = new C4Sec1TimerCallback<C4GameOverDlg>(this); Update(); // initial focus on quit button if visible, so space/enter/low gamepad buttons quit fIsQuitBtnVisible = fIsNetDone || !Game.Network.isHost(); if (fIsQuitBtnVisible) SetFocus(btnExit, false); }
Window::Window() : Container() { UpdateOwnPos(); }
void ScrollWindow::SetScrollBarEnabled(bool fToVal) { if (fHasBar == fToVal) return; pScrollBar->SetVisibility(fHasBar = fToVal); UpdateOwnPos(); }