mirror of https://github.com/stella-emu/stella.git
added icons to file lists and removed special directory name formatting
This commit is contained in:
parent
48aced6c1e
commit
dc10ca9c00
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
* Added option to toggle autofire mode.
|
* Added option to toggle autofire mode.
|
||||||
|
|
||||||
|
* Added icons to file lists (TODO: doc)
|
||||||
|
|
||||||
-Have fun!
|
-Have fun!
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
|
||||||
if (includeParentDirectory && hasParent())
|
if (includeParentDirectory && hasParent())
|
||||||
{
|
{
|
||||||
FilesystemNode parent = getParent();
|
FilesystemNode parent = getParent();
|
||||||
parent.setName(" [..]");
|
parent.setName("..");
|
||||||
fslist.emplace_back(parent);
|
fslist.emplace_back(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,10 +204,6 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// Make directories stand out
|
|
||||||
if(i->isDirectory())
|
|
||||||
i->setName(" [" + i->getName() + "]");
|
|
||||||
|
|
||||||
FilesystemNode node(i);
|
FilesystemNode node(i);
|
||||||
|
|
||||||
if(includeChildDirectories)
|
if(includeChildDirectories)
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "FileListWidget.hxx"
|
#include "FileListWidget.hxx"
|
||||||
#include "TimerManager.hxx"
|
#include "TimerManager.hxx"
|
||||||
#include "ProgressDialog.hxx"
|
#include "ProgressDialog.hxx"
|
||||||
|
#include "FBSurface.hxx"
|
||||||
|
#include "Bankswitch.hxx"
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
@ -56,9 +58,6 @@ void FileListWidget::setDirectory(const FilesystemNode& node,
|
||||||
string name = tmp.getName();
|
string name = tmp.getName();
|
||||||
if(name.back() == FilesystemNode::PATH_SEPARATOR)
|
if(name.back() == FilesystemNode::PATH_SEPARATOR)
|
||||||
name.pop_back();
|
name.pop_back();
|
||||||
if(!BSPF::startsWithIgnoreCase(name, " ["))
|
|
||||||
name = " [" + name.append("]");
|
|
||||||
|
|
||||||
_history.push(name);
|
_history.push(name);
|
||||||
tmp = tmp.getParent();
|
tmp = tmp.getParent();
|
||||||
}
|
}
|
||||||
|
@ -102,16 +101,29 @@ void FileListWidget::setLocation(const FilesystemNode& node,
|
||||||
size_t orgLen = _node.getShortPath().length();
|
size_t orgLen = _node.getShortPath().length();
|
||||||
|
|
||||||
_dirList.clear();
|
_dirList.clear();
|
||||||
|
_iconList.clear();
|
||||||
for(const auto& file : _fileList)
|
for(const auto& file : _fileList)
|
||||||
{
|
{
|
||||||
const string path = file.getShortPath();
|
const string path = file.getShortPath();
|
||||||
|
const string name = file.getName();
|
||||||
|
|
||||||
l.push_back(file.getName());
|
l.push_back(name);
|
||||||
// display only relative path in tooltip
|
// display only relative path in tooltip
|
||||||
if(path.length() >= orgLen)
|
if(path.length() >= orgLen)
|
||||||
_dirList.push_back(path.substr(orgLen));
|
_dirList.push_back(path.substr(orgLen));
|
||||||
else
|
else
|
||||||
_dirList.push_back(path);
|
_dirList.push_back(path);
|
||||||
|
if(file.isDirectory())
|
||||||
|
{
|
||||||
|
if(BSPF::endsWithIgnoreCase(name, ".zip"))
|
||||||
|
_iconList.push_back(IconType::zip);
|
||||||
|
else
|
||||||
|
_iconList.push_back(IconType::directory);
|
||||||
|
}
|
||||||
|
else if(file.isFile() && Bankswitch::isValidRomName(name))
|
||||||
|
_iconList.push_back(IconType::rom);
|
||||||
|
else
|
||||||
|
_iconList.push_back(IconType::unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
setList(l);
|
setList(l);
|
||||||
|
@ -167,26 +179,21 @@ bool FileListWidget::handleText(char text)
|
||||||
// (or a substring accumulated from the last couple key presses).
|
// (or a substring accumulated from the last couple key presses).
|
||||||
// Only works in a useful fashion if the list entries are sorted.
|
// Only works in a useful fashion if the list entries are sorted.
|
||||||
uInt64 time = TimerManager::getTicks() / 1000;
|
uInt64 time = TimerManager::getTicks() / 1000;
|
||||||
|
|
||||||
if(_quickSelectTime < time)
|
if(_quickSelectTime < time)
|
||||||
{
|
_quickSelectStr = text;
|
||||||
if(std::isupper(text))
|
|
||||||
{
|
|
||||||
// Select directories when the first character is uppercase
|
|
||||||
_quickSelectStr = " [";
|
|
||||||
_quickSelectStr.push_back(text);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_quickSelectStr = text;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
_quickSelectStr += text;
|
_quickSelectStr += text;
|
||||||
_quickSelectTime = time + _QUICK_SELECT_DELAY;
|
_quickSelectTime = time + _QUICK_SELECT_DELAY;
|
||||||
|
|
||||||
int selectedItem = 0;
|
int selectedItem = 0;
|
||||||
for(const auto& i: _list)
|
for(const auto& i : _list)
|
||||||
{
|
{
|
||||||
if(BSPF::startsWithIgnoreCase(i, _quickSelectStr))
|
if(BSPF::startsWithIgnoreCase(i, _quickSelectStr))
|
||||||
break;
|
// Select directories when the first character is uppercase
|
||||||
|
if(std::isupper(_quickSelectStr[0]) ==
|
||||||
|
(_iconList[selectedItem] == IconType::directory))
|
||||||
|
break;
|
||||||
selectedItem++;
|
selectedItem++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +222,7 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
|
||||||
_selected = data;
|
_selected = data;
|
||||||
if(selected().isDirectory())
|
if(selected().isDirectory())
|
||||||
{
|
{
|
||||||
if(selected().getName() == " [..]")
|
if(selected().getName() == "..")
|
||||||
selectParent();
|
selectParent();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -246,11 +253,219 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
|
||||||
setTarget(this);
|
setTarget(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
int FileListWidget::drawIcon(int i, int x, int y, ColorId color)
|
||||||
|
{
|
||||||
|
const Icon unknown_small = {
|
||||||
|
0b00111111'1100000,
|
||||||
|
0b00100000'0110000,
|
||||||
|
0b00100000'0011000,
|
||||||
|
0b00100000'0001100,
|
||||||
|
0b00100000'0000100,
|
||||||
|
0b00100000'0000100,
|
||||||
|
0b00100000'0000100,
|
||||||
|
0b00100000'0000100,
|
||||||
|
0b00100000'0000100,
|
||||||
|
0b00100000'0000100,
|
||||||
|
0b00100000'0000100,
|
||||||
|
0b00100000'0000100,
|
||||||
|
0b00100000'0000100,
|
||||||
|
0b00111111'1111100
|
||||||
|
};
|
||||||
|
const Icon rom_small = {
|
||||||
|
0b00001111'1110000,
|
||||||
|
0b00001010'1010000,
|
||||||
|
0b00001010'1010000,
|
||||||
|
0b00001010'1010000,
|
||||||
|
0b00001010'1010000,
|
||||||
|
0b00001010'1010000,
|
||||||
|
0b00011010'1011000,
|
||||||
|
0b00110010'1001100,
|
||||||
|
0b00100110'1100100,
|
||||||
|
0b11101110'1110111,
|
||||||
|
0b10001010'1010001,
|
||||||
|
0b10011010'1011001,
|
||||||
|
0b11110011'1001111
|
||||||
|
};
|
||||||
|
const Icon directory_small = {
|
||||||
|
0b11111000'0000000,
|
||||||
|
0b11111100'0000000,
|
||||||
|
0b11111111'1111111,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b11111111'1111111
|
||||||
|
};
|
||||||
|
const Icon zip_small = {
|
||||||
|
//0b0011111'11111111,
|
||||||
|
//0b0110000'11000111,
|
||||||
|
//0b1111111'11111101,
|
||||||
|
//0b1000001'00000111,
|
||||||
|
//0b1000001'00000101,
|
||||||
|
//0b1000001'00000111,
|
||||||
|
//0b1000001'00000111,
|
||||||
|
//0b1111111'11111101,
|
||||||
|
//0b1000001'00000111,
|
||||||
|
//0b1000001'00000101,
|
||||||
|
//0b1000001'00000111,
|
||||||
|
//0b1000001'00000110,
|
||||||
|
//0b1111111'11111100
|
||||||
|
0b11111000'0000000,
|
||||||
|
0b11111100'0000000,
|
||||||
|
0b11111111'1111111,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b10001111'1110001,
|
||||||
|
0b10000000'1110001,
|
||||||
|
0b10000001'1100001,
|
||||||
|
0b10000011'1000001,
|
||||||
|
0b10000111'0000001,
|
||||||
|
0b10001110'0000001,
|
||||||
|
0b10001111'1110001,
|
||||||
|
0b10000000'0000001,
|
||||||
|
0b11111111'1111111
|
||||||
|
|
||||||
|
};
|
||||||
|
const Icon unknown_large = {
|
||||||
|
0b00111'11111111'11000000,
|
||||||
|
0b00111'11111111'11100000,
|
||||||
|
0b00110'00000000'01110000,
|
||||||
|
0b00110'00000000'00111000,
|
||||||
|
0b00110'00000000'00011100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00110'00000000'00001100,
|
||||||
|
0b00111'11111111'11111100,
|
||||||
|
0b00111'11111111'11111100
|
||||||
|
};
|
||||||
|
const Icon rom_large = {
|
||||||
|
0b00000'01111111'11000000,
|
||||||
|
0b00000'01111111'11000000,
|
||||||
|
0b00000'01101010'11000000,
|
||||||
|
0b00000'01101010'11000000,
|
||||||
|
0b00000'01101010'11000000,
|
||||||
|
0b00000'01101010'11000000,
|
||||||
|
0b00000'01101010'11000000,
|
||||||
|
0b00000'01101010'11000000,
|
||||||
|
0b00000'11101010'11100000,
|
||||||
|
0b00000'11001010'01100000,
|
||||||
|
0b00000'11001010'01100000,
|
||||||
|
0b00001'11001010'01110000,
|
||||||
|
0b00001'10001010'00110000,
|
||||||
|
0b00011'10011011'00111000,
|
||||||
|
0b00011'00011011'00011000,
|
||||||
|
0b11111'00111011'10011111,
|
||||||
|
0b11110'01111011'11001111,
|
||||||
|
0b11000'01111011'11000011,
|
||||||
|
0b11000'11111011'11100011,
|
||||||
|
0b11111'11011111'01111111,
|
||||||
|
0b11111'10011111'00111111
|
||||||
|
};
|
||||||
|
const Icon directory_large = {
|
||||||
|
0b111111'10000000'0000000,
|
||||||
|
0b111111'11000000'0000000,
|
||||||
|
0b111111'11100000'0000000,
|
||||||
|
0b111111'11111111'1111111,
|
||||||
|
0b111111'11111111'1111111,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b111111'11111111'1111111,
|
||||||
|
0b111111'11111111'1111111
|
||||||
|
};
|
||||||
|
const Icon zip_large = {
|
||||||
|
0b111111'10000000'0000000,
|
||||||
|
0b111111'11000000'0000000,
|
||||||
|
0b111111'11100000'0000000,
|
||||||
|
0b111111'11111111'1111111,
|
||||||
|
0b111111'11111111'1111111,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'11111111'1000011,
|
||||||
|
0b110000'11111111'1000011,
|
||||||
|
0b110000'00000011'0000011,
|
||||||
|
0b110000'00000110'0000011,
|
||||||
|
0b110000'00001100'0000011,
|
||||||
|
0b110000'00011000'0000011,
|
||||||
|
0b110000'00110000'0000011,
|
||||||
|
0b110000'01100000'0000011,
|
||||||
|
0b110000'11111111'1000011,
|
||||||
|
0b110000'11111111'1000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b110000'00000000'0000011,
|
||||||
|
0b111111'11111111'1111111,
|
||||||
|
0b111111'11111111'1111111
|
||||||
|
};
|
||||||
|
const bool smallIcon = iconWidth() < 24;
|
||||||
|
const int iconGap = smallIcon ? 2 : 3;
|
||||||
|
Icon icon = smallIcon ? unknown_small : unknown_large;
|
||||||
|
|
||||||
|
switch(_iconList[i])
|
||||||
|
{
|
||||||
|
case IconType::rom:
|
||||||
|
icon = smallIcon ? rom_small: rom_large;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IconType::directory:
|
||||||
|
icon = smallIcon ? directory_small : directory_large;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IconType::zip:
|
||||||
|
icon = smallIcon ? zip_small : zip_large;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FBSurface& s = _boss->dialog().surface();
|
||||||
|
|
||||||
|
s.drawBitmap(icon.data(), x + 1 + iconGap, y + (_lineHeight - static_cast<int>(icon.size())) / 2,
|
||||||
|
color, iconWidth() - iconGap * 2, static_cast<int>(icon.size()));
|
||||||
|
|
||||||
|
return iconWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
int FileListWidget::iconWidth() const
|
||||||
|
{
|
||||||
|
bool smallIcon = _lineHeight < 26;
|
||||||
|
|
||||||
|
return smallIcon ? 16 + 4: 24 + 6;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string FileListWidget::getToolTip(const Common::Point& pos) const
|
string FileListWidget::getToolTip(const Common::Point& pos) const
|
||||||
{
|
{
|
||||||
Common::Rect rect = getEditRect();
|
const Common::Rect rect = getEditRect();
|
||||||
int idx = getToolTipIndex(pos);
|
const int idx = getToolTipIndex(pos);
|
||||||
|
|
||||||
if(idx < 0)
|
if(idx < 0)
|
||||||
return EmptyString;
|
return EmptyString;
|
||||||
|
@ -260,12 +475,11 @@ string FileListWidget::getToolTip(const Common::Point& pos) const
|
||||||
|
|
||||||
const string value = _list[idx];
|
const string value = _list[idx];
|
||||||
|
|
||||||
if(uInt32(_font.getStringWidth(value)) > rect.w())
|
if(uInt32(_font.getStringWidth(value)) > rect.w() - iconWidth())
|
||||||
return _toolTipText + value;
|
return _toolTipText + value;
|
||||||
else
|
else
|
||||||
return _toolTipText;
|
return _toolTipText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt64 FileListWidget::_QUICK_SELECT_DELAY = 300;
|
uInt64 FileListWidget::_QUICK_SELECT_DELAY = 300;
|
||||||
|
|
|
@ -96,12 +96,24 @@ class FileListWidget : public StringListWidget
|
||||||
ProgressDialog& progress();
|
ProgressDialog& progress();
|
||||||
void incProgress();
|
void incProgress();
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum class IconType {
|
||||||
|
unknown,
|
||||||
|
rom,
|
||||||
|
directory,
|
||||||
|
zip
|
||||||
|
};
|
||||||
|
using IconTypeList = std::vector<IconType>;
|
||||||
|
using Icon = std::vector<uInt32>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Very similar to setDirectory(), but also updates the history */
|
/** Very similar to setDirectory(), but also updates the history */
|
||||||
void setLocation(const FilesystemNode& node, const string& select);
|
void setLocation(const FilesystemNode& node, const string& select);
|
||||||
|
|
||||||
bool handleText(char text) override;
|
bool handleText(char text) override;
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
int drawIcon(int i, int x, int y, ColorId color) override;
|
||||||
|
int iconWidth() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FilesystemNode::ListMode _fsmode{FilesystemNode::ListMode::All};
|
FilesystemNode::ListMode _fsmode{FilesystemNode::ListMode::All};
|
||||||
|
@ -111,6 +123,7 @@ class FileListWidget : public StringListWidget
|
||||||
bool _includeSubDirs{false};
|
bool _includeSubDirs{false};
|
||||||
|
|
||||||
StringList _dirList;
|
StringList _dirList;
|
||||||
|
IconTypeList _iconList;
|
||||||
|
|
||||||
Common::FixedStack<string> _history;
|
Common::FixedStack<string> _history;
|
||||||
uInt32 _selected{0};
|
uInt32 _selected{0};
|
||||||
|
|
|
@ -796,7 +796,7 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
case kLoadROMCmd:
|
case kLoadROMCmd:
|
||||||
if(myList->selected().isDirectory())
|
if(myList->selected().isDirectory())
|
||||||
{
|
{
|
||||||
if(myList->selected().getName() == " [..]")
|
if(myList->selected().getName() == "..")
|
||||||
myList->selectParent();
|
myList->selectParent();
|
||||||
else
|
else
|
||||||
myList->selectDirectory();
|
myList->selectDirectory();
|
||||||
|
|
|
@ -102,6 +102,7 @@ void StringListWidget::drawWidget(bool hilite)
|
||||||
for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++)
|
for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++)
|
||||||
{
|
{
|
||||||
const int y = _y + 2 + _lineHeight * i;
|
const int y = _y + 2 + _lineHeight * i;
|
||||||
|
int iw = 0;
|
||||||
ColorId textColor = kTextColor;
|
ColorId textColor = kTextColor;
|
||||||
|
|
||||||
// Draw the selected item inverted, on a highlighted background.
|
// Draw the selected item inverted, on a highlighted background.
|
||||||
|
@ -115,17 +116,18 @@ void StringListWidget::drawWidget(bool hilite)
|
||||||
else
|
else
|
||||||
s.frameRect(_x + 1, _y + 1 + _lineHeight * i, _w - 1, _lineHeight, kWidColorHi);
|
s.frameRect(_x + 1, _y + 1 + _lineHeight * i, _w - 1, _lineHeight, kWidColorHi);
|
||||||
}
|
}
|
||||||
|
iw = drawIcon(pos, _x, y - 1, textColor);
|
||||||
|
|
||||||
Common::Rect r(getEditRect());
|
Common::Rect r(getEditRect());
|
||||||
if (_selectedItem == pos && _editMode)
|
if (_selectedItem == pos && _editMode)
|
||||||
{
|
{
|
||||||
adjustOffset();
|
adjustOffset();
|
||||||
|
|
||||||
s.drawString(_font, editString(), _x + r.x(), y, r.w(), textColor,
|
s.drawString(_font, editString(), _x + iw + r.x(), y, r.w() - iw, textColor,
|
||||||
TextAlign::Left, -_editScrollOffset, false);
|
TextAlign::Left, -_editScrollOffset, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s.drawString(_font, _list[pos], _x + r.x(), y, r.w(), textColor);
|
s.drawString(_font, _list[pos], _x + iw + r.x(), y, r.w() - iw, textColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only draw the caret while editing, and if it's in the current viewport
|
// Only draw the caret while editing, and if it's in the current viewport
|
||||||
|
|
|
@ -44,6 +44,7 @@ class StringListWidget : public ListWidget
|
||||||
int getToolTipIndex(const Common::Point& pos) const;
|
int getToolTipIndex(const Common::Point& pos) const;
|
||||||
|
|
||||||
void drawWidget(bool hilite) override;
|
void drawWidget(bool hilite) override;
|
||||||
|
virtual int drawIcon(int i, int x, int y, ColorId color) { return 0; }
|
||||||
Common::Rect getEditRect() const override;
|
Common::Rect getEditRect() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in New Issue