/* * InfiniPaint * Copyright (C) 2025-2026 Yousef Khadadeh * * 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 . */ #pragma once #include "GUIStuff/Elements/ScrollArea.hpp" #include "DrawData.hpp" #include "TimePoint.hpp" #include "Helpers/FileDownloader.hpp" #include #include #include #include #include #include #include "Screens/Screen.hpp" class MainProgram; class DesktopDrawingProgramScreen; class Toolbar { public: struct ChatMessage { static constexpr float DISPLAY_TIME = 8.0f; static constexpr float FADE_START_TIME = 7.0f; std::string name; std::string message; enum Type { NORMAL = 0, JOIN } type; TimePoint time; }; std::string chatMessageInput; Toolbar(MainProgram& initMain, DesktopDrawingProgramScreen& initDrawScreen); void update(); void layout_run(); struct ColorSelectorData { std::function onChange; std::function onSelect; std::function onDeselect; }; struct ColorSelectorButtonData { std::function onSelectorButtonClick; std::function onChange; std::function onSelect; std::function onDeselect; }; void color_selector_left(GUIStuff::Element* button, Vector4f* color, const ColorSelectorData& colorSelectorData = {}); void color_selector_right(GUIStuff::Element* button, Vector4f* color, const ColorSelectorData& colorSelectorData = {}); void color_button_left(const char* id, Vector4f* color, const ColorSelectorButtonData& colorSelectorData = {}); void color_button_right(const char* id, Vector4f* color, const ColorSelectorButtonData& colorSelectorData = {}); void paint_popup(Vector2f popupPos); void open_file_selector(const std::string& filePickerName, const std::vector& extensionFilters, Screen::OpenFileSelectorCallback postSelectionFunc, const std::string& fileName = "", bool isSaving = false); void open_file_selector_non_native(const std::string& filePickerName, const std::vector& extensionFilters, Screen::OpenFileSelectorCallback postSelectionFunc, const std::string& fileName = "", bool isSaving = false); void save_func(); void save_as_func(); void open_chatbox(); void close_chatbox(); void toggle_player_list(); bool drawGui = true; bool app_close_requested(); private: static void sdl_open_file_dialog_callback(void* userData, const char * const * fileList, int filter); void text_button_wide(const char* id, const char* str, const std::function& onClick); void reload_theme_list(); void player_list(); void chat_box(); void global_log(); void top_toolbar(); void grid_menu(GUIStuff::Element* gridMenuButton); void stop_displaying_grid_menu(); void stop_displaying_bookmark_menu(); void stop_displaying_layer_menu(); void bookmark_menu(GUIStuff::Element* bookmarkMenuButton); void layer_menu(GUIStuff::Element* layerMenuButton); void drawing_program_gui(); void options_menu(); void file_picker_gui_refresh_entries(); void file_picker_gui_done(); void file_picker_gui(); void color_picker_window(const char* id, Vector4f** color, GUIStuff::Element* b, const ColorSelectorData& colorSelectorData); void color_palette(const char* id, Vector4f* color, const std::function& onChange); void open_world_file(bool isClient, const std::string& netSource, const std::string& serverLocalID); void load_default_theme(); void about_menu_inner_gui(); void web_version_welcome(); void center_message(const char* id, const std::string& m); void close_popup_gui(); void add_world_to_close_popup_data(const std::shared_ptr& w); void general_settings_inner_gui(); void center_obstructing_window_gui(const char* id, Clay_SizingAxis x, Clay_SizingAxis y, const std::function& innerContent); GUIStuff::Element* colorLeftButton; Vector4f* colorLeft = nullptr; ColorSelectorData colorLeftData; GUIStuff::Element* colorRightButton; Vector4f* colorRight = nullptr; ColorSelectorData colorRightData; struct ClosePopupData { struct CloseWorldData { std::weak_ptr w; bool setToSave = true; }; std::vector worldsToClose; // Using a vector to ensure that the worlds are in proper order bool closeAppWhenDone = false; } closePopupData; void update_notification_gui(); int selectedLicense = -1; std::string downloadNameSet; struct PaletteData { size_t selectedPalette = 0; bool addingPalette = false; std::string newPaletteStr; } paletteData; struct ThemeData { std::vector themeDirList; std::optional selectedThemeIndex; bool openedSaveAsMenu = false; } themeData; bool menuPopUpOpen = false; bool optionsMenuOpen = false; bool playerMenuOpen = false; float finalCalculatedGuiScale = 1.0f; bool chatboxOpen = false; enum OptionsMenuType { HOST_MENU, CONNECT_MENU, GENERAL_SETTINGS_MENU, LOBBY_INFO_MENU, CANVAS_SETTINGS_MENU, SET_DOWNLOAD_NAME, ABOUT_MENU } optionsMenuType; enum GeneralSettingsOptions { GSETTINGS_GENERAL = 0, GSETTINGS_IMAGES, GSETTINGS_GRAPHICS, GSETTINGS_TABLET, GSETTINGS_THEME, GSETTINGS_KEYBINDS, GSETTINGS_DEBUG } generalSettingsOptions = GSETTINGS_GENERAL; bool bookmarkMenuPopupOpen = false; bool layerMenuPopupOpen = false; bool gridMenuPopupOpen = false; struct FilePicker { bool isOpen = false; std::string filePickerWindowName; std::vector extensionFiltersComplete; std::vector extensionFilters; std::vector entries; std::filesystem::path currentSelectedPath; std::string fileName = ""; bool isSaving = false; size_t extensionSelected; GUIStuff::ScrollArea* entriesScrollArea = nullptr; Screen::OpenFileSelectorCallback postSelectionFunc; } filePicker; RichText::TextData build_paragraph_from_chat_message(const ChatMessage& message, float alpha); void load_icons_at(const std::filesystem::path& pathToLoad); std::string serverToConnectTo; std::string serverLocalID; MainProgram& main; DesktopDrawingProgramScreen& drawScreen; };