Adding an image library because i apparently need TGAs
This commit is contained in:
@@ -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
BIN
assets/images/icon.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 627 KiB |
55
assets/images/icon.svg
Executable file
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
BIN
assets/images/icon.tga
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 625 KiB |
@@ -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,11 +15,23 @@
|
|||||||
|
|
||||||
<!-- 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">
|
||||||
<p><strong>Species:</strong> {{entry.value.species}}</p>
|
<span class="critter-id">ID: #{{entry.key}}</span>
|
||||||
<p><strong>Gender:</strong> {{entry.value.gender}}</p>
|
<button class="btn-delete">X</button>
|
||||||
</div>
|
</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>Gender:</strong> {{entry.value.gender}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal Dialog Overlay -->
|
<!-- Modal Dialog Overlay -->
|
||||||
|
|||||||
@@ -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
38
src/image_utils.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
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
1724
vendor/stb/stb_image_write.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user