mirror of https://github.com/Poikilos/b3view
move modes to engine, improve texture search
parent
e75f4c1c36
commit
0a4aac71a9
|
@ -1,4 +1,12 @@
|
|||
# Changelog
|
||||
## [git] - 2019-07-03
|
||||
(poikilos)
|
||||
### Changes
|
||||
* Move display mode booleans to engine.
|
||||
* Add more string utilities.
|
||||
* Do fuzzy search against actual texture names if can't find theoretical
|
||||
ones.
|
||||
|
||||
## [git] - 2019-05-16
|
||||
(poikilos)
|
||||
### Added
|
||||
|
|
57
Engine.cpp
57
Engine.cpp
|
@ -22,6 +22,49 @@ using namespace irr::gui;
|
|||
PRIVATE METHODS
|
||||
/////////////////////////////////////////////////////////////////////// */
|
||||
|
||||
bool Engine::getEnableWireframe() const
|
||||
{
|
||||
return m_EnableWireframe;
|
||||
}
|
||||
|
||||
bool Engine::getEnableLighting() const
|
||||
{
|
||||
return m_EnableLighting;
|
||||
}
|
||||
|
||||
bool Engine::getEnableTextureInterpolation() const
|
||||
{
|
||||
return m_EnableTextureInterpolation;
|
||||
}
|
||||
|
||||
void Engine::setEnableWireframe(bool EnableWireframe)
|
||||
{
|
||||
if (this->m_EnableWireframe != EnableWireframe) {
|
||||
this->setMeshDisplayMode(EnableWireframe, this->m_EnableLighting,
|
||||
this->m_EnableTextureInterpolation);
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::setEnableLighting(bool EnableLighting)
|
||||
{
|
||||
if (this->m_EnableLighting != EnableLighting) {
|
||||
this->setMeshDisplayMode(this->m_EnableWireframe, EnableLighting,
|
||||
this->m_EnableTextureInterpolation);
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::setEnableTextureInterpolation(bool EnableTextureInterpolation)
|
||||
{
|
||||
if (this->m_EnableTextureInterpolation != EnableTextureInterpolation)
|
||||
debug() << "setEnableTextureInterpolation(..., setEnableTextureInterpolation:"
|
||||
<< (EnableTextureInterpolation?"true":"false") << ")" << endl;
|
||||
|
||||
if (this->m_EnableTextureInterpolation != EnableTextureInterpolation) {
|
||||
this->setMeshDisplayMode(this->m_EnableWireframe, this->m_EnableLighting,
|
||||
EnableTextureInterpolation);
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::setupScene()
|
||||
{
|
||||
// Setup Light
|
||||
|
@ -237,6 +280,9 @@ Engine::Engine()
|
|||
keyState[i] = 0;
|
||||
LMouseState = 0;
|
||||
RMouseState = 0;
|
||||
this->m_EnableWireframe = false;
|
||||
this->m_EnableLighting = false;
|
||||
this->m_EnableTextureInterpolation = true;
|
||||
this->axisLength = 10;
|
||||
this->worldFPS = 60;
|
||||
this->prevFPS = 30;
|
||||
|
@ -382,6 +428,8 @@ bool Engine::loadMesh(const wstring& fileName)
|
|||
// EMT_TRANSPARENT_ALPHA_CHANNEL: constant transparency
|
||||
}
|
||||
}
|
||||
this->setMeshDisplayMode(this->m_EnableWireframe, this->m_EnableLighting,
|
||||
this->m_EnableTextureInterpolation);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -400,7 +448,7 @@ std::wstring Engine::saveMesh(const io::path path, const std::string& nameOrBlan
|
|||
// see also https://bitbucket.org/mzeilfelder/irr-playground-micha/src/default/obj_readwrite.cpp (saves scene::EMWT_OBJ)
|
||||
scene::ISceneManager* smgr = m_Device->getSceneManager();
|
||||
scene::IMeshWriter* meshWriter = nullptr;
|
||||
//this->m_FileName = "";
|
||||
// this->m_FileName = "";
|
||||
io::path fileName = io::path();
|
||||
std::string beginning = "export-";
|
||||
if (nameOrBlank.length() > 0) {
|
||||
|
@ -424,7 +472,7 @@ std::wstring Engine::saveMesh(const io::path path, const std::string& nameOrBlan
|
|||
meshWriter = smgr->createMeshWriter(scene::EMWT_STL);
|
||||
}
|
||||
if (meshWriter != nullptr) {
|
||||
//io::path filePath = path + fileName;
|
||||
// io::path filePath = path + fileName;
|
||||
io::path filePath = path + "/" + fileName;
|
||||
io::IWriteFile* meshFile = m_Device->getFileSystem()->createAndWriteFile(filePath);
|
||||
if (!meshWriter->writeMesh(meshFile, m_LoadedMesh->getMesh())) {
|
||||
|
@ -481,6 +529,9 @@ bool Engine::loadTexture(const wstring& fileName)
|
|||
void Engine::setMeshDisplayMode(bool wireframe, bool lighting,
|
||||
bool textureInterpolation)
|
||||
{
|
||||
this->m_EnableWireframe = wireframe;
|
||||
this->m_EnableLighting = lighting;
|
||||
this->m_EnableTextureInterpolation = textureInterpolation;
|
||||
if (m_LoadedMesh != nullptr) {
|
||||
for (u32 materialIndex = 0; materialIndex < m_LoadedMesh->getMaterialCount(); materialIndex++) {
|
||||
// Set Wireframe display
|
||||
|
@ -506,7 +557,7 @@ void Engine::setMeshDisplayMode(bool wireframe, bool lighting,
|
|||
}
|
||||
// m_LoadedMesh->setMaterialType(
|
||||
// video::EMT_TRANSPARENT_ALPHA_CHANNEL
|
||||
// ); //already done on load
|
||||
// ); // already done on load
|
||||
// // requires EMT_ONETEXTURE:
|
||||
// m_LoadedMesh->setMaterialFlag(video::E_ALPHA_SOURCE, true);
|
||||
if (textureInterpolation) {
|
||||
|
|
11
Engine.h
11
Engine.h
|
@ -37,6 +37,9 @@ private:
|
|||
irr::core::dimension2d<irr::u32> m_WindowSize;
|
||||
|
||||
bool m_RunEngine;
|
||||
bool m_EnableWireframe;
|
||||
bool m_EnableLighting;
|
||||
bool m_EnableTextureInterpolation;
|
||||
|
||||
EventHandler* m_EventHandler;
|
||||
UserInterface* m_UserInterface;
|
||||
|
@ -81,7 +84,7 @@ public:
|
|||
std::wstring saveMesh(const irr::io::path path, const std::string& nameOrBlank, const std::string& extension);
|
||||
void reloadTexture();
|
||||
bool loadTexture(const std::wstring& fileName);
|
||||
void setMeshDisplayMode(bool wireframe = false, bool lighting = true, bool textureInterpolation = true);
|
||||
void setMeshDisplayMode(bool wireframe = false, bool lighting = false, bool textureInterpolation = true);
|
||||
bool isAnimating();
|
||||
void playAnimation();
|
||||
void pauseAnimation();
|
||||
|
@ -90,6 +93,12 @@ public:
|
|||
void incrementAnimationFPS(irr::f32 by);
|
||||
void setZUp(bool zUp);
|
||||
irr::u32 animationFPS();
|
||||
bool getEnableWireframe() const;
|
||||
bool getEnableLighting() const;
|
||||
bool getEnableTextureInterpolation() const;
|
||||
void setEnableWireframe(bool EnableWireframe);
|
||||
void setEnableLighting(bool EnableLighting);
|
||||
void setEnableTextureInterpolation(bool EnableTextureInterpolation);
|
||||
};
|
||||
|
||||
#endif // ENGINE_H
|
||||
|
|
|
@ -49,6 +49,5 @@ bool EventHandler::OnEvent(const SEvent& event)
|
|||
iter->second->OnEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -66,10 +66,10 @@ void UserInterface::setupUserInterface()
|
|||
viewMenu = menu->getSubMenu(2);
|
||||
viewWireframeIdx = viewMenu->addItem(L"Wireframe",
|
||||
UIC_VIEW_WIREFRAME, true,
|
||||
false, this->m_WireframeDisplay, true);
|
||||
false, this->m_Engine->getEnableWireframe(), true);
|
||||
viewLightingIdx = viewMenu->addItem(L"Lighting",
|
||||
UIC_VIEW_LIGHTING, true,
|
||||
false, this->m_Lighting, true);
|
||||
false, this->m_Engine->getEnableLighting(), true);
|
||||
viewAxisWidgetIdx = viewMenu->addItem(L"Origin Axis Widget",
|
||||
UIC_VIEW_AXIS_WIDGET, true, false,
|
||||
true, true);
|
||||
|
@ -79,7 +79,7 @@ void UserInterface::setupUserInterface()
|
|||
|
||||
viewTextureInterpolationIdx = viewMenu->addItem(L"Texture Interpolation Ctrl i",
|
||||
UIC_VIEW_TEXTURE_INTERPOLATION, true, false,
|
||||
this->m_TextureInterpolation, true);
|
||||
this->m_Engine->getEnableTextureInterpolation(), true);
|
||||
|
||||
viewYUpIdx = viewMenu->addItem(L"Y Up",
|
||||
UIC_VIEW_Y_UP, true, false,
|
||||
|
@ -356,18 +356,6 @@ void UserInterface::handleMenuItemPressed(IGUIContextMenu* menu)
|
|||
//}
|
||||
break;
|
||||
|
||||
case UIC_VIEW_WIREFRAME:
|
||||
m_WireframeDisplay = viewMenu->isItemChecked(viewWireframeIdx);
|
||||
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting,
|
||||
m_TextureInterpolation);
|
||||
break;
|
||||
|
||||
case UIC_VIEW_LIGHTING:
|
||||
m_Lighting = viewMenu->isItemChecked(viewLightingIdx);
|
||||
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting,
|
||||
m_TextureInterpolation);
|
||||
break;
|
||||
|
||||
case UIC_VIEW_TARGET:
|
||||
//
|
||||
break;
|
||||
|
@ -382,17 +370,55 @@ void UserInterface::handleMenuItemPressed(IGUIContextMenu* menu)
|
|||
viewMenu->setItemChecked(viewYUpIdx, false);
|
||||
break;
|
||||
|
||||
case UIC_VIEW_TEXTURE_INTERPOLATION:
|
||||
m_TextureInterpolation = viewMenu->isItemChecked(
|
||||
viewTextureInterpolationIdx
|
||||
case UIC_VIEW_WIREFRAME:
|
||||
m_Engine->setEnableWireframe(
|
||||
!m_Engine->getEnableWireframe()
|
||||
);
|
||||
viewMenu->setItemChecked(
|
||||
viewWireframeIdx,
|
||||
m_Engine->getEnableWireframe()
|
||||
);
|
||||
break;
|
||||
|
||||
case UIC_VIEW_LIGHTING:
|
||||
m_Engine->setEnableLighting(
|
||||
!m_Engine->getEnableLighting()
|
||||
);
|
||||
viewMenu->setItemChecked(
|
||||
viewLightingIdx,
|
||||
m_Engine->getEnableLighting()
|
||||
);
|
||||
break;
|
||||
|
||||
case UIC_VIEW_TEXTURE_INTERPOLATION:
|
||||
m_Engine->setEnableTextureInterpolation(
|
||||
!m_Engine->getEnableTextureInterpolation()
|
||||
);
|
||||
viewMenu->setItemChecked(
|
||||
viewTextureInterpolationIdx,
|
||||
m_Engine->getEnableTextureInterpolation()
|
||||
);
|
||||
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting,
|
||||
m_TextureInterpolation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UserInterface::updateSettingsDisplay()
|
||||
{
|
||||
viewMenu->setItemChecked(
|
||||
viewWireframeIdx,
|
||||
m_Engine->getEnableWireframe()
|
||||
);
|
||||
viewMenu->setItemChecked(
|
||||
viewLightingIdx,
|
||||
m_Engine->getEnableLighting()
|
||||
);
|
||||
viewMenu->setItemChecked(
|
||||
viewTextureInterpolationIdx,
|
||||
m_Engine->getEnableTextureInterpolation()
|
||||
);
|
||||
}
|
||||
|
||||
void UserInterface::snapWidgets()
|
||||
{
|
||||
dimension2d<u32> screenSize = m_Engine->m_Driver->getScreenSize();
|
||||
|
@ -430,10 +456,6 @@ UserInterface::UserInterface(Engine* engine)
|
|||
|
||||
m_Engine = engine;
|
||||
m_Gui = engine->getGUIEnvironment();
|
||||
|
||||
m_WireframeDisplay = false;
|
||||
m_Lighting = true;
|
||||
m_TextureInterpolation = true;
|
||||
playbackWindow = nullptr;
|
||||
|
||||
setupUserInterface();
|
||||
|
@ -463,6 +485,21 @@ bool UserInterface::loadNextTexture(int direction)
|
|||
std::wstring lastName = Utility::basename(
|
||||
this->m_Engine->m_PreviousPath
|
||||
);
|
||||
vector<wstring> dotExtensions;
|
||||
dotExtensions.push_back(L".png");
|
||||
dotExtensions.push_back(L".jpg");
|
||||
wstring foundPath;
|
||||
wstring partial;
|
||||
partial = Utility::withoutExtension(lastName);
|
||||
vector<wstring> names;
|
||||
names.push_back(partial+L"_mesh");
|
||||
names.push_back(partial);
|
||||
names.push_back(partial+L"1");
|
||||
names.push_back(partial+L"2");
|
||||
names.push_back(partial+L"_child");
|
||||
names.push_back(partial+L"_female");
|
||||
names.push_back(partial+L"_male");
|
||||
|
||||
std::wstring lastDirPath = Utility::parentOfPath(
|
||||
this->m_Engine->m_PreviousPath
|
||||
);
|
||||
|
@ -500,66 +537,39 @@ bool UserInterface::loadNextTexture(int direction)
|
|||
wstring tryPath;
|
||||
if (fs::is_directory(fs::status(path))) {
|
||||
if (this->m_Engine->m_PrevTexturePath.length() == 0) {
|
||||
if (this->m_Engine->m_PreviousPath.length() > 0) {
|
||||
vector<wstring> dotExtensions;
|
||||
dotExtensions.push_back(L".png");
|
||||
dotExtensions.push_back(L".jpg");
|
||||
wstring foundPath;
|
||||
wstring partial = Utility::withoutExtension(
|
||||
Utility::basename(
|
||||
this->m_Engine->m_PreviousPath
|
||||
)
|
||||
);
|
||||
vector<wstring> names;
|
||||
names.push_back(partial+L"_mesh");
|
||||
names.push_back(partial);
|
||||
names.push_back(partial+L"1");
|
||||
names.push_back(partial+L"_child");
|
||||
names.push_back(partial+L"_female");
|
||||
names.push_back(partial+L"_male");
|
||||
|
||||
for(auto name : names) {
|
||||
for(auto extension : dotExtensions) {
|
||||
tryPath = texturesPath + dirSeparator
|
||||
+ name
|
||||
+ extension;
|
||||
// tryPath = Utility::toWstring(Utility::toString(tryPath));
|
||||
if (Utility::isFile(tryPath)) {
|
||||
foundPath = tryPath;
|
||||
break;
|
||||
}
|
||||
//else
|
||||
//debug() << " - no '" << Utility::toString(tryPath) << "'" << endl;
|
||||
}
|
||||
if (foundPath.length() > 0) {
|
||||
// if (this->m_Engine->m_PreviousPath.length() > 0) {
|
||||
for(auto name : names) {
|
||||
for(auto extension : dotExtensions) {
|
||||
tryPath = texturesPath + dirSeparator
|
||||
+ name
|
||||
+ extension;
|
||||
// tryPath = Utility::toWstring(Utility::toString(tryPath));
|
||||
if (Utility::isFile(tryPath)) {
|
||||
foundPath = tryPath;
|
||||
break;
|
||||
}
|
||||
//else
|
||||
//debug() << " - no '" << Utility::toString(tryPath) << "'" << endl;
|
||||
}
|
||||
if (foundPath.length() > 0) {
|
||||
nextPath = foundPath;
|
||||
found = true;
|
||||
force = true;
|
||||
m_TextureInterpolation = viewMenu->isItemChecked(
|
||||
viewTextureInterpolationIdx
|
||||
);
|
||||
if (m_TextureInterpolation) {
|
||||
m_TextureInterpolation = false;
|
||||
m_Engine->setMeshDisplayMode(
|
||||
m_WireframeDisplay,
|
||||
m_Lighting,
|
||||
m_TextureInterpolation
|
||||
);
|
||||
viewMenu->setItemChecked(
|
||||
viewTextureInterpolationIdx,
|
||||
m_TextureInterpolation
|
||||
);
|
||||
}
|
||||
} else {
|
||||
nextPath = tryPath;
|
||||
found = true;
|
||||
force = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundPath.length() > 0) {
|
||||
nextPath = foundPath;
|
||||
found = true;
|
||||
force = true;
|
||||
this->m_Engine->setEnableTextureInterpolation(false);
|
||||
viewMenu->setItemChecked(
|
||||
viewTextureInterpolationIdx,
|
||||
this->m_Engine->getEnableTextureInterpolation()
|
||||
);
|
||||
} else {
|
||||
nextPath = tryPath;
|
||||
found = true;
|
||||
force = true;
|
||||
}
|
||||
//}
|
||||
}
|
||||
for (const auto& itr : fs::directory_iterator(path)) {
|
||||
std::wstring ext = Utility::extensionOf(
|
||||
|
@ -572,6 +582,24 @@ bool UserInterface::loadNextTexture(int direction)
|
|||
// cycle through files (go to next after
|
||||
// m_PrevTexturePath if any previously loaded,
|
||||
// otherwise first)
|
||||
if (this->m_Engine->m_PrevTexturePath.length() == 0) {
|
||||
// If matched nothing yet, match regardless of beginning
|
||||
std::wstring nameNoExt = Utility::withoutExtension(itr.path().filename().wstring());
|
||||
// std::wstring rightName = Utility::rightOf(nameNoExt, L"_", true);
|
||||
// std::wstring rightLastName = Utility::rightOfLast(nameNoExt, L"_", true);
|
||||
// debug() << "itr.path().filename().wstring(): " << itr.path().filename().c_str() << endl;
|
||||
for(auto name : names) {
|
||||
if (Utility::endsWith(nameNoExt, name)) {
|
||||
nextPath = itr.path().wstring();
|
||||
this->m_Engine->setEnableTextureInterpolation(false);
|
||||
viewMenu->setItemChecked(
|
||||
viewTextureInterpolationIdx,
|
||||
this->m_Engine->getEnableTextureInterpolation()
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nextPath.length() == 0)
|
||||
nextPath = itr.path().wstring();
|
||||
lastPath = itr.path().wstring();
|
||||
|
@ -800,11 +828,14 @@ bool UserInterface::OnEvent(const SEvent& event)
|
|||
// )
|
||||
// );
|
||||
// )
|
||||
m_TextureInterpolation = m_TextureInterpolation ? false : true;
|
||||
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting,
|
||||
m_TextureInterpolation);
|
||||
viewMenu->setItemChecked(viewTextureInterpolationIdx,
|
||||
m_TextureInterpolation);
|
||||
|
||||
m_Engine->setEnableTextureInterpolation(
|
||||
!m_Engine->getEnableTextureInterpolation()
|
||||
);
|
||||
viewMenu->setItemChecked(
|
||||
viewTextureInterpolationIdx,
|
||||
m_Engine->getEnableTextureInterpolation()
|
||||
);
|
||||
}
|
||||
else
|
||||
handled = false;
|
||||
|
|
|
@ -70,10 +70,8 @@ private:
|
|||
void displayLoadTextureDialog();
|
||||
void incrementFrame(irr::f32 frameCount, bool enableRound);
|
||||
void handleMenuItemPressed(irr::gui::IGUIContextMenu* menu);
|
||||
void updateSettingsDisplay();
|
||||
|
||||
bool m_WireframeDisplay;
|
||||
bool m_Lighting;
|
||||
bool m_TextureInterpolation;
|
||||
irr::gui::IGUIWindow* playbackWindow;
|
||||
irr::core::dimension2d<irr::u32> m_WindowSize; // previous size
|
||||
public:
|
||||
|
|
59
Utility.cpp
59
Utility.cpp
|
@ -80,6 +80,7 @@ std::wstring Utility::parentOfPath(const wstring& path)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Filename without path (may still have extension)
|
||||
wstring Utility::basename(const wstring& path)
|
||||
{
|
||||
std::wstring ret = path;
|
||||
|
@ -93,6 +94,64 @@ wstring Utility::basename(const wstring& path)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Get any substring to the right of the first delimiter.
|
||||
/// allIfNotFound: Return whole string on no delimiter, vs empty string.
|
||||
wstring Utility::rightOf(const wstring& path, const wstring& delimiter, bool allIfNotFound)
|
||||
{
|
||||
std::wstring ret = allIfNotFound ? path : L"";
|
||||
std::wstring::size_type lastPos = path.find(delimiter);
|
||||
if (lastPos != std::wstring::npos) {
|
||||
ret = path.substr(lastPos + 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get any substring to the right of the last delimiter.
|
||||
/// allIfNotFound: Return whole string on no delimiter, vs empty string.
|
||||
wstring Utility::rightOfLast(const wstring& path, const wstring& delimiter, bool allIfNotFound)
|
||||
{
|
||||
std::wstring ret = allIfNotFound ? path : L"";
|
||||
std::wstring::size_type lastPos = path.find_last_of(delimiter);
|
||||
if (lastPos != std::wstring::npos) {
|
||||
ret = path.substr(lastPos + 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get any substring to the left of the first delimiter.
|
||||
/// allIfNotFound: Return whole string on no delimiter, vs empty string.
|
||||
wstring Utility::leftOf(const wstring& path, const wstring& delimiter, bool allIfNotFound)
|
||||
{
|
||||
std::wstring ret = allIfNotFound ? path : L"";
|
||||
std::wstring::size_type lastPos = path.find(delimiter);
|
||||
if (lastPos != std::wstring::npos) {
|
||||
ret = path.substr(0, lastPos);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Utility::endsWith(const std::wstring& haystack, const std::wstring& needle) {
|
||||
bool found = false;
|
||||
if (haystack.length() >= needle.length()) {
|
||||
if (haystack.substr(haystack.length()-needle.length())==needle) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/// Get any substring to the left of the last delimiter.
|
||||
/// allIfNotFound: Return whole string on no delimiter, vs empty string.
|
||||
wstring Utility::leftOfLast(const wstring& path, const wstring& delimiter, bool allIfNotFound)
|
||||
{
|
||||
std::wstring ret = allIfNotFound ? path : L"";
|
||||
std::wstring::size_type lastPos = path.find_last_of(delimiter);
|
||||
if (lastPos != std::wstring::npos) {
|
||||
ret = path.substr(0, lastPos);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
wstring Utility::withoutExtension(const wstring& path)
|
||||
{
|
||||
std::wstring ret = path;
|
||||
|
|
|
@ -12,6 +12,11 @@ public:
|
|||
static void dumpMeshInfoToConsole(irr::scene::IAnimatedMeshSceneNode* node);
|
||||
static std::wstring parentOfPath(const std::wstring& path);
|
||||
static std::wstring basename(const std::wstring& path);
|
||||
static std::wstring leftOf(const std::wstring& path, const std::wstring& delimiter, bool allIfNotFound);
|
||||
static std::wstring leftOfLast(const std::wstring& path, const std::wstring& delimiter, bool allIfNotFound);
|
||||
static std::wstring rightOf(const std::wstring& path, const std::wstring& delimiter, bool allIfNotFound);
|
||||
static std::wstring rightOfLast(const std::wstring& path, const std::wstring& delimiter, bool allIfNotFound);
|
||||
static bool endsWith(const std::wstring& haystack, const std::wstring& needle);
|
||||
static std::wstring withoutExtension(const std::wstring& path);
|
||||
static std::wstring extensionOf(const std::wstring& path);
|
||||
static std::wstring delimiter(const std::wstring& path);
|
||||
|
|
Loading…
Reference in New Issue