Adding an image library because i apparently need TGAs

This commit is contained in:
2026-08-05 23:24:32 -05:00
parent 466e0570d4
commit 62a6f49eba
10 changed files with 9917 additions and 6 deletions

View File

@@ -28,6 +28,7 @@ add_executable(${PROJECT_NAME}
src/main.cpp src/main.cpp
src/database.cpp src/database.cpp
src/ui.cpp src/ui.cpp
src/image_utils.cpp
vendor/rmlui_backend/RmlUi_Backend_GLFW_GL3.cpp vendor/rmlui_backend/RmlUi_Backend_GLFW_GL3.cpp
vendor/rmlui_backend/RmlUi_Platform_GLFW.cpp vendor/rmlui_backend/RmlUi_Platform_GLFW.cpp

BIN
assets/images/icon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 KiB

55
assets/images/icon.svg Executable file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 269 KiB

BIN
assets/images/icon.tga Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 KiB

View File

@@ -2,6 +2,10 @@
<head> <head>
<title>Critterfolio</title> <title>Critterfolio</title>
<link type="text/rcss" href="styles/main.rcss" /> <link type="text/rcss" href="styles/main.rcss" />
<script>
</script>
</head> </head>
<body data-model="app_data"> <body data-model="app_data">
@@ -11,12 +15,24 @@
<!-- Critter Cards --> <!-- Critter Cards -->
<div class="critter-list"> <div class="critter-list">
<div data-for="entry : critters" class="critter-card"> <button data-for="entry : critters" class="critter-card">
<h3>#{{entry.key}} - {{entry.value.name}}</h3> <div class="critter-card-header">
<span class="critter-id">ID: #{{entry.key}}</span>
<button class="btn-delete">X</button>
</div>
<div class="critter-card-body">
<img class="critter-thumb"
src="images/icon.tga" />
<div class="critter-info">
<h3 class="critter-name">{{entry.value.name}}</h3>
<p><strong>Species:</strong> {{entry.value.species}}</p> <p><strong>Species:</strong> {{entry.value.species}}</p>
<p><strong>Gender:</strong> {{entry.value.gender}}</p> <p><strong>Gender:</strong> {{entry.value.gender}}</p>
</div> </div>
</div> </div>
</button>
</div>
<!-- Modal Dialog Overlay --> <!-- Modal Dialog Overlay -->
<div class="modal-overlay" data-visible="is_dialog_open"> <div class="modal-overlay" data-visible="is_dialog_open">

View File

@@ -272,7 +272,92 @@ progress-value {
Specific app stuff Specific app stuff
=================================== */ =================================== */
/* Critter cards */ /* Critter Cards Container */
.critter-list {
display: flex;
flex-wrap: wrap;
padding: 10px;
}
/* Interactive Card Base */
.critter-card {
display: block;
width: 220px;
margin: 10px;
padding: 10px;
background-color: #2b2b2b;
color: #ffffff;
border: 1px #444444;
border-radius: 6px;
text-align: left;
}
.critter-card:hover {
background-color: #383838;
border: 1px #005aff;
}
.critter-card:active {
background-color: #222222;
}
/* Header with Small ID & Delete Button */
.critter-card-header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px #444444;
padding-bottom: 4px;
margin-bottom: 8px;
}
.critter-id {
font-size: 11px;
color: #aaaaaa;
}
.btn-delete {
padding: 2px 6px;
min-width: 0px;
font-size: 10px;
background-color: #aa2222;
color: #ffffff;
border: 0px;
}
.btn-delete:hover {
background-color: #ff3333;
}
/* Body & Thumbnail */
.critter-card-body {
display: flex;
align-items: center;
}
.critter-thumb {
width: 48px;
height: 48px;
margin-right: 10px;
background-color: #1a1a1a;
border: 1px #555555;
}
.critter-info {
flex: 1;
}
.critter-name {
margin: 0px 0px 4px 0px;
font-size: 16px;
color: #ffffff;
}
.critter-info p {
margin: 2px 0px;
font-size: 12px;
color: #dddddd;
}
/* Modals */ /* Modals */
.modal-overlay { .modal-overlay {

38
src/image_utils.cpp Normal file
View File

@@ -0,0 +1,38 @@
// image_utils.cpp
#define STB_IMAGE_IMPLEMENTATION
#include "../vendor/stb/stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "../vendor/stb/stb_image_write.h"
#include <iostream>
#include <string>
bool ConvertToThumbnailTGA(const std::string& input_path, const std::string& output_tga_path) {
int width, height, channels;
stbi_uc* data = stbi_load(input_path.c_str(), &width, &height, &channels, 4);
if (!data) {
std::cout << "[ERROR] Failed to decode image: " << input_path << std::endl;
return false;
}
int result = stbi_write_tga(output_tga_path.c_str(), width, height, 4, data);
stbi_image_free(data);
if (!result) {
std::cout << "[ERROR] Failed to save TGA thumbnail to: " << output_tga_path << std::endl;
return false;
}
return true;
}
void ProcessUserThumbnail(int critter_id, const std::string& user_selected_file_path) {
std::string target_tga_path = "./data/thumbnails/" + std::to_string(critter_id) + ".tga";
if (ConvertToThumbnailTGA(user_selected_file_path, target_tga_path)) {
std::cout << "[INFO] Thumbnail successfully generated for Critter #" << critter_id << std::endl;
}
}

View File

@@ -1,6 +1,8 @@
#include "critter.hpp" #include "critter.hpp"
#include "database.hpp" #include "database.hpp"
#include "ui.hpp" #include "ui.hpp"
#include "../vendor/stb/stb_image.h"
#include "../vendor/stb/stb_image_write.h"
#include <RmlUi/Core.h> #include <RmlUi/Core.h>
#include <RmlUi/Debugger/Debugger.h> #include <RmlUi/Debugger/Debugger.h>
@@ -55,6 +57,8 @@ bool initialize() {
return true; return true;
} }
int main() { int main() {
std::cout << "[INFO] Starting CritterFolio...\n"; std::cout << "[INFO] Starting CritterFolio...\n";

7988
vendor/stb/stb_image.h vendored Normal file

File diff suppressed because it is too large Load Diff

1724
vendor/stb/stb_image_write.h vendored Normal file

File diff suppressed because it is too large Load Diff