From 2b86772d6c5d33c833c77e3a7c94c9105b2c8cfa Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 15 Feb 2020 23:49:14 +0100 Subject: [PATCH] add delete options to HighScoresDialog --- src/gui/HighScoresDialog.cxx | 236 ++++++++++++++++++----------------- src/gui/HighScoresDialog.hxx | 24 ++-- 2 files changed, 133 insertions(+), 127 deletions(-) diff --git a/src/gui/HighScoresDialog.cxx b/src/gui/HighScoresDialog.cxx index 06561109c..37f50774f 100644 --- a/src/gui/HighScoresDialog.cxx +++ b/src/gui/HighScoresDialog.cxx @@ -48,7 +48,7 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent, WidgetArray wid; VariantList items; - _w = 40 * fontWidth + HBORDER * 2; // max_w - 20; + _w = 44 * fontWidth + HBORDER * 2; // max_w - 20; _h = 400; // max_h - 20; ypos = VBORDER + _th; xpos = HBORDER; @@ -69,6 +69,7 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent, int xposSpecial = xposScore + font.getStringWidth("Score") + 24; int xposName = xposSpecial + font.getStringWidth("Round") + 16; int xposDate = xposName + font.getStringWidth("Name") + 16; + int xposDelete = xposDate + font.getStringWidth("YY-MM-DD HH:MM") + 16; int nWidth = font.getStringWidth("ABC") + 4; new StaticTextWidget(this, font, xposRank, ypos + 1, "Rank"); @@ -91,6 +92,10 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent, myEditNamesWidget[p]->setEnabled(false); wid.push_back(myEditNamesWidget[p]); myDatesWidget[p] = new StaticTextWidget(this, font, xposDate, ypos + 1, "12-02-20 17:15"); + myDeleteButtons[p] = new ButtonWidget(this, font, xposDelete, ypos + 1, 18, 18, "X", + kDeleteSingle); + myDeleteButtons[p]->setID(p); + wid.push_back(myDeleteButtons[p]); ypos += lineHeight + VGAP; } @@ -98,7 +103,7 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent, myMD5Widget = new StaticTextWidget(this, ifont, xpos, ypos + 1, "MD5: 12345678901234567890123456789012"); - addOKCancelBGroup(wid, font); + addDefaultsOKCancelBGroup(wid, font, "Save", "Cancel", " Reset "); addToFocusList(wid); } @@ -129,24 +134,13 @@ void HighScoresDialog::loadConfig() VarList::push_back(items, buf.str(), i); } myVariationWidget->addItems(items); - myDisplayedVariation = instance().highScores().variation(); - myVariationWidget->setSelected(myDisplayedVariation); + myVariationWidget->setSelected(instance().highScores().variation()); mySpecialLabelWidget->setLabel(instance().highScores().specialLabel()); - // required when leaving with hot key - for (Int32 p = 0; p < NUM_POSITIONS; ++p) - { - myNamesWidget[p]->clearFlags(EditTextWidget::FLAG_INVISIBLE); - myEditNamesWidget[p]->setFlags(EditTextWidget::FLAG_INVISIBLE); - myEditNamesWidget[p]->setEnabled(false); - } - myMD5 = instance().console().properties().get(PropType::Cart_MD5); myMD5Widget->setLabel("MD5: " + myMD5); - myPlayedVariation = instance().highScores().variation(); - myEditPos = myHighScorePos = -1; myNow = now(); handleVariation(true); @@ -155,17 +149,17 @@ void HighScoresDialog::loadConfig() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void HighScoresDialog::saveConfig() { + // save initials and remember for the next time if (myHighScorePos != -1) { - if (myDisplayedVariation != myPlayedVariation) - { - loadHighScores(myPlayedVariation); - handlePlayedVariation(); - } myInitials = myEditNamesWidget[myHighScorePos]->getText(); myNames[myHighScorePos] = myInitials; - saveHighScores(); } + // save selected variation + + Int32 variation = myVariationWidget->getSelectedTag().toInt(); + saveHighScores(variation); + } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -177,7 +171,6 @@ void HighScoresDialog::handleCommand(CommandSender* sender, int cmd, int data, i saveConfig(); // falls through... case kCloseCmd: - resetVisibility(); instance().eventHandler().leaveMenuMode(); break; @@ -185,8 +178,15 @@ void HighScoresDialog::handleCommand(CommandSender* sender, int cmd, int data, i handleVariation(); break; - case Event::UISelect: - resetVisibility(); + case kDeleteSingle: + deletePos(id); + updateWidgets(); + break; + + case GuiObject::kDefaultsCmd: + for (int p = NUM_POSITIONS - 1; p >= 0; --p) + deletePos(p); + updateWidgets(); break; default: @@ -195,31 +195,69 @@ void HighScoresDialog::handleCommand(CommandSender* sender, int cmd, int data, i } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string HighScoresDialog::now() const +void HighScoresDialog::handleVariation(bool init) { - std::tm now = BSPF::localTime(); - ostringstream ss; + // TODO: if anything changed, asked for saving + Int32 variation = myVariationWidget->getSelectedTag().toInt(); - ss << std::setfill('0') << std::right - << std::setw(2) << (now.tm_year - 100) << '-' - << std::setw(2) << (now.tm_mon + 1) << '-' - << std::setw(2) << now.tm_mday << " " - << std::setw(2) << now.tm_hour << ":" - << std::setw(2) << now.tm_min; + loadHighScores(variation); - return ss.str(); + myEditPos = -1; + + if (variation == instance().highScores().variation()) + handlePlayedVariation(); + + updateWidgets(init); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void HighScoresDialog::resetVisibility() +void HighScoresDialog::updateWidgets(bool init) { - if (myEditPos != -1) + for (Int32 p = 0; p < NUM_POSITIONS; ++p) { - // hide again - myEditNamesWidget[myEditPos]->setFlags(EditTextWidget::FLAG_INVISIBLE); - myEditNamesWidget[myEditPos]->setEnabled(false); - myNamesWidget[myEditPos]->clearFlags(EditTextWidget::FLAG_INVISIBLE); + ostringstream buf; + + if (myHighScores[p] > 0) + { + buf << std::setw(HSM::MAX_SCORE_DIGITS) << std::setfill(' ') << myHighScores[p]; + myPositionsWidget[p]->clearFlags(Widget::FLAG_INVISIBLE); + myDeleteButtons[p]->clearFlags(Widget::FLAG_INVISIBLE); + myDeleteButtons[p]->setEnabled(true); + } + else + { + myPositionsWidget[p]->setFlags(Widget::FLAG_INVISIBLE); + myDeleteButtons[p]->setFlags(Widget::FLAG_INVISIBLE); + myDeleteButtons[p]->setEnabled(false); + } + myScoresWidget[p]->setLabel(buf.str()); + + buf.str(""); + if (mySpecials[p] > 0) + buf << std::setw(HSM::MAX_SPECIAL_DIGITS) << std::setfill(' ') << mySpecials[p]; + mySpecialsWidget[p]->setLabel(buf.str()); + + myNamesWidget[p]->setLabel(myNames[p]); + myDatesWidget[p]->setLabel(myDates[p]); + + if (p == myEditPos) + { + myNamesWidget[p]->setFlags(EditTextWidget::FLAG_INVISIBLE); + myEditNamesWidget[p]->clearFlags(EditTextWidget::FLAG_INVISIBLE); + myEditNamesWidget[p]->setEnabled(true); + myEditNamesWidget[p]->setEditable(true); + if (init) + myEditNamesWidget[p]->setText(myInitials); + } + else + { + myNamesWidget[p]->clearFlags(EditTextWidget::FLAG_INVISIBLE); + myEditNamesWidget[p]->setFlags(EditTextWidget::FLAG_INVISIBLE); + myEditNamesWidget[p]->setEnabled(false); + myEditNamesWidget[p]->setEditable(false); + } } + } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -258,58 +296,41 @@ void HighScoresDialog::handlePlayedVariation() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void HighScoresDialog::handleVariation(bool init) +void HighScoresDialog::deletePos(int pos) { - resetVisibility(); - - myDisplayedVariation = myVariationWidget->getSelectedTag().toInt(); - - loadHighScores(myDisplayedVariation); - - myEditPos = -1; - - if (myDisplayedVariation == myPlayedVariation) + for (Int32 p = pos; p < NUM_POSITIONS - 1; ++p) { - handlePlayedVariation(); - - if (myHighScorePos != -1) - { - myNamesWidget[myHighScorePos]->setFlags(EditTextWidget::FLAG_INVISIBLE); - myEditNamesWidget[myHighScorePos]->clearFlags(EditTextWidget::FLAG_INVISIBLE); - myEditNamesWidget[myHighScorePos]->setEnabled(true); - myEditNamesWidget[myHighScorePos]->setEditable(true); - if (init) - myEditNamesWidget[myHighScorePos]->setText(myInitials); - } + myHighScores[p] = myHighScores[p + 1]; + mySpecials[p] = mySpecials[p + 1]; + myNames[p] = myNames[p + 1]; + myDates[p] = myDates[p + 1]; } + myHighScores[NUM_POSITIONS - 1] = 0; + mySpecials[NUM_POSITIONS - 1] = 0; + myNames[NUM_POSITIONS - 1] = ""; + myDates[NUM_POSITIONS - 1] = ""; - for (Int32 p = 0; p < NUM_POSITIONS; ++p) + if (myEditPos == pos) { - ostringstream buf; - - if (myHighScores[p] > 0) - buf << std::setw(HSM::MAX_SCORE_DIGITS) << std::setfill(' ') << myHighScores[p]; - myScoresWidget[p]->setLabel(buf.str()); - - buf.str(""); - if (mySpecials[p] > 0) - buf << std::setw(HSM::MAX_SPECIAL_DIGITS) << std::setfill(' ') << mySpecials[p]; - mySpecialsWidget[p]->setLabel(buf.str()); - - myNamesWidget[p]->setLabel(myNames[p]); - myDatesWidget[p]->setLabel(myDates[p]); + myHighScorePos = myEditPos = -1; + } + if (myEditPos > pos) + { + myHighScorePos--; + myEditPos--; + myEditNamesWidget[myEditPos]->setText(myEditNamesWidget[myEditPos + 1]->getText()); } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void HighScoresDialog::saveHighScores() const +void HighScoresDialog::saveHighScores(Int32 variation) const { if(instance().hasConsole()) { ostringstream buf; buf << instance().stateDir() << instance().console().properties().get(PropType::Cart_Name) - << ".hs" << myPlayedVariation; + << ".hs" << variation; // Make sure the file can be opened for writing Serializer out(buf.str()); @@ -317,16 +338,15 @@ void HighScoresDialog::saveHighScores() const if(!out) { buf.str(""); - buf << "Can't open/save to high scores file for variation " << myPlayedVariation; + buf << "Can't open/save to high scores file for variation " << variation; instance().frameBuffer().showMessage(buf.str()); - return; } // Do a complete high scores save - if (!save(out)) + if (!save(out, variation)) { buf.str(""); - buf << "Error saving high scores for variation" << myPlayedVariation; + buf << "Error saving high scores for variation" << variation; instance().frameBuffer().showMessage(buf.str()); } } @@ -343,30 +363,6 @@ void HighScoresDialog::loadHighScores(Int32 variation) myDates[p] = ""; } - ///////////////////////////////////////////////////////////////////////////////////////////////// - /* - // mock data - const Int32 SCORES[NUM_POSITIONS] = {999999, 250000, 100000, 50000, 20000, - 5000, 2000, 200, 20, 0}; - const Int32 SPECIALS[NUM_POSITIONS] = {200, 150, 90, 70, 45, - 30, 25, 10, 7, 0}; - const string NAMES[NUM_POSITIONS] = {"RAM", "CDW", "AD ", "JTZ", "DOA", - "ROM", "VCS", "N.S", "JWC", " -"}; - const string DATES[NUM_POSITIONS] = {"19-12-24 21:00", "19-07-18 00:00", "20-01-01 12:00", - "20-02-12 21:50", "20-02-11 14:16", "20-02-11 13:11", - "20-02-10 19:45", "10-02-10 20:04", "05-02-09 22:32", - " - -"}; - - for (Int32 p = 0; p < NUM_POSITIONS; ++p) - { - myHighScores[p] = SCORES[p]; - mySpecials[p] = SPECIALS[p]; - myNames[p] = NAMES[p]; - myDates[p] = DATES[p]; - } - */ - ///////////////////////////////////////////////////////////////////////////////////////////////// - if(instance().hasConsole()) { ostringstream buf; @@ -376,13 +372,9 @@ void HighScoresDialog::loadHighScores(Int32 variation) // Make sure the file can be opened in read-only mode Serializer in(buf.str(), Serializer::Mode::ReadOnly); + if(!in) - { - //buf.str(""); - //buf << "No high scores file for variation " << variation << " found."; - //instance().frameBuffer().showMessage(buf.str()); return; - } // First test if we have a valid header // If so, do a complete high scores load @@ -394,7 +386,6 @@ void HighScoresDialog::loadHighScores(Int32 variation) else { if (load(in, variation)) - //buf << "High scores for variation " << variation << " loaded"; return; else buf << "Invalid data in high scores for variation " << variation << " file"; @@ -410,7 +401,7 @@ void HighScoresDialog::loadHighScores(Int32 variation) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool HighScoresDialog::save(Serializer& out) const +bool HighScoresDialog::save(Serializer& out, Int32 variation) const { try { @@ -419,7 +410,7 @@ bool HighScoresDialog::save(Serializer& out) const out.putString(HIGHSCORE_HEADER); out.putString(myMD5); - out.putInt(myPlayedVariation); + out.putInt(variation); for (Int32 p = 0; p < NUM_POSITIONS; ++p) { out.putInt(myHighScores[p]); @@ -442,13 +433,10 @@ bool HighScoresDialog::load(Serializer& in, Int32 variation) try { if (in.getString() != myMD5) - { return false; - } if (Int32(in.getInt()) != variation) - { return false; - } + for (Int32 p = 0; p < NUM_POSITIONS; ++p) { myHighScores[p] = in.getInt(); @@ -464,3 +452,19 @@ bool HighScoresDialog::load(Serializer& in, Int32 variation) } return true; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string HighScoresDialog::now() const +{ + std::tm now = BSPF::localTime(); + ostringstream ss; + + ss << std::setfill('0') << std::right + << std::setw(2) << (now.tm_year - 100) << '-' + << std::setw(2) << (now.tm_mon + 1) << '-' + << std::setw(2) << now.tm_mday << " " + << std::setw(2) << now.tm_hour << ":" + << std::setw(2) << now.tm_min; + + return ss.str(); +} diff --git a/src/gui/HighScoresDialog.hxx b/src/gui/HighScoresDialog.hxx index 7f11bff98..539ab803c 100644 --- a/src/gui/HighScoresDialog.hxx +++ b/src/gui/HighScoresDialog.hxx @@ -51,11 +51,13 @@ class HighScoresDialog : public Dialog void saveConfig() override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - void handlePlayedVariation(); + void updateWidgets(bool init = false); void handleVariation(bool init = false); - void resetVisibility(); + void handlePlayedVariation(); - void saveHighScores() const; + void deletePos(int pos); + + void saveHighScores(Int32 variation) const; void loadHighScores(Int32 variation); /** @@ -64,7 +66,7 @@ class HighScoresDialog : public Dialog @param out The serializer device to save to. @return The result of the save. True on success, false on failure. */ - bool save(Serializer& out) const; + bool save(Serializer& out, Int32 variation) const; /** Loads the current high scores for this game and variation from the given Serializer. @@ -74,15 +76,15 @@ class HighScoresDialog : public Dialog */ bool load(Serializer& in, Int32 variation); - enum { - kVariationChanged = 'Vach' - }; + string now() const; + enum { + kVariationChanged = 'Vach', + kDeleteSingle = 'DeSi' + }; private: string myInitials; - Int32 myDisplayedVariation; - Int32 myPlayedVariation; Int32 myEditPos; Int32 myHighScorePos; string myNow; @@ -101,9 +103,9 @@ class HighScoresDialog : public Dialog StaticTextWidget* myNamesWidget[NUM_POSITIONS]{nullptr}; EditTextWidget* myEditNamesWidget[NUM_POSITIONS]{nullptr}; StaticTextWidget* myDatesWidget[NUM_POSITIONS]{nullptr}; - StaticTextWidget* myMD5Widget{nullptr}; + ButtonWidget* myDeleteButtons[NUM_POSITIONS]{nullptr}; - string now() const; + StaticTextWidget* myMD5Widget{nullptr}; private: // Following constructors and assignment operators not supported