12 const std::string kDownloadUrlPrefix =
"";
13 const std::string kPacksUrlPrefix =
"";
14 const std::string kTokenUrlQuery =
"?idToken=";
18 Overlay(std::move(name)), auth_(auth),
19 body_(
Shaders::kRoundedRectangleFragment),
20 download_progress_(
Shaders::kColorFragment),
21 download_background_(
Shaders::kColorFragment),
22 install_text_background_(
Shaders::kRoundedRectangleFragment),
23 install_thread_(this) {
27 progress_value_ = 0.0f;
35 logo_ = std::make_unique<AppLogo>(
"logo");
38 loading_wheel_ = std::make_unique<LoadingWheel>();
41 install_button_ = std::make_unique<OpenGlToggleButton>(
"Install");
42 install_button_->setText(
"Install");
43 install_button_->setUiButton(
true);
44 install_button_->addListener(
this);
45 install_button_->setEnabled(
false);
46 addAndMakeVisible(install_button_.get());
49 cancel_button_ = std::make_unique<OpenGlToggleButton>(
"Cancel");
50 cancel_button_->setText(
"Cancel");
51 cancel_button_->setUiButton(
false);
52 cancel_button_->addListener(
this);
53 addAndMakeVisible(cancel_button_.get());
56 download_text_ = std::make_unique<PlainTextComponent>(
"Download",
"Downloading factory content...");
60 download_text_->setJustification(Justification::centred);
63 install_location_text_ = std::make_unique<PlainTextComponent>(
"Location", install_location_.getFullPathName());
67 install_location_text_->setJustification(Justification::centredLeft);
69 folder_button_ = std::make_unique<OpenGlShapeButton>(
"Folder");
70 addAndMakeVisible(folder_button_.get());
72#if !defined(NO_TEXT_ENTRY)
73 folder_button_->addListener(
this);
75 folder_button_->setTriggeredOnMouseDown(
true);
78 available_packs_location_ = File::getSpecialLocation(File::tempDirectory).getChildFile(
"available_packs.json");
82 static constexpr int kLogoWidth = 128;
83 static constexpr int kDownloadHeight = 8;
84 static constexpr float kRingThicknessRatio = 0.03f;
85 static constexpr float kRingMarginRatio = 0.03f;
90 download_background_.
setColor(background);
91 install_text_background_.
setColor(background);
98 body_.setBounds(download_rect);
105 int logo_x = (getWidth() - logo_width) / 2;
106 int logo_y = download_rect.getY() + padding_y;
107 logo_->setBounds(logo_x, logo_y, logo_width, logo_width);
109 int wheel_margin = logo_width * kRingMarginRatio;
110 loading_wheel_->setBounds(logo_->getX() - wheel_margin, logo_->getY() - wheel_margin,
111 logo_->getWidth() + 2 * wheel_margin, logo_->getHeight() + 2 * wheel_margin);
112 loading_wheel_->setThickness(logo_width * kRingThicknessRatio);
114 float button_width = (download_rect.getWidth() - 3 * padding_x) / 2;
115 install_button_->setBounds(download_rect.getX() + padding_x,
116 download_rect.getBottom() - padding_y - button_height,
117 button_width, button_height);
118 cancel_button_->setBounds(install_button_->getRight() + padding_x, install_button_->getY(),
119 download_rect.getRight() - 2 * padding_x - install_button_->getRight(), button_height);
122 download_text_->setTextSize(text_size);
124 download_text_->setBounds(download_rect.getX() + padding_x, logo_y + logo_width + padding_y,
125 download_rect.getWidth() - 2 * padding_x, text_height);
126 int download_height =
size_ratio_ * kDownloadHeight;
127 int download_y = (download_text_->getBottom() + install_button_->getY() -
128 download_height + text_size - text_height) / 2;
129 if (initial_download_) {
130 folder_button_->setBounds(install_button_->getX(), install_button_->getY() - padding_y - button_height,
131 button_height, button_height);
132 download_y = (download_text_->getBottom() + folder_button_->getY() - download_height + text_size - text_height) / 2;
134 install_location_text_->setTextSize(text_size);
135 int install_background_x = folder_button_->getRight() + text_height / 2;
136 int install_text_x = folder_button_->getRight() + text_height;
137 install_location_text_->setBounds(install_text_x, folder_button_->getY(),
138 download_rect.getRight() - padding_x - install_text_x, button_height);
139 install_text_background_.setBounds(install_background_x, folder_button_->getY(),
140 download_rect.getRight() - padding_x - install_background_x, button_height);
143 download_progress_.setBounds(install_button_->getX(), download_y,
144 download_rect.getWidth() - 2 * padding_x, download_height);
145 download_background_.setBounds(download_progress_.getBounds());
151 if (should_be_visible) {
152 Image image(Image::ARGB, 1, 1,
false);
159 if (install_text_background_.getBounds().contains(e.getPosition()))
164 if (clicked_button == cancel_button_.get())
166 else if (clicked_button == install_button_.get())
168 else if (clicked_button == folder_button_.get())
173 download_progress_.
setQuad(0, -1.0f, -1.0f, 2.0f * progress_value_, 2.0f);
177 download_progress_.getHeight() / 2);
184 if (awaiting_install_.empty()) {
188 packs_data = json::parse(available_packs_location_.loadFileAsString().toStdString(),
nullptr,
false);
193 json available_packs = packs_data[
"packs"];
196 MessageManagerLock lock(Thread::getCurrentThread());
197 if (!lock.lockWasGained())
200 for (
auto& pack : available_packs) {
201 bool purchased =
false;
202 if (pack.count(
"Purchased"))
203 purchased = pack[
"Purchased"];
205 std::string pack_name = pack[
"Name"];
206 pack_name = String(pack_name).removeCharacters(
" ._").toLowerCase().toStdString();
208 if (purchased && installed_packs.count(std::to_string(
id)) == 0 && installed_packs.count(pack_name) == 0) {
209 std::string name = pack[
"Name"];
210 std::string author = pack[
"Author"];
211 std::string url = pack[
"DownloadLink"];
214 File download_location = File::getSpecialLocation(File::tempDirectory).getChildFile(name +
".zip");
215 if (!url.empty() && url[0] ==
'/')
216 url = kDownloadUrlPrefix + url;
217 awaiting_download_.emplace_back(name, author,
id, URL(url), download_location);
221 if (awaiting_download_.empty()) {
222 for (
Listener* listener : listeners_)
223 listener->noDownloadNeeded();
228 catch (
const json::exception& e) {
233 progress_value_ = 1.0f;
234 awaiting_install_[awaiting_install_.size() - 1].finished = success;
237 if (!awaiting_download_.empty()) {
238 DownloadPack pack = awaiting_download_[awaiting_download_.size() - 1];
239 awaiting_download_.pop_back();
240 awaiting_install_.push_back(pack);
241 int number =
static_cast<int>(awaiting_install_.size());
242 int total = awaiting_download_.size() + awaiting_install_.size();
244 MessageManagerLock lock(Thread::getCurrentThread());
245 if (!lock.lockWasGained())
248 std::string order_string =
"(" + std::to_string(number) +
" / " + std::to_string(total) +
")";
249 download_text_->setText(pack.
author +
": " + pack.
name +
" " + order_string);
250 download_threads_.emplace_back(std::make_unique<DownloadThread>(
this, pack.
url, pack.
download_location));
251 download_threads_[download_threads_.size() - 1]->startThread();
255 MessageManagerLock lock(Thread::getCurrentThread());
256 if (!lock.lockWasGained())
260 install_button_->setEnabled(
true);
262 loading_wheel_->setActive(
false);
263 download_text_->setText(
"Downloads completed");
267 MessageManagerLock lock(Thread::getCurrentThread());
269 if (lock.lockWasGained() && !awaiting_install_.empty()) {
270 double completed = bytesDownloaded;
271 progress_value_ = completed / totalLength;
278 if (!initial_download_)
281 int x = (getWidth() - width) / 2;
283 return Rectangle<int>(x, y, width, height);
288 progress_value_ = 0.0f;
289 awaiting_install_.clear();
290 awaiting_download_.clear();
291 packs_url_ = URL(kPacksUrlPrefix + kTokenUrlQuery + auth_->
token());
292 download_text_->setText(
"Getting available packs...");
293 loading_wheel_->setActive(
true);
294 download_threads_.emplace_back(std::make_unique<DownloadThread>(
this, packs_url_, available_packs_location_));
295 download_threads_[download_threads_.size() - 1]->startThread();
299 install_location_.createDirectory();
300 File errors_file = install_location_.getChildFile(
"errors.txt");
301 errors_file.create();
303 if (!install_location_.exists() || !errors_file.exists() || !errors_file.hasWriteAccess()) {
304 MessageManagerLock lock(Thread::getCurrentThread());
305 String warning =
"Can't create install directory. Select another destination";
306 AlertWindow::showNativeDialogBox(
"Can't Create Directory", warning,
false);
307 install_button_->setEnabled(
true);
308 cancel_button_->setEnabled(
true);
312 loading_wheel_->setActive(
true);
313 download_text_->setText(
"Installing...");
314 install_button_->setEnabled(
false);
315 cancel_button_->setEnabled(
false);
316 install_thread_.startThread();
320 download_tasks_.emplace_back(url.downloadToFile(dest,
"",
this));
324 std::vector<int> installed;
328 if (!pack.download_location.exists())
334 if (!pack.finished || !pack.download_location.exists())
337 ZipFile zip(pack.download_location);
338 if (zip.getNumEntries() <= 0)
341 Result unzip_result = zip.uncompressTo(install_location_);
342 if (!unzip_result.wasOk())
345 installed.push_back(pack.id);
348 pack.download_location.deleteFile();
351 MessageManagerLock lock(Thread::getCurrentThread());
352 if (!lock.lockWasGained())
354 for (
int installed_pack_id : installed)
357 for (
Listener* listener : listeners_)
358 listener->dataDirectoryChanged();
360 loading_wheel_->completeRing();
361 download_text_->setText(
"All done!");
368 download_tasks_.clear();
373 FileChooser open_box(
"Choose Install Directory", install_location_);
374 if (open_box.browseForDirectory()) {
375 File result = open_box.getResult();
376 if (result.getFileName() !=
"Vial")
377 result = result.getChildFile(
"Vial");
379 result.createDirectory();
380 File errors_file = result.getChildFile(
"errors.txt");
381 errors_file.create();
383 if (result.exists() && errors_file.exists() && errors_file.hasWriteAccess()) {
384 install_location_ = result;
385 install_location_text_->setText(install_location_.getFullPathName());
388 String warning =
"Can't create install directory. Select another destination";
389 AlertWindow::showNativeDialogBox(
"Invalid Directory", warning,
false);
A no-op stub implementation used when authentication is disabled.
Definition authentication.h:163
std::string token()
Returns an empty token string.
Definition authentication.h:174
Interface for objects that need to respond to data directory changes or no-download scenarios.
Definition download_section.h:54
void startDownload(Thread *thread, URL &url, const File &dest)
Definition download_section.cpp:319
void triggerInstall()
Starts the installation process after all downloads are completed.
Definition download_section.cpp:298
static constexpr int kDownloadAdditionalHeight
The additional height if more content is available.
Definition download_section.h:28
void renderOpenGlComponents(OpenGlWrapper &open_gl, bool animate) override
Definition download_section.cpp:172
static constexpr int kDownloadWidth
The width of the download UI.
Definition download_section.h:24
void triggerDownload()
Triggers the process of checking available packs and downloading necessary content.
Definition download_section.cpp:286
static constexpr int kTextHeight
The text height for labels.
Definition download_section.h:30
Rectangle< int > getDownloadRect()
Definition download_section.cpp:275
static constexpr int kY
The vertical offset for the download UI.
Definition download_section.h:22
void mouseUp(const MouseEvent &e) override
Definition download_section.cpp:158
void cancelDownload()
Cancels all ongoing downloads.
Definition download_section.cpp:366
void setVisible(bool should_be_visible) override
Definition download_section.cpp:148
void chooseInstallFolder()
Allows the user to choose a folder for installation.
Definition download_section.cpp:372
static constexpr int kPaddingX
Horizontal padding inside the UI.
Definition download_section.h:32
void progress(URL::DownloadTask *task, int64 bytesDownloaded, int64 totalLength) override
Definition download_section.cpp:266
void startInstall(Thread *thread)
Definition download_section.cpp:323
static constexpr int kButtonHeight
Height of buttons.
Definition download_section.h:36
static constexpr int kDownloadInitialHeight
The initial height of the download UI before any content is loaded.
Definition download_section.h:26
DownloadSection(String name, Authentication *auth)
Definition download_section.cpp:17
static constexpr int kPaddingY
Vertical padding inside the UI.
Definition download_section.h:34
void resized() override
Lays out the UI components within the overlay.
Definition download_section.cpp:81
static constexpr int kCompletionWaitMs
Time in milliseconds to wait before hiding the UI after completion.
Definition download_section.h:38
void finished(URL::DownloadTask *task, bool success) override
Definition download_section.cpp:180
void buttonClicked(Button *clicked_button) override
Definition download_section.cpp:163
static File getAvailablePacksFile()
Retrieves the file listing available packs.
Definition load_save.cpp:1428
static void markPackInstalled(int id)
Marks a pack as installed by ID in the packs file.
Definition load_save.cpp:1494
static File getDataDirectory()
Gets the current data directory from the config.
Definition load_save.cpp:1718
static json getInstalledPacks()
Returns a JSON list of installed packs.
Definition load_save.cpp:1470
static void saveDataDirectory(const File &data_directory)
Saves the given directory as the data directory in the configuration.
Definition load_save.cpp:1508
static void writeErrorLog(String error_log)
Appends an error message to an error log file.
Definition load_save.cpp:1140
static bool hasDataDirectory()
Checks if a data directory is properly configured (exists and has packs.json).
Definition load_save.cpp:1417
void addRoundedCorners()
Adds rounded corners to the component's edges.
Definition open_gl_component.cpp:138
void renderCorners(OpenGlWrapper &open_gl, bool animate, Colour color, float rounding)
Renders the corner shapes using the given color and rounding amount.
Definition open_gl_component.cpp:153
Colour getBodyColor() const
Retrieves the component's body color.
Definition open_gl_component.h:172
void setQuad(int i, float x, float y, float w, float h)
Sets the position and size of a quad in normalized device space.
Definition open_gl_multi_quad.h:313
force_inline void setColor(Colour color)
Sets the base color for the quads.
Definition open_gl_multi_quad.h:102
void setRounding(float rounding)
Sets the rounding radius of the quads.
Definition open_gl_multi_quad.h:347
A SynthSection that displays an overlay with a background and optional listeners.
Definition overlay.h:180
virtual void resized() override
Called when the overlay is resized. Updates background color and size.
Definition overlay.h:237
void setVisible(bool should_be_visible) override
Sets the visibility of the overlay and notifies listeners.
Definition overlay.h:224
float size_ratio_
A scaling factor for the overlay size.
Definition overlay.h:267
static Path folder()
Creates a folder icon path.
Definition paths.h:133
@ kLight
Definition open_gl_image_component.h:309
Manages and provides access to vertex and fragment shaders used by the OpenGL rendering pipeline.
Definition shaders.h:19
@ kBodyRounding
Definition skin.h:71
@ kWidgetRoundedCorner
Definition skin.h:104
@ kBackground
Definition skin.h:128
@ kWidgetPrimary1
Definition skin.h:165
@ kBody
Definition skin.h:129
virtual void renderOpenGlComponents(OpenGlWrapper &open_gl, bool animate)
Renders all OpenGL components in this section and sub-sections.
Definition synth_section.cpp:357
virtual void animate(bool animate)
Triggers animation state change in sub-sections if needed.
Definition synth_section.cpp:822
void paintOpenGlChildrenBackgrounds(Graphics &g)
Paints the backgrounds for all OpenGL child components.
Definition synth_section.cpp:267
float findValue(Skin::ValueId value_id) const
Finds a value in the skin overrides or from the parent if not found locally.
Definition synth_section.cpp:18
void addOpenGlComponent(OpenGlComponent *open_gl_component, bool to_beginning=false)
Definition synth_section.cpp:489
Declares the DownloadSection class, providing a UI for downloading and installing preset packs.
nlohmann::json json
Definition line_generator.h:7
Represents a downloadable pack with name, author, ID, URL, and local destination file.
Definition download_section.h:41
std::string author
The author of the pack.
Definition download_section.h:45
std::string name
The name of the pack.
Definition download_section.h:44
File download_location
The local file where the pack is downloaded.
Definition download_section.h:48
URL url
The download URL for the pack.
Definition download_section.h:47
A helper struct containing references to OpenGL context, shaders, and display scale.
Definition shaders.h:174