1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2005, Sven2
6 * Copyright (c) 2017-2021, The LegacyClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18// main game dialogs (abort game dlg, observer dlg)
19
20#include "C4GuiResource.h"
21#include <C4Include.h>
22#include <C4GameDialogs.h>
23
24#include <C4Viewport.h>
25#include <C4Network2Dialogs.h>
26#include <C4Game.h>
27#include <C4Player.h>
28
29bool C4AbortGameDialog::is_shown = false;
30
31// C4GameAbortDlg
32
33C4AbortGameDialog::C4AbortGameDialog()
34 : C4GUI::Dialog((Game.Control.isCtrlHost() || (Game.C4S.Head.Film == 2)) ? 400 : C4GUI::MessageDialog::dsSmall, 100, LoadResStr(id: C4ResStrTableKey::IDS_DLG_ABORT), false), fGameHalted(false)
35{
36 const auto showRestart = (Game.Control.isCtrlHost() || (Game.C4S.Head.Film == 2));
37
38 is_shown = true; // assume dlg will be shown, soon
39
40 CStdFont &rUseFont = C4GUI::GetRes()->TextFont;
41 // get positions
42 C4GUI::ComponentAligner caMain(GetClientRect(), C4GUI_DefDlgIndent, C4GUI_DefDlgIndent, true);
43 // place icon
44 C4Rect rcIcon = caMain.GetFromLeft(C4GUI_IconWdt);
45 rcIcon.Hgt = C4GUI_IconHgt;
46 AddElement(pChild: new C4GUI::Icon(rcIcon, C4GUI::Ico_Exit));
47
48 // centered text dialog: waste some icon space on the right to balance dialog
49 caMain.GetFromRight(C4GUI_IconWdt);
50
51 StdStrBuf sMsgBroken;
52 int iMsgHeight = rUseFont.BreakMessage(szMsg: LoadResStr(id: C4ResStrTableKey::IDS_HOLD_ABORT), iWdt: caMain.GetInnerWidth(), pOut: &sMsgBroken, fCheckMarkup: true);
53 C4GUI::Label *pLblMessage = new C4GUI::Label("", caMain.GetFromTop(iHgt: iMsgHeight), ACenter, C4GUI_MessageFontClr, &rUseFont, false);
54 pLblMessage->SetText(szText: sMsgBroken.getData(), fAllowHotkey: false);
55 AddElement(pChild: pLblMessage);
56
57 // place button(s)
58 C4GUI::ComponentAligner caButtonArea(caMain.GetFromTop(C4GUI_ButtonAreaHgt), 0, 0);
59 int32_t iButtonCount = showRestart ? 3 : 2;
60 C4Rect rcBtn = caButtonArea.GetCentered(iWdt: iButtonCount * C4GUI_DefButton2Wdt + (iButtonCount - 1) * C4GUI_DefButton2HSpace, C4GUI_ButtonHgt);
61 rcBtn.Wdt = C4GUI_DefButton2Wdt;
62
63 auto *const yesBtn = C4GUI::newYesButton(bounds: rcBtn);
64 AddElement(pChild: yesBtn);
65 rcBtn.x += C4GUI_DefButton2Wdt + C4GUI_DefButton2HSpace;
66
67 if (showRestart)
68 {
69 AddElement(pChild: new C4GUI::CallbackButton<C4AbortGameDialog>(LoadResStr(id: C4ResStrTableKey::IDS_BTN_RESTART), rcBtn, &C4AbortGameDialog::OnRestartBtn, this));
70 rcBtn.x += C4GUI_DefButton2Wdt + C4GUI_DefButton2HSpace;
71 }
72
73 AddElement(pChild: C4GUI::newNoButton(bounds: rcBtn));
74
75 SetFocus(pCtrl: yesBtn, fByMouse: false);
76 // resize to actually needed size
77 SetClientSize(iToWdt: GetClientRect().Wdt, iToHgt: GetClientRect().Hgt - caMain.GetHeight());
78}
79
80C4AbortGameDialog::~C4AbortGameDialog()
81{
82 is_shown = false;
83}
84
85void C4AbortGameDialog::OnShown()
86{
87 if (!Game.Network.isEnabled())
88 {
89 fGameHalted = true;
90 Game.HaltCount++;
91 }
92}
93
94void C4AbortGameDialog::OnClosed(bool fOK)
95{
96 if (fGameHalted)
97 Game.HaltCount--;
98 bool restart = fRestart;
99 // inherited
100 typedef C4GUI::Dialog Base;
101 Base::OnClosed(fOK);
102
103 // abort
104 if (fOK)
105 {
106 if (!restart)
107 {
108 Game.RestartRestoreInfos.Clear();
109 }
110
111 if (restart)
112 {
113 Application.SetNextMission(Game.ScenarioFilename);
114 }
115
116 Game.Abort();
117 }
118 else
119 {
120 Game.Players.ClearLocalPlayerPressedComs();
121 }
122}
123
124void C4AbortGameDialog::OnRestartBtn(C4GUI::Control *)
125{
126 fRestart = true;
127 Close(fOK: true);
128}
129