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();
	}
示例#2
0
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();
}
示例#3
0
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);
	}
示例#8
0
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();
	}
示例#10
0
void ScrollWindow::SetScrollBarEnabled(bool fToVal)
	{
	if (fHasBar == fToVal) return;
	pScrollBar->SetVisibility(fHasBar = fToVal);
	UpdateOwnPos();
	}