mirror of
https://github.com/joel16/VITAlbum.git
synced 2024-11-26 21:10:25 +00:00
gui: Use tabs for filebrowser/settings and use table impl for file management
This commit is contained in:
parent
72f50c05f1
commit
6e0be931c2
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
12
include/tabs.h
Normal 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
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
162
source/gui.cpp
162
source/gui.cpp
@ -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
40
source/image.cpp
Normal 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();
|
||||
}
|
||||
}
|
@ -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];
|
||||
|
108
source/main.cpp
108
source/main.cpp
@ -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
|
||||
|
@ -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
173
source/tabs/filebrowser.cpp
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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
161
source/window.cpp
Normal 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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user