Merge branch 'release/6.0'
25
Changes.txt
|
@ -12,29 +12,29 @@
|
||||||
Release History
|
Release History
|
||||||
===========================================================================
|
===========================================================================
|
||||||
|
|
||||||
5.1.3 to 5.2: (MMM d, 2018)
|
5.1.3 to 6.0: (MMM d, 2018)
|
||||||
|
|
||||||
* New cycle exact audio core based on work by Chris Brenner (crispy); greatly
|
* New cycle exact audio core based on work by Chris Brenner (crispy); greatly
|
||||||
improved audio emulation accuracy (i.e. E.T., Ms. Pacman)
|
improved audio emulation accuracy (i.e. E.T., Ms. Pacman).
|
||||||
|
|
||||||
* Full rewrite of the audio subsystem; resample TIA output to target sample
|
* Full rewrite of the audio subsystem; resample TIA output to target sample
|
||||||
rate directly in Stella
|
rate directly in Stella.
|
||||||
|
|
||||||
* Threading: decouple emulation from frame rendering
|
* Threading: decouple emulation from frame rendering.
|
||||||
|
|
||||||
* Main loop rewritten; emulating speed and timing is now much more faithful
|
* Main loop rewritten; emulating speed and timing is now much more faithful
|
||||||
(i.e. speed in Pick'n'Pile)
|
(i.e. speed in Pick'n'Pile).
|
||||||
|
|
||||||
* Audio settings replaced with new audio.xxx settings
|
* Audio settings replaced with new 'audio.xxx' settings.
|
||||||
|
|
||||||
* FPS setting replaced with speed setting for adjusting emulation speed
|
* FPS setting replaced with speed setting for adjusting emulation speed.
|
||||||
|
|
||||||
* Extra functionality for Time Machine dialog (start/stop recording;
|
* Extra functionality for Time Machine dialog (start/stop recording;
|
||||||
minor fixes; TODO button and initial key repeats...)
|
minor fixes; TODO button and initial key repeats...)
|
||||||
|
|
||||||
* Fixes for collision corner cases (during HBlank)
|
* Fixes for collision corner cases (during HBlank).
|
||||||
|
|
||||||
* UI modernization (new widget look, dialog titles added, dialogs refactored)
|
* UI modernization (new widget look, dialog titles added, dialogs refactored).
|
||||||
|
|
||||||
* Changes in 'Game Properties' dialog
|
* Changes in 'Game Properties' dialog
|
||||||
- 'Default' button now affects only current tab like in all other dialogs.
|
- 'Default' button now affects only current tab like in all other dialogs.
|
||||||
|
@ -46,8 +46,11 @@
|
||||||
* The Linux builds now use the system-installed PNG and ZLIB libraries
|
* The Linux builds now use the system-installed PNG and ZLIB libraries
|
||||||
by default.
|
by default.
|
||||||
|
|
||||||
|
* When starting Stella for the first time, the first ROM selected will
|
||||||
|
determine which path to use by default for subsequent runs.
|
||||||
|
|
||||||
* Fixed emulator crash when starting SaveKey ROMs from commandline with
|
* Fixed emulator crash when starting SaveKey ROMs from commandline with
|
||||||
SaveKey messages enabled
|
SaveKey messages enabled.
|
||||||
|
|
||||||
* Fixed missing TV format update in frame stats dialog when switching display
|
* Fixed missing TV format update in frame stats dialog when switching display
|
||||||
type.
|
type.
|
||||||
|
@ -57,7 +60,7 @@
|
||||||
* Updated included PNG library to latest stable version.
|
* Updated included PNG library to latest stable version.
|
||||||
|
|
||||||
* For better compatibility, the Windows 32-bit version does not requires SSE2
|
* For better compatibility, the Windows 32-bit version does not requires SSE2
|
||||||
anymore
|
anymore.
|
||||||
|
|
||||||
-Have fun!
|
-Have fun!
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 4.0 KiB |
|
@ -10,7 +10,7 @@
|
||||||
<br><br>
|
<br><br>
|
||||||
<center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center>
|
<center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center>
|
||||||
|
|
||||||
<center><h4><b>Release 5.1.1</b></h4></center>
|
<center><h4><b>Release 6.0</b></h4></center>
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
<center><h2><b>User's Guide</b></h2></center>
|
<center><h2><b>User's Guide</b></h2></center>
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
|
|
||||||
<br><br><br>
|
<br><br><br>
|
||||||
|
|
||||||
<center><b>February 1999 - February 2018</b></center>
|
<center><b>February 1999 - TODO 2018</b></center>
|
||||||
<center><b>The Stella Team</b></center>
|
<center><b>The Stella Team</b></center>
|
||||||
<center><b><a href="https://stella-emu.github.io">Stella Homepage</a></b></center>
|
<center><b><a href="https://stella-emu.github.io">Stella Homepage</a></b></center>
|
||||||
|
|
||||||
|
@ -2736,8 +2736,8 @@
|
||||||
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
|
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
|
||||||
<tr><td>Save path</td><td>Specifies where to save snapshots</td><td>-snapsavedir</td></tr>
|
<tr><td>Save path</td><td>Specifies where to save snapshots</td><td>-snapsavedir</td></tr>
|
||||||
<tr><td>Load path</td><td>Specifies where to load snapshots</td><td>-snaploaddir</td></tr>
|
<tr><td>Load path</td><td>Specifies where to load snapshots</td><td>-snaploaddir</td></tr>
|
||||||
<tr><td>Save snapshots according to</td><td>Specifies how to name saved snapshots</td><td>-snapname</td></tr>
|
|
||||||
<tr><td>Continuous snapshot interval</td><td>Interval (in seconds) between snapshots</td><td>-ssinterval</td></tr>
|
<tr><td>Continuous snapshot interval</td><td>Interval (in seconds) between snapshots</td><td>-ssinterval</td></tr>
|
||||||
|
<tr><td>Use actual ROM name</td><td>Use the actual ROM filename instead of the internal database name.</td><td>-snapname</td></tr>
|
||||||
<tr><td>Overwrite existing files</td><td>Whether to overwrite old snapshots</td><td>-sssingle</td></tr>
|
<tr><td>Overwrite existing files</td><td>Whether to overwrite old snapshots</td><td>-sssingle</td></tr>
|
||||||
<tr><td>Ignore scaling (1x mode)</td><td>Save snapshot in 1x mode without scaling</td><td>-ss1x</td></tr>
|
<tr><td>Ignore scaling (1x mode)</td><td>Save snapshot in 1x mode without scaling</td><td>-ss1x</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -40,19 +40,19 @@ class FilesystemNodeFactory
|
||||||
enum Type { SYSTEM, ZIP };
|
enum Type { SYSTEM, ZIP };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static AbstractFSNode* create(const string& path, Type type)
|
static unique_ptr<AbstractFSNode> create(const string& path, Type type)
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case SYSTEM:
|
case SYSTEM:
|
||||||
#if defined(BSPF_UNIX) || defined(BSPF_MAC_OSX)
|
#if defined(BSPF_UNIX) || defined(BSPF_MAC_OSX)
|
||||||
return new FilesystemNodePOSIX(path);
|
return make_unique<FilesystemNodePOSIX>(path);
|
||||||
#elif defined(BSPF_WINDOWS)
|
#elif defined(BSPF_WINDOWS)
|
||||||
return new FilesystemNodeWINDOWS(path);
|
return make_unique<FilesystemNodeWINDOWS>(path);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case ZIP:
|
case ZIP:
|
||||||
return new FilesystemNodeZIP(path);
|
return make_unique<FilesystemNodeZIP>(path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -29,8 +29,6 @@ FilesystemNodeZIP::FilesystemNodeZIP()
|
||||||
_isDirectory(false),
|
_isDirectory(false),
|
||||||
_isFile(false)
|
_isFile(false)
|
||||||
{
|
{
|
||||||
// We need a name, else the node is invalid
|
|
||||||
_realNode = shared_ptr<AbstractFSNode>(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -92,9 +90,7 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
|
||||||
else
|
else
|
||||||
_isDirectory = true;
|
_isDirectory = true;
|
||||||
|
|
||||||
AbstractFSNode* tmp =
|
_realNode = FilesystemNodeFactory::create(_zipFile, FilesystemNodeFactory::SYSTEM);
|
||||||
FilesystemNodeFactory::create(_zipFile, FilesystemNodeFactory::SYSTEM);
|
|
||||||
_realNode = shared_ptr<AbstractFSNode>(tmp);
|
|
||||||
|
|
||||||
setFlags(_zipFile, _virtualPath, _realNode);
|
setFlags(_zipFile, _virtualPath, _realNode);
|
||||||
}
|
}
|
||||||
|
@ -102,7 +98,7 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FilesystemNodeZIP::FilesystemNodeZIP(
|
FilesystemNodeZIP::FilesystemNodeZIP(
|
||||||
const string& zipfile, const string& virtualpath,
|
const string& zipfile, const string& virtualpath,
|
||||||
shared_ptr<AbstractFSNode> realnode, bool isdir)
|
AbstractFSNodePtr realnode, bool isdir)
|
||||||
: _error(ZIPERR_NONE),
|
: _error(ZIPERR_NONE),
|
||||||
_numFiles(0),
|
_numFiles(0),
|
||||||
_isDirectory(isdir),
|
_isDirectory(isdir),
|
||||||
|
@ -114,7 +110,7 @@ FilesystemNodeZIP::FilesystemNodeZIP(
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FilesystemNodeZIP::setFlags(const string& zipfile,
|
void FilesystemNodeZIP::setFlags(const string& zipfile,
|
||||||
const string& virtualpath,
|
const string& virtualpath,
|
||||||
shared_ptr<AbstractFSNode> realnode)
|
AbstractFSNodePtr realnode)
|
||||||
{
|
{
|
||||||
_zipFile = zipfile;
|
_zipFile = zipfile;
|
||||||
_virtualPath = virtualpath;
|
_virtualPath = virtualpath;
|
||||||
|
@ -195,7 +191,7 @@ uInt32 FilesystemNodeZIP::read(BytePtr& image) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
AbstractFSNode* FilesystemNodeZIP::getParent() const
|
AbstractFSNodePtr FilesystemNodeZIP::getParent() const
|
||||||
{
|
{
|
||||||
if(_virtualPath == "")
|
if(_virtualPath == "")
|
||||||
return _realNode ? _realNode->getParent() : nullptr;
|
return _realNode ? _realNode->getParent() : nullptr;
|
||||||
|
@ -203,7 +199,7 @@ AbstractFSNode* FilesystemNodeZIP::getParent() const
|
||||||
const char* start = _path.c_str();
|
const char* start = _path.c_str();
|
||||||
const char* end = lastPathComponent(_path);
|
const char* end = lastPathComponent(_path);
|
||||||
|
|
||||||
return new FilesystemNodeZIP(string(start, end - start - 1));
|
return make_shared<FilesystemNodeZIP>(string(start, end - start - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -61,16 +61,16 @@ class FilesystemNodeZIP : public AbstractFSNode
|
||||||
//////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const;
|
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const;
|
||||||
AbstractFSNode* getParent() const;
|
AbstractFSNodePtr getParent() const;
|
||||||
|
|
||||||
uInt32 read(BytePtr& image) const;
|
uInt32 read(BytePtr& image) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FilesystemNodeZIP(const string& zipfile, const string& virtualpath,
|
FilesystemNodeZIP(const string& zipfile, const string& virtualpath,
|
||||||
shared_ptr<AbstractFSNode> realnode, bool isdir);
|
AbstractFSNodePtr realnode, bool isdir);
|
||||||
|
|
||||||
void setFlags(const string& zipfile, const string& virtualpath,
|
void setFlags(const string& zipfile, const string& virtualpath,
|
||||||
shared_ptr<AbstractFSNode> realnode);
|
AbstractFSNodePtr realnode);
|
||||||
|
|
||||||
friend ostream& operator<<(ostream& os, const FilesystemNodeZIP& node)
|
friend ostream& operator<<(ostream& os, const FilesystemNodeZIP& node)
|
||||||
{
|
{
|
||||||
|
@ -91,7 +91,7 @@ class FilesystemNodeZIP : public AbstractFSNode
|
||||||
ZIPERR_NO_ROMS
|
ZIPERR_NO_ROMS
|
||||||
};
|
};
|
||||||
|
|
||||||
shared_ptr<AbstractFSNode> _realNode;
|
AbstractFSNodePtr _realNode;
|
||||||
string _zipFile, _virtualPath;
|
string _zipFile, _virtualPath;
|
||||||
string _name, _path, _shortPath;
|
string _name, _path, _shortPath;
|
||||||
zip_error _error;
|
zip_error _error;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#ifndef VERSION_HXX
|
#ifndef VERSION_HXX
|
||||||
#define VERSION_HXX
|
#define VERSION_HXX
|
||||||
|
|
||||||
#define STELLA_VERSION "5.2_soundtest-1"
|
#define STELLA_VERSION "6.0_pre1"
|
||||||
#define STELLA_BUILD "4138"
|
#define STELLA_BUILD "4409"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,7 +30,7 @@ FilesystemNode::FilesystemNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FilesystemNode::FilesystemNode(AbstractFSNode *realNode)
|
FilesystemNode::FilesystemNode(AbstractFSNodePtr realNode)
|
||||||
: _realNode(realNode)
|
: _realNode(realNode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -38,15 +38,11 @@ FilesystemNode::FilesystemNode(AbstractFSNode *realNode)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FilesystemNode::FilesystemNode(const string& p)
|
FilesystemNode::FilesystemNode(const string& p)
|
||||||
{
|
{
|
||||||
AbstractFSNode* tmp = nullptr;
|
|
||||||
|
|
||||||
// Is this potentially a ZIP archive?
|
// Is this potentially a ZIP archive?
|
||||||
if(BSPF::containsIgnoreCase(p, ".zip"))
|
if(BSPF::containsIgnoreCase(p, ".zip"))
|
||||||
tmp = FilesystemNodeFactory::create(p, FilesystemNodeFactory::ZIP);
|
_realNode = FilesystemNodeFactory::create(p, FilesystemNodeFactory::ZIP);
|
||||||
else
|
else
|
||||||
tmp = FilesystemNodeFactory::create(p, FilesystemNodeFactory::SYSTEM);
|
_realNode = FilesystemNodeFactory::create(p, FilesystemNodeFactory::SYSTEM);
|
||||||
|
|
||||||
_realNode = shared_ptr<AbstractFSNode>(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -132,7 +128,7 @@ FilesystemNode FilesystemNode::getParent() const
|
||||||
if (_realNode == nullptr)
|
if (_realNode == nullptr)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
AbstractFSNode* node = _realNode->getParent();
|
AbstractFSNodePtr node = _realNode->getParent();
|
||||||
return node ? FilesystemNode(node) : *this;
|
return node ? FilesystemNode(node) : *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
|
|
||||||
class FilesystemNode;
|
class FilesystemNode;
|
||||||
class AbstractFSNode;
|
class AbstractFSNode;
|
||||||
|
using AbstractFSNodePtr = shared_ptr<AbstractFSNode>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of multiple file system nodes. E.g. the contents of a given directory.
|
* List of multiple file system nodes. E.g. the contents of a given directory.
|
||||||
|
@ -144,7 +145,7 @@ class FilesystemNode
|
||||||
* @return true if successful, false otherwise (e.g. when the directory
|
* @return true if successful, false otherwise (e.g. when the directory
|
||||||
* does not exist).
|
* does not exist).
|
||||||
*/
|
*/
|
||||||
virtual bool getChildren(FSList &fslist, ListMode mode = kListDirectoriesOnly,
|
virtual bool getChildren(FSList& fslist, ListMode mode = kListDirectoriesOnly,
|
||||||
bool hidden = false) const;
|
bool hidden = false) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -261,8 +262,8 @@ class FilesystemNode
|
||||||
string getShortPathWithExt(const string& ext) const; // FIXME - dead code
|
string getShortPathWithExt(const string& ext) const; // FIXME - dead code
|
||||||
|
|
||||||
private:
|
private:
|
||||||
shared_ptr<AbstractFSNode> _realNode;
|
AbstractFSNodePtr _realNode;
|
||||||
FilesystemNode(AbstractFSNode* realNode);
|
FilesystemNode(AbstractFSNodePtr realNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -275,7 +276,7 @@ class FilesystemNode
|
||||||
* the semantics.
|
* the semantics.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using AbstractFSList = vector<AbstractFSNode*>;
|
using AbstractFSList = vector<AbstractFSNodePtr>;
|
||||||
|
|
||||||
class AbstractFSNode
|
class AbstractFSNode
|
||||||
{
|
{
|
||||||
|
@ -403,7 +404,7 @@ class AbstractFSNode
|
||||||
* The parent node of this directory.
|
* The parent node of this directory.
|
||||||
* The parent of the root is the root itself.
|
* The parent of the root is the root itself.
|
||||||
*/
|
*/
|
||||||
virtual AbstractFSNode* getParent() const = 0;
|
virtual AbstractFSNodePtr getParent() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
|
ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
|
||||||
const VariantList& combolist)
|
const VariantList& combolist)
|
||||||
: Dialog(boss->instance(), boss->parent(), font, ""),
|
: Dialog(boss->instance(), boss->parent(), font, "Add..."),
|
||||||
myComboEvent(Event::NoType)
|
myComboEvent(Event::NoType)
|
||||||
{
|
{
|
||||||
const int lineHeight = font.getLineHeight(),
|
const int lineHeight = font.getLineHeight(),
|
||||||
|
@ -38,7 +38,7 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
|
||||||
WidgetArray wid;
|
WidgetArray wid;
|
||||||
|
|
||||||
// Set real dimensions
|
// Set real dimensions
|
||||||
_w = 35 * fontWidth + 10;
|
_w = 33 * fontWidth + 10*2;
|
||||||
_h = 10 * (lineHeight + 4) + 10 + _th;
|
_h = 10 * (lineHeight + 4) + 10 + _th;
|
||||||
xpos = 10;
|
xpos = 10;
|
||||||
ypos = 10 + _th;
|
ypos = 10 + _th;
|
||||||
|
@ -57,7 +57,6 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
|
||||||
ypos += lineHeight + 4;
|
ypos += lineHeight + 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
xpos = 10;
|
|
||||||
myEvents[0] = nullptr; ADD_EVENT_POPUP(0, "Event 1 ");
|
myEvents[0] = nullptr; ADD_EVENT_POPUP(0, "Event 1 ");
|
||||||
myEvents[1] = nullptr; ADD_EVENT_POPUP(1, "Event 2 ");
|
myEvents[1] = nullptr; ADD_EVENT_POPUP(1, "Event 2 ");
|
||||||
myEvents[2] = nullptr; ADD_EVENT_POPUP(2, "Event 3 ");
|
myEvents[2] = nullptr; ADD_EVENT_POPUP(2, "Event 3 ");
|
||||||
|
|
|
@ -56,6 +56,7 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font
|
||||||
_okWidget(nullptr),
|
_okWidget(nullptr),
|
||||||
_cancelWidget(nullptr),
|
_cancelWidget(nullptr),
|
||||||
_visible(false),
|
_visible(false),
|
||||||
|
_onTop(true),
|
||||||
_processCancel(false),
|
_processCancel(false),
|
||||||
_title(title),
|
_title(title),
|
||||||
_th(0),
|
_th(0),
|
||||||
|
@ -331,25 +332,25 @@ void Dialog::drawDialog()
|
||||||
|
|
||||||
cerr << COUNT++ << " Dialog::drawDialog()\n";
|
cerr << COUNT++ << " Dialog::drawDialog()\n";
|
||||||
// Dialog is still on top if e.g a ContextMenu is opened
|
// Dialog is still on top if e.g a ContextMenu is opened
|
||||||
bool onTop = parent().myDialogStack.top() == this
|
_onTop = parent().myDialogStack.top() == this
|
||||||
|| (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this
|
|| (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this
|
||||||
&& !parent().myDialogStack.top()->hasTitle());
|
&& !parent().myDialogStack.top()->hasTitle());
|
||||||
|
|
||||||
if(_flags & WIDGET_CLEARBG)
|
if(_flags & WIDGET_CLEARBG)
|
||||||
{
|
{
|
||||||
// cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl;
|
// cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl;
|
||||||
s.fillRect(_x, _y + _th, _w, _h - _th, onTop ? kDlgColor : kBGColorLo);
|
s.fillRect(_x, _y + _th, _w, _h - _th, _onTop ? kDlgColor : kBGColorLo);
|
||||||
if(_th)
|
if(_th)
|
||||||
{
|
{
|
||||||
s.fillRect(_x, _y, _w, _th, onTop ? kColorTitleBar : kColorTitleBarLo);
|
s.fillRect(_x, _y, _w, _th, _onTop ? kColorTitleBar : kColorTitleBarLo);
|
||||||
s.drawString(_font, _title, _x + 10, _y + 2 + 1, _font.getStringWidth(_title),
|
s.drawString(_font, _title, _x + 10, _y + 2 + 1, _font.getStringWidth(_title),
|
||||||
onTop ? kColorTitleText : kColorTitleTextLo);
|
_onTop ? kColorTitleText : kColorTitleTextLo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s.invalidate();
|
s.invalidate();
|
||||||
if(_flags & WIDGET_BORDER)
|
if(_flags & WIDGET_BORDER) // currently only used by Dialog itself
|
||||||
s.frameRect(_x, _y, _w, _h, onTop ? kColor : kShadowColor);
|
s.frameRect(_x, _y, _w, _h, _onTop ? kColor : kShadowColor);
|
||||||
|
|
||||||
// Make all child widget dirty
|
// Make all child widget dirty
|
||||||
Widget* w = _firstWidget;
|
Widget* w = _firstWidget;
|
||||||
|
|
|
@ -55,6 +55,7 @@ class Dialog : public GuiObject
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
bool isVisible() const override { return _visible; }
|
bool isVisible() const override { return _visible; }
|
||||||
|
bool isOnTop() { return _onTop; }
|
||||||
|
|
||||||
virtual void center();
|
virtual void center();
|
||||||
virtual void drawDialog();
|
virtual void drawDialog();
|
||||||
|
@ -152,6 +153,7 @@ class Dialog : public GuiObject
|
||||||
Widget* _cancelWidget;
|
Widget* _cancelWidget;
|
||||||
|
|
||||||
bool _visible;
|
bool _visible;
|
||||||
|
bool _onTop;
|
||||||
bool _processCancel;
|
bool _processCancel;
|
||||||
string _title;
|
string _title;
|
||||||
int _th;
|
int _th;
|
||||||
|
|
|
@ -85,7 +85,10 @@ void EditTextWidget::drawWidget(bool hilite)
|
||||||
if(_changed)
|
if(_changed)
|
||||||
s.fillRect(_x, _y, _w, _h, kDbgChangedColor);
|
s.fillRect(_x, _y, _w, _h, kDbgChangedColor);
|
||||||
else if(!isEditable())
|
else if(!isEditable())
|
||||||
s.fillRect(_x, _y, _w, _h, kDlgColor);
|
{
|
||||||
|
bool onTop = _boss->dialog().isOnTop();
|
||||||
|
s.fillRect(_x, _y, _w, _h, onTop ? kDlgColor : kBGColorLo);
|
||||||
|
}
|
||||||
|
|
||||||
// Draw a thin frame around us.
|
// Draw a thin frame around us.
|
||||||
s.frameRect(_x, _y, _w, _h, hilite && isEditable() && isEnabled() ? kWidColorHi : kColor);
|
s.frameRect(_x, _y, _w, _h, hilite && isEditable() && isEnabled() ? kWidColorHi : kColor);
|
||||||
|
|
|
@ -39,6 +39,7 @@ EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
|
|
||||||
_bgcolor = kWidColor;
|
_bgcolor = kWidColor;
|
||||||
_bgcolorhi = kWidColor;
|
_bgcolorhi = kWidColor;
|
||||||
|
_bgcolorlo = kDlgColor;
|
||||||
_textcolor = kTextColor;
|
_textcolor = kTextColor;
|
||||||
_textcolorhi = kTextColor;
|
_textcolorhi = kTextColor;
|
||||||
|
|
||||||
|
|
|
@ -57,17 +57,19 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
const string ELLIPSIS = "\x1d";
|
const string ELLIPSIS = "\x1d";
|
||||||
const GUI::Font& font = instance().frameBuffer().launcherFont();
|
const GUI::Font& font = instance().frameBuffer().launcherFont();
|
||||||
|
|
||||||
|
const int HBORDER = 10;
|
||||||
|
const int BUTTON_GAP = 8;
|
||||||
const int fontWidth = font.getMaxCharWidth(),
|
const int fontWidth = font.getMaxCharWidth(),
|
||||||
fontHeight = font.getFontHeight(),
|
fontHeight = font.getFontHeight(),
|
||||||
lineHeight = font.getLineHeight(),
|
lineHeight = font.getLineHeight(),
|
||||||
bwidth = (_w - 2 * 10 - 8 * (4 - 1)) / 4,
|
bwidth = (_w - 2 * HBORDER - BUTTON_GAP * (4 - 1)),
|
||||||
bheight = lineHeight + 4;
|
bheight = lineHeight + 4;
|
||||||
int xpos = 0, ypos = 0, lwidth = 0, lwidth2 = 0;
|
int xpos, ypos = 0, lwidth = 0, lwidth2 = 0;
|
||||||
WidgetArray wid;
|
WidgetArray wid;
|
||||||
|
|
||||||
// Show game name
|
// Show game name
|
||||||
lwidth = font.getStringWidth("Select a ROM from the list" + ELLIPSIS);
|
lwidth = font.getStringWidth("Select a ROM from the list" + ELLIPSIS);
|
||||||
xpos += 10; ypos += 8;
|
xpos = HBORDER; ypos += 8;
|
||||||
new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight,
|
new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight,
|
||||||
"Select a ROM from the list" + ELLIPSIS);
|
"Select a ROM from the list" + ELLIPSIS);
|
||||||
|
|
||||||
|
@ -131,35 +133,35 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
// Add four buttons at the bottom
|
// Add four buttons at the bottom
|
||||||
xpos = 10; ypos += myDir->getHeight() + 8;
|
xpos = 10; ypos += myDir->getHeight() + 8;
|
||||||
#ifndef BSPF_MAC_OSX
|
#ifndef BSPF_MAC_OSX
|
||||||
myStartButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
|
myStartButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 0) / 4, bheight,
|
||||||
"Select", kLoadROMCmd);
|
"Select", kLoadROMCmd);
|
||||||
wid.push_back(myStartButton);
|
wid.push_back(myStartButton);
|
||||||
xpos += bwidth + 8;
|
xpos += (bwidth + 0) / 4 + BUTTON_GAP;
|
||||||
myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
|
myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 1) / 4, bheight,
|
||||||
"Go Up", kPrevDirCmd);
|
"Go Up", kPrevDirCmd);
|
||||||
wid.push_back(myPrevDirButton);
|
wid.push_back(myPrevDirButton);
|
||||||
xpos += bwidth + 8;
|
xpos += (bwidth + 1) / 4 + BUTTON_GAP;
|
||||||
myOptionsButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
|
myOptionsButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 2) / 4, bheight,
|
||||||
"Options" + ELLIPSIS, kOptionsCmd);
|
"Options" + ELLIPSIS, kOptionsCmd);
|
||||||
wid.push_back(myOptionsButton);
|
wid.push_back(myOptionsButton);
|
||||||
xpos += bwidth + 8;
|
xpos += (bwidth + 2) / 4 + BUTTON_GAP;
|
||||||
myQuitButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
|
myQuitButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 3) / 4, bheight,
|
||||||
"Quit", kQuitCmd);
|
"Quit", kQuitCmd);
|
||||||
wid.push_back(myQuitButton);
|
wid.push_back(myQuitButton);
|
||||||
#else
|
#else
|
||||||
myQuitButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
|
myQuitButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 0) / 4, bheight,
|
||||||
"Quit", kQuitCmd);
|
"Quit", kQuitCmd);
|
||||||
wid.push_back(myQuitButton);
|
wid.push_back(myQuitButton);
|
||||||
xpos += bwidth + 8;
|
xpos += (bwidth + 0) / 4 + BUTTON_GAP;
|
||||||
myOptionsButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
|
myOptionsButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 1) / 4, bheight,
|
||||||
"Options" + ELLIPSIS, kOptionsCmd);
|
"Options" + ELLIPSIS, kOptionsCmd);
|
||||||
wid.push_back(myOptionsButton);
|
wid.push_back(myOptionsButton);
|
||||||
xpos += bwidth + 8;
|
xpos += (bwidth + 1) / 4 + BUTTON_GAP;
|
||||||
myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
|
myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 2) / 4, bheight,
|
||||||
"Go Up", kPrevDirCmd);
|
"Go Up", kPrevDirCmd);
|
||||||
wid.push_back(myPrevDirButton);
|
wid.push_back(myPrevDirButton);
|
||||||
xpos += bwidth + 8;
|
xpos += (bwidth + 2) / 4 + BUTTON_GAP;
|
||||||
myStartButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
|
myStartButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 3) / 4, bheight,
|
||||||
"Select", kLoadROMCmd);
|
"Select", kLoadROMCmd);
|
||||||
wid.push_back(myStartButton);
|
wid.push_back(myStartButton);
|
||||||
#endif
|
#endif
|
||||||
|
@ -214,31 +216,12 @@ const string& LauncherDialog::selectedRomMD5()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void LauncherDialog::loadConfig()
|
void LauncherDialog::loadConfig()
|
||||||
{
|
{
|
||||||
|
// Should we use a temporary directory specified on the commandline, or the
|
||||||
|
// default one specified by the settings?
|
||||||
const string& tmpromdir = instance().settings().getString("tmpromdir");
|
const string& tmpromdir = instance().settings().getString("tmpromdir");
|
||||||
const string& romdir = tmpromdir != "" ? tmpromdir :
|
const string& romdir = tmpromdir != "" ? tmpromdir :
|
||||||
instance().settings().getString("romdir");
|
instance().settings().getString("romdir");
|
||||||
|
|
||||||
// When romdir hasn't been set, it probably indicates that this is the first
|
|
||||||
// time running Stella; in this case, we should prompt the user
|
|
||||||
if(romdir == "")
|
|
||||||
{
|
|
||||||
if(!myFirstRunMsg)
|
|
||||||
{
|
|
||||||
StringList msg;
|
|
||||||
msg.push_back("This seems to be your first time running Stella.");
|
|
||||||
msg.push_back("Before you can start a game, you need to");
|
|
||||||
msg.push_back("specify where your ROMs are located.");
|
|
||||||
msg.push_back("");
|
|
||||||
msg.push_back("Click 'Default' to select a default ROM directory,");
|
|
||||||
msg.push_back("or 'Browse' to browse the filesystem manually.");
|
|
||||||
myFirstRunMsg = make_unique<GUI::MessageBox>
|
|
||||||
(this, instance().frameBuffer().font(),
|
|
||||||
msg, _w, _h, kFirstRunMsgChosenCmd,
|
|
||||||
"Default", "Browse", "ROM directory");
|
|
||||||
}
|
|
||||||
myFirstRunMsg->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assume that if the list is empty, this is the first time that loadConfig()
|
// Assume that if the list is empty, this is the first time that loadConfig()
|
||||||
// has been called (and we should reload the list)
|
// has been called (and we should reload the list)
|
||||||
if(myList->getList().empty())
|
if(myList->getList().empty())
|
||||||
|
@ -486,7 +469,13 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
const string& result =
|
const string& result =
|
||||||
instance().createConsole(romnode, myGameList->md5(item));
|
instance().createConsole(romnode, myGameList->md5(item));
|
||||||
if(result == EmptyString)
|
if(result == EmptyString)
|
||||||
|
{
|
||||||
instance().settings().setValue("lastrom", myList->getSelectedString());
|
instance().settings().setValue("lastrom", myList->getSelectedString());
|
||||||
|
|
||||||
|
// If romdir has never been set, set it now based on the selected rom
|
||||||
|
if(instance().settings().getString("romdir") == EmptyString)
|
||||||
|
instance().settings().setValue("romdir", romnode.getParent().getShortPath());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
instance().frameBuffer().showMessage(result, MessagePosition::MiddleCenter, true);
|
instance().frameBuffer().showMessage(result, MessagePosition::MiddleCenter, true);
|
||||||
}
|
}
|
||||||
|
@ -513,20 +502,6 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
instance().eventHandler().quit();
|
instance().eventHandler().quit();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kFirstRunMsgChosenCmd:
|
|
||||||
// Show a file browser, starting from the users' home directory
|
|
||||||
if(!myRomDir)
|
|
||||||
myRomDir = make_unique<BrowserDialog>(this, instance().frameBuffer().font(),
|
|
||||||
_w, _h, "Select ROM directory");
|
|
||||||
myRomDir->show("~", BrowserDialog::Directories, kStartupRomDirChosenCmd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kStartupRomDirChosenCmd:
|
|
||||||
{
|
|
||||||
FilesystemNode dir(myRomDir->getResult());
|
|
||||||
instance().settings().setValue("romdir", dir.getShortPath());
|
|
||||||
[[fallthrough]];
|
|
||||||
}
|
|
||||||
case kRomDirChosenCmd:
|
case kRomDirChosenCmd:
|
||||||
myCurrentNode = FilesystemNode(instance().settings().getString("romdir"));
|
myCurrentNode = FilesystemNode(instance().settings().getString("romdir"));
|
||||||
if(!(myCurrentNode.exists() && myCurrentNode.isDirectory()))
|
if(!(myCurrentNode.exists() && myCurrentNode.isDirectory()))
|
||||||
|
|
|
@ -48,7 +48,7 @@ class LauncherDialog : public Dialog
|
||||||
// These must be accessible from dialogs created by this class
|
// These must be accessible from dialogs created by this class
|
||||||
enum {
|
enum {
|
||||||
kLoadROMCmd = 'STRT', // load currently selected ROM
|
kLoadROMCmd = 'STRT', // load currently selected ROM
|
||||||
kRomDirChosenCmd = 'romc', // rom chosen
|
kRomDirChosenCmd = 'romc', // rom dir chosen
|
||||||
kReloadRomDirCmd = 'rdrl', // reload the current listing
|
kReloadRomDirCmd = 'rdrl', // reload the current listing
|
||||||
kReloadFiltersCmd = 'rlfl' // reload filtering options and current listing
|
kReloadFiltersCmd = 'rlfl' // reload filtering options and current listing
|
||||||
};
|
};
|
||||||
|
@ -98,7 +98,6 @@ class LauncherDialog : public Dialog
|
||||||
unique_ptr<GlobalPropsDialog> myGlobalProps;
|
unique_ptr<GlobalPropsDialog> myGlobalProps;
|
||||||
unique_ptr<LauncherFilterDialog> myFilters;
|
unique_ptr<LauncherFilterDialog> myFilters;
|
||||||
unique_ptr<BrowserDialog> myRomDir;
|
unique_ptr<BrowserDialog> myRomDir;
|
||||||
unique_ptr<GUI::MessageBox> myFirstRunMsg;
|
|
||||||
|
|
||||||
ButtonWidget* myStartButton;
|
ButtonWidget* myStartButton;
|
||||||
ButtonWidget* myPrevDirButton;
|
ButtonWidget* myPrevDirButton;
|
||||||
|
@ -122,10 +121,7 @@ class LauncherDialog : public Dialog
|
||||||
enum {
|
enum {
|
||||||
kPrevDirCmd = 'PRVD',
|
kPrevDirCmd = 'PRVD',
|
||||||
kOptionsCmd = 'OPTI',
|
kOptionsCmd = 'OPTI',
|
||||||
kQuitCmd = 'QUIT',
|
kQuitCmd = 'QUIT'
|
||||||
|
|
||||||
kFirstRunMsgChosenCmd = 'frmc',
|
|
||||||
kStartupRomDirChosenCmd = 'rmsc'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -39,7 +39,8 @@ RomInfoWidget::RomInfoWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
GUI::Size(320, TIAConstants::maxViewableHeight))
|
GUI::Size(320, TIAConstants::maxViewableHeight))
|
||||||
{
|
{
|
||||||
_flags = WIDGET_ENABLED;
|
_flags = WIDGET_ENABLED;
|
||||||
_bgcolor = _bgcolorhi = kWidColor;
|
_bgcolor = kDlgColor;
|
||||||
|
_bgcolorlo = kBGColorLo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -139,10 +140,11 @@ void RomInfoWidget::parseProperties()
|
||||||
void RomInfoWidget::drawWidget(bool hilite)
|
void RomInfoWidget::drawWidget(bool hilite)
|
||||||
{
|
{
|
||||||
FBSurface& s = dialog().surface();
|
FBSurface& s = dialog().surface();
|
||||||
|
bool onTop = _boss->dialog().isOnTop();
|
||||||
|
|
||||||
const int yoff = myAvail.h + 10;
|
const int yoff = myAvail.h + 10;
|
||||||
|
|
||||||
s.fillRect(_x+2, _y+2, _w-4, _h-4, kDlgColor);
|
s.fillRect(_x+2, _y+2, _w-4, _h-4, onTop ? _bgcolor : _bgcolorlo);
|
||||||
s.frameRect(_x, _y, _w, _h, kColor);
|
s.frameRect(_x, _y, _w, _h, kColor);
|
||||||
s.frameRect(_x, _y+yoff, _w, _h-yoff, kColor);
|
s.frameRect(_x, _y+yoff, _w, _h-yoff, kColor);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ StringListWidget::StringListWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
boss->instance().settings().getInt("listdelay") >= 300),
|
boss->instance().settings().getInt("listdelay") >= 300),
|
||||||
_hilite(hilite)
|
_hilite(hilite)
|
||||||
{
|
{
|
||||||
|
_bgcolorlo = kDlgColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -77,7 +78,10 @@ void StringListWidget::drawWidget(bool hilite)
|
||||||
textColor = kTextColorInv;
|
textColor = kTextColorInv;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s.frameRect(_x + 1, _y + 1 + _fontHeight * i, _w - 1, _fontHeight, kWidColorHi);
|
{
|
||||||
|
bool onTop = _boss->dialog().isOnTop();
|
||||||
|
s.frameRect(_x + 1, _y + 1 + _fontHeight * i, _w - 1, _fontHeight, onTop ? kWidColorHi : kBGColorLo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI::Rect r(getEditRect());
|
GUI::Rect r(getEditRect());
|
||||||
|
|
|
@ -262,6 +262,7 @@ void TabWidget::drawWidget(bool hilite)
|
||||||
Widget::setDirtyInChain(_tabs[_activeTab].firstWidget);
|
Widget::setDirtyInChain(_tabs[_activeTab].firstWidget);
|
||||||
|
|
||||||
FBSurface& s = dialog().surface();
|
FBSurface& s = dialog().surface();
|
||||||
|
bool onTop = _boss->dialog().isOnTop();
|
||||||
|
|
||||||
// Iterate over all tabs and draw them
|
// Iterate over all tabs and draw them
|
||||||
int i, x = _x + kTabLeftOffset;
|
int i, x = _x + kTabLeftOffset;
|
||||||
|
@ -269,25 +270,27 @@ void TabWidget::drawWidget(bool hilite)
|
||||||
{
|
{
|
||||||
uInt32 fontcolor = _tabs[i].enabled ? kTextColor : kColor;
|
uInt32 fontcolor = _tabs[i].enabled ? kTextColor : kColor;
|
||||||
int yOffset = (i == _activeTab) ? 0 : 1;
|
int yOffset = (i == _activeTab) ? 0 : 1;
|
||||||
s.fillRect(x, _y + 1, _tabWidth, _tabHeight - 1, (i == _activeTab)
|
s.fillRect(x, _y + 1, _tabWidth, _tabHeight - 1,
|
||||||
? kDlgColor : kBGColorHi); // ? kWidColor : kDlgColor
|
(i == _activeTab)
|
||||||
|
? onTop ? kDlgColor : kBGColorLo
|
||||||
|
: onTop ? kBGColorHi : kDlgColor); // ? kWidColor : kDlgColor
|
||||||
s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset,
|
s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset,
|
||||||
_y + yOffset + (_tabHeight - _fontHeight - 1),
|
_y + yOffset + (_tabHeight - _fontHeight - 1),
|
||||||
_tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center);
|
_tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center);
|
||||||
if(i == _activeTab)
|
if(i == _activeTab)
|
||||||
{
|
{
|
||||||
s.hLine(x, _y, x + _tabWidth - 1, kWidColor);
|
s.hLine(x, _y, x + _tabWidth - 1, onTop ? kWidColor : kDlgColor);
|
||||||
s.vLine(x + _tabWidth, _y + 1, _y + _tabHeight - 1, kBGColorLo);
|
s.vLine(x + _tabWidth, _y + 1, _y + _tabHeight - 1, onTop ? kBGColorLo : kColor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s.hLine(x, _y + _tabHeight, x + _tabWidth, kWidColor);
|
s.hLine(x, _y + _tabHeight, x + _tabWidth, onTop ? kWidColor : kDlgColor);
|
||||||
|
|
||||||
x += _tabWidth + kTabSpacing;
|
x += _tabWidth + kTabSpacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill empty right space
|
// fill empty right space
|
||||||
s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, kWidColor);
|
s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, onTop ? kWidColor : kDlgColor);
|
||||||
s.hLine(_x, _y + _h - 1, _x + _w - 1, kBGColorLo);
|
s.hLine(_x, _y + _h - 1, _x + _w - 1, onTop ? kBGColorLo : kColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -38,8 +38,10 @@ Widget::Widget(GuiObject* boss, const GUI::Font& font,
|
||||||
_hasFocus(false),
|
_hasFocus(false),
|
||||||
_bgcolor(kWidColor),
|
_bgcolor(kWidColor),
|
||||||
_bgcolorhi(kWidColor),
|
_bgcolorhi(kWidColor),
|
||||||
|
_bgcolorlo(kBGColorLo),
|
||||||
_textcolor(kTextColor),
|
_textcolor(kTextColor),
|
||||||
_textcolorhi(kTextColorHi),
|
_textcolorhi(kTextColorHi),
|
||||||
|
_textcolorlo(kBGColorLo),
|
||||||
_shadowcolor(kShadowColor)
|
_shadowcolor(kShadowColor)
|
||||||
{
|
{
|
||||||
// Insert into the widget list of the boss
|
// Insert into the widget list of the boss
|
||||||
|
@ -77,7 +79,9 @@ void Widget::draw()
|
||||||
|
|
||||||
FBSurface& s = _boss->dialog().surface();
|
FBSurface& s = _boss->dialog().surface();
|
||||||
|
|
||||||
bool hasBorder = _flags & WIDGET_BORDER;
|
bool onTop = _boss->dialog().isOnTop();
|
||||||
|
|
||||||
|
bool hasBorder = _flags & WIDGET_BORDER; // currently only used by Dialog widget
|
||||||
int oldX = _x, oldY = _y;
|
int oldX = _x, oldY = _y;
|
||||||
|
|
||||||
// Account for our relative position in the dialog
|
// Account for our relative position in the dialog
|
||||||
|
@ -92,13 +96,13 @@ void Widget::draw()
|
||||||
{
|
{
|
||||||
x++; y++; w-=2; h-=2;
|
x++; y++; w-=2; h-=2;
|
||||||
}
|
}
|
||||||
s.fillRect(x, y, w, h, (_flags & WIDGET_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor);
|
s.fillRect(x, y, w, h, !onTop ? _bgcolorlo : (_flags & WIDGET_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw border
|
// Draw border
|
||||||
if(hasBorder)
|
if(hasBorder)
|
||||||
{
|
{
|
||||||
s.frameRect(_x, _y, _w, _h, (_flags & WIDGET_HILITED) && isEnabled() ? kWidColorHi : kColor);
|
s.frameRect(_x, _y, _w, _h, !onTop ? kColor : (_flags & WIDGET_HILITED) && isEnabled() ? kWidColorHi : kColor);
|
||||||
_x += 4;
|
_x += 4;
|
||||||
_y += 4;
|
_y += 4;
|
||||||
_w -= 8;
|
_w -= 8;
|
||||||
|
@ -203,6 +207,8 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
|
||||||
FBSurface& s = boss->dialog().surface();
|
FBSurface& s = boss->dialog().surface();
|
||||||
int size = int(arr.size()), pos = -1;
|
int size = int(arr.size()), pos = -1;
|
||||||
Widget* tmp;
|
Widget* tmp;
|
||||||
|
bool onTop = boss->dialog().isOnTop();
|
||||||
|
|
||||||
for(int i = 0; i < size; ++i)
|
for(int i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
tmp = arr[i];
|
tmp = arr[i];
|
||||||
|
@ -226,7 +232,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
|
||||||
else
|
else
|
||||||
tmp->_hasFocus = false;
|
tmp->_hasFocus = false;
|
||||||
|
|
||||||
s.frameRect(x, y, w, h, kDlgColor);
|
s.frameRect(x, y, w, h, onTop ? kDlgColor : kBGColorLo);
|
||||||
|
|
||||||
tmp->setDirty();
|
tmp->setDirty();
|
||||||
}
|
}
|
||||||
|
@ -279,6 +285,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
|
||||||
else
|
else
|
||||||
tmp->_hasFocus = true;
|
tmp->_hasFocus = true;
|
||||||
|
|
||||||
|
if (onTop)
|
||||||
s.frameRect(x, y, w, h, kWidFrameColor, FrameStyle::Dashed);
|
s.frameRect(x, y, w, h, kWidFrameColor, FrameStyle::Dashed);
|
||||||
|
|
||||||
tmp->setDirty();
|
tmp->setDirty();
|
||||||
|
@ -368,8 +375,10 @@ ButtonWidget::ButtonWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
_flags = WIDGET_ENABLED | WIDGET_CLEARBG;
|
_flags = WIDGET_ENABLED | WIDGET_CLEARBG;
|
||||||
_bgcolor = kBtnColor;
|
_bgcolor = kBtnColor;
|
||||||
_bgcolorhi = kBtnColorHi;
|
_bgcolorhi = kBtnColorHi;
|
||||||
|
_bgcolorlo = kColor;
|
||||||
_textcolor = kBtnTextColor;
|
_textcolor = kBtnTextColor;
|
||||||
_textcolorhi = kBtnTextColorHi;
|
_textcolorhi = kBtnTextColorHi;
|
||||||
|
_textcolorlo = kBGColorLo;
|
||||||
|
|
||||||
_editable = false;
|
_editable = false;
|
||||||
}
|
}
|
||||||
|
@ -457,16 +466,17 @@ void ButtonWidget::setBitmap(uInt32* bitmap, int bmw, int bmh)
|
||||||
void ButtonWidget::drawWidget(bool hilite)
|
void ButtonWidget::drawWidget(bool hilite)
|
||||||
{
|
{
|
||||||
FBSurface& s = _boss->dialog().surface();
|
FBSurface& s = _boss->dialog().surface();
|
||||||
|
bool onTop = _boss->dialog().isOnTop();
|
||||||
|
|
||||||
s.frameRect(_x, _y, _w, _h, hilite && isEnabled() ? kBtnBorderColorHi : kBtnBorderColor);
|
s.frameRect(_x, _y, _w, _h, !onTop ? kShadowColor : hilite && isEnabled() ? kBtnBorderColorHi : kBtnBorderColor);
|
||||||
|
|
||||||
if (!_useBitmap)
|
if (!_useBitmap)
|
||||||
s.drawString(_font, _label, _x, _y + (_h - _fontHeight)/2 + 1, _w,
|
s.drawString(_font, _label, _x, _y + (_h - _fontHeight)/2 + 1, _w,
|
||||||
!isEnabled() ? /*hilite ? uInt32(kColor) :*/ uInt32(kBGColorLo) :
|
!(isEnabled() && onTop) ? _textcolorlo :
|
||||||
hilite ? _textcolorhi : _textcolor, _align);
|
hilite ? _textcolorhi : _textcolor, _align);
|
||||||
else
|
else
|
||||||
s.drawBitmap(_bitmap, _x + (_w - _bmw) / 2, _y + (_h - _bmh) / 2,
|
s.drawBitmap(_bitmap, _x + (_w - _bmw) / 2, _y + (_h - _bmh) / 2,
|
||||||
!isEnabled() ? /*hilite ? uInt32(kColor) :*/ uInt32(kBGColorLo) :
|
!(isEnabled() && onTop) ? _textcolorlo :
|
||||||
hilite ? _textcolorhi : _textcolor,
|
hilite ? _textcolorhi : _textcolor,
|
||||||
_bmw, _bmh);
|
_bmw, _bmh);
|
||||||
|
|
||||||
|
|
|
@ -142,8 +142,10 @@ class Widget : public GuiObject
|
||||||
int _fontHeight;
|
int _fontHeight;
|
||||||
uInt32 _bgcolor;
|
uInt32 _bgcolor;
|
||||||
uInt32 _bgcolorhi;
|
uInt32 _bgcolorhi;
|
||||||
|
uInt32 _bgcolorlo;
|
||||||
uInt32 _textcolor;
|
uInt32 _textcolor;
|
||||||
uInt32 _textcolorhi;
|
uInt32 _textcolorhi;
|
||||||
|
uInt32 _textcolorlo;
|
||||||
uInt32 _shadowcolor;
|
uInt32 _shadowcolor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -97,12 +97,11 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode,
|
||||||
assert(_isDirectory);
|
assert(_isDirectory);
|
||||||
|
|
||||||
DIR* dirp = opendir(_path.c_str());
|
DIR* dirp = opendir(_path.c_str());
|
||||||
struct dirent* dp;
|
|
||||||
|
|
||||||
if (dirp == nullptr)
|
if (dirp == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// loop over dir entries using readdir
|
// Loop over dir entries using readdir
|
||||||
|
struct dirent* dp;
|
||||||
while ((dp = readdir(dirp)) != nullptr)
|
while ((dp = readdir(dirp)) != nullptr)
|
||||||
{
|
{
|
||||||
// Skip 'invisible' files if necessary
|
// Skip 'invisible' files if necessary
|
||||||
|
@ -137,7 +136,6 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
entry._isValid = (dp->d_type == DT_DIR) || (dp->d_type == DT_REG) || (dp->d_type == DT_LNK);
|
|
||||||
if (dp->d_type == DT_LNK)
|
if (dp->d_type == DT_LNK)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -157,6 +155,8 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode,
|
||||||
|
|
||||||
if (entry._isDirectory)
|
if (entry._isDirectory)
|
||||||
entry._path += "/";
|
entry._path += "/";
|
||||||
|
|
||||||
|
entry._isValid = entry._isDirectory || entry._isFile;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ bool FilesystemNodePOSIX::rename(const string& newfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
AbstractFSNode* FilesystemNodePOSIX::getParent() const
|
AbstractFSNodePtr FilesystemNodePOSIX::getParent() const
|
||||||
{
|
{
|
||||||
if (_path == "/")
|
if (_path == "/")
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -234,5 +234,5 @@ AbstractFSNode* FilesystemNodePOSIX::getParent() const
|
||||||
const char* start = _path.c_str();
|
const char* start = _path.c_str();
|
||||||
const char* end = lastPathComponent(_path);
|
const char* end = lastPathComponent(_path);
|
||||||
|
|
||||||
return new FilesystemNodePOSIX(string(start, size_t(end - start)));
|
return make_unique<FilesystemNodePOSIX>(string(start, size_t(end - start)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ class FilesystemNodePOSIX : public AbstractFSNode
|
||||||
bool rename(const string& newfile) override;
|
bool rename(const string& newfile) override;
|
||||||
|
|
||||||
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const override;
|
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const override;
|
||||||
AbstractFSNode* getParent() const override;
|
AbstractFSNodePtr getParent() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
string _path;
|
string _path;
|
||||||
|
|
|
@ -296,7 +296,7 @@ bool FilesystemNodeWINDOWS::rename(const string& newfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
AbstractFSNode* FilesystemNodeWINDOWS::getParent() const
|
AbstractFSNodePtr FilesystemNodeWINDOWS::getParent() const
|
||||||
{
|
{
|
||||||
if(_isPseudoRoot)
|
if(_isPseudoRoot)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -306,8 +306,8 @@ AbstractFSNode* FilesystemNodeWINDOWS::getParent() const
|
||||||
const char* start = _path.c_str();
|
const char* start = _path.c_str();
|
||||||
const char* end = lastPathComponent(_path);
|
const char* end = lastPathComponent(_path);
|
||||||
|
|
||||||
return new FilesystemNodeWINDOWS(string(start, size_t(end - start)));
|
return make_shared<FilesystemNodeWINDOWS>(string(start, size_t(end - start)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return new FilesystemNodeWINDOWS();
|
return make_shared<FilesystemNodeWINDOWS>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ class FilesystemNodeWINDOWS : public AbstractFSNode
|
||||||
bool rename(const string& newfile) override;
|
bool rename(const string& newfile) override;
|
||||||
|
|
||||||
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const override;
|
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const override;
|
||||||
AbstractFSNode* getParent() const override;
|
AbstractFSNodePtr getParent() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
string _displayName;
|
string _displayName;
|
||||||
|
|