added icons to file lists and removed special directory name formatting

This commit is contained in:
Thomas Jentzsch 2021-11-24 23:27:42 +01:00
parent 48aced6c1e
commit dc10ca9c00
7 changed files with 257 additions and 29 deletions

View File

@ -16,6 +16,8 @@
* Added option to toggle autofire mode.
* Added icons to file lists (TODO: doc)
-Have fun!

View File

@ -171,7 +171,7 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
if (includeParentDirectory && hasParent())
{
FilesystemNode parent = getParent();
parent.setName(" [..]");
parent.setName("..");
fslist.emplace_back(parent);
}
@ -204,10 +204,6 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
else
#endif
{
// Make directories stand out
if(i->isDirectory())
i->setName(" [" + i->getName() + "]");
FilesystemNode node(i);
if(includeChildDirectories)

View File

@ -21,6 +21,8 @@
#include "FileListWidget.hxx"
#include "TimerManager.hxx"
#include "ProgressDialog.hxx"
#include "FBSurface.hxx"
#include "Bankswitch.hxx"
#include "bspf.hxx"
@ -56,9 +58,6 @@ void FileListWidget::setDirectory(const FilesystemNode& node,
string name = tmp.getName();
if(name.back() == FilesystemNode::PATH_SEPARATOR)
name.pop_back();
if(!BSPF::startsWithIgnoreCase(name, " ["))
name = " [" + name.append("]");
_history.push(name);
tmp = tmp.getParent();
}
@ -102,16 +101,29 @@ void FileListWidget::setLocation(const FilesystemNode& node,
size_t orgLen = _node.getShortPath().length();
_dirList.clear();
_iconList.clear();
for(const auto& file : _fileList)
{
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
if(path.length() >= orgLen)
_dirList.push_back(path.substr(orgLen));
else
_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);
@ -167,26 +179,21 @@ bool FileListWidget::handleText(char text)
// (or a substring accumulated from the last couple key presses).
// Only works in a useful fashion if the list entries are sorted.
uInt64 time = TimerManager::getTicks() / 1000;
if(_quickSelectTime < time)
{
if(std::isupper(text))
{
// Select directories when the first character is uppercase
_quickSelectStr = " [";
_quickSelectStr.push_back(text);
}
else
_quickSelectStr = text;
}
_quickSelectStr = text;
else
_quickSelectStr += text;
_quickSelectTime = time + _QUICK_SELECT_DELAY;
int selectedItem = 0;
for(const auto& i: _list)
for(const auto& i : _list)
{
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++;
}
@ -215,7 +222,7 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
_selected = data;
if(selected().isDirectory())
{
if(selected().getName() == " [..]")
if(selected().getName() == "..")
selectParent();
else
{
@ -246,11 +253,219 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
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
{
Common::Rect rect = getEditRect();
int idx = getToolTipIndex(pos);
const Common::Rect rect = getEditRect();
const int idx = getToolTipIndex(pos);
if(idx < 0)
return EmptyString;
@ -260,12 +475,11 @@ string FileListWidget::getToolTip(const Common::Point& pos) const
const string value = _list[idx];
if(uInt32(_font.getStringWidth(value)) > rect.w())
if(uInt32(_font.getStringWidth(value)) > rect.w() - iconWidth())
return _toolTipText + value;
else
return _toolTipText;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt64 FileListWidget::_QUICK_SELECT_DELAY = 300;

View File

@ -96,12 +96,24 @@ class FileListWidget : public StringListWidget
ProgressDialog& progress();
void incProgress();
private:
enum class IconType {
unknown,
rom,
directory,
zip
};
using IconTypeList = std::vector<IconType>;
using Icon = std::vector<uInt32>;
private:
/** Very similar to setDirectory(), but also updates the history */
void setLocation(const FilesystemNode& node, const string& select);
bool handleText(char text) 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:
FilesystemNode::ListMode _fsmode{FilesystemNode::ListMode::All};
@ -111,6 +123,7 @@ class FileListWidget : public StringListWidget
bool _includeSubDirs{false};
StringList _dirList;
IconTypeList _iconList;
Common::FixedStack<string> _history;
uInt32 _selected{0};

View File

@ -796,7 +796,7 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
case kLoadROMCmd:
if(myList->selected().isDirectory())
{
if(myList->selected().getName() == " [..]")
if(myList->selected().getName() == "..")
myList->selectParent();
else
myList->selectDirectory();

View File

@ -102,6 +102,7 @@ void StringListWidget::drawWidget(bool hilite)
for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++)
{
const int y = _y + 2 + _lineHeight * i;
int iw = 0;
ColorId textColor = kTextColor;
// Draw the selected item inverted, on a highlighted background.
@ -115,17 +116,18 @@ void StringListWidget::drawWidget(bool hilite)
else
s.frameRect(_x + 1, _y + 1 + _lineHeight * i, _w - 1, _lineHeight, kWidColorHi);
}
iw = drawIcon(pos, _x, y - 1, textColor);
Common::Rect r(getEditRect());
if (_selectedItem == pos && _editMode)
{
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);
}
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

View File

@ -44,6 +44,7 @@ class StringListWidget : public ListWidget
int getToolTipIndex(const Common::Point& pos) const;
void drawWidget(bool hilite) override;
virtual int drawIcon(int i, int x, int y, ColorId color) { return 0; }
Common::Rect getEditRect() const override;
protected: