diff --git a/assets/data/icons/RemixIcon/global-line.svg b/assets/data/icons/RemixIcon/global-line.svg
new file mode 100644
index 0000000..c1d81d7
--- /dev/null
+++ b/assets/data/icons/RemixIcon/global-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/data/icons/RemixIcon/hand-coin-line.svg b/assets/data/icons/RemixIcon/hand-coin-line.svg
new file mode 100644
index 0000000..94a3e4c
--- /dev/null
+++ b/assets/data/icons/RemixIcon/hand-coin-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/data/icons/RemixIcon/question-line.svg b/assets/data/icons/RemixIcon/question-line.svg
new file mode 100644
index 0000000..5409158
--- /dev/null
+++ b/assets/data/icons/RemixIcon/question-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/GlobalConfig.hpp b/src/GlobalConfig.hpp
index b7713de..dd366b0 100644
--- a/src/GlobalConfig.hpp
+++ b/src/GlobalConfig.hpp
@@ -85,8 +85,7 @@ class GlobalConfig {
void load_palettes();
void load_licenses();
- bool showPerformance = false;
- bool checkForUpdates = false;
+ bool checkForUpdates = true;
bool useNativeFilePicker = true;
std::string themeCurrentlyLoaded = "Default";
diff --git a/src/MainProgram.cpp b/src/MainProgram.cpp
index 656936e..d5f40c0 100755
--- a/src/MainProgram.cpp
+++ b/src/MainProgram.cpp
@@ -52,6 +52,8 @@
#include
+#define UPDATE_NOTIFICATION_URL "https://infinipaint.com/updateNotificationVersion.txt"
+
MainProgram::MainProgram():
input(*this),
fonts(std::make_shared()),
@@ -108,12 +110,61 @@ void MainProgram::update() {
deltaTime.update_time_point();
input.update();
g.update();
+ update_notification_check();
screen->update();
background_update();
NetThreadManager::get().synchronous_update();
post_callback();
}
+void MainProgram::update_notification_check() {
+#ifndef __EMSCRIPTEN__
+ if(!updateCheckerData.updateCheckDone) {
+ if(conf.checkForUpdates) {
+ if(!updateCheckerData.versionFile)
+ updateCheckerData.versionFile = FileDownloader::download_data_from_url(UPDATE_NOTIFICATION_URL);
+ else {
+ switch(updateCheckerData.versionFile->status) {
+ case FileDownloader::DownloadData::Status::IN_PROGRESS:
+ break;
+ case FileDownloader::DownloadData::Status::SUCCESS: {
+ updateCheckerData.updateCheckDone = true;
+ std::optional newVersion = version_str_to_version_numbers(updateCheckerData.versionFile->str);
+ std::optional currentVersion = VersionConstants::CURRENT_VERSION_NUMBER;
+ if(newVersion.has_value() && currentVersion.has_value()) {
+ VersionNumber& newV = newVersion.value();
+ VersionNumber& currentV = currentVersion.value();
+ updateCheckerData.newVersionStr = version_numbers_to_version_str(newV);
+ Logger::get().log(Logger::LogType::INFO, "Latest online version is v" + updateCheckerData.newVersionStr);
+ if(newV > currentV) {
+ updateCheckerData.showGui = true;
+ Logger::get().log(Logger::LogType::PHONE_USERINFO, "New version v" + updateCheckerData.newVersionStr + " available");
+ g.gui.set_to_layout();
+ }
+ else if(newV == currentV)
+ Logger::get().log(Logger::LogType::INFO, "Current version is up to date");
+ else
+ Logger::get().log(Logger::LogType::INFO, "Local version has larger version number than the latest online one");
+ }
+ else
+ Logger::get().log(Logger::LogType::INFO, "Update notification file couldn't be converted to version numbers");
+ updateCheckerData.versionFile = nullptr;
+ break;
+ }
+ case FileDownloader::DownloadData::Status::FAILURE:
+ Logger::get().log(Logger::LogType::INFO, "Failed to check for updates");
+ updateCheckerData.updateCheckDone = true;
+ updateCheckerData.versionFile = nullptr;
+ break;
+ }
+ }
+ }
+ else
+ updateCheckerData.updateCheckDone = true;
+ }
+#endif
+}
+
void MainProgram::background_update() {
bool isAnyWorldConnected = false;
for(auto& w : worlds) {
diff --git a/src/MainProgram.hpp b/src/MainProgram.hpp
index 5a447a8..e7d6fe6 100644
--- a/src/MainProgram.hpp
+++ b/src/MainProgram.hpp
@@ -63,6 +63,7 @@ struct UserLogMessage {
class MainProgram {
public:
static constexpr size_t LOG_SIZE = 30;
+ static constexpr const char* UPDATE_DOWNLOAD_URL = "https://infinipaint.com/download.html";
InputManager input;
@@ -191,6 +192,15 @@ class MainProgram {
void switch_to_tab(size_t wIndex);
~MainProgram();
+
+ void update_notification_check();
+ struct UpdateCheckerData {
+ bool showGui = false;
+ bool updateCheckDone = false;
+ std::string newVersionStr;
+ std::shared_ptr versionFile;
+ } updateCheckerData;
+
private:
std::unordered_set tabsToClose;
void close_set_to_close_tabs();
diff --git a/src/Screens/FileSelectScreen.cpp b/src/Screens/FileSelectScreen.cpp
index 277e1e4..1f19a7e 100644
--- a/src/Screens/FileSelectScreen.cpp
+++ b/src/Screens/FileSelectScreen.cpp
@@ -151,7 +151,7 @@ void FileSelectScreen::global_log() {
auto& gui = main.g.gui;
auto& io = gui.io;
- float notificationSize = std::min(300.0f, gui.io.safeWindowRect.width() - 20.0f);
+ float notificationSize = std::min(240.0f, gui.io.safeWindowRect.width() - 20.0f);
gui.set_z_index(gui.get_z_index() + 100, [&] {
gui.new_id("Global log popup list file select screen", [&] {
@@ -298,13 +298,33 @@ void FileSelectScreen::main_display() {
case SelectedMenu::SETTINGS:
settings_view();
break;
+ case SelectedMenu::ABOUT:
+ about_view();
+ break;
}
global_log();
}
window_gap_side_bar(gui, WindowFillSideBarConfig::Direction::RIGHT);
}
- window_gap_side_bar(gui, WindowFillSideBarConfig::Direction::BOTTOM);
- edit_action_bar();
+ switch(selectedMenu) {
+ case SelectedMenu::FILES:
+ window_gap_side_bar(gui, WindowFillSideBarConfig::Direction::BOTTOM);
+ edit_action_bar();
+ break;
+ case SelectedMenu::TRASH:
+ window_gap_side_bar(gui, WindowFillSideBarConfig::Direction::BOTTOM);
+ edit_action_bar();
+ break;
+ case SelectedMenu::CONNECT:
+ window_gap_side_bar(gui, WindowFillSideBarConfig::Direction::BOTTOM);
+ break;
+ case SelectedMenu::SETTINGS:
+ window_gap_side_bar(gui, WindowFillSideBarConfig::Direction::BOTTOM);
+ break;
+ case SelectedMenu::ABOUT:
+ about_bottom_bar();
+ break;
+ }
menu_black_box();
}
}
@@ -441,6 +461,69 @@ void FileSelectScreen::delete_selected_files_in_trash() {
}
}
+void FileSelectScreen::about_bottom_bar() {
+ auto& gui = main.g.gui;
+ gui.element("about bottom bar fill", [&](LayoutElement*, const Clay_ElementId& lId) {
+ CLAY(lId, {}) {
+ window_fill_side_bar(gui, {
+ .dir = WindowFillSideBarConfig::Direction::BOTTOM,
+ .backgroundColor = gui.io.theme->backColor1
+ }, [&] {
+ gui.element("about bottom bar", [&](LayoutElement*, const Clay_ElementId& lId) {
+ CLAY(lId, {
+ .layout = {
+ .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(40)},
+ .layoutDirection = CLAY_LEFT_TO_RIGHT
+ }
+ }) {
+ gui.element("about scroll area", ScrollArea::Options{
+ .scrollHorizontal = true,
+ .clipHorizontal = true,
+ .scrollbarX = ScrollArea::ScrollbarType::NORMAL,
+ .innerContent = [&] (auto&) {
+ CLAY_AUTO_ID({
+ .layout = {
+ .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
+ .layoutDirection = CLAY_LEFT_TO_RIGHT
+ },
+ }) {
+ CLAY_AUTO_ID({
+ .layout = {
+ .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0)}
+ }
+ }) {
+ text_button(gui, "infinipaintnoticebutton", "InfiniPaint", {
+ .drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
+ .isSelected = selectedLicense == -1,
+ .onClick = [&] { selectedLicense = -1; }
+ });
+ }
+ for(int i = 0; i < static_cast(main.conf.thirdPartyLicenses.size()); i++) {
+ CLAY_AUTO_ID({
+ .layout = {
+ .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0) },
+ .padding = CLAY_PADDING_ALL(1)
+ }
+ }) {
+ gui.new_id(i, [&] {
+ text_button(gui, "noticebutton", main.conf.thirdPartyLicenses[i].first, {
+ .drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
+ .isSelected = selectedLicense == i,
+ .onClick = [&, i] { selectedLicense = i; }
+ });
+ });
+ }
+ }
+ }
+ }
+ });
+ }
+ });
+ });
+ }
+ });
+}
+
void FileSelectScreen::edit_action_bar() {
auto& gui = main.g.gui;
if(actionBarOpenAnim->get_val()) {
@@ -578,6 +661,9 @@ void FileSelectScreen::title_bar() {
case SelectedMenu::SETTINGS:
mutable_text_label(gui, "main screen header text settings", "Settings");
break;
+ case SelectedMenu::ABOUT:
+ mutable_text_label(gui, "main screen header about", "About");
+ break;
}
CLAY_AUTO_ID({
.layout = {
@@ -785,6 +871,17 @@ void FileSelectScreen::main_menu() {
mainMenuOpenAnim->animation_trigger_reverse();
if(mainViewScrollArea) mainViewScrollArea->reset_scroll();
});
+ icon_text_transparent_option_selected_button("About", "data/icons/RemixIcon/question-line.svg", "About", selectedMenu == SelectedMenu::ABOUT, [&] {
+ selectedMenu = SelectedMenu::ABOUT;
+ mainMenuOpenAnim->animation_trigger_reverse();
+ if(mainViewScrollArea) mainViewScrollArea->reset_scroll();
+ });
+ icon_text_transparent_option_selected_button("Website", "data/icons/RemixIcon/global-line.svg", "Website", false, [&] {
+ SDL_OpenURL("https://infinipaint.com/");
+ });
+ icon_text_transparent_option_selected_button("Donate", "data/icons/RemixIcon/hand-coin-line.svg", "Donate", false, [&] {
+ SDL_OpenURL("https://infinipaint.com/donate.html");
+ });
}
}
});
@@ -1015,19 +1112,43 @@ void FileSelectScreen::settings_view() {
slider_scalar_field(gui, "tablet brush minimum size", "Brush relative minimum size", &main.conf.tabletOptions.brushMinimumSize, 0.0f, 1.0f, {.decimalPrecision = 3});
slider_scalar_field(gui, "tablet brush pressure smoothing factor", "Brush pressure smoothing factor", &main.conf.tabletOptions.brushPressureSmoothingFactor, 0.0f, 1.0f, {.decimalPrecision = 3});
checkbox_boolean_field(gui, "pen pressure width", "Pen pressure affects brush size", &main.conf.tabletOptions.pressureAffectsBrushWidth);
-#ifndef __ANDROID__
- checkbox_boolean_field(gui, "use mobile UI", "Use mobile UI (requires restart)", &main.conf.mobileUI);
-#endif
+ #ifndef __ANDROID__
+ checkbox_boolean_field(gui, "use mobile UI", "Use mobile UI (requires restart)", &main.conf.mobileUI);
+ #endif
+ #ifndef __EMSCRIPTEN__
+ checkbox_boolean_field(gui, "update notifications enable", "Check for updates on startup", &main.conf.checkForUpdates);
+ #endif
}
}
}
});
}
+void FileSelectScreen::about_view() {
+ auto& gui = main.g.gui;
+ auto& io = gui.io;
+
+ mainViewScrollArea = gui.element("about scroll area", ScrollArea::Options{
+ .scrollVertical = true,
+ .clipVertical = true,
+ .scrollbarY = ScrollArea::ScrollbarType::NORMAL,
+ .innerContent = [&] (auto&) {
+ CLAY_AUTO_ID({
+ .layout = {
+ .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
+ .layoutDirection = CLAY_LEFT_TO_RIGHT
+ },
+ }) {
+ text_label_size(gui, (selectedLicense == -1) ? main.conf.ownLicenseText : main.conf.thirdPartyLicenses[selectedLicense].second, 0.8f);
+ }
+ }
+ });
+}
+
void FileSelectScreen::menu_black_box() {
auto& gui = main.g.gui;
if(!mainMenuOpenAnim->is_at_start()) {
- gui.set_z_index(gui.get_z_index() + 1, [&] {
+ gui.set_z_index(gui.get_z_index() + 2000, [&] {
gui.element("file list disable fill", [&] (LayoutElement* l, const Clay_ElementId& lId) {
CLAY(lId, {
.layout = {
diff --git a/src/Screens/FileSelectScreen.hpp b/src/Screens/FileSelectScreen.hpp
index 589b5d1..a2f5812 100644
--- a/src/Screens/FileSelectScreen.hpp
+++ b/src/Screens/FileSelectScreen.hpp
@@ -93,10 +93,12 @@ class FileSelectScreen : public Screen {
void file_view();
void connect_view();
void settings_view();
+ void about_view();
void create_file_button();
void file_view_edit();
void menu_black_box();
void edit_action_bar();
+ void about_bottom_bar();
void edit_title_bar();
void title_bar();
void text_transparent_option_button(const char* id, const char* text, const std::function& onClick);
@@ -123,9 +125,12 @@ class FileSelectScreen : public Screen {
FILES,
TRASH,
CONNECT,
- SETTINGS
+ SETTINGS,
+ ABOUT
} selectedMenu = SelectedMenu::FILES;
+ int selectedLicense = -1;
+
void start_edit_mode();
size_t numberOfSelectedEntries;
bool editMode = false;
diff --git a/src/Screens/PhoneDrawingProgramScreen.cpp b/src/Screens/PhoneDrawingProgramScreen.cpp
index 12a9b04..7210a18 100644
--- a/src/Screens/PhoneDrawingProgramScreen.cpp
+++ b/src/Screens/PhoneDrawingProgramScreen.cpp
@@ -366,7 +366,7 @@ void PhoneDrawingProgramScreen::global_log() {
auto& gui = main.g.gui;
auto& io = gui.io;
- float notificationSize = std::min(300.0f, gui.io.safeWindowRect.width() - 20.0f);
+ float notificationSize = std::min(240.0f, gui.io.safeWindowRect.width() - 20.0f);
gui.new_id("Global log popup list phone drawing screen", [&] {
CLAY_AUTO_ID({
diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp
index 4a2e1ff..8be3382 100644
--- a/src/Toolbar.cpp
+++ b/src/Toolbar.cpp
@@ -73,9 +73,6 @@
#include "Screens/DesktopDrawingProgramScreen.hpp"
-#define UPDATE_DOWNLOAD_URL "https://infinipaint.com/download.html"
-#define UPDATE_NOTIFICATION_URL "https://infinipaint.com/updateNotificationVersion.txt"
-
#ifdef __EMSCRIPTEN__
#include
#endif
@@ -199,10 +196,6 @@ void Toolbar::layout_run() {
auto& gui = main.g.gui;
auto& io = gui.io;
-#ifndef __EMSCRIPTEN__
- update_notification_check();
-#endif
-
if(drawGui) {
CLAY_AUTO_ID({
.layout = {
@@ -220,10 +213,8 @@ void Toolbar::layout_run() {
close_popup_gui();
if(main.conf.viewWebVersionWelcome)
web_version_welcome();
-#ifndef __EMSCRIPTEN__
- else if(updateCheckerData.showGui)
+ else if(main.updateCheckerData.showGui)
update_notification_gui();
-#endif
else if(filePicker.isOpen)
file_picker_gui();
else if(optionsMenuOpen)
@@ -671,82 +662,35 @@ void Toolbar::center_message(const char* id, const std::string& m) {
});
}
-#ifndef __EMSCRIPTEN__
-void Toolbar::update_notification_check() {
- if(!updateCheckerData.updateCheckDone) {
- if(main.conf.checkForUpdates) {
- if(!updateCheckerData.versionFile)
- updateCheckerData.versionFile = FileDownloader::download_data_from_url(UPDATE_NOTIFICATION_URL);
- else {
- switch(updateCheckerData.versionFile->status) {
- case FileDownloader::DownloadData::Status::IN_PROGRESS:
- break;
- case FileDownloader::DownloadData::Status::SUCCESS: {
- updateCheckerData.updateCheckDone = true;
- std::optional newVersion = version_str_to_version_numbers(updateCheckerData.versionFile->str);
- std::optional currentVersion = VersionConstants::CURRENT_VERSION_NUMBER;
- if(newVersion.has_value() && currentVersion.has_value()) {
- VersionNumber& newV = newVersion.value();
- VersionNumber& currentV = currentVersion.value();
- updateCheckerData.newVersionStr = version_numbers_to_version_str(newV);
- Logger::get().log(Logger::LogType::INFO, "Latest online version is v" + updateCheckerData.newVersionStr);
- if(newV > currentV) {
- updateCheckerData.showGui = true;
- main.g.gui.set_to_layout();
- }
- else if(newV == currentV)
- Logger::get().log(Logger::LogType::INFO, "Current version is up to date");
- else
- Logger::get().log(Logger::LogType::INFO, "Local version has larger version number than the latest online one");
- }
- else
- Logger::get().log(Logger::LogType::INFO, "Update notification file couldn't be converted to version numbers");
- updateCheckerData.versionFile = nullptr;
- break;
- }
- case FileDownloader::DownloadData::Status::FAILURE:
- Logger::get().log(Logger::LogType::INFO, "Failed to check for updates");
- updateCheckerData.updateCheckDone = true;
- updateCheckerData.versionFile = nullptr;
- break;
- }
- }
- }
- else
- updateCheckerData.updateCheckDone = true;
- }
-}
-
void Toolbar::update_notification_gui() {
auto& gui = main.g.gui;
center_obstructing_window_gui("Update notifications GUI", CLAY_SIZING_FIXED(700), CLAY_SIZING_FIT(0), [&] {
gui.new_id("update notification gui", [&] {
- text_label_centered(gui, "Update v" + updateCheckerData.newVersionStr + " available!");
+ text_label_centered(gui, "Update v" + main.updateCheckerData.newVersionStr + " available!");
text_button(gui, "download", "Open download page in web browser", {
.wide = true,
.onClick = [&]{
- SDL_OpenURL(UPDATE_DOWNLOAD_URL);
- updateCheckerData.showGui = false;
+ SDL_OpenURL(MainProgram::UPDATE_DOWNLOAD_URL);
+ main.updateCheckerData.showGui = false;
}
});
text_button(gui, "ignore forever", "Ignore and don't notify again (can be changed in settings)", {
.wide = true,
.onClick = [&]{
main.conf.checkForUpdates = false;
- updateCheckerData.showGui = false;
+ main.updateCheckerData.showGui = false;
}
});
text_button(gui, "ignore for now", "Ignore for now", {
.wide = true,
.onClick = [&]{
- updateCheckerData.showGui = false;
+ main.updateCheckerData.showGui = false;
}
});
});
});
}
-#endif
void Toolbar::grid_menu(Element* gridMenuButton) {
auto& gui = main.g.gui;
diff --git a/src/Toolbar.hpp b/src/Toolbar.hpp
index bd855fb..9e1de72 100644
--- a/src/Toolbar.hpp
+++ b/src/Toolbar.hpp
@@ -131,16 +131,7 @@ class Toolbar {
bool closeAppWhenDone = false;
} closePopupData;
- #ifndef __EMSCRIPTEN__
void update_notification_gui();
- void update_notification_check();
- struct UpdateCheckerData {
- bool showGui = false;
- bool updateCheckDone = false;
- std::string newVersionStr;
- std::shared_ptr versionFile;
- } updateCheckerData;
- #endif
int selectedLicense = -1;