added multiple image searching and switching

This commit is contained in:
Thomas Jentzsch 2022-08-10 20:59:02 +02:00
parent df95dd0df8
commit 15ecfc1887
3 changed files with 139 additions and 21 deletions

View File

@ -319,6 +319,65 @@ namespace BSPF
return false; return false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline size_t matchWithJoker(const string& str, const string& pattern)
{
if(str.length() >= pattern.length())
{
// optimize a bit
if(pattern.find('?') != string::npos)
{
for(size_t pos = 0; pos < str.length() - pattern.length() + 1; ++pos)
{
bool found = true;
for(size_t i = 0; found && i < pattern.length(); ++i)
if(pattern[i] != str[pos + i] && pattern[i] != '?')
found = false;
if(found)
return pos;
}
}
else
return str.find(pattern);
}
return string::npos;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline bool matchWithWildcards(const string& str, const string& pattern)
{
string pat = pattern;
// remove leading and trailing '*'
size_t i = 0;
while(pat[i++] == '*');
pat = pat.substr(i - 1);
i = pat.length();
while(pat[--i] == '*');
pat.erase(i + 1);
// Search for first '*'
const size_t pos = pat.find('*');
if(pos != string::npos)
{
// '*' found, split pattern into left and right part, search recursively
const string leftPat = pat.substr(0, pos);
const string rightPat = pat.substr(pos + 1);
const size_t posLeft = matchWithJoker(str, leftPat);
if(posLeft != string::npos)
return matchWithWildcards(str.substr(pos + posLeft), rightPat);
else
return false;
}
// no further '*' found
return matchWithJoker(str, pat) != string::npos;
}
// Modify 'str', replacing all occurrences of 'from' with 'to' // Modify 'str', replacing all occurrences of 'from' with 'to'
inline void replaceAll(string& str, const string& from, const string& to) inline void replaceAll(string& str, const string& from, const string& to)
{ {

View File

@ -24,6 +24,7 @@
#include "PNGLibrary.hxx" #include "PNGLibrary.hxx"
#include "Props.hxx" #include "Props.hxx"
#include "PropsSet.hxx" #include "PropsSet.hxx"
#include "bspf.hxx"
#include "RomImageWidget.hxx" #include "RomImageWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -99,20 +100,26 @@ void RomImageWidget::parseProperties(const FSNode& node)
mySurfaceIsValid = false; mySurfaceIsValid = false;
#ifdef PNG_SUPPORT #ifdef PNG_SUPPORT
// TODO: RETRON_77
// Get a valid filename representing a snapshot file for this rom and load the snapshot // Get a valid filename representing a snapshot file for this rom and load the snapshot
const string& path = instance().snapshotLoadDir().getPath(); const string& path = instance().snapshotLoadDir().getPath();
// 1. Try to load snapshot by property name // 1. Try to load snapshots by property name
mySurfaceIsValid = loadPng(path + myProperties.get(PropType::Cart_Name) + ".png"); if(getImageList(path + myProperties.get(PropType::Cart_Name)))
mySurfaceIsValid = loadPng(myImageList[0].getPath());
//mySurfaceIsValid = loadPng(path + myProperties.get(PropType::Cart_Name) + ".png");
if(!mySurfaceIsValid) if(!mySurfaceIsValid)
{ {
// 2. If no snapshot with property name exists, try to load snapshot image by filename // 2. If no snapshots with property name exists, try to load snapshot images by filename
mySurfaceIsValid = loadPng(path + node.getNameWithExt("") + ".png"); if(getImageList(path + node.getNameWithExt("")))
mySurfaceIsValid = loadPng(myImageList[0].getPath());
//mySurfaceIsValid = loadPng(path + node.getNameWithExt("") + ".png");
if(!mySurfaceIsValid) if(!mySurfaceIsValid)
{ {
// 3. If no ROM snapshot exists, try to load a default snapshot // 3. If no ROM snapshots exist, try to load a default snapshot
mySurfaceIsValid = loadPng(path + "default_snapshot.png"); mySurfaceIsValid = loadPng(path + "default_snapshot.png");
} }
} }
@ -126,6 +133,22 @@ void RomImageWidget::parseProperties(const FSNode& node)
} }
#ifdef PNG_SUPPORT #ifdef PNG_SUPPORT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RomImageWidget::getImageList(const string& filename)
{
FSNode::NameFilter filter = ([&](const FSNode& node) {
return (!node.isDirectory() &&
(node.getPath() == filename + ".png" ||
BSPF::matchWithWildcards(node.getPath(), filename + "#*.png")));
});
FSNode node(instance().snapshotLoadDir().getPath());
myImageList.clear();
node.getChildren(myImageList, FSNode::ListMode::FilesOnly, filter, false, false);
return myImageList.size() > 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RomImageWidget::loadPng(const string& filename) bool RomImageWidget::loadPng(const string& filename)
{ {
@ -139,6 +162,7 @@ bool RomImageWidget::loadPng(const string& filename)
instance().frameBuffer().hidpiScaleFactor(); instance().frameBuffer().hidpiScaleFactor();
mySurface->setDstSize(static_cast<uInt32>(src.w() * scale), static_cast<uInt32>(src.h() * scale)); mySurface->setDstSize(static_cast<uInt32>(src.w() * scale), static_cast<uInt32>(src.h() * scale));
setDirty();
return true; return true;
} }
catch(const runtime_error& e) catch(const runtime_error& e)
@ -149,17 +173,32 @@ bool RomImageWidget::loadPng(const string& filename)
} }
#endif #endif
#ifdef PNG_SUPPORT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//void RomImageWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount) void RomImageWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
//{ {
// if(isEnabled() && isHighlighted() if(isEnabled() && x >= 0 && x < _w && y >= 0 && y < _h)
// && x >= 0 && x < _w {
// && y >= static_cast<int>(_h) + _font.getFontHeight() / 2 && y < _h) if(x < _w/2)
// { {
// clearFlags(Widget::FLAG_HILITED); // avoid double clicks and opened URLs if(myImageIdx)
// sendCommand(kClickedCmd, 0, _id); {
// } loadPng(myImageList[--myImageIdx].getPath());
//} }
}
else if(myImageIdx < myImageList.size())
{
loadPng(myImageList[++myImageIdx].getPath());
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomImageWidget::handleMouseMoved(int x, int y)
{
myMouseX = x;
}
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomImageWidget::drawWidget(bool hilite) void RomImageWidget::drawWidget(bool hilite)
@ -195,5 +234,15 @@ void RomImageWidget::drawWidget(bool hilite)
s.drawString(_font, mySurfaceErrorMsg, x, y, _w - 10, _textcolor); s.drawString(_font, mySurfaceErrorMsg, x, y, _w - 10, _textcolor);
} }
#ifdef PNG_SUPPORT
if(isHighlighted())
{
// TODO: need another surface
const int xOfs = myMouseX < _w / 2 ? 10 : _w - 50;
s.line(xOfs, _h / 2 - 10, xOfs + 20, _h / 2, kBtnTextColorHi);
}
#endif
clearDirty(); clearDirty();
} }

View File

@ -26,11 +26,6 @@ class Properties;
class RomImageWidget : public Widget, public CommandSender class RomImageWidget : public Widget, public CommandSender
{ {
public:
//enum {
// kClickedCmd = 'RIcl'
//};
public: public:
RomImageWidget(GuiObject *boss, const GUI::Font& font, RomImageWidget(GuiObject *boss, const GUI::Font& font,
int x, int y, int w, int h); int x, int y, int w, int h);
@ -42,11 +37,15 @@ class RomImageWidget : public Widget, public CommandSender
protected: protected:
void drawWidget(bool hilite) override; void drawWidget(bool hilite) override;
//void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; #ifdef PNG_SUPPORT
void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
void handleMouseMoved(int x, int y) override;
#endif
private: private:
void parseProperties(const FSNode& node); void parseProperties(const FSNode& node);
#ifdef PNG_SUPPORT #ifdef PNG_SUPPORT
bool getImageList(const string& filename);
bool loadPng(const string& filename); bool loadPng(const string& filename);
#endif #endif
@ -66,6 +65,17 @@ class RomImageWidget : public Widget, public CommandSender
// Indicates if an error occurred in creating/displaying the surface // Indicates if an error occurred in creating/displaying the surface
string mySurfaceErrorMsg; string mySurfaceErrorMsg;
#ifdef PNG_SUPPORT
// Contains the list of image names for the current ROM
FSList myImageList;
// Index of currently displayed image
int myImageIdx{0};
// Current x-position of the mouse
int myMouseX{0};
#endif
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported
RomImageWidget() = delete; RomImageWidget() = delete;