3434#include < wx/dcps.h>
3535#endif // !defined(__WXMSW__) || wxUSE_POSTSCRIPT
3636#include < wx/splitter.h>
37+ #include < wx/artprov.h>
3738
3839#include " gambit.h"
3940
@@ -1311,24 +1312,95 @@ void GameFrame::OnUnsplit(wxSplitterEvent &)
13111312
13121313namespace {
13131314
1314- wxString CloseWarningMessage (GameDocument *p_doc)
1315+ struct CloseWarningText {
1316+ wxString primary;
1317+ wxString secondary;
1318+ };
1319+
1320+ CloseWarningText CloseWarningMessage (GameDocument *p_doc)
13151321{
1316- if (p_doc->IsGameModified () && !p_doc->IsWorkspaceModified ()) {
1317- return _ (" This game has unsaved changes.\n\n "
1318- " Close without saving?" );
1322+ const bool gameModified = p_doc->IsGameModified ();
1323+ const bool workspaceModified = p_doc->IsWorkspaceModified ();
1324+
1325+ if (gameModified && !workspaceModified) {
1326+ return {_ (" This game has unsaved changes." ),
1327+ _ (" If you close this window now, changes to the game will be lost." )};
13191328 }
1320- if (!p_doc->IsGameModified () && p_doc->IsWorkspaceModified ()) {
1321- return _ (" There are unsaved computational results.\n\n "
1322- " These can be saved in a Gambit workspace file.\n "
1323- " Close without saving?" );
1329+
1330+ if (!gameModified && workspaceModified) {
1331+ return {_ (" There are unsaved computational results." ),
1332+ _ (" These results can be saved in a Gambit workspace file. "
1333+ " If you close this window now, the unsaved results will be lost." )};
13241334 }
1325- if (p_doc->IsGameModified () && p_doc->IsWorkspaceModified ()) {
1326- return _ (" This game has unsaved changes, and there are unsaved computational results.\n\n "
1327- " Close without saving?" );
1335+
1336+ if (gameModified && workspaceModified) {
1337+ return {_ (" This game and its computational results have unsaved changes." ),
1338+ _ (" If you close this window now, changes to the game and unsaved "
1339+ " computational results will be lost." )};
13281340 }
1329- return wxEmptyString;
1341+
1342+ return {wxEmptyString, wxEmptyString};
13301343}
13311344
1345+ class CloseWarningDialog final : public wxDialog {
1346+ public:
1347+ CloseWarningDialog (wxWindow *parent, const CloseWarningText &text)
1348+ : wxDialog(parent, wxID_ANY, _(" Unsaved Changes" ), wxDefaultPosition, wxDefaultSize,
1349+ wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
1350+ {
1351+ auto *topSizer = new wxBoxSizer (wxVERTICAL);
1352+
1353+ auto *contentSizer = new wxBoxSizer (wxHORIZONTAL);
1354+ contentSizer->Add (new wxStaticBitmap (this , wxID_ANY,
1355+ wxArtProvider::GetBitmap (wxART_WARNING, wxART_MESSAGE_BOX,
1356+ wxSize (32 , 32 ))),
1357+ 0 , wxALIGN_TOP | wxRIGHT, FromDIP (16 ));
1358+
1359+ auto *textSizer = new wxBoxSizer (wxVERTICAL);
1360+
1361+ auto *primary = new wxStaticText (this , wxID_ANY, text.primary );
1362+ auto font = primary->GetFont ();
1363+ font.SetWeight (wxFONTWEIGHT_BOLD);
1364+ primary->SetFont (font);
1365+
1366+ auto *secondary = new wxStaticText (this , wxID_ANY, text.secondary );
1367+ secondary->Wrap (FromDIP (460 ));
1368+
1369+ auto *question = new wxStaticText (this , wxID_ANY, _ (" Close without saving?" ));
1370+ question->Wrap (FromDIP (460 ));
1371+
1372+ textSizer->Add (primary, 0 , wxBOTTOM, FromDIP (8 ));
1373+ textSizer->Add (secondary, 0 , wxBOTTOM, FromDIP (12 ));
1374+ textSizer->Add (question, 0 );
1375+
1376+ contentSizer->Add (textSizer, 1 , wxEXPAND);
1377+
1378+ topSizer->Add (contentSizer, 1 , wxEXPAND | wxALL, FromDIP (20 ));
1379+
1380+ auto *buttonSizer = new wxBoxSizer (wxHORIZONTAL);
1381+
1382+ auto *cancelButton = new wxButton (this , wxID_CANCEL, _ (" Cancel" ));
1383+ auto *closeButton = new wxButton (this , wxID_YES, _ (" Close Without Saving" ));
1384+
1385+ buttonSizer->AddStretchSpacer ();
1386+ buttonSizer->Add (cancelButton, 0 , wxRIGHT, FromDIP (8 ));
1387+ buttonSizer->Add (closeButton, 0 );
1388+
1389+ topSizer->Add (buttonSizer, 0 , wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP (20 ));
1390+
1391+ SetSizerAndFit (topSizer);
1392+ SetMinSize (wxSize (FromDIP (540 ), -1 ));
1393+
1394+ SetEscapeId (wxID_CANCEL);
1395+ SetAffirmativeId (wxID_YES);
1396+
1397+ cancelButton->SetDefault ();
1398+ cancelButton->SetFocus ();
1399+
1400+ CentreOnParent ();
1401+ }
1402+ };
1403+
13321404} // namespace
13331405
13341406void GameFrame::OnCloseWindow (wxCloseEvent &p_event)
@@ -1339,10 +1411,10 @@ void GameFrame::OnCloseWindow(wxCloseEvent &p_event)
13391411 }
13401412
13411413 if (m_doc->IsModified ()) {
1342- const int response = wxMessageBox (CloseWarningMessage (m_doc), _ (" Unsaved Changes" ),
1343- wxYES_NO | wxNO_DEFAULT | wxICON_WARNING, this );
1414+ const auto warning = CloseWarningMessage (m_doc);
13441415
1345- if (response != wxYES) {
1416+ CloseWarningDialog dialog (this , warning);
1417+ if (dialog.ShowModal () != wxID_YES) {
13461418 p_event.Veto ();
13471419 return ;
13481420 }
0 commit comments