Skip to content

Commit

Permalink
Fix issues of #11
Browse files Browse the repository at this point in the history
  • Loading branch information
user-grinch committed Nov 4, 2024
1 parent dc9f01d commit 0574189
Show file tree
Hide file tree
Showing 12 changed files with 5,289 additions and 115 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# IMG Editor
# Grinch_'s IMG Editor

IMG archive editor for rockstar 3D era titles.

Expand Down
8 changes: 6 additions & 2 deletions include/hotkeys.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "hotkeys.h"
#include <Windows.h>

Hotkey::Hotkey(ImGuiKey key1, ImGuiKey key2) {
codes[0] = defaultCodes[0] = key1;
Expand All @@ -13,10 +14,13 @@ Hotkey::Hotkey(ImGuiKey key1, ImGuiKey key2) {
bool Hotkey::Pressed(bool noDelay) {
if (ImGui::GetTime() - lastUpdate < 2.0) return false;

bool key0Pressed = GetAsyncKeyState(codes[0]) & 0x8000;
bool key1Pressed = GetAsyncKeyState(codes[1]) & 0x8000;

if (noDelay) {
return ImGui::IsKeyDown(codes[0]) && ImGui::IsKeyDown(codes[1]);
return key0Pressed && key1Pressed;
} else {
if (ImGui::IsKeyDown(codes[0]) && ImGui::IsKeyDown(codes[1])) {
if (key0Pressed && key1Pressed) {
wPressed = true;
} else {
if (wPressed) {
Expand Down
5,118 changes: 5,118 additions & 0 deletions include/ui/font.h

Large diffs are not rendered by default.

24 changes: 23 additions & 1 deletion include/ui/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <dwmapi.h>
#include "resource.h"
#include "application.h"
#include "font.h"

#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
Expand Down Expand Up @@ -372,6 +373,27 @@ void Ui::Renderer::DrawLayer(Specification &Spec)
}
}

static const ImWchar ranges[] = {
0x0020, 0x00FF, // Basic Latin and Latin-1 Supplement
0x0400, 0x04FF, // Cyrillic
0x0980, 0x09FF, // Bangla
0x2000, 0x206F, // General Punctuation
0x0400, 0x052F, // Cyrillic Supplement
0x2DE0, 0x2DFF, // Hangul Jamo Extended-B
0xA640, 0xA69F, // Cyrillic Extended-D
0x011E, 0x011F, // Latin Extended-D
0x015E, 0x015F, // Latin Extended-D
0x0130, 0x0131, // Latin Extended-D
0x0600, 0x06FF, // Arabic
0x4E00, 0x9FFF, // CJK Unified Ideographs
0xAC00, 0xD7AF, // Hangul Syllables
0x3040, 0x309F, // Hiragana
0x30A0, 0x30FF, // Katakana
0x0E00, 0x0E7F, // Thai
0x0370, 0x03FF, // Greek and Coptic
0,
};

void Ui::Renderer::Init(const Specification &Spec)
{
ImGui_ImplWin32_EnableDpiAwareness();
Expand Down Expand Up @@ -415,7 +437,7 @@ void Ui::Renderer::Init(const Specification &Spec)
info.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(monitor, &info);
int h = info.rcMonitor.bottom - info.rcMonitor.top;
io.FontDefault = io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeui.ttf", 17.0f * h/768);
io.FontDefault = io.Fonts->AddFontFromMemoryCompressedBase85TTF(UiFont, 17.0f * h/768, NULL, ranges);
io.Fonts->Build();

ImGui_ImplWin32_Init(hwnd);
Expand Down
151 changes: 70 additions & 81 deletions src/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,19 @@
#include "windialogs.h"
#include "updater.h"
#include "hotkeys.h"
#include <codecvt>

std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;

Hotkey selectAll {ImGuiKey_ModCtrl, ImGuiKey_A};
Hotkey selectInverse {ImGuiKey_ModShift, ImGuiKey_A};
Hotkey openFile {ImGuiKey_ModCtrl, ImGuiKey_O};
Hotkey newFile {ImGuiKey_ModCtrl, ImGuiKey_N};
Hotkey saveFile {ImGuiKey_ModCtrl, ImGuiKey_S};
Hotkey saveFileAs {ImGuiKey_ModShift, ImGuiKey_S};
Hotkey importFile {ImGuiKey_ModCtrl, ImGuiKey_I};
Hotkey importReplaceFile {ImGuiKey_ModShift, ImGuiKey_I};
Hotkey exportFile {ImGuiKey_ModCtrl, ImGuiKey_E};
Hotkey exportSelectedFile {ImGuiKey_ModShift, ImGuiKey_E};
#include "utils.h"

Hotkey closeTab {VK_SHIFT, 0x58}; // VK_X
Hotkey selectAll {VK_CONTROL, 0x41}; // VK_A
Hotkey selectInverse {VK_SHIFT, 0x41}; // VK_A
Hotkey openFile {VK_CONTROL, 0x4F}; // VK_O
Hotkey newFile {VK_CONTROL, 0x4E}; // VK_N
Hotkey saveFile {VK_CONTROL, 0x53}; // VK_S
Hotkey saveFileAs {VK_SHIFT, 0x53}; // VK_S
Hotkey importFile {VK_CONTROL, 0x49}; // VK_I
Hotkey importReplaceFile {VK_SHIFT, 0x49}; // VK_I
Hotkey exportFile {VK_CONTROL, 0x45}; // VK_E
Hotkey exportSelectedFile {VK_SHIFT, 0x45}; // VK_E

void Editor::AboutPopUp()
{
Expand All @@ -33,6 +32,7 @@ void Editor::AboutPopUp()
ImGui::Dummy(ImVec2(0, 10));
Widget::TextCentered("Credits");
ImGui::Columns(2, NULL, false);

ImGui::Text("Freetype");
ImGui::Text("ImGui");
ImGui::NextColumn();
Expand Down Expand Up @@ -106,10 +106,7 @@ void Editor::WelcomePopup()

const wchar_t* Editor::GetFilterText()
{
static wchar_t buf[256];
ConvertCharToWideChar(Filter.InputBuf, buf, sizeof(buf));
assert(sizeof(Filter.InputBuf) != sizeof(buf));
return buf;
return FilterText;
}

bool Editor::DoesArchiveExist(const std::wstring &name)
Expand Down Expand Up @@ -140,6 +137,7 @@ void Editor::ProcessMenuBar()
if (ImGui::MenuItem("Open... (Ctrl + O)")) OpenArchive();
if (ImGui::MenuItem("Save (Ctrl + S)", NULL, false, pSelectedArchive && !pSelectedArchive->Path.empty())) SaveArchive();
if (ImGui::MenuItem("Save as... (Shift + S)", NULL, false, pSelectedArchive)) SaveArchiveAs();
if (ImGui::MenuItem("Close (Shift + X)", NULL, false, pSelectedArchive)) CloseArchive(pSelectedArchive);
ImGui::EndMenu();
}

Expand Down Expand Up @@ -233,7 +231,9 @@ void Editor::ProcessContextMenu()
{
if (ImGui::MenuItem("Copy name"))
{
ImGui::SetClipboardText(converter.to_bytes(pContextEntry->FileName).c_str());
char buf[24];
Utils::ConvertWideToUtf8(pContextEntry->FileName, sizeof(pContextEntry->FileName), buf, sizeof(buf));
ImGui::SetClipboardText(buf);
pContextEntry = nullptr;
}
if (ImGui::MenuItem("Delete"))
Expand All @@ -249,15 +249,7 @@ void Editor::ProcessContextMenu()
),
pSelectedArchive->EntryList.end()
);
wchar_t buf[256];
ConvertCharToWideChar(Filter.InputBuf, buf, sizeof(buf));
assert(sizeof(Filter.InputBuf) != sizeof(buf));
pSelectedArchive->UpdateSelectList(buf);
pContextEntry = nullptr;
}
if (ImGui::MenuItem("Dump list"))
{
DumpList();
pSelectedArchive->UpdateSelectList(FilterText);
pContextEntry = nullptr;
}
if (ImGui::MenuItem("Export"))
Expand All @@ -270,11 +262,6 @@ void Editor::ProcessContextMenu()
}
pContextEntry = nullptr;
}
if (ImGui::MenuItem("Import"))
{
ImportAndReplaceFiles();
pContextEntry = nullptr;
}
if (ImGui::MenuItem("Rename"))
{
if (pSelectedArchive)
Expand All @@ -284,23 +271,10 @@ void Editor::ProcessContextMenu()
e.bRename = false;
}
pContextEntry->bRename = true;
wchar_t buf[256];
ConvertCharToWideChar(Filter.InputBuf, buf, sizeof(buf));
assert(sizeof(Filter.InputBuf) != sizeof(buf));
pSelectedArchive->UpdateSelectList(buf);
pSelectedArchive->UpdateSelectList(FilterText);
}
pContextEntry = nullptr;
}
if (ImGui::MenuItem("Select all"))
{
SelectAll();
pContextEntry = nullptr;
}
if (ImGui::MenuItem("Select inverse"))
{
SelectInverse();
pContextEntry = nullptr;
}
height = ImGui::GetWindowHeight();
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsWindowHovered())
{
Expand Down Expand Up @@ -330,7 +304,9 @@ void Editor::ProcessWindow()
{
for (IMGArchive &archive : ArchiveList)
{
if (ImGui::BeginTabItem(converter.to_bytes(archive.FileName).c_str(), &archive.bOpen))
char buf[24];
Utils::ConvertWideToUtf8(archive.FileName.c_str(), archive.FileName.size(), buf, sizeof(buf));
if (ImGui::BeginTabItem(buf, &archive.bOpen))
{
pSelectedArchive = &archive;
ImGui::Columns(2, NULL, false);
Expand All @@ -339,12 +315,13 @@ void Editor::ProcessWindow()

// Search bar
ImGui::SetNextItemWidth(ImGui::GetColumnWidth() - style.ItemSpacing.x - style.WindowPadding.x);
if (Widget::Filter("##Search", Filter, "Search"))

static char buf[256] = "";
if (ImGui::InputTextWithHint("##Filter", "Search", buf, sizeof(buf)))
{
wchar_t buf[256];
ConvertCharToWideChar(Filter.InputBuf, buf, sizeof(buf));
assert(sizeof(Filter.InputBuf) != sizeof(buf));
pSelectedArchive->UpdateSelectList(buf);
Utils::ConvertUtf8ToWide(buf, sizeof(buf), FilterText, sizeof(buf));
Utils::ToLowerCase(FilterText);
pSelectedArchive->UpdateSelectList(FilterText);
}

if (ImGui::BeginTable("ListedItems", 3, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
Expand All @@ -364,20 +341,17 @@ void Editor::ProcessWindow()
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; ++i)
{
EntryInfo *pEntry = archive.SelectedList[i];
if (Filter.PassFilter(converter.to_bytes(pEntry->FileName).c_str()))
{

ImGui::TableNextRow();
ImGui::TableNextColumn();
// Renaming system
if (pEntry->bRename)
{
ImGui::SetNextItemWidth(ImGui::GetColumnWidth());

char buf[24];
memset(buf, 0, sizeof(buf));
assert(sizeof(buf) != sizeof(pEntry->FileName));
char buf[24] = "";
if (ImGui::InputText("##Rename", buf, sizeof(buf))) {
ConvertCharToWideChar(buf, pEntry->FileName, sizeof(pEntry->FileName));
Utils::ConvertUtf8ToWide(buf, sizeof(buf), pEntry->FileName, sizeof(pEntry->FileName));
}
if (ImGui::IsKeyPressed(VK_RETURN)
|| (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsItemHovered()))
Expand All @@ -393,7 +367,9 @@ void Editor::ProcessWindow()
ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive));
styleApplied = true;
}
if (ImGui::Selectable(converter.to_bytes(pEntry->FileName).c_str(), pEntry->bSelected))
char buf[24] = "";
Utils::ConvertWideToUtf8(pEntry->FileName, sizeof(pEntry->FileName), buf, sizeof(buf));
if (ImGui::Selectable(buf, pEntry->bSelected))
{
ProcessSelection(pEntry, &archive);
}
Expand All @@ -410,7 +386,10 @@ void Editor::ProcessWindow()
}

ImGui::TableNextColumn();
if (ImGui::Selectable(converter.to_bytes(pEntry->Type + L"##" + pEntry->FileName).c_str(), archive.EntryList[i].bSelected))
char buf[128] = "";
std::wstring str = pEntry->Type + L"##" + pEntry->FileName;
Utils::ConvertWideToUtf8(str.c_str(), str.size(), buf, sizeof(buf));
if (ImGui::Selectable(buf, archive.EntryList[i].bSelected))
{
ProcessSelection(pEntry, &archive);
}
Expand All @@ -419,16 +398,16 @@ void Editor::ProcessWindow()
pContextEntry = pContextEntry ? nullptr : pEntry;
}
ImGui::TableNextColumn();
;
if (ImGui::Selectable(converter.to_bytes(std::format(L"{} kb ## {}", pEntry->Size*2, pEntry->FileName)).c_str(), archive.EntryList[i].bSelected))
str = std::format(L"{} kb ## {}", pEntry->Size*2, pEntry->FileName);
Utils::ConvertWideToUtf8(str.c_str(), str.size(), buf, sizeof(buf));
if (ImGui::Selectable(buf, archive.EntryList[i].bSelected))
{
ProcessSelection(pEntry, &archive);
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Right))
{
pContextEntry = pContextEntry ? nullptr : pEntry;
}
}
}
}
ProcessContextMenu();
Expand Down Expand Up @@ -479,11 +458,13 @@ void Editor::ProcessWindow()
ImGui::TableHeadersRow();

int size = static_cast<int>(pSelectedArchive->LogList.size()-1);
char buf[256];
for (int i = size; i >= 0; --i)
{
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text(converter.to_bytes(pSelectedArchive->LogList[i]).c_str());
Utils::ConvertWideToUtf8(pSelectedArchive->LogList[i].c_str(), pSelectedArchive->LogList[i].size(), buf, sizeof(buf));
ImGui::Text(buf);
}
ImGui::EndTable();
}
Expand All @@ -496,17 +477,7 @@ void Editor::ProcessWindow()
// Remove element if closed form editor
if (!archive.bOpen)
{
ArchiveList.erase (
std::remove_if (
ArchiveList.begin(),
ArchiveList.end(),

[&archive](IMGArchive const& obj) {
return obj.bCreateNew ? obj.FileName == archive.FileName : obj.Path == archive.Path;
}
),
ArchiveList.end()
);
CloseArchive(&archive);
}
}

Expand All @@ -533,6 +504,8 @@ void Editor::ProcessWindow()
SelectAll();
} else if (selectInverse.Pressed()) {
SelectInverse();
} else if (closeTab.Pressed()) {
CloseArchive(pSelectedArchive);
}
}

Expand Down Expand Up @@ -566,7 +539,7 @@ void Editor::Run()
static_cast<long>(Ui::eTheme::SystemDefault)));

Ui::Specification spec;
spec.Name = "IMG Editor v" EDITOR_VERSION;
spec.Name = "Grinch_'s IMG Editor v" EDITOR_VERSION;
spec.MenuBarFunc = ProcessMenuBar;

HMONITOR monitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTONEAREST);
Expand Down Expand Up @@ -613,8 +586,10 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
}
}

bool exists = std::filesystem::exists(&lpCmdLine[1]);
Editor::AddArchiveEntry(exists ? IMGArchive(converter.from_bytes(&lpCmdLine[1])) : IMGArchive(L"Untitled", true));
bool exists = std::filesystem::exists(&lpCmdLine[1]);
wchar_t buf[256];
Utils::ConvertUtf8ToWide(&lpCmdLine[1], strlen(&lpCmdLine[1]), buf, sizeof(buf));
Editor::AddArchiveEntry(exists ? IMGArchive(buf) : IMGArchive(L"Untitled", true));
Updater::CheckUpdate();
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)&Updater::Process, NULL, NULL, NULL);
Editor::Run();
Expand Down Expand Up @@ -766,11 +741,25 @@ void Editor::DumpList()
}
}

void Editor::CloseArchive(IMGArchive *pArchive)
{
ArchiveList.erase (
std::remove_if (
ArchiveList.begin(),
ArchiveList.end(),
[pArchive](IMGArchive const& obj) {
return obj.bCreateNew ? obj.FileName == pArchive->FileName : obj.Path == pArchive->Path;
}
),
ArchiveList.end()
);
}


void Editor::ProcessSelection(EntryInfo *pEntry, IMGArchive *pArchive)
{
bool isShiftDown = ImGui::IsKeyDown(VK_LSHIFT) || ImGui::IsKeyDown(VK_RSHIFT);
bool isCtrlDown = ImGui::IsKeyDown(VK_LCONTROL) || ImGui::IsKeyDown(VK_RCONTROL);
bool isShiftDown = GetAsyncKeyState(VK_SHIFT) & 0x8000;
bool isCtrlDown = GetAsyncKeyState(VK_CONTROL) & 0x8000;
int lastSelectedIndex = -1;
int clickedIndex = -1;

Expand Down
Loading

0 comments on commit 0574189

Please sign in to comment.