add delete options to HighScoresDialog

This commit is contained in:
thrust26 2020-02-15 23:49:14 +01:00
parent e1467acf66
commit 2b86772d6c
2 changed files with 133 additions and 127 deletions

View File

@ -48,7 +48,7 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
WidgetArray wid; WidgetArray wid;
VariantList items; VariantList items;
_w = 40 * fontWidth + HBORDER * 2; // max_w - 20; _w = 44 * fontWidth + HBORDER * 2; // max_w - 20;
_h = 400; // max_h - 20; _h = 400; // max_h - 20;
ypos = VBORDER + _th; xpos = HBORDER; ypos = VBORDER + _th; xpos = HBORDER;
@ -69,6 +69,7 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
int xposSpecial = xposScore + font.getStringWidth("Score") + 24; int xposSpecial = xposScore + font.getStringWidth("Score") + 24;
int xposName = xposSpecial + font.getStringWidth("Round") + 16; int xposName = xposSpecial + font.getStringWidth("Round") + 16;
int xposDate = xposName + font.getStringWidth("Name") + 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; int nWidth = font.getStringWidth("ABC") + 4;
new StaticTextWidget(this, font, xposRank, ypos + 1, "Rank"); new StaticTextWidget(this, font, xposRank, ypos + 1, "Rank");
@ -91,6 +92,10 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
myEditNamesWidget[p]->setEnabled(false); myEditNamesWidget[p]->setEnabled(false);
wid.push_back(myEditNamesWidget[p]); wid.push_back(myEditNamesWidget[p]);
myDatesWidget[p] = new StaticTextWidget(this, font, xposDate, ypos + 1, "12-02-20 17:15"); 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; ypos += lineHeight + VGAP;
} }
@ -98,7 +103,7 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
myMD5Widget = new StaticTextWidget(this, ifont, xpos, ypos + 1, "MD5: 12345678901234567890123456789012"); myMD5Widget = new StaticTextWidget(this, ifont, xpos, ypos + 1, "MD5: 12345678901234567890123456789012");
addOKCancelBGroup(wid, font); addDefaultsOKCancelBGroup(wid, font, "Save", "Cancel", " Reset ");
addToFocusList(wid); addToFocusList(wid);
} }
@ -129,24 +134,13 @@ void HighScoresDialog::loadConfig()
VarList::push_back(items, buf.str(), i); VarList::push_back(items, buf.str(), i);
} }
myVariationWidget->addItems(items); myVariationWidget->addItems(items);
myDisplayedVariation = instance().highScores().variation(); myVariationWidget->setSelected(instance().highScores().variation());
myVariationWidget->setSelected(myDisplayedVariation);
mySpecialLabelWidget->setLabel(instance().highScores().specialLabel()); 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); myMD5 = instance().console().properties().get(PropType::Cart_MD5);
myMD5Widget->setLabel("MD5: " + myMD5); myMD5Widget->setLabel("MD5: " + myMD5);
myPlayedVariation = instance().highScores().variation();
myEditPos = myHighScorePos = -1; myEditPos = myHighScorePos = -1;
myNow = now(); myNow = now();
handleVariation(true); handleVariation(true);
@ -155,17 +149,17 @@ void HighScoresDialog::loadConfig()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void HighScoresDialog::saveConfig() void HighScoresDialog::saveConfig()
{ {
// save initials and remember for the next time
if (myHighScorePos != -1) if (myHighScorePos != -1)
{ {
if (myDisplayedVariation != myPlayedVariation)
{
loadHighScores(myPlayedVariation);
handlePlayedVariation();
}
myInitials = myEditNamesWidget[myHighScorePos]->getText(); myInitials = myEditNamesWidget[myHighScorePos]->getText();
myNames[myHighScorePos] = myInitials; 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(); saveConfig();
// falls through... // falls through...
case kCloseCmd: case kCloseCmd:
resetVisibility();
instance().eventHandler().leaveMenuMode(); instance().eventHandler().leaveMenuMode();
break; break;
@ -185,8 +178,15 @@ void HighScoresDialog::handleCommand(CommandSender* sender, int cmd, int data, i
handleVariation(); handleVariation();
break; break;
case Event::UISelect: case kDeleteSingle:
resetVisibility(); deletePos(id);
updateWidgets();
break;
case GuiObject::kDefaultsCmd:
for (int p = NUM_POSITIONS - 1; p >= 0; --p)
deletePos(p);
updateWidgets();
break; break;
default: 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(); // TODO: if anything changed, asked for saving
ostringstream ss; Int32 variation = myVariationWidget->getSelectedTag().toInt();
ss << std::setfill('0') << std::right loadHighScores(variation);
<< 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(); 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 ostringstream buf;
myEditNamesWidget[myEditPos]->setFlags(EditTextWidget::FLAG_INVISIBLE);
myEditNamesWidget[myEditPos]->setEnabled(false); if (myHighScores[p] > 0)
myNamesWidget[myEditPos]->clearFlags(EditTextWidget::FLAG_INVISIBLE); {
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(); for (Int32 p = pos; p < NUM_POSITIONS - 1; ++p)
myDisplayedVariation = myVariationWidget->getSelectedTag().toInt();
loadHighScores(myDisplayedVariation);
myEditPos = -1;
if (myDisplayedVariation == myPlayedVariation)
{ {
handlePlayedVariation(); myHighScores[p] = myHighScores[p + 1];
mySpecials[p] = mySpecials[p + 1];
if (myHighScorePos != -1) myNames[p] = myNames[p + 1];
{ myDates[p] = myDates[p + 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[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; myHighScorePos = myEditPos = -1;
}
if (myHighScores[p] > 0) if (myEditPos > pos)
buf << std::setw(HSM::MAX_SCORE_DIGITS) << std::setfill(' ') << myHighScores[p]; {
myScoresWidget[p]->setLabel(buf.str()); myHighScorePos--;
myEditPos--;
buf.str(""); myEditNamesWidget[myEditPos]->setText(myEditNamesWidget[myEditPos + 1]->getText());
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]);
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void HighScoresDialog::saveHighScores() const void HighScoresDialog::saveHighScores(Int32 variation) const
{ {
if(instance().hasConsole()) if(instance().hasConsole())
{ {
ostringstream buf; ostringstream buf;
buf << instance().stateDir() buf << instance().stateDir()
<< instance().console().properties().get(PropType::Cart_Name) << instance().console().properties().get(PropType::Cart_Name)
<< ".hs" << myPlayedVariation; << ".hs" << variation;
// Make sure the file can be opened for writing // Make sure the file can be opened for writing
Serializer out(buf.str()); Serializer out(buf.str());
@ -317,16 +338,15 @@ void HighScoresDialog::saveHighScores() const
if(!out) if(!out)
{ {
buf.str(""); 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()); instance().frameBuffer().showMessage(buf.str());
return;
} }
// Do a complete high scores save // Do a complete high scores save
if (!save(out)) if (!save(out, variation))
{ {
buf.str(""); buf.str("");
buf << "Error saving high scores for variation" << myPlayedVariation; buf << "Error saving high scores for variation" << variation;
instance().frameBuffer().showMessage(buf.str()); instance().frameBuffer().showMessage(buf.str());
} }
} }
@ -343,30 +363,6 @@ void HighScoresDialog::loadHighScores(Int32 variation)
myDates[p] = ""; 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()) if(instance().hasConsole())
{ {
ostringstream buf; ostringstream buf;
@ -376,13 +372,9 @@ void HighScoresDialog::loadHighScores(Int32 variation)
// Make sure the file can be opened in read-only mode // Make sure the file can be opened in read-only mode
Serializer in(buf.str(), Serializer::Mode::ReadOnly); Serializer in(buf.str(), Serializer::Mode::ReadOnly);
if(!in) if(!in)
{
//buf.str("");
//buf << "No high scores file for variation " << variation << " found.";
//instance().frameBuffer().showMessage(buf.str());
return; return;
}
// First test if we have a valid header // First test if we have a valid header
// If so, do a complete high scores load // If so, do a complete high scores load
@ -394,7 +386,6 @@ void HighScoresDialog::loadHighScores(Int32 variation)
else else
{ {
if (load(in, variation)) if (load(in, variation))
//buf << "High scores for variation " << variation << " loaded";
return; return;
else else
buf << "Invalid data in high scores for variation " << variation << " file"; 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 try
{ {
@ -419,7 +410,7 @@ bool HighScoresDialog::save(Serializer& out) const
out.putString(HIGHSCORE_HEADER); out.putString(HIGHSCORE_HEADER);
out.putString(myMD5); out.putString(myMD5);
out.putInt(myPlayedVariation); out.putInt(variation);
for (Int32 p = 0; p < NUM_POSITIONS; ++p) for (Int32 p = 0; p < NUM_POSITIONS; ++p)
{ {
out.putInt(myHighScores[p]); out.putInt(myHighScores[p]);
@ -442,13 +433,10 @@ bool HighScoresDialog::load(Serializer& in, Int32 variation)
try try
{ {
if (in.getString() != myMD5) if (in.getString() != myMD5)
{
return false; return false;
}
if (Int32(in.getInt()) != variation) if (Int32(in.getInt()) != variation)
{
return false; return false;
}
for (Int32 p = 0; p < NUM_POSITIONS; ++p) for (Int32 p = 0; p < NUM_POSITIONS; ++p)
{ {
myHighScores[p] = in.getInt(); myHighScores[p] = in.getInt();
@ -464,3 +452,19 @@ bool HighScoresDialog::load(Serializer& in, Int32 variation)
} }
return true; 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();
}

View File

@ -51,11 +51,13 @@ class HighScoresDialog : public Dialog
void saveConfig() override; void saveConfig() override;
void handleCommand(CommandSender* sender, int cmd, int data, int id) 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 handleVariation(bool init = false);
void resetVisibility(); void handlePlayedVariation();
void saveHighScores() const; void deletePos(int pos);
void saveHighScores(Int32 variation) const;
void loadHighScores(Int32 variation); void loadHighScores(Int32 variation);
/** /**
@ -64,7 +66,7 @@ class HighScoresDialog : public Dialog
@param out The serializer device to save to. @param out The serializer device to save to.
@return The result of the save. True on success, false on failure. @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. 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); bool load(Serializer& in, Int32 variation);
enum { string now() const;
kVariationChanged = 'Vach'
};
enum {
kVariationChanged = 'Vach',
kDeleteSingle = 'DeSi'
};
private: private:
string myInitials; string myInitials;
Int32 myDisplayedVariation;
Int32 myPlayedVariation;
Int32 myEditPos; Int32 myEditPos;
Int32 myHighScorePos; Int32 myHighScorePos;
string myNow; string myNow;
@ -101,9 +103,9 @@ class HighScoresDialog : public Dialog
StaticTextWidget* myNamesWidget[NUM_POSITIONS]{nullptr}; StaticTextWidget* myNamesWidget[NUM_POSITIONS]{nullptr};
EditTextWidget* myEditNamesWidget[NUM_POSITIONS]{nullptr}; EditTextWidget* myEditNamesWidget[NUM_POSITIONS]{nullptr};
StaticTextWidget* myDatesWidget[NUM_POSITIONS]{nullptr}; StaticTextWidget* myDatesWidget[NUM_POSITIONS]{nullptr};
StaticTextWidget* myMD5Widget{nullptr}; ButtonWidget* myDeleteButtons[NUM_POSITIONS]{nullptr};
string now() const; StaticTextWidget* myMD5Widget{nullptr};
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported