Skip to content

Commit

Permalink
add feature to save previously used icons (#15)
Browse files Browse the repository at this point in the history
* working changes

* basic delete/select working

* collection feature working

* add hashing to avoid duplicate copies

* increment version

* sort categories alphabetically
  • Loading branch information
dslatt authored Jun 29, 2024
1 parent c6bb41f commit 51815c3
Show file tree
Hide file tree
Showing 17 changed files with 437 additions and 74 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ include(${BOREALIS_LIBRARY}/cmake/toolchain.cmake)
# project info
project(nso-icon-tool)
set(VERSION_MAJOR "0")
set(VERSION_MINOR "3")
set(VERSION_MINOR "4")
set(VERSION_ALTER "0")
set(VERSION_BUILD "0")
set(PROJECT_AUTHOR "dslatt")
Expand Down Expand Up @@ -53,6 +53,8 @@ if (PLATFORM_SWITCH)
curl z bz2 zstd lzma lz4
# extract
minizip
# hash
xxhash
)
list(APPEND MAIN_SRC ${BOREALIS_LIBRARY}/lib/platforms/switch/switch_wrapper.c)
list(APPEND APP_PLATFORM_INCLUDE ${DEVKITPRO}/portlibs/switch/include)
Expand Down
6 changes: 6 additions & 0 deletions include/util/image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@ struct Image
void resize(int x, int y);
bool writeJpg(std::string path);
bool writePng(std::string path);
void applyAlpha(float alpha);

std::string hash();

static void applyAlpha(Image& image, float alpha);
static void merge(Image &frame, Image &character, Image &background, Image &output);
};
1 change: 1 addition & 0 deletions include/util/paths.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ namespace paths
const std::string IconCachePath = "sdmc:/avatars/nso-icons-main/";
const std::string CacheFilePath = "sdmc:/avatars/nso-icon-tool/cache.json";
const std::string LogFilePath = "sdmc:/avatars/nso-icon-tool/log.log";
const std::string CollectionPath = "sdmc:/avatars/nso-icon-tool/collection";
}
79 changes: 79 additions & 0 deletions include/view/collection_grid.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#pragma once

#include <borealis.hpp>
#include "view/recycling_grid.hpp"
#include "state/image_state.hpp"

#include <borealis/core/event.hpp>

namespace collection {

struct CollectionItem {
std::string file = "";
Image image;
bool selected = false;
};

class RecyclerCell
: public RecyclingGridItem
{
public:
RecyclerCell();

BRLS_BIND(brls::Image, image, "image");

virtual void prepareForReuse() override
{
image->clear();
img.clear();
}

virtual void cacheForReuse() override
{
image->clear();
img.clear();
}

virtual void onFocusGained() override;

static RecyclerCell *create(std::function<void(std::string)> cb);
CollectionItem* ref;
std::string img = "";
std::function<void(std::string)> cb;
};

class DataSource
: public RecyclingGridDataSource
{
public:
DataSource(std::vector<CollectionItem> items, std::function<void(std::string)> onSelected, brls::View *parent);
bool onItemAction(RecyclingGrid *recycler, size_t index, brls::ControllerButton button) override;

RecyclingGridItem *cellForRow(RecyclingGrid *recycler, size_t index) override;

void onItemSelected(RecyclingGrid *recycler, size_t index) override;

void clearData() override;

size_t getItemCount() override;

void deleteSelected();

void updateCell(RecyclingGridItem* item, size_t index) override;

std::function<void(std::string)> onSelected;
std::vector<CollectionItem> items;
brls::View *parent = nullptr;
};

class CollectionGrid : public brls::Box
{
public:
CollectionGrid(const std::vector<std::string> &files, std::string title, ImageState &state, std::function<void(std::string)> onSelected, std::function<void(std::string, ImageState &state)> onFocused);

BRLS_BIND(RecyclingGrid, recycler, "recycler");
BRLS_BIND(brls::Image, workingImage, "image");
BRLS_BIND(brls::Button, confirmDelete, "confirm_delete");
};

}
2 changes: 2 additions & 0 deletions include/view/main_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class MainView : public brls::Box
BRLS_BIND(brls::DetailCell, btnCustom, "btn_custom");
BRLS_BIND(brls::DetailCell, btnSettings, "btn_settings");

BRLS_BIND(brls::DetailCell, btnCollectionLoad, "btn_collection_load");

BRLS_BIND(brls::Label, currentUser, "current_user");
BRLS_BIND(brls::Image, currentImage, "current_image");
BRLS_BIND(brls::Image, image, "image");
Expand Down
4 changes: 4 additions & 0 deletions include/view/recycling_grid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class RecyclingGridDataSource
return nullptr;
}

virtual void updateCell(RecyclingGridItem* item, size_t index) {}

/*
* Asks the data source for the height to use for a row in a specified location.
* Return -1 to use autoscaling.
Expand All @@ -90,6 +92,8 @@ class RecyclingGridDataSource
*/
virtual void onItemSelected(RecyclingGrid *recycler, size_t index) {}

virtual bool onItemAction(RecyclingGrid *recycler, size_t index, brls::ControllerButton button) { return false; }

virtual void clearData() = 0;
};

Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<img src="https://img.shields.io/static/v1?label=license&message=GPLV3&labelColor=111111&color=0057da&style=for-the-badge&logo=data%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHpFAACAgwAA/FcAAIDoAAB5FgAA8QEAADtfAAAcheDStWoAAAFGSURBVHjarJK9LgRhFIafWUuiEH/rJwrJClEq3IELUKgo3IrETWh0FC7BNVih0AoKBQoEydq11qMwm5yMsbPEm3yZd55zvnfO92VQKVhLak09UZeL%2BrsVZ9Qdv2tXnf1NYEndUushZFGthvemuq32FwWuq%2BeZid5DvZGpXambeYGr6qnd9dGldqaudQL3QuFWvVbbmaC6%2BprDr9WbwA4SdQW4BwaABb50CTykfjjwC%2BAx9SPAfOANYDxRCXpOnxNAM4ePA63Ul8NHR4E2QClsGgGG0jUR%2BFjglcAn8/pj4HTwUz/42FPJ68lOSDhCkR/O46XM0Qh3VcRH83jph%2BZefKUosBr8XA%2B%2BmufLAR4Dh6k/CrzWA691YOc/3Ejv6iNM3k59Xw%2B8D3gC9hN1ErjjfzSbqHVg8J8CG2XgBXgL4/9VCdD6HACaHdcHGCRMgQAAAABJRU5ErkJggg%3D%3D" alt=License>
</a>
<a rel="VERSION" href="https://github.com/dslatt/nso-icon-tool">
<img src="https://img.shields.io/static/v1?label=version&message=0.3.0&labelColor=111111&color=06f&style=for-the-badge" alt="Version">
<img src="https://img.shields.io/static/v1?label=version&message=0.4.0&labelColor=111111&color=06f&style=for-the-badge" alt="Version">
</a>
<a rel="BUILD" href="https://github.com/dslatt/nso-icon-tool/actions">
<img src="https://img.shields.io/github/actions/workflow/status/dslatt/nso-icon-tool/build-switch-release.yml?branch=main&labelColor=111111&color=06f&style=for-the-badge" alt=Build>
Expand Down
6 changes: 4 additions & 2 deletions resources/i18n/en-US/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
"config": "Config",
"settings": "Settings",
"icon_components": "Icon Components",
"custom": "Custom",
"other": "Other",
"custom_image": "Custom Image",
"frame": "Frame",
"character": "Character",
"background": "Background",
"new_icon": "New Icon",
"apply": "Apply to User",
"select_game": "Select a Game",
"available_images": "Available Images"
"available_images": "Available Images",
"collection_load": "Previous Icons",
"confirm_delete": "Delete Selected"
},
"settings": {
"title": "Settings",
Expand Down
2 changes: 1 addition & 1 deletion resources/i18n/es-419/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"config": "Configuración",
"settings": "Configuraciones",
"icon_components": "Componentes del Ícono",
"custom": "Personalizado",
"other": "Personalizado",
"custom_image": "Imágen personalizada",
"frame": "Seleccionar Marco",
"character": "Seleccionar Personaje",
Expand Down
2 changes: 1 addition & 1 deletion resources/i18n/ru/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"config": "Конфигурация",
"settings": "Настройки",
"icon_components": "Компоненты иконки",
"custom": "Пользовательские настройки",
"other": "Пользовательские настройки",
"custom_image": "Изображение пользователя",
"frame": "Выбор рамки",
"character": "Выбор персонажа",
Expand Down
56 changes: 56 additions & 0 deletions resources/xml/views/cell_grid.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<brls:Box
width="auto"
height="auto"
axis="row">

<brls:Box
width="60%"
height="auto">
<RecyclingGrid
id="recycler"
width="auto"
height="auto"
grow="1.0"
spanCount="5"
itemHeight="128px"
itemSpace="2px"
paddingTop="@style/brls/sidebar/padding_top"
paddingRight="@style/brls/sidebar/padding_right"
paddingBottom="@style/brls/sidebar/padding_bottom"
paddingLeft="@style/brls/sidebar/padding_left" />

</brls:Box>
<brls:Box
width="40%"
height="auto"
justifyContent="flexStart"
alignItems="center"
axis="column"
paddingTop="60px">

<brls:Label
width="auto"
height="auto"
text="@i18n/app/main/new_icon"
fontSize="26"
marginBottom="20px" />

<brls:Image
id="image"
width="340px"
height="340px"
borderThickness="5px"
cornerRadius="5px"
borderColor="@theme/brls/applet_frame/separator" />

<brls:Button
id="confirm_delete"
width="75%"
height="auto"
text="@i18n/app/main/confirm_delete"
marginTop="20px" />


</brls:Box>

</brls:Box>
10 changes: 6 additions & 4 deletions resources/xml/views/main_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,15 @@
/>

<brls:Header
marginTop="100px"
title="@i18n/app/main/custom" />
title="@i18n/app/main/other"
marginTop="30px"/>

<brls:DetailCell
id="btn_custom"
title="@i18n/app/main/custom_image"
/>
title="@i18n/app/main/custom_image"/>
<brls:DetailCell
id="btn_collection_load"
title="@i18n/app/main/collection_load"/>
</brls:Box>

<brls:Box
Expand Down
1 change: 1 addition & 0 deletions source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ int main(int argc, char *argv[])
{
GenericToolbox::mkdir(paths::BasePath);
GenericToolbox::mkdir(paths::BaseAppPath);
GenericToolbox::mkdir(paths::CollectionPath);

// We recommend to use INFO for real apps
for (int i = 1; i < argc; i++)
Expand Down
59 changes: 1 addition & 58 deletions source/state/image_state.cpp
Original file line number Diff line number Diff line change
@@ -1,64 +1,7 @@
#include "state/image_state.hpp"

#define RED(px) (uint8_t)(px)
#define GREEN(px) (uint8_t)(px >> 8)
#define BLUE(px) (uint8_t)(px >> 16)
#define ALPHA(px) (uint8_t)(px >> 24)
#define RGBA(r, g, b, a) ((r & 0xff) | ((g & 0xff) << 8) | ((b & 0xff) << 16) | ((a & 0xff) << 24))
#define BLEND(a, b, alpha) (((a * alpha) + (b * (255 - alpha))) / 255)

Image empty(256, 256);

// assumes images same size, little endian, RGBA channels
void overlayImg(Image &frame, Image &character, Image &background, Image &output)
{
auto total = frame.x * frame.y;
auto frameRef = (int *)frame.img;
auto characterRef = (int *)character.img;
auto backgroundRef = (int *)background.img;
auto outputRef = (int *)output.img;

for (auto i = 0; i < total; i++)
{
auto frameAlpha = ALPHA(*frameRef);
auto characterAlpha = ALPHA(*characterRef);
auto backgroundAlpha = ALPHA(*backgroundRef);

// frame blocking
if (frameAlpha == 0xff)
{
*outputRef = *frameRef;
// character blocking
}
else if (frameAlpha == 0 && characterAlpha == 0xff)
{
*outputRef = *characterRef;
// background only
}
else if (frameAlpha == 0 && characterAlpha == 0)
{
*outputRef = *backgroundRef;
}
// blend
else
{
*outputRef = RGBA(BLEND(RED(*characterRef), RED(*backgroundRef), characterAlpha),
BLEND(GREEN(*characterRef), GREEN(*backgroundRef), characterAlpha),
BLEND(BLUE(*characterRef), BLUE(*backgroundRef), characterAlpha),
0xff);

*outputRef = RGBA(BLEND(RED(*frameRef), RED(*outputRef), frameAlpha),
BLEND(GREEN(*frameRef), GREEN(*outputRef), frameAlpha),
BLEND(BLUE(*frameRef), BLUE(*outputRef), frameAlpha),
0xff);
}

frameRef++;
characterRef++;
outputRef++;
backgroundRef++;
}
}

ImageState::ImageState() : frame(256, 256),
character(256, 256),
Expand All @@ -69,7 +12,7 @@ ImageState::ImageState() : frame(256, 256),

void ImageState::merge()
{
overlayImg(frame, character, background, working);
Image::merge(frame, character, background, working);
}

void ImageState::resize()
Expand Down
Loading

0 comments on commit 51815c3

Please sign in to comment.