gui: Use tabs for filebrowser/settings and use table impl for file management

This commit is contained in:
Joel16 2021-11-21 14:48:19 -05:00
parent 72f50c05f1
commit 6e0be931c2
20 changed files with 558 additions and 463 deletions

View File

@ -72,15 +72,16 @@ add_executable(${PROJECT_NAME}
source/config.cpp
source/fs.cpp
source/gui.cpp
source/image.cpp
source/keyboard.cpp
source/log.cpp
source/main.cpp
source/textures.cpp
source/utils.cpp
source/window.cpp
source/popups/properties.cpp
source/windows/filebrowser.cpp
source/windows/image.cpp
source/windows/settings.cpp
source/tabs/filebrowser.cpp
source/tabs/settings.cpp
)
# Library to link to (drop the prefix). This will mostly be stubs.

View File

@ -10,10 +10,10 @@ typedef struct {
std::string cwd;
} config_t;
extern config_t config;
extern config_t cfg;
namespace Config {
int Save(config_t config);
int Save(config_t &config);
int Load(void);
}

View File

@ -9,15 +9,15 @@
namespace FS {
bool FileExists(const std::string &path);
bool DirExists(const std::string &path);
int GetFileSize(const std::string &path, SceOff *size);
int GetFileSize(const std::string &path, SceOff &size);
std::string GetFileExt(const std::string &filename);
bool IsImageType(const std::string &filename);
int GetDirList(const std::string &path, std::vector<SceIoDirent> &entries);
int ChangeDirNext(const std::string &path, std::vector<SceIoDirent> &entries);
int ChangeDirPrev(std::vector<SceIoDirent> &entries);
const std::string BuildPath(SceIoDirent *entry);
const std::string BuildPath(SceIoDirent &entry);
int CreateFile(const std::string &path);
int ReadFile(const std::string &path, unsigned char **buffer, SceOff *size);
int ReadFile(const std::string &path, unsigned char **buffer, SceOff &size);
int WriteFile(const std::string &path, const void *data, SceSize size);
}

View File

@ -1,25 +1,6 @@
#ifndef _VITALBUM_GUI_H_
#define _VITALBUM_GUI_H_
#include <psp2/io/dirent.h>
#include "textures.h"
enum GUI_STATES {
GUI_STATE_HOME,
GUI_STATE_IMAGE_PREVIEW,
GUI_STATE_SETTINGS
};
typedef struct {
GUI_STATES state = GUI_STATE_HOME;
SceOff selected = 0;
std::vector<SceIoDirent> entries;
std::vector<Tex> textures;
int frame_count = 0;
float zoom_factor = 1.0f;
} MenuItem;
namespace GUI {
int RenderLoop(void);
}

View File

@ -3,6 +3,7 @@
#include "imgui.h"
#include "textures.h"
#include "windows.h"
namespace Popups {
inline void SetupPopup(const char *id) {
@ -16,7 +17,7 @@ namespace Popups {
ImGui::PopStyleVar();
};
void ImageProperties(bool *state, MenuItem *item, Tex *texture);
void ImageProperties(bool &state, WindowData &data, Tex &texture);
}
#endif

12
include/tabs.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef _VITALBUM_TABS_H_
#define _VITALBUM_TABS_H_
#include "imgui.h"
#include "windows.h"
namespace Tabs {
void FileBrowser(WindowData &data);
void Settings(void);
}
#endif

View File

@ -1,25 +1,42 @@
#ifndef _VITALBUM_WINDOWS_H_
#define _VITALBUM_WINDOWS_H_
#include <psp2/ctrl.h>
#include <psp2/io/dirent.h>
#include "gui.h"
#include "imgui.h"
#include "textures.h"
enum WINDOW_STATES {
WINDOW_STATE_FILEBROWSER = 0,
WINDOW_STATE_IMAGEVIEWER,
WINDOW_STATE_SETTINGS
};
enum FS_SORT_STATE {
FS_SORT_ALPHA_ASC = 0,
FS_SORT_ALPHA_DESC,
FS_SORT_SIZE_ASC,
FS_SORT_SIZE_DESC
};
typedef struct {
WINDOW_STATES state = WINDOW_STATE_FILEBROWSER;
SceOff selected = 0;
std::vector<SceIoDirent> entries;
std::vector<Tex> textures;
int frame_count = 0;
float zoom_factor = 1.0f;
} WindowData;
extern int sort;
namespace Windows {
inline void SetupWindow(void) {
ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f), ImGuiCond_Once);
ImGui::SetNextWindowSize(ImVec2(960.0f, 544.0f), ImGuiCond_Once);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
};
inline void ExitWindow(void) {
ImGui::End();
ImGui::PopStyleVar();
};
void FileBrowserWindow(MenuItem *item);
void ImageWindow(MenuItem *item);
void SettingsWindow(MenuItem *item);
void SetupWindow(void);
void ExitWindow(void);
void MainWindow(WindowData &data, SceCtrlData &pad);
void ImageViewer(WindowData &data);
}
#endif

View File

@ -8,7 +8,7 @@
#define CONFIG_VERSION 2
config_t config;
config_t cfg;
namespace Config {
static const char *config_file = "{\n\t\"config_ver\": %d,\n\t\"dev_options\": %s,\n\t\"image_filename\": %s,\n\t\"last_dir\": \"%s\",\n\t\"sort\": %d\n}";
@ -27,7 +27,7 @@ namespace Config {
}
};
int Save(config_t config) {
int Save(config_t &config) {
int ret = 0;
char *buf = new char[1024];
SceSize len = std::snprintf(buf, 1024, config_file, CONFIG_VERSION, config.dev_options? "true" : "false",
@ -42,11 +42,11 @@ namespace Config {
return 0;
}
static void SetDefault(config_t *config) {
config->sort = 0;
config->dev_options = false;
config->image_filename = false;
config->cwd = "ux0:";
static void SetDefault(config_t &config) {
config.sort = 0;
config.dev_options = false;
config.image_filename = false;
config.cwd = "ux0:";
}
int Load(void) {
@ -58,8 +58,8 @@ namespace Config {
sceIoMkdir("ux0:data/VITAlbum", 0777);
if (!FS::FileExists("ux0:data/VITAlbum/config.json")) {
Config::SetDefault(&config);
return Config::Save(config);
Config::SetDefault(cfg);
return Config::Save(cfg);
}
SceUID file = 0;
@ -94,22 +94,22 @@ namespace Config {
// We know sceJson API loops through the child values in root alphabetically.
config_version_holder = value.getValue(0).getInteger();
config.dev_options = value.getValue(1).getBoolean();
config.image_filename = value.getValue(2).getBoolean();
config.cwd = value.getValue(3).getString().c_str();
config.sort = value.getValue(4).getInteger();
cfg.dev_options = value.getValue(1).getBoolean();
cfg.image_filename = value.getValue(2).getBoolean();
cfg.cwd = value.getValue(3).getString().c_str();
cfg.sort = value.getValue(4).getInteger();
init.terminate();
delete alloc;
if (!FS::DirExists(config.cwd))
config.cwd = "ux0:";
if (!FS::DirExists(cfg.cwd))
cfg.cwd = "ux0:";
// Delete config file if config file is updated. This will rarely happen.
if (config_version_holder < CONFIG_VERSION) {
sceIoRemove("ux0:data/VITAlbum/config.json");
Config::SetDefault(&config);
return Config::Save(config);
Config::SetDefault(cfg);
return Config::Save(cfg);
}
return 0;

View File

@ -34,7 +34,7 @@ namespace FS {
return false;
}
int GetFileSize(const std::string &path, SceOff *size) {
int GetFileSize(const std::string &path, SceOff &size) {
int ret = 0;
SceIoStat stat;
@ -43,7 +43,7 @@ namespace FS {
return ret;
}
*size = stat.st_size;
size = stat.st_size;
return 0;
}
@ -65,46 +65,17 @@ namespace FS {
}
static bool Sort(const SceIoDirent &entryA, const SceIoDirent &entryB) {
if ((SCE_S_ISDIR(entryA.d_stat.st_mode)) && !(SCE_S_ISDIR(entryB.d_stat.st_mode)))
return true;
else if (!(SCE_S_ISDIR(entryA.d_stat.st_mode)) && (SCE_S_ISDIR(entryB.d_stat.st_mode)))
return false;
else {
switch(config.sort) {
case 0:
if (strcasecmp(entryA.d_name, entryB.d_name) < 0)
return true;
break;
case 1:
if (strcasecmp(entryB.d_name, entryA.d_name) < 0)
return true;
break;
case 2:
if (entryB.d_stat.st_size < entryA.d_stat.st_size)
return true;
break;
case 3:
if (entryA.d_stat.st_size < entryB.d_stat.st_size)
return true;
break;
}
}
return false;
}
int GetDirList(const std::string &path, std::vector<SceIoDirent> &entries) {
int ret = 0;
SceUID dir = 0;
entries.clear();
// Create ".." entry
SceIoDirent entry;
std::strncpy(entry.d_name, "..", 3);
entry.d_stat.st_mode = SCE_S_IFDIR;
entry.d_stat.st_size = 0;
entries.push_back(entry);
if (R_FAILED(ret = dir = sceIoDopen(path.c_str()))) {
Log::Error("sceIoDopen(%s) failed: %08x\n", path.c_str(), ret);
@ -123,8 +94,7 @@ namespace FS {
entries.push_back(entry);
}
} while (ret > 0);
std::sort(entries.begin(), entries.end(), FS::Sort);
sceIoDclose(dir);
return 0;
}
@ -139,24 +109,24 @@ namespace FS {
// Free entries and change the current working directory.
entries.clear();
config.cwd = path;
Config::Save(config);
cfg.cwd = path;
Config::Save(cfg);
entries = new_entries;
return 0;;
}
static int ChangeDirUp(char path[256]) {
if (config.cwd.length() <= 1 && config.cwd.c_str()[0] == '/')
if (cfg.cwd.length() <= 1 && cfg.cwd.c_str()[0] == '/')
return -1;
// Remove upmost directory
bool copy = false;
int len = 0;
for (ssize_t i = config.cwd.length(); i >= 0; i--) {
if (config.cwd.c_str()[i] == '/')
for (ssize_t i = cfg.cwd.length(); i >= 0; i--) {
if (cfg.cwd.c_str()[i] == '/')
copy = true;
if (copy) {
path[i] = config.cwd.c_str()[i];
path[i] = cfg.cwd.c_str()[i];
len++;
}
}
@ -170,7 +140,7 @@ namespace FS {
}
int ChangeDirNext(const std::string &path, std::vector<SceIoDirent> &entries) {
std::string new_path = config.cwd;
std::string new_path = cfg.cwd;
new_path.append("/");
new_path.append(path);
return FS::ChangeDir(new_path, entries);
@ -184,10 +154,10 @@ namespace FS {
return FS::ChangeDir(std::string(new_path), entries);
}
const std::string BuildPath(SceIoDirent *entry) {
std::string path = config.cwd;
const std::string BuildPath(SceIoDirent &entry) {
std::string path = cfg.cwd;
path.append("/");
path.append(entry->d_name);
path.append(entry.d_name);
return path;
}
@ -208,7 +178,7 @@ namespace FS {
return 0;
}
int ReadFile(const std::string &path, unsigned char **buffer, SceOff *size) {
int ReadFile(const std::string &path, unsigned char **buffer, SceOff &size) {
int ret = 0;
SceUID file = 0;
@ -217,10 +187,10 @@ namespace FS {
return ret;
}
*size = sceIoLseek(file, 0, SEEK_END);
*buffer = new unsigned char[*size];
size = sceIoLseek(file, 0, SEEK_END);
*buffer = new unsigned char[size];
if (R_FAILED(ret = sceIoPread(file, *buffer, *size, SCE_SEEK_SET))) {
if (R_FAILED(ret = sceIoPread(file, *buffer, size, SCE_SEEK_SET))) {
Log::Error("sceIoPread(%s) failed: 0x%lx\n", path.c_str(), ret);
return ret;
}

View File

@ -1,5 +1,4 @@
#include <imgui_vita.h>
#include <psp2/kernel/threadmgr.h>
#include <vitaGL.h>
#include "config.h"
@ -7,7 +6,6 @@
#include "gui.h"
#include "imgui.h"
#include "imgui_internal.h"
#include "popups.h"
#include "utils.h"
#include "windows.h"
@ -28,172 +26,28 @@ namespace Renderer {
}
namespace GUI {
static void ClearTextures(MenuItem *item) {
for (int i = 0; i < item->textures.size(); i++)
Textures::Free(&item->textures[i]);
item->textures.clear();
item->frame_count = 0;
}
static bool HandleScroll(MenuItem *item, int index) {
if (SCE_S_ISDIR(item->entries[index].d_stat.st_mode))
return false;
else {
item->selected = index;
std::string path = FS::BuildPath(&item->entries[index]);
bool ret = Textures::LoadImageFile(path, item->textures);
IM_ASSERT(ret);
return true;
}
return false;
}
static bool HandlePrev(MenuItem *item) {
bool ret = false;
for (int i = item->selected - 1; i > 0; i--) {
std::string filename = item->entries[i].d_name;
if (filename.empty())
continue;
if (!(ret = GUI::HandleScroll(item, i)))
continue;
else
break;
}
return ret;
}
static bool HandleNext(MenuItem *item) {
bool ret = false;
if (item->selected == item->entries.size())
return ret;
for (int i = item->selected + 1; i < item->entries.size(); i++) {
if (!(ret = GUI::HandleScroll(item, i)))
continue;
else
break;
}
return ret;
}
int RenderLoop(void) {
bool done = false, properties = false;
bool done = false;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
MenuItem item;
WindowData data;
SceCtrlData pad = { 0 };
int ret = 0;
if (R_FAILED(ret = FS::GetDirList(config.cwd, item.entries)))
if (R_FAILED(ret = FS::GetDirList(cfg.cwd, data.entries)))
return ret;
while (!done) {
Renderer::Start();
Windows::FileBrowserWindow(&item);
switch (item.state) {
case GUI_STATE_IMAGE_PREVIEW:
Windows::ImageWindow(&item);
if (properties)
Popups::ImageProperties(&properties, &item, &item.textures[0]);
break;
case GUI_STATE_SETTINGS:
Windows::SettingsWindow(&item);
break;
default:
break;
}
Renderer::End(clear_color);
pad = Utils::ReadControls();
Windows::MainWindow(data, pad);
Renderer::End(clear_color);
switch (item.state) {
case GUI_STATE_HOME:
if (pressed & SCE_CTRL_SELECT)
item.state = GUI_STATE_SETTINGS;
else if (pressed & SCE_CTRL_CANCEL) {
if (R_SUCCEEDED(FS::ChangeDirPrev(item.entries)))
GImGui->NavId = 0;
}
break;
case GUI_STATE_IMAGE_PREVIEW:
if (pressed & SCE_CTRL_TRIANGLE)
properties = !properties;
if (pad.ly > 170) {
item.zoom_factor -= 0.5f * ImGui::GetIO().DeltaTime;
if (item.zoom_factor < 0.1f)
item.zoom_factor = 0.1f;
}
else if (pad.ly < 70) {
item.zoom_factor += 0.5f * ImGui::GetIO().DeltaTime;
if (item.zoom_factor > 5.0f)
item.zoom_factor = 5.0f;
}
if (!properties) {
if (pressed & SCE_CTRL_CANCEL) {
GUI::ClearTextures(&item);
item.zoom_factor = 1.0f;
item.state = GUI_STATE_HOME;
}
if (pressed & SCE_CTRL_LTRIGGER) {
GUI::ClearTextures(&item);
sceKernelDelayThread(100000);
if (!GUI::HandlePrev(&item))
item.state = GUI_STATE_HOME;
}
else if (pressed & SCE_CTRL_RTRIGGER) {
GUI::ClearTextures(&item);
sceKernelDelayThread(100000);
if (!GUI::HandleNext(&item))
item.state = GUI_STATE_HOME;
}
}
else {
if (pressed & SCE_CTRL_CANCEL)
properties = false;
}
break;
case GUI_STATE_SETTINGS:
if (pressed & SCE_CTRL_CANCEL) {
Config::Save(config);
item.entries.clear();
FS::GetDirList(config.cwd, item.entries);
item.state = GUI_STATE_HOME;
}
break;
default:
break;
}
/*if (pressed & SCE_CTRL_START)
done = true;*/
if (pressed & SCE_CTRL_START)
done = true;
}
item.entries.clear();
data.entries.clear();
return 0;
}
}

40
source/image.cpp Normal file
View File

@ -0,0 +1,40 @@
#include <psp2/kernel/threadmgr.h>
#include "config.h"
#include "imgui.h"
#include "windows.h"
#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui_internal.h"
namespace Windows {
void ImageViewer(WindowData &data) {
Windows::SetupWindow();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGuiWindowFlags_ filename_flag = !cfg.image_filename? ImGuiWindowFlags_NoTitleBar : ImGuiWindowFlags_None;
if (ImGui::Begin(data.entries[data.selected].d_name, nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | filename_flag)) {
if (((data.textures[0].width * data.zoom_factor) <= 960.0f) && ((data.textures[0].height * data.zoom_factor) <= 544.0f))
ImGui::SetCursorPos((ImGui::GetContentRegionAvail() - ImVec2((data.textures[data.frame_count].width * data.zoom_factor),
(data.textures[data.frame_count].height * data.zoom_factor))) * 0.5f);
if (data.textures.size() > 1) {
sceKernelDelayThread(data.textures[data.frame_count].delay * 10000);
ImGui::Image(reinterpret_cast<ImTextureID>(data.textures[data.frame_count].id), ImVec2(data.textures[data.frame_count].width * data.zoom_factor,
data.textures[data.frame_count].height * data.zoom_factor));
data.frame_count++;
// Reset frame counter
if (data.frame_count == data.textures.size() - 1)
data.frame_count = 0;
}
else
ImGui::Image(reinterpret_cast<ImTextureID>(data.textures[0].id), ImVec2(data.textures[0].width * data.zoom_factor, data.textures[0].height * data.zoom_factor));
}
Windows::ExitWindow();
ImGui::PopStyleVar();
}
}

View File

@ -10,7 +10,7 @@ namespace Log {
static SceUID log_file = 0;
void Init(void) {
if (!config.dev_options)
if (!cfg.dev_options)
return;
if (!FS::FileExists("ux0:data/VITAlbum/debug.log"))
@ -21,7 +21,7 @@ namespace Log {
}
void Exit(void) {
if (!config.dev_options)
if (!cfg.dev_options)
return;
if (R_FAILED(sceIoClose(log_file)))
@ -29,7 +29,7 @@ namespace Log {
}
void Error(const char *data, ...) {
if (!config.dev_options)
if (!cfg.dev_options)
return;
char buf[512];

View File

@ -12,63 +12,63 @@ int _newlib_heap_size_user = 192 * 1024 * 1024;
namespace Services {
void SetDefaultTheme(void) {
ImGui::GetStyle().FrameRounding = 4.0f;
ImGui::GetStyle().GrabRounding = 4.0f;
ImVec4 *colors = ImGui::GetStyle().Colors;
colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.12f, 0.14f, 0.65f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.18f, 0.22f, 0.25f, 1.00f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.09f, 0.21f, 0.31f, 1.00f);
colors[ImGuiCol_CheckMark] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.37f, 0.61f, 1.00f, 1.00f);
colors[ImGuiCol_Button] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_Header] = ImVec4(0.20f, 0.25f, 0.29f, 0.55f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f);
colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_NavHighlight] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
ImGui::GetStyle().FrameRounding = 4.0f;
ImGui::GetStyle().GrabRounding = 4.0f;
ImVec4 *colors = ImGui::GetStyle().Colors;
colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.12f, 0.14f, 0.65f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.18f, 0.22f, 0.25f, 1.00f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.09f, 0.21f, 0.31f, 1.00f);
colors[ImGuiCol_CheckMark] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.37f, 0.61f, 1.00f, 1.00f);
colors[ImGuiCol_Button] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_Header] = ImVec4(0.20f, 0.25f, 0.29f, 0.55f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_TabActive] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_NavHighlight] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
io.IniFilename = nullptr;
}
}
void Init(void) {
// Initalize vitaGL and imGui contexts

View File

@ -5,28 +5,28 @@
#include "utils.h"
namespace Popups {
void ImageProperties(bool *state, MenuItem *item, Tex *texture) {
void ImageProperties(bool &state, WindowData &data, Tex &texture) {
ImGui::OpenPopup("Properties");
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20));
ImGui::SetNextWindowPos(ImVec2(480.0f, 272.0f), ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
std::string new_width, new_height;
if (ImGui::BeginPopupModal("Properties", state, ImGuiWindowFlags_AlwaysAutoResize)) {
if (ImGui::BeginPopupModal("Properties", &state, ImGuiWindowFlags_AlwaysAutoResize)) {
std::string parent_text = "Parent: ";
parent_text.append(config.cwd);
parent_text.append(cfg.cwd);
ImGui::Text(parent_text.c_str());
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
std::string name_text = "Name: ";
name_text.append(item->entries[item->selected].d_name);
name_text.append(data.entries[data.selected].d_name);
ImGui::Text(name_text.c_str());
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
if (!SCE_S_ISDIR(item->entries[item->selected].d_stat.st_mode)) {
if (!SCE_S_ISDIR(data.entries[data.selected].d_stat.st_mode)) {
char size[16];
Utils::GetSizeString(size, item->entries[item->selected].d_stat.st_size);
Utils::GetSizeString(size, data.entries[data.selected].d_stat.st_size);
std::string size_text = "Size: ";
size_text.append(size);
ImGui::Text(size_text.c_str());
@ -35,22 +35,22 @@ namespace Popups {
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
std::string width_text = "Width: ";
width_text.append(std::to_string(texture->width));
width_text.append(std::to_string(texture.width));
width_text.append("px");
ImGui::Text(width_text.c_str());
/*ImGui::SameLine(0.0f, 10.0f);
if (ImGui::Button("Edit width"))
new_width = Keyboard::GetText("Enter width", std::to_string(texture->width));*/
new_width = Keyboard::GetText("Enter width", std::to_string(texture.width));*/
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
std::string height_text = "Height: ";
height_text.append(std::to_string(texture->height));
height_text.append(std::to_string(texture.height));
height_text.append("px");
ImGui::Text(height_text.c_str());
/*ImGui::SameLine(0.0f, 10.0f);
if (ImGui::Button("Edit height"))
new_height = Keyboard::GetText("Enter height", std::to_string(texture->height));*/
new_height = Keyboard::GetText("Enter height", std::to_string(texture.height));*/
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
@ -58,8 +58,8 @@ namespace Popups {
// int new_width_int = std::stoi(new_width);
// int new_height_int = std::stoi(new_height);
if ((!new_height.empty()) || (!new_width.empty())) {
if (new_width != std::to_string(texture->width))
else if (new_height != std::to_string(texture->height))
if (new_width != std::to_string(texture.width))
else if (new_height != std::to_string(texture.height))
}
}
@ -68,7 +68,7 @@ namespace Popups {
if (ImGui::Button("OK", ImVec2(120, 0))) {
ImGui::CloseCurrentPopup();
*state = false;
state = false;
}
ImGui::EndPopup();

173
source/tabs/filebrowser.cpp Normal file
View File

@ -0,0 +1,173 @@
#include <algorithm>
#include <cstring>
#include "config.h"
#include "fs.h"
#include "imgui.h"
#include "imgui_internal.h"
#include "utils.h"
#include "windows.h"
int sort = 0;
namespace FileBrowser {
// Sort without using ImGuiTableSortSpecs
bool Sort(const SceIoDirent &entryA, const SceIoDirent &entryB) {
// Make sure ".." stays at the top regardless of sort direction
if (strcasecmp(entryA.d_name, "..") == 0)
return true;
if (strcasecmp(entryB.d_name, "..") == 0)
return false;
if ((SCE_S_ISDIR(entryA.d_stat.st_mode)) && !(SCE_S_ISDIR(entryB.d_stat.st_mode)))
return true;
else if (!(SCE_S_ISDIR(entryA.d_stat.st_mode)) && (SCE_S_ISDIR(entryB.d_stat.st_mode)))
return false;
switch(sort) {
case FS_SORT_ALPHA_ASC:
return (strcasecmp(entryA.d_name, entryB.d_name) < 0);
break;
case FS_SORT_ALPHA_DESC:
return (strcasecmp(entryB.d_name, entryA.d_name) < 0);
break;
case FS_SORT_SIZE_ASC:
return (entryA.d_stat.st_size < entryB.d_stat.st_size);
break;
case FS_SORT_SIZE_DESC:
return (entryB.d_stat.st_size < entryA.d_stat.st_size);
break;
}
return false;
}
}
namespace Tabs {
static const ImVec2 tex_size = ImVec2(22, 22);
// Sort using ImGuiTableSortSpecs
bool Sort(const SceIoDirent &entryA, const SceIoDirent &entryB) {
bool descending = false;
ImGuiTableSortSpecs *table_sort_specs = ImGui::TableGetSortSpecs();
for (int i = 0; i < table_sort_specs->SpecsCount; ++i) {
const ImGuiTableColumnSortSpecs *column_sort_spec = &table_sort_specs->Specs[i];
descending = (column_sort_spec->SortDirection == ImGuiSortDirection_Descending);
// Make sure ".." stays at the top regardless of sort direction
if (strcasecmp(entryA.d_name, "..") == 0)
return true;
if (strcasecmp(entryB.d_name, "..") == 0)
return false;
if ((SCE_S_ISDIR(entryA.d_stat.st_mode)) && !(SCE_S_ISDIR(entryB.d_stat.st_mode)))
return true;
else if (!(SCE_S_ISDIR(entryA.d_stat.st_mode)) && (SCE_S_ISDIR(entryB.d_stat.st_mode)))
return false;
else {
switch (column_sort_spec->ColumnIndex) {
case 1: // filename
sort = descending? FS_SORT_ALPHA_DESC : FS_SORT_ALPHA_ASC;
return descending? (strcasecmp(entryB.d_name, entryA.d_name) < 0) : (strcasecmp(entryA.d_name, entryB.d_name) < 0);
break;
case 2: // Size
sort = descending? FS_SORT_SIZE_DESC : FS_SORT_SIZE_ASC;
return descending? (entryB.d_stat.st_size < entryA.d_stat.st_size) : (entryA.d_stat.st_size < entryB.d_stat.st_size);
break;
default:
break;
}
}
}
return false;
}
void FileBrowser(WindowData &data) {
if (ImGui::BeginTabItem("File Browser")) {
// Display current working directory
ImGui::TextColored(ImVec4(1.00f, 1.00f, 1.00f, 1.00f), cfg.cwd.c_str());
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_BordersInner |
ImGuiTableFlags_BordersOuter | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_ScrollY;
if (ImGui::BeginTable("Directory List", 2, tableFlags)) {
// Make header always visible
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableSetupColumn("Filename", ImGuiTableColumnFlags_DefaultSort);
ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableHeadersRow();
if (ImGuiTableSortSpecs *sorts_specs = ImGui::TableGetSortSpecs()) {
if (sort == -1)
sorts_specs->SpecsDirty = true;
if (sorts_specs->SpecsDirty) {
std::sort(data.entries.begin(), data.entries.end(), Tabs::Sort);
sorts_specs->SpecsDirty = false;
}
}
for (SceOff i = 0; i < data.entries.size(); i++) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (SCE_S_ISDIR(data.entries[i].d_stat.st_mode))
ImGui::Image(reinterpret_cast<ImTextureID>(icons[FOLDER].id), tex_size);
else
ImGui::Image(reinterpret_cast<ImTextureID>(icons[IMAGE].id), tex_size);
ImGui::SameLine();
if (ImGui::Selectable(data.entries[i].d_name, false)) {
if (SCE_S_ISDIR(data.entries[i].d_stat.st_mode)) {
if (std::strncmp(data.entries[i].d_name, "..", 2) == 0) {
FS::ChangeDirPrev(data.entries);
}
else {
FS::ChangeDirNext(data.entries[i].d_name, data.entries);
}
// Reset navigation ID -- TODO: Scroll to top
ImGuiContext& g = *GImGui;
ImGui::SetNavID(ImGui::GetID(data.entries[0].d_name, 0), g.NavLayer, 0, ImRect());
// Reapply sort
ImGuiTableSortSpecs *sorts_specs = ImGui::TableGetSortSpecs();
sorts_specs->SpecsDirty = true;
}
else {
std::string path = FS::BuildPath(data.entries[i]);
bool ret = Textures::LoadImageFile(path, data.textures);
IM_ASSERT(ret);
data.state = WINDOW_STATE_IMAGEVIEWER;
}
}
if (ImGui::IsItemHovered())
data.selected = i;
ImGui::TableNextColumn();
if ((data.entries[i].d_stat.st_size != 0) && (!SCE_S_ISDIR(data.entries[i].d_stat.st_mode))) {
char size[16];
Utils::GetSizeString(size, static_cast<double>(data.entries[i].d_stat.st_size));
ImGui::Text(size);
}
}
ImGui::EndTable();
}
ImGui::EndTabItem();
}
}
}

View File

@ -11,46 +11,30 @@
#define STRINGIFY(x) #x
#define TO_STRING(x) STRINGIFY(x)
namespace Windows {
namespace Tabs {
static void Separator(void) {
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
ImGui::Separator();
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
}
void SettingsWindow(MenuItem *item) {
Windows::SetupWindow();
if (ImGui::Begin("Settings", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) {
if (ImGui::TreeNode("Sort Settings")) {
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
ImGui::RadioButton(" By name (ascending)", &config.sort, 0);
ImGui::Dummy(ImVec2(0.0f, 15.0f)); // Spacing
ImGui::RadioButton(" By name (descending)", &config.sort, 1);
ImGui::Dummy(ImVec2(0.0f, 15.0f)); // Spacing
ImGui::RadioButton(" By size (largest first)", &config.sort, 2);
ImGui::Dummy(ImVec2(0.0f, 15.0f)); // Spacing
ImGui::RadioButton(" By size (smallest first)", &config.sort, 3);
ImGui::TreePop();
}
Windows::Separator();
void Settings(void) {
if (ImGui::BeginTabItem("Settings")) {
if (ImGui::TreeNode("Image/Gif Viewer")) {
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
ImGui::Checkbox(" Display filename", &config.image_filename);
ImGui::Checkbox(" Display filename", &cfg.image_filename);
ImGui::TreePop();
}
Windows::Separator();
Tabs::Separator();
if (ImGui::TreeNode("Developer Options")) {
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
ImGui::Checkbox(" Enable logs", &config.dev_options);
ImGui::Checkbox(" Enable logs", &cfg.dev_options);
ImGui::TreePop();
}
Windows::Separator();
Tabs::Separator();
if (ImGui::TreeNode("About")) {
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
@ -71,8 +55,8 @@ namespace Windows {
ImGui::Text("libwebp version: %d.%d.%d", (WebPGetDecoderVersion() >> 16) & 0xFF, (WebPGetDecoderVersion() >> 8) & 0xFF, WebPGetDecoderVersion() & 0xFF);
ImGui::TreePop();
}
ImGui::EndTabItem();
}
Windows::ExitWindow();
}
}

View File

@ -448,7 +448,7 @@ namespace Textures {
else {
unsigned char *data = nullptr;
SceOff size = 0;
FS::ReadFile(path, &data, &size);
FS::ReadFile(path, &data, size);
if (ext == ".BMP")
ret = Textures::LoadImageBMP(&data, &size, &textures[0]);
@ -485,7 +485,7 @@ namespace Textures {
};
for (int i = 0; i < num_icons; i++) {
if (R_FAILED(FS::ReadFile(filenames[i], &data[i], &size[i])))
if (R_FAILED(FS::ReadFile(filenames[i], &data[i], size[i])))
break;
}

161
source/window.cpp Normal file
View File

@ -0,0 +1,161 @@
#include <psp2/kernel/threadmgr.h>
#include "config.h"
#include "fs.h"
#include "imgui.h"
#include "popups.h"
#include "tabs.h"
#include "utils.h"
#include "windows.h"
namespace Windows {
static bool properties = false;
void SetupWindow(void) {
ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f), ImGuiCond_Once);
ImGui::SetNextWindowSize(ImVec2(960.0f, 544.0f), ImGuiCond_Once);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
};
void ExitWindow(void) {
ImGui::End();
ImGui::PopStyleVar();
};
static void ClearTextures(WindowData &data) {
for (int i = 0; i < data.textures.size(); i++)
Textures::Free(&data.textures[i]);
data.textures.clear();
data.frame_count = 0;
}
static bool HandleScroll(WindowData &data, int index) {
if (SCE_S_ISDIR(data.entries[index].d_stat.st_mode))
return false;
else {
data.selected = index;
std::string path = FS::BuildPath(data.entries[index]);
bool ret = Textures::LoadImageFile(path, data.textures);
IM_ASSERT(ret);
return true;
}
return false;
}
static bool HandlePrev(WindowData &data) {
bool ret = false;
for (int i = data.selected - 1; i > 0; i--) {
std::string filename = data.entries[i].d_name;
if (filename.empty())
continue;
if (!(ret = Windows::HandleScroll(data, i)))
continue;
else
break;
}
return ret;
}
static bool HandleNext(WindowData &data) {
bool ret = false;
if (data.selected == data.entries.size())
return ret;
for (int i = data.selected + 1; i < data.entries.size(); i++) {
if (!(ret = Windows::HandleScroll(data, i)))
continue;
else
break;
}
return ret;
}
void MainWindow(WindowData &data, SceCtrlData &pad) {
Windows::SetupWindow();
if (ImGui::Begin("VITAlbum", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) {
if (ImGui::BeginTabBar("VITAlbum-tabs")) {
Tabs::FileBrowser(data);
Tabs::Settings();
ImGui::EndTabBar();
}
if (data.state == WINDOW_STATE_IMAGEVIEWER)
Windows::ImageViewer(data);
switch (data.state) {
case WINDOW_STATE_FILEBROWSER:
if (pressed & SCE_CTRL_SELECT)
data.state = WINDOW_STATE_SETTINGS;
break;
case WINDOW_STATE_IMAGEVIEWER:
if (pressed & SCE_CTRL_TRIANGLE)
properties = !properties;
if (pad.ly > 170) {
data.zoom_factor -= 0.5f * ImGui::GetIO().DeltaTime;
if (data.zoom_factor < 0.1f)
data.zoom_factor = 0.1f;
}
else if (pad.ly < 70) {
data.zoom_factor += 0.5f * ImGui::GetIO().DeltaTime;
if (data.zoom_factor > 5.0f)
data.zoom_factor = 5.0f;
}
if (!properties) {
if (pressed & SCE_CTRL_CANCEL) {
Windows::ClearTextures(data);
data.zoom_factor = 1.0f;
data.state = WINDOW_STATE_FILEBROWSER;
}
if (pressed & SCE_CTRL_LTRIGGER) {
Windows::ClearTextures(data);
sceKernelDelayThread(100000);
if (!Windows::HandlePrev(data))
data.state = WINDOW_STATE_FILEBROWSER;
}
else if (pressed & SCE_CTRL_RTRIGGER) {
Windows::ClearTextures(data);
sceKernelDelayThread(100000);
if (!Windows::HandleNext(data))
data.state = WINDOW_STATE_FILEBROWSER;
}
}
else {
if (pressed & SCE_CTRL_CANCEL)
properties = false;
}
break;
case WINDOW_STATE_SETTINGS:
if (pressed & SCE_CTRL_CANCEL) {
Config::Save(cfg);
data.entries.clear();
FS::GetDirList(cfg.cwd, data.entries);
data.state = WINDOW_STATE_FILEBROWSER;
}
break;
default:
break;
}
}
Windows::ExitWindow();
}
}

View File

@ -1,59 +0,0 @@
#include "config.h"
#include "fs.h"
#include "imgui.h"
#include "imgui_internal.h"
#include "windows.h"
namespace Windows {
static bool focus = false;
void FileBrowserWindow(MenuItem *item) {
Windows::SetupWindow();
if (ImGui::Begin("VITAlbum", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) {
ImGui::TextColored(ImVec4(1.00f, 1.00f, 1.00f, 1.00f), config.cwd.c_str());
if (!focus) {
ImGui::SetNextWindowFocus();
focus = true;
}
ImGui::BeginChild("##FS::GetDirList");
for (unsigned int i = 0; i < item->entries.size(); i++) {
if (SCE_S_ISDIR(item->entries[i].d_stat.st_mode))
ImGui::Image(reinterpret_cast<ImTextureID>(icons[FOLDER].id), ImVec2(icons[FOLDER].width, icons[FOLDER].height));
else if (FS::IsImageType(item->entries[i].d_name))
ImGui::Image(reinterpret_cast<ImTextureID>(icons[IMAGE].id), ImVec2(icons[IMAGE].width, icons[IMAGE].height));
ImGui::SameLine();
if (ImGui::Selectable(item->entries[i].d_name)) {
item->selected = i;
if (SCE_S_ISDIR(item->entries[i].d_stat.st_mode)) {
std::string filename = item->entries[i].d_name;
if (filename == "..")
FS::ChangeDirPrev(item->entries);
else
FS::ChangeDirNext(filename, item->entries);
GImGui->NavId = 0;
}
else {
std::string path = FS::BuildPath(&item->entries[i]);
bool ret = Textures::LoadImageFile(path, item->textures);
IM_ASSERT(ret);
item->state = GUI_STATE_IMAGE_PREVIEW;
}
}
if (ImGui::IsItemHovered())
item->selected = i;
}
ImGui::EndChild();
}
Windows::ExitWindow();
}
}

View File

@ -1,40 +0,0 @@
#include <psp2/kernel/threadmgr.h>
#include "config.h"
#include "imgui.h"
#include "windows.h"
#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui_internal.h"
namespace Windows {
void ImageWindow(MenuItem *item) {
Windows::SetupWindow();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGuiWindowFlags_ filename_flag = !config.image_filename? ImGuiWindowFlags_NoTitleBar : ImGuiWindowFlags_None;
if (ImGui::Begin(item->entries[item->selected].d_name, nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | filename_flag)) {
if (((item->textures[0].width * item->zoom_factor) <= 960.0f) && ((item->textures[0].height * item->zoom_factor) <= 544.0f))
ImGui::SetCursorPos((ImGui::GetContentRegionAvail() - ImVec2((item->textures[item->frame_count].width * item->zoom_factor),
(item->textures[item->frame_count].height * item->zoom_factor))) * 0.5f);
if (item->textures.size() > 1) {
sceKernelDelayThread(item->textures[item->frame_count].delay * 10000);
ImGui::Image(reinterpret_cast<ImTextureID>(item->textures[item->frame_count].id), ImVec2(item->textures[item->frame_count].width * item->zoom_factor,
item->textures[item->frame_count].height * item->zoom_factor));
item->frame_count++;
// Reset frame counter
if (item->frame_count == item->textures.size() - 1)
item->frame_count = 0;
}
else
ImGui::Image(reinterpret_cast<ImTextureID>(item->textures[0].id), ImVec2(item->textures[0].width * item->zoom_factor, item->textures[0].height * item->zoom_factor));
}
Windows::ExitWindow();
ImGui::PopStyleVar();
}
}