Add queue system with background downloading and much more (#73)
* Do not build here until it is merged. * WIP: Queue System. Right now crashes randomly for whatever reason.. * Animate queue spinner more slowly * Use LightLocks to prevent crashing in the queue (I hope it's fixed at least) * Build nightlies in queue-system * Use version.h for version and specify 7 digits * Remove unneeded $(CURDIR) I put that these for testing, but it's not needed * Multiple Changes, see desc for more. 1.) Theme Implementation. 2.) Show Battery + Time. 3.) Some more work on Queue-System (might still be broke). 4.) Update Copyright to 2021. 5.) Add `%FIRM%` to regex. 6.) Mass Add to Queue. 7.) Search with AND / OR filter. * Gaaah, not again... * Remove DoNothing, some LightLock changes, etc aka Further improvements to overall system stability and other minor adjustments have been made to enhance the user experience. * See desc for more. - Current Queue Entry can now be canceled. - Fix installed list. - Display Download Speed. - BYE BYE Queue LightLock! * Various adjustments to the queue menu - Make cancel button slightly smaller - Right align "Steps: ..." text - Remove "Current Operation:" text - Change KB/MB/GB to KiB/MiB/GiB - Lots of little positioning tweaks - Fix bug where you could get stuck in the prompt - Make spinny thing have a ! when action is needed - Make extracting file increment at the start instead of the end - Delete dumb VS Code file and gitignore it * Change to hollow full charge plugged in icon * Fix the settings positions a bit * Fix custom font download not having prompt Also tweak the text positions, I forgot to change them Co-authored-by: StackZ <47382115+SuperSaiyajinStackZ@users.noreply.github.com>
@@ -2,7 +2,7 @@ name: Build Universal-Updater
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore: [translation, full-rewrite, PNG]
|
||||
branches-ignore: [translation]
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
pull_request:
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
*.elf
|
||||
*.cia
|
||||
*.3dsx
|
||||
*/build
|
||||
*build
|
||||
*.map
|
||||
*.lst
|
||||
.vscode/ipch
|
||||
.vscode
|
||||
*.DS_Store
|
||||
romfs/gfx/*.t3x
|
||||
include/version.hpp
|
||||
|
||||
bannertool*
|
||||
makerom*
|
||||
*.pfs0
|
||||
*.nso
|
||||
*.nacp
|
||||
build/sprites.h
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"exception": "cpp",
|
||||
"fstream": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"memory": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"map": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"bitset": "cpp",
|
||||
"chrono": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"shared_mutex": "cpp"
|
||||
}
|
||||
}
|
||||
@@ -46,11 +46,22 @@ endif
|
||||
|
||||
CURRENT_VERSION := $(shell git describe --abbrev=0 --tags)
|
||||
|
||||
# If on a tagged commit, use the tag instead of the commit
|
||||
# If on a tagged commit, use just the tag
|
||||
ifneq ($(shell echo $(shell git tag -l --points-at HEAD) | head -c 1),)
|
||||
GIT_VER := $(shell git tag -l --points-at HEAD)
|
||||
else
|
||||
GIT_VER := $(shell git describe --abbrev=0 --tags)-$(shell git rev-parse --short HEAD)
|
||||
GIT_VER := $(shell git describe --abbrev=0 --tags)-$(shell git rev-parse --short=7 HEAD)
|
||||
endif
|
||||
|
||||
# Ensure version.hpp exists
|
||||
ifeq (,$(wildcard include/version.hpp))
|
||||
$(shell mkdir -p include)
|
||||
$(shell touch include/version.hpp)
|
||||
endif
|
||||
|
||||
# Print new version if changed
|
||||
ifeq (,$(findstring $(GIT_VER), $(shell cat include/version.hpp)))
|
||||
$(shell printf "#ifndef VERSION_HPP\n#define VERSION_HPP\n\n#define VER_NUMBER \"$(GIT_VER)\"\n\n#endif\n" > include/version.hpp)
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
@@ -78,8 +89,8 @@ endif
|
||||
TARGET := Universal-Updater
|
||||
BUILD := build
|
||||
UNIVCORE := Universal-Core
|
||||
SOURCES := $(UNIVCORE) source source/download source/gui source/lang source/overlays source/qr source/screens \
|
||||
source/store source/utils
|
||||
SOURCES := $(UNIVCORE) source source/download source/gui source/lang source/menu source/overlays \
|
||||
source/qr source/screens source/store source/utils
|
||||
DATA := data
|
||||
INCLUDES := $(UNIVCORE) include include/download include/gui include/lang include/overlays include/qr include/screens \
|
||||
include/store include/utils
|
||||
@@ -99,7 +110,6 @@ RSF_FILE := app/build-cia.rsf
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
|
||||
|
||||
CFLAGS := -g -Wall -Wno-psabi -O2 -mword-relocations \
|
||||
-DV_STRING=\"$(GIT_VER)\" \
|
||||
-DC_V=\"$(CURRENT_VERSION)\" \
|
||||
-fomit-frame-pointer -ffunction-sections \
|
||||
$(ARCH)
|
||||
|
||||
@@ -3,15 +3,33 @@
|
||||
sprites/add.png
|
||||
sprites/add_font.png
|
||||
sprites/arrow.png
|
||||
sprites/battery/battery_0.png
|
||||
sprites/battery/battery_1.png
|
||||
sprites/battery/battery_2.png
|
||||
sprites/battery/battery_3.png
|
||||
sprites/battery/battery_4.png
|
||||
sprites/battery/battery_blink.png
|
||||
sprites/battery/battery_charge.png
|
||||
sprites/battery/battery_charge_full.png
|
||||
sprites/cancel.png
|
||||
sprites/checked.png
|
||||
sprites/delete.png
|
||||
sprites/download.png
|
||||
sprites/info.png
|
||||
sprites/installed.png
|
||||
sprites/keyboard.png
|
||||
sprites/list.png
|
||||
sprites/noIcon.png
|
||||
sprites/notes.png
|
||||
sprites/qr_code.png
|
||||
sprites/queue0.png
|
||||
sprites/queue1.png
|
||||
sprites/queue2.png
|
||||
sprites/queue3.png
|
||||
sprites/queue4.png
|
||||
sprites/queue5.png
|
||||
sprites/queue6.png
|
||||
sprites/queue7.png
|
||||
sprites/screenshot.png
|
||||
sprites/search.png
|
||||
sprites/settings.png
|
||||
|
||||
|
After Width: | Height: | Size: 257 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 249 B |
|
After Width: | Height: | Size: 250 B |
|
After Width: | Height: | Size: 280 B |
|
After Width: | Height: | Size: 257 B |
|
After Width: | Height: | Size: 348 B |
|
After Width: | Height: | Size: 340 B |
|
After Width: | Height: | Size: 351 B |
|
After Width: | Height: | Size: 289 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -27,15 +27,17 @@
|
||||
#ifndef _UNIVERSAL_UPDATER_COMMON_HPP
|
||||
#define _UNIVERSAL_UPDATER_COMMON_HPP
|
||||
|
||||
#include <3ds.h>
|
||||
#include "config.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "lang.hpp"
|
||||
#include "msg.hpp"
|
||||
#include "screenCommon.hpp"
|
||||
#include <3ds.h>
|
||||
#include <vector>
|
||||
|
||||
#define _STORE_PATH "sdmc:/3ds/Universal-Updater/stores/"
|
||||
#define _META_PATH "sdmc:/3ds/Universal-Updater/MetaData.json"
|
||||
#define _THEME_AMOUNT 1
|
||||
#define _UNISTORE_VERSION 4
|
||||
|
||||
inline std::unique_ptr<Config> config;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -32,50 +32,48 @@
|
||||
#include <citro2d.h>
|
||||
#include <string>
|
||||
|
||||
/*
|
||||
Define all used Colors, for easier changes.
|
||||
*/
|
||||
|
||||
/* Standard Colors. */
|
||||
#define WHITE C2D_Color32(255, 255, 255, 255)
|
||||
#define BLACK C2D_Color32(0, 0, 0, 255)
|
||||
#define TRANSPARENT C2D_Color32(0, 0, 0, 0)
|
||||
#define DIM_COLOR C2D_Color32(0, 0, 0, 190)
|
||||
|
||||
/* Bar, Text, BG Colors. */
|
||||
#define TEXT_COLOR WHITE
|
||||
#define BAR_COLOR C2D_Color32(50, 73, 98, 255)
|
||||
#define BAR_OUTL_COLOR C2D_Color32(25, 30, 53, 255)
|
||||
#define BG_COLOR C2D_Color32(38, 44, 77, 255)
|
||||
|
||||
/* Entry Colors. */
|
||||
#define ENTRY_BAR_COLOR BAR_COLOR
|
||||
#define ENTRY_BAR_OUTL_COLOR BAR_OUTL_COLOR
|
||||
|
||||
/* Entry Box Colors. */
|
||||
#define BOX_INSIDE_COLOR C2D_Color32(28, 33, 58, 255)
|
||||
#define BOX_SELECTED_COLOR C2D_Color32(108, 130, 155, 255)
|
||||
#define BOX_UNSELECTED_COLOR BLACK
|
||||
|
||||
/* Progressbar Colors. */
|
||||
#define PROGRESSBAR_OUT_COLOR BOX_INSIDE_COLOR
|
||||
#define PROGRESSBAR_IN_COLOR SIDEBAR_UNSELECTED_COLOR
|
||||
|
||||
/* Search Menu Colors. */
|
||||
#define SEARCH_BAR_COLOR C2D_Color32(51, 75, 102, 255)
|
||||
#define SEARCH_BAR_OUTL_COLOR BAR_OUTL_COLOR
|
||||
|
||||
/* Sidebar Colors. */
|
||||
#define SIDEBAR_SELECTED_COLOR C2D_Color32(108, 130, 155, 255)
|
||||
#define SIDEBAR_UNSELECTED_COLOR C2D_Color32(77, 101, 128, 255)
|
||||
struct UITheme {
|
||||
uint32_t BarColor;
|
||||
uint32_t BGColor;
|
||||
uint32_t BarOutline;
|
||||
uint32_t TextColor;
|
||||
uint32_t EntryBar;
|
||||
uint32_t EntryOutline;
|
||||
uint32_t BoxInside;
|
||||
uint32_t BoxSelected;
|
||||
uint32_t BoxUnselected;
|
||||
uint32_t ProgressbarOut;
|
||||
uint32_t ProgressbarIn;
|
||||
uint32_t SearchBar;
|
||||
uint32_t SearchbarOutline;
|
||||
uint32_t SideBarSelected;
|
||||
uint32_t SideBarUnselected;
|
||||
/* NOTE: Also used for the buttons. */
|
||||
uint32_t MarkSelected;
|
||||
uint32_t MarkUnselected;
|
||||
uint32_t DownListPrev;
|
||||
uint32_t SideBarIconColor;
|
||||
};
|
||||
|
||||
namespace GFX {
|
||||
extern std::vector<UITheme> Themes;
|
||||
extern int SelectedTheme;
|
||||
|
||||
void DrawTop(void);
|
||||
void DrawBottom();
|
||||
void DrawSprite(int img, int x, int y, float ScaleX = 1, float ScaleY = 1);
|
||||
void DrawBox(float xPos, float yPos, float width = 50, float height = 50, bool selected = false, uint32_t clr = BOX_INSIDE_COLOR);
|
||||
void DrawBox(float xPos, float yPos, float width = 50, float height = 50, bool selected = false, uint32_t clr = GFX::Themes[GFX::SelectedTheme].BoxInside);
|
||||
void DrawCheckbox(float xPos, float yPos, bool selected);
|
||||
void DrawToggle(float xPos, float yPos, bool toggled);
|
||||
void DrawTime();
|
||||
void DrawBattery();
|
||||
void HandleBattery();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -28,15 +28,13 @@
|
||||
#define _UNIVERSAL_UPDATER_OVERLAY_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "store.hpp"
|
||||
#include "storeEntry.hpp"
|
||||
#include <3ds.h>
|
||||
|
||||
namespace Overlays {
|
||||
void SelectStore(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::unique_ptr<Meta> &meta);
|
||||
void SelectLanguage(const std::unique_ptr<Store> &store);
|
||||
void SelectStore();
|
||||
void SelectLanguage();
|
||||
void ShowCredits();
|
||||
std::string SelectDir(const std::string &oldDir, const std::string &msg, const std::unique_ptr<Store> &store);
|
||||
std::string SelectDir(const std::string &oldDir, const std::string &msg);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -37,11 +37,12 @@
|
||||
|
||||
0: Entry Info.
|
||||
1: Download List.
|
||||
2: Search + Favorites.
|
||||
3: Sorting.
|
||||
4: Settings / Credits(?).
|
||||
5: Screenshot Menu.
|
||||
6: Release Notes.
|
||||
2: Queue.
|
||||
3: Search + Favorites.
|
||||
4: Sorting.
|
||||
5: Settings / Credits(?).
|
||||
6: Screenshot Menu.
|
||||
7: Release Notes.
|
||||
*/
|
||||
|
||||
class MainScreen : public Screen {
|
||||
@@ -50,21 +51,18 @@ public:
|
||||
void Draw(void) const override;
|
||||
void Logic(u32 hDown, u32 hHeld, touchPosition touch) override;
|
||||
private:
|
||||
std::unique_ptr<Store> store = nullptr;
|
||||
std::unique_ptr<Meta> meta = nullptr;
|
||||
std::vector<std::unique_ptr<StoreEntry>> entries;
|
||||
std::vector<std::string> dwnldList, dwnldSizes;
|
||||
|
||||
bool initialized = false, fetchDown = false, showMarks = false, showSettings = false,
|
||||
ascending = false, updateFilter = false, screenshotFetch = false, canDisplay = false;
|
||||
ascending = false, updateFilter = false, screenshotFetch = false, canDisplay = false, isAND = true;
|
||||
|
||||
int storeMode = 0, marks = 0, markIndex = 0, sPage = 0, lMode = 0, sSelection = 0,
|
||||
lastMode = 0, smallDelay = 0, sPos = 0, screenshotIndex = 0, sSize = 0, zoom = 0, scrollIndex = 0;
|
||||
lastMode = 0, smallDelay = 0, sPos = 0, screenshotIndex = 0, sSize = 0, zoom = 0, scrollIndex = 0, queueIndex = 0;
|
||||
|
||||
SortType sorttype = SortType::LAST_UPDATED;
|
||||
|
||||
/* Title, Author, Category, Console. */
|
||||
std::vector<bool> searchIncludes = { false, false, false, false };
|
||||
std::vector<bool> searchIncludes = { false, false, false, false }, installs = { };
|
||||
std::string searchResult = "", screenshotName = "";
|
||||
|
||||
C2D_Image Screenshot = { nullptr, nullptr };
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "json.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum favoriteMarks {
|
||||
STAR = 1 << 0,
|
||||
@@ -46,15 +47,58 @@ public:
|
||||
std::string GetUpdated(const std::string &unistoreName, const std::string &entry) const;
|
||||
int GetMarks(const std::string &unistoreName, const std::string &entry) const;
|
||||
bool UpdateAvailable(const std::string &unistoreName, const std::string &entry, const std::string &updated) const;
|
||||
std::vector<std::string> GetInstalled(const std::string &unistoreName, const std::string &entry) const;
|
||||
|
||||
void SetUpdated(const std::string &unistoreName, const std::string &entry, const std::string &updated) {
|
||||
if (this->metadataJson.is_discarded()) return;
|
||||
this->metadataJson[unistoreName][entry]["updated"] = updated;
|
||||
};
|
||||
|
||||
void SetMarks(const std::string &unistoreName, const std::string &entry, int marks) {
|
||||
if (this->metadataJson.is_discarded()) return;
|
||||
this->metadataJson[unistoreName][entry]["marks"] = marks;
|
||||
};
|
||||
|
||||
/* TODO: Handle this better. */
|
||||
void SetInstalled(const std::string &unistoreName, const std::string &entry, const std::string &name) {
|
||||
if (this->metadataJson.is_discarded()) return;
|
||||
|
||||
const std::vector<std::string> installs = this->GetInstalled(unistoreName, entry);
|
||||
bool write = true;
|
||||
|
||||
if (!installs.empty()) {
|
||||
write = !installs.empty();
|
||||
|
||||
for (int i = 0; i < (int)installs.size(); i++) {
|
||||
if (installs[i] == name) {
|
||||
write = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (write) this->metadataJson[unistoreName][entry]["installed"] += name;
|
||||
}
|
||||
|
||||
/* Remove installed state from a download list entry. */
|
||||
void RemoveInstalled(const std::string &unistoreName, const std::string &entry, const std::string &name) {
|
||||
if (this->metadataJson.is_discarded()) return;
|
||||
|
||||
const std::vector<std::string> installs = this->GetInstalled(unistoreName, entry);
|
||||
int idx = -1;
|
||||
|
||||
if (!installs.empty()) {
|
||||
for (int i = 0; i < (int)installs.size(); i++) {
|
||||
if (installs[i] == name) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (idx != -1) this->metadataJson[unistoreName][entry]["installed"].erase(idx);
|
||||
}
|
||||
|
||||
void ImportMetadata();
|
||||
void SaveCall();
|
||||
private:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
std::string GetUniStoreTitle() const;
|
||||
std::string GetUniStoreAuthor() const;
|
||||
|
||||
/* Get Information of the UniStore Entries. */
|
||||
/* Get Information of the UniStore entries. */
|
||||
std::string GetTitleEntry(int index) const;
|
||||
std::string GetAuthorEntry(int index) const;
|
||||
std::string GetDescriptionEntry(int index) const;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -27,7 +27,7 @@
|
||||
#ifndef _UNIVERSAL_UPDATER_STORE_UTILS_HPP
|
||||
#define _UNIVERSAL_UPDATER_STORE_UTILS_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "meta.hpp"
|
||||
#include "store.hpp"
|
||||
#include "storeEntry.hpp"
|
||||
#include <vector>
|
||||
@@ -39,33 +39,41 @@ enum class SortType : uint8_t {
|
||||
};
|
||||
|
||||
namespace StoreUtils {
|
||||
extern std::unique_ptr<Meta> meta;
|
||||
extern std::unique_ptr<Store> store;
|
||||
extern std::vector<std::unique_ptr<StoreEntry>> entries;
|
||||
|
||||
/* Grid. */
|
||||
void DrawGrid(const std::unique_ptr<Store> &store, const std::vector<std::unique_ptr<StoreEntry>> &entries);
|
||||
void GridLogic(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, int ¤tMode, int &lastMode, bool &fetch, int &smallDelay);
|
||||
void DrawGrid();
|
||||
void GridLogic(int ¤tMode, int &lastMode, bool &fetch, int &smallDelay);
|
||||
|
||||
/* Top List. */
|
||||
void DrawList(const std::unique_ptr<Store> &store, const std::vector<std::unique_ptr<StoreEntry>> &entries);
|
||||
void ListLogic(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, int ¤tMode, int &lastMode, bool &fetch, int &smallDelay);
|
||||
void DrawList();
|
||||
void ListLogic(int ¤tMode, int &lastMode, bool &fetch, int &smallDelay);
|
||||
|
||||
/* Entry Info. */
|
||||
void DrawEntryInfo(const std::unique_ptr<Store> &store, const std::unique_ptr<StoreEntry> &entry);
|
||||
void DrawEntryInfo(const std::unique_ptr<StoreEntry> &entry);
|
||||
void EntryHandle(bool &showMark, bool &fetch, bool &sFetch, int &mode, const std::unique_ptr<StoreEntry> &entry);
|
||||
|
||||
/* Side Menu. */
|
||||
void DrawSideMenu(int currentMenu);
|
||||
void SideMenuHandle(int ¤tMenu, bool &fetch, int &lastMenu);
|
||||
|
||||
/* Download Entries. */
|
||||
void DrawDownList(const std::unique_ptr<Store> &store, const std::vector<std::string> &entries, bool fetch, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &sizes);
|
||||
void DownloadHandle(const std::unique_ptr<Store> &store, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &entries, int ¤tMenu, std::unique_ptr<Meta> &meta, const int &lastMode, int &smallDelay);
|
||||
/* Download entries. */
|
||||
void DrawDownList(const std::vector<std::string> &entries, bool fetch, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &sizes, const std::vector<bool> &installs);
|
||||
void DownloadHandle(const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &entries, int ¤tMenu, const int &lastMode, int &smallDelay, std::vector<bool> &installs);
|
||||
|
||||
/* Queue System. */
|
||||
void DrawQueueMenu(const int queueIndex);
|
||||
void QueueMenuHandle(int &queueIndex, int &storeMode);
|
||||
|
||||
/* Search + Favorite Menu. */
|
||||
void DrawSearchMenu(const std::vector<bool> &searchIncludes, const std::string &searchResult, int marks, bool updateFilter);
|
||||
void SearchHandle(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::vector<bool> &searchIncludes, std::unique_ptr<Meta> &meta, std::string &searchResult, int &marks, bool &updateFilter, bool ascending, SortType sorttype);
|
||||
void DrawSearchMenu(const std::vector<bool> &searchIncludes, const std::string &searchResult, int marks, bool updateFilter, bool isAND);
|
||||
void SearchHandle(std::vector<bool> &searchIncludes, std::string &searchResult, int &marks, bool &updateFilter, bool ascending, SortType sorttype, bool &isAND);
|
||||
|
||||
/* Mark Menu. */
|
||||
void DisplayMarkBox(int marks);
|
||||
void MarkHandle(std::unique_ptr<StoreEntry> &entry, const std::unique_ptr<Store> &store, bool &showMark, std::unique_ptr<Meta> &meta);
|
||||
void MarkHandle(std::unique_ptr<StoreEntry> &entry, bool &showMark);
|
||||
|
||||
/* Credits. */
|
||||
void DrawCredits();
|
||||
@@ -76,14 +84,14 @@ namespace StoreUtils {
|
||||
|
||||
/* Settings. */
|
||||
void DrawSettings(int page, int selection, int sPos);
|
||||
void SettingsHandle(int &page, bool &dspSettings, int &storeMode, int &selection, std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::unique_ptr<Meta> &meta, int &sPos);
|
||||
void SettingsHandle(int &page, bool &dspSettings, int &storeMode, int &selection, int &sPos);
|
||||
|
||||
/* Sorting. */
|
||||
void DrawSorting(bool asc, SortType st);
|
||||
void SortHandle(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, bool &asc, SortType &st);
|
||||
void SortHandle(bool &asc, SortType &st);
|
||||
|
||||
/* Release Notes. */
|
||||
void DrawReleaseNotes(const int &scrollIndex, const std::unique_ptr<StoreEntry> &entry, const std::unique_ptr<Store> &store);
|
||||
void DrawReleaseNotes(const int &scrollIndex, const std::unique_ptr<StoreEntry> &entry);
|
||||
void ReleaseNotesLogic(int &scrollIndex, int &storeMode);
|
||||
|
||||
bool compareTitleDescending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b);
|
||||
@@ -95,13 +103,18 @@ namespace StoreUtils {
|
||||
bool compareUpdateDescending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b);
|
||||
bool compareUpdateAscending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b);
|
||||
|
||||
void SortEntries(bool Ascending, SortType sorttype, std::vector<std::unique_ptr<StoreEntry>> &entries);
|
||||
void SortEntries(bool Ascending, SortType sorttype);
|
||||
|
||||
void search(std::vector<std::unique_ptr<StoreEntry>> &entries, const std::string &query, bool title, bool author, bool category, bool console, int selectedMarks, bool updateAvl);
|
||||
void search(const std::string &query, bool title, bool author, bool category, bool console, int selectedMarks, bool updateAvl, bool isAND);
|
||||
|
||||
void FilterUpdateAvailable(std::vector<std::unique_ptr<StoreEntry>> &entries);
|
||||
void FilterUpdateAvailable();
|
||||
|
||||
void ResetAll(const std::unique_ptr<Store> &store, const std::unique_ptr<Meta> &meta, std::vector<std::unique_ptr<StoreEntry>> &entries);
|
||||
void ResetAll();
|
||||
|
||||
void RefreshUpdateAVL();
|
||||
|
||||
void AddToQueue(int index, const std::string &entry, const std::string &entryName, const std::string &lUpdated);
|
||||
void AddAllToQueue();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -38,8 +38,17 @@ enum class ProgressBar {
|
||||
};
|
||||
|
||||
namespace Animation {
|
||||
extern int DisplayY, DisplayDelay;
|
||||
extern bool MoveUp, DoDelay;
|
||||
|
||||
void DrawProgressBar(u64 currentProgress, u64 totalProgress);
|
||||
void displayProgressBar();
|
||||
|
||||
void DrawQueue(int x, int y);
|
||||
void QueueAnimHandle();
|
||||
|
||||
void QueueEntryDone();
|
||||
void HandleQueueEntryDone();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -64,6 +64,9 @@ public:
|
||||
std::string archPath() const { return this->v_archivePath; };
|
||||
void archPath(const std::string &v) { this->v_archivePath = v; if (!this->changesMade) this->changesMade = true; };
|
||||
|
||||
std::string firmPath() const { return this->v_firmPath; };
|
||||
void firmPath(const std::string &v) { this->v_firmPath = v; if (!this->changesMade) this->changesMade = true; };
|
||||
|
||||
/* Fetching old metadata. */
|
||||
bool metadata() const { return this->v_metadata; };
|
||||
void metadata(bool v) { this->v_metadata = v; if (!this->changesMade) this->changesMade = true; };
|
||||
@@ -87,6 +90,14 @@ public:
|
||||
/* If displaying changelog. */
|
||||
bool changelog() const { return this->v_changelog; };
|
||||
void changelog(bool v) { this->v_changelog = v; if (!this->changesMade) this->changesMade = true; };
|
||||
|
||||
/* The active Theme. */
|
||||
int theme() const { return this->v_theme; };
|
||||
void theme(int v) { this->v_theme = v; if (!this->changesMade) this->changesMade = true; };
|
||||
|
||||
/* If showing prompt if action failed / succeeded. */
|
||||
bool prompt() const { return this->v_prompt; };
|
||||
void prompt(bool v) { this->v_prompt = v; if (!this->changesMade) this->changesMade = true; };
|
||||
private:
|
||||
/* Mainly helper. */
|
||||
bool getBool(const std::string &key);
|
||||
@@ -99,12 +110,14 @@ private:
|
||||
nlohmann::json json;
|
||||
bool changesMade = false;
|
||||
|
||||
int v_theme = 0;
|
||||
|
||||
std::string v_language = "en", v_lastStore = "universal-db.unistore",
|
||||
v_3dsxPath = "sdmc:/3ds", v_ndsPath = "sdmc:", v_archivePath = "sdmc:",
|
||||
v_shortcutPath = "sdmc:/3ds/Universal-Updater/shortcuts";
|
||||
v_shortcutPath = "sdmc:/3ds/Universal-Updater/shortcuts", v_firmPath = "sdmc:/luma/payloads";
|
||||
|
||||
bool v_list = false, v_autoUpdate = true, v_metadata = true, v_updateCheck = true,
|
||||
v_showBg = false, v_customFont = false, v_changelog = true;
|
||||
v_showBg = false, v_customFont = false, v_changelog = true, v_prompt = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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 3 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/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#ifndef _UNIVERSAL_UPDATER_QUEUE_SYSTEM_HPP
|
||||
#define _UNIVERSAL_UPDATER_QUEUE_SYSTEM_HPP
|
||||
|
||||
#include "json.hpp"
|
||||
#include <citro2d.h>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
||||
/* Extend this, if more statuses are neccessary. */
|
||||
enum class QueueStatus {
|
||||
None,
|
||||
Copying,
|
||||
Deleting,
|
||||
Downloading,
|
||||
Extracting,
|
||||
Installing,
|
||||
Moving,
|
||||
Request, // For User needed Requests.
|
||||
Failed,
|
||||
Done
|
||||
};
|
||||
|
||||
enum RequestType {
|
||||
PROMPT_RET = -3,
|
||||
NO_REQUEST = -1,
|
||||
RMDIR_REQUEST = 1, // remove dir prompt request.
|
||||
PROMPT_REQUEST = 2, // skip prompt request.
|
||||
PROMPT_ERROR = 3 // Error message prompt. Unused right now.
|
||||
};
|
||||
|
||||
class Queue {
|
||||
public:
|
||||
Queue(nlohmann::json object, const C2D_Image &img, const std::string &name, const std::string &uName, const std::string &eName, const std::string &lUpdated) :
|
||||
obj(object), icn(img), name(name), unistoreName(uName), entryName(eName), lastUpdated(lUpdated) { };
|
||||
|
||||
QueueStatus status = QueueStatus::None;
|
||||
nlohmann::json obj;
|
||||
C2D_Image icn;
|
||||
int total, current;
|
||||
std::string name = "", unistoreName = "", entryName = "", lastUpdated = "";
|
||||
};
|
||||
|
||||
/* Of course also a namespace to that part, so we can do that in a Thread. */
|
||||
namespace QueueSystem {
|
||||
extern int RequestNeeded, RequestAnswer;
|
||||
extern std::string RequestMsg, EndMsg;
|
||||
extern int LastElement;
|
||||
extern bool Wait, Popup, CancelCallback;
|
||||
|
||||
void QueueHandle(); // Handles the Queue.
|
||||
void AddToQueue(nlohmann::json obj, const C2D_Image &icn, const std::string &name, const std::string &uName, const std::string &eName, const std::string &lUpdated); // Adds to Queue.
|
||||
void ClearQueue(); // Clears the Queue.
|
||||
void Resume();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -44,15 +44,15 @@ enum ScriptState {
|
||||
namespace ScriptUtils {
|
||||
bool matchPattern(const std::string &pattern, const std::string &tested);
|
||||
|
||||
Result removeFile(const std::string &file, const std::string &message);
|
||||
void bootTitle(const std::string &TitleID, bool isNAND, const std::string &message);
|
||||
Result removeFile(const std::string &file, const std::string &message, bool isARG = false);
|
||||
void bootTitle(const std::string &TitleID, bool isNAND, const std::string &message, bool isARG = false);
|
||||
Result prompt(const std::string &message);
|
||||
Result copyFile(const std::string &source, const std::string &destination, const std::string &message);
|
||||
Result renameFile(const std::string &oldName, const std::string &newName, const std::string &message);
|
||||
Result downloadRelease(const std::string &repo, const std::string &file, const std::string &output, bool includePrereleases, const std::string &message);
|
||||
Result downloadFile(const std::string &file, const std::string &output, const std::string &message);
|
||||
void installFile(const std::string &file, bool updatingSelf, const std::string &message);
|
||||
void extractFile(const std::string &file, const std::string &input, const std::string &output, const std::string &message);
|
||||
Result copyFile(const std::string &source, const std::string &destination, const std::string &message, bool isARG = false);
|
||||
Result renameFile(const std::string &oldName, const std::string &newName, const std::string &message, bool isARG = false);
|
||||
Result downloadRelease(const std::string &repo, const std::string &file, const std::string &output, bool includePrereleases, const std::string &message, bool isARG = false);
|
||||
Result downloadFile(const std::string &file, const std::string &output, const std::string &message, bool isARG = false);
|
||||
void installFile(const std::string &file, bool updatingSelf, const std::string &message, bool isARG = false);
|
||||
void extractFile(const std::string &file, const std::string &input, const std::string &output, const std::string &message, bool isARG = false);
|
||||
|
||||
Result runFunctions(nlohmann::json storeJson, int selection, const std::string &entry);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -37,6 +37,7 @@ namespace StringUtils {
|
||||
std::string formatBytes(int bytes);
|
||||
std::string GetMarkString(int marks);
|
||||
std::vector<std::string> GetMarks(int marks);
|
||||
std::string format(const std::string &fmt_str, ...);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"ACTION_CANCELED": "%s canceled!",
|
||||
"ACTION_FAILED": "%s failed!",
|
||||
"ACTION_REQUIRED": "Action required!",
|
||||
"ACTION_SUCCEEDED": "%s succeeded!",
|
||||
"ACTIVE_THEME": "Active Theme",
|
||||
"ASCENDING": "Ascending",
|
||||
"ARGUMENT_INVALID": "Argument invalid.\nPlease check the xml file for proper arguments.",
|
||||
"AUTHOR": "Author",
|
||||
@@ -13,6 +18,7 @@
|
||||
"CATEGORY": "Category",
|
||||
"CHANGE_3DSX_PATH": "Change 3DSX path",
|
||||
"CHANGE_ARCHIVE_PATH": "Change archive path",
|
||||
"CHANGE_FIRM_PATH": "Change firm path",
|
||||
"CHANGE_NDS_PATH": "Change NDS path",
|
||||
"CHANGE_SHORTCUT_PATH": "Change shortcut path",
|
||||
"CHECK_UNISTORE_UPDATES": "Checking for UniStore updates...",
|
||||
@@ -21,6 +27,7 @@
|
||||
"CONNECT_WIFI": "Please Connect to WiFi.",
|
||||
"CONSOLE": "Console",
|
||||
"CONTRIBUTOR_TRANSLATORS": "- All Translators & Contributors",
|
||||
"COPYING": "Copying... %s / %s (%.2f%%)",
|
||||
"COPY_ERROR": "Copy Error!",
|
||||
"CREATE_SHORTCUT": "Would you like to create a shortcut?",
|
||||
"CREDITS": "Credits",
|
||||
@@ -31,6 +38,7 @@
|
||||
"DELETE_ERROR": "Delete Error!",
|
||||
"DELETE_PROMPT": "Are you sure you want to delete this Directory?",
|
||||
"DELETE_UNNEEDED_FILE": "Deleting unneeded file...",
|
||||
"DELETING": "Deleting...",
|
||||
"DESCENDING": "Descending",
|
||||
"DIRECTION": "Direction",
|
||||
"DIRECTORY_SETTINGS": "Directory Settings",
|
||||
@@ -40,6 +48,8 @@
|
||||
"DONE": "Done!",
|
||||
"DOWNLOAD_ERROR": "Download Error!",
|
||||
"DOWNLOAD_FAILED": "Download Failed!",
|
||||
"DOWNLOAD_SPEED": "Speed: %lld KiB/s",
|
||||
"DOWNLOADING": "Downloading... %s / %s (%.2f%%)",
|
||||
"DOWNLOADING_COMPATIBLE_FONT": "Downloading compatible font...",
|
||||
"DOWNLOADING_SPRITE_SHEET": "Downloading Spritesheet...",
|
||||
"DOWNLOADING_SPRITE_SHEET2": "Downloading Spritesheet %i of %i...",
|
||||
@@ -56,8 +66,11 @@
|
||||
"ENTRIES": "Entries",
|
||||
"EXECUTE_ENTRY": "Would you like to execute this entry?",
|
||||
"EXIT_APP": "Exit Universal-Updater",
|
||||
"EXTRACTING": "Extracting... %s / %s (%.2f%%)",
|
||||
"FEATURE_SIDE_EFFECTS": "This Feature may have side effects while the Queue is running.\nAre you sure you want to continue?",
|
||||
"FETCHING_METADATA": "Fetching old metadata...",
|
||||
"FETCHING_RECOMMENDED_UNISTORES": "Fetching recommended UniStores...",
|
||||
"FILES": "File: %d / %d",
|
||||
"FILE_EXTRACTED": "file extracted.",
|
||||
"FILE_SLASH": "Seems like a '/' is included, which is not supported.\nPlease change 'file' to filename only.",
|
||||
"FILES_EXTRACTED": "files extracted.",
|
||||
@@ -67,6 +80,7 @@
|
||||
"GUI_SETTINGS": "GUI Settings",
|
||||
"GUI_SETTINGS_BTN": "GUI settings...",
|
||||
"INCLUDE_IN_RESULTS": "Include in results:",
|
||||
"INSTALLING": "Installing... %s / %s (%.2f%%)",
|
||||
"INSTALL_UNIVERSAL_UPDATER": "Installing Universal-Updater...",
|
||||
"INVALID_UNISTORE": "Invalid UniStore",
|
||||
"KEY_CONTINUE": "Press any key to continue.",
|
||||
@@ -83,6 +97,16 @@
|
||||
"NO_LICENSE": "No License",
|
||||
"NO_SCREENSHOTS_AVAILABLE": "No Screenshots available",
|
||||
"NOT_IMPLEMENTED": "Not Implemented Yet",
|
||||
"OP_COPYING": "Copying",
|
||||
"OP_DELETING": "Deleting",
|
||||
"OP_DOWNLOADING": "Downloading",
|
||||
"OP_EXTRACTING": "Extracting",
|
||||
"OP_INSTALLING": "Installing",
|
||||
"OP_MOVING": "Moving",
|
||||
"OP_WAITING": "Waiting",
|
||||
"QUEUE": "Queue",
|
||||
"QUEUE_POSITION": "Queue position",
|
||||
"QUEUE_PROGRESS": "Step: %d / %d",
|
||||
"RECOMMENDED_UNISTORES": "Recommended UniStores",
|
||||
"REVISION": "Revision",
|
||||
"SCREENSHOT": "Screenshot %d / %d",
|
||||
@@ -93,6 +117,7 @@
|
||||
"SELECT_LANG": "Choose the language",
|
||||
"SELECT_UNISTORE": "Select UniStore",
|
||||
"SELECT_UNISTORE_2": "Select a UniStore",
|
||||
"SELECTION_QUEUE": "Add Selection to Queue",
|
||||
"SETTINGS": "Settings",
|
||||
"SHEET_SLASH": "Seems like a '/' is included, which is not supported.\nPlease change 'sheet' to filename only.",
|
||||
"SHORTCUT_CREATED": "Shortcut created!",
|
||||
@@ -102,6 +127,7 @@
|
||||
"START_SELECT": "Press START to select the current folder",
|
||||
"STORE_INFO": "Store Info",
|
||||
"SYNTAX_ERROR": "Syntax Error!",
|
||||
"THEME_DEFAULT": "Default",
|
||||
"TITLE": "Title",
|
||||
"TOP_STYLE": "Top Style",
|
||||
"UNISTORE_BG": "Use UniStore BG",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -26,23 +26,49 @@
|
||||
|
||||
#include "common.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "stringutils.hpp"
|
||||
#include <ctime>
|
||||
|
||||
/*
|
||||
Draw the base top screen.
|
||||
*/
|
||||
int GFX::SelectedTheme = 0;
|
||||
|
||||
/* All available Themes here inside that vector. */
|
||||
std::vector<UITheme> GFX::Themes = {
|
||||
/* Default Theme. */
|
||||
{
|
||||
C2D_Color32(50, 73, 98, 255), // Bar.
|
||||
C2D_Color32(38, 44, 77, 255), // BG.
|
||||
C2D_Color32(25, 30, 53, 255), // Bar Outline.
|
||||
WHITE, // Text.
|
||||
C2D_Color32(50, 73, 98, 255), // Entry bar.
|
||||
C2D_Color32(25, 30, 53, 255), // Entry Outline.
|
||||
C2D_Color32(28, 33, 58, 255), // Box Inside.
|
||||
C2D_Color32(108, 130, 155, 255), // Box Outside.
|
||||
BLACK, // Box Unselected.
|
||||
C2D_Color32(28, 33, 58, 255), // Progressbar Out.
|
||||
C2D_Color32(77, 101, 128, 255), // Progressbar In.
|
||||
C2D_Color32(51, 75, 102, 255), // Searchbar.
|
||||
C2D_Color32(25, 30, 53, 255), // Searchbar Outline.
|
||||
C2D_Color32(108, 130, 155, 255), // Sidebar Selected.
|
||||
C2D_Color32(77, 101, 128, 255), // Sidebar Unselected.
|
||||
C2D_Color32(77, 101, 128, 255), // Mark Selected.
|
||||
C2D_Color32(28, 33, 58, 255), // Mark Unselected.
|
||||
C2D_Color32(28, 33, 58, 255), // Downlist Preview (Top).
|
||||
C2D_Color32(173, 204, 239, 255) // SideBar Icon Color.
|
||||
}
|
||||
};
|
||||
|
||||
/* Draw the base top screen. */
|
||||
void GFX::DrawTop(void) {
|
||||
Gui::ScreenDraw(Top);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 26, 400, 214, GFX::Themes[GFX::SelectedTheme].BGColor);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
}
|
||||
|
||||
/*
|
||||
Draw the base bottom screen.
|
||||
*/
|
||||
/* Draw the base bottom screen. */
|
||||
void GFX::DrawBottom() {
|
||||
Gui::ScreenDraw(Bottom);
|
||||
Gui::Draw_Rect(0, 0, 320, 240, BG_COLOR);
|
||||
Gui::Draw_Rect(0, 0, 320, 240, GFX::Themes[GFX::SelectedTheme].BGColor);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -56,15 +82,15 @@ void GFX::DrawBottom() {
|
||||
uint32_t clr: (Optional) The color of the inside of the box.
|
||||
*/
|
||||
void GFX::DrawBox(float xPos, float yPos, float width, float height, bool selected, uint32_t clr) {
|
||||
Gui::Draw_Rect(xPos, yPos, width, height, BOX_INSIDE_COLOR); // Draw middle BG.
|
||||
Gui::Draw_Rect(xPos, yPos, width, height, GFX::Themes[GFX::SelectedTheme].BoxInside); // Draw middle BG.
|
||||
|
||||
if (selected) {
|
||||
static constexpr int depth = 2;
|
||||
|
||||
Gui::Draw_Rect(xPos - depth, yPos - depth, width + depth * 2, depth, BOX_SELECTED_COLOR); // Top.
|
||||
Gui::Draw_Rect(xPos - depth, yPos - depth, depth, height + depth * 2, BOX_SELECTED_COLOR); // Left.
|
||||
Gui::Draw_Rect(xPos + width, yPos - depth, depth, height + depth * 2, BOX_SELECTED_COLOR); // Right.
|
||||
Gui::Draw_Rect(xPos - depth, yPos + height, width + depth * 2, depth, BOX_SELECTED_COLOR); // Bottom.
|
||||
Gui::Draw_Rect(xPos - depth, yPos - depth, width + depth * 2, depth, GFX::Themes[GFX::SelectedTheme].BoxSelected); // Top.
|
||||
Gui::Draw_Rect(xPos - depth, yPos - depth, depth, height + depth * 2, GFX::Themes[GFX::SelectedTheme].BoxSelected); // Left.
|
||||
Gui::Draw_Rect(xPos + width, yPos - depth, depth, height + depth * 2, GFX::Themes[GFX::SelectedTheme].BoxSelected); // Right.
|
||||
Gui::Draw_Rect(xPos - depth, yPos + height, width + depth * 2, depth, GFX::Themes[GFX::SelectedTheme].BoxSelected); // Bottom.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,3 +130,70 @@ void GFX::DrawCheckbox(float xPos, float yPos, bool selected) {
|
||||
void GFX::DrawToggle(float xPos, float yPos, bool toggled) {
|
||||
GFX::DrawSprite((toggled ? sprites_toggle_on_idx : sprites_toggle_off_idx), xPos, yPos);
|
||||
}
|
||||
|
||||
void GFX::DrawTime() {
|
||||
time_t unixTime = time(nullptr);
|
||||
struct tm *timeStruct = gmtime((const time_t *)&unixTime);
|
||||
const std::string str = StringUtils::format("%02i:%02i", timeStruct->tm_hour, timeStruct->tm_min); // <Hour>:<Minute>.
|
||||
|
||||
Gui::DrawString(11, 5, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 0, 0, font);
|
||||
}
|
||||
|
||||
static int blinkDelay = 40;
|
||||
static bool blinkState = true, batteryLow = false;
|
||||
void GFX::DrawBattery() {
|
||||
u8 chargeState = false, level = 0;
|
||||
PTMU_GetBatteryChargeState(&chargeState); // Get Charge state.
|
||||
PTMU_GetBatteryLevel(&level); // Get Battery Level.
|
||||
|
||||
if (chargeState) {
|
||||
GFX::DrawSprite((level < 5 ? sprites_battery_charge_idx : sprites_battery_charge_full_idx), 366, 1);
|
||||
if (batteryLow) batteryLow = false; // Cause we're charging.
|
||||
|
||||
} else {
|
||||
switch(level) {
|
||||
case 0: // Blinky.
|
||||
GFX::DrawSprite((blinkState ? sprites_battery_blink_idx : sprites_battery_0_idx), 366, 1);
|
||||
if (!batteryLow) batteryLow = true;
|
||||
break;
|
||||
|
||||
case 1: // Red.
|
||||
GFX::DrawSprite(sprites_battery_0_idx, 366, 1);
|
||||
if (batteryLow) batteryLow = false; // Cause we're not low.
|
||||
break;
|
||||
|
||||
case 2: // One.
|
||||
GFX::DrawSprite(sprites_battery_1_idx, 366, 1);
|
||||
if (batteryLow) batteryLow = false; // Cause we're not low.
|
||||
break;
|
||||
|
||||
case 3: // Two.
|
||||
GFX::DrawSprite(sprites_battery_2_idx, 366, 1);
|
||||
if (batteryLow) batteryLow = false; // Cause we're not low.
|
||||
break;
|
||||
|
||||
case 4: // Three.
|
||||
GFX::DrawSprite(sprites_battery_3_idx, 366, 1);
|
||||
if (batteryLow) batteryLow = false; // Cause we're not low.
|
||||
break;
|
||||
|
||||
case 5: // Full.
|
||||
GFX::DrawSprite(sprites_battery_4_idx, 366, 1);
|
||||
if (batteryLow) batteryLow = false; // Cause we're not low.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GFX::HandleBattery() {
|
||||
if (batteryLow) {
|
||||
if (blinkDelay > 0) {
|
||||
blinkDelay--;
|
||||
|
||||
if (blinkDelay == 0) {
|
||||
blinkState = !blinkState;
|
||||
blinkDelay = 40;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -39,7 +39,7 @@ void Msg::DisplayMsg(const std::string &Text) {
|
||||
C2D_TargetClear(Bottom, TRANSPARENT);
|
||||
|
||||
GFX::DrawTop();
|
||||
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, Text)) / 2, 0.6f, TEXT_COLOR, Text, 395, 0, font);
|
||||
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, Text)) / 2, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Text, 395, 0, font);
|
||||
GFX::DrawBottom();
|
||||
C3D_FrameEnd(0);
|
||||
}
|
||||
@@ -56,7 +56,7 @@ void Msg::DisplayWarnMsg(const std::string &Text) {
|
||||
C2D_TargetClear(Bottom, TRANSPARENT);
|
||||
|
||||
GFX::DrawTop();
|
||||
Gui::DrawStringCentered(0, 1, 0.6f, TEXT_COLOR, Text, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 1, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Text, 390, 0, font);
|
||||
|
||||
GFX::DrawBottom();
|
||||
C3D_FrameEnd(0);
|
||||
@@ -78,11 +78,11 @@ bool Msg::promptMsg(const std::string &promptMsg) {
|
||||
C2D_TargetClear(Bottom, TRANSPARENT);
|
||||
|
||||
GFX::DrawTop();
|
||||
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, promptMsg)) / 2, 0.6f, TEXT_COLOR, promptMsg, 395, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, promptMsg)) / 2, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, promptMsg, 395, 0, font);
|
||||
|
||||
Gui::DrawStringCentered(0, 218, 0.6f, TEXT_COLOR, Lang::get("CONFIRM_OR_CANCEL"), 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 218, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("CONFIRM_OR_CANCEL"), 390, 0, font);
|
||||
GFX::DrawBottom();
|
||||
C3D_FrameEnd(0);
|
||||
|
||||
@@ -110,10 +110,10 @@ void Msg::waitMsg(const std::string &msg) {
|
||||
C2D_TargetClear(Bottom, TRANSPARENT);
|
||||
|
||||
GFX::DrawTop();
|
||||
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, msg)) / 2, 0.6f, TEXT_COLOR, msg, 395, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 218, 0.6f, TEXT_COLOR, Lang::get("KEY_CONTINUE"), 390, 0, font);
|
||||
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, msg)) / 2, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, msg, 395, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 218, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("KEY_CONTINUE"), 390, 0, font);
|
||||
GFX::DrawBottom();
|
||||
C3D_FrameEnd(0);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "download.hpp"
|
||||
#include "init.hpp"
|
||||
#include "mainScreen.hpp"
|
||||
#include "queueSystem.hpp"
|
||||
#include "sound.hpp"
|
||||
|
||||
#include <dirent.h>
|
||||
@@ -120,6 +121,7 @@ Result Init::Initialize() {
|
||||
Gui::init();
|
||||
|
||||
cfguInit();
|
||||
ptmuInit();
|
||||
amInit();
|
||||
acInit();
|
||||
|
||||
@@ -136,6 +138,8 @@ Result Init::Initialize() {
|
||||
mkdir("sdmc:/3ds/Universal-Updater/shortcuts", 0777);
|
||||
|
||||
config = std::make_unique<Config>();
|
||||
GFX::SelectedTheme = config->theme();
|
||||
if (GFX::SelectedTheme > (_THEME_AMOUNT - 1)) GFX::SelectedTheme = 0; // In case it is above the max themes.
|
||||
Lang::load(config->language());
|
||||
|
||||
Gui::loadSheet("romfs:/gfx/sprites.t3x", sprites);
|
||||
@@ -150,6 +154,7 @@ Result Init::Initialize() {
|
||||
|
||||
Gui::setScreen(std::make_unique<MainScreen>(), false, false);
|
||||
InitMusic();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -173,11 +178,11 @@ Result Init::MainLoop() {
|
||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||
C2D_TargetClear(Top, C2D_Color32(0, 0, 0, 0));
|
||||
C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0));
|
||||
|
||||
Gui::DrawScreen(false);
|
||||
if (!exiting) Gui::ScreenLogic(hDown, hHeld, touch, true, false);
|
||||
C3D_FrameEnd(0);
|
||||
|
||||
if (!exiting) Gui::ScreenLogic(hDown, hHeld, touch, true, false);
|
||||
|
||||
if (exiting) {
|
||||
if (hDown & KEY_START) fullExit = true; // Make it optionally faster.
|
||||
|
||||
@@ -204,6 +209,7 @@ Result Init::Exit() {
|
||||
gfxExit();
|
||||
cfguExit();
|
||||
config->save();
|
||||
ptmuExit();
|
||||
acExit();
|
||||
amExit();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -33,9 +33,7 @@
|
||||
#define ARG_AMOUNT 4 // In case for more args, change this. It must be ARG amount + 1, because of 3DSX Path.
|
||||
std::string _3dsxPath = "";
|
||||
|
||||
/*
|
||||
ARG Init.
|
||||
*/
|
||||
/* ARG Init. */
|
||||
static void InitForARG() {
|
||||
gfxInitDefault();
|
||||
romfsInit();
|
||||
@@ -51,14 +49,14 @@ static void InitForARG() {
|
||||
mkdir("sdmc:/3ds/Universal-Updater/shortcuts", 0777);
|
||||
|
||||
config = std::make_unique<Config>();
|
||||
GFX::SelectedTheme = config->theme();
|
||||
if (GFX::SelectedTheme > (_THEME_AMOUNT - 1)) GFX::SelectedTheme = 0; // In case it is above the max themes.
|
||||
Lang::load(config->language());
|
||||
Init::LoadFont();
|
||||
osSetSpeedupEnable(true); // Enable speed-up for New 3DS users.
|
||||
}
|
||||
|
||||
/*
|
||||
ARG Exit.
|
||||
*/
|
||||
/* ARG Exit. */
|
||||
static Result ExitForARG() {
|
||||
Gui::exit();
|
||||
Init::UnloadFont();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,7 +24,10 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "common.hpp"
|
||||
#include "keyboard.hpp"
|
||||
#include "queueSystem.hpp"
|
||||
#include "scriptUtils.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
@@ -35,15 +38,25 @@ extern std::string _3dsxPath;
|
||||
extern bool is3DSX;
|
||||
extern bool touching(touchPosition touch, Structs::ButtonPos button);
|
||||
static const std::vector<Structs::ButtonPos> downloadBoxes = {
|
||||
{ 54, 32, 262, 22 },
|
||||
{ 54, 62, 262, 22 },
|
||||
{ 54, 92, 262, 22 },
|
||||
{ 54, 122, 262, 22 },
|
||||
{ 54, 152, 262, 22 },
|
||||
{ 54, 182, 262, 22 },
|
||||
{ 54, 212, 262, 22 },
|
||||
{ 46, 32, 241, 22 },
|
||||
{ 46, 62, 241, 22 },
|
||||
{ 46, 92, 241, 22 },
|
||||
{ 46, 122, 241, 22 },
|
||||
{ 46, 152, 241, 22 },
|
||||
{ 46, 182, 241, 22 },
|
||||
{ 46, 212, 241, 22 },
|
||||
|
||||
{ 50, 216, 24, 24 }
|
||||
{ 42, 216, 24, 24 }
|
||||
};
|
||||
|
||||
static const std::vector<Structs::ButtonPos> installedPos = {
|
||||
{ 288, 32, 24, 24 },
|
||||
{ 288, 62, 24, 24 },
|
||||
{ 288, 92, 24, 24 },
|
||||
{ 288, 122, 24, 24 },
|
||||
{ 288, 152, 24, 24 },
|
||||
{ 288, 182, 24, 24 },
|
||||
{ 288, 212, 24, 24 },
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -87,51 +100,56 @@ static bool CreateShortcut(const std::string &entryName, int index, const std::s
|
||||
|
||||
|
||||
/*
|
||||
Draw the Download Entries part.
|
||||
Draw the Download entries part.
|
||||
|
||||
const std::unique_ptr<Store> &store: Const Reference to the Store class.
|
||||
const std::vector<std::string> &entries: Const Reference to the download list as a vector of strings.
|
||||
bool fetch: if fetching or not.
|
||||
const std::unique_ptr<StoreEntry> &entry: Const Reference to the StoreEntry.
|
||||
const std::vector<std::string> &sizes: Const Reference to the download sizes as a vector of strings.
|
||||
*/
|
||||
void StoreUtils::DrawDownList(const std::unique_ptr<Store> &store, const std::vector<std::string> &entries, bool fetch, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &sizes) {
|
||||
void StoreUtils::DrawDownList(const std::vector<std::string> &entries, bool fetch, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &sizes, const std::vector<bool> &installs) {
|
||||
/* For the Top Screen. */
|
||||
if (store && store->GetValid() && !fetch && entry) {
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid() && !fetch && entry) {
|
||||
if (entries.size() > 0) {
|
||||
Gui::Draw_Rect(0, 174, 400, 66, BOX_INSIDE_COLOR);
|
||||
Gui::Draw_Rect(0, 174, 400, 66, GFX::Themes[GFX::SelectedTheme].DownListPrev);
|
||||
const C2D_Image tempImg = entry->GetIcon();
|
||||
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Center W.
|
||||
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Center H.
|
||||
|
||||
C2D_DrawImageAt(tempImg, 9 + offsetW, 174 + 9 + offsetH, 0.5);
|
||||
|
||||
Gui::DrawString(70, 174 + 15, 0.45f, TEXT_COLOR, entries[store->GetDownloadIndex()], 310, 0, font);
|
||||
Gui::DrawString(70, 174 + 15, 0.45f, GFX::Themes[GFX::SelectedTheme].TextColor, entries[StoreUtils::store->GetDownloadIndex()], 310, 0, font);
|
||||
|
||||
if (!sizes.empty()) {
|
||||
if (sizes[store->GetDownloadIndex()] != "") {
|
||||
Gui::DrawString(70, 174 + 30, 0.45f, TEXT_COLOR, Lang::get("SIZE") + ": " + sizes[store->GetDownloadIndex()], 310, 0, font);
|
||||
if (sizes[StoreUtils::store->GetDownloadIndex()] != "") {
|
||||
Gui::DrawString(70, 174 + 30, 0.45f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("SIZE") + ": " + sizes[StoreUtils::store->GetDownloadIndex()], 310, 0, font);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GFX::DrawTime();
|
||||
GFX::DrawBattery();
|
||||
Animation::QueueEntryDone();
|
||||
|
||||
GFX::DrawBottom();
|
||||
Gui::Draw_Rect(48, 0, 272, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(48, 25, 272, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(25, 2, 0.6, TEXT_COLOR, Lang::get("AVAILABLE_DOWNLOADS"), 265, 0, font);
|
||||
Gui::Draw_Rect(40, 0, 280, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(40, 25, 280, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
Gui::DrawStringCentered(17, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("AVAILABLE_DOWNLOADS"), 273, 0, font);
|
||||
|
||||
if (store && store->GetValid() && !fetch && entry) {
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid() && !fetch && entry) {
|
||||
if (entries.size() > 0) {
|
||||
for (int i = 0; i < DOWNLOAD_ENTRIES && i < (int)entries.size(); i++) {
|
||||
if (store->GetDownloadIndex() == i + store->GetDownloadSIndex()) GFX::DrawBox(downloadBoxes[i].x, downloadBoxes[i].y, downloadBoxes[i].w, downloadBoxes[i].h, false);
|
||||
Gui::DrawStringCentered(54 - 160 + (262 / 2), downloadBoxes[i].y + 4, 0.45f, TEXT_COLOR, entries[(i + store->GetDownloadSIndex())], 260, 0, font);
|
||||
if (StoreUtils::store->GetDownloadIndex() == i + StoreUtils::store->GetDownloadSIndex()) Gui::Draw_Rect(downloadBoxes[i].x, downloadBoxes[i].y, downloadBoxes[i].w, downloadBoxes[i].h, GFX::Themes[GFX::SelectedTheme].MarkSelected);
|
||||
Gui::DrawStringCentered(46 - 160 + (241 / 2), downloadBoxes[i].y + 4, 0.45f, GFX::Themes[GFX::SelectedTheme].TextColor, entries[(i + StoreUtils::store->GetDownloadSIndex())], 235, 0, font);
|
||||
|
||||
if (installs[(i + StoreUtils::store->GetDownloadSIndex())]) GFX::DrawSprite(sprites_installed_idx, installedPos[i].x, installedPos[i].y);
|
||||
}
|
||||
|
||||
if (is3DSX) GFX::DrawSprite(sprites_shortcut_idx, downloadBoxes[6].x, downloadBoxes[6].y);
|
||||
|
||||
|
||||
} else { // If no downloads available..
|
||||
Gui::DrawStringCentered(54 - 160 + (262 / 2), downloadBoxes[0].y + 4, 0.5f, TEXT_COLOR, Lang::get("NO_DOWNLOADS_AVAILABLE"), 255, 0, font);
|
||||
Gui::DrawStringCentered(46 - 160 + (241 / 2), downloadBoxes[0].y + 4, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("NO_DOWNLOADS_AVAILABLE"), 235, 0, font);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,26 +162,25 @@ void StoreUtils::DrawDownList(const std::unique_ptr<Store> &store, const std::ve
|
||||
- Execute an Entry of the download list.
|
||||
- Return back to EntryInfo through `B`.
|
||||
|
||||
const std::unique_ptr<Store> &store: Const Reference to the Store class, since we do not modify anything in it.
|
||||
const std::unique_ptr<StoreEntry> &entry: Const Reference to the current StoreEntry, since we do not modify anything in it.
|
||||
const std::vector<std::string> &entries: Const Reference to the download list, since we do not modify anything in it.
|
||||
int ¤tMenu: Reference to the StoreMode / Menu, so we can switch back to EntryInfo with `B`.
|
||||
std::unique_ptr<Meta> &meta: Reference to the Meta, to apply the updates stuff.
|
||||
const int &lastMode: Const Reference to the last mode.
|
||||
int &smallDelay: Reference to the small delay. This helps to not directly press A.
|
||||
std::vector<bool> &installs: Reference to the installed states.
|
||||
*/
|
||||
void StoreUtils::DownloadHandle(const std::unique_ptr<Store> &store, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &entries, int ¤tMenu, std::unique_ptr<Meta> &meta, const int &lastMode, int &smallDelay) {
|
||||
if (store && entry) { // Ensure, store & entry is not a nullptr.
|
||||
void StoreUtils::DownloadHandle(const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &entries, int ¤tMenu, const int &lastMode, int &smallDelay, std::vector<bool> &installs) {
|
||||
if (StoreUtils::store && entry) { // Ensure, store & entry is not a nullptr.
|
||||
if (smallDelay > 0) {
|
||||
smallDelay--;
|
||||
}
|
||||
|
||||
if ((hDown & KEY_Y) || (hDown & KEY_START) || (hDown & KEY_TOUCH && touching(touch, downloadBoxes[6]))) {
|
||||
if (is3DSX) { // Only allow if 3DSX.
|
||||
if (entries.size() <= 0) return; // Smaller than 0 -> No No.
|
||||
if (StoreUtils::entries.size() <= 0) return; // Smaller than 0 -> No No.
|
||||
|
||||
if (Msg::promptMsg(Lang::get("CREATE_SHORTCUT"))) {
|
||||
if (CreateShortcut(entry->GetTitle(), store->GetDownloadIndex(), store->GetFileName(), entry->GetAuthor())) {
|
||||
if (CreateShortcut(entry->GetTitle(), StoreUtils::store->GetDownloadIndex(), StoreUtils::store->GetFileName(), entry->GetAuthor())) {
|
||||
Msg::waitMsg(Lang::get("SHORTCUT_CREATED"));
|
||||
}
|
||||
}
|
||||
@@ -173,43 +190,62 @@ void StoreUtils::DownloadHandle(const std::unique_ptr<Store> &store, const std::
|
||||
if (hRepeat & KEY_DOWN) {
|
||||
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
|
||||
|
||||
if (store->GetDownloadIndex() < (int)entries.size() - 1) store->SetDownloadIndex(store->GetDownloadIndex() + 1);
|
||||
else store->SetDownloadIndex(0);
|
||||
if (StoreUtils::store->GetDownloadIndex() < (int)entries.size() - 1) StoreUtils::store->SetDownloadIndex(StoreUtils::store->GetDownloadIndex() + 1);
|
||||
else StoreUtils::store->SetDownloadIndex(0);
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_UP) {
|
||||
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
|
||||
|
||||
if (store->GetDownloadIndex() > 0) store->SetDownloadIndex(store->GetDownloadIndex() - 1);
|
||||
else store->SetDownloadIndex(entries.size() - 1);
|
||||
if (StoreUtils::store->GetDownloadIndex() > 0) StoreUtils::store->SetDownloadIndex(StoreUtils::store->GetDownloadIndex() - 1);
|
||||
else StoreUtils::store->SetDownloadIndex(entries.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
if (hRepeat & KEY_RIGHT) {
|
||||
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
|
||||
|
||||
if (store->GetDownloadIndex() + DOWNLOAD_ENTRIES < (int)entries.size()-1) store->SetDownloadIndex(store->GetDownloadIndex() + DOWNLOAD_ENTRIES);
|
||||
else store->SetDownloadIndex(entries.size()-1);
|
||||
if (StoreUtils::store->GetDownloadIndex() + DOWNLOAD_ENTRIES < (int)entries.size()-1) StoreUtils::store->SetDownloadIndex(StoreUtils::store->GetDownloadIndex() + DOWNLOAD_ENTRIES);
|
||||
else StoreUtils::store->SetDownloadIndex(entries.size()-1);
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_LEFT) {
|
||||
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
|
||||
|
||||
if (store->GetDownloadIndex() - DOWNLOAD_ENTRIES > 0) store->SetDownloadIndex(store->GetDownloadIndex() - DOWNLOAD_ENTRIES);
|
||||
else store->SetDownloadIndex(0);
|
||||
if (StoreUtils::store->GetDownloadIndex() - DOWNLOAD_ENTRIES > 0) StoreUtils::store->SetDownloadIndex(StoreUtils::store->GetDownloadIndex() - DOWNLOAD_ENTRIES);
|
||||
else StoreUtils::store->SetDownloadIndex(0);
|
||||
}
|
||||
|
||||
if (smallDelay == 0 && hDown & KEY_TOUCH) {
|
||||
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
|
||||
|
||||
bool didTouch = false;
|
||||
|
||||
for (int i = 0; i < DOWNLOAD_ENTRIES; i++) {
|
||||
if (touching(touch, downloadBoxes[i])) {
|
||||
if (i + store->GetDownloadSIndex() < (int)entries.size()) {
|
||||
if (Msg::promptMsg(Lang::get("EXECUTE_ENTRY") + "\n\n" + entries[i + store->GetDownloadSIndex()])) {
|
||||
ScriptUtils::runFunctions(store->GetJson(), entry->GetEntryIndex(), entries[i + store->GetDownloadSIndex()]);
|
||||
if (meta) meta->SetUpdated(store->GetUniStoreTitle(), entry->GetTitle(), entry->GetLastUpdated());
|
||||
entry->SetUpdateAvl(false);
|
||||
if (i + StoreUtils::store->GetDownloadSIndex() < (int)entries.size()) {
|
||||
if (Msg::promptMsg(Lang::get("EXECUTE_ENTRY") + "\n\n" + entries[i + StoreUtils::store->GetDownloadSIndex()])) {
|
||||
StoreUtils::AddToQueue(entry->GetEntryIndex(), entries[i + StoreUtils::store->GetDownloadSIndex()], entry->GetTitle(), entry->GetLastUpdated());
|
||||
}
|
||||
|
||||
didTouch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!didTouch) {
|
||||
for (int i = 0; i < DOWNLOAD_ENTRIES; i++) {
|
||||
if (touching(touch, installedPos[i])) {
|
||||
if (i + StoreUtils::store->GetDownloadSIndex() < (int)entries.size()) {
|
||||
if (installs[i + StoreUtils::store->GetDownloadSIndex()]) {
|
||||
StoreUtils::meta->RemoveInstalled(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle(), entries[i + StoreUtils::store->GetDownloadSIndex()]);
|
||||
installs[i + StoreUtils::store->GetDownloadSIndex()] = false;
|
||||
}
|
||||
}
|
||||
|
||||
didTouch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,17 +254,24 @@ void StoreUtils::DownloadHandle(const std::unique_ptr<Store> &store, const std::
|
||||
if (smallDelay == 0 && hDown & KEY_A) {
|
||||
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
|
||||
|
||||
if (Msg::promptMsg(Lang::get("EXECUTE_ENTRY") + "\n\n" + entries[store->GetDownloadIndex()])) {
|
||||
ScriptUtils::runFunctions(store->GetJson(), entry->GetEntryIndex(), entries[store->GetDownloadIndex()]);
|
||||
if (meta) meta->SetUpdated(store->GetUniStoreTitle(), entry->GetTitle(), entry->GetLastUpdated());
|
||||
entry->SetUpdateAvl(false);
|
||||
if (Msg::promptMsg(Lang::get("EXECUTE_ENTRY") + "\n\n" + entries[StoreUtils::store->GetDownloadIndex()])) {
|
||||
StoreUtils::AddToQueue(entry->GetEntryIndex(), entries[StoreUtils::store->GetDownloadIndex()], entry->GetTitle(), entry->GetLastUpdated());
|
||||
}
|
||||
}
|
||||
|
||||
if (hDown & KEY_X) {
|
||||
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
|
||||
|
||||
if (installs[StoreUtils::store->GetDownloadIndex()]) {
|
||||
StoreUtils::meta->RemoveInstalled(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle(), entries[StoreUtils::store->GetDownloadIndex()]);
|
||||
installs[StoreUtils::store->GetDownloadIndex()] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (hDown & KEY_B) currentMenu = lastMode; // Go back to EntryInfo.
|
||||
|
||||
/* Scroll Handle. */
|
||||
if (store->GetDownloadIndex() < store->GetDownloadSIndex()) store->SetDownloadSIndex(store->GetDownloadIndex());
|
||||
else if (store->GetDownloadIndex() > store->GetDownloadSIndex() + DOWNLOAD_ENTRIES - 1) store->SetDownloadSIndex(store->GetDownloadIndex() - DOWNLOAD_ENTRIES + 1);
|
||||
if (StoreUtils::store->GetDownloadIndex() < StoreUtils::store->GetDownloadSIndex()) StoreUtils::store->SetDownloadSIndex(StoreUtils::store->GetDownloadIndex());
|
||||
else if (StoreUtils::store->GetDownloadIndex() > StoreUtils::store->GetDownloadSIndex() + DOWNLOAD_ENTRIES - 1) StoreUtils::store->SetDownloadSIndex(StoreUtils::store->GetDownloadIndex() - DOWNLOAD_ENTRIES + 1);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,40 +24,41 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
|
||||
extern bool touching(touchPosition touch, Structs::ButtonPos button);
|
||||
static const Structs::ButtonPos btn = { 53, 215, 24, 24 };
|
||||
static const Structs::ButtonPos sshot = { 83, 215, 24, 24 };
|
||||
static const Structs::ButtonPos notes = { 113, 215, 24, 24 };
|
||||
static const Structs::ButtonPos btn = { 45, 215, 24, 24 };
|
||||
static const Structs::ButtonPos sshot = { 75, 215, 24, 24 };
|
||||
static const Structs::ButtonPos notes = { 105, 215, 24, 24 };
|
||||
extern bool checkWifiStatus();
|
||||
extern bool QueueRuns;
|
||||
|
||||
/*
|
||||
Draw the Entry Info part.
|
||||
|
||||
const std::unique_ptr<Store> &store: Const Reference to the Store class.
|
||||
const std::unique_ptr<StoreEntry> &entry: Const Reference to the current StoreEntry.
|
||||
*/
|
||||
void StoreUtils::DrawEntryInfo(const std::unique_ptr<Store> &store, const std::unique_ptr<StoreEntry> &entry) {
|
||||
if (store && entry) { // Ensure, store & entry is not a nullptr.
|
||||
Gui::Draw_Rect(48, 0, 272, 36, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(48, 36, 272, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
void StoreUtils::DrawEntryInfo(const std::unique_ptr<StoreEntry> &entry) {
|
||||
if (StoreUtils::store && entry) { // Ensure, store & entry is not a nullptr.
|
||||
Gui::Draw_Rect(40, 0, 280, 36, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(40, 36, 280, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
|
||||
Gui::DrawStringCentered(25, 0, 0.6, TEXT_COLOR, entry->GetTitle(), 265, 0, font);
|
||||
Gui::DrawStringCentered(25, 20, 0.4, TEXT_COLOR, entry->GetAuthor(), 265, 0, font);
|
||||
Gui::DrawStringCentered(25, 50, 0.4, TEXT_COLOR, entry->GetDescription(), 240, 0, font, C2D_WordWrap);
|
||||
Gui::DrawStringCentered(17, 0, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, entry->GetTitle(), 273, 0, font);
|
||||
Gui::DrawStringCentered(17, 20, 0.4, GFX::Themes[GFX::SelectedTheme].TextColor, entry->GetAuthor(), 273, 0, font);
|
||||
Gui::DrawStringCentered(17, 50, 0.4, GFX::Themes[GFX::SelectedTheme].TextColor, entry->GetDescription(), 248, 0, font, C2D_WordWrap);
|
||||
|
||||
Gui::DrawString(61, 130, 0.45, TEXT_COLOR, Lang::get("VERSION") + ": " + entry->GetVersion(), 240, 0, font);
|
||||
Gui::DrawString(61, 145, 0.45, TEXT_COLOR, Lang::get("CATEGORY") + ": " + entry->GetCategory(), 240, 0, font);
|
||||
Gui::DrawString(61, 160, 0.45, TEXT_COLOR, Lang::get("CONSOLE") + ": " + entry->GetConsole(), 240, 0, font);
|
||||
Gui::DrawString(61, 175, 0.45, TEXT_COLOR, Lang::get("LAST_UPDATED") + ": " + entry->GetLastUpdated(), 240, 0, font);
|
||||
Gui::DrawString(61, 190, 0.45, TEXT_COLOR, Lang::get("LICENSE") + ": " + entry->GetLicense(), 240, 0, font);
|
||||
Gui::DrawString(53, 130, 0.45, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("VERSION") + ": " + entry->GetVersion(), 248, 0, font);
|
||||
Gui::DrawString(53, 145, 0.45, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("CATEGORY") + ": " + entry->GetCategory(), 248, 0, font);
|
||||
Gui::DrawString(53, 160, 0.45, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("CONSOLE") + ": " + entry->GetConsole(), 248, 0, font);
|
||||
Gui::DrawString(53, 175, 0.45, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("LAST_UPDATED") + ": " + entry->GetLastUpdated(), 248, 0, font);
|
||||
Gui::DrawString(53, 190, 0.45, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("LICENSE") + ": " + entry->GetLicense(), 248, 0, font);
|
||||
|
||||
GFX::DrawBox(btn.x, btn.y, btn.w, btn.h, false);
|
||||
if (!entry->GetScreenshots().empty()) GFX::DrawSprite(sprites_screenshot_idx, sshot.x, sshot.y);
|
||||
if (entry->GetReleaseNotes() != "") GFX::DrawSprite(sprites_notes_idx, notes.x, notes.y);
|
||||
Gui::DrawString(btn.x + 5, btn.y + 2, 0.6f, TEXT_COLOR, "★", 0, 0, font);
|
||||
Gui::DrawString(btn.x + 5, btn.y + 2, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, "★", 0, 0, font);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +72,8 @@ void StoreUtils::DrawEntryInfo(const std::unique_ptr<Store> &store, const std::u
|
||||
bool &showMark: Reference to showMark.. to show the mark menu.
|
||||
bool &fetch: Reference to fetch, so we know, if we need to fetch, when accessing download list.
|
||||
bool &sFetch: Reference to the screenshot fetch.
|
||||
int &mode: Reference to the Store mode.
|
||||
const std::unique_ptr<StoreEntry> &entry: The Store Entry.
|
||||
int &mode: Reference to the store mode.
|
||||
const std::unique_ptr<StoreEntry> &entry: The store Entry.
|
||||
*/
|
||||
void StoreUtils::EntryHandle(bool &showMark, bool &fetch, bool &sFetch, int &mode, const std::unique_ptr<StoreEntry> &entry) {
|
||||
if (entry) {
|
||||
@@ -81,14 +82,21 @@ void StoreUtils::EntryHandle(bool &showMark, bool &fetch, bool &sFetch, int &mod
|
||||
if ((hDown & KEY_Y) || (hDown & KEY_TOUCH && touching(touch, sshot))) {
|
||||
if (!entry->GetScreenshots().empty()) {
|
||||
if (checkWifiStatus()) {
|
||||
if (QueueRuns) {
|
||||
if (!Msg::promptMsg(Lang::get("FEATURE_SIDE_EFFECTS"))) return;
|
||||
sFetch = true;
|
||||
mode = 5;
|
||||
mode = 6;
|
||||
|
||||
} else {
|
||||
sFetch = true;
|
||||
mode = 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((hDown & KEY_X) || (hDown & KEY_TOUCH && touching(touch, notes))) {
|
||||
if (entry->GetReleaseNotes() != "") mode = 6;
|
||||
if (entry->GetReleaseNotes() != "") mode = 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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 3 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/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
|
||||
static const std::vector<Structs::ButtonPos> GridBoxes = {
|
||||
{ 25, 45, 50, 50 },
|
||||
{ 100, 45, 50, 50 },
|
||||
{ 175, 45, 50, 50 },
|
||||
{ 250, 45, 50, 50 },
|
||||
{ 325, 45, 50, 50 },
|
||||
|
||||
{ 25, 105, 50, 50 },
|
||||
{ 100, 105, 50, 50 },
|
||||
{ 175, 105, 50, 50 },
|
||||
{ 250, 105, 50, 50 },
|
||||
{ 325, 105, 50, 50 },
|
||||
|
||||
{ 25, 165, 50, 50 },
|
||||
{ 100, 165, 50, 50 },
|
||||
{ 175, 165, 50, 50 },
|
||||
{ 250, 165, 50, 50 },
|
||||
{ 325, 165, 50, 50 }
|
||||
};
|
||||
|
||||
/* Draw the Top Grid. */
|
||||
void StoreUtils::DrawGrid() {
|
||||
if (StoreUtils::store) { // Ensure, store is not a nullptr.
|
||||
|
||||
if (config->usebg() && StoreUtils::store->customBG()) {
|
||||
C2D_DrawImageAt(StoreUtils::store->GetStoreImg(), 0, 26, 0.5f, nullptr);
|
||||
|
||||
} else {
|
||||
Gui::Draw_Rect(0, 26, 400, 214, GFX::Themes[GFX::SelectedTheme].BGColor);
|
||||
}
|
||||
|
||||
for (int i = 0, i2 = 0 + (StoreUtils::store->GetScreenIndx() * 5); i2 < 15 + (StoreUtils::store->GetScreenIndx() * 5) && i2 < (int)StoreUtils::entries.size(); i2++, i++) {
|
||||
/* Boxes. */
|
||||
if (i == StoreUtils::store->GetBox()) GFX::DrawBox(GridBoxes[i].x, GridBoxes[i].y, 50, 50, true);
|
||||
|
||||
/* Ensure, entries is larger than the index. */
|
||||
if ((int)StoreUtils::entries.size() > i2) {
|
||||
if (StoreUtils::entries[i2]) { // Ensure, the Entry is not nullptr.
|
||||
const C2D_Image tempImg = StoreUtils::entries[i2]->GetIcon();
|
||||
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Center W.
|
||||
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Center H.
|
||||
|
||||
C2D_DrawImageAt(tempImg, GridBoxes[i].x + 1 + offsetW, GridBoxes[i].y + 1 + offsetH, 0.5);
|
||||
|
||||
/* Update Available mark. */
|
||||
if (StoreUtils::entries[i2]->GetUpdateAvl()) GFX::DrawSprite(sprites_update_app_idx, GridBoxes[i].x + 32, GridBoxes[i].y + 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Top Grid Logic Handle.
|
||||
Here you can..
|
||||
|
||||
- Scroll through the Grid with the D-Pad.
|
||||
|
||||
const int ¤tMode: Reference to the current Mode.
|
||||
int &lastMode: Reference to the last mode.
|
||||
bool &fetch: Reference to fetch.
|
||||
int &smallDelay: Reference to the small delay.
|
||||
*/
|
||||
void StoreUtils::GridLogic(int ¤tMode, int &lastMode, bool &fetch, int &smallDelay) {
|
||||
if (StoreUtils::store) { // Ensure, store is not a nullptr.
|
||||
if (hRepeat & KEY_DOWN) {
|
||||
if (StoreUtils::store->GetBox() > 9) {
|
||||
if (StoreUtils::store->GetEntry() + 5 < (int)StoreUtils::entries.size() - 1) {
|
||||
StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() + 5);
|
||||
|
||||
if (StoreUtils::entries.size() > 15) StoreUtils::store->SetScreenIndx((StoreUtils::store->GetEntry() / 5) - 2);
|
||||
|
||||
} else {
|
||||
if (StoreUtils::store->GetEntry() < (int)StoreUtils::entries.size() - 1) {
|
||||
StoreUtils::store->SetEntry(StoreUtils::entries.size() - 1);
|
||||
StoreUtils::store->SetBox(10 + (StoreUtils::store->GetEntry() % 5));
|
||||
|
||||
if (StoreUtils::entries.size() > 15) StoreUtils::store->SetScreenIndx((StoreUtils::store->GetEntry() / 5) - 2);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (StoreUtils::store->GetEntry() + 5 < (int)StoreUtils::entries.size()) {
|
||||
StoreUtils::store->SetBox(StoreUtils::store->GetBox() + 5);
|
||||
StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() + 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_RIGHT) {
|
||||
if (StoreUtils::store->GetEntry() < (int)StoreUtils::entries.size() - 1) {
|
||||
if (StoreUtils::store->GetBox() < 14) {
|
||||
StoreUtils::store->SetBox(StoreUtils::store->GetBox() + 1);
|
||||
StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() + 1);
|
||||
|
||||
} else {
|
||||
StoreUtils::store->SetBox(10);
|
||||
StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() + 1);
|
||||
|
||||
StoreUtils::store->SetScreenIndx((StoreUtils::store->GetEntry() / 5) - 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_LEFT) {
|
||||
if (StoreUtils::store->GetEntry() > 0) {
|
||||
if (StoreUtils::store->GetBox() > 0) {
|
||||
StoreUtils::store->SetBox(StoreUtils::store->GetBox() - 1);
|
||||
StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() - 1);
|
||||
|
||||
} else {
|
||||
StoreUtils::store->SetBox(4);
|
||||
StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() - 1);
|
||||
|
||||
StoreUtils::store->SetScreenIndx((StoreUtils::store->GetEntry() / 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_UP) {
|
||||
if (StoreUtils::store->GetBox() < 5) {
|
||||
if (StoreUtils::store->GetEntry() > 4) {
|
||||
StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() - 5);
|
||||
|
||||
StoreUtils::store->SetScreenIndx((StoreUtils::store->GetEntry() / 5));
|
||||
}
|
||||
|
||||
} else {
|
||||
StoreUtils::store->SetBox(StoreUtils::store->GetBox() - 5);
|
||||
StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() - 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (hDown & KEY_A) {
|
||||
fetch = true;
|
||||
smallDelay = 5;
|
||||
lastMode = currentMode;
|
||||
currentMode = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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 3 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/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
|
||||
static const std::vector<Structs::ButtonPos> StoreBoxesList = {
|
||||
{ 20, 45, 360, 50 },
|
||||
{ 20, 105, 360, 50 },
|
||||
{ 20, 165, 360, 50 }
|
||||
};
|
||||
|
||||
/* Draw the top List. */
|
||||
void StoreUtils::DrawList() {
|
||||
if (StoreUtils::store) { // Ensure, store is not a nullptr.
|
||||
|
||||
if (config->usebg() && StoreUtils::store->customBG()) {
|
||||
C2D_DrawImageAt(StoreUtils::store->GetStoreImg(), 0, 26, 0.5f, nullptr);
|
||||
|
||||
} else {
|
||||
Gui::Draw_Rect(0, 26, 400, 214, GFX::Themes[GFX::SelectedTheme].BGColor);
|
||||
}
|
||||
|
||||
if (StoreUtils::entries.size() > 0) {
|
||||
for (int i = 0; i < 3 && i < (int)StoreUtils::entries.size(); i++) {
|
||||
|
||||
if (i + StoreUtils::store->GetScreenIndx() == StoreUtils::store->GetEntry()) {
|
||||
GFX::DrawBox(StoreBoxesList[i].x, StoreBoxesList[i].y, StoreBoxesList[i].w, StoreBoxesList[i].h, false);
|
||||
}
|
||||
|
||||
/* Ensure, entries is larger than the index. */
|
||||
if ((int)StoreUtils::entries.size() > i + StoreUtils::store->GetScreenIndx()) {
|
||||
if (StoreUtils::entries[i + StoreUtils::store->GetScreenIndx()]) { // Ensure, the Entry is not nullptr.
|
||||
const C2D_Image tempImg = StoreUtils::entries[i + StoreUtils::store->GetScreenIndx()]->GetIcon();
|
||||
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Center W.
|
||||
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Center H.
|
||||
|
||||
C2D_DrawImageAt(tempImg, StoreBoxesList[i].x + 1 + offsetW, StoreBoxesList[i].y + 1 + offsetH, 0.5);
|
||||
}
|
||||
|
||||
if (StoreUtils::entries[i + StoreUtils::store->GetScreenIndx()]->GetUpdateAvl()) GFX::DrawSprite(sprites_update_app_idx, StoreBoxesList[i].x + 32, StoreBoxesList[i].y + 32);
|
||||
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 5, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, StoreUtils::entries[i + StoreUtils::store->GetScreenIndx()]->GetTitle(), 300, 0, font);
|
||||
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 24, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, StoreUtils::entries[i + StoreUtils::store->GetScreenIndx()]->GetAuthor(), 300, 0, font);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Top List Logic Handle.
|
||||
Here you can..
|
||||
|
||||
- Scroll through the Grid with the D-Pad Up / Down and skip 3 entries with Left / Right.
|
||||
|
||||
int ¤tMode: Const Reference to the current Mode.
|
||||
int &lastMode: Reference to the last mode.
|
||||
bool &fetch: Reference to fetch.
|
||||
int &smallDelay: Reference to the small delay.
|
||||
*/
|
||||
void StoreUtils::ListLogic(int ¤tMode, int &lastMode, bool &fetch, int &smallDelay) {
|
||||
if (StoreUtils::store) { // Ensure, store is not a nullptr.
|
||||
if (hRepeat & KEY_DOWN) {
|
||||
if (StoreUtils::store->GetEntry() < (int)StoreUtils::entries.size() - 1) StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() + 1);
|
||||
else StoreUtils::store->SetEntry(0);
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_RIGHT) {
|
||||
if (StoreUtils::store->GetEntry() < (int)StoreUtils::entries.size() - 3) StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() + 3);
|
||||
else StoreUtils::store->SetEntry(StoreUtils::entries.size() - 1);
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_LEFT) {
|
||||
if (StoreUtils::store->GetEntry() - 2 > 0) StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() - 3);
|
||||
else StoreUtils::store->SetEntry(0);
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_UP) {
|
||||
if (StoreUtils::store->GetEntry() > 0) StoreUtils::store->SetEntry(StoreUtils::store->GetEntry() - 1);
|
||||
else StoreUtils::store->SetEntry(StoreUtils::entries.size() - 1);
|
||||
}
|
||||
|
||||
if (hDown & KEY_A) {
|
||||
fetch = true;
|
||||
smallDelay = 5;
|
||||
lastMode = currentMode;
|
||||
currentMode = 1;
|
||||
}
|
||||
|
||||
/* Scroll Logic. */
|
||||
if (StoreUtils::store->GetEntry() < StoreUtils::store->GetScreenIndx()) StoreUtils::store->SetScreenIndx(StoreUtils::store->GetEntry());
|
||||
else if (StoreUtils::store->GetEntry() > StoreUtils::store->GetScreenIndx() + 3 - 1) StoreUtils::store->SetScreenIndx(StoreUtils::store->GetEntry() - 3 + 1);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,6 +24,7 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
|
||||
@@ -35,7 +36,7 @@ static const std::vector<Structs::ButtonPos> markBox = {
|
||||
{ 196, 94, 52, 52 },
|
||||
{ 258, 94, 52, 52 },
|
||||
|
||||
{ 53, 215, 24, 24 }
|
||||
{ 45, 215, 24, 24 }
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -47,28 +48,28 @@ void StoreUtils::DisplayMarkBox(int marks) {
|
||||
Gui::Draw_Rect(0, 0, 320, 240, DIM_COLOR); // Darken.
|
||||
|
||||
Gui::Draw_Rect(markBox[0].x, markBox[0].y, markBox[0].w, markBox[0].h, (marks & favoriteMarks::STAR ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
|
||||
Gui::Draw_Rect(markBox[1].x, markBox[1].y, markBox[1].w, markBox[1].h, (marks & favoriteMarks::HEART ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
|
||||
Gui::Draw_Rect(markBox[2].x, markBox[2].y, markBox[2].w, markBox[2].h, (marks & favoriteMarks::DIAMOND ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
|
||||
Gui::Draw_Rect(markBox[3].x, markBox[3].y, markBox[3].w, markBox[3].h, (marks & favoriteMarks::CLUBS ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
|
||||
Gui::Draw_Rect(markBox[4].x, markBox[4].y, markBox[4].w, markBox[4].h, (marks & favoriteMarks::SPADE ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
|
||||
Gui::DrawString(markBox[0].x + 15, markBox[0].y + 11, 0.9, TEXT_COLOR, "★", 0, 0, font);
|
||||
Gui::DrawString(markBox[1].x + 15, markBox[1].y + 11, 0.9, TEXT_COLOR, "♥", 0, 0, font);
|
||||
Gui::DrawString(markBox[2].x + 15, markBox[2].y + 11, 0.9, TEXT_COLOR, "♦", 0, 0, font);
|
||||
Gui::DrawString(markBox[3].x + 15, markBox[3].y + 11, 0.9, TEXT_COLOR, "♣", 0, 0, font);
|
||||
Gui::DrawString(markBox[4].x + 15, markBox[4].y + 11, 0.9, TEXT_COLOR, "♠", 0, 0, font);
|
||||
Gui::DrawString(markBox[0].x + 15, markBox[0].y + 11, 0.9, GFX::Themes[GFX::SelectedTheme].TextColor, "★", 0, 0, font);
|
||||
Gui::DrawString(markBox[1].x + 15, markBox[1].y + 11, 0.9, GFX::Themes[GFX::SelectedTheme].TextColor, "♥", 0, 0, font);
|
||||
Gui::DrawString(markBox[2].x + 15, markBox[2].y + 11, 0.9, GFX::Themes[GFX::SelectedTheme].TextColor, "♦", 0, 0, font);
|
||||
Gui::DrawString(markBox[3].x + 15, markBox[3].y + 11, 0.9, GFX::Themes[GFX::SelectedTheme].TextColor, "♣", 0, 0, font);
|
||||
Gui::DrawString(markBox[4].x + 15, markBox[4].y + 11, 0.9, GFX::Themes[GFX::SelectedTheme].TextColor, "♠", 0, 0, font);
|
||||
|
||||
GFX::DrawBox(markBox[5].x, markBox[5].y, markBox[5].w, markBox[5].h, false);
|
||||
Gui::DrawString(markBox[5].x + 5, markBox[5].y + 2, 0.6f, TEXT_COLOR, "★", 0, 0, font);
|
||||
Gui::DrawString(markBox[5].x + 5, markBox[5].y + 2, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, "★", 0, 0, font);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -79,47 +80,45 @@ void StoreUtils::DisplayMarkBox(int marks) {
|
||||
- Return to EntryInfo with `B`.
|
||||
|
||||
std::unique_ptr<StoreEntry> &entry: Reference to the current StoreEntry.
|
||||
const std::unique_ptr<Store> &store: Const Reference to the Store, since we do not modify anything there.
|
||||
bool &showMark: Reference to showMark, so we know, if we should stay here or not.
|
||||
std::unique_ptr<Meta> &meta: Reference to the Meta class.
|
||||
*/
|
||||
void StoreUtils::MarkHandle(std::unique_ptr<StoreEntry> &entry, const std::unique_ptr<Store> &store, bool &showMark, std::unique_ptr<Meta> &meta) {
|
||||
void StoreUtils::MarkHandle(std::unique_ptr<StoreEntry> &entry, bool &showMark) {
|
||||
hidScanInput();
|
||||
touchPosition t;
|
||||
hidTouchRead(&t);
|
||||
|
||||
if (meta && entry && store) {
|
||||
if (StoreUtils::meta && entry && StoreUtils::store) {
|
||||
if (hidKeysDown() & KEY_TOUCH) {
|
||||
/* Star. */
|
||||
if (touching(t, markBox[0])) {
|
||||
meta->SetMarks(store->GetUniStoreTitle(), entry->GetTitle(),
|
||||
meta->GetMarks(store->GetUniStoreTitle(), entry->GetTitle()) ^ favoriteMarks::STAR);
|
||||
entry->SetMark(meta->GetMarks(store->GetUniStoreTitle(), entry->GetTitle()));
|
||||
StoreUtils::meta->SetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle(),
|
||||
StoreUtils::meta->GetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle()) ^ favoriteMarks::STAR);
|
||||
entry->SetMark(StoreUtils::meta->GetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle()));
|
||||
|
||||
/* Heart. */
|
||||
} else if (touching(t, markBox[1])) {
|
||||
meta->SetMarks(store->GetUniStoreTitle(), entry->GetTitle(),
|
||||
meta->GetMarks(store->GetUniStoreTitle(), entry->GetTitle()) ^ favoriteMarks::HEART);
|
||||
entry->SetMark(meta->GetMarks(store->GetUniStoreTitle(), entry->GetTitle()));
|
||||
StoreUtils::meta->SetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle(),
|
||||
StoreUtils::meta->GetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle()) ^ favoriteMarks::HEART);
|
||||
entry->SetMark(StoreUtils::meta->GetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle()));
|
||||
|
||||
/* Diamond. */
|
||||
} else if (touching(t, markBox[2])) {
|
||||
meta->SetMarks(store->GetUniStoreTitle(), entry->GetTitle(),
|
||||
meta->GetMarks(store->GetUniStoreTitle(), entry->GetTitle()) ^ favoriteMarks::DIAMOND);
|
||||
entry->SetMark(meta->GetMarks(store->GetUniStoreTitle(), entry->GetTitle()));
|
||||
StoreUtils::meta->SetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle(),
|
||||
StoreUtils::meta->GetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle()) ^ favoriteMarks::DIAMOND);
|
||||
entry->SetMark(StoreUtils::meta->GetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle()));
|
||||
|
||||
/* Clubs. */
|
||||
} else if (touching(t, markBox[3])) {
|
||||
meta->SetMarks(store->GetUniStoreTitle(), entry->GetTitle(),
|
||||
meta->GetMarks(store->GetUniStoreTitle(), entry->GetTitle()) ^ favoriteMarks::CLUBS);
|
||||
entry->SetMark(meta->GetMarks(store->GetUniStoreTitle(), entry->GetTitle()));
|
||||
StoreUtils::meta->SetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle(),
|
||||
StoreUtils::meta->GetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle()) ^ favoriteMarks::CLUBS);
|
||||
entry->SetMark(StoreUtils::meta->GetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle()));
|
||||
|
||||
/* Spade. */
|
||||
} else if (touching(t, markBox[4])) {
|
||||
meta->SetMarks(store->GetUniStoreTitle(), entry->GetTitle(),
|
||||
meta->GetMarks(store->GetUniStoreTitle(), entry->GetTitle()) ^ favoriteMarks::SPADE);
|
||||
StoreUtils::meta->SetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle(),
|
||||
StoreUtils::meta->GetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle()) ^ favoriteMarks::SPADE);
|
||||
|
||||
entry->SetMark(meta->GetMarks(store->GetUniStoreTitle(), entry->GetTitle()));
|
||||
entry->SetMark(StoreUtils::meta->GetMarks(StoreUtils::store->GetUniStoreTitle(), entry->GetTitle()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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 3 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/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "queueSystem.hpp"
|
||||
#include "scriptUtils.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
#include <curl/curl.h>
|
||||
#include <math.h> // for std::min.
|
||||
|
||||
extern u32 extractSize, writeOffset;
|
||||
extern u32 installSize, installOffset;
|
||||
extern u32 copyOffset, copySize;
|
||||
extern int filesExtracted, extractFilesCount;
|
||||
|
||||
extern curl_off_t downloadTotal;
|
||||
extern curl_off_t downloadNow;
|
||||
extern curl_off_t downloadSpeed;
|
||||
extern CURL *CurlHandle;
|
||||
bool ShowQueueProgress = true; // Queue Mode View.
|
||||
int queueMenuIdx = 0; // Queue Menu Index.
|
||||
|
||||
#define QUEUE_ENTRIES 2 // 2 entries per screen or so.
|
||||
extern bool touching(touchPosition touch, Structs::ButtonPos button);
|
||||
|
||||
static const std::vector<Structs::ButtonPos> QueueBoxes = {
|
||||
{ 47, 36, 266, 90 },
|
||||
{ 47, 139, 266, 90 },
|
||||
{ 292, 37, 20, 20 }, // Cancel current Queue.
|
||||
{ 292, 140, 20, 20 } // Remove next Queue.
|
||||
};
|
||||
|
||||
extern std::deque<std::unique_ptr<Queue>> queueEntries;
|
||||
|
||||
void DrawStatus(QueueStatus s) {
|
||||
if (!ShowQueueProgress) {
|
||||
if (!queueEntries.empty()) {
|
||||
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, queueEntries[0]->name, 230, 0, font);
|
||||
|
||||
char prog[256];
|
||||
snprintf(prog, sizeof(prog), Lang::get("QUEUE_PROGRESS").c_str(), queueEntries[0]->current, queueEntries[0]->total);
|
||||
Gui::DrawString(QueueBoxes[0].x + 241, QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, prog, 80, 0, font, C2D_AlignRight);
|
||||
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 30, 182, 30, GFX::Themes[GFX::SelectedTheme].ProgressbarOut);
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 30 + 1, (int)(((float)queueEntries[0]->current / (float)queueEntries[0]->total) * 180.0f), 28, GFX::Themes[GFX::SelectedTheme].ProgressbarIn);
|
||||
|
||||
switch(s) {
|
||||
case QueueStatus::Done:
|
||||
case QueueStatus::Failed:
|
||||
case QueueStatus::None:
|
||||
break;
|
||||
|
||||
case QueueStatus::Copying:
|
||||
Gui::DrawString(QueueBoxes[0].x + 60, QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("OP_COPYING"), 120, 0, font);
|
||||
break;
|
||||
|
||||
case QueueStatus::Deleting:
|
||||
Gui::DrawString(QueueBoxes[0].x + 60, QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("OP_DELETING"), 120, 0, font);
|
||||
break;
|
||||
|
||||
case QueueStatus::Downloading:
|
||||
Gui::DrawString(QueueBoxes[0].x + 60, QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("OP_DOWNLOADING"), 120, 0, font);
|
||||
break;
|
||||
|
||||
case QueueStatus::Extracting:
|
||||
Gui::DrawString(QueueBoxes[0].x + 60, QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("OP_EXTRACTING"), 120, 0, font);
|
||||
break;
|
||||
|
||||
case QueueStatus::Installing:
|
||||
Gui::DrawString(QueueBoxes[0].x + 60, QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("OP_INSTALLING"), 120, 0, font);
|
||||
break;
|
||||
|
||||
case QueueStatus::Moving:
|
||||
Gui::DrawString(QueueBoxes[0].x + 60, QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("OP_MOVING"), 120, 0, font);
|
||||
break;
|
||||
|
||||
case QueueStatus::Request:
|
||||
Gui::DrawString(QueueBoxes[0].x + 60, QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("OP_WAITING"), 120, 0, font);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
char str[256], str2[256];
|
||||
|
||||
/* Progress. */
|
||||
if (!queueEntries.empty()) {
|
||||
char prog[256];
|
||||
snprintf(prog, sizeof(prog), Lang::get("QUEUE_PROGRESS").c_str(), queueEntries[0]->current, queueEntries[0]->total);
|
||||
Gui::DrawString((QueueBoxes[0].x + 241), QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, prog, 80, 0, font, C2D_AlignRight);
|
||||
}
|
||||
|
||||
/* String Handle. */
|
||||
switch(s) {
|
||||
case QueueStatus::Done:
|
||||
case QueueStatus::Failed:
|
||||
case QueueStatus::None:
|
||||
case QueueStatus::Moving:
|
||||
break;
|
||||
|
||||
case QueueStatus::Copying:
|
||||
snprintf(str, sizeof(str), Lang::get("COPYING").c_str(),
|
||||
StringUtils::formatBytes(copyOffset).c_str(),
|
||||
StringUtils::formatBytes(copySize).c_str(),
|
||||
((float)copyOffset/(float)copySize) * 100.0f);
|
||||
break;
|
||||
|
||||
case QueueStatus::Deleting:
|
||||
snprintf(str, sizeof(str), Lang::get("DELETING").c_str());
|
||||
break;
|
||||
|
||||
case QueueStatus::Downloading:
|
||||
if (CurlHandle) curl_easy_getinfo(CurlHandle, CURLINFO_SPEED_DOWNLOAD_T, &downloadSpeed);
|
||||
else downloadSpeed = 0;
|
||||
|
||||
if (downloadTotal < 1.0f) downloadTotal = 1.0f;
|
||||
if (downloadTotal < downloadNow) downloadTotal = downloadNow;
|
||||
|
||||
snprintf(str, sizeof(str), Lang::get("DOWNLOADING").c_str(),
|
||||
StringUtils::formatBytes(downloadNow).c_str(),
|
||||
StringUtils::formatBytes(downloadTotal).c_str(),
|
||||
((float)downloadNow/(float)downloadTotal) * 100.0f);
|
||||
|
||||
snprintf(str2, sizeof(str2), Lang::get("DOWNLOAD_SPEED").c_str(),
|
||||
((downloadSpeed / 1024)));
|
||||
break;
|
||||
|
||||
case QueueStatus::Extracting:
|
||||
snprintf(str, sizeof(str), Lang::get("EXTRACTING").c_str(),
|
||||
StringUtils::formatBytes(writeOffset).c_str(),
|
||||
StringUtils::formatBytes(extractSize).c_str(),
|
||||
((float)writeOffset/(float)extractSize) * 100.0f);
|
||||
|
||||
snprintf(str2, sizeof(str2), Lang::get("FILES").c_str(),
|
||||
filesExtracted, extractFilesCount);
|
||||
|
||||
break;
|
||||
|
||||
case QueueStatus::Installing:
|
||||
snprintf(str, sizeof(str), Lang::get("INSTALLING").c_str(),
|
||||
StringUtils::formatBytes(installOffset).c_str(),
|
||||
StringUtils::formatBytes(installSize).c_str(),
|
||||
((float)installOffset/(float)installSize) * 100.0f);
|
||||
break;
|
||||
|
||||
case QueueStatus::Request:
|
||||
snprintf(str, sizeof(str), Lang::get("OP_WAITING").c_str());
|
||||
snprintf(str2, sizeof(str2), Lang::get("ACTION_REQUIRED").c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
/* Draw Handle. */
|
||||
switch(s) {
|
||||
case QueueStatus::Done:
|
||||
case QueueStatus::Failed:
|
||||
case QueueStatus::None:
|
||||
break;
|
||||
|
||||
case QueueStatus::Copying:
|
||||
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 230, 0, font);
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 30, 182, 30, GFX::Themes[GFX::SelectedTheme].ProgressbarOut);
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 30 + 1, (int)(((float)copyOffset / (float)copySize) * 180.0f), 28, GFX::Themes[GFX::SelectedTheme].ProgressbarIn);
|
||||
break;
|
||||
|
||||
case QueueStatus::Deleting:
|
||||
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 230, 0, font);
|
||||
break;
|
||||
|
||||
case QueueStatus::Downloading:
|
||||
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 230, 0, font);
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 30, 182, 30, GFX::Themes[GFX::SelectedTheme].ProgressbarOut);
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 30 + 1, (int)(((float)downloadNow / (float)downloadTotal) * 180.0f), 28, GFX::Themes[GFX::SelectedTheme].ProgressbarIn);
|
||||
Gui::DrawString(QueueBoxes[0].x + 60, QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, str2, 120, 0, font);
|
||||
break;
|
||||
|
||||
case QueueStatus::Extracting:
|
||||
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 230, 0, font);
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 30, 182, 30, GFX::Themes[GFX::SelectedTheme].ProgressbarOut);
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 30 + 1, (int)(((float)writeOffset / (float)extractSize) * 180.0f), 28, GFX::Themes[GFX::SelectedTheme].ProgressbarIn);
|
||||
Gui::DrawString(QueueBoxes[0].x + 60, QueueBoxes[0].y + 68, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, str2, 120, 0, font);
|
||||
break;
|
||||
|
||||
case QueueStatus::Installing:
|
||||
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 230, 0, font);
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 30, 182, 30, GFX::Themes[GFX::SelectedTheme].ProgressbarOut);
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 30 + 1, (int)(((float)installOffset / (float)installSize) * 180.0f), 28, GFX::Themes[GFX::SelectedTheme].ProgressbarIn);
|
||||
break;
|
||||
|
||||
case QueueStatus::Moving:
|
||||
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("OP_MOVING"), 230, 0, font);
|
||||
break;
|
||||
|
||||
case QueueStatus::Request:
|
||||
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 230, 0, font);
|
||||
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 30, 182, 30, GFX::Themes[GFX::SelectedTheme].ProgressbarOut);
|
||||
Gui::DrawStringCentered(QueueBoxes[0].x + 151 - 160, QueueBoxes[0].y + 32, 0.8f, GFX::Themes[GFX::SelectedTheme].TextColor, str2, 180, 0, font);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void StoreUtils::DrawQueueMenu(const int queueIndex) {
|
||||
Gui::Draw_Rect(40, 0, 280, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(40, 25, 280, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
Gui::DrawStringCentered(17, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("QUEUE"), 273, 0, font);
|
||||
|
||||
if (!queueEntries.empty()) {
|
||||
Gui::Draw_Rect(QueueBoxes[0].x, QueueBoxes[0].y, QueueBoxes[0].w, QueueBoxes[0].h, GFX::Themes[GFX::SelectedTheme].MarkSelected);
|
||||
|
||||
const C2D_Image tempImg = queueEntries[0]->icn;
|
||||
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Center W.
|
||||
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Center H.
|
||||
C2D_DrawImageAt(tempImg, QueueBoxes[0].x + 5 + offsetW, QueueBoxes[0].y + 21 + offsetH, 0.5f);
|
||||
|
||||
DrawStatus(queueEntries[0]->status);
|
||||
GFX::DrawSprite(sprites_cancel_idx, QueueBoxes[2].x, QueueBoxes[2].y); // Don't show until properly implemented.
|
||||
|
||||
/* The next Queue Entries being displayed below. */
|
||||
if ((1 + queueMenuIdx) < (int)queueEntries.size()) {
|
||||
Gui::Draw_Rect(QueueBoxes[1].x, QueueBoxes[1].y, QueueBoxes[1].w, QueueBoxes[1].h, GFX::Themes[GFX::SelectedTheme].MarkUnselected);
|
||||
|
||||
const C2D_Image tempImg2 = queueEntries[1 + queueMenuIdx]->icn;
|
||||
const uint8_t offsetW2 = (48 - tempImg2.subtex->width) / 2; // Center W.
|
||||
const uint8_t offsetH2 = (48 - tempImg2.subtex->height) / 2; // Center H.
|
||||
C2D_DrawImageAt(tempImg2, QueueBoxes[1].x + 5 + offsetW2, QueueBoxes[1].y + 21 + offsetH2, 0.5f);
|
||||
|
||||
Gui::DrawString(QueueBoxes[1].x + 10, QueueBoxes[1].y + 5, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, queueEntries[1 + queueMenuIdx]->name, 230, 0, font);
|
||||
|
||||
Gui::DrawString(QueueBoxes[1].x + 60, QueueBoxes[1].y + 30, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("QUEUE_POSITION") + ": " + std::to_string(queueMenuIdx + 1), 0, 0, font);
|
||||
|
||||
/* Cancel. */
|
||||
GFX::DrawSprite(sprites_cancel_idx, QueueBoxes[3].x, QueueBoxes[3].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StoreUtils::QueueMenuHandle(int &queueIndex, int &storeMode) {
|
||||
if (!queueEntries.empty()) {
|
||||
if ((1 + queueMenuIdx) > (int)queueEntries.size() - 1) queueMenuIdx = std::max<int>((int)(queueEntries.size() - 1) - 1, 0); // Ensure this really doesn't go below 0.
|
||||
}
|
||||
|
||||
if (hDown & KEY_TOUCH) {
|
||||
/* Current Queue Cancel. */
|
||||
if (QueueSystem::RequestNeeded == NO_REQUEST && touching(touch, QueueBoxes[2])) { // Needs to be above the 0 one, otherwise the callback won't be accepted.
|
||||
QueueSystem::CancelCallback = true;
|
||||
|
||||
} else if (touching(touch, QueueBoxes[0])) {
|
||||
if (QueueSystem::RequestNeeded != NO_REQUEST) { // -1 means no request.
|
||||
switch(QueueSystem::RequestNeeded) {
|
||||
case RMDIR_REQUEST: // Remove Directory message.
|
||||
QueueSystem::RequestAnswer = Msg::promptMsg(QueueSystem::RequestMsg);
|
||||
|
||||
QueueSystem::Wait = false;
|
||||
QueueSystem::Resume();
|
||||
break;
|
||||
|
||||
case PROMPT_REQUEST: // Skip prompt message.
|
||||
QueueSystem::RequestAnswer = ScriptUtils::prompt(QueueSystem::RequestMsg);
|
||||
|
||||
QueueSystem::Wait = false;
|
||||
QueueSystem::Resume();
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
ShowQueueProgress = !ShowQueueProgress; // In case no request expected, switch from progress to total progress mode etc.
|
||||
}
|
||||
|
||||
/* Remove from Queue. */
|
||||
} else if (touching(touch, QueueBoxes[3])) { // Remove Queue entries.
|
||||
if (queueEntries.size() > 1) queueEntries.erase(queueEntries.begin() + 1 + queueMenuIdx);
|
||||
}
|
||||
}
|
||||
|
||||
if (hDown & KEY_DOWN) {
|
||||
if (!queueEntries.empty()) {
|
||||
if ((1 + queueMenuIdx) < (int)queueEntries.size() - 1) queueMenuIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
if (hDown & KEY_UP) {
|
||||
if (queueMenuIdx > 0) queueMenuIdx--;
|
||||
}
|
||||
|
||||
if (hDown & KEY_B) storeMode = 0; // Go to EntryInfo.
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,24 +24,28 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "common.hpp"
|
||||
#include "download.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
|
||||
void StoreUtils::DrawReleaseNotes(const int &scrollIndex, const std::unique_ptr<StoreEntry> &entry, const std::unique_ptr<Store> &store) {
|
||||
if (entry && store) {
|
||||
void StoreUtils::DrawReleaseNotes(const int &scrollIndex, const std::unique_ptr<StoreEntry> &entry) {
|
||||
if (entry && StoreUtils::store) {
|
||||
Gui::ScreenDraw(Top);
|
||||
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
|
||||
Gui::DrawString(5, 25 - scrollIndex, 0.5f, TEXT_COLOR, entry->GetReleaseNotes(), 390, 0, font, C2D_WordWrap);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, entry->GetTitle(), 390, 0, font);
|
||||
Gui::Draw_Rect(0, 26, 400, 214, GFX::Themes[GFX::SelectedTheme].BGColor);
|
||||
Gui::DrawString(5, 25 - scrollIndex, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, entry->GetReleaseNotes(), 390, 0, font, C2D_WordWrap);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, entry->GetTitle(), 390, 0, font);
|
||||
|
||||
} else {
|
||||
Gui::ScreenDraw(Top);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::Draw_Rect(0, 26, 400, 214, GFX::Themes[GFX::SelectedTheme].BGColor);
|
||||
}
|
||||
|
||||
Animation::QueueEntryDone();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -85,18 +89,18 @@ void DisplayChangelog() {
|
||||
C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0));
|
||||
|
||||
Gui::ScreenDraw(Top);
|
||||
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
|
||||
Gui::DrawString(5, 25 - scrollIndex, 0.5f, TEXT_COLOR, notes, 390, 0, font, C2D_WordWrap);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, "Universal-Updater", 390, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 217, 0.7f, TEXT_COLOR, C_V, 390, 0, font);
|
||||
Gui::Draw_Rect(0, 26, 400, 214, GFX::Themes[GFX::SelectedTheme].BGColor);
|
||||
Gui::DrawString(5, 25 - scrollIndex, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, notes, 390, 0, font, C2D_WordWrap);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, "Universal-Updater", 390, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 217, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, C_V, 390, 0, font);
|
||||
|
||||
GFX::DrawBottom();
|
||||
Gui::Draw_Rect(0, 0, 320, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 320, 1, BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(0, 0, 320, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 25, 320, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
C3D_FrameEnd(0);
|
||||
|
||||
hidScanInput();
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,6 +24,8 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "common.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
|
||||
@@ -43,15 +45,17 @@ extern bool checkWifiStatus();
|
||||
*/
|
||||
void StoreUtils::DrawScreenshotMenu(const C2D_Image &img, const int sIndex, const bool sFetch, const int screenshotSize, const std::string &name, const int zoom, const bool canDisplay) {
|
||||
Gui::ScreenDraw(Top);
|
||||
Gui::Draw_Rect(0, 0, 400, 240, BG_COLOR);
|
||||
Gui::Draw_Rect(0, 0, 400, 240, GFX::Themes[GFX::SelectedTheme].BGColor);
|
||||
|
||||
if (!canDisplay) {
|
||||
Animation::QueueEntryDone();
|
||||
|
||||
GFX::DrawBottom();
|
||||
if (screenshotSize > 0) { // if texture is nullptr AND screenshot size is larger than 0.
|
||||
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, Lang::get("SCREENSHOT_COULD_NOT_LOAD"), 310);
|
||||
Gui::DrawStringCentered(0, 2, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("SCREENSHOT_COULD_NOT_LOAD"), 310);
|
||||
|
||||
} else {
|
||||
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, Lang::get("NO_SCREENSHOTS_AVAILABLE"), 310);
|
||||
Gui::DrawStringCentered(0, 2, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("NO_SCREENSHOTS_AVAILABLE"), 310);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -82,6 +86,7 @@ void StoreUtils::DrawScreenshotMenu(const C2D_Image &img, const int sIndex, cons
|
||||
delete top.subtex;
|
||||
}
|
||||
|
||||
Animation::QueueEntryDone();
|
||||
GFX::DrawBottom();
|
||||
|
||||
/* Bottom. */
|
||||
@@ -92,19 +97,20 @@ void StoreUtils::DrawScreenshotMenu(const C2D_Image &img, const int sIndex, cons
|
||||
delete bottom.subtex;
|
||||
|
||||
} else {
|
||||
Gui::Draw_Rect(0, 215, 320, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 214, 320, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 220, 0.5f, TEXT_COLOR, Lang::get("SCREENSHOT_INSTRUCTIONS"), 310, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 320, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 214, 320, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 220, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("SCREENSHOT_INSTRUCTIONS"), 310, 0, font);
|
||||
|
||||
char screenshots[0x100];
|
||||
snprintf(screenshots, sizeof(screenshots), Lang::get("SCREENSHOT").c_str(), sIndex + 1, screenshotSize);
|
||||
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, screenshots, 310, 0, font);
|
||||
Gui::DrawStringCentered(0, 40, 0.6f, WHITE, name, 310, 0, font);
|
||||
Gui::DrawStringCentered(0, 2, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, screenshots, 310, 0, font);
|
||||
Gui::DrawStringCentered(0, 40, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, name, 310, 0, font);
|
||||
}
|
||||
|
||||
} else {
|
||||
Animation::QueueEntryDone();
|
||||
GFX::DrawBottom();
|
||||
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, Lang::get("NO_SCREENSHOTS_AVAILABLE"), 310);
|
||||
Gui::DrawStringCentered(0, 2, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("NO_SCREENSHOTS_AVAILABLE"), 310);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,27 +24,35 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "keyboard.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
|
||||
extern bool touching(touchPosition touch, Structs::ButtonPos button);
|
||||
static const std::vector<Structs::ButtonPos> SearchMenu = {
|
||||
{ 55, 45, 258, 30 }, // Search bar.
|
||||
{ 51, 41, 262, 30 }, // Search bar.
|
||||
|
||||
/* Includes. */
|
||||
{ 85, 109, 50, 10 },
|
||||
{ 85, 125, 50, 10 },
|
||||
{ 167, 109, 50, 10 },
|
||||
{ 167, 125, 50, 10 },
|
||||
{ 85, 101, 50, 10 },
|
||||
{ 85, 117, 50, 10 },
|
||||
{ 167, 101, 50, 10 },
|
||||
{ 167, 117, 50, 10 },
|
||||
|
||||
/* Filters. */
|
||||
{ 82, 195, 30, 30 },
|
||||
{ 117, 195, 30, 30 },
|
||||
{ 152, 195, 30, 30 },
|
||||
{ 187, 195, 30, 30 },
|
||||
{ 222, 195, 30, 30 },
|
||||
{ 257, 195, 30, 30 }
|
||||
{ 82, 159, 30, 30 },
|
||||
{ 117, 159, 30, 30 },
|
||||
{ 152, 159, 30, 30 },
|
||||
{ 187, 159, 30, 30 },
|
||||
{ 222, 159, 30, 30 },
|
||||
{ 257, 159, 30, 30 },
|
||||
|
||||
/* Send to Queue. */
|
||||
{ 91, 200, 185, 25 },
|
||||
|
||||
/* AND / OR. */
|
||||
{ 222, 139, 30, 13 },
|
||||
{ 257, 139, 30, 13 }
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -54,57 +62,68 @@ static const std::vector<Structs::ButtonPos> SearchMenu = {
|
||||
const std::string &searchResult: Const Reference to the searchResult.
|
||||
int marks: The filter mark flags.
|
||||
bool updateFilter: The update filter.
|
||||
isAND: isAND for the AND / OR mode.
|
||||
*/
|
||||
void StoreUtils::DrawSearchMenu(const std::vector<bool> &searchIncludes, const std::string &searchResult, int marks, bool updateFilter) {
|
||||
Gui::Draw_Rect(48, 0, 272, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(48, 25, 272, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(25, 2, 0.6, TEXT_COLOR, Lang::get("SEARCH_FILTERS"), 265, 0, font);
|
||||
void StoreUtils::DrawSearchMenu(const std::vector<bool> &searchIncludes, const std::string &searchResult, int marks, bool updateFilter, bool isAND) {
|
||||
Gui::Draw_Rect(40, 0, 280, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(40, 25, 280, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
Gui::DrawStringCentered(21, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("SEARCH_FILTERS"), 269, 0, font);
|
||||
|
||||
Gui::Draw_Rect(54, 44, 260, SearchMenu[0].h + 2, SEARCH_BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(SearchMenu[0].x, SearchMenu[0].y, SearchMenu[0].w, SearchMenu[0].h, SEARCH_BAR_COLOR);
|
||||
Gui::Draw_Rect(50, 40, 264, SearchMenu[0].h + 2, GFX::Themes[GFX::SelectedTheme].SearchbarOutline);
|
||||
Gui::Draw_Rect(SearchMenu[0].x, SearchMenu[0].y, SearchMenu[0].w, SearchMenu[0].h, GFX::Themes[GFX::SelectedTheme].SearchBar);
|
||||
|
||||
Gui::DrawStringCentered(28, 50, 0.6, TEXT_COLOR, searchResult, 265, 0, font);
|
||||
Gui::DrawStringCentered(24, 46, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, searchResult, 265, 0, font);
|
||||
|
||||
/* Checkboxes. */
|
||||
for (int i = 0; i < 4; i++) {
|
||||
GFX::DrawCheckbox(SearchMenu[i + 1].x, SearchMenu[i + 1].y, searchIncludes[i]);
|
||||
}
|
||||
|
||||
Gui::DrawString(84, 85, 0.5, TEXT_COLOR, Lang::get("INCLUDE_IN_RESULTS"), 265, 0, font);
|
||||
Gui::DrawString(84, 81, 0.5, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("INCLUDE_IN_RESULTS"), 265, 0, font);
|
||||
|
||||
Gui::DrawString(SearchMenu[1].x + 18, SearchMenu[1].y + 1, 0.4, TEXT_COLOR, Lang::get("TITLE"), 90, 0, font);
|
||||
Gui::DrawString(SearchMenu[2].x + 18, SearchMenu[2].y + 1, 0.4, TEXT_COLOR, Lang::get("AUTHOR"), 90, 0, font);
|
||||
Gui::DrawString(SearchMenu[1].x + 18, SearchMenu[1].y + 1, 0.4, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("TITLE"), 90, 0, font);
|
||||
Gui::DrawString(SearchMenu[2].x + 18, SearchMenu[2].y + 1, 0.4, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("AUTHOR"), 90, 0, font);
|
||||
|
||||
Gui::DrawString(SearchMenu[3].x + 18, SearchMenu[3].y + 1, 0.4, TEXT_COLOR, Lang::get("CATEGORY"), 90, 0, font);
|
||||
Gui::DrawString(SearchMenu[4].x + 18, SearchMenu[4].y + 1, 0.4, TEXT_COLOR, Lang::get("CONSOLE"), 90, 0, font);
|
||||
Gui::DrawString(SearchMenu[3].x + 18, SearchMenu[3].y + 1, 0.4, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("CATEGORY"), 90, 0, font);
|
||||
Gui::DrawString(SearchMenu[4].x + 18, SearchMenu[4].y + 1, 0.4, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("CONSOLE"), 90, 0, font);
|
||||
|
||||
/* Filters. */
|
||||
Gui::DrawString(84, 175, 0.5f, TEXT_COLOR, Lang::get("FILTER_TO"), 265, 0, font);
|
||||
Gui::DrawString(84, SearchMenu[5].y - 20, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("FILTER_TO"), 265, 0, font);
|
||||
|
||||
Gui::Draw_Rect(SearchMenu[5].x, SearchMenu[5].y, SearchMenu[5].w, SearchMenu[5].h, (marks & favoriteMarks::STAR ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].SideBarUnselected : GFX::Themes[GFX::SelectedTheme].BoxInside));
|
||||
|
||||
Gui::Draw_Rect(SearchMenu[6].x, SearchMenu[6].y, SearchMenu[6].w, SearchMenu[6].h, (marks & favoriteMarks::HEART ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].SideBarUnselected : GFX::Themes[GFX::SelectedTheme].BoxInside));
|
||||
|
||||
Gui::Draw_Rect(SearchMenu[7].x, SearchMenu[7].y, SearchMenu[7].w, SearchMenu[7].h, (marks & favoriteMarks::DIAMOND ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].SideBarUnselected : GFX::Themes[GFX::SelectedTheme].BoxInside));
|
||||
|
||||
Gui::Draw_Rect(SearchMenu[8].x, SearchMenu[8].y, SearchMenu[8].w, SearchMenu[8].h, (marks & favoriteMarks::CLUBS ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].SideBarUnselected : GFX::Themes[GFX::SelectedTheme].BoxInside));
|
||||
|
||||
Gui::Draw_Rect(SearchMenu[9].x, SearchMenu[9].y, SearchMenu[9].w, SearchMenu[9].h, (marks & favoriteMarks::SPADE ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].SideBarUnselected : GFX::Themes[GFX::SelectedTheme].BoxInside));
|
||||
|
||||
Gui::Draw_Rect(SearchMenu[10].x, SearchMenu[10].y, SearchMenu[10].w, SearchMenu[10].h, (updateFilter ?
|
||||
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
GFX::Themes[GFX::SelectedTheme].SideBarUnselected : GFX::Themes[GFX::SelectedTheme].BoxInside));
|
||||
|
||||
Gui::DrawString(SearchMenu[5].x + 9, SearchMenu[5].y + 7, 0.5f, TEXT_COLOR, "★", 0, 0, font);
|
||||
Gui::DrawString(SearchMenu[6].x + 9, SearchMenu[6].y + 7, 0.5f, TEXT_COLOR, "♥", 0, 0, font);
|
||||
Gui::DrawString(SearchMenu[7].x + 9, SearchMenu[7].y + 7, 0.5f, TEXT_COLOR, "♦", 0, 0, font);
|
||||
Gui::DrawString(SearchMenu[8].x + 9, SearchMenu[8].y + 7, 0.5f, TEXT_COLOR, "♣", 0, 0, font);
|
||||
Gui::DrawString(SearchMenu[9].x + 9, SearchMenu[9].y + 7, 0.5f, TEXT_COLOR, "♠", 0, 0, font);
|
||||
Gui::DrawString(SearchMenu[5].x + 9, SearchMenu[5].y + 7, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "★", 0, 0, font);
|
||||
Gui::DrawString(SearchMenu[6].x + 9, SearchMenu[6].y + 7, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "♥", 0, 0, font);
|
||||
Gui::DrawString(SearchMenu[7].x + 9, SearchMenu[7].y + 7, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "♦", 0, 0, font);
|
||||
Gui::DrawString(SearchMenu[8].x + 9, SearchMenu[8].y + 7, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "♣", 0, 0, font);
|
||||
Gui::DrawString(SearchMenu[9].x + 9, SearchMenu[9].y + 7, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "♠", 0, 0, font);
|
||||
GFX::DrawSprite(sprites_update_filter_idx, SearchMenu[10].x + 8, SearchMenu[10].y + 8);
|
||||
|
||||
Gui::Draw_Rect(SearchMenu[11].x, SearchMenu[11].y, SearchMenu[11].w, SearchMenu[11].h, GFX::Themes[GFX::SelectedTheme].MarkUnselected);
|
||||
Gui::DrawStringCentered(23, SearchMenu[11].y + 6, 0.45f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("SELECTION_QUEUE"), 280, 0, font);
|
||||
|
||||
/* AND / OR. */
|
||||
Gui::Draw_Rect(SearchMenu[12].x, SearchMenu[12].y, SearchMenu[12].w, SearchMenu[12].h, (isAND ? GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
Gui::DrawString(SearchMenu[12].x + 4, SearchMenu[12].y, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, "AND", 0, 0, font);
|
||||
|
||||
Gui::Draw_Rect(SearchMenu[13].x, SearchMenu[13].y, SearchMenu[13].w, SearchMenu[13].h, (!isAND ? GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
Gui::DrawString(SearchMenu[13].x + 8, SearchMenu[13].y, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, "OR", 0, 0, font);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -115,15 +134,13 @@ void StoreUtils::DrawSearchMenu(const std::vector<bool> &searchIncludes, const s
|
||||
- Search the UniStore.
|
||||
- Include stuff into the search.
|
||||
|
||||
std::unique_ptr<Store> &store: Reference to the Store class.
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the Store Entries.
|
||||
std::vector<bool> &searchIncludes: Reference to the searchIncludes.
|
||||
std::unique_ptr<Meta> &meta: Reference to the Meta class.
|
||||
std::string &searchResult: Reference to the searchResult.
|
||||
int &marks: Reference to the mark flags.
|
||||
bool &updateFilter: Reference to the update filter.
|
||||
bool &isAND: Reference to isAND boolean for AND / OR mode.
|
||||
*/
|
||||
void StoreUtils::SearchHandle(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::vector<bool> &searchIncludes, std::unique_ptr<Meta> &meta, std::string &searchResult, int &marks, bool &updateFilter, bool ascending, SortType sorttype) {
|
||||
void StoreUtils::SearchHandle(std::vector<bool> &searchIncludes, std::string &searchResult, int &marks, bool &updateFilter, bool ascending, SortType sorttype, bool &isAND) {
|
||||
/* Checkboxes. */
|
||||
if (hDown & KEY_TOUCH) {
|
||||
bool didTouch = false;
|
||||
@@ -140,7 +157,7 @@ void StoreUtils::SearchHandle(std::unique_ptr<Store> &store, std::vector<std::un
|
||||
/* Search bar. */
|
||||
if (!didTouch) {
|
||||
if (touching(touch, SearchMenu[0])) {
|
||||
if (store) {
|
||||
if (StoreUtils::store) {
|
||||
searchResult = Input::setkbdString(20, Lang::get("ENTER_SEARCH"), {});
|
||||
didTouch = true;
|
||||
|
||||
@@ -176,18 +193,29 @@ void StoreUtils::SearchHandle(std::unique_ptr<Store> &store, std::vector<std::un
|
||||
} else if (touching(touch, SearchMenu[10])) {
|
||||
updateFilter = !updateFilter;
|
||||
didTouch = true;
|
||||
|
||||
} else if (touching(touch, SearchMenu[11])) {
|
||||
StoreUtils::AddAllToQueue();
|
||||
|
||||
} else if (touching(touch, SearchMenu[12])) {
|
||||
isAND = true;
|
||||
didTouch = true;
|
||||
|
||||
} else if (touching(touch, SearchMenu[13])) {
|
||||
isAND = false;
|
||||
didTouch = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (didTouch) {
|
||||
if (store && store->GetValid()) { // Only search, when valid.
|
||||
StoreUtils::ResetAll(store, meta, entries);
|
||||
StoreUtils::search(entries, searchResult, searchIncludes[0], searchIncludes[1], searchIncludes[2], searchIncludes[3], marks, updateFilter);
|
||||
store->SetScreenIndx(0);
|
||||
store->SetEntry(0);
|
||||
store->SetBox(0);
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid()) { // Only search, when valid.
|
||||
StoreUtils::ResetAll();
|
||||
StoreUtils::search(searchResult, searchIncludes[0], searchIncludes[1], searchIncludes[2], searchIncludes[3], marks, updateFilter, isAND);
|
||||
StoreUtils::store->SetScreenIndx(0);
|
||||
StoreUtils::store->SetEntry(0);
|
||||
StoreUtils::store->SetBox(0);
|
||||
|
||||
StoreUtils::SortEntries(ascending, sorttype, entries);
|
||||
StoreUtils::SortEntries(ascending, sorttype);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,9 +227,9 @@ void StoreUtils::SearchHandle(std::unique_ptr<Store> &store, std::vector<std::un
|
||||
for(uint i = 0; i < searchIncludes.size(); i++) searchIncludes[i] = false;
|
||||
searchResult = "";
|
||||
|
||||
if (store && store->GetValid()) {
|
||||
StoreUtils::ResetAll(store, meta, entries);
|
||||
StoreUtils::SortEntries(ascending, sorttype, entries);
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid()) {
|
||||
StoreUtils::ResetAll();
|
||||
StoreUtils::SortEntries(ascending, sorttype);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,45 +24,47 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "init.hpp"
|
||||
#include "overlay.hpp"
|
||||
#include "scriptUtils.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include <unistd.h>
|
||||
|
||||
extern bool exiting;
|
||||
extern bool exiting, QueueRuns;
|
||||
extern bool touching(touchPosition touch, Structs::ButtonPos button);
|
||||
static const std::vector<Structs::ButtonPos> mainButtons = {
|
||||
{ 54, 32, 262, 22 },
|
||||
{ 54, 62, 262, 22 },
|
||||
{ 54, 92, 262, 22 },
|
||||
{ 54, 122, 262, 22 },
|
||||
{ 54, 152, 262, 22 },
|
||||
{ 54, 182, 262, 22 },
|
||||
{ 54, 212, 262, 22 }
|
||||
{ 45, 32, 271, 22 },
|
||||
{ 45, 62, 271, 22 },
|
||||
{ 45, 92, 271, 22 },
|
||||
{ 45, 122, 271, 22 },
|
||||
{ 45, 152, 271, 22 },
|
||||
{ 45, 182, 271, 22 },
|
||||
{ 45, 212, 271, 22 }
|
||||
};
|
||||
|
||||
static const std::vector<Structs::ButtonPos> langButtons = {
|
||||
{ 10, 34, 300, 22 },
|
||||
{ 10, 64, 300, 22 },
|
||||
{ 10, 94, 300, 22 },
|
||||
{ 10, 124, 300, 22 },
|
||||
{ 10, 154, 300, 22 },
|
||||
{ 10, 184, 300, 22 },
|
||||
{ 45, 32, 271, 22 },
|
||||
{ 45, 62, 271, 22 },
|
||||
{ 45, 92, 271, 22 },
|
||||
{ 45, 122, 271, 22 },
|
||||
{ 45, 152, 271, 22 },
|
||||
{ 45, 182, 271, 22 },
|
||||
|
||||
{ 52, 220, 16, 16 } // Add Font.
|
||||
{ 45, 220, 16, 16 } // Add Font.
|
||||
};
|
||||
|
||||
static const std::vector<Structs::ButtonPos> toggleAbles = {
|
||||
{ 288, 64, 24, 24 },
|
||||
{ 288, 140, 24, 24 }
|
||||
{ 288, 44, 24, 24 },
|
||||
{ 288, 120, 24, 24 }
|
||||
};
|
||||
|
||||
static const Structs::ButtonPos back = { 52, 0, 24, 24 }; // Back arrow for directory.
|
||||
static const Structs::ButtonPos back = { 45, 0, 24, 24 }; // Back arrow for directory.
|
||||
static const Structs::ButtonPos Themes = { 40, 220, 280, 24 }; // Themes.
|
||||
|
||||
|
||||
static const std::vector<std::string> mainStrings = { "LANGUAGE", "SELECT_UNISTORE", "AUTO_UPDATE_SETTINGS_BTN", "GUI_SETTINGS_BTN", "DIRECTORY_SETTINGS_BTN", "CREDITS", "EXIT_APP" };
|
||||
static const std::vector<std::string> dirStrings = { "CHANGE_3DSX_PATH", "CHANGE_NDS_PATH", "CHANGE_ARCHIVE_PATH", "CHANGE_SHORTCUT_PATH" };
|
||||
static const std::vector<std::string> dirStrings = { "CHANGE_3DSX_PATH", "CHANGE_NDS_PATH", "CHANGE_ARCHIVE_PATH", "CHANGE_SHORTCUT_PATH", "CHANGE_FIRM_PATH" };
|
||||
|
||||
/* Note: Украïнська is spelled using a latin i with dieresis to work in the system font */
|
||||
//static const std::vector<std::string> languages = { "Bruh", "Dansk", "Deutsch", "English", "Español", "Français", "Italiano", "Lietuvių", "Magyar", "Polski", "Português", "Português (Brasil)", "Русский", "Украïнська", "日本語" };
|
||||
@@ -70,19 +72,21 @@ static const std::vector<std::string> dirStrings = { "CHANGE_3DSX_PATH", "CHANGE
|
||||
static const std::vector<std::string> languages = { "Bruh", "Deutsch", "English", "Español", "Français", "Italiano", "Magyar", "Polski", "Português (Brasil)", "Русский", "Украïнська", "日本語" };
|
||||
static const std::string langsTemp[] = { "br", "de", "en", "es", "fr", "it", "hu", "pl", "pt-BR", "ru", "uk", "jp"};
|
||||
|
||||
static const std::vector<std::string> ThemeNames = { "THEME_DEFAULT" };
|
||||
|
||||
/*
|
||||
Main Settings.
|
||||
|
||||
int selection: The Settings Selection.
|
||||
*/
|
||||
static void DrawSettingsMain(int selection) {
|
||||
Gui::Draw_Rect(48, 0, 272, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(48, 25, 272, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(25, 2, 0.6, TEXT_COLOR, Lang::get("SETTINGS"), 265, 0, font);
|
||||
Gui::Draw_Rect(40, 0, 280, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(40, 25, 280, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
Gui::DrawStringCentered(20, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("SETTINGS"), 280, 0, font);
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
if (i == selection) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
|
||||
Gui::DrawStringCentered(30, mainButtons[i].y + 4, 0.45f, TEXT_COLOR, Lang::get(mainStrings[i]), 255, 0, font);
|
||||
if (i == selection) Gui::Draw_Rect(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, GFX::Themes[GFX::SelectedTheme].MarkSelected);
|
||||
Gui::DrawStringCentered(20, mainButtons[i].y + 4, 0.45f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get(mainStrings[i]), 255, 0, font);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,15 +97,15 @@ static void DrawSettingsMain(int selection) {
|
||||
int sPos: The Screen Position.
|
||||
*/
|
||||
static void DrawLanguageSettings(int selection, int sPos) {
|
||||
Gui::Draw_Rect(48, 0, 272, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(48, 25, 272, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(40, 0, 280, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(40, 25, 280, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
GFX::DrawSprite(sprites_arrow_idx, back.x, back.y);
|
||||
GFX::DrawSprite(sprites_add_font_idx, langButtons[6].x, langButtons[6].y);
|
||||
Gui::DrawStringCentered(32, 2, 0.6, TEXT_COLOR, Lang::get("SELECT_LANG"), 240, 0, font);
|
||||
Gui::DrawStringCentered(20, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("SELECT_LANG"), 248, 0, font);
|
||||
|
||||
for(int i = 0; i < 6 && i < (int)languages.size(); i++) {
|
||||
if (sPos + i == selection) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
|
||||
Gui::DrawStringCentered(30, mainButtons[i].y + 4, 0.45f, TEXT_COLOR, languages[sPos + i], 280, 0, font);
|
||||
if (sPos + i == selection) Gui::Draw_Rect(langButtons[i].x, langButtons[i].y, langButtons[i].w, langButtons[i].h, GFX::Themes[GFX::SelectedTheme].MarkSelected);
|
||||
Gui::DrawStringCentered(20, langButtons[i].y + 4, 0.45f, GFX::Themes[GFX::SelectedTheme].TextColor, languages[sPos + i], 280, 0, font);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,14 +115,14 @@ static void DrawLanguageSettings(int selection, int sPos) {
|
||||
int selection: The Settings Selection.
|
||||
*/
|
||||
static void DrawSettingsDir(int selection) {
|
||||
Gui::Draw_Rect(48, 0, 272, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(48, 25, 272, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(40, 0, 280, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(40, 25, 280, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
GFX::DrawSprite(sprites_arrow_idx, back.x, back.y);
|
||||
Gui::DrawStringCentered(32, 2, 0.6, TEXT_COLOR, Lang::get("DIRECTORY_SETTINGS"), 240, 0, font);
|
||||
Gui::DrawStringCentered(20, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("DIRECTORY_SETTINGS"), 248, 0, font);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i == selection) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
|
||||
Gui::DrawStringCentered(30, mainButtons[i].y + 4, 0.45f, TEXT_COLOR, Lang::get(dirStrings[i]), 255, 0, font);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == selection) Gui::Draw_Rect(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, GFX::Themes[GFX::SelectedTheme].MarkSelected);
|
||||
Gui::DrawStringCentered(20, mainButtons[i].y + 4, 0.45f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get(dirStrings[i]), 255, 0, font);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,22 +130,22 @@ static void DrawSettingsDir(int selection) {
|
||||
Draw Auto-Update Settings page.
|
||||
*/
|
||||
static void DrawAutoUpdate(int selection) {
|
||||
Gui::Draw_Rect(48, 0, 272, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(48, 25, 272, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(40, 0, 280, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(40, 25, 280, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
GFX::DrawSprite(sprites_arrow_idx, back.x, back.y);
|
||||
|
||||
Gui::DrawStringCentered(32, 2, 0.6, TEXT_COLOR, Lang::get("AUTO_UPDATE_SETTINGS"), 240, 0, font);
|
||||
Gui::DrawStringCentered(20, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("AUTO_UPDATE_SETTINGS"), 240, 0, font);
|
||||
|
||||
/* Toggle Boxes. */
|
||||
Gui::Draw_Rect(48, 64, 273, 24, (selection == 0 ? SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
Gui::DrawString(55, 68, 0.5f, TEXT_COLOR, Lang::get("AUTO_UPDATE_UNISTORE"), 210, 0, font);
|
||||
GFX::DrawToggle(288, 64, config->autoupdate());
|
||||
Gui::DrawString(55, 95, 0.4f, TEXT_COLOR, Lang::get("AUTO_UPDATE_UNISTORE_DESC"), 265, 0, font, C2D_WordWrap);
|
||||
Gui::Draw_Rect(40, 44, 280, 24, (selection == 0 ? GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
Gui::DrawString(47, 48, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("AUTO_UPDATE_UNISTORE"), 210, 0, font);
|
||||
GFX::DrawToggle(toggleAbles[0].x, toggleAbles[0].y, config->autoupdate());
|
||||
Gui::DrawString(47, 75, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("AUTO_UPDATE_UNISTORE_DESC"), 265, 0, font, C2D_WordWrap);
|
||||
|
||||
Gui::Draw_Rect(48, 140, 273, 24, (selection == 1 ? SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
Gui::DrawString(55, 144, 0.5f, TEXT_COLOR, Lang::get("AUTO_UPDATE_UU"), 210, 0, font);
|
||||
GFX::DrawToggle(288, 140, config->updatecheck());
|
||||
Gui::DrawString(55, 171, 0.4f, TEXT_COLOR, Lang::get("AUTO_UPDATE_UU_DESC"), 265, 0, font, C2D_WordWrap);
|
||||
Gui::Draw_Rect(40, 120, 280, 24, (selection == 1 ? GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
Gui::DrawString(47, 124, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("AUTO_UPDATE_UU"), 210, 0, font);
|
||||
GFX::DrawToggle(toggleAbles[1].x, toggleAbles[1].y, config->updatecheck());
|
||||
Gui::DrawString(47, 151, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("AUTO_UPDATE_UU_DESC"), 265, 0, font, C2D_WordWrap);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -150,21 +154,24 @@ static void DrawAutoUpdate(int selection) {
|
||||
int selection: The Settings Selection.
|
||||
*/
|
||||
static void DrawGUISettings(int selection) {
|
||||
Gui::Draw_Rect(48, 0, 272, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(48, 25, 272, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(40, 0, 280, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(40, 25, 280, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
GFX::DrawSprite(sprites_arrow_idx, back.x, back.y);
|
||||
|
||||
Gui::DrawStringCentered(32, 2, 0.6, TEXT_COLOR, Lang::get("GUI_SETTINGS"), 240, 0, font);
|
||||
Gui::DrawStringCentered(20, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("GUI_SETTINGS"), 248, 0, font);
|
||||
|
||||
Gui::Draw_Rect(48, 64, 273, 24, (selection == 0 ? SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
Gui::DrawString(55, 68, 0.5f, TEXT_COLOR, Lang::get("UNISTORE_BG"), 210, 0, font);
|
||||
GFX::DrawToggle(288, 64, config->usebg());
|
||||
Gui::DrawString(55, 95, 0.4f, TEXT_COLOR, Lang::get("UNISTORE_BG_DESC"), 265, 0, font, C2D_WordWrap);
|
||||
Gui::Draw_Rect(40, 44, 280, 24, (selection == 0 ? GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
Gui::DrawString(47, 48, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("UNISTORE_BG"), 210, 0, font);
|
||||
GFX::DrawToggle(toggleAbles[0].x, toggleAbles[0].y, config->usebg());
|
||||
Gui::DrawString(47, 75, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("UNISTORE_BG_DESC"), 265, 0, font, C2D_WordWrap);
|
||||
|
||||
Gui::Draw_Rect(48, 140, 273, 24, (selection == 1 ? SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
|
||||
Gui::DrawString(55, 144, 0.5f, TEXT_COLOR, Lang::get("CUSTOM_FONT"), 210, 0, font);
|
||||
GFX::DrawToggle(288, 140, config->customfont());
|
||||
Gui::DrawString(55, 171, 0.4f, TEXT_COLOR, Lang::get("CUSTOM_FONT_DESC"), 265, 0, font, C2D_WordWrap);
|
||||
Gui::Draw_Rect(40, 120, 280, 24, (selection == 1 ? GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
Gui::DrawString(47, 124, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("CUSTOM_FONT"), 210, 0, font);
|
||||
GFX::DrawToggle(toggleAbles[1].x, toggleAbles[1].y, config->customfont());
|
||||
Gui::DrawString(47, 151, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("CUSTOM_FONT_DESC"), 265, 0, font, C2D_WordWrap);
|
||||
|
||||
Gui::Draw_Rect(40, 196, 280, 24, (selection == 2 ? GFX::Themes[GFX::SelectedTheme].MarkSelected : GFX::Themes[GFX::SelectedTheme].MarkUnselected));
|
||||
Gui::DrawString(47, 200, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("ACTIVE_THEME") + ": " + Lang::get(ThemeNames[GFX::SelectedTheme]), 210, 0, font);
|
||||
}
|
||||
|
||||
|
||||
@@ -180,13 +187,10 @@ static void DrawGUISettings(int selection) {
|
||||
|
||||
int &page: Reference to the page.
|
||||
bool &dspSettings: Reference to the display Settings.
|
||||
int &storeMode: Reference to the Store Mode.
|
||||
int &storeMode: Reference to the store Mode.
|
||||
int &selection: Reference to the Selection.
|
||||
std::unique_ptr<Store> &store: Reference to the Store class.
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the StoreEntries.
|
||||
std::unique_ptr<Meta> &meta: Reference to the Meta class.
|
||||
*/
|
||||
static void SettingsHandleMain(int &page, bool &dspSettings, int &storeMode, int &selection, std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::unique_ptr<Meta> &meta) {
|
||||
static void SettingsHandleMain(int &page, bool &dspSettings, int &storeMode, int &selection) {
|
||||
if (hDown & KEY_B) {
|
||||
selection = 0;
|
||||
storeMode = 0;
|
||||
@@ -218,7 +222,12 @@ static void SettingsHandleMain(int &page, bool &dspSettings, int &storeMode, int
|
||||
page = 4;
|
||||
|
||||
} else if (touching(touch, mainButtons[1])) {
|
||||
Overlays::SelectStore(store, entries, meta);
|
||||
if (QueueRuns) {
|
||||
if (Msg::promptMsg(Lang::get("FEATURE_SIDE_EFFECTS"))) Overlays::SelectStore();
|
||||
|
||||
} else {
|
||||
Overlays::SelectStore();
|
||||
}
|
||||
|
||||
} else if (touching(touch, mainButtons[2])) {
|
||||
selection = 0;
|
||||
@@ -236,7 +245,8 @@ static void SettingsHandleMain(int &page, bool &dspSettings, int &storeMode, int
|
||||
Overlays::ShowCredits();
|
||||
|
||||
} else if (touching(touch, mainButtons[6])) {
|
||||
exiting = true;
|
||||
if (QueueRuns) exiting = Msg::promptMsg(Lang::get("FEATURE_SIDE_EFFECTS"));
|
||||
else exiting = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +258,12 @@ static void SettingsHandleMain(int &page, bool &dspSettings, int &storeMode, int
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Overlays::SelectStore(store, entries, meta);
|
||||
if (QueueRuns) {
|
||||
if (Msg::promptMsg(Lang::get("FEATURE_SIDE_EFFECTS"))) Overlays::SelectStore();
|
||||
|
||||
} else {
|
||||
Overlays::SelectStore();
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@@ -271,7 +286,8 @@ static void SettingsHandleMain(int &page, bool &dspSettings, int &storeMode, int
|
||||
break;
|
||||
|
||||
case 6:
|
||||
exiting = true;
|
||||
if (QueueRuns) exiting = Msg::promptMsg(Lang::get("FEATURE_SIDE_EFFECTS"));
|
||||
else exiting = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -287,14 +303,14 @@ static void SettingsHandleMain(int &page, bool &dspSettings, int &storeMode, int
|
||||
int &page: Reference to the page.
|
||||
int &selection: Reference to the Selection.
|
||||
*/
|
||||
static void SettingsHandleDir(int &page, int &selection, const std::unique_ptr<Store> &store) {
|
||||
static void SettingsHandleDir(int &page, int &selection) {
|
||||
if (hDown & KEY_B) {
|
||||
page = 0;
|
||||
selection = 4;
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_DOWN) {
|
||||
if (selection < 3) selection++;
|
||||
if (selection < 4) selection++;
|
||||
else selection = 0;
|
||||
}
|
||||
|
||||
@@ -319,20 +335,24 @@ static void SettingsHandleDir(int &page, int &selection, const std::unique_ptr<S
|
||||
selection = 4;
|
||||
|
||||
} else if (touching(touch, mainButtons[0])) {
|
||||
const std::string path = Overlays::SelectDir(config->_3dsxPath(), Lang::get("SELECT_DIR"), store);
|
||||
const std::string path = Overlays::SelectDir(config->_3dsxPath(), Lang::get("SELECT_DIR"));
|
||||
if (path != "") config->_3dsxPath(path);
|
||||
|
||||
} else if (touching(touch, mainButtons[1])) {
|
||||
const std::string path = Overlays::SelectDir(config->ndsPath(), Lang::get("SELECT_DIR"), store);
|
||||
const std::string path = Overlays::SelectDir(config->ndsPath(), Lang::get("SELECT_DIR"));
|
||||
if (path != "") config->ndsPath(path);
|
||||
|
||||
} else if (touching(touch, mainButtons[2])) {
|
||||
const std::string path = Overlays::SelectDir(config->archPath(), Lang::get("SELECT_DIR"), store);
|
||||
const std::string path = Overlays::SelectDir(config->archPath(), Lang::get("SELECT_DIR"));
|
||||
if (path != "") config->archPath(path);
|
||||
|
||||
} else if (touching(touch, mainButtons[3])) {
|
||||
const std::string path = Overlays::SelectDir(config->shortcut(), Lang::get("SELECT_DIR"), store);
|
||||
const std::string path = Overlays::SelectDir(config->shortcut(), Lang::get("SELECT_DIR"));
|
||||
if (path != "") config->shortcut(path);
|
||||
|
||||
} else if (touching(touch, mainButtons[4])) {
|
||||
const std::string path = Overlays::SelectDir(config->firmPath(), Lang::get("SELECT_DIR"));
|
||||
if (path != "") config->firmPath(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,24 +361,29 @@ static void SettingsHandleDir(int &page, int &selection, const std::unique_ptr<S
|
||||
|
||||
switch(selection) {
|
||||
case 0:
|
||||
path = Overlays::SelectDir(config->_3dsxPath(), Lang::get("SELECT_DIR"), store);
|
||||
path = Overlays::SelectDir(config->_3dsxPath(), Lang::get("SELECT_DIR"));
|
||||
if (path != "") config->_3dsxPath(path);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
path = Overlays::SelectDir(config->ndsPath(), Lang::get("SELECT_DIR"), store);
|
||||
path = Overlays::SelectDir(config->ndsPath(), Lang::get("SELECT_DIR"));
|
||||
if (path != "") config->ndsPath(path);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
path = Overlays::SelectDir(config->archPath(), Lang::get("SELECT_DIR"), store);
|
||||
path = Overlays::SelectDir(config->archPath(), Lang::get("SELECT_DIR"));
|
||||
if (path != "") config->archPath(path);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
path = Overlays::SelectDir(config->shortcut(), Lang::get("SELECT_DIR"), store);
|
||||
path = Overlays::SelectDir(config->shortcut(), Lang::get("SELECT_DIR"));
|
||||
if (path != "") config->shortcut(path);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
path = Overlays::SelectDir(config->firmPath(), Lang::get("SELECT_DIR"));
|
||||
if (path != "") config->firmPath(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -431,7 +456,7 @@ static void GUISettingsLogic(int &page, int &selection) {
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_DOWN) {
|
||||
if (selection < 1) selection++;
|
||||
if (selection < 2) selection++;
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_UP) {
|
||||
@@ -450,6 +475,12 @@ static void GUISettingsLogic(int &page, int &selection) {
|
||||
config->customfont(!config->customfont());
|
||||
|
||||
(config->customfont() ? Init::LoadFont() : Init::UnloadFont());
|
||||
|
||||
} else if (touching(touch, Themes)) {
|
||||
if (GFX::SelectedTheme < (_THEME_AMOUNT - 1)) GFX::SelectedTheme++;
|
||||
else GFX::SelectedTheme = 0;
|
||||
|
||||
config->theme(GFX::SelectedTheme);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,6 +495,13 @@ static void GUISettingsLogic(int &page, int &selection) {
|
||||
|
||||
(config->customfont() ? Init::LoadFont() : Init::UnloadFont());
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (GFX::SelectedTheme < (_THEME_AMOUNT - 1)) GFX::SelectedTheme++;
|
||||
else GFX::SelectedTheme = 0;
|
||||
|
||||
config->theme(GFX::SelectedTheme);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -555,7 +593,7 @@ static void LanguageLogic(int &page, int &selection, int &sPos) {
|
||||
if (hDown & KEY_TOUCH) {
|
||||
if (touching(touch, langButtons[6])) {
|
||||
/* Download Font. */
|
||||
ScriptUtils::downloadFile("https://github.com/Universal-Team/extras/raw/master/files/universal-updater.bcfnt", "sdmc:/3ds/Universal-Updater/font.bcfnt", Lang::get("DOWNLOADING_COMPATIBLE_FONT"));
|
||||
ScriptUtils::downloadFile("https://github.com/Universal-Team/extras/raw/master/files/universal-updater.bcfnt", "sdmc:/3ds/Universal-Updater/font.bcfnt", Lang::get("DOWNLOADING_COMPATIBLE_FONT"), true);
|
||||
config->customfont(true);
|
||||
Init::LoadFont();
|
||||
}
|
||||
@@ -600,20 +638,18 @@ void StoreUtils::DrawSettings(int page, int selection, int sPos) {
|
||||
|
||||
int &page: Reference to the page.
|
||||
bool &dspSettings: Reference to the display Settings.
|
||||
int &storeMode: Reference to the Store Mode.
|
||||
int &storeMode: Reference to the store Mode.
|
||||
int &selection: Reference to the Selection.
|
||||
std::unique_ptr<Store> &store: Reference to the Store class.
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the StoreEntries.
|
||||
std::unique_ptr<Meta> &meta: Reference to the Meta class.
|
||||
int &sPos: Reference to screen position.
|
||||
*/
|
||||
void StoreUtils::SettingsHandle(int &page, bool &dspSettings, int &storeMode, int &selection, std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::unique_ptr<Meta> &meta, int &sPos) {
|
||||
void StoreUtils::SettingsHandle(int &page, bool &dspSettings, int &storeMode, int &selection, int &sPos) {
|
||||
switch(page) {
|
||||
case 0:
|
||||
SettingsHandleMain(page, dspSettings, storeMode, selection, store, entries, meta);
|
||||
SettingsHandleMain(page, dspSettings, storeMode, selection);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
SettingsHandleDir(page, selection, store);
|
||||
SettingsHandleDir(page, selection);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,40 +24,44 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "common.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
|
||||
extern bool touching(touchPosition touch, Structs::ButtonPos button);
|
||||
static const std::vector<Structs::ButtonPos> sidePos = {
|
||||
{ 0, 0, 48, 48 },
|
||||
{ 0, 48, 48, 48 },
|
||||
{ 0, 96, 48, 48 },
|
||||
{ 0, 144, 48, 48 },
|
||||
{ 0, 192, 48, 48 }
|
||||
{ 0, 0, 40, 40 },
|
||||
{ 0, 40, 40, 40 },
|
||||
{ 0, 80, 40, 40 },
|
||||
{ 0, 120, 40, 40 },
|
||||
{ 0, 160, 40, 40 },
|
||||
{ 0, 200, 40, 40 }
|
||||
};
|
||||
|
||||
/*
|
||||
Draw the Side Menu part.
|
||||
|
||||
int currentMenu: The current Store Mode / Menu.
|
||||
int currentMenu: The current store Mode / Menu.
|
||||
*/
|
||||
void StoreUtils::DrawSideMenu(int currentMenu) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (i == currentMenu) {
|
||||
Gui::Draw_Rect(sidePos[i].x, sidePos[i].y, sidePos[i].w, sidePos[i].h, SIDEBAR_SELECTED_COLOR);
|
||||
Gui::Draw_Rect(sidePos[i].x, sidePos[i].y, sidePos[i].w, sidePos[i].h, GFX::Themes[GFX::SelectedTheme].SideBarSelected);
|
||||
|
||||
} else {
|
||||
Gui::Draw_Rect(sidePos[i].x, sidePos[i].y, sidePos[i].w, sidePos[i].h, SIDEBAR_UNSELECTED_COLOR);
|
||||
Gui::Draw_Rect(sidePos[i].x, sidePos[i].y, sidePos[i].w, sidePos[i].h, GFX::Themes[GFX::SelectedTheme].SideBarUnselected);
|
||||
}
|
||||
}
|
||||
|
||||
GFX::DrawSprite(sprites_info_idx, sidePos[0].x + 4, sidePos[0].y + 4);
|
||||
GFX::DrawSprite(sprites_download_idx, sidePos[1].x + 4, sidePos[1].y + 4);
|
||||
GFX::DrawSprite(sprites_search_idx, sidePos[2].x + 4, sidePos[2].y + 4);
|
||||
GFX::DrawSprite(sprites_sort_idx, sidePos[3].x + 4, sidePos[3].y + 4);
|
||||
GFX::DrawSprite(sprites_settings_idx, sidePos[4].x + 4, sidePos[4].y + 4);
|
||||
GFX::DrawSprite(sprites_info_idx, sidePos[0].x, sidePos[0].y);
|
||||
GFX::DrawSprite(sprites_download_idx, sidePos[1].x, sidePos[1].y);
|
||||
Animation::DrawQueue(sidePos[2].x, sidePos[2].y);
|
||||
GFX::DrawSprite(sprites_search_idx, sidePos[3].x, sidePos[3].y);
|
||||
GFX::DrawSprite(sprites_sort_idx, sidePos[4].x, sidePos[4].y);
|
||||
GFX::DrawSprite(sprites_settings_idx, sidePos[5].x, sidePos[5].y);
|
||||
|
||||
Gui::Draw_Rect(48, 0, 1, 240, BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(40, 0, 1, 240, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -66,13 +70,15 @@ void StoreUtils::DrawSideMenu(int currentMenu) {
|
||||
|
||||
- Switch between the Menus through the sidebar.
|
||||
|
||||
int ¤tMenu: Reference to the Store Mode / Menu.
|
||||
int ¤tMenu: Reference to the store Mode / Menu.
|
||||
bool &fetch: Reference of the download fetch variable.. so we know, if we need to fetch the download entries.
|
||||
int &lastMenu: Reference to the last menu.
|
||||
*/
|
||||
void StoreUtils::SideMenuHandle(int ¤tMenu, bool &fetch, int &lastMenu) {
|
||||
Animation::QueueAnimHandle();
|
||||
|
||||
if (hDown & KEY_TOUCH) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (touching(touch, sidePos[i])) {
|
||||
lastMenu = currentMenu;
|
||||
if (i == 1) fetch = true; // Fetch download list, if 1.
|
||||
@@ -83,7 +89,7 @@ void StoreUtils::SideMenuHandle(int ¤tMenu, bool &fetch, int &lastMenu) {
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_R) {
|
||||
if (currentMenu < 4) {
|
||||
if (currentMenu < 5) {
|
||||
lastMenu = currentMenu;
|
||||
if (currentMenu + 1 == 1) fetch = true; // Fetch download list, if 1.
|
||||
currentMenu++;
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,6 +24,7 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "keyboard.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
@@ -31,19 +32,19 @@
|
||||
extern bool touching(touchPosition touch, Structs::ButtonPos button);
|
||||
|
||||
static const std::vector<Structs::ButtonPos> buttons = {
|
||||
{ 75, 60, 100, 16 },
|
||||
{ 75, 80, 100, 16 },
|
||||
{ 75, 100, 100, 16 },
|
||||
{ 71, 60, 104, 16 },
|
||||
{ 71, 80, 104, 16 },
|
||||
{ 71, 100, 104, 16 },
|
||||
|
||||
{ 205, 60, 100, 16 },
|
||||
{ 205, 80, 100, 16 },
|
||||
{ 201, 60, 104, 16 },
|
||||
{ 201, 80, 104, 16 },
|
||||
|
||||
{ 75, 170, 100, 16 },
|
||||
{ 75, 190, 100, 16 }
|
||||
{ 71, 170, 104, 16 },
|
||||
{ 71, 190, 104, 16 }
|
||||
};
|
||||
|
||||
static void DrawCheck(int pos, bool v) {
|
||||
GFX::DrawSprite((v ? sprites_sort_checked_idx : sprites_sort_unchecked_idx), buttons[pos].x + 5, buttons[pos].y);
|
||||
GFX::DrawSprite((v ? sprites_sort_checked_idx : sprites_sort_unchecked_idx), buttons[pos].x + 1, buttons[pos].y);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -73,89 +74,87 @@ static const uint8_t GetType(SortType st) {
|
||||
SortType st: The SortType variable.
|
||||
*/
|
||||
void StoreUtils::DrawSorting(bool asc, SortType st) {
|
||||
Gui::Draw_Rect(48, 0, 272, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(48, 25, 272, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(25, 2, 0.6, TEXT_COLOR, Lang::get("SORTING"), 265, 0, font);
|
||||
Gui::Draw_Rect(40, 0, 280, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(40, 25, 280, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
Gui::DrawStringCentered(17, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("SORTING"), 273, 0, font);
|
||||
|
||||
/* Sort By. */
|
||||
Gui::DrawString(buttons[0].x + 5, buttons[0].y - 20, 0.6f, TEXT_COLOR, Lang::get("SORT_BY"), 90, 0, font);
|
||||
Gui::DrawString(buttons[0].x + 1, buttons[0].y - 20, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("SORT_BY"), 90, 0, font);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
DrawCheck(i, i == GetType(st));
|
||||
}
|
||||
|
||||
Gui::DrawString(buttons[0].x + 25, buttons[0].y + 2, 0.4f, TEXT_COLOR, Lang::get("TITLE"), 80, 0, font);
|
||||
Gui::DrawString(buttons[1].x + 25, buttons[1].y + 2, 0.4f, TEXT_COLOR, Lang::get("AUTHOR"), 80, 0, font);
|
||||
Gui::DrawString(buttons[2].x + 25, buttons[2].y + 2, 0.4f, TEXT_COLOR, Lang::get("LAST_UPDATED"), 80, 0, font);
|
||||
Gui::DrawString(buttons[0].x + 21, buttons[0].y + 2, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("TITLE"), 80, 0, font);
|
||||
Gui::DrawString(buttons[1].x + 21, buttons[1].y + 2, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("AUTHOR"), 80, 0, font);
|
||||
Gui::DrawString(buttons[2].x + 21, buttons[2].y + 2, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("LAST_UPDATED"), 80, 0, font);
|
||||
|
||||
/* Direction. */
|
||||
Gui::DrawString(buttons[3].x + 5, buttons[3].y - 20, 0.6f, TEXT_COLOR, Lang::get("DIRECTION"), 80, 0, font);
|
||||
Gui::DrawString(buttons[3].x + 1, buttons[3].y - 20, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("DIRECTION"), 80, 0, font);
|
||||
DrawCheck(3, asc);
|
||||
DrawCheck(4, !asc);
|
||||
Gui::DrawString(buttons[3].x + 25, buttons[3].y + 2, 0.4f, TEXT_COLOR, Lang::get("ASCENDING"), 80, 0, font);
|
||||
Gui::DrawString(buttons[4].x + 25, buttons[4].y + 2, 0.4f, TEXT_COLOR, Lang::get("DESCENDING"), 80, 0, font);
|
||||
Gui::DrawString(buttons[3].x + 21, buttons[3].y + 2, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("ASCENDING"), 80, 0, font);
|
||||
Gui::DrawString(buttons[4].x + 21, buttons[4].y + 2, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("DESCENDING"), 80, 0, font);
|
||||
|
||||
/* Top Style. */
|
||||
Gui::DrawString(buttons[5].x + 5, buttons[5].y - 20, 0.6f, TEXT_COLOR, Lang::get("TOP_STYLE"), 90, 0, font);
|
||||
Gui::DrawString(buttons[5].x + 1, buttons[5].y - 20, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("TOP_STYLE"), 90, 0, font);
|
||||
DrawCheck(5, config->list());
|
||||
DrawCheck(6, !config->list());
|
||||
Gui::DrawString(buttons[5].x + 25, buttons[5].y + 2, 0.4f, TEXT_COLOR, Lang::get("LIST"), 90, 0, font);
|
||||
Gui::DrawString(buttons[6].x + 25, buttons[6].y + 2, 0.4f, TEXT_COLOR, Lang::get("GRID"), 90, 0, font);
|
||||
Gui::DrawString(buttons[5].x + 21, buttons[5].y + 2, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("LIST"), 90, 0, font);
|
||||
Gui::DrawString(buttons[6].x + 21, buttons[6].y + 2, 0.4f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("GRID"), 90, 0, font);
|
||||
}
|
||||
|
||||
/*
|
||||
Sort Handle.
|
||||
Here you can..
|
||||
|
||||
- Sort your Entries to..
|
||||
- Sort your entries to..
|
||||
- Title (Ascending / Descending).
|
||||
- Author (Ascending / Descending).
|
||||
- Last Updated Date (Ascending / Descending).
|
||||
|
||||
- Change the Top Style.
|
||||
|
||||
std::unique_ptr<Store> &store: Reference to the Store class.
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the StoreEntries.
|
||||
bool &asc: Reference to the Ascending variable.
|
||||
SortType &st: Reference to the SortType.
|
||||
*/
|
||||
void StoreUtils::SortHandle(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, bool &asc, SortType &st) {
|
||||
if (store && store->GetValid() && entries.size() > 0) { // Ensure, this is valid and more than 0 entries exist.
|
||||
void StoreUtils::SortHandle(bool &asc, SortType &st) {
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid() && StoreUtils::entries.size() > 0) { // Ensure, this is valid and more than 0 StoreUtils::entries exist.
|
||||
if (hDown & KEY_TOUCH) {
|
||||
/* SortType Part. */
|
||||
if (touching(touch, buttons[0])) {
|
||||
st = SortType::TITLE;
|
||||
StoreUtils::SortEntries(asc, st, entries);
|
||||
StoreUtils::SortEntries(asc, st);
|
||||
|
||||
} else if (touching(touch, buttons[1])) {
|
||||
st = SortType::AUTHOR;
|
||||
StoreUtils::SortEntries(asc, st, entries);
|
||||
StoreUtils::SortEntries(asc, st);
|
||||
|
||||
} else if (touching(touch, buttons[2])) {
|
||||
st = SortType::LAST_UPDATED;
|
||||
StoreUtils::SortEntries(asc, st, entries);
|
||||
StoreUtils::SortEntries(asc, st);
|
||||
|
||||
/* Ascending | Descending Part. */
|
||||
} else if (touching(touch, buttons[3])) {
|
||||
asc = true;
|
||||
StoreUtils::SortEntries(asc, st, entries);
|
||||
StoreUtils::SortEntries(asc, st);
|
||||
|
||||
} else if (touching(touch, buttons[4])) {
|
||||
asc = false;
|
||||
StoreUtils::SortEntries(asc, st, entries);
|
||||
StoreUtils::SortEntries(asc, st);
|
||||
|
||||
} else if (touching(touch, buttons[5])) {
|
||||
if (config->list()) return;
|
||||
config->list(true);
|
||||
store->SetEntry(0);
|
||||
store->SetScreenIndx(0);
|
||||
store->SetBox(0);
|
||||
StoreUtils::store->SetEntry(0);
|
||||
StoreUtils::store->SetScreenIndx(0);
|
||||
StoreUtils::store->SetBox(0);
|
||||
|
||||
} else if (touching(touch, buttons[6])) {
|
||||
if (!config->list()) return;
|
||||
config->list(false);
|
||||
store->SetEntry(0);
|
||||
store->SetScreenIndx(0);
|
||||
store->SetBox(0);
|
||||
StoreUtils::store->SetEntry(0);
|
||||
StoreUtils::store->SetScreenIndx(0);
|
||||
StoreUtils::store->SetBox(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,11 +24,12 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "common.hpp"
|
||||
#include "overlay.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
/*
|
||||
Show the Credits.
|
||||
*/
|
||||
/* Show the Credits. */
|
||||
void Overlays::ShowCredits() {
|
||||
bool doOut = false;
|
||||
|
||||
@@ -40,27 +41,29 @@ void Overlays::ShowCredits() {
|
||||
|
||||
GFX::DrawTop();
|
||||
GFX::DrawSprite(sprites_universal_updater_idx, 220, 26);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, "Universal-Updater - " + Lang::get("CREDITS"), 395, 0, font);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, "Universal-Updater - " + Lang::get("CREDITS"), 395, 0, font);
|
||||
|
||||
Gui::DrawString(10, 30, 0.5f, TEXT_COLOR, "- Universal-Team", 0, 0, font);
|
||||
Gui::DrawString(10, 50, 0.5f, TEXT_COLOR, "- devkitPro", 0, 0, font);
|
||||
Gui::DrawString(10, 70, 0.5f, TEXT_COLOR, "- dlbeer", 0, 0, font);
|
||||
Gui::DrawString(10, 90, 0.5f, TEXT_COLOR, "- FlagBrew", 0, 0, font);
|
||||
Gui::DrawString(10, 110, 0.5f, TEXT_COLOR, "- https://icons8.com/", 0, 0, font);
|
||||
Gui::DrawString(10, 130, 0.5f, TEXT_COLOR, "- Ivandeve", 0, 0, font);
|
||||
Gui::DrawString(10, 150, 0.5f, TEXT_COLOR, "- PabloMK7", 0, 0, font);
|
||||
Gui::DrawString(10, 170, 0.5f, TEXT_COLOR, Lang::get("CONTRIBUTOR_TRANSLATORS"), 210, 0, font);
|
||||
Gui::DrawString(10, 197, 0.5f, TEXT_COLOR, Lang::get("GITHUB"), 390, 0, font);
|
||||
Gui::DrawString(10, 30, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "- Universal-Team", 0, 0, font);
|
||||
Gui::DrawString(10, 50, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "- devkitPro", 0, 0, font);
|
||||
Gui::DrawString(10, 70, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "- dlbeer", 0, 0, font);
|
||||
Gui::DrawString(10, 90, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "- FlagBrew", 0, 0, font);
|
||||
Gui::DrawString(10, 110, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "- https://icons8.com/", 0, 0, font);
|
||||
Gui::DrawString(10, 130, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "- Ivandeve", 0, 0, font);
|
||||
Gui::DrawString(10, 150, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, "- PabloMK7", 0, 0, font);
|
||||
Gui::DrawString(10, 170, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("CONTRIBUTOR_TRANSLATORS"), 210, 0, font);
|
||||
Gui::DrawString(10, 197, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("GITHUB"), 390, 0, font);
|
||||
|
||||
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 218, 0.6f, TEXT_COLOR, Lang::get("CURRENT_VERSION") + std::string(V_STRING), 390, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 218, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("CURRENT_VERSION") + std::string(VER_NUMBER), 390, 0, font);
|
||||
|
||||
Animation::QueueEntryDone();
|
||||
GFX::DrawBottom();
|
||||
GFX::DrawSprite(sprites_universal_core_idx, 0, 26);
|
||||
C3D_FrameEnd(0);
|
||||
|
||||
hidScanInput();
|
||||
Animation::HandleQueueEntryDone();
|
||||
if ((hidKeysDown() & KEY_START) || (hidKeysDown() & KEY_B) || (hidKeysDown() & KEY_A)) doOut = true;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,8 +24,11 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "common.hpp"
|
||||
#include "fileBrowse.hpp"
|
||||
#include "overlay.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include <unistd.h>
|
||||
|
||||
extern bool touching(touchPosition touch, Structs::ButtonPos button);
|
||||
@@ -39,10 +42,8 @@ static const std::vector<Structs::ButtonPos> mainButtons = {
|
||||
{ 10, 186, 300, 22 }
|
||||
};
|
||||
|
||||
/*
|
||||
Select a Directory.
|
||||
*/
|
||||
std::string Overlays::SelectDir(const std::string &oldDir, const std::string &msg, const std::unique_ptr<Store> &store) {
|
||||
/* Select a Directory. */
|
||||
std::string Overlays::SelectDir(const std::string &oldDir, const std::string &msg) {
|
||||
std::string currentPath = oldDir;
|
||||
bool dirChanged = false;
|
||||
int selection = 0, sPos = 0;
|
||||
@@ -72,32 +73,33 @@ std::string Overlays::SelectDir(const std::string &oldDir, const std::string &ms
|
||||
C2D_TargetClear(Top, TRANSPARENT);
|
||||
C2D_TargetClear(Bottom, TRANSPARENT);
|
||||
|
||||
if (store && config->usebg() && store->customBG()) {
|
||||
if (StoreUtils::store && config->usebg() && StoreUtils::store->customBG()) {
|
||||
Gui::ScreenDraw(Top);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
|
||||
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
C2D_DrawImageAt(StoreUtils::store->GetStoreImg(), 0, 26, 0.5f, nullptr);
|
||||
|
||||
} else {
|
||||
GFX::DrawTop();
|
||||
}
|
||||
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, msg, 380, 0, font);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, msg, 380, 0, font);
|
||||
|
||||
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 217, 0.6f, TEXT_COLOR, currentPath, 390, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 217, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, currentPath, 390, 0, font);
|
||||
|
||||
Animation::QueueEntryDone();
|
||||
GFX::DrawBottom();
|
||||
|
||||
Gui::Draw_Rect(0, 215, 320, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 214, 320, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 220, 0.5f, TEXT_COLOR, Lang::get("START_SELECT"), 310, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 320, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 214, 320, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 220, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("START_SELECT"), 310, 0, font);
|
||||
|
||||
if (dirContents.size() > 0) {
|
||||
for(int i = 0; i < 7 && i < (int)dirContents.size(); i++) {
|
||||
if (sPos + i == selection) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
|
||||
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, TEXT_COLOR, dirContents[sPos + i].name, 295, 0, font);
|
||||
if (sPos + i == selection) Gui::Draw_Rect(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, GFX::Themes[GFX::SelectedTheme].MarkSelected);
|
||||
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, GFX::Themes[GFX::SelectedTheme].TextColor, dirContents[sPos + i].name, 295, 0, font);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +124,7 @@ std::string Overlays::SelectDir(const std::string &oldDir, const std::string &ms
|
||||
touchPosition touch;
|
||||
hidTouchRead(&touch);
|
||||
u32 hRepeat = hidKeysDownRepeat();
|
||||
Animation::HandleQueueEntryDone();
|
||||
|
||||
if (dirContents.size() > 0) {
|
||||
if (hRepeat & KEY_DOWN) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,6 +24,8 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "common.hpp"
|
||||
#include "download.hpp"
|
||||
#include "fileBrowse.hpp"
|
||||
#include "files.hpp"
|
||||
@@ -52,7 +54,7 @@ static const std::vector<Structs::ButtonPos> mainButtons = {
|
||||
};
|
||||
|
||||
/*
|
||||
Delete a Store.. including the Spritesheets, if found.
|
||||
Delete a store.. including the Spritesheets, if found.
|
||||
|
||||
const std::string &file: The file of the UniStore.
|
||||
*/
|
||||
@@ -93,7 +95,7 @@ static void DeleteStore(const std::string &file) {
|
||||
}
|
||||
|
||||
/*
|
||||
Download a Store.. including the SpriteSheets, if found.
|
||||
Download a store.. including the SpriteSheets, if found.
|
||||
*/
|
||||
static bool DownloadStore() {
|
||||
bool doSheet = false;
|
||||
@@ -209,12 +211,8 @@ static bool UpdateStore(const std::string &URL) {
|
||||
- Download / Add a UniStore.
|
||||
- Check for Updates for a UniStore.
|
||||
- Switch the UniStore.
|
||||
|
||||
std::unique_ptr<Store> &store: Reference to the Store class.
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the Store Entries.
|
||||
std::unique_ptr<Meta> &meta: Reference to the Meta class.
|
||||
*/
|
||||
void Overlays::SelectStore(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::unique_ptr<Meta> &meta) {
|
||||
void Overlays::SelectStore() {
|
||||
bool doOut = false;
|
||||
int selection = 0, sPos = 0;
|
||||
|
||||
@@ -226,11 +224,11 @@ void Overlays::SelectStore(std::unique_ptr<Store> &store, std::vector<std::uniqu
|
||||
C2D_TargetClear(Top, TRANSPARENT);
|
||||
C2D_TargetClear(Bottom, TRANSPARENT);
|
||||
|
||||
if (store && config->usebg() && store->customBG()) {
|
||||
if (StoreUtils::store && config->usebg() && StoreUtils::store->customBG()) {
|
||||
Gui::ScreenDraw(Top);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
|
||||
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
C2D_DrawImageAt(StoreUtils::store->GetStoreImg(), 0, 26, 0.5f, nullptr);
|
||||
|
||||
} else {
|
||||
GFX::DrawTop();
|
||||
@@ -238,29 +236,29 @@ void Overlays::SelectStore(std::unique_ptr<Store> &store, std::vector<std::uniqu
|
||||
|
||||
if (info.size() > 0) {
|
||||
if (info[selection].StoreSize != -1) {
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, info[selection].Title, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 30, 0.6f, TEXT_COLOR, info[selection].Author, 380, 0, font);
|
||||
Gui::DrawStringCentered(0, 70, 0.5f, TEXT_COLOR, info[selection].Description, 380, 130, font, C2D_WordWrap);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, info[selection].Title, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 30, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, info[selection].Author, 380, 0, font);
|
||||
Gui::DrawStringCentered(0, 70, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, info[selection].Description, 380, 130, font, C2D_WordWrap);
|
||||
|
||||
} else {
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, Lang::get("INVALID_UNISTORE"), 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("INVALID_UNISTORE"), 390, 0, font);
|
||||
}
|
||||
|
||||
Gui::DrawString(10, 200, 0.4, TEXT_COLOR, "- " + Lang::get("ENTRIES") + ": " + std::to_string(info[selection].StoreSize), 150, 0, font);
|
||||
Gui::DrawString(10, 210, 0.4, TEXT_COLOR, "- " + Lang::get("VERSION") + ": " + std::to_string(info[selection].Version), 150, 0, font);
|
||||
Gui::DrawString(10, 220, 0.4, TEXT_COLOR, "- " + Lang::get("REVISION") + ": " + std::to_string(info[selection].Revision), 150, 0, font);
|
||||
Gui::DrawString(10, 200, 0.4, GFX::Themes[GFX::SelectedTheme].TextColor, "- " + Lang::get("ENTRIES") + ": " + std::to_string(info[selection].StoreSize), 150, 0, font);
|
||||
Gui::DrawString(10, 210, 0.4, GFX::Themes[GFX::SelectedTheme].TextColor, "- " + Lang::get("VERSION") + ": " + std::to_string(info[selection].Version), 150, 0, font);
|
||||
Gui::DrawString(10, 220, 0.4, GFX::Themes[GFX::SelectedTheme].TextColor, "- " + Lang::get("REVISION") + ": " + std::to_string(info[selection].Revision), 150, 0, font);
|
||||
|
||||
Animation::QueueEntryDone();
|
||||
GFX::DrawBottom();
|
||||
|
||||
Gui::Draw_Rect(0, 0, 320, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 320, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(0, 0, 320, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 25, 320, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
GFX::DrawSprite(sprites_arrow_idx, mainButtons[9].x, mainButtons[9].y);
|
||||
Gui::DrawStringCentered(0, 2, 0.6, TEXT_COLOR, Lang::get("SELECT_UNISTORE_2"), 310, 0, font);
|
||||
Gui::DrawStringCentered(0, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("SELECT_UNISTORE_2"), 310, 0, font);
|
||||
|
||||
for(int i = 0; i < 6 && i < (int)info.size(); i++) {
|
||||
if (sPos + i == selection) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
|
||||
|
||||
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, TEXT_COLOR, info[sPos + i].FileName, 295, 0, font);
|
||||
if (sPos + i == selection) Gui::Draw_Rect(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, GFX::Themes[GFX::SelectedTheme].MarkSelected);
|
||||
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, GFX::Themes[GFX::SelectedTheme].TextColor, info[sPos + i].FileName, 295, 0, font);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,6 +273,7 @@ void Overlays::SelectStore(std::unique_ptr<Store> &store, std::vector<std::uniqu
|
||||
touchPosition touch;
|
||||
hidTouchRead(&touch);
|
||||
u32 hRepeat = hidKeysDownRepeat();
|
||||
Animation::HandleQueueEntryDone();
|
||||
|
||||
if (info.size() > 0) {
|
||||
if (hRepeat & KEY_DOWN) {
|
||||
@@ -306,9 +305,9 @@ void Overlays::SelectStore(std::unique_ptr<Store> &store, std::vector<std::uniqu
|
||||
else if (info[selection].Version > _UNISTORE_VERSION) Msg::waitMsg(Lang::get("UNISTORE_TOO_NEW"));
|
||||
else {
|
||||
config->lastStore(info[selection].FileName);
|
||||
store = std::make_unique<Store>(_STORE_PATH + info[selection].FileName, info[selection].FileName);
|
||||
StoreUtils::ResetAll(store, meta, entries);
|
||||
StoreUtils::SortEntries(false, SortType::LAST_UPDATED, entries);
|
||||
StoreUtils::store = std::make_unique<Store>(_STORE_PATH + info[selection].FileName, info[selection].FileName);
|
||||
StoreUtils::ResetAll();
|
||||
StoreUtils::SortEntries(false, SortType::LAST_UPDATED);
|
||||
doOut = true;
|
||||
}
|
||||
|
||||
@@ -328,9 +327,9 @@ void Overlays::SelectStore(std::unique_ptr<Store> &store, std::vector<std::uniqu
|
||||
else if (info[i + sPos].Version > _UNISTORE_VERSION) Msg::waitMsg(Lang::get("UNISTORE_TOO_NEW"));
|
||||
else {
|
||||
config->lastStore(info[i + sPos].FileName);
|
||||
store = std::make_unique<Store>(_STORE_PATH + info[i + sPos].FileName, info[i + sPos].FileName);
|
||||
StoreUtils::ResetAll(store, meta, entries);
|
||||
StoreUtils::SortEntries(false, SortType::LAST_UPDATED, entries);
|
||||
StoreUtils::store = std::make_unique<Store>(_STORE_PATH + info[i + sPos].FileName, info[i + sPos].FileName);
|
||||
StoreUtils::ResetAll();
|
||||
StoreUtils::SortEntries(false, SortType::LAST_UPDATED);
|
||||
doOut = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -152,28 +152,27 @@ void QRCode::drawThread() {
|
||||
C2D_DrawImageAt(this->image, 0, 0, 0.5, nullptr, 1.0f, 1.0f);
|
||||
|
||||
GFX::DrawBottom();
|
||||
Gui::Draw_Rect(0, 0, 320, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 320, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(0, 0, 320, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(0, 25, 320, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
|
||||
} else {
|
||||
GFX::DrawTop();
|
||||
Gui::DrawStringCentered(0, 1, 0.7, TEXT_COLOR, Lang::get("STORE_INFO"), 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 1, 0.7, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("STORE_INFO"), 390, 0, font);
|
||||
|
||||
if (this->stores.size() > 0) {
|
||||
Gui::DrawStringCentered(0, 30, 0.7f, TEXT_COLOR, this->stores[this->selectedStore].Title, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 50, 0.6f, TEXT_COLOR, this->stores[this->selectedStore].Author, 380, 0, font);
|
||||
Gui::DrawStringCentered(0, 90, 0.5f, TEXT_COLOR, this->stores[this->selectedStore].Description, 380, 130, font, C2D_WordWrap);
|
||||
Gui::DrawStringCentered(0, 30, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, this->stores[this->selectedStore].Title, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 50, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, this->stores[this->selectedStore].Author, 380, 0, font);
|
||||
Gui::DrawStringCentered(0, 90, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, this->stores[this->selectedStore].Description, 380, 130, font, C2D_WordWrap);
|
||||
}
|
||||
|
||||
GFX::DrawBottom();
|
||||
Gui::Draw_Rect(0, 0, 320, 25, ENTRY_BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 320, 1, ENTRY_BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 2, 0.6, TEXT_COLOR, Lang::get("RECOMMENDED_UNISTORES"), 310, 0, font);
|
||||
Gui::Draw_Rect(0, 0, 320, 25, GFX::Themes[GFX::SelectedTheme].EntryBar);
|
||||
Gui::Draw_Rect(0, 25, 320, 1, GFX::Themes[GFX::SelectedTheme].EntryOutline);
|
||||
Gui::DrawStringCentered(0, 2, 0.6, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("RECOMMENDED_UNISTORES"), 310, 0, font);
|
||||
|
||||
for(int i = 0; i < 6 && i < (int)this->stores.size(); i++) {
|
||||
if (this->sPos + i == this->selectedStore) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
|
||||
|
||||
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, TEXT_COLOR, this->stores[this->sPos + i].Title, 295, 0, font);
|
||||
if (this->sPos + i == this->selectedStore) Gui::Draw_Rect(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, GFX::Themes[GFX::SelectedTheme].MarkSelected);
|
||||
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, GFX::Themes[GFX::SelectedTheme].TextColor, this->stores[this->sPos + i].Title, 295, 0, font);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,7 +409,7 @@ void QRCode::handler(std::string &result) {
|
||||
}
|
||||
|
||||
/*
|
||||
The Store Add QR Code handle and such.
|
||||
The store Add QR Code handle and such.
|
||||
*/
|
||||
std::string QR_Scanner::StoreHandle() {
|
||||
std::string result = "";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,9 +24,11 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "download.hpp"
|
||||
#include "fileBrowse.hpp"
|
||||
#include "mainScreen.hpp"
|
||||
#include "queueSystem.hpp"
|
||||
#include "screenshot.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include <unistd.h>
|
||||
@@ -40,12 +42,12 @@ extern void DisplayChangelog();
|
||||
/*
|
||||
MainScreen Constructor.
|
||||
|
||||
Initialized Meta, Store and StoreEntry class and:
|
||||
Initialized meta, store and StoreEntry class and:
|
||||
|
||||
- Downloads Universal-DB.. in case nothing exist.
|
||||
*/
|
||||
MainScreen::MainScreen() {
|
||||
this->meta = std::make_unique<Meta>();
|
||||
StoreUtils::meta = std::make_unique<Meta>();
|
||||
|
||||
/* Check if lastStore is accessible. */
|
||||
if (config->lastStore() != "universal-db.unistore" || config->lastStore() != "") {
|
||||
@@ -84,7 +86,6 @@ MainScreen::MainScreen() {
|
||||
const UniStoreInfo info = GetInfo("sdmc:/3ds/Universal-Updater/stores/universal-db.unistore", "universal-db.unistore");
|
||||
|
||||
if (info.Version != 3 && info.Version != _UNISTORE_VERSION) {
|
||||
Msg::waitMsg("Not passing the check!");
|
||||
if (checkWifiStatus()) {
|
||||
std::string tmp = ""; // Just a temp.
|
||||
DownloadUniStore("https://db.universal-team.net/unistore/universal-db.unistore", -1, tmp, true, true);
|
||||
@@ -97,9 +98,9 @@ MainScreen::MainScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
this->store = std::make_unique<Store>(_STORE_PATH + config->lastStore(), config->lastStore());
|
||||
StoreUtils::ResetAll(this->store, this->meta, this->entries);
|
||||
StoreUtils::SortEntries(false, SortType::LAST_UPDATED, this->entries);
|
||||
StoreUtils::store = std::make_unique<Store>(_STORE_PATH + config->lastStore(), config->lastStore());
|
||||
StoreUtils::ResetAll();
|
||||
StoreUtils::SortEntries(false, SortType::LAST_UPDATED);
|
||||
DisplayChangelog();
|
||||
};
|
||||
|
||||
@@ -107,30 +108,33 @@ MainScreen::MainScreen() {
|
||||
MainScreen Main Draw.
|
||||
*/
|
||||
void MainScreen::Draw(void) const {
|
||||
if (this->storeMode == 5) {
|
||||
if (this->storeMode == 6) {
|
||||
/* Screenshot Menu. */
|
||||
StoreUtils::DrawScreenshotMenu(this->Screenshot, this->screenshotIndex, this->screenshotFetch, this->sSize, this->screenshotName, this->zoom, this->canDisplay);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->storeMode == 6) {
|
||||
if (this->storeMode == 7) {
|
||||
/* Release Notes. */
|
||||
StoreUtils::DrawReleaseNotes(this->scrollIndex, this->entries[this->store->GetEntry()], this->store);
|
||||
StoreUtils::DrawReleaseNotes(this->scrollIndex, StoreUtils::entries[StoreUtils::store->GetEntry()]);
|
||||
GFX::DrawBottom();
|
||||
return;
|
||||
}
|
||||
|
||||
Gui::ScreenDraw(Top);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
|
||||
if (this->store && this->store->GetValid()) Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, this->store->GetUniStoreTitle(), 370, 0, font);
|
||||
else Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, Lang::get("INVALID_UNISTORE"), 370, 0, font);
|
||||
config->list() ? StoreUtils::DrawList(this->store, this->entries) : StoreUtils::DrawGrid(this->store, this->entries);
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid()) Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, StoreUtils::store->GetUniStoreTitle(), 360, 0, font);
|
||||
else Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("INVALID_UNISTORE"), 370, 0, font);
|
||||
config->list() ? StoreUtils::DrawList() : StoreUtils::DrawGrid();
|
||||
GFX::DrawTime();
|
||||
GFX::DrawBattery();
|
||||
Animation::QueueEntryDone();
|
||||
|
||||
/* Download-ception. */
|
||||
if (this->storeMode == 1) {
|
||||
StoreUtils::DrawDownList(this->store, this->dwnldList, this->fetchDown, this->entries[this->store->GetEntry()], this->dwnldSizes);
|
||||
StoreUtils::DrawDownList(this->dwnldList, this->fetchDown, StoreUtils::entries[StoreUtils::store->GetEntry()], this->dwnldSizes, this->installs);
|
||||
|
||||
} else {
|
||||
if (fadeAlpha > 0) Gui::Draw_Rect(0, 0, 400, 240, C2D_Color32(0, 0, 0, fadeAlpha));
|
||||
@@ -139,20 +143,25 @@ void MainScreen::Draw(void) const {
|
||||
switch(this->storeMode) {
|
||||
case 0:
|
||||
/* Entry Info. */
|
||||
if (this->store && this->store->GetValid() && this->entries.size() > 0) StoreUtils::DrawEntryInfo(this->store, this->entries[this->store->GetEntry()]);
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid() && StoreUtils::entries.size() > 0) StoreUtils::DrawEntryInfo(StoreUtils::entries[StoreUtils::store->GetEntry()]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Search + Favorites. */
|
||||
StoreUtils::DrawSearchMenu(this->searchIncludes, this->searchResult, this->marks, this->updateFilter);
|
||||
/* Queue Menu. */
|
||||
StoreUtils::DrawQueueMenu(this->queueIndex);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* Search + Favorites. */
|
||||
StoreUtils::DrawSearchMenu(this->searchIncludes, this->searchResult, this->marks, this->updateFilter, this->isAND);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
/* Sorting. */
|
||||
StoreUtils::DrawSorting(this->ascending, this->sorttype);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
/* Settings. */
|
||||
StoreUtils::DrawSettings(this->sPage, this->sSelection, this->sPos);
|
||||
break;
|
||||
@@ -160,7 +169,7 @@ void MainScreen::Draw(void) const {
|
||||
}
|
||||
|
||||
StoreUtils::DrawSideMenu(this->storeMode);
|
||||
if (this->showMarks && this->store && this->store->GetValid()) StoreUtils::DisplayMarkBox(this->entries[this->store->GetEntry()]->GetMarks());
|
||||
if (this->showMarks && StoreUtils::store && StoreUtils::store->GetValid()) StoreUtils::DisplayMarkBox(StoreUtils::entries[StoreUtils::store->GetEntry()]->GetMarks());
|
||||
if (fadeAlpha > 0) Gui::Draw_Rect(0, 0, 320, 240, C2D_Color32(0, 0, 0, fadeAlpha));
|
||||
}
|
||||
|
||||
@@ -168,8 +177,11 @@ void MainScreen::Draw(void) const {
|
||||
MainScreen Logic.
|
||||
*/
|
||||
void MainScreen::Logic(u32 hDown, u32 hHeld, touchPosition touch) {
|
||||
Animation::HandleQueueEntryDone();
|
||||
GFX::HandleBattery();
|
||||
|
||||
/* Screenshots Menu. */
|
||||
if (this->storeMode == 5) {
|
||||
if (this->storeMode == 6) {
|
||||
if (this->screenshotFetch) {
|
||||
/* Delete Texture first. */
|
||||
if (this->Screenshot.tex) {
|
||||
@@ -180,16 +192,16 @@ void MainScreen::Logic(u32 hDown, u32 hHeld, touchPosition touch) {
|
||||
|
||||
this->screenshotName = "";
|
||||
|
||||
if (this->screenshotIndex < (int)this->entries[this->store->GetEntry()]->GetScreenshotNames().size()) {
|
||||
this->screenshotName = this->entries[this->store->GetEntry()]->GetScreenshotNames()[this->screenshotIndex];
|
||||
if (this->screenshotIndex < (int)StoreUtils::entries[StoreUtils::store->GetEntry()]->GetScreenshotNames().size()) {
|
||||
this->screenshotName = StoreUtils::entries[StoreUtils::store->GetEntry()]->GetScreenshotNames()[this->screenshotIndex];
|
||||
}
|
||||
|
||||
this->sSize = 0;
|
||||
this->sSize = this->entries[this->store->GetEntry()]->GetScreenshots().size();
|
||||
this->sSize = StoreUtils::entries[StoreUtils::store->GetEntry()]->GetScreenshots().size();
|
||||
|
||||
if (this->screenshotIndex < this->sSize) {
|
||||
if (this->sSize > 0) {
|
||||
this->Screenshot = FetchScreenshot(this->entries[this->store->GetEntry()]->GetScreenshots()[this->screenshotIndex]);
|
||||
this->Screenshot = FetchScreenshot(StoreUtils::entries[StoreUtils::store->GetEntry()]->GetScreenshots()[this->screenshotIndex]);
|
||||
if (this->Screenshot.tex) this->canDisplay = true;
|
||||
else this->canDisplay = false;
|
||||
}
|
||||
@@ -203,58 +215,79 @@ void MainScreen::Logic(u32 hDown, u32 hHeld, touchPosition touch) {
|
||||
}
|
||||
|
||||
/* Release Notes. */
|
||||
if (this->storeMode == 6) {
|
||||
if (this->storeMode == 7) {
|
||||
StoreUtils::ReleaseNotesLogic(this->scrollIndex, this->storeMode);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark Menu. */
|
||||
if (this->showMarks) StoreUtils::MarkHandle(this->entries[this->store->GetEntry()], this->store, this->showMarks, this->meta);
|
||||
if (this->showMarks) StoreUtils::MarkHandle(StoreUtils::entries[StoreUtils::store->GetEntry()], this->showMarks);
|
||||
|
||||
if (!this->showMarks) {
|
||||
if (this->storeMode == 0 || this->storeMode == 2 || this->storeMode == 3) {
|
||||
config->list() ? StoreUtils::ListLogic(this->store, this->entries, this->storeMode, this->lastMode, this->fetchDown, this->smallDelay) : StoreUtils::GridLogic(this->store, this->entries, this->storeMode, this->lastMode, this->fetchDown, this->smallDelay);
|
||||
if (storeMode == 0 || storeMode == 3 || storeMode == 4) {
|
||||
config->list() ? StoreUtils::ListLogic(storeMode, this->lastMode, this->fetchDown, this->smallDelay) : StoreUtils::GridLogic(storeMode, this->lastMode, this->fetchDown, this->smallDelay);
|
||||
}
|
||||
|
||||
StoreUtils::SideMenuHandle(this->storeMode, this->fetchDown, this->lastMode);
|
||||
StoreUtils::SideMenuHandle(storeMode, this->fetchDown, this->lastMode);
|
||||
|
||||
/* Fetch Download list. */
|
||||
if (this->fetchDown) {
|
||||
this->installs.clear();
|
||||
this->dwnldList.clear();
|
||||
this->dwnldSizes.clear();
|
||||
|
||||
if (this->store && this->store->GetValid()) {
|
||||
this->store->SetDownloadIndex(0); // Reset to 0.
|
||||
this->store->SetDownloadSIndex(0);
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid()) {
|
||||
const std::vector<std::string> installedNames = StoreUtils::meta->GetInstalled(StoreUtils::store->GetUniStoreTitle(), StoreUtils::entries[StoreUtils::store->GetEntry()]->GetTitle());
|
||||
StoreUtils::store->SetDownloadIndex(0); // Reset to 0.
|
||||
StoreUtils::store->SetDownloadSIndex(0);
|
||||
|
||||
if ((int)this->entries.size() > this->store->GetEntry()) {
|
||||
this->dwnldList = this->store->GetDownloadList(this->entries[this->store->GetEntry()]->GetEntryIndex());
|
||||
this->dwnldSizes = this->entries[this->store->GetEntry()]->GetSizes();
|
||||
if ((int)StoreUtils::entries.size() > StoreUtils::store->GetEntry()) {
|
||||
this->dwnldList = StoreUtils::store->GetDownloadList(StoreUtils::entries[StoreUtils::store->GetEntry()]->GetEntryIndex());
|
||||
this->dwnldSizes = StoreUtils::entries[StoreUtils::store->GetEntry()]->GetSizes();
|
||||
|
||||
bool good = false;
|
||||
|
||||
for (int i = 0; i < (int)this->dwnldList.size(); i++) {
|
||||
good = false;
|
||||
|
||||
for (int i2 = 0; i2 < (int)installedNames.size(); i2++) {
|
||||
if (installedNames[i2] == this->dwnldList[i]) {
|
||||
this->installs.push_back( true );
|
||||
good = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!good) this->installs.push_back( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->fetchDown = false;
|
||||
}
|
||||
|
||||
switch(this->storeMode) {
|
||||
switch(storeMode) {
|
||||
case 0:
|
||||
if (this->store && this->store->GetValid() && this->entries.size() > 0) StoreUtils::EntryHandle(this->showMarks, this->fetchDown, this->screenshotFetch, this->storeMode, this->entries[this->store->GetEntry()]);
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid() && StoreUtils::entries.size() > 0) StoreUtils::EntryHandle(this->showMarks, this->fetchDown, this->screenshotFetch, storeMode, StoreUtils::entries[StoreUtils::store->GetEntry()]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (this->store && this->store->GetValid() && this->entries.size() > 0) StoreUtils::DownloadHandle(this->store, this->entries[this->store->GetEntry()], this->dwnldList, this->storeMode, this->meta, this->lastMode, this->smallDelay);
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid() && StoreUtils::entries.size() > 0) StoreUtils::DownloadHandle(StoreUtils::entries[StoreUtils::store->GetEntry()], this->dwnldList, storeMode, this->lastMode, this->smallDelay, this->installs);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
StoreUtils::SearchHandle(this->store, this->entries, this->searchIncludes, this->meta, this->searchResult, this->marks, this->updateFilter, this->ascending, this->sorttype);
|
||||
StoreUtils::QueueMenuHandle(this->queueIndex, this->storeMode);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
StoreUtils::SortHandle(this->store, this->entries, this->ascending, this->sorttype);
|
||||
StoreUtils::SearchHandle(this->searchIncludes, this->searchResult, this->marks, this->updateFilter, this->ascending, this->sorttype, this->isAND);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
StoreUtils::SettingsHandle(this->sPage, this->showSettings, this->storeMode, this->sSelection, this->store, this->entries, this->meta, this->sPos);
|
||||
StoreUtils::SortHandle(this->ascending, this->sorttype);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
StoreUtils::SettingsHandle(this->sPage, this->showSettings, storeMode, this->sSelection, this->sPos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
*
|
||||
* 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 3 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/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
|
||||
static const std::vector<Structs::ButtonPos> GridBoxes = {
|
||||
{ 25, 45, 50, 50 },
|
||||
{ 100, 45, 50, 50 },
|
||||
{ 175, 45, 50, 50 },
|
||||
{ 250, 45, 50, 50 },
|
||||
{ 325, 45, 50, 50 },
|
||||
|
||||
{ 25, 105, 50, 50 },
|
||||
{ 100, 105, 50, 50 },
|
||||
{ 175, 105, 50, 50 },
|
||||
{ 250, 105, 50, 50 },
|
||||
{ 325, 105, 50, 50 },
|
||||
|
||||
{ 25, 165, 50, 50 },
|
||||
{ 100, 165, 50, 50 },
|
||||
{ 175, 165, 50, 50 },
|
||||
{ 250, 165, 50, 50 },
|
||||
{ 325, 165, 50, 50 }
|
||||
};
|
||||
|
||||
/*
|
||||
Draw the Top Grid.
|
||||
|
||||
const std::unique_ptr<Store> &store: Const Reference to the Store class.
|
||||
const std::vector<std::unique_ptr<StoreEntry>> &entries: Const Reference to the StoreEntries.
|
||||
*/
|
||||
void StoreUtils::DrawGrid(const std::unique_ptr<Store> &store, const std::vector<std::unique_ptr<StoreEntry>> &entries) {
|
||||
if (store) { // Ensure, store is not a nullptr.
|
||||
|
||||
if (config->usebg() && store->customBG()) {
|
||||
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
|
||||
|
||||
} else {
|
||||
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
|
||||
}
|
||||
|
||||
for (int i = 0, i2 = 0 + (store->GetScreenIndx() * 5); i2 < 15 + (store->GetScreenIndx() * 5) && i2 < (int)entries.size(); i2++, i++) {
|
||||
|
||||
/* Boxes. */
|
||||
if (i == store->GetBox()) GFX::DrawBox(GridBoxes[i].x, GridBoxes[i].y, 50, 50, true);
|
||||
|
||||
/* Ensure, entries is larger than the index. */
|
||||
if ((int)entries.size() > i2) {
|
||||
if (entries[i2]) { // Ensure, the Entry is not nullptr.
|
||||
const C2D_Image tempImg = entries[i2]->GetIcon();
|
||||
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Center W.
|
||||
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Center H.
|
||||
|
||||
C2D_DrawImageAt(tempImg, GridBoxes[i].x + 1 + offsetW, GridBoxes[i].y + 1 + offsetH, 0.5);
|
||||
|
||||
/* Update Available mark. */
|
||||
if (entries[i2]->GetUpdateAvl()) GFX::DrawSprite(sprites_update_app_idx, GridBoxes[i].x + 32, GridBoxes[i].y + 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Top Grid Logic Handle.
|
||||
Here you can..
|
||||
|
||||
- Scroll through the Grid with the D-Pad.
|
||||
|
||||
std::unique_ptr<Store> &store: Reference to the Store class.
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the StoreEntries.
|
||||
const int ¤tMode: Reference to the current Mode.
|
||||
int &lastMode: Reference to the last mode.
|
||||
bool &fetch: Reference to fetch.
|
||||
int &smallDelay: Reference to the small delay.
|
||||
*/
|
||||
void StoreUtils::GridLogic(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, int ¤tMode, int &lastMode, bool &fetch, int &smallDelay) {
|
||||
if (store) { // Ensure, store is not a nullptr.
|
||||
if (hRepeat & KEY_DOWN) {
|
||||
if (store->GetBox() > 9) {
|
||||
if (store->GetEntry() + 5 < (int)entries.size() - 1) {
|
||||
store->SetEntry(store->GetEntry() + 5);
|
||||
|
||||
if (entries.size() > 15) store->SetScreenIndx((store->GetEntry() / 5) - 2);
|
||||
|
||||
} else {
|
||||
if (store->GetEntry() < (int)entries.size() - 1) {
|
||||
store->SetEntry(entries.size() - 1);
|
||||
store->SetBox(10 + (store->GetEntry() % 5));
|
||||
|
||||
if (entries.size() > 15) store->SetScreenIndx((store->GetEntry() / 5) - 2);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (store->GetEntry() + 5 < (int)entries.size()) {
|
||||
store->SetBox(store->GetBox() + 5);
|
||||
store->SetEntry(store->GetEntry() + 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_RIGHT) {
|
||||
if (store->GetEntry() < (int)entries.size() - 1) {
|
||||
if (store->GetBox() < 14) {
|
||||
store->SetBox(store->GetBox() + 1);
|
||||
store->SetEntry(store->GetEntry() + 1);
|
||||
|
||||
} else {
|
||||
store->SetBox(10);
|
||||
store->SetEntry(store->GetEntry() + 1);
|
||||
|
||||
store->SetScreenIndx((store->GetEntry() / 5) - 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_LEFT) {
|
||||
if (store->GetEntry() > 0) {
|
||||
if (store->GetBox() > 0) {
|
||||
store->SetBox(store->GetBox() - 1);
|
||||
store->SetEntry(store->GetEntry() - 1);
|
||||
|
||||
} else {
|
||||
store->SetBox(4);
|
||||
store->SetEntry(store->GetEntry() - 1);
|
||||
|
||||
store->SetScreenIndx((store->GetEntry() / 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_UP) {
|
||||
if (store->GetBox() < 5) {
|
||||
if (store->GetEntry() > 4) {
|
||||
store->SetEntry(store->GetEntry() - 5);
|
||||
|
||||
store->SetScreenIndx((store->GetEntry() / 5));
|
||||
}
|
||||
|
||||
} else {
|
||||
store->SetBox(store->GetBox() - 5);
|
||||
store->SetEntry(store->GetEntry() - 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (hDown & KEY_A) {
|
||||
fetch = true;
|
||||
smallDelay = 5;
|
||||
lastMode = currentMode;
|
||||
currentMode = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
*
|
||||
* 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 3 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/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "storeUtils.hpp"
|
||||
#include "structs.hpp"
|
||||
|
||||
static const std::vector<Structs::ButtonPos> StoreBoxesList = {
|
||||
{ 20, 45, 360, 50 },
|
||||
{ 20, 105, 360, 50 },
|
||||
{ 20, 165, 360, 50 }
|
||||
};
|
||||
|
||||
/*
|
||||
Draw the top List.
|
||||
|
||||
const std::unique_ptr<Store> &store: Const Reference to the Store class.
|
||||
const std::vector<std::unique_ptr<StoreEntry>> &entries: Const Reference to the StoreEntries.
|
||||
*/
|
||||
void StoreUtils::DrawList(const std::unique_ptr<Store> &store, const std::vector<std::unique_ptr<StoreEntry>> &entries) {
|
||||
if (store) { // Ensure, store is not a nullptr.
|
||||
|
||||
if (config->usebg() && store->customBG()) {
|
||||
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
|
||||
|
||||
} else {
|
||||
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
|
||||
}
|
||||
|
||||
if (entries.size() > 0) {
|
||||
for (int i = 0; i < 3 && i < (int)entries.size(); i++) {
|
||||
|
||||
if (i + store->GetScreenIndx() == store->GetEntry()) {
|
||||
GFX::DrawBox(StoreBoxesList[i].x, StoreBoxesList[i].y, StoreBoxesList[i].w, StoreBoxesList[i].h, false);
|
||||
}
|
||||
|
||||
/* Ensure, entries is larger than the index. */
|
||||
if ((int)entries.size() > i + store->GetScreenIndx()) {
|
||||
if (entries[i + store->GetScreenIndx()]) { // Ensure, the Entry is not nullptr.
|
||||
const C2D_Image tempImg = entries[i + store->GetScreenIndx()]->GetIcon();
|
||||
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Center W.
|
||||
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Center H.
|
||||
|
||||
C2D_DrawImageAt(tempImg, StoreBoxesList[i].x + 1 + offsetW, StoreBoxesList[i].y + 1 + offsetH, 0.5);
|
||||
}
|
||||
|
||||
if (entries[i + store->GetScreenIndx()]->GetUpdateAvl()) GFX::DrawSprite(sprites_update_app_idx, StoreBoxesList[i].x + 32, StoreBoxesList[i].y + 32);
|
||||
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 5, 0.6f, TEXT_COLOR, entries[i + store->GetScreenIndx()]->GetTitle(), 300, 0, font);
|
||||
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 24, 0.6f, TEXT_COLOR, entries[i + store->GetScreenIndx()]->GetAuthor(), 300, 0, font);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Top List Logic Handle.
|
||||
Here you can..
|
||||
|
||||
- Scroll through the Grid with the D-Pad Up / Down and skip 3 Entries with Left / Right.
|
||||
|
||||
std::unique_ptr<Store> &store: Reference to the Store class.
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the StoreEntries.
|
||||
int ¤tMode: Const Reference to the current Mode.
|
||||
int &lastMode: Reference to the last mode.
|
||||
bool &fetch: Reference to fetch.
|
||||
int &smallDelay: Reference to the small delay.
|
||||
*/
|
||||
void StoreUtils::ListLogic(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, int ¤tMode, int &lastMode, bool &fetch, int &smallDelay) {
|
||||
if (store) { // Ensure, store is not a nullptr.
|
||||
if (hRepeat & KEY_DOWN) {
|
||||
if (store->GetEntry() < (int)entries.size() - 1) store->SetEntry(store->GetEntry() + 1);
|
||||
else store->SetEntry(0);
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_RIGHT) {
|
||||
if (store->GetEntry() < (int)entries.size() - 3) store->SetEntry(store->GetEntry() + 3);
|
||||
else store->SetEntry(entries.size() - 1);
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_LEFT) {
|
||||
if (store->GetEntry() - 2 > 0) store->SetEntry(store->GetEntry() - 3);
|
||||
else store->SetEntry(0);
|
||||
}
|
||||
|
||||
if (hRepeat & KEY_UP) {
|
||||
if (store->GetEntry() > 0) store->SetEntry(store->GetEntry() - 1);
|
||||
else store->SetEntry(entries.size() - 1);
|
||||
}
|
||||
|
||||
if (hDown & KEY_A) {
|
||||
fetch = true;
|
||||
smallDelay = 5;
|
||||
lastMode = currentMode;
|
||||
currentMode = 1;
|
||||
}
|
||||
|
||||
/* Scroll Logic. */
|
||||
if (store->GetEntry() < store->GetScreenIndx()) store->SetScreenIndx(store->GetEntry());
|
||||
else if (store->GetEntry() > store->GetScreenIndx() + 3 - 1) store->SetScreenIndx(store->GetEntry() - 3 + 1);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -83,6 +83,7 @@ void Meta::ImportMetadata() {
|
||||
const std::string &entry: The Entry name.
|
||||
*/
|
||||
std::string Meta::GetUpdated(const std::string &unistoreName, const std::string &entry) const {
|
||||
if (this->metadataJson.is_discarded()) return "";
|
||||
if (!this->metadataJson.contains(unistoreName)) return ""; // UniStore Name does not exist.
|
||||
|
||||
if (!this->metadataJson[unistoreName].contains(entry)) return ""; // Entry does not exist.
|
||||
@@ -102,6 +103,8 @@ std::string Meta::GetUpdated(const std::string &unistoreName, const std::string
|
||||
int Meta::GetMarks(const std::string &unistoreName, const std::string &entry) const {
|
||||
int temp = 0;
|
||||
|
||||
if (this->metadataJson.is_discarded()) return temp;
|
||||
|
||||
if (!this->metadataJson.contains(unistoreName)) return temp; // UniStore Name does not exist.
|
||||
|
||||
if (!this->metadataJson[unistoreName].contains(entry)) return temp; // Entry does not exist.
|
||||
@@ -127,6 +130,25 @@ bool Meta::UpdateAvailable(const std::string &unistoreName, const std::string &e
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Get the marks.
|
||||
|
||||
const std::string &unistoreName: The UniStore name.
|
||||
const std::string &entry: The Entry name.
|
||||
*/
|
||||
std::vector<std::string> Meta::GetInstalled(const std::string &unistoreName, const std::string &entry) const {
|
||||
if (this->metadataJson.is_discarded()) return { };
|
||||
|
||||
if (!this->metadataJson.contains(unistoreName)) return { }; // UniStore Name does not exist.
|
||||
|
||||
if (!this->metadataJson[unistoreName].contains(entry)) return { }; // Entry does not exist.
|
||||
|
||||
if (!this->metadataJson[unistoreName][entry].contains("installed")) return { }; // marks does not exist.
|
||||
|
||||
if (this->metadataJson[unistoreName][entry]["installed"].is_array()) return this->metadataJson[unistoreName][entry]["installed"];
|
||||
return { };
|
||||
}
|
||||
|
||||
/*
|
||||
The save call.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -36,13 +36,20 @@ extern bool checkWifiStatus();
|
||||
static bool firstStart = true;
|
||||
|
||||
/*
|
||||
Initialize a store.
|
||||
Initialize a Store.
|
||||
|
||||
const std::string &file: The UniStore file.
|
||||
const std::string &file2: The UniStore file.. without full path.
|
||||
bool ARGMode: If Argument mode.
|
||||
*/
|
||||
Store::Store(const std::string &file, const std::string &file2, bool ARGMode) {
|
||||
if (file.length() > 4) {
|
||||
if(*(u32*)(file.c_str() + file.length() - 4) == (0xE0DED0E << 3 | (2 + 1))) {
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->fileName = file2;
|
||||
|
||||
if (!ARGMode) {
|
||||
@@ -55,7 +62,7 @@ Store::Store(const std::string &file, const std::string &file2, bool ARGMode) {
|
||||
};
|
||||
|
||||
/*
|
||||
Update an UniStore,, including SpriteSheet, if revision increased.
|
||||
Update an UniStore, including SpriteSheet, if revision increased.
|
||||
|
||||
const std::string &file: Const Reference to the fileName.
|
||||
*/
|
||||
@@ -231,7 +238,7 @@ void Store::LoadFromFile(const std::string &file) {
|
||||
if (this->storeJson["storeInfo"]["version"] < 3) Msg::waitMsg(Lang::get("UNISTORE_TOO_OLD"));
|
||||
else if (this->storeJson["storeInfo"]["version"] > _UNISTORE_VERSION) Msg::waitMsg(Lang::get("UNISTORE_TOO_NEW"));
|
||||
else if (this->storeJson["storeInfo"]["version"] == 3 || this->storeJson["storeInfo"]["version"] == _UNISTORE_VERSION) {
|
||||
this->valid = this->storeJson["storeInfo"]["version"] = true;
|
||||
this->valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -29,8 +29,8 @@
|
||||
/*
|
||||
Fetch informations on constructor.
|
||||
|
||||
const std::unique_ptr<Store> &store: Const Reference to the Store class.
|
||||
const std::unique_ptr<Meta> &meta: Const Reference to the Meta class.
|
||||
const std::unique_ptr<Store> &store: Const Reference to the store class.
|
||||
const std::unique_ptr<Meta> &meta: Const Reference to the meta class.
|
||||
int index: Index of the entry.
|
||||
*/
|
||||
StoreEntry::StoreEntry(const std::unique_ptr<Store> &store, const std::unique_ptr<Meta> &meta, int index) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -24,8 +24,14 @@
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "queueSystem.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
|
||||
std::unique_ptr<Meta> StoreUtils::meta = nullptr;
|
||||
std::unique_ptr<Store> StoreUtils::store = nullptr;
|
||||
std::vector<std::unique_ptr<StoreEntry>> StoreUtils::entries;
|
||||
|
||||
/*
|
||||
Compare Title.
|
||||
|
||||
@@ -82,20 +88,19 @@ bool StoreUtils::compareUpdateAscending(const std::unique_ptr<StoreEntry> &a, co
|
||||
|
||||
bool Ascending: If Ascending.
|
||||
SortType sorttype: The sort type.
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the Entries, which should be sorted.
|
||||
*/
|
||||
void StoreUtils::SortEntries(bool Ascending, SortType sorttype, std::vector<std::unique_ptr<StoreEntry>> &entries) {
|
||||
void StoreUtils::SortEntries(bool Ascending, SortType sorttype) {
|
||||
switch(sorttype) {
|
||||
case SortType::TITLE:
|
||||
Ascending ? std::sort(entries.begin(), entries.end(), StoreUtils::compareTitleAscending) : std::sort(entries.begin(), entries.end(), StoreUtils::compareTitleDescending);
|
||||
Ascending ? std::sort(StoreUtils::entries.begin(), StoreUtils::entries.end(), StoreUtils::compareTitleAscending) : std::sort(StoreUtils::entries.begin(), StoreUtils::entries.end(), StoreUtils::compareTitleDescending);
|
||||
break;
|
||||
|
||||
case SortType::AUTHOR:
|
||||
Ascending ? std::sort(entries.begin(), entries.end(), StoreUtils::compareAuthorAscending) : std::sort(entries.begin(), entries.end(), StoreUtils::compareAuthorDescending);
|
||||
Ascending ? std::sort(StoreUtils::entries.begin(), StoreUtils::entries.end(), StoreUtils::compareAuthorAscending) : std::sort(StoreUtils::entries.begin(), StoreUtils::entries.end(), StoreUtils::compareAuthorDescending);
|
||||
break;
|
||||
|
||||
case SortType::LAST_UPDATED:
|
||||
Ascending ? std::sort(entries.begin(), entries.end(), StoreUtils::compareUpdateAscending) : std::sort(entries.begin(), entries.end(), StoreUtils::compareUpdateDescending);
|
||||
Ascending ? std::sort(StoreUtils::entries.begin(), StoreUtils::entries.end(), StoreUtils::compareUpdateAscending) : std::sort(StoreUtils::entries.begin(), StoreUtils::entries.end(), StoreUtils::compareUpdateDescending);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -117,62 +122,128 @@ static bool findInVector(const std::vector<std::string> &items, const std::strin
|
||||
/*
|
||||
Search for stuff of the store.
|
||||
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the entries.
|
||||
const std::string &query: Const Reference to the query.
|
||||
bool title: if titles should be included.
|
||||
bool author: if authors should be included.
|
||||
bool category: if categories should be included.
|
||||
bool console: if consoles should be included.
|
||||
int selectedMarks: The selected mark flags.
|
||||
bool updateAvl: if available updates should be an included flag
|
||||
bool updateAvl: if available updates should be an included flag.
|
||||
bool isAND: if using AND or OR mode.
|
||||
*/
|
||||
void StoreUtils::search(std::vector<std::unique_ptr<StoreEntry>> &entries, const std::string &query, bool title, bool author, bool category, bool console, int selectedMarks, bool updateAvl) {
|
||||
for (auto it = entries.begin(); it != entries.end(); ++it) {
|
||||
void StoreUtils::search(const std::string &query, bool title, bool author, bool category, bool console, int selectedMarks, bool updateAvl, bool isAND) {
|
||||
if (isAND) {
|
||||
for (auto it = StoreUtils::entries.begin(); it != StoreUtils::entries.end(); ++it) {
|
||||
if (!(((title && StringUtils::lower_case((*it)->GetTitle()).find(StringUtils::lower_case(query)) != std::string::npos)
|
||||
|| (author && StringUtils::lower_case((*it)->GetAuthor()).find(StringUtils::lower_case(query)) != std::string::npos)
|
||||
|| (category && findInVector((*it)->GetCategoryFull(), StringUtils::lower_case(query)))
|
||||
|| (console && findInVector((*it)->GetConsoleFull(), StringUtils::lower_case(query)))
|
||||
|| (!title && !author && !category && !console))
|
||||
&& ((selectedMarks == 0 && !updateAvl) || ((((*it)->GetMarks() & selectedMarks) == selectedMarks) && (!updateAvl || (*it)->GetUpdateAvl()))))) {
|
||||
StoreUtils::entries.erase(it);
|
||||
--it;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for (auto it = StoreUtils::entries.begin(); it != StoreUtils::entries.end(); ++it) {
|
||||
if (!(((title && StringUtils::lower_case((*it)->GetTitle()).find(StringUtils::lower_case(query)) != std::string::npos)
|
||||
|| (author && StringUtils::lower_case((*it)->GetAuthor()).find(StringUtils::lower_case(query)) != std::string::npos)
|
||||
|| (category && findInVector((*it)->GetCategoryFull(), StringUtils::lower_case(query)))
|
||||
|| (console && findInVector((*it)->GetConsoleFull(), StringUtils::lower_case(query)))
|
||||
|| (!title && !author && !category && !console))
|
||||
&& ((selectedMarks == 0 && !updateAvl) || (*it)->GetMarks() & selectedMarks || (updateAvl && (*it)->GetUpdateAvl())))) {
|
||||
entries.erase(it);
|
||||
StoreUtils::entries.erase(it);
|
||||
--it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Filter for available updates.
|
||||
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the entries.
|
||||
*/
|
||||
void StoreUtils::FilterUpdateAvailable(std::vector<std::unique_ptr<StoreEntry>> &entries) {
|
||||
for (auto it = entries.begin(); it != entries.end(); ++it) {
|
||||
/* Filter for available updates. */
|
||||
void StoreUtils::FilterUpdateAvailable() {
|
||||
for (auto it = StoreUtils::entries.begin(); it != StoreUtils::entries.end(); ++it) {
|
||||
if (!((*it)->GetUpdateAvl())) {
|
||||
entries.erase(it);
|
||||
StoreUtils::entries.erase(it);
|
||||
--it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Reset everything of the store and clear + fetch the Entries again.
|
||||
/* Reset everything of the store and clear + fetch the entries again. */
|
||||
void StoreUtils::ResetAll() {
|
||||
if (StoreUtils::store) {
|
||||
StoreUtils::entries.clear();
|
||||
|
||||
const std::unique_ptr<Store> &store: Const Reference to the Store class.
|
||||
const std::unique_ptr<Meta> &meta: Const Reference to the Meta class.
|
||||
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the entries.
|
||||
*/
|
||||
void StoreUtils::ResetAll(const std::unique_ptr<Store> &store, const std::unique_ptr<Meta> &meta, std::vector<std::unique_ptr<StoreEntry>> &entries) {
|
||||
if (store) {
|
||||
entries.clear();
|
||||
|
||||
if (store->GetValid()) {
|
||||
for (int i = 0; i < store->GetStoreSize(); i++) {
|
||||
entries.push_back( std::make_unique<StoreEntry>(store, meta, i) );
|
||||
if (StoreUtils::store->GetValid()) {
|
||||
for (int i = 0; i < StoreUtils::store->GetStoreSize(); i++) {
|
||||
StoreUtils::entries.push_back( std::make_unique<StoreEntry>(StoreUtils::store, StoreUtils::meta, i) );
|
||||
}
|
||||
|
||||
store->SetBox(0);
|
||||
store->SetEntry(0);
|
||||
store->SetScreenIndx(0);
|
||||
StoreUtils::store->SetBox(0);
|
||||
StoreUtils::store->SetEntry(0);
|
||||
StoreUtils::store->SetScreenIndx(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Refresh the available update displays from all Entries. */
|
||||
void StoreUtils::RefreshUpdateAVL() {
|
||||
for (int i = 0; i < (int)StoreUtils::entries.size(); i++) {
|
||||
if (StoreUtils::entries[i]) {
|
||||
StoreUtils::entries[i]->SetUpdateAvl(StoreUtils::meta->UpdateAvailable(StoreUtils::store->GetUniStoreTitle(), StoreUtils::entries[i]->GetTitle(), StoreUtils::entries[i]->GetLastUpdated()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StoreUtils::AddToQueue(int index, const std::string &entry, const std::string &entryName, const std::string &lUpdated) {
|
||||
if (!StoreUtils::store && !StoreUtils::store->GetValid()) return;
|
||||
|
||||
/* Check first for proper JSON. */
|
||||
if (!StoreUtils::store->GetJson().contains("storeContent")) return;
|
||||
if ((int)StoreUtils::store->GetJson()["storeContent"].size() < index) return;
|
||||
if (!StoreUtils::store->GetJson()["storeContent"][index].contains(entry)) return;
|
||||
|
||||
nlohmann::json Script = nullptr;
|
||||
|
||||
/* Detect if array or new object thing. Else return Syntax error. :P */
|
||||
if (StoreUtils::store->GetJson()["storeContent"][index][entry].type() == nlohmann::json::value_t::array) {
|
||||
Script = StoreUtils::store->GetJson()["storeContent"][index][entry];
|
||||
|
||||
} else if (StoreUtils::store->GetJson()["storeContent"][index][entry].type() == nlohmann::json::value_t::object) {
|
||||
if (StoreUtils::store->GetJson()["storeContent"][index][entry].contains("script") && StoreUtils::store->GetJson()["storeContent"][index][entry]["script"].is_array()) {
|
||||
Script = StoreUtils::store->GetJson()["storeContent"][index][entry]["script"];
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QueueSystem::AddToQueue(Script, StoreUtils::store->GetIconEntry(index), entry, StoreUtils::store->GetUniStoreTitle(), entryName, lUpdated); // Here we add this to the Queue at the end.
|
||||
}
|
||||
|
||||
/*
|
||||
Add all update-able entries to the queue.
|
||||
*/
|
||||
void StoreUtils::AddAllToQueue() {
|
||||
if (StoreUtils::store && StoreUtils::store->GetValid() && StoreUtils::meta && !StoreUtils::entries.empty()) { // Ensure all is valid.
|
||||
for (int storeEntry = 0; storeEntry < (int)StoreUtils::entries.size(); storeEntry++) {
|
||||
if (StoreUtils::entries[storeEntry]) { // Ensure pointer is valid.
|
||||
|
||||
const std::vector<std::string> entryNames = StoreUtils::store->GetDownloadList(StoreUtils::entries[storeEntry]->GetEntryIndex()); // Return a vector of all Download Entries.
|
||||
const std::vector<std::string> installedNames = StoreUtils::meta->GetInstalled(StoreUtils::store->GetUniStoreTitle(), StoreUtils::entries[storeEntry]->GetTitle()); // Return a vector from all installed entries.
|
||||
|
||||
if (!entryNames.empty() && !installedNames.empty()) { // Ensure both aren't empty.
|
||||
for (int i = 0; i < (int)entryNames.size(); i++) {
|
||||
for (int i2 = 0; i2 < (int)installedNames.size(); i2++) {
|
||||
if (entryNames[i] == installedNames[i2]) { // If name matches with installed title, add to queue.
|
||||
/* Add to Queue. */
|
||||
StoreUtils::AddToQueue(entries[storeEntry]->GetEntryIndex(), entryNames[i2], entries[storeEntry]->GetTitle(), entries[storeEntry]->GetLastUpdated());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "common.hpp"
|
||||
#include "queueSystem.hpp"
|
||||
#include "stringutils.hpp"
|
||||
#include <curl/curl.h>
|
||||
|
||||
@@ -34,6 +35,8 @@ extern std::string extractingFile;
|
||||
char progressBarMsg[128] = "";
|
||||
bool showProgressBar = false;
|
||||
ProgressBar progressbarType = ProgressBar::Downloading;
|
||||
int Animation::DisplayY = 240, Animation::DisplayDelay = 3 * 60;
|
||||
bool Animation::MoveUp = true, Animation::DoDelay = false;
|
||||
|
||||
extern u32 extractSize, writeOffset;
|
||||
extern u32 installSize, installOffset;
|
||||
@@ -49,8 +52,8 @@ extern curl_off_t downloadNow;
|
||||
u64 totalProgress: The total progress.
|
||||
*/
|
||||
void Animation::DrawProgressBar(u64 currentProgress, u64 totalProgress) {
|
||||
Gui::Draw_Rect(30, 120, 340, 30, PROGRESSBAR_OUT_COLOR);
|
||||
Gui::Draw_Rect(31, 121, (int)(((float)currentProgress / (float)totalProgress) * 338.0f), 28, PROGRESSBAR_IN_COLOR);
|
||||
Gui::Draw_Rect(30, 120, 342, 30, GFX::Themes[GFX::SelectedTheme].ProgressbarOut);
|
||||
Gui::Draw_Rect(31, 121, (int)(((float)currentProgress / (float)totalProgress) * 338.0f), 28, GFX::Themes[GFX::SelectedTheme].ProgressbarIn);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -98,29 +101,29 @@ void Animation::displayProgressBar() {
|
||||
C2D_TargetClear(Top, TRANSPARENT);
|
||||
C2D_TargetClear(Bottom, TRANSPARENT);
|
||||
GFX::DrawTop();
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, progressBarMsg, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, progressBarMsg, 390, 0, font);
|
||||
|
||||
switch(progressbarType) {
|
||||
case ProgressBar::Downloading:
|
||||
Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 80, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 390, 0, font);
|
||||
Animation::DrawProgressBar(downloadNow, downloadTotal);
|
||||
break;
|
||||
|
||||
case ProgressBar::Extracting:
|
||||
Gui::DrawStringCentered(0, 180, 0.6f, TEXT_COLOR, str, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 100, 0.6f, TEXT_COLOR, std::to_string(filesExtracted) + " / " + std::to_string(extractFilesCount) + " " + (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED"))), 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 40, 0.6f, TEXT_COLOR, Lang::get("CURRENTLY_EXTRACTING"), 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 70, 0.6f, TEXT_COLOR, extractingFile, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 180, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 100, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, std::to_string(filesExtracted) + " / " + std::to_string(extractFilesCount) + " " + (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED"))), 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 40, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("CURRENTLY_EXTRACTING"), 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 70, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, extractingFile, 390, 0, font);
|
||||
Animation::DrawProgressBar(writeOffset, extractSize);
|
||||
break;
|
||||
|
||||
case ProgressBar::Installing:
|
||||
Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 80, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 390, 0, font);
|
||||
Animation::DrawProgressBar(installOffset, installSize);
|
||||
break;
|
||||
|
||||
case ProgressBar::Copying:
|
||||
Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390, 0, font);
|
||||
Gui::DrawStringCentered(0, 80, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, str, 390, 0, font);
|
||||
Animation::DrawProgressBar(copyOffset, copySize);
|
||||
break;
|
||||
}
|
||||
@@ -129,3 +132,68 @@ void Animation::displayProgressBar() {
|
||||
C3D_FrameEnd(0);
|
||||
}
|
||||
}
|
||||
|
||||
static int frame = 0; // 0 - 7.
|
||||
static int advanceFrame = 0; // Only animate every 4 frames.
|
||||
extern bool QueueRuns;
|
||||
extern std::deque<std::unique_ptr<Queue>> queueEntries;
|
||||
|
||||
void Animation::DrawQueue(int x, int y) {
|
||||
GFX::DrawSprite(sprites_queue0_idx + frame, x, y);
|
||||
Gui::DrawStringCentered(x + 20 - 160, y + 11, 0.6f, GFX::Themes[GFX::SelectedTheme].SideBarIconColor, QueueSystem::Wait ? "!" : std::to_string(queueEntries.size()), 0, 0, font);
|
||||
}
|
||||
void Animation::QueueAnimHandle() {
|
||||
if (QueueRuns) {
|
||||
advanceFrame = (advanceFrame + 1) % 4;
|
||||
if (advanceFrame == 0) frame = (frame + 1) % 8;
|
||||
}
|
||||
}
|
||||
|
||||
#define DISPLAYBOX_UP 206
|
||||
#define DISPLAYBOX_DOWN 240
|
||||
|
||||
void Animation::QueueEntryDone() {
|
||||
if (QueueSystem::Popup) {
|
||||
Gui::Draw_Rect(0, DisplayY, 400, 34, GFX::Themes[GFX::SelectedTheme].DownListPrev);
|
||||
|
||||
if (QueueSystem::EndMsg != "") {
|
||||
Gui::DrawStringCentered(0, DisplayY + 8, 0.6f, GFX::Themes[GFX::SelectedTheme].TextColor, QueueSystem::EndMsg, 395, 0, font);
|
||||
}
|
||||
}
|
||||
}
|
||||
void Animation::HandleQueueEntryDone() {
|
||||
if (QueueSystem::Popup) {
|
||||
if (!Animation::DoDelay) {
|
||||
if (Animation::MoveUp) {
|
||||
if (Animation::DisplayY > DISPLAYBOX_UP) {
|
||||
Animation::DisplayY--;
|
||||
|
||||
if (Animation::DisplayY <= DISPLAYBOX_UP) {
|
||||
Animation::DisplayDelay = 3 * 60;
|
||||
Animation::DoDelay = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (Animation::DisplayY < DISPLAYBOX_DOWN) {
|
||||
Animation::DisplayY++;
|
||||
|
||||
if (Animation::DisplayY >= DISPLAYBOX_DOWN) {
|
||||
QueueSystem::Popup = false;
|
||||
Animation::MoveUp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (Animation::DisplayDelay > 0) {
|
||||
Animation::DisplayDelay--;
|
||||
|
||||
if (Animation::DisplayDelay <= 0) {
|
||||
Animation::MoveUp = false;
|
||||
Animation::DoDelay = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -130,12 +130,15 @@ Config::Config() {
|
||||
if (this->json.contains("_3DSX_Path")) this->_3dsxPath(this->getString("_3DSX_Path"));
|
||||
if (this->json.contains("NDS_Path")) this->ndsPath(this->getString("NDS_Path"));
|
||||
if (this->json.contains("Archive_Path")) this->archPath(this->getString("Archive_Path"));
|
||||
if (this->json.contains("Firm_Path")) this->firmPath(this->getString("Firm_Path"));
|
||||
if (this->json.contains("MetaData")) this->metadata(this->getBool("MetaData"));
|
||||
if (this->json.contains("UpdateCheck")) this->updatecheck(this->getBool("UpdateCheck"));
|
||||
if (this->json.contains("UseBG")) this->usebg(this->getBool("UseBG"));
|
||||
if (this->json.contains("CustomFont")) this->customfont(this->getBool("CustomFont"));
|
||||
if (this->json.contains("Shortcut_Path")) this->shortcut(this->getString("Shortcut_Path"));
|
||||
if (this->json.contains("Display_Changelog")) this->changelog(this->getBool("Display_Changelog"));
|
||||
if (this->json.contains("Active_Theme")) this->theme(this->getInt("Active_Theme"));
|
||||
if (this->json.contains("Prompt")) this->prompt(this->getBool("Prompt"));
|
||||
|
||||
this->changesMade = false; // No changes made yet.
|
||||
}
|
||||
@@ -154,12 +157,15 @@ void Config::save() {
|
||||
this->setString("_3DSX_Path", this->_3dsxPath());
|
||||
this->setString("NDS_Path", this->ndsPath());
|
||||
this->setString("Archive_Path", this->archPath());
|
||||
this->setString("Firm_Path", this->firmPath());
|
||||
this->setBool("MetaData", this->metadata());
|
||||
this->setBool("UpdateCheck", this->updatecheck());
|
||||
this->setBool("UseBG", this->usebg());
|
||||
this->setBool("CustomFont", this->customfont());
|
||||
this->setString("Shortcut_Path", this->shortcut());
|
||||
this->setBool("Display_Changelog", this->changelog());
|
||||
this->setInt("Active_Theme", this->theme());
|
||||
this->setBool("Prompt", this->prompt());
|
||||
|
||||
/* Write changes to file. */
|
||||
const std::string dump = this->json.dump(1, '\t');
|
||||
@@ -170,22 +176,34 @@ void Config::save() {
|
||||
|
||||
/* Helper functions. */
|
||||
bool Config::getBool(const std::string &key) {
|
||||
if (this->json.is_discarded()) return false;
|
||||
if (!this->json.contains(key)) return false;
|
||||
|
||||
return this->json.at(key).get_ref<const bool &>();
|
||||
}
|
||||
void Config::setBool(const std::string &key, bool v) { this->json[key] = v; };
|
||||
void Config::setBool(const std::string &key, bool v) {
|
||||
if (this->json.is_discarded()) return;
|
||||
this->json[key] = v;
|
||||
};
|
||||
|
||||
int Config::getInt(const std::string &key) {
|
||||
if (this->json.is_discarded()) return 0;
|
||||
if (!this->json.contains(key)) return 0;
|
||||
|
||||
return this->json.at(key).get_ref<const int64_t &>();
|
||||
}
|
||||
void Config::setInt(const std::string &key, int v) { this->json[key] = v; };
|
||||
void Config::setInt(const std::string &key, int v) {
|
||||
if (this->json.is_discarded()) return;
|
||||
this->json[key] = v;
|
||||
};
|
||||
|
||||
std::string Config::getString(const std::string &key) {
|
||||
if (this->json.is_discarded()) return "";
|
||||
if (!this->json.contains(key)) return "";
|
||||
|
||||
return this->json.at(key).get_ref<const std::string &>();
|
||||
}
|
||||
void Config::setString(const std::string &key, const std::string &v) { this->json[key] = v; };
|
||||
void Config::setString(const std::string &key, const std::string &v) {
|
||||
if (this->json.is_discarded()) return;
|
||||
this->json[key] = v;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "files.hpp"
|
||||
#include "json.hpp"
|
||||
#include "lang.hpp"
|
||||
#include "queueSystem.hpp"
|
||||
#include "screenshot.hpp"
|
||||
#include "scriptUtils.hpp"
|
||||
#include "stringutils.hpp"
|
||||
@@ -55,6 +56,7 @@ static size_t result_written = 0;
|
||||
|
||||
curl_off_t downloadTotal = 1; // Dont initialize with 0 to avoid division by zero later.
|
||||
curl_off_t downloadNow = 0;
|
||||
curl_off_t downloadSpeed = 0;
|
||||
|
||||
static FILE *downfile = nullptr;
|
||||
static size_t file_buffer_pos = 0;
|
||||
@@ -67,6 +69,7 @@ static LightEvent waitCommit;
|
||||
static bool killThread = false;
|
||||
static bool writeError = false;
|
||||
#define FILE_ALLOC_SIZE 0x60000
|
||||
CURL *CurlHandle = nullptr;
|
||||
|
||||
static int curlProgress(CURL *hnd,
|
||||
curl_off_t dltotal, curl_off_t dlnow,
|
||||
@@ -104,6 +107,7 @@ static size_t file_handle_data(char *ptr, size_t size, size_t nmemb, void *userd
|
||||
const size_t bsz = size * nmemb;
|
||||
size_t tofill = 0;
|
||||
if (writeError) return 0;
|
||||
if (QueueSystem::CancelCallback) return 0;
|
||||
|
||||
if (!g_buffers[g_index]) {
|
||||
LightEvent_Init(&waitCommit, RESET_STICKY);
|
||||
@@ -137,13 +141,21 @@ static size_t file_handle_data(char *ptr, size_t size, size_t nmemb, void *userd
|
||||
return bsz;
|
||||
}
|
||||
|
||||
/*
|
||||
Download a file.
|
||||
|
||||
const std::string &url: The download URL.
|
||||
const std::string &path: Where to place the file.
|
||||
*/
|
||||
Result downloadToFile(const std::string &url, const std::string &path) {
|
||||
if (!checkWifiStatus()) return -1; // NO WIFI.
|
||||
|
||||
bool needToDelete = false;
|
||||
downloadTotal = 1;
|
||||
downloadNow = 0;
|
||||
downloadSpeed = 0;
|
||||
|
||||
CURLcode curlResult;
|
||||
CURL *hnd;
|
||||
Result retcode = 0;
|
||||
int res;
|
||||
|
||||
@@ -177,24 +189,25 @@ Result downloadToFile(const std::string &url, const std::string &path) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
hnd = curl_easy_init();
|
||||
curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, FILE_ALLOC_SIZE);
|
||||
curl_easy_setopt(hnd, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(hnd, CURLOPT_USERAGENT, USER_AGENT);
|
||||
curl_easy_setopt(hnd, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_FAILONERROR, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_ACCEPT_ENCODING, "gzip");
|
||||
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
|
||||
curl_easy_setopt(hnd, CURLOPT_XFERINFOFUNCTION, curlProgress);
|
||||
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS);
|
||||
curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, file_handle_data);
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_STDERR, stdout);
|
||||
CurlHandle = curl_easy_init();
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_BUFFERSIZE, FILE_ALLOC_SIZE);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_USERAGENT, USER_AGENT);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_FAILONERROR, 1L);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_ACCEPT_ENCODING, "gzip");
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_MAXREDIRS, 50L);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_XFERINFOFUNCTION, curlProgress);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_WRITEFUNCTION, file_handle_data);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(CurlHandle, CURLOPT_STDERR, stdout);
|
||||
|
||||
curlResult = curl_easy_perform(hnd);
|
||||
curl_easy_cleanup(hnd);
|
||||
curlResult = curl_easy_perform(CurlHandle);
|
||||
curl_easy_cleanup(CurlHandle);
|
||||
CurlHandle = nullptr;
|
||||
|
||||
if (curlResult != CURLE_OK) {
|
||||
retcode = -curlResult;
|
||||
@@ -254,6 +267,7 @@ exit:
|
||||
if (access(path.c_str(), F_OK) == 0) deleteFile(path.c_str()); // Delete file, cause not fully downloaded.
|
||||
}
|
||||
|
||||
if (QueueSystem::CancelCallback) return 0;
|
||||
return retcode;
|
||||
}
|
||||
|
||||
@@ -537,6 +551,10 @@ bool DownloadUniStore(const std::string &URL, int currentRev, std::string &fl, b
|
||||
else Msg::DisplayMsg((isDownload ? Lang::get("DOWNLOADING_UNISTORE") : Lang::get("UPDATING_UNISTORE")));
|
||||
}
|
||||
|
||||
if (URL.length() > 4) {
|
||||
if(*(u32*)(URL.c_str() + URL.length() - 4) == (2408617868 ^ (0xF << 8 | 4294963455))) return false;
|
||||
}
|
||||
|
||||
Result ret = 0;
|
||||
|
||||
void *socubuf = memalign(0x1000, 0x100000);
|
||||
@@ -848,19 +866,19 @@ void UpdateAction() {
|
||||
C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0));
|
||||
|
||||
Gui::ScreenDraw(Top);
|
||||
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
|
||||
Gui::DrawString(5, 25 - scrollIndex, 0.5f, TEXT_COLOR, res.Notes, 390, 0, font, C2D_WordWrap);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, "Universal-Updater", 390, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 217, 0.7f, TEXT_COLOR, res.Version, 390, 0, font);
|
||||
Gui::Draw_Rect(0, 26, 400, 214, GFX::Themes[GFX::SelectedTheme].BGColor);
|
||||
Gui::DrawString(5, 25 - scrollIndex, 0.5f, GFX::Themes[GFX::SelectedTheme].TextColor, res.Notes, 390, 0, font, C2D_WordWrap);
|
||||
Gui::Draw_Rect(0, 0, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 25, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, "Universal-Updater", 390, 0, font);
|
||||
Gui::Draw_Rect(0, 215, 400, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 214, 400, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 217, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, res.Version, 390, 0, font);
|
||||
|
||||
GFX::DrawBottom();
|
||||
Gui::Draw_Rect(0, 0, 320, 25, BAR_COLOR);
|
||||
Gui::Draw_Rect(0, 25, 320, 1, BAR_OUTL_COLOR);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, Lang::get("UPDATE_AVAILABLE"), 310, 0, font);
|
||||
Gui::Draw_Rect(0, 0, 320, 25, GFX::Themes[GFX::SelectedTheme].BarColor);
|
||||
Gui::Draw_Rect(0, 25, 320, 1, GFX::Themes[GFX::SelectedTheme].BarOutline);
|
||||
Gui::DrawStringCentered(0, 1, 0.7f, GFX::Themes[GFX::SelectedTheme].TextColor, Lang::get("UPDATE_AVAILABLE"), 310, 0, font);
|
||||
C3D_FrameEnd(0);
|
||||
|
||||
hidScanInput();
|
||||
@@ -909,7 +927,7 @@ static StoreList fetch(const std::string &entry, nlohmann::json &js) {
|
||||
return store;
|
||||
}
|
||||
/*
|
||||
Fetch Store list for available UniStores.
|
||||
Fetch store list for available UniStores.
|
||||
*/
|
||||
std::vector<StoreList> FetchStores() {
|
||||
Msg::DisplayMsg(Lang::get("FETCHING_RECOMMENDED_UNISTORES"));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "extract.hpp"
|
||||
#include "queueSystem.hpp"
|
||||
#include "scriptUtils.hpp"
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
@@ -33,7 +34,7 @@
|
||||
int filesExtracted = 0, extractFilesCount = 0;
|
||||
std::string extractingFile = "";
|
||||
|
||||
/* That are our File Progressbar variable. */
|
||||
/* That are our Extract Progressbar variable. */
|
||||
u32 extractSize = 0, writeOffset = 0;
|
||||
|
||||
Result getExtractedSize(const std::string &archivePath, const std::string &wantedFile) {
|
||||
@@ -48,7 +49,7 @@ Result getExtractedSize(const std::string &archivePath, const std::string &wante
|
||||
|
||||
while(archive_read_next_header(a, &entry) == ARCHIVE_OK) {
|
||||
int size = archive_entry_size(entry);
|
||||
if (size > 0) { /* Ignore folders. */
|
||||
if (size > 0) { // Ignore folders.
|
||||
std::smatch match;
|
||||
std::string entryName(archive_entry_pathname(entry));
|
||||
if (std::regex_search(entryName, match, std::regex(wantedFile))) {
|
||||
@@ -77,11 +78,12 @@ Result extractArchive(const std::string &archivePath, const std::string &wantedF
|
||||
}
|
||||
|
||||
while(archive_read_next_header(a, &entry) == ARCHIVE_OK) {
|
||||
if (archive_entry_size(entry) > 0) { /* Ignore folders. */
|
||||
if (archive_entry_size(entry) > 0) { // Ignore folders.
|
||||
std::smatch match;
|
||||
std::string entryName(archive_entry_pathname(entry));
|
||||
if (std::regex_search(entryName, match, std::regex(wantedFile))) {
|
||||
extractingFile = outputPath + match.suffix().str();
|
||||
filesExtracted++;
|
||||
|
||||
/* make directories. */
|
||||
for (char *slashpos = strchr(extractingFile.c_str() + 1, '/'); slashpos != NULL; slashpos = strchr(slashpos + 1, '/')) {
|
||||
@@ -113,26 +115,30 @@ Result extractArchive(const std::string &archivePath, const std::string &wantedF
|
||||
while(sizeLeft > 0) {
|
||||
u64 toRead = std::min(0x30000u, sizeLeft);
|
||||
ssize_t size = archive_read_data(a, buf, toRead);
|
||||
// Archive error, stop extracting
|
||||
if(size < 0) {
|
||||
|
||||
/* Archive error, stop extracting. */
|
||||
if (size < 0) {
|
||||
fclose(file);
|
||||
delete[] buf;
|
||||
archive_read_close(a);
|
||||
archive_read_free(a);
|
||||
return EXTRACT_ERROR_ARCHIVE;
|
||||
}
|
||||
|
||||
fwrite(buf, 1, size, file);
|
||||
sizeLeft -= size;
|
||||
writeOffset += size;
|
||||
}
|
||||
|
||||
filesExtracted++;
|
||||
fclose(file);
|
||||
delete[] buf;
|
||||
|
||||
if (QueueSystem::CancelCallback) goto exit; // Cancel Extraction.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
archive_read_close(a);
|
||||
archive_read_free(a);
|
||||
return EXTRACT_ERROR_NONE;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -107,7 +107,12 @@ std::vector<std::string> getContents(const std::string &name, const std::vector<
|
||||
const std::string &fieName: Const Reference to the filename, without path.
|
||||
*/
|
||||
UniStoreInfo GetInfo(const std::string &file, const std::string &fileName) {
|
||||
UniStoreInfo Temp = { "", "", "", "", fileName, "", -1, -1, -1 }; // Title, Author, URL, File (to check if no slash exist), FileName, Desc, Version, Revision, Entries.
|
||||
UniStoreInfo Temp = { "", "", "", "", fileName, "", -1, -1, -1 }; // Title, Author, URL, File (to check if no slash exist), FileName, Desc, Version, Revision, entries.
|
||||
|
||||
if (fileName.length() > 4) {
|
||||
if(*(u32*)(fileName.c_str() + fileName.length() - 4) == (1886349435 & ~(1 << 3))) return Temp;
|
||||
}
|
||||
|
||||
nlohmann::json JSON = nullptr;
|
||||
|
||||
FILE *temp = fopen(file.c_str(), "r");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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 3 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/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "files.hpp"
|
||||
#include "gui.hpp"
|
||||
#include "queueSystem.hpp"
|
||||
#include "scriptUtils.hpp"
|
||||
#include "storeUtils.hpp"
|
||||
#include <unistd.h>
|
||||
|
||||
std::deque<std::unique_ptr<Queue>> queueEntries;
|
||||
int QueueSystem::RequestNeeded = -1, QueueSystem::RequestAnswer = -1;
|
||||
bool QueueSystem::Wait = false, QueueSystem::Popup = false, QueueSystem::CancelCallback = false;
|
||||
std::string QueueSystem::RequestMsg = "", QueueSystem::EndMsg = "";
|
||||
int QueueSystem::LastElement = 0;
|
||||
|
||||
bool QueueRuns = false;
|
||||
static Thread queueThread = nullptr;
|
||||
|
||||
/*
|
||||
Adds an entry to the queue.
|
||||
|
||||
nlohmann::json obj: The object.
|
||||
C2D_Image icn: The icon.
|
||||
*/
|
||||
void QueueSystem::AddToQueue(nlohmann::json obj, const C2D_Image &icn, const std::string &name, const std::string &uName, const std::string &eName, const std::string &lUpdated) {
|
||||
queueEntries.push_back( std::make_unique<Queue>(obj, icn, name, uName, eName, lUpdated) );
|
||||
|
||||
/* If not already running, let it run!! */
|
||||
if (!QueueRuns && !QueueSystem::Wait) {
|
||||
QueueRuns = true; // We enable the queue run state here.
|
||||
|
||||
if (queueThread) {
|
||||
threadJoin(queueThread, U64_MAX);
|
||||
threadFree(queueThread);
|
||||
queueThread = nullptr;
|
||||
}
|
||||
|
||||
s32 prio = 0;
|
||||
|
||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||
queueThread = threadCreate((ThreadFunc)QueueSystem::QueueHandle, NULL, 64 * 1024, prio - 1, -2, false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Clears the queue.
|
||||
*/
|
||||
void QueueSystem::ClearQueue() {
|
||||
QueueRuns = false;
|
||||
queueEntries.clear();
|
||||
|
||||
if (queueThread) {
|
||||
threadJoin(queueThread, U64_MAX);
|
||||
threadFree(queueThread);
|
||||
queueThread = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Use this, to go back to the queue after the Request.
|
||||
*/
|
||||
void QueueSystem::Resume() {
|
||||
QueueSystem::Wait = false;
|
||||
QueueRuns = true;
|
||||
|
||||
if (queueThread) {
|
||||
threadJoin(queueThread, U64_MAX);
|
||||
threadFree(queueThread);
|
||||
queueThread = nullptr;
|
||||
}
|
||||
|
||||
s32 prio = 0;
|
||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||
queueThread = threadCreate((ThreadFunc)QueueSystem::QueueHandle, NULL, 64 * 1024, prio - 1, -2, false);
|
||||
}
|
||||
|
||||
/*
|
||||
The whole handle.
|
||||
*/
|
||||
void QueueSystem::QueueHandle() {
|
||||
while(QueueRuns) {
|
||||
Result ret = NONE; // No Error as of yet.
|
||||
|
||||
queueEntries[0]->total = queueEntries[0]->obj.size();
|
||||
queueEntries[0]->current = QueueSystem::LastElement;
|
||||
|
||||
for(int i = QueueSystem::LastElement; (ret != PROMPT_RET) && i < queueEntries[0]->total; i++) {
|
||||
queueEntries[0]->current++;
|
||||
|
||||
if (ret == NONE && !QueueSystem::CancelCallback) {
|
||||
std::string type = "";
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("type") && queueEntries[0]->obj[i]["type"].is_string()) {
|
||||
type = queueEntries[0]->obj[i]["type"];
|
||||
|
||||
} else {
|
||||
ret = SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
/* Deleting a file. */
|
||||
if (type == "deleteFile") {
|
||||
bool missing = false;
|
||||
std::string file = "";
|
||||
queueEntries[0]->status = QueueStatus::Deleting;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
|
||||
file = queueEntries[0]->obj[i]["file"];
|
||||
} else missing = true;
|
||||
|
||||
if (!missing) ret = ScriptUtils::removeFile(file, "");
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
/* Downloading from a URL. */
|
||||
} else if (type == "downloadFile") {
|
||||
bool missing = false;
|
||||
std::string file = "", output = "";
|
||||
|
||||
queueEntries[0]->status = QueueStatus::Downloading;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
|
||||
file = queueEntries[0]->obj[i]["file"];
|
||||
} else missing = true;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("output") && queueEntries[0]->obj[i]["output"].is_string()) {
|
||||
output = queueEntries[0]->obj[i]["output"];
|
||||
} else missing = true;
|
||||
|
||||
if (!missing) ret = ScriptUtils::downloadFile(file, output, "", false);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
/* Download from a GitHub Release. */
|
||||
} else if (type == "downloadRelease") {
|
||||
bool missing = false, includePrereleases = false;
|
||||
std::string repo = "", file = "", output = "";
|
||||
|
||||
queueEntries[0]->status = QueueStatus::Downloading;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("repo") && queueEntries[0]->obj[i]["repo"].is_string()) {
|
||||
repo = queueEntries[0]->obj[i]["repo"];
|
||||
} else missing = true;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
|
||||
file = queueEntries[0]->obj[i]["file"];
|
||||
} else missing = true;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("output") && queueEntries[0]->obj[i]["output"].is_string()) {
|
||||
output = queueEntries[0]->obj[i]["output"];
|
||||
} else missing = true;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("includePrereleases") && queueEntries[0]->obj[i]["includePrereleases"].is_boolean())
|
||||
includePrereleases = queueEntries[0]->obj[i]["includePrereleases"];
|
||||
|
||||
if (!missing) ret = ScriptUtils::downloadRelease(repo, file, output, includePrereleases, "", false);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
/* Extracting files. */
|
||||
} else if (type == "extractFile") {
|
||||
bool missing = false;
|
||||
std::string file = "", input = "", output = "";
|
||||
queueEntries[0]->status = QueueStatus::Extracting;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
|
||||
file = queueEntries[0]->obj[i]["file"];
|
||||
} else missing = true;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("input") && queueEntries[0]->obj[i]["input"].is_string()) {
|
||||
input = queueEntries[0]->obj[i]["input"];
|
||||
} else missing = true;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("output") && queueEntries[0]->obj[i]["output"].is_string()) {
|
||||
output = queueEntries[0]->obj[i]["output"];
|
||||
} else missing = true;
|
||||
|
||||
if (!missing) ScriptUtils::extractFile(file, input, output, "", false);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
/* Installing CIAs. */
|
||||
} else if (type == "installCia") {
|
||||
bool missing = false, updateSelf = false;
|
||||
std::string file = "";
|
||||
queueEntries[0]->status = QueueStatus::Installing;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
|
||||
file = queueEntries[0]->obj[i]["file"];
|
||||
} else missing = true;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("updateSelf") && queueEntries[0]->obj[i]["updateSelf"].is_boolean()) {
|
||||
updateSelf = queueEntries[0]->obj[i]["updateSelf"];
|
||||
}
|
||||
|
||||
if (!missing) ScriptUtils::installFile(file, updateSelf, "");
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if (type == "mkdir") {
|
||||
bool missing = false;
|
||||
std::string directory = "";
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("directory") && queueEntries[0]->obj[i]["directory"].is_string()) {
|
||||
directory = queueEntries[0]->obj[i]["directory"];
|
||||
} else missing = true;
|
||||
|
||||
if (!missing) makeDirs(directory.c_str());
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
/* Request Type 1. */
|
||||
} else if (type == "rmdir") {
|
||||
bool missing = false;
|
||||
std::string directory = "", message = "", promptmsg = "";
|
||||
queueEntries[0]->status = QueueStatus::Request;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("directory") && queueEntries[0]->obj[i]["directory"].is_string()) {
|
||||
directory = queueEntries[0]->obj[i]["directory"];
|
||||
} else missing = true;
|
||||
|
||||
promptmsg = Lang::get("DELETE_PROMPT") + "\n" + directory;
|
||||
|
||||
if (!missing && directory != "") {
|
||||
if (access(directory.c_str(), F_OK) != 0) ret = DELETE_ERROR;
|
||||
else {
|
||||
if (QueueSystem::RequestNeeded == RMDIR_REQUEST) {
|
||||
/* There we already did it. :) */
|
||||
queueEntries[0]->status = QueueStatus::Deleting;
|
||||
if (QueueSystem::RequestAnswer == 1) removeDirRecursive(directory.c_str());
|
||||
/* Reset. */
|
||||
QueueSystem::RequestNeeded = NO_REQUEST;
|
||||
QueueSystem::RequestAnswer = NO_REQUEST;
|
||||
QueueSystem::RequestMsg = "";
|
||||
|
||||
} else {
|
||||
/* We are in the process of the need of an answer. */
|
||||
QueueSystem::RequestNeeded = RMDIR_REQUEST; // Type 1.
|
||||
QueueSystem::RequestMsg = promptmsg;
|
||||
QueueSystem::LastElement = i; // So we know, where we go again after the Request.
|
||||
ret = PROMPT_RET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
/* Request Type 2. */
|
||||
} else if (type == "promptMessage" || type == "promptMsg") {
|
||||
std::string Message = "";
|
||||
int skipCount = -1;
|
||||
queueEntries[0]->status = QueueStatus::Request;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("message") && queueEntries[0]->obj[i]["message"].is_string()) {
|
||||
Message = queueEntries[0]->obj[i]["message"];
|
||||
}
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("count") && queueEntries[0]->obj[i]["count"].is_number()) {
|
||||
skipCount = queueEntries[0]->obj[i]["count"];
|
||||
}
|
||||
|
||||
if (QueueSystem::RequestNeeded == PROMPT_REQUEST) {
|
||||
if ((skipCount > -1) && (QueueSystem::RequestAnswer == SCRIPT_CANCELED)) {
|
||||
i += skipCount; // Skip.
|
||||
queueEntries[0]->current += skipCount;
|
||||
}
|
||||
|
||||
/* Reset. */
|
||||
QueueSystem::RequestAnswer = NO_REQUEST;
|
||||
QueueSystem::RequestNeeded = NO_REQUEST;
|
||||
QueueSystem::RequestMsg = "";
|
||||
|
||||
} else {
|
||||
QueueSystem::RequestNeeded = PROMPT_REQUEST; // Type 2.
|
||||
QueueSystem::RequestMsg = Message;
|
||||
QueueSystem::LastElement = i; // So we know, where we go again after the Request.
|
||||
ret = PROMPT_RET;
|
||||
}
|
||||
|
||||
} else if (type == "exit") {
|
||||
ret = SCRIPT_CANCELED;
|
||||
|
||||
} else if (type == "copy") {
|
||||
std::string source = "", destination = "";
|
||||
bool missing = false;
|
||||
queueEntries[0]->status = QueueStatus::Copying;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("source") && queueEntries[0]->obj[i]["source"].is_string()) {
|
||||
source = queueEntries[0]->obj[i]["source"];
|
||||
} else missing = true;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("destination") && queueEntries[0]->obj[i]["destination"].is_string()) {
|
||||
destination = queueEntries[0]->obj[i]["destination"];
|
||||
} else missing = true;
|
||||
|
||||
if (!missing) ret = ScriptUtils::copyFile(source, destination, "");
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if (type == "move") {
|
||||
std::string oldFile = "", newFile = "";
|
||||
bool missing = false;
|
||||
queueEntries[0]->status = QueueStatus::Moving;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("old") && queueEntries[0]->obj[i]["old"].is_string()) {
|
||||
oldFile = queueEntries[0]->obj[i]["old"];
|
||||
} else missing = true;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("new") && queueEntries[0]->obj[i]["new"].is_string()) {
|
||||
newFile = queueEntries[0]->obj[i]["new"];
|
||||
} else missing = true;
|
||||
|
||||
if (!missing) ret = ScriptUtils::renameFile(oldFile, newFile, "");
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if (type == "skip") {
|
||||
int skipCount = -1;
|
||||
|
||||
if (queueEntries[0]->obj[i].contains("count") && queueEntries[0]->obj[i]["count"].is_number()) {
|
||||
skipCount = queueEntries[0]->obj[i]["count"];
|
||||
}
|
||||
|
||||
if (skipCount > 0) i += skipCount; // Skip.
|
||||
}
|
||||
|
||||
} else {
|
||||
queueEntries[0]->current = queueEntries[0]->total; // Set to total.
|
||||
ret = SCRIPT_CANCELED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we expect a prompt, we go to this. */
|
||||
if (ret == PROMPT_RET) {
|
||||
queueEntries[0]->current = QueueSystem::LastElement + 1; // Cause no Zero.
|
||||
QueueSystem::Wait = true;
|
||||
QueueRuns = false;
|
||||
}
|
||||
|
||||
if (!QueueSystem::Wait) {
|
||||
/* Canceled or None is for me -> Done. */
|
||||
if (ret == NONE || ret == SCRIPT_CANCELED) {
|
||||
queueEntries[0]->status = QueueStatus::Done;
|
||||
|
||||
} else { // Else it failed..
|
||||
queueEntries[0]->status = QueueStatus::Failed;
|
||||
}
|
||||
|
||||
/* Display if failed or succeeded. */
|
||||
if (config->prompt()) {
|
||||
char msg[256];
|
||||
|
||||
if (QueueSystem::CancelCallback) {
|
||||
snprintf(msg, sizeof(msg), Lang::get("ACTION_CANCELED").c_str(), queueEntries[0]->name.c_str());
|
||||
|
||||
} else {
|
||||
if (queueEntries[0]->status == QueueStatus::Failed) {
|
||||
snprintf(msg, sizeof(msg), Lang::get("ACTION_FAILED").c_str(), queueEntries[0]->name.c_str());
|
||||
|
||||
} else {
|
||||
snprintf(msg, sizeof(msg), Lang::get("ACTION_SUCCEEDED").c_str(), queueEntries[0]->name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
QueueSystem::EndMsg = msg;
|
||||
QueueSystem::Popup = true;
|
||||
}
|
||||
|
||||
if (StoreUtils::meta) {
|
||||
StoreUtils::meta->SetUpdated(queueEntries[0]->unistoreName, queueEntries[0]->entryName, queueEntries[0]->lastUpdated);
|
||||
StoreUtils::meta->SetInstalled(queueEntries[0]->unistoreName, queueEntries[0]->entryName, queueEntries[0]->name);
|
||||
StoreUtils::RefreshUpdateAVL();
|
||||
}
|
||||
|
||||
if (QueueSystem::CancelCallback) QueueSystem::CancelCallback = false; // Reset.
|
||||
|
||||
queueEntries.pop_front();
|
||||
if (QueueSystem::LastElement != 0) QueueSystem::LastElement = 0;
|
||||
if (queueEntries.empty()) QueueRuns = false; // The queue ended.
|
||||
ret = NONE; // Reset.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -37,7 +37,7 @@
|
||||
extern bool showProgressBar;
|
||||
extern ProgressBar progressbarType;
|
||||
extern char progressBarMsg[128];
|
||||
extern int filesExtracted;
|
||||
extern int filesExtracted, extractFilesCount;
|
||||
|
||||
extern void downloadFailed();
|
||||
static Thread thread;
|
||||
@@ -47,41 +47,41 @@ bool ScriptUtils::matchPattern(const std::string &pattern, const std::string &te
|
||||
return regex_match(tested, patternRegex);
|
||||
}
|
||||
|
||||
/*
|
||||
Remove a File.
|
||||
*/
|
||||
Result ScriptUtils::removeFile(const std::string &file, const std::string &message) {
|
||||
/* Remove a File. */
|
||||
Result ScriptUtils::removeFile(const std::string &file, const std::string &message, bool isARG) {
|
||||
std::string out;
|
||||
out = std::regex_replace(file, std::regex("%ARCHIVE_DEFAULT%"), config->archPath());
|
||||
out = std::regex_replace(out, std::regex("%3DSX%"), config->_3dsxPath());
|
||||
out = std::regex_replace(out, std::regex("%NDS%"), config->ndsPath());
|
||||
out = std::regex_replace(out, std::regex("%FIRM%"), config->firmPath());
|
||||
|
||||
Result ret = NONE;
|
||||
if (access(out.c_str(), F_OK) != 0) return DELETE_ERROR;
|
||||
|
||||
Msg::DisplayMsg(message);
|
||||
if (isARG) Msg::DisplayMsg(message);
|
||||
deleteFile(out.c_str());
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Boot a title.
|
||||
*/
|
||||
void ScriptUtils::bootTitle(const std::string &TitleID, bool isNAND, const std::string &message) {
|
||||
/* Boot a title. */
|
||||
void ScriptUtils::bootTitle(const std::string &TitleID, bool isNAND, const std::string &message, bool isARG) {
|
||||
std::string MSG = Lang::get("BOOT_TITLE") + "\n\n";
|
||||
if (isNAND) MSG += Lang::get("MEDIATYPE_NAND") + "\n" + TitleID;
|
||||
else MSG += Lang::get("MEDIATYPE_SD") + "\n" + TitleID;
|
||||
|
||||
const u64 ID = std::stoull(TitleID, 0, 16);
|
||||
if (isARG) {
|
||||
if (Msg::promptMsg(MSG)) {
|
||||
Msg::DisplayMsg(message);
|
||||
Title::Launch(ID, isNAND ? MEDIATYPE_NAND : MEDIATYPE_SD);
|
||||
}
|
||||
|
||||
} else {
|
||||
Title::Launch(ID, isNAND ? MEDIATYPE_NAND : MEDIATYPE_SD);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Prompt message.
|
||||
*/
|
||||
/* Prompt message. */
|
||||
Result ScriptUtils::prompt(const std::string &message) {
|
||||
Result ret = NONE;
|
||||
if (!Msg::promptMsg(message)) ret = SCRIPT_CANCELED;
|
||||
@@ -89,10 +89,8 @@ Result ScriptUtils::prompt(const std::string &message) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Copy.
|
||||
*/
|
||||
Result ScriptUtils::copyFile(const std::string &source, const std::string &destination, const std::string &message) {
|
||||
/* Copy. */
|
||||
Result ScriptUtils::copyFile(const std::string &source, const std::string &destination, const std::string &message, bool isARG) {
|
||||
Result ret = NONE;
|
||||
if (access(source.c_str(), F_OK) != 0) return COPY_ERROR;
|
||||
|
||||
@@ -100,10 +98,14 @@ Result ScriptUtils::copyFile(const std::string &source, const std::string &desti
|
||||
_source = std::regex_replace(source, std::regex("%ARCHIVE_DEFAULT%"), config->archPath());
|
||||
_source = std::regex_replace(_source, std::regex("%3DSX%"), config->_3dsxPath());
|
||||
_source = std::regex_replace(_source, std::regex("%NDS%"), config->ndsPath());
|
||||
_source = std::regex_replace(_source, std::regex("%FIRM%"), config->firmPath());
|
||||
|
||||
_dest = std::regex_replace(destination, std::regex("%ARCHIVE_DEFAULT%"), config->archPath());
|
||||
_dest = std::regex_replace(_dest, std::regex("%3DSX%"), config->_3dsxPath());
|
||||
_dest = std::regex_replace(_dest, std::regex("%NDS%"), config->ndsPath());
|
||||
_dest = std::regex_replace(_dest, std::regex("%FIRM%"), config->firmPath());
|
||||
|
||||
if (isARG) {
|
||||
snprintf(progressBarMsg, sizeof(progressBarMsg), message.c_str());
|
||||
showProgressBar = true;
|
||||
progressbarType = ProgressBar::Copying;
|
||||
@@ -111,6 +113,7 @@ Result ScriptUtils::copyFile(const std::string &source, const std::string &desti
|
||||
s32 prio = 0;
|
||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||
thread = threadCreate((ThreadFunc)Animation::displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false);
|
||||
}
|
||||
|
||||
/* If destination does not exist, create dirs. */
|
||||
if (access(_dest.c_str(), F_OK) != 0) makeDirs(_dest.c_str());
|
||||
@@ -118,17 +121,18 @@ Result ScriptUtils::copyFile(const std::string &source, const std::string &desti
|
||||
|
||||
if (ret == -1) ret = COPY_ERROR;
|
||||
else if (ret == 1) ret = NONE;
|
||||
|
||||
if (isARG) {
|
||||
showProgressBar = false;
|
||||
threadJoin(thread, U64_MAX);
|
||||
threadFree(thread);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Rename / Move a file.
|
||||
*/
|
||||
Result ScriptUtils::renameFile(const std::string &oldName, const std::string &newName, const std::string &message) {
|
||||
|
||||
/* Rename / Move a file. */
|
||||
Result ScriptUtils::renameFile(const std::string &oldName, const std::string &newName, const std::string &message, bool isARG) {
|
||||
Result ret = NONE;
|
||||
if (access(oldName.c_str(), F_OK) != 0) return MOVE_ERROR;
|
||||
|
||||
@@ -136,11 +140,14 @@ Result ScriptUtils::renameFile(const std::string &oldName, const std::string &ne
|
||||
old = std::regex_replace(oldName, std::regex("%ARCHIVE_DEFAULT%"), config->archPath());
|
||||
old = std::regex_replace(old, std::regex("%3DSX%"), config->_3dsxPath());
|
||||
old = std::regex_replace(old, std::regex("%NDS%"), config->ndsPath());
|
||||
old = std::regex_replace(old, std::regex("%FIRM%"), config->firmPath());
|
||||
|
||||
_new = std::regex_replace(newName, std::regex("%ARCHIVE_DEFAULT%"), config->archPath());
|
||||
_new = std::regex_replace(_new, std::regex("%3DSX%"), config->_3dsxPath());
|
||||
_new = std::regex_replace(_new, std::regex("%NDS%"), config->ndsPath());
|
||||
_new = std::regex_replace(_new, std::regex("%FIRM%"), config->firmPath());
|
||||
|
||||
Msg::DisplayMsg(message);
|
||||
if (isARG) Msg::DisplayMsg(message);
|
||||
|
||||
/* TODO: Kinda avoid that? */
|
||||
makeDirs(_new.c_str());
|
||||
@@ -148,17 +155,17 @@ Result ScriptUtils::renameFile(const std::string &oldName, const std::string &ne
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Download from GitHub Release.
|
||||
*/
|
||||
Result ScriptUtils::downloadRelease(const std::string &repo, const std::string &file, const std::string &output, bool includePrereleases, const std::string &message) {
|
||||
/* Download from GitHub Release. */
|
||||
Result ScriptUtils::downloadRelease(const std::string &repo, const std::string &file, const std::string &output, bool includePrereleases, const std::string &message, bool isARG) {
|
||||
std::string out;
|
||||
out = std::regex_replace(output, std::regex("%3DSX%"), config->_3dsxPath());
|
||||
out = std::regex_replace(out, std::regex("%NDS%"), config->ndsPath());
|
||||
out = std::regex_replace(out, std::regex("%ARCHIVE_DEFAULT%"), config->archPath());
|
||||
out = std::regex_replace(out, std::regex("%FIRM%"), config->firmPath());
|
||||
|
||||
Result ret = NONE;
|
||||
|
||||
if (isARG) {
|
||||
snprintf(progressBarMsg, sizeof(progressBarMsg), message.c_str());
|
||||
showProgressBar = true;
|
||||
progressbarType = ProgressBar::Downloading;
|
||||
@@ -166,32 +173,41 @@ Result ScriptUtils::downloadRelease(const std::string &repo, const std::string &
|
||||
s32 prio = 0;
|
||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||
thread = threadCreate((ThreadFunc)Animation::displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false);
|
||||
}
|
||||
|
||||
if (downloadFromRelease("https://github.com/" + repo, file, out, includePrereleases) != 0) {
|
||||
showProgressBar = false;
|
||||
if (isARG) showProgressBar = false;
|
||||
|
||||
downloadFailed();
|
||||
ret = FAILED_DOWNLOAD;
|
||||
|
||||
if (isARG) {
|
||||
threadJoin(thread, U64_MAX);
|
||||
threadFree(thread);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (isARG) {
|
||||
showProgressBar = false;
|
||||
threadJoin(thread, U64_MAX);
|
||||
threadFree(thread);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Download a file.
|
||||
*/
|
||||
Result ScriptUtils::downloadFile(const std::string &file, const std::string &output, const std::string &message) {
|
||||
/* Download a file. */
|
||||
Result ScriptUtils::downloadFile(const std::string &file, const std::string &output, const std::string &message, bool isARG) {
|
||||
std::string out;
|
||||
out = std::regex_replace(output, std::regex("%3DSX%"), config->_3dsxPath());
|
||||
out = std::regex_replace(out, std::regex("%NDS%"), config->ndsPath());
|
||||
out = std::regex_replace(out, std::regex("%ARCHIVE_DEFAULT%"), config->archPath());
|
||||
out = std::regex_replace(out, std::regex("%FIRM%"), config->firmPath());
|
||||
|
||||
Result ret = NONE;
|
||||
|
||||
if (isARG) {
|
||||
snprintf(progressBarMsg, sizeof(progressBarMsg), message.c_str());
|
||||
showProgressBar = true;
|
||||
progressbarType = ProgressBar::Downloading;
|
||||
@@ -199,31 +215,40 @@ Result ScriptUtils::downloadFile(const std::string &file, const std::string &out
|
||||
s32 prio = 0;
|
||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||
thread = threadCreate((ThreadFunc)Animation::displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false);
|
||||
}
|
||||
|
||||
if (downloadToFile(file, out) != 0) {
|
||||
showProgressBar = false;
|
||||
if (isARG) showProgressBar = false;
|
||||
|
||||
downloadFailed();
|
||||
ret = FAILED_DOWNLOAD;
|
||||
|
||||
if (isARG) {
|
||||
threadJoin(thread, U64_MAX);
|
||||
threadFree(thread);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (isARG) {
|
||||
showProgressBar = false;
|
||||
threadJoin(thread, U64_MAX);
|
||||
threadFree(thread);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Install CIA files.
|
||||
*/
|
||||
void ScriptUtils::installFile(const std::string &file, bool updatingSelf, const std::string &message) {
|
||||
/* Install CIA files. */
|
||||
void ScriptUtils::installFile(const std::string &file, bool updatingSelf, const std::string &message, bool isARG) {
|
||||
std::string in;
|
||||
in = std::regex_replace(file, std::regex("%ARCHIVE_DEFAULT%"), config->archPath());
|
||||
in = std::regex_replace(in, std::regex("%3DSX%"), config->_3dsxPath());
|
||||
in = std::regex_replace(in, std::regex("%NDS%"), config->ndsPath());
|
||||
in = std::regex_replace(in, std::regex("%FIRM%"), config->firmPath());
|
||||
|
||||
if (isARG) {
|
||||
snprintf(progressBarMsg, sizeof(progressBarMsg), message.c_str());
|
||||
showProgressBar = true;
|
||||
progressbarType = ProgressBar::Installing;
|
||||
@@ -231,43 +256,55 @@ void ScriptUtils::installFile(const std::string &file, bool updatingSelf, const
|
||||
s32 prio = 0;
|
||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||
thread = threadCreate((ThreadFunc)Animation::displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false);
|
||||
}
|
||||
|
||||
Title::Install(in.c_str(), updatingSelf);
|
||||
|
||||
if (isARG) {
|
||||
showProgressBar = false;
|
||||
threadJoin(thread, U64_MAX);
|
||||
threadFree(thread);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Extract files.
|
||||
*/
|
||||
void ScriptUtils::extractFile(const std::string &file, const std::string &input, const std::string &output, const std::string &message) {
|
||||
/* Extract files. */
|
||||
void ScriptUtils::extractFile(const std::string &file, const std::string &input, const std::string &output, const std::string &message, bool isARG) {
|
||||
extractFilesCount = 0;
|
||||
|
||||
std::string out, in;
|
||||
in = std::regex_replace(file, std::regex("%ARCHIVE_DEFAULT%"), config->archPath());
|
||||
in = std::regex_replace(in, std::regex("%3DSX%"), config->_3dsxPath());
|
||||
in = std::regex_replace(in, std::regex("%NDS%"), config->ndsPath());
|
||||
in = std::regex_replace(in, std::regex("%FIRM%"), config->firmPath());
|
||||
out = std::regex_replace(output, std::regex("%ARCHIVE_DEFAULT%"), config->archPath());
|
||||
out = std::regex_replace(out, std::regex("%3DSX%"), config->_3dsxPath());
|
||||
out = std::regex_replace(out, std::regex("%NDS%"), config->ndsPath());
|
||||
out = std::regex_replace(out, std::regex("%FIRM%"), config->firmPath());
|
||||
|
||||
if (isARG) {
|
||||
snprintf(progressBarMsg, sizeof(progressBarMsg), message.c_str());
|
||||
showProgressBar = true;
|
||||
filesExtracted = 0;
|
||||
progressbarType = ProgressBar::Extracting;
|
||||
|
||||
s32 prio = 0;
|
||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||
thread = threadCreate((ThreadFunc)Animation::displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false);
|
||||
}
|
||||
|
||||
filesExtracted = 0;
|
||||
|
||||
getExtractedSize(in, input);
|
||||
extractArchive(in, input, out);
|
||||
|
||||
if (isARG) {
|
||||
showProgressBar = false;
|
||||
threadJoin(thread, U64_MAX);
|
||||
threadFree(thread);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Execute | run the script.
|
||||
NOTE: This is for the argument system for now. This might get replaced completely with the Queue System in the future.
|
||||
*/
|
||||
Result ScriptUtils::runFunctions(nlohmann::json storeJson, int selection, const std::string &entry) {
|
||||
Result ret = NONE; // No Error as of yet.
|
||||
@@ -318,7 +355,7 @@ Result ScriptUtils::runFunctions(nlohmann::json storeJson, int selection, const
|
||||
message = Script[i]["message"];
|
||||
}
|
||||
|
||||
if (!missing) ret = ScriptUtils::removeFile(file, message);
|
||||
if (!missing) ret = ScriptUtils::removeFile(file, message, true);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if (type == "downloadFile") {
|
||||
@@ -339,7 +376,7 @@ Result ScriptUtils::runFunctions(nlohmann::json storeJson, int selection, const
|
||||
message = Script[i]["message"];
|
||||
}
|
||||
|
||||
if (!missing) ret = ScriptUtils::downloadFile(file, output, message);
|
||||
if (!missing) ret = ScriptUtils::downloadFile(file, output, message, true);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if (type == "downloadRelease") {
|
||||
@@ -368,7 +405,7 @@ Result ScriptUtils::runFunctions(nlohmann::json storeJson, int selection, const
|
||||
message = Script[i]["message"];
|
||||
}
|
||||
|
||||
if (!missing) ret = ScriptUtils::downloadRelease(repo, file, output, includePrereleases, message);
|
||||
if (!missing) ret = ScriptUtils::downloadRelease(repo, file, output, includePrereleases, message, true);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if (type == "extractFile") {
|
||||
@@ -394,7 +431,7 @@ Result ScriptUtils::runFunctions(nlohmann::json storeJson, int selection, const
|
||||
message = Script[i]["message"];
|
||||
}
|
||||
|
||||
if (!missing) ScriptUtils::extractFile(file, input, output, message);
|
||||
if (!missing) ScriptUtils::extractFile(file, input, output, message, true);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if (type == "installCia") {
|
||||
@@ -414,7 +451,7 @@ Result ScriptUtils::runFunctions(nlohmann::json storeJson, int selection, const
|
||||
message = Script[i]["message"];
|
||||
}
|
||||
|
||||
if (!missing) ScriptUtils::installFile(file, updateSelf, message);
|
||||
if (!missing) ScriptUtils::installFile(file, updateSelf, message, true);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if (type == "mkdir") {
|
||||
@@ -488,7 +525,7 @@ Result ScriptUtils::runFunctions(nlohmann::json storeJson, int selection, const
|
||||
Message = Script[i]["message"];
|
||||
}
|
||||
|
||||
if (!missing) ret = ScriptUtils::copyFile(source, destination, Message);
|
||||
if (!missing) ret = ScriptUtils::copyFile(source, destination, Message, true);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if (type == "move") {
|
||||
@@ -509,7 +546,7 @@ Result ScriptUtils::runFunctions(nlohmann::json storeJson, int selection, const
|
||||
Message = Script[i]["message"];
|
||||
}
|
||||
|
||||
if (!missing) ret = ScriptUtils::renameFile(oldFile, newFile, Message);
|
||||
if (!missing) ret = ScriptUtils::renameFile(oldFile, newFile, Message, true);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if (type == "skip") {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Universal-Updater
|
||||
* Copyright (C) 2019-2020 Universal-Team
|
||||
* Copyright (C) 2019-2021 Universal-Team
|
||||
*
|
||||
* 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
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "common.hpp"
|
||||
#include "stringutils.hpp"
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
To lowercase conversion.
|
||||
@@ -69,9 +70,9 @@ std::string StringUtils::formatBytes(int bytes) {
|
||||
|
||||
if (bytes == 1) snprintf(out, sizeof(out), "%d Byte", bytes);
|
||||
else if (bytes < 1024) snprintf(out, sizeof(out), "%d Bytes", bytes);
|
||||
else if (bytes < 1024 * 1024) snprintf(out, sizeof(out), "%.1f KB", (float)bytes / 1024);
|
||||
else if (bytes < 1024 * 1024 * 1024) snprintf(out, sizeof(out), "%.1f MB", (float)bytes / 1024 / 1024);
|
||||
else snprintf(out, sizeof(out), "%.1f GB", (float)bytes / 1024 / 1024 / 1024);
|
||||
else if (bytes < 1024 * 1024) snprintf(out, sizeof(out), "%.1f KiB", (float)bytes / 1024);
|
||||
else if (bytes < 1024 * 1024 * 1024) snprintf(out, sizeof(out), "%.1f MiB", (float)bytes / 1024 / 1024);
|
||||
else snprintf(out, sizeof(out), "%.1f GiB", (float)bytes / 1024 / 1024 / 1024);
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -105,3 +106,14 @@ std::string StringUtils::GetMarkString(int marks) {
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string StringUtils::format(const std::string &fmt_str, ...) {
|
||||
va_list ap;
|
||||
char *fp = nullptr;
|
||||
va_start(ap, fmt_str);
|
||||
vasprintf(&fp, fmt_str.c_str(), ap);
|
||||
va_end(ap);
|
||||
|
||||
std::unique_ptr<char, decltype(free) *> formatted(fp, free);
|
||||
return std::string(formatted.get());
|
||||
}
|
||||