diff --git a/CMakeLists.txt b/CMakeLists.txt index db266af..4f633d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ cmake_minimum_required(VERSION 3.15) # `project()` command. `project()` sets up some helpful variables that describe source/binary # directories, and the current project version. This is a standard CMake command. -project(blocks VERSION 0.1.2) +project(blocks VERSION 0.1.3) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest") # If you've installed JUCE somehow (via a package manager, or directly using the CMake install diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index e4c903a..6d42a5d 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -6,6 +6,7 @@ #include "settings/UserSettings.h" #include "module_new.h" #include "vital/common/synth_constants.h" +#include "version_config.h" MainComponent::MainComponent(juce::MidiKeyboardState& keyboard_state, Delegate* delegate): delegate(delegate), @@ -53,6 +54,14 @@ MainComponent::MainComponent(juce::MidiKeyboardState& keyboard_state, Delegate* // ui_layer_.setConnections(delegate->getModulations()); // auto osc_block2 = addBlock(0, { 0, 0 }); // spawnBlockComponent(osc_block2); + + auto req = [this] { + auto options = juce::URL::InputStreamOptions(juce::URL::ParameterHandling::inAddress); + auto version = juce::URL("https://blocksbucket.s3.us-east-2.amazonaws.com/version").createInputStream(options)->readEntireStreamAsString().toStdString(); + juce::MessageManager::callAsync([this, version] { ui_layer_.update_button_.setVisible(version != BLOCKS_VERSION);}); + }; + + juce::Thread::launch(req); } void MainComponent::updateDotPosition(const Point position) { diff --git a/Source/MainComponent.h b/Source/MainComponent.h index dba73bc..953bec6 100644 --- a/Source/MainComponent.h +++ b/Source/MainComponent.h @@ -22,6 +22,7 @@ #include "vital/synthesis/framework/synth_module.h" #include "gui/column_controls_container.h" #include "selection_rect.h" +#include "gui/controls/SavePopup.h" using Modulation = Model::Modulation; using Block = Model::Block; diff --git a/Source/gui/UILayer.cpp b/Source/gui/UILayer.cpp index 12eaf7f..cdb2ae8 100644 --- a/Source/gui/UILayer.cpp +++ b/Source/gui/UILayer.cpp @@ -34,6 +34,9 @@ UILayer::UILayer(juce::MidiKeyboardState& keyboard_state, Slider::Listener* list connections_list_box_model_.slider_listener_ = listener; setInterceptsMouseClicks(false, true); setOpaque(false); + update_button_.text.setText("update", dontSendNotification); + addChildComponent(update_button_); + update_button_.on_click_ = [this]() { juce::URL("https://www.soonth.com").launchInDefaultBrowser(); }; } void UILayer::addSVGButton(std::unique_ptr& button, const char* rawData, size_t size) { @@ -104,6 +107,10 @@ void UILayer::resizeSaveAndNewButtons() { int newPresetX = preset_button_.getX() - verticalSpacing - buttonSize / 2; newPresetButton->setBounds(0, 0, buttonSize, buttonSize); newPresetButton->setCentrePosition(newPresetX, preset_button_.getBounds().getCentreY()); + + int update_button_width = 50; + update_button_.setBounds(0, 0, update_button_width, 23); + update_button_.setCentrePosition(saveButton->getRight() + verticalSpacing + update_button_width / 2, preset_button_.getBounds().getCentreY()); } void UILayer::resizeSettingsButton() { diff --git a/Source/gui/UILayer.h b/Source/gui/UILayer.h index bd28b25..2c1fa64 100644 --- a/Source/gui/UILayer.h +++ b/Source/gui/UILayer.h @@ -23,7 +23,6 @@ #include "gui/controls/ButtonGridPopup.h" #include #include "gui/controls/SVGButton.h" -#include "gui/controls/SavePopup.h" #include "connection.h" using Modulation = Model::Modulation; @@ -43,6 +42,7 @@ class UILayer: public juce::Component, ComponentMovementWatcher { std::unique_ptr theme_button_; std::unique_ptr modulatorsButton; + LabelButton update_button_; ModulationsListBoxModel connections_list_box_model_; diff --git a/Source/gui/base/BaseButton.h b/Source/gui/base/BaseButton.h index 4da1581..0503a58 100644 --- a/Source/gui/base/BaseButton.h +++ b/Source/gui/base/BaseButton.h @@ -20,14 +20,13 @@ class BaseButton: public Component { std::function on_click_; Colour colour; - BaseButton(); - virtual void setButtonColour(Colour colour) = 0; protected: void mouseEnter(const juce::MouseEvent& event) override; void mouseExit(const juce::MouseEvent& event) override; void mouseUp(const juce::MouseEvent& event) override; + virtual void setButtonColour(Colour colour) = 0; void paint(juce::Graphics&) override; void resized() override; diff --git a/Source/gui/base/BasePopup.cpp b/Source/gui/base/BasePopup.cpp index c41dab2..bf910cc 100644 --- a/Source/gui/base/BasePopup.cpp +++ b/Source/gui/base/BasePopup.cpp @@ -21,16 +21,12 @@ void BasePopup::setVisible(bool shouldBeVisible) { void BasePopup::triggerDismissAnimation() { auto bounds = getBounds(); - auto animation = [this, bounds](float value, float progress) { setBounds(getX(), getY(), bounds.getWidth() * value, bounds.getHeight() * value); - float invertedProgress = 1.0f - progress; setAlpha(invertedProgress); }; - auto completion = [this]() { juce::Component::setVisible(false); }; - EasingAnimator::AnimateInput input = { .seconds = 0.06f, .completion = completion, @@ -38,7 +34,6 @@ void BasePopup::triggerDismissAnimation() { .range = { 1.00f, 0.95f }, .points = { 0.50f, 0.75f, 0.30f, 1.20f }, }; - animator.animate(input); } @@ -46,22 +41,18 @@ void BasePopup::present() { auto p = getPosition(); setBounds(getX(), getY(), getWidth(), getHeight()); toFront(false); - auto bounds = getBounds(); setAlpha(0.0f); setVisible(true); - auto animation = [this, bounds](float value, float progress) { setBounds(getX(), getY(), bounds.getWidth() * value, bounds.getHeight() * value); setAlpha(progress); }; - auto completion = [this, p, bounds]() { setBounds(p.getX(), p.getY(), bounds.getWidth(), bounds.getHeight()); setAlpha(1.0f); this->setInterceptsMouseClicks(true, true); }; - EasingAnimator::AnimateInput input = { .seconds = 0.06f, .completion = completion, @@ -69,6 +60,5 @@ void BasePopup::present() { .range = { 0.95f, 1.00f }, .points = { 0.50f, 0.75f, 0.30f, 1.20f } }; - animator.animate(input); } diff --git a/Source/gui/controls/LabelButton.cpp b/Source/gui/controls/LabelButton.cpp index dce8407..0b42fac 100644 --- a/Source/gui/controls/LabelButton.cpp +++ b/Source/gui/controls/LabelButton.cpp @@ -7,16 +7,12 @@ LabelButton::~LabelButton() { LabelButton::LabelButton() { hoverBrightness = 8.0f; orbit = false; - addAndMakeVisible(content); - text.setJustificationType(Justification::centred); text.setFont(Font(fontSize)); text.setInterceptsMouseClicks(false, false); - text.setColour(Label::ColourIds::textColourId, colour); - content.addAndMakeVisible(text); - + content.setInterceptsMouseClicks(false, false); ThemeManager::shared()->addListener(this); themeChanged(ThemeManager::shared()->getCurrent()); } @@ -53,8 +49,8 @@ void LabelButton::selectedCompletion() { } void LabelButton::resized() { + BaseButton::resized(); text.setBounds(getLocalBounds()); - content.setBounds(getLocalBounds().reduced(1)); } void LabelButton::themeChanged(Theme theme) { diff --git a/Source/gui/controls/LabelButton.h b/Source/gui/controls/LabelButton.h index 6b2c68d..77299e7 100644 --- a/Source/gui/controls/LabelButton.h +++ b/Source/gui/controls/LabelButton.h @@ -12,10 +12,9 @@ class LabelButton: public BaseButton, public ThemeListener { LabelButton(); ~LabelButton() override; - DrawablePath content; + Component content; Label text; - Path p; float fontSize = 15.0f; float selectedFontSize = 16.5f; diff --git a/Source/gui/controls/SavePopup.h b/Source/gui/controls/SavePopup.h index 4754bd2..cb21fe2 100644 --- a/Source/gui/controls/SavePopup.h +++ b/Source/gui/controls/SavePopup.h @@ -8,12 +8,12 @@ class SavePopup: public BasePopup { LabelButton saveButton; TextEditor textEditor; + ~SavePopup() override { } + SavePopup() { cornerRadius = 13.0f; - addAndMakeVisible(saveButton); addAndMakeVisible(textEditor); - saveButton.text.setText("save", dontSendNotification); } @@ -25,19 +25,15 @@ class SavePopup: public BasePopup { } } - ~SavePopup() override { } - void resized() override { auto inset = 8.0f; auto buttonWidth = 37.0f; - textEditor.setBounds( inset, inset, getWidth() - buttonWidth - inset * 3, getHeight() - inset * 2 ); - saveButton.setBounds( textEditor.getRight(), textEditor.getY() - 2, diff --git a/Source/util/Analytics.cpp b/Source/util/Analytics.cpp index 97bb11a..ced0a11 100644 --- a/Source/util/Analytics.cpp +++ b/Source/util/Analytics.cpp @@ -39,7 +39,7 @@ Analytics* Analytics::shared() { return instance; } -void Analytics::sendHTTPRequest(const juce::String& urlString, const json& bodyData) { +void Analytics::sendPOST(const juce::String& urlString, const json& bodyData) { auto options = juce::URL::InputStreamOptions(juce::URL::ParameterHandling::inAddress).withExtraHeaders("Content-Type: application/json"); juce::URL(urlString).withPOSTData(bodyData.dump()).createInputStream(options); } @@ -97,7 +97,7 @@ void Analytics::initProfileIfNeeded() { json array; array.push_back(body); - sendHTTPRequest("https://api.mixpanel.com/engage#profile-set-once", array); + sendPOST("https://api.mixpanel.com/engage#profile-set-once", array); UserSettings::shared()->set("ProfileInitialized", juce::String("true")); }; @@ -121,7 +121,7 @@ void Analytics::sendEvent(const String& eventName, std::optional cu json array; array.push_back(event); - sendHTTPRequest("https://api.mixpanel.com/track", array); + sendPOST("https://api.mixpanel.com/track", array); }; juce::Thread::launch(req); diff --git a/Source/util/Analytics.h b/Source/util/Analytics.h index 578d830..68f921e 100644 --- a/Source/util/Analytics.h +++ b/Source/util/Analytics.h @@ -23,5 +23,5 @@ class Analytics { void handleQuit(); void handleLaunch(String wrapperType); void initProfileIfNeeded(); - void sendHTTPRequest(const juce::String& urlString, const json& bodyData); + void sendPOST(const juce::String& urlString, const json& bodyData); };