OpenClonk
C4StartupAboutDlg.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2010-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 // About/credits screen
17 
18 #include "C4Include.h"
19 #include "gui/C4StartupAboutDlg.h"
20 
21 #include "C4Version.h"
23 #include "gui/C4UpdateDlg.h"
24 
25 #include <fstream>
26 
27 struct PersonList
28 {
29  struct Entry
30  {
31  const char *name, *nick;
32  };
33  virtual void WriteTo(C4GUI::TextWindow *textbox, CStdFont &font) = 0;
34  virtual std::string ToString() = 0;
35  virtual ~PersonList() { }
36 };
37 
38 static struct DeveloperList : public PersonList
39 {
40  std::vector<Entry> developers;
41 
42  DeveloperList(std::initializer_list<Entry> l) : developers(l) { }
43 
44  void WriteTo(C4GUI::TextWindow *textbox, CStdFont &font)
45  {
46  for (auto& p : developers)
47  {
48  textbox->AddTextLine(FormatString("%s <c f7f76f>(%s)</c>", p.name, p.nick).getData(), &font, C4GUI_MessageFontClr, false, true);
49  }
50  }
51 
52  std::string ToString()
53  {
54  std::stringstream out;
55  for (auto& p : developers)
56  {
57  out << p.name << " (" << p.nick << ")\n";
58  }
59  return out.str();
60  }
61 }
62 // the following lists are all sorted by all-time commit count: git shortlog -s | sort -rn
63 engineAndTools =
64 {
65  {"Sven Eberhardt", "Sven2"},
66  {"Günther Brammer", "Günther"},
67  {"Nicolas Hake", "Isilkor"},
68  {"Armin Burgmeier", "Clonk-Karl"},
69  {"Lukas Werling", "Luchs"},
70  {"Martin Plicht", "Mortimer"},
71  {"Julius Michaelis", "JCaesar"},
72  {"Peter Wortmann", "PeterW"},
73 },
74 scriptingAndContent =
75 {
76  {"Maikel de Vries", "Maikel"},
77  {"David Dormagen", "Zapper"},
78  {"Mark Haßelbusch", "Marky"},
79  {"Felix Wagner", "Clonkonaut"},
80  {"Bernhard Bonigl", "Boni"},
81 },
82 administration =
83 {
84  {"Tobias Zwick", "Newton"},
85 },
86 artAndContent =
87 {
88  {"Charles Spurrill", "Ringwaul"},
89  {"Richard Gerum", "Randrian"},
90  {"Timo Stabbert", "Mimmo"},
91  {"Matthias Rottländer", "Matthi"},
92 },
93 musicAndSound =
94 {
95  {"David Oerther", "ala"},
96  {"Martin Strohmeier", "K-Pone"},
97 };
98 
99 static struct ContributorList : public PersonList
100 {
101  static const std::vector<Entry> contributorsThisRelease, contributors, packageMaintainers;
102 
103  std::string ConcatNames(const std::vector<Entry>& names, bool with_color)
104  {
105  const char *opening_tag = with_color ? "<c f7f76f>" : "";
106  const char *closing_tag = with_color ? "</c>" : "";
107  std::stringstream result;
108  bool first = true;
109  for (auto& p : names)
110  {
111  if (!first) result << ", ";
112  first = false;
113  if (p.nick)
114  result << p.name << " " << opening_tag << "(" << p.nick << ")" << closing_tag;
115  else
116  result << p.name;
117  }
118  return result.str();
119  }
120 
121  template<typename Func>
122  std::string WriteLines(Func f, bool with_color)
123  {
124  const char *opening_tag = with_color ? "<c ff0000>" : "";
125  const char *closing_tag = with_color ? "</c>" : "";
126  std::stringstream text;
127 
128  text << opening_tag << "Contributors for OpenClonk 8.0:" << closing_tag << " ";
129  text << ConcatNames(contributorsThisRelease, with_color);
130  f(text);
131 
132  text << opening_tag << "Previous contributors:" << closing_tag << " ";
133  text << ConcatNames(contributors, with_color);
134  f(text);
135 
136  text << opening_tag << "Also thanks to our Linux package maintainers" << closing_tag << " ";
137  text << ConcatNames(packageMaintainers, with_color);
138  text << ", and more";
139  f(text);
140 
141  text << "Finally, a big thanks to Matthes Bender and all those who contributed to previous Clonk titles for the passion they put into the game and for agreeing to make Clonk open source.";
142  f(text);
143 
144  return text.str();
145  }
146 
147  void WriteTo(C4GUI::TextWindow *textbox, CStdFont &font)
148  {
149  WriteLines([&](std::stringstream& text)
150  {
151  textbox->AddTextLine(text.str().c_str(), &font, C4GUI_MessageFontClr, false, true);
152  text.str("");
153  }, true);
154  }
155 
156  std::string ToString()
157  {
158  return WriteLines([&](std::stringstream& text)
159  {
160  text << "\n";
161  }, false);
162  }
163 } contributors;
164 
165 // Sorted by commit count this release, e.g.: git shortlog -s v7.0.. | sort -rn
166 // Stuff from the milestone project sorted in-between as those commits usually end up squashed.
167 const std::vector<ContributorList::Entry> ContributorList::contributorsThisRelease = {
168  {"George Tokmaji", "Fulgen"}, // 75 commits
169  {"Martin Adam", "Win"}, // lava core animal
170  {"Merten Ehmig", "pluto"}, // helmet
171  {"Florian Graier", "Nachtfalter"}, // tree and guidepost
172  {"Philip Holzmann", "Foaly"}, // "another decorative deciduous tree"
173  {"Dominik Bayerl", "Kanibal"}, // 7 commits
174  {"Linus Heckemann", "sphalerite"}, // 6 commits
175  {"Pyrit", nullptr}, // texture to sproutberry bush
176  {"Armin Schäfer", nullptr}, // 5 commits
177  {"Tushar Maheshwari", nullptr}, // 4 commits
178  {"jok", nullptr}, // 3 commits
179  {"Tarte", nullptr}, // fixed normal map for brick textures
180  {"Philip Kern", "pkern"}, // 2 commits
181  {"Arne Schauf", "NativeException"},// 1 commit
182  {"Matthias Mailänder", nullptr}, // 1 commit
183  {"marsmoon", nullptr}, // 1 commit
184 };
185 
186 // First real names sorted by last name (sort -k2), then nicks (sort)
187 const std::vector<ContributorList::Entry> ContributorList::contributors = {
188  {"Tim Blume", nullptr},
189  {"Sven-Hendrik Haase", nullptr},
190  {"Carl-Philip Hänsch", "Carli"},
191  {"Jan Heberer", nullptr},
192  {"Benjamin Herr", "Loriel"},
193  {"Lauri Niskanen", "Ape"},
194  {"Johannes Nixdorf", "mixi"},
195  {"Misty de Meo", nullptr}, // note: three part name
196  {"Fabian Pietsch", nullptr},
197  {"Manuel Rieke", "MrBeast"},
198  {"Felix Riese", "Fungiform"},
199  {"Sebastian Rühl", nullptr},
200  {"Oliver Schneider", "ker"},
201  {"Lorenz Schwittmann", nullptr},
202  {"Alexander Semeniuk", "AlteredARMOR"},
203  {"Daniel Theuke", "ST-DDT"},
204  {"Andriel", nullptr},
205  {"Apfelclonk", nullptr},
206  {"Asmageddon", nullptr},
207  {"Checkmaty", nullptr},
208  {"Clonkine", nullptr},
209  {"dylanstrategie", nullptr},
210  {"Faby", nullptr},
211  {"grgecko", nullptr},
212  {"Gurkenglas", nullptr},
213  {"hasufell", nullptr},
214  {"Koronis", nullptr},
215  {"mizipzor", nullptr},
216  {"Peewee", nullptr},
217  {"Russell", nullptr},
218  {"Stan", nullptr},
219  {"TomyLobo", nullptr},
220 };
221 
222 // Sorted alphabetically: sort -k2
223 const std::vector<ContributorList::Entry> ContributorList::packageMaintainers = {
224  {"Benedict Etzel", "B_E"}, // Arch
225  {"Linus Heckemann", "sphalerite"}, // NixOS
226  {"Philip Kern", "pkern"}, // Debian
227  {"Matthias Mailänder", nullptr}, // OpenSUSE
228  {"Julian Ospald", "hasufell"}, // Gentoo
229  {"Kevin Zheng", nullptr}, // FreeBSD
230 };
231 
232 // ------------------------------------------------
233 // --- C4StartupAboutDlg
234 
236 {
237  // ctor
238  UpdateSize();
239 
241  C4Rect rcClient = GetContainedClientRect();
242 
243  // bottom line buttons and copyright messages
244  C4GUI::ComponentAligner caMain(rcClient, 0,0, true);
245  C4GUI::ComponentAligner caButtons(caMain.GetFromBottom(caMain.GetHeight()*1/8), 0,0, false);
247  int32_t iButtonWidth = caButtons.GetInnerWidth() / 4;
248  AddElement(btn = new C4GUI::CallbackButton<C4StartupAboutDlg>(LoadResStr("IDS_BTN_BACK"), caButtons.GetGridCell(0,3,0,1,iButtonWidth,C4GUI_ButtonHgt,true), &C4StartupAboutDlg::OnBackBtn));
249  btn->SetToolTip(LoadResStr("IDS_DLGTIP_BACKMAIN"));
250 #ifdef WITH_AUTOMATIC_UPDATE
251  AddElement(btn = new C4GUI::CallbackButton<C4StartupAboutDlg>(LoadResStr("IDS_BTN_CHECKFORUPDATES"), caButtons.GetGridCell(2,3,0,1,iButtonWidth,C4GUI_ButtonHgt,true), &C4StartupAboutDlg::OnUpdateBtn));
252  btn->SetToolTip(LoadResStr("IDS_DESC_CHECKONLINEFORNEWVERSIONS"));
253 #endif
254 
255  AddElement(new C4GUI::Label("'Clonk' is a registered trademark of Matthes Bender.",
256  caButtons.GetFromBottom(rUseFont.GetLineHeight())));
257 
258  C4GUI::ComponentAligner caDevelopers(caMain.GetFromTop(caMain.GetHeight() * 1/2), 0,0, false);
259  C4GUI::ComponentAligner caContributors(caMain.GetFromTop(caMain.GetHeight()), 0,0, false);
260  DrawPersonList(C4StartupAboutEngineAndTools, engineAndTools, caDevelopers.GetFromLeft(caMain.GetWidth()*1/3));
261  C4GUI::ComponentAligner caDevelopersCol2(caDevelopers.GetFromLeft(caMain.GetWidth()*1/3), 0,0, false);
262  DrawPersonList(C4StartupAboutScriptingAndContent, scriptingAndContent, caDevelopersCol2.GetFromTop(caDevelopers.GetHeight()*2/3));
263  DrawPersonList(C4StartupAboutAdministration, administration, caDevelopersCol2.GetFromTop(caDevelopers.GetHeight()*1/3));
264  C4GUI::ComponentAligner caDevelopersCol3(caDevelopers.GetFromLeft(caMain.GetWidth()*1/3), 0,0, false);
265  DrawPersonList(C4StartupAboutArtAndContent, artAndContent, caDevelopersCol3.GetFromTop(caDevelopers.GetHeight()*2/3));
266  DrawPersonList(C4StartupAboutMusicAndSound, musicAndSound, caDevelopersCol3.GetFromTop(caDevelopers.GetHeight()*1/3));
267 
268  DrawPersonList(C4StartupAboutContributors, contributors, caContributors.GetFromTop(caContributors.GetHeight()));
269 
270  keySaveCredits = std::make_unique<C4KeyBinding>(C4KeyCodeEx(K_S, KEYS_Control), "StartupAboutSaveCredits", KEYSCOPE_Gui,
271  new C4GUI::DlgKeyCB<C4StartupAboutDlg>(*this, &C4StartupAboutDlg::SaveCredits), C4CustomKey::PRIO_CtrlOverride);
272 }
273 
275 
276 
277 void C4StartupAboutDlg::DrawPersonList(int title, PersonList& persons, C4Rect& rect)
278 {
280  auto image = C4Startup::Get()->Graphics.fctAboutTitles.GetPhase(0, title);
281  int height = 2*rUseFont.GetFontHeight(), width = std::min(image.GetWidthByHeight(height), rect.Wdt);
282  auto picture = new C4GUI::Picture(C4Rect(rect.x, rect.y, width, height), true);
283  AddElement(picture);
284  picture->SetFacet(image);
285  rect.y += height; rect.Hgt -= height;
286  auto textbox = new C4GUI::TextWindow(rect, 0, 0, 0, 100, 4096, "", true, nullptr, 0, true);
287  AddElement(textbox);
288  textbox->SetDecoration(false, false, nullptr, true);
289  persons.WriteTo(textbox, rUseFont);
290  textbox->UpdateHeight();
291 }
292 
293 bool C4StartupAboutDlg::SaveCredits()
294 {
295  std::ofstream credits("Credits.txt", std::ios::out | std::ios::trunc);
296  if (!credits)
297  {
298  GetScreen()->ShowMessageModal("Couldn't open Credits.txt", "Credits", C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error, nullptr);
299  return true;
300  }
301 
302  credits << "<Engine and Tools>\n";
303  credits << engineAndTools.ToString();
304 
305  credits << "\n<Scripting and Content>\n";
306  credits << scriptingAndContent.ToString();
307 
308  credits << "\n<Art and Content>\n";
309  credits << artAndContent.ToString();
310 
311  credits << "\n<Music and Sound>\n";
312  credits << musicAndSound.ToString();
313 
314  credits << "\n<Administration>\n";
315  credits << administration.ToString();
316 
317  credits << "\n<Special Thanks to Contributors>\n";
318  credits << contributors.ToString();
319 
320  GetScreen()->ShowMessageModal("Saved to Credits.txt", "Credits", C4GUI::MessageDialog::btnOK, C4GUI::Ico_Notify, nullptr);
321  return true;
322 }
323 
325 {
327 }
328 
330 {
331 }
332 
333 #ifdef WITH_AUTOMATIC_UPDATE
334 void C4StartupAboutDlg::OnUpdateBtn(C4GUI::Control *btn)
335 {
336  C4UpdateDlg::CheckForUpdates(GetScreen());
337 }
338 #endif
virtual void WriteTo(C4GUI::TextWindow *textbox, CStdFont &font)=0
virtual ~PersonList()
#define C4GUI_ButtonHgt
Definition: C4Gui.h:111
#define C4GUI_MessageFontClr
Definition: C4Gui.h:43
int32_t GetWidth() const
Definition: C4Gui.h:2800
Definition: C4Rect.h:27
void AddElement(Element *pChild)
C4Rect GetContainedClientRect()
Definition: C4Gui.h:448
C4GraphicsResource GraphicsResource
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
int32_t Wdt
Definition: C4Rect.h:30
bool GetFromTop(int32_t iHgt, int32_t iWdt, C4Rect &rcOut)
Definition: C4Gui.cpp:1059
int32_t y
Definition: C4Rect.h:30
bool ShowMessageModal(const char *szMessage, const char *szCaption, DWORD dwButtons, Icons icoIcon, int32_t *piConfigDontShowAgainSetting=nullptr)
~C4StartupAboutDlg() override
class C4StartupDlg * SwitchDialog(DialogID eToDlg, bool fFade=true, const char *szSubDialog=nullptr)
Definition: C4Startup.cpp:137
void UpdateSize() override
const char * getData() const
Definition: StdBuf.h:442
int32_t x
Definition: C4Rect.h:30
void DrawElement(C4TargetFacet &cgo) override
C4Rect & GetGridCell(int32_t iSectX, int32_t iSectXMax, int32_t iSectY, int32_t iSectYMax, int32_t iSectSizeX=-1, int32_t iSectSizeY=-1, bool fCenterPos=false, int32_t iSectNumX=1, int32_t iSectNumY=1)
Definition: C4Gui.cpp:1148
int GetLineHeight() const
Definition: C4FontLoader.h:125
int GetFontHeight() const
Definition: C4FontLoader.h:134
static C4Startup * Get()
Definition: C4Startup.h:145
virtual std::string ToString()=0
void AddTextLine(const char *szText, CStdFont *pFont, DWORD dwClr, bool fDoUpdate, bool fMakeReadableOnBlack, CStdFont *pCaptionFont=nullptr)
Definition: C4Gui.h:1740
int32_t GetHeight() const
Definition: C4Gui.h:2801
virtual Screen * GetScreen()
Definition: C4Gui.cpp:289
int32_t Hgt
Definition: C4Rect.h:30
int32_t GetInnerWidth() const
Definition: C4Gui.h:2805
C4Facet GetPhase(int iPhaseX=0, int iPhaseY=0)
Definition: C4Facet.cpp:59
C4StartupGraphics Graphics
Definition: C4Startup.h:112
C4FacetID fctAboutTitles
Definition: C4Startup.h:56
bool GetFromBottom(int32_t iHgt, int32_t iWdt, C4Rect &rcOut)
Definition: C4Gui.cpp:1109
void OnBackBtn(C4GUI::Control *btn)
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270