mirror of https://github.com/stella-emu/stella.git
added cancel option (button, enter, ESC) to ProgressDialog
adapted all ProgressDialog using actions to allow canceling
This commit is contained in:
parent
6e4052763b
commit
b569444854
|
@ -3689,19 +3689,29 @@
|
||||||
<p>ROM Info Viewer width at 50% , UI sized 1280x900, large launcher font:</p>
|
<p>ROM Info Viewer width at 50% , UI sized 1280x900, large launcher font:</p>
|
||||||
<img src="graphics/rominfo_2x_small.png">
|
<img src="graphics/rominfo_2x_small.png">
|
||||||
|
|
||||||
<p>The 'Show all files' checkbox allows displaying files which do not
|
<p>The dialog items at the top can be used to define the listed files:</p>
|
||||||
have a valid ROM extension. The 'Filter' text box can be used to narrow down
|
|
||||||
the results in the ROM listing. When this box is empty, all files are shown.
|
<ul>
|
||||||
Typing characters here will show only those files that match that
|
<li>
|
||||||
pattern. For example, typing 'Activision' will show only files that
|
The 'Show all files' checkbox allows displaying files which do not
|
||||||
contain the word 'Activision' in their name. This is very useful for
|
have a valid ROM extension.
|
||||||
quickly finding a group of related ROMs.</p>
|
</li><li>
|
||||||
<p>Note that the search is not case sensitive, so you don't need to worry about
|
The 'Filter' text box can be used to narrow down the results in the
|
||||||
capital or lower-case letters. Also you can use '*' and '?' as wildcards. E.g.
|
ROM listing. When this box is empty, all files are shown. Typing
|
||||||
for '(198?)*atari' only games from the 1980s made by Atari will be listed.</p>
|
characters here will show only those files that match that
|
||||||
<p>When there are least three characters in the filter, the checkbox 'Incl.
|
pattern. For example, typing 'Activision' will show only files that
|
||||||
subdirectories' gets enabled. When checked, Stella will search files in all
|
contain the word 'Activision' in their name. This is very useful for
|
||||||
subdirectories too.</p>
|
quickly finding a group of related ROMs.</br>
|
||||||
|
Note that the search is not case sensitive, so you don't need to worry
|
||||||
|
about capital or lower-case letters. You also can use '*' and '?' as
|
||||||
|
wildcards. E.g. for '(198?)*atari' only ROMs from the 1980s made by
|
||||||
|
Atari will be listed.
|
||||||
|
</li><li>
|
||||||
|
If 'Incl. subdirectories' is checked, Stella will list matching files
|
||||||
|
from all subdirectories too.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</br>
|
||||||
|
|
||||||
<h3><b><a name="ROMLauncherContextMenu">ROM Launcher Context Menu</a></b></h3>
|
<h3><b><a name="ROMLauncherContextMenu">ROM Launcher Context Menu</a></b></h3>
|
||||||
|
|
||||||
|
|
|
@ -1747,9 +1747,13 @@ void DebuggerParser::executeRunTo()
|
||||||
// Create a progress dialog box to show the progress searching through the
|
// Create a progress dialog box to show the progress searching through the
|
||||||
// disassembly, since this may be a time-consuming operation
|
// disassembly, since this may be a time-consuming operation
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
buf << "RunTo searching through " << max_iterations << " disassembled instructions";
|
ProgressDialog progress(debugger.baseDialog(), debugger.lfont());
|
||||||
ProgressDialog progress(debugger.baseDialog(), debugger.lfont(), buf.str());
|
|
||||||
|
buf << "RunTo searching through " << max_iterations << " disassembled instructions"
|
||||||
|
<< progress.ELLIPSIS;
|
||||||
|
progress.setMessage(buf.str());
|
||||||
progress.setRange(0, max_iterations, 5);
|
progress.setRange(0, max_iterations, 5);
|
||||||
|
progress.open();
|
||||||
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
do {
|
do {
|
||||||
|
@ -1763,8 +1767,8 @@ void DebuggerParser::executeRunTo()
|
||||||
done = (BSPF::findIgnoreCase(next, argStrings[0]) != string::npos);
|
done = (BSPF::findIgnoreCase(next, argStrings[0]) != string::npos);
|
||||||
}
|
}
|
||||||
// Update the progress bar
|
// Update the progress bar
|
||||||
progress.setProgress(count);
|
progress.incProgress();
|
||||||
} while(!done && ++count < max_iterations);
|
} while(!done && ++count < max_iterations && !progress.isCancelled());
|
||||||
|
|
||||||
progress.close();
|
progress.close();
|
||||||
|
|
||||||
|
@ -1789,13 +1793,15 @@ void DebuggerParser::executeRunToPc()
|
||||||
|
|
||||||
uInt32 count = 0;
|
uInt32 count = 0;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
constexpr uInt32 max_iterations = 1000000;
|
|
||||||
// Create a progress dialog box to show the progress searching through the
|
// Create a progress dialog box to show the progress searching through the
|
||||||
// disassembly, since this may be a time-consuming operation
|
// disassembly, since this may be a time-consuming operation
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
buf << "RunTo PC searching through " << max_iterations << " instructions";
|
ProgressDialog progress(debugger.baseDialog(), debugger.lfont());
|
||||||
ProgressDialog progress(debugger.baseDialog(), debugger.lfont(), buf.str());
|
|
||||||
progress.setRange(0, max_iterations, 5);
|
buf << " RunTo PC running" << progress.ELLIPSIS << " ";
|
||||||
|
progress.setMessage(buf.str());
|
||||||
|
progress.setRange(0, 100000, 5);
|
||||||
|
progress.open();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
debugger.step(false);
|
debugger.step(false);
|
||||||
|
@ -1803,8 +1809,9 @@ void DebuggerParser::executeRunToPc()
|
||||||
// Update romlist to point to current PC
|
// Update romlist to point to current PC
|
||||||
int pcline = cartdbg.addressToLine(debugger.cpuDebug().pc());
|
int pcline = cartdbg.addressToLine(debugger.cpuDebug().pc());
|
||||||
done = (pcline >= 0) && (list[pcline].address == args[0]);
|
done = (pcline >= 0) && (list[pcline].address == args[0]);
|
||||||
progress.setProgress(count);
|
progress.incProgress();
|
||||||
} while(!done && ++count < max_iterations/*list.size()*/);
|
++count;
|
||||||
|
} while(!done && !progress.isCancelled());
|
||||||
progress.close();
|
progress.close();
|
||||||
|
|
||||||
if(done)
|
if(done)
|
||||||
|
@ -1953,20 +1960,24 @@ void DebuggerParser::executeStepwhile()
|
||||||
Expression* expr = YaccParser::getResult();
|
Expression* expr = YaccParser::getResult();
|
||||||
int ncycles = 0;
|
int ncycles = 0;
|
||||||
uInt32 count = 0;
|
uInt32 count = 0;
|
||||||
constexpr uInt32 max_iterations = 1000000;
|
|
||||||
|
|
||||||
// Create a progress dialog box to show the progress searching through the
|
// Create a progress dialog box to show the progress searching through the
|
||||||
// disassembly, since this may be a time-consuming operation
|
// disassembly, since this may be a time-consuming operation
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
buf << "stepwhile running through " << max_iterations << " disassembled instructions";
|
ProgressDialog progress(debugger.baseDialog(), debugger.lfont());
|
||||||
ProgressDialog progress(debugger.baseDialog(), debugger.lfont(), buf.str());
|
|
||||||
progress.setRange(0, max_iterations, 5);
|
buf << "stepwhile running through disassembled instructions"
|
||||||
|
<< progress.ELLIPSIS;
|
||||||
|
progress.setMessage(buf.str());
|
||||||
|
progress.setRange(0, 100000, 5);
|
||||||
|
progress.open();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ncycles += debugger.step(false);
|
ncycles += debugger.step(false);
|
||||||
|
|
||||||
progress.setProgress(count);
|
progress.incProgress();
|
||||||
} while (expr->evaluate() && ++count < max_iterations);
|
++count;
|
||||||
|
} while (expr->evaluate() && !progress.isCancelled());
|
||||||
|
|
||||||
progress.close();
|
progress.close();
|
||||||
commandResult << "executed " << ncycles << " cycles";
|
commandResult << "executed " << ncycles << " cycles";
|
||||||
|
|
|
@ -79,9 +79,10 @@ bool FilesystemNode::exists() const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FilesystemNode::getAllChildren(FSList& fslist, ListMode mode,
|
bool FilesystemNode::getAllChildren(FSList& fslist, ListMode mode,
|
||||||
const NameFilter& filter,
|
const NameFilter& filter,
|
||||||
bool includeParentDirectory) const
|
bool includeParentDirectory,
|
||||||
|
const CancelCheck& isCancelled) const
|
||||||
{
|
{
|
||||||
if(getChildren(fslist, mode, filter, includeParentDirectory))
|
if(getChildren(fslist, mode, filter, includeParentDirectory, true, isCancelled))
|
||||||
{
|
{
|
||||||
// Sort only once at the end
|
// Sort only once at the end
|
||||||
#if defined(ZIP_SUPPORT)
|
#if defined(ZIP_SUPPORT)
|
||||||
|
@ -124,7 +125,6 @@ bool FilesystemNode::getAllChildren(FSList& fslist, ListMode mode,
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,8 @@ bool FilesystemNode::getAllChildren(FSList& fslist, ListMode mode,
|
||||||
bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
|
bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
|
||||||
const NameFilter& filter,
|
const NameFilter& filter,
|
||||||
bool includeChildDirectories,
|
bool includeChildDirectories,
|
||||||
bool includeParentDirectory) const
|
bool includeParentDirectory,
|
||||||
|
const CancelCheck& isCancelled) const
|
||||||
{
|
{
|
||||||
if (!_realNode || !_realNode->isDirectory())
|
if (!_realNode || !_realNode->isDirectory())
|
||||||
return false;
|
return false;
|
||||||
|
@ -146,6 +147,9 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
|
||||||
// when incuding child directories, everything must be sorted once at the end
|
// when incuding child directories, everything must be sorted once at the end
|
||||||
if(!includeChildDirectories)
|
if(!includeChildDirectories)
|
||||||
{
|
{
|
||||||
|
if(isCancelled())
|
||||||
|
return false;
|
||||||
|
|
||||||
#if defined(ZIP_SUPPORT)
|
#if defined(ZIP_SUPPORT)
|
||||||
// before sorting, replace single file ZIP archive names with contained file names
|
// before sorting, replace single file ZIP archive names with contained file names
|
||||||
// because they are displayed using their contained file names
|
// because they are displayed using their contained file names
|
||||||
|
@ -182,6 +186,9 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
|
||||||
// And now add the rest of the entries
|
// And now add the rest of the entries
|
||||||
for (const auto& i: tmp)
|
for (const auto& i: tmp)
|
||||||
{
|
{
|
||||||
|
if(isCancelled())
|
||||||
|
return false;
|
||||||
|
|
||||||
#if defined(ZIP_SUPPORT)
|
#if defined(ZIP_SUPPORT)
|
||||||
if (BSPF::endsWithIgnoreCase(i->getPath(), ".zip"))
|
if (BSPF::endsWithIgnoreCase(i->getPath(), ".zip"))
|
||||||
{
|
{
|
||||||
|
@ -214,7 +221,7 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
|
||||||
if(includeChildDirectories)
|
if(includeChildDirectories)
|
||||||
{
|
{
|
||||||
if(i->isDirectory())
|
if(i->isDirectory())
|
||||||
node.getChildren(fslist, mode, filter, includeChildDirectories, false);
|
node.getChildren(fslist, mode, filter, includeChildDirectories, false, isCancelled);
|
||||||
else
|
else
|
||||||
// do not add directories in this mode
|
// do not add directories in this mode
|
||||||
if(filter(node))
|
if(filter(node))
|
||||||
|
@ -227,7 +234,6 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ class FilesystemNode
|
||||||
/** Function used to filter the file listing. Returns true if the filename
|
/** Function used to filter the file listing. Returns true if the filename
|
||||||
should be included, else false.*/
|
should be included, else false.*/
|
||||||
using NameFilter = std::function<bool(const FilesystemNode& node)>;
|
using NameFilter = std::function<bool(const FilesystemNode& node)>;
|
||||||
|
using CancelCheck = std::function<bool()> const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new pathless FilesystemNode. Since there's no path associated
|
* Create a new pathless FilesystemNode. Since there's no path associated
|
||||||
|
@ -123,7 +124,8 @@ class FilesystemNode
|
||||||
*/
|
*/
|
||||||
bool getAllChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly,
|
bool getAllChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly,
|
||||||
const NameFilter& filter = [](const FilesystemNode&) { return true; },
|
const NameFilter& filter = [](const FilesystemNode&) { return true; },
|
||||||
bool includeParentDirectory = true) const;
|
bool includeParentDirectory = true,
|
||||||
|
const CancelCheck& isCancelled = []() { return false; }) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of child nodes of this directory node. If called on a node
|
* Return a list of child nodes of this directory node. If called on a node
|
||||||
|
@ -135,7 +137,8 @@ class FilesystemNode
|
||||||
bool getChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly,
|
bool getChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly,
|
||||||
const NameFilter& filter = [](const FilesystemNode&){ return true; },
|
const NameFilter& filter = [](const FilesystemNode&){ return true; },
|
||||||
bool includeChildDirectories = false,
|
bool includeChildDirectories = false,
|
||||||
bool includeParentDirectory = true) const;
|
bool includeParentDirectory = true,
|
||||||
|
const CancelCheck& isCancelled = []() { return false; }) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set/get a string representation of the name of the file. This is can be
|
* Set/get a string representation of the name of the file. This is can be
|
||||||
|
|
|
@ -75,6 +75,9 @@ void FileListWidget::setLocation(const FilesystemNode& node,
|
||||||
{
|
{
|
||||||
progress().resetProgress();
|
progress().resetProgress();
|
||||||
progress().open();
|
progress().open();
|
||||||
|
class FilesystemNode::CancelCheck isCancelled = []() {
|
||||||
|
return myProgressDialog->isCancelled();
|
||||||
|
};
|
||||||
|
|
||||||
_node = node;
|
_node = node;
|
||||||
|
|
||||||
|
@ -85,21 +88,24 @@ void FileListWidget::setLocation(const FilesystemNode& node,
|
||||||
{
|
{
|
||||||
// Actually this could become HUGE
|
// Actually this could become HUGE
|
||||||
_fileList.reserve(0x2000);
|
_fileList.reserve(0x2000);
|
||||||
_node.getAllChildren(_fileList, _fsmode, _filter);
|
_node.getAllChildren(_fileList, _fsmode, _filter, true, isCancelled);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_fileList.reserve(0x200);
|
_fileList.reserve(0x200);
|
||||||
_node.getChildren(_fileList, _fsmode, _filter);
|
_node.getChildren(_fileList, _fsmode, _filter, false, true, isCancelled);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now fill the list widget with the names from the file list
|
if(!isCancelled())
|
||||||
StringList l;
|
{
|
||||||
for(const auto& file : _fileList)
|
// Now fill the list widget with the names from the file list
|
||||||
l.push_back(file.getName());
|
StringList l;
|
||||||
|
for(const auto& file : _fileList)
|
||||||
|
l.push_back(file.getName());
|
||||||
|
|
||||||
setList(l);
|
setList(l);
|
||||||
setSelected(select);
|
setSelected(select);
|
||||||
|
}
|
||||||
|
|
||||||
ListWidget::recalc();
|
ListWidget::recalc();
|
||||||
|
|
||||||
|
@ -134,7 +140,7 @@ void FileListWidget::reload()
|
||||||
ProgressDialog& FileListWidget::progress()
|
ProgressDialog& FileListWidget::progress()
|
||||||
{
|
{
|
||||||
if(myProgressDialog == nullptr)
|
if(myProgressDialog == nullptr)
|
||||||
myProgressDialog = make_unique<ProgressDialog>(this, _font, "", false);
|
myProgressDialog = make_unique<ProgressDialog>(this, _font, "");
|
||||||
|
|
||||||
return *myProgressDialog;
|
return *myProgressDialog;
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,10 +177,8 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
// Show the subdirectories checkbox
|
// Show the subdirectories checkbox
|
||||||
xpos -= cwSubDirs + LBL_GAP;
|
xpos -= cwSubDirs + LBL_GAP;
|
||||||
mySubDirs = new CheckboxWidget(this, font, xpos, ypos, lblSubDirs, kSubDirsCmd);
|
mySubDirs = new CheckboxWidget(this, font, xpos, ypos, lblSubDirs, kSubDirsCmd);
|
||||||
mySubDirs->setEnabled(false);
|
|
||||||
ostringstream tip;
|
ostringstream tip;
|
||||||
tip << "Search files in subdirectories too.\n"
|
tip << "Search files in subdirectories too.";
|
||||||
<< "Filter must have at least " << MIN_SUBDIRS_CHARS << " chars.";
|
|
||||||
mySubDirs->setToolTip(tip.str());
|
mySubDirs->setToolTip(tip.str());
|
||||||
|
|
||||||
// Show the filter input field
|
// Show the filter input field
|
||||||
|
@ -780,15 +778,14 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EditableWidget::kChangedCmd:
|
case EditableWidget::kChangedCmd:
|
||||||
|
case EditableWidget::kAcceptCmd:
|
||||||
{
|
{
|
||||||
bool subAllowed = myPattern->getText().length() >= MIN_SUBDIRS_CHARS;
|
bool subDirs = mySubDirs->getState();
|
||||||
bool subDirs = subAllowed && mySubDirs->getState();
|
|
||||||
|
|
||||||
mySubDirs->setEnabled(subAllowed);
|
|
||||||
myList->setIncludeSubDirs(subDirs);
|
myList->setIncludeSubDirs(subDirs);
|
||||||
applyFiltering(); // pattern matching taken care of directly in this method
|
applyFiltering(); // pattern matching taken care of directly in this method
|
||||||
|
|
||||||
if(subDirs)
|
if(subDirs && cmd == EditableWidget::kChangedCmd)
|
||||||
{
|
{
|
||||||
// delay (potentially slow) subdirectories reloads until user stops typing
|
// delay (potentially slow) subdirectories reloads until user stops typing
|
||||||
myReloadTime = TimerManager::getTicks() / 1000 + myList->getQuickSelectDelay();
|
myReloadTime = TimerManager::getTicks() / 1000 + myList->getQuickSelectDelay();
|
||||||
|
|
|
@ -102,7 +102,6 @@ class LauncherDialog : public Dialog
|
||||||
static constexpr int MIN_ROMINFO_CHARS = 30;
|
static constexpr int MIN_ROMINFO_CHARS = 30;
|
||||||
static constexpr int MIN_ROMINFO_ROWS = 7; // full lines
|
static constexpr int MIN_ROMINFO_ROWS = 7; // full lines
|
||||||
static constexpr int MIN_ROMINFO_LINES = 4; // extra lines
|
static constexpr int MIN_ROMINFO_LINES = 4; // extra lines
|
||||||
static constexpr int MIN_SUBDIRS_CHARS = 3; // minimum filter chars for subdirectory search
|
|
||||||
|
|
||||||
void setPosition() override { positionAt(0); }
|
void setPosition() override { positionAt(0); }
|
||||||
void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override;
|
void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override;
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
#include "FrameBuffer.hxx"
|
#include "FrameBuffer.hxx"
|
||||||
|
#include "EventHandler.hxx"
|
||||||
|
#include "TimerManager.hxx"
|
||||||
#include "Widget.hxx"
|
#include "Widget.hxx"
|
||||||
#include "Dialog.hxx"
|
#include "Dialog.hxx"
|
||||||
#include "Font.hxx"
|
#include "Font.hxx"
|
||||||
|
@ -26,7 +28,7 @@
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
ProgressDialog::ProgressDialog(GuiObject* boss, const GUI::Font& font,
|
ProgressDialog::ProgressDialog(GuiObject* boss, const GUI::Font& font,
|
||||||
const string& message, bool openDialog)
|
const string& message)
|
||||||
: Dialog(boss->instance(), boss->parent()),
|
: Dialog(boss->instance(), boss->parent()),
|
||||||
myFont(font)
|
myFont(font)
|
||||||
{
|
{
|
||||||
|
@ -35,41 +37,56 @@ ProgressDialog::ProgressDialog(GuiObject* boss, const GUI::Font& font,
|
||||||
lineHeight = font.getLineHeight(),
|
lineHeight = font.getLineHeight(),
|
||||||
VBORDER = fontHeight / 2,
|
VBORDER = fontHeight / 2,
|
||||||
HBORDER = fontWidth * 1.25,
|
HBORDER = fontWidth * 1.25,
|
||||||
VGAP = fontHeight / 4;
|
VGAP = fontHeight / 4,
|
||||||
int xpos, ypos, lwidth;
|
buttonHeight = font.getLineHeight() * 1.25,
|
||||||
|
BTN_BORDER = fontWidth * 2.5,
|
||||||
|
buttonWidth = font.getStringWidth("Cancel") + BTN_BORDER,
|
||||||
|
lwidth = font.getStringWidth(message);
|
||||||
|
|
||||||
|
int xpos, ypos;
|
||||||
|
WidgetArray wid;
|
||||||
|
|
||||||
// Calculate real dimensions
|
// Calculate real dimensions
|
||||||
lwidth = font.getStringWidth(message);
|
_w = HBORDER * 2 + std::max(lwidth, buttonWidth);
|
||||||
_w = HBORDER * 2 + lwidth;
|
_h = VBORDER * 2 + lineHeight * 2 + buttonHeight + VGAP * 6;
|
||||||
_h = VBORDER * 2 + lineHeight * 2 + VGAP * 2;
|
|
||||||
|
|
||||||
xpos = HBORDER; ypos = VBORDER;
|
xpos = HBORDER; ypos = VBORDER;
|
||||||
myMessage = new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight,
|
myMessage = new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight,
|
||||||
message, TextAlign::Center);
|
message, TextAlign::Center);
|
||||||
myMessage->setTextColor(kTextColorEm);
|
myMessage->setTextColor(kTextColorEm);
|
||||||
|
|
||||||
xpos = HBORDER; ypos += lineHeight + VGAP * 2;
|
ypos += lineHeight + VGAP * 2;
|
||||||
mySlider = new SliderWidget(this, font, xpos, ypos, lwidth, lineHeight, "", 0, 0);
|
mySlider = new SliderWidget(this, font, xpos, ypos, lwidth, lineHeight,
|
||||||
|
"", 0, 0);
|
||||||
mySlider->setMinValue(1);
|
mySlider->setMinValue(1);
|
||||||
mySlider->setMaxValue(100);
|
mySlider->setMaxValue(100);
|
||||||
|
|
||||||
if(openDialog)
|
ypos += lineHeight + VGAP * 4;
|
||||||
open();
|
ButtonWidget* b = new ButtonWidget(this, font, (_w - buttonWidth) / 2, ypos,
|
||||||
|
buttonWidth, buttonHeight, "Cancel",
|
||||||
|
Event::UICancel);
|
||||||
|
wid.push_back(b);
|
||||||
|
addCancelWidget(b);
|
||||||
|
addToFocusList(wid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void ProgressDialog::setMessage(const string& message)
|
void ProgressDialog::setMessage(const string& message)
|
||||||
{
|
{
|
||||||
const int fontWidth = myFont.getMaxCharWidth(),
|
const int fontWidth = myFont.getMaxCharWidth(),
|
||||||
HBORDER = fontWidth * 1.25;
|
HBORDER = fontWidth * 1.25,
|
||||||
const int lwidth = myFont.getStringWidth(message);
|
lwidth = myFont.getStringWidth(message),
|
||||||
|
BTN_BORDER = fontWidth * 2.5,
|
||||||
|
buttonWidth = myFont.getStringWidth("Cancel") + BTN_BORDER;
|
||||||
|
|
||||||
// Recalculate real dimensions
|
// Recalculate real dimensions
|
||||||
_w = HBORDER * 2 + lwidth;
|
_w = HBORDER * 2 + std::max(lwidth, buttonWidth);
|
||||||
|
|
||||||
myMessage->setWidth(lwidth);
|
myMessage->setWidth(lwidth);
|
||||||
myMessage->setLabel(message);
|
myMessage->setLabel(message);
|
||||||
mySlider->setWidth(lwidth);
|
mySlider->setWidth(lwidth);
|
||||||
|
|
||||||
|
_cancelWidget->setPos((_w - buttonWidth) / 2, _cancelWidget->getTop());
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -88,6 +105,7 @@ void ProgressDialog::resetProgress()
|
||||||
{
|
{
|
||||||
myProgress = myStepProgress = 0;
|
myProgress = myStepProgress = 0;
|
||||||
mySlider->setValue(0);
|
mySlider->setValue(0);
|
||||||
|
myIsCancelled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -100,11 +118,13 @@ void ProgressDialog::setProgress(int progress)
|
||||||
mySlider->setValue(progress % (myFinish - myStart + 1));
|
mySlider->setValue(progress % (myFinish - myStart + 1));
|
||||||
|
|
||||||
// Since this dialog is usually called in a tight loop that doesn't
|
// Since this dialog is usually called in a tight loop that doesn't
|
||||||
// yield, we need to manually tell the framebuffer that a redraw is
|
// yield, we need to manually:
|
||||||
// necessary
|
// - tell the framebuffer that a redraw is necessary
|
||||||
|
// - poll the events
|
||||||
// This isn't really an ideal solution, since all redrawing and
|
// This isn't really an ideal solution, since all redrawing and
|
||||||
// event handling is suspended until the dialog is closed
|
// event handling is suspended until the dialog is closed
|
||||||
instance().frameBuffer().update();
|
instance().frameBuffer().update();
|
||||||
|
instance().eventHandler().poll(TimerManager::getTicks());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,3 +133,20 @@ void ProgressDialog::incProgress()
|
||||||
{
|
{
|
||||||
setProgress(++myProgress);
|
setProgress(++myProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void ProgressDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
|
int data, int id)
|
||||||
|
{
|
||||||
|
switch(cmd)
|
||||||
|
{
|
||||||
|
case Event::UICancel:
|
||||||
|
myIsCancelled = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Dialog::handleCommand(sender, cmd, data, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
class GuiObject;
|
class GuiObject;
|
||||||
class StaticTextWidget;
|
class StaticTextWidget;
|
||||||
class SliderWidget;
|
class SliderWidget;
|
||||||
|
class ButtonWidget;
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "Dialog.hxx"
|
#include "Dialog.hxx"
|
||||||
|
@ -29,7 +30,7 @@ class ProgressDialog : public Dialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProgressDialog(GuiObject* boss, const GUI::Font& font,
|
ProgressDialog(GuiObject* boss, const GUI::Font& font,
|
||||||
const string& message, bool openDialog = true);
|
const string& message = "");
|
||||||
~ProgressDialog() override = default;
|
~ProgressDialog() override = default;
|
||||||
|
|
||||||
void setMessage(const string& message);
|
void setMessage(const string& message);
|
||||||
|
@ -37,6 +38,7 @@ class ProgressDialog : public Dialog
|
||||||
void resetProgress();
|
void resetProgress();
|
||||||
void setProgress(int progress);
|
void setProgress(int progress);
|
||||||
void incProgress();
|
void incProgress();
|
||||||
|
bool isCancelled() const { return myIsCancelled; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const GUI::Font& myFont;
|
const GUI::Font& myFont;
|
||||||
|
@ -46,6 +48,10 @@ class ProgressDialog : public Dialog
|
||||||
int myStart{0}, myFinish{0}, myStep{0};
|
int myStart{0}, myFinish{0}, myStep{0};
|
||||||
int myProgress{0};
|
int myProgress{0};
|
||||||
int myStepProgress{0};
|
int myStepProgress{0};
|
||||||
|
bool myIsCancelled{false};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -119,13 +119,17 @@ void RomAuditDialog::auditRoms()
|
||||||
|
|
||||||
// Create a progress dialog box to show the progress of processing
|
// Create a progress dialog box to show the progress of processing
|
||||||
// the ROMs, since this is usually a time-consuming operation
|
// the ROMs, since this is usually a time-consuming operation
|
||||||
ProgressDialog progress(this, instance().frameBuffer().font(),
|
ostringstream buf;
|
||||||
"Auditing ROM files ...");
|
ProgressDialog progress(this, instance().frameBuffer().font());
|
||||||
|
|
||||||
|
buf << "Auditing ROM files" << ELLIPSIS;
|
||||||
|
progress.setMessage(buf.str());
|
||||||
progress.setRange(0, int(files.size()) - 1, 5);
|
progress.setRange(0, int(files.size()) - 1, 5);
|
||||||
|
progress.open();
|
||||||
|
|
||||||
Properties props;
|
Properties props;
|
||||||
uInt32 renamed = 0, notfound = 0;
|
uInt32 renamed = 0, notfound = 0;
|
||||||
for(uInt32 idx = 0; idx < files.size(); ++idx)
|
for(uInt32 idx = 0; idx < files.size() && !progress.isCancelled(); ++idx)
|
||||||
{
|
{
|
||||||
string extension;
|
string extension;
|
||||||
if(files[idx].isFile() &&
|
if(files[idx].isFile() &&
|
||||||
|
@ -156,7 +160,7 @@ void RomAuditDialog::auditRoms()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the progress bar, indicating one more ROM has been processed
|
// Update the progress bar, indicating one more ROM has been processed
|
||||||
progress.setProgress(idx);
|
progress.incProgress();
|
||||||
}
|
}
|
||||||
progress.close();
|
progress.close();
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,36 @@ void Widget::drawChain()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Widget::setPosX(int x)
|
||||||
|
{
|
||||||
|
setPos(x, _y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Widget::setPosY(int y)
|
||||||
|
{
|
||||||
|
setPos(_x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Widget::setPos(int x, int y)
|
||||||
|
{
|
||||||
|
setPos(Common::Point(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Widget::setPos(const Common::Point& pos)
|
||||||
|
{
|
||||||
|
if(pos != Common::Point(_x, _y))
|
||||||
|
{
|
||||||
|
_x = pos.x;
|
||||||
|
_y = pos.y;
|
||||||
|
// we have to redraw the whole dialog!
|
||||||
|
dialog().setDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Widget::handleMouseEntered()
|
void Widget::handleMouseEntered()
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,10 @@ class Widget : public GuiObject
|
||||||
virtual int getTop() const { return _y; }
|
virtual int getTop() const { return _y; }
|
||||||
virtual int getRight() const { return _x + getWidth(); }
|
virtual int getRight() const { return _x + getWidth(); }
|
||||||
virtual int getBottom() const { return _y + getHeight(); }
|
virtual int getBottom() const { return _y + getHeight(); }
|
||||||
|
virtual void setPosX(int x);
|
||||||
|
virtual void setPosY(int y);
|
||||||
|
virtual void setPos(int x, int y);
|
||||||
|
virtual void setPos(const Common::Point& pos);
|
||||||
|
|
||||||
virtual bool handleText(char text) { return false; }
|
virtual bool handleText(char text) { return false; }
|
||||||
virtual bool handleKeyDown(StellaKey key, StellaMod mod) { return false; }
|
virtual bool handleKeyDown(StellaKey key, StellaMod mod) { return false; }
|
||||||
|
|
Loading…
Reference in New Issue