diff --git a/src/ImageHolder.cpp b/src/ImageHolder.cpp new file mode 100644 index 0000000..dd8d16e --- /dev/null +++ b/src/ImageHolder.cpp @@ -0,0 +1,108 @@ +/* +=========================================================================== + * Sago Multi Scrambler Puzzle +Copyright (C) 2024 Poul Sander + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see http://www.gnu.org/licenses/ + +Source information and contacts persons can be found at +https://github.com/sago007/saland +=========================================================================== +*/ + +#include "ImageHolder.hpp" +#include + +ImageHolder::ImageHolder() : pictureTex(nullptr), source_image_width(1), source_image_height(1) {} + +ImageHolder::ImageHolder(ImageHolder&& other) { + pictureTex = other.pictureTex; + source_image_width = other.source_image_width; + source_image_height = other.source_image_height; + source_filename = other.source_filename; + other.pictureTex = nullptr; +} + +ImageHolder::~ImageHolder() { + if (pictureTex != nullptr) { + SDL_DestroyTexture(pictureTex); + pictureTex = nullptr; + } +} + +void ImageHolder::LoadPictureFromFile(const std::string& filename, SDL_Renderer* renderer) { + source_filename = filename; + SDL_Surface* pictureSurface = IMG_Load(filename.c_str()); + if (pictureSurface == nullptr) { + printf("ImageHolder::LoadPictureFromFile() failed to load image. Filename: %s\n", filename.c_str()); + return; + } + + if (pictureTex != nullptr) { + SDL_DestroyTexture(pictureTex); + } + + pictureTex = SDL_CreateTextureFromSurface(renderer, pictureSurface); + if (pictureTex == nullptr) { + printf("ImageHolder::LoadPictureFromFile() failed to create texture. Filename: %s\n", filename.c_str()); + } + + source_image_width = pictureSurface->w; + source_image_height = pictureSurface->h; + +SDL_FreeSurface(pictureSurface); +} + + + +int ImageHolder::GetWidth() const { + return source_image_width; +} + +int ImageHolder::GetHeight() const { + return source_image_height; +} + +SDL_Texture* ImageHolder::GetTexture() const { + return pictureTex; +} + +void ImageHolder::Draw(SDL_Renderer* target, int x, int y, int max_w, int max_h) const { + if (pictureTex == nullptr) { + printf("ImageHolder::Draw() called with no image loaded. Filename: %s\n", source_filename.c_str()); + return; + } + + int imgWidth = GetWidth(); + int imgHeight = GetHeight(); + + if (max_w == 0) { + max_w = imgWidth; + } + + if (max_h == 0) { + max_h = imgHeight; + } + + // Calculate the scaled dimensions while maintaining the aspect ratio + double aspect_ratio = static_cast(imgWidth) / imgHeight; + if (max_w / aspect_ratio < max_h) { + max_h = static_cast(max_w / aspect_ratio); + } else { + max_w = static_cast(max_h * aspect_ratio); + } + + SDL_Rect destRect = { x, y, max_w, max_h }; + SDL_RenderCopy(target, pictureTex, nullptr, &destRect); +} diff --git a/src/ImageHolder.hpp b/src/ImageHolder.hpp new file mode 100644 index 0000000..214f4e5 --- /dev/null +++ b/src/ImageHolder.hpp @@ -0,0 +1,73 @@ +/* +=========================================================================== + * Sago Multi Scrambler Puzzle +Copyright (C) 2024 Poul Sander + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see http://www.gnu.org/licenses/ + +Source information and contacts persons can be found at +https://github.com/sago007/saland +=========================================================================== +*/ + +#ifndef IMAGEHOLDER_HPP +#define IMAGEHOLDER_HPP + +#include +#include + +class ImageHolder { +public: + // Constructor + ImageHolder(); + + // Copy constructor + ImageHolder(const ImageHolder& other) = delete; + + // Assignment operator + ImageHolder& operator=(const ImageHolder& other) = delete; + + // Move constructor + ImageHolder(ImageHolder&& other); + + // Destructor + ~ImageHolder(); + + // Other member functions and variables + void LoadPictureFromFile(const std::string& filename, SDL_Renderer* renderer); + int GetWidth() const; + int GetHeight() const; + SDL_Texture* GetTexture() const; + + /** + * Draw the image to the target. + * Image will be scaled to fit within the max_w and max_h. + * Ratio is kept. + * @param target The target to draw to. + * @param x The x coordinate to draw to. + * @param y The y coordinate to draw to. + * @param max_w The maximum width to draw. If 0 then the image width is used. + * @param max_h The maximum height to draw. If 0 then the image height is used. + */ + void Draw(SDL_Renderer* target, int x, int y, int max_w = 0, int max_h = 0) const; + +private: + // Private member variables + SDL_Texture* pictureTex = NULL; + int source_image_height = 1; + int source_image_width = 1; + std::string source_filename; +}; + +#endif // IMAGEHOLDER_HPP diff --git a/src/ImageSelectState.cpp b/src/ImageSelectState.cpp index c097e0c..b49e26a 100644 --- a/src/ImageSelectState.cpp +++ b/src/ImageSelectState.cpp @@ -85,6 +85,7 @@ void ImageSelectState::Draw(SDL_Renderer* target) { const int number_of_images_per_page = 6; const int frame_size = 300; const int frame_spacing = 20; + const int frame_border = 10; const int number_of_columns = 3; const int top_x = (globalData.xsize-(3*frame_size+2*frame_spacing))/2; const int top_y = (globalData.ysize-(2*frame_size+frame_spacing))/2; @@ -92,6 +93,9 @@ void ImageSelectState::Draw(SDL_Renderer* target) { int x = i % number_of_columns; int y = i / number_of_columns; DrawRectYellow(target, top_x+x*(frame_size+frame_spacing), top_y+y*(frame_size+frame_spacing), frame_size, frame_size); + if (i < imageHolders.size()) { + imageHolders[i].Draw(target, top_x+x*(frame_size+frame_spacing)+frame_border, top_y+y*(frame_size+frame_spacing)+frame_border, frame_size-2*frame_border, frame_size-2*frame_border); + } if (i < imageNameFields.size()) { imageNameFields[i].Draw(target, top_x+x*(frame_size+frame_spacing)+frame_size/2, top_y+y*(frame_size+frame_spacing)+frame_size-5, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::bottom); } @@ -150,6 +154,8 @@ void ImageSelectState::Init() { sago::SagoTextField field; setFontText(globalData.dataHolder, field, entry.path().filename().string().c_str()); imageNameFields.push_back(std::move(field)); + imageHolders.emplace_back(); + imageHolders.back().LoadPictureFromFile(entry.path().string(), globalData.screen); } } } diff --git a/src/ImageSelectState.hpp b/src/ImageSelectState.hpp index 93e1633..9b031d9 100644 --- a/src/ImageSelectState.hpp +++ b/src/ImageSelectState.hpp @@ -25,6 +25,7 @@ https://github.com/sago007/saland #include #include #include "sago/SagoTextField.hpp" +#include "ImageHolder.hpp" #pragma once @@ -46,6 +47,7 @@ public: std::string collection = ""; std::vector imageList; std::vector imageNameFields; + std::vector imageHolders; private: bool isActive = true;