diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..61e646b
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,83 @@
+# Google C/C++ Code Style settings
+# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
+# Author: Kehan Xue, kehan.xue (at) gmail.com
+
+Language: Cpp
+BasedOnStyle: Google
+AccessModifierOffset: -1
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: None
+AlignOperands: Align
+AllowAllArgumentsOnNextLine: true
+AllowAllConstructorInitializersOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: Empty
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: Never # To avoid conflict, set this "Never" and each "if statement" should include brace when coding
+AllowShortLambdasOnASingleLine: Inline
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterReturnType: None
+AlwaysBreakTemplateDeclarations: Yes
+BinPackArguments: true
+BreakBeforeBraces: Custom
+BraceWrapping:
+ AfterCaseLabel: false
+ AfterClass: false
+ AfterStruct: false
+ AfterControlStatement: Never
+ AfterEnum: false
+ AfterFunction: false
+ AfterNamespace: false
+ AfterUnion: false
+ AfterExternBlock: false
+ BeforeCatch: false
+ BeforeElse: false
+ BeforeLambdaBody: false
+ IndentBraces: false
+ SplitEmptyFunction: false
+ SplitEmptyRecord: false
+ SplitEmptyNamespace: false
+BreakBeforeBinaryOperators: None
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeColon
+BreakInheritanceList: BeforeColon
+ColumnLimit: 80
+CompactNamespaces: false
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false # Make sure the * or & align on the left
+EmptyLineBeforeAccessModifier: LogicalBlock
+FixNamespaceComments: true
+IncludeBlocks: Preserve
+IndentCaseLabels: true
+IndentPPDirectives: None
+IndentWidth: 4
+KeepEmptyLinesAtTheStartOfBlocks: true
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PointerAlignment: Left
+ReflowComments: false
+# SeparateDefinitionBlocks: Always # Only support since clang-format 14
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInCStyleCastParentheses: false
+SpacesInContainerLiterals: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: c++11
+TabWidth: 4
+UseTab: Always
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index 8851e64..cb168bc 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,3 @@
-[submodule "docs"]
- path = docs
- url = git@github.com:k147-studio/docs.git
[submodule "JUCE"]
path = JUCE
- url = https://github.com/juce-framework/JUCE.git
+ url = https://github.com/k147-studio/JUCE.git
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..79ee123
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/docs b/docs
deleted file mode 160000
index 80463c5..0000000
--- a/docs
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 80463c5e6fd68b4b4966701ce6b1dfa24e52da98
diff --git a/include/AccountComponent.h b/include/AccountComponent.h
index 77ae47d..bd2756a 100644
--- a/include/AccountComponent.h
+++ b/include/AccountComponent.h
@@ -2,28 +2,33 @@
#include
-class AccountComponent : public juce::Component
-{
+class AccountComponent : public Component {
public:
- AccountComponent();
- void paint(juce::Graphics&) override;
- void resized() override;
+ AccountComponent();
+ void paint(Graphics&) override;
+ void resized() override;
private:
- void apiResponseReceived(const juce::String& content);
- void saveSettings();
- void importSettings();
- void changePassword();
+ void apiResponseReceived(const String& content);
+ void saveSettings();
+ void importSettings();
- juce::Label titleLabel;
- juce::Label responseLabel;
+ void setupLabels();
+ void setupButtons();
+ void setupGrid();
- juce::Label emailLabel, usernameLabel;
- juce::Label emailValueLabel, usernameValueLabel;
+ Label titleLabel{"titleLabel", "Mon compte"};
+ Label responseLabel{"responseLabel", "En attente de réponse..."};
- juce::TextButton saveButton, importButton, changePasswordButton;
+ Label emailLabel{"emailLabel", "Adresse mail :"};
+ Label usernameLabel{"usernameLabel", "Nom d'utilisateur :"};
+ Label emailValueLabel{"emailValueLabel", "utilisateur@example.com"};
+ Label usernameValueLabel{"usernameValueLabel", "NomUtilisateur"};
- juce::Grid grid;
+ TextButton saveButton{"Sauvegarder les réglages"};
+ TextButton importButton{"Importer les réglages"};
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AccountComponent)
-};
+ Grid grid;
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AccountComponent)
+};
\ No newline at end of file
diff --git a/include/BasePedalComponent.h b/include/BasePedalComponent.h
index ed61d3f..3997706 100644
--- a/include/BasePedalComponent.h
+++ b/include/BasePedalComponent.h
@@ -7,89 +7,88 @@
* @brief Base class for pedal components.
* This class provides a common interface and functionality for all pedal components.
*/
-class BasePedalComponent : public EffectComponent
-{
+class BasePedalComponent : public EffectComponent {
public:
- /**
- * @brief Initializes a new instance of the BasePedalComponent class.
- * @param effect The effect associated with this pedal component.
- */
- BasePedalComponent(AbstractEffect* effect);
-
- /**
- * @brief Destroys the instance of the BasePedalComponent class.
- */
- ~BasePedalComponent() override;
-
- /**
- * @brief Paints the component.
- * @param g The JUCE graphics context that paints the component.
- */
- void paint(juce::Graphics &g) override;
-
- /**
- * @brief Resizes the component.
- */
- void resized() override;
+ /**
+ * @brief Initializes a new instance of the BasePedalComponent class.
+ * @param effect The effect associated with this pedal component.
+ */
+ BasePedalComponent(AbstractEffect* effect);
+
+ /**
+ * @brief Destroys the instance of the BasePedalComponent class.
+ */
+ ~BasePedalComponent() override;
+
+ /**
+ * @brief Paints the component.
+ * @param g The JUCE graphics context that paints the component.
+ */
+ void paint(Graphics& g) override;
+
+ /**
+ * @brief Resizes the component.
+ */
+ void resized() override;
protected:
- /**
- * @brief The default width of the component.
- */
- const float DEFAULT_WIDTH = 200.0f;
-
- /**
- * @brief The default height of the component.
- */
- const float DEFAULT_HEIGHT = 300.0f;
-
- /**
- * @brief The main layout for the pedal component.
- */
- juce::Grid pedalLayout;
-
- /**
- * @brief The primary color of the pedal component. Used as background color.
- */
- juce::Colour primaryColor;
-
- /**
- * @brief The secondary color of the pedal component. Used as background color.
- */
- juce::Colour secondaryColor;
-
- /**
- * @brief The layout for the pedal settings.
- */
- PedalSettingsLayoutComponent* settingsLayout;
-
- /**
- * @brief The label for the pedal name.
- */
- juce::Label* pedalLabel;
-
- /**
- * @brief The button to enable/disable the pedal.
- */
- juce::ImageButton enablePedalButton;
-
- /**
- * @brief The indicator for the pedal power status.
- */
- PedalPowerIndicatorComponent* isEnabledIndicator;
-
- /**
- * @brief Tells if the pedal is enabled or not.
- */
- bool* isEnabled;
-
- /**
- * @brief Called when the enable button is clicked.
- */
- void onEnableButtonClicked();
-
- /**
- * @brief Initializes the pedal layout to display it.
- */
- void initializePedal();
+ /**
+ * @brief The default width of the component.
+ */
+ const float DEFAULT_WIDTH = 200.0f;
+
+ /**
+ * @brief The default height of the component.
+ */
+ const float DEFAULT_HEIGHT = 300.0f;
+
+ /**
+ * @brief The main layout for the pedal component.
+ */
+ Grid pedalLayout;
+
+ /**
+ * @brief The primary color of the pedal component. Used as background color.
+ */
+ Colour primaryColor;
+
+ /**
+ * @brief The secondary color of the pedal component. Used as background color.
+ */
+ Colour secondaryColor;
+
+ /**
+ * @brief The layout for the pedal settings.
+ */
+ PedalSettingsLayoutComponent* settingsLayout;
+
+ /**
+ * @brief The label for the pedal name.
+ */
+ Label* pedalLabel;
+
+ /**
+ * @brief The button to enable/disable the pedal.
+ */
+ ImageButton enablePedalButton;
+
+ /**
+ * @brief The indicator for the pedal power status.
+ */
+ PedalPowerIndicatorComponent* isEnabledIndicator;
+
+ /**
+ * @brief Tells if the pedal is enabled or not.
+ */
+ bool* isEnabled;
+
+ /**
+ * @brief Called when the enable button is clicked.
+ */
+ void onEnableButtonClicked();
+
+ /**
+ * @brief Initializes the pedal layout to display it.
+ */
+ void initializePedal();
};
diff --git a/include/ConnectionComponent.h b/include/ConnectionComponent.h
deleted file mode 100644
index bd55dd9..0000000
--- a/include/ConnectionComponent.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#pragma once
-
-#include
-
-/**
- * @brief Represents a graphical component that contains and displays the login form.
- */
-class LoginComponent final : public juce::Component {
- public:
- /**
- * @brief Initializes a new instance of the LoginComponent class.
- */
- LoginComponent();
-
- /**
- * @brief Destroys the instance of the LoginComponent class.
- */
- ~LoginComponent() override;
-
- /**
- * @brief Determines how to display the component.
- * @param g The JUCE graphics context that paints the component.
- */
- void paint(juce::Graphics &g) override;
-
- /**
- * @brief Determines what to do when the component is resized.
- */
- void resized() override;
- private:
- /**
- * @brief The username field.
- */
- juce::TextEditor usernameField;
-
- /**
- * @brief The password field.
- */
- juce::TextEditor passwordField;
-
- /**
- * @brief The login button.
- */
- juce::TextButton loginButton;
-
- /**
- * @brief The skip button.
- */
- juce::TextButton skipButton;
-
- /**
- * @brief Determines what to do when the skip button is clicked.
- */
- void skipButtonClicked();
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LoginComponent)
-};
\ No newline at end of file
diff --git a/include/DelayEffect.h b/include/DelayEffect.h
index babd770..06d00bd 100644
--- a/include/DelayEffect.h
+++ b/include/DelayEffect.h
@@ -9,84 +9,86 @@
*/
class DelayEffect : public AbstractEffect {
public:
- /**
- * @brief Initializes a new instance of the DelayEffect class.
- */
- DelayEffect();
+ /**
+ * @brief Initializes a new instance of the DelayEffect class.
+ */
+ DelayEffect();
- /**
- * @brief Destroys the instance of the DelayEffect class.
- */
- ~DelayEffect() override;
+ /**
+ * @brief Destroys the instance of the DelayEffect class.
+ */
+ ~DelayEffect() override;
- /**
- * @brief Applies the delay effect to the given audio buffer.
- * @param bufferToFill The audio buffer to apply the effect to.
- */
- void apply(const AudioSourceChannelInfo &bufferToFill) override;
+ /**
+ * @brief Applies the delay effect to the given audio buffer.
+ * @param bufferToFill The audio buffer to apply the effect to.
+ */
+ void apply(const AudioSourceChannelInfo& bufferToFill) override;
- /**
- * @brief Sets the rate of the delay effect.
- * @param rate The rate of the delay effect.
- */
- void setRate(float rate);
+ /**
+ * @brief Sets the rate of the delay effect.
+ * @param rate The rate of the delay effect.
+ */
+ void setRate(float rate);
- /**
- * @brief Sets the delay of the effect.
- * @param delay The delay of the effect.
- */
- void setDelay(float delay);
+ /**
+ * @brief Sets the delay of the effect.
+ * @param delay The delay of the effect.
+ */
+ void setDelay(float delay);
- /**
- * @brief Compares the effect with another given effect.
- * @param effect The effect to compare with.
- * @return True if the effect is equal to the given effect, false otherwise.
- */
- bool operator==(const AbstractEffect *effect) override;
+ /**
+ * @brief Compares the effect with another given effect.
+ * @param effect The effect to compare with.
+ * @return True if the effect is equal to the given effect, false otherwise.
+ */
+ bool operator==(const AbstractEffect* effect) override;
- /**
- * @brief Gets the type name of the effect for serialization purposes.
- * @return A string representing the effect type.
- */
- [[nodiscard]] String getEffectType() const override { return "DelayEffect"; }
+ /**
+ * @brief Gets the type name of the effect for serialization purposes.
+ * @return A string representing the effect type.
+ */
+ [[nodiscard]] String getEffectType() const override {
+ return "DelayEffect";
+ }
- /**
- * @brief Serializes the delay effect to a JSON object.
- * @return JSON object containing serialized effect data.
- */
- [[nodiscard]] var toJSON() const override {
- auto obj = AbstractEffect::toJSON();
- if (auto *dynamicObj = obj.getDynamicObject()) {
- dynamicObj->setProperty("rate", rate);
- dynamicObj->setProperty("delay", delay);
- }
- return obj;
- }
+ /**
+ * @brief Serializes the delay effect to a JSON object.
+ * @return JSON object containing serialized effect data.
+ */
+ [[nodiscard]] var toJSON() const override {
+ auto obj = AbstractEffect::toJSON();
+ if (auto* dynamicObj = obj.getDynamicObject()) {
+ dynamicObj->setProperty("rate", rate);
+ dynamicObj->setProperty("delay", delay);
+ }
+ return obj;
+ }
- /**
- * @brief Deserializes the delay effect from a JSON object.
- * @param json JSON object containing serialized effect data.
- */
- void fromJSON(const var &json) override {
- AbstractEffect::fromJSON(json);
+ /**
+ * @brief Deserializes the delay effect from a JSON object.
+ * @param json JSON object containing serialized effect data.
+ */
+ void fromJSON(const var& json) override {
+ AbstractEffect::fromJSON(json);
- if (const auto *obj = json.getDynamicObject()) {
- rate = static_cast(obj->getProperty("rate"));
- delay = static_cast(obj->getProperty("delay"));
- }
- }
+ if (const auto* obj = json.getDynamicObject()) {
+ rate = static_cast(obj->getProperty("rate"));
+ delay = static_cast(obj->getProperty("delay"));
+ }
+ }
private:
- /**
- * @brief The rate of the delay.
- */
- float rate;
+ /**
+ * @brief The rate of the delay.
+ */
+ float rate;
- /**
- * @brief The delay of the effect.
- */
- float delay;
+ /**
+ * @brief The delay of the effect.
+ */
+ float delay;
- std::vector circularBuffer;
- int writePosition = 0;
+ std::vector circularBuffer;
+ int writePosition = 0;
};
diff --git a/include/LoginComponent.h b/include/LoginComponent.h
new file mode 100644
index 0000000..2d545cb
--- /dev/null
+++ b/include/LoginComponent.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include
+
+class LoginComponent final : public Component {
+public:
+ LoginComponent();
+ ~LoginComponent() override;
+
+ void paint(Graphics&) override;
+ void resized() override;
+
+private:
+ void setupFields();
+ void setupButtons();
+ void layoutComponents();
+ void skipButtonClicked();
+
+ TextEditor usernameField;
+ TextEditor passwordField;
+ TextButton loginButton{"Login"};
+ TextButton skipButton{"Skip"};
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LoginComponent)
+};
\ No newline at end of file
diff --git a/include/MainComponent.h b/include/MainComponent.h
index 647c1db..645f75f 100644
--- a/include/MainComponent.h
+++ b/include/MainComponent.h
@@ -1,7 +1,7 @@
#pragma once
#include "BottomMenuBarComponent.h"
-#include "ConnectionComponent.h"
+#include "LoginComponent.h"
#include "Manager.h"
#include "PedalboardComponent.h"
#include "TopMenuBarComponent.h"
diff --git a/include/ToggleButtonComponent.h b/include/ToggleButtonComponent.h
index 3cd17df..6b2e9b3 100644
--- a/include/ToggleButtonComponent.h
+++ b/include/ToggleButtonComponent.h
@@ -2,10 +2,9 @@
#include
-class ToggleButtonComponent : public ToggleButton
-{
+class ToggleButtonComponent : public ToggleButton {
public:
- ToggleButtonComponent();
- ~ToggleButtonComponent() override;
- void paint(juce::Graphics& g) override;
-};
\ No newline at end of file
+ ToggleButtonComponent();
+ ~ToggleButtonComponent() override;
+ void paint(Graphics& g) override;
+};
diff --git a/include/TopMenuBarComponent.h b/include/TopMenuBarComponent.h
index 5778bbe..ad810ad 100644
--- a/include/TopMenuBarComponent.h
+++ b/include/TopMenuBarComponent.h
@@ -1,61 +1,38 @@
#pragma once
-#include
-#include
-
+#include
+#include "AccountComponent.h"
#include "ModalOverlayComponent.h"
#include "SettingsComponent.h"
-#include "AccountComponent.h"
-/**
- * @brief Represents a graphical component that contains and displays the top menu bar.
- */
-class TopMenuBarComponent : public juce::Component {
- public:
- /**
- * @brief Initializes a new instance of the TopMenuBarComponent class.
- */
- explicit TopMenuBarComponent(juce::AudioDeviceManager& deviceManager, bool* isMuted = nullptr);
-
- /**
- * @brief Destroys the instance of the TopMenuBarComponent class.
- */
- ~TopMenuBarComponent() override;
-
- /**
- * @brief Determines how to display the component.
- * @param g The JUCE graphics context that paints the component.
- */
- void paint(juce::Graphics &g) override;
-
- /**
- * @brief Determines what to do when the component is resized.
- */
- void resized() override;
-
- private:
- /**
- * @brief The flexBox component that contains the menu items.
- */
- juce::FlexBox flexBox;
-
- ModalOverlayComponent* modalOverlay;
-
- /**
- * @brief The image button to open settings.
- */
- juce::ImageButton settingsButton;
- SettingsComponent* settingsComponent;
-
- juce::ImageButton accountButton;
- AccountComponent* accountComponent;
-
- bool* isSoundMuted = nullptr;
- juce::ImageButton muteButton;
-
- void openSettingsPopup(juce::AudioDeviceManager& deviceManager);
- void openAccountPopup();
- void toggleMute();
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TopMenuBarComponent)
-};
\ No newline at end of file
+class TopMenuBarComponent : public Component {
+public:
+ explicit TopMenuBarComponent(AudioDeviceManager& deviceManager,
+ bool* isMuted = nullptr);
+ ~TopMenuBarComponent() override;
+
+ void paint(Graphics& g) override;
+ void resized() override;
+
+private:
+ int buttonSize = 32;
+ float gap = 16;
+
+ FlexBox flexBox;
+
+ ImageButton accountButton;
+ ImageButton muteButton;
+ ImageButton settingsButton;
+
+ AccountComponent* accountComponent;
+ ModalOverlayComponent* modalOverlay;
+ SettingsComponent* settingsComponent;
+
+ bool* isSoundMuted = nullptr;
+
+ void openSettingsPopup(AudioDeviceManager& deviceManager);
+ void openAccountPopup();
+ void toggleMute();
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TopMenuBarComponent)
+};
diff --git a/resources/icons/export.png b/resources/icons/export.png
new file mode 100644
index 0000000..69f11e2
Binary files /dev/null and b/resources/icons/export.png differ
diff --git a/resources/icons/mute.png b/resources/icons/mute.png
index 76b5156..88dc4e0 100644
Binary files a/resources/icons/mute.png and b/resources/icons/mute.png differ
diff --git a/resources/icons/power.png b/resources/icons/power.png
index 26bfb45..dcfe593 100644
Binary files a/resources/icons/power.png and b/resources/icons/power.png differ
diff --git a/resources/icons/settings.png b/resources/icons/settings.png
index 912e5b0..2071f27 100644
Binary files a/resources/icons/settings.png and b/resources/icons/settings.png differ
diff --git a/resources/icons/sync.png b/resources/icons/sync.png
new file mode 100644
index 0000000..cba8294
Binary files /dev/null and b/resources/icons/sync.png differ
diff --git a/resources/icons/unmute.png b/resources/icons/unmute.png
index 84bb7f7..d1e4d79 100644
Binary files a/resources/icons/unmute.png and b/resources/icons/unmute.png differ
diff --git a/resources/icons/xmark.png b/resources/icons/xmark.png
new file mode 100644
index 0000000..4937ee7
Binary files /dev/null and b/resources/icons/xmark.png differ
diff --git a/src/Main.cpp b/src/Main.cpp
index a403b1a..895ebdb 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -1,91 +1,80 @@
#include
-
#include "EffectsFactory.h"
#include "MainComponent.h"
class GuiAppApplication final : public JUCEApplication {
public:
- GuiAppApplication() = default;
-
- // We inject these as compile definitions from the CMakeLists.txt
- // If you've enabled the juce header with `juce_generate_juce_header()`
- // you could `#include ` and use `ProjectInfo::projectName` etc. instead.
- const String getApplicationName() override { return JUCE_APPLICATION_NAME_STRING; }
- const String getApplicationVersion() override { return JUCE_APPLICATION_VERSION_STRING; }
- bool moreThanOneInstanceAllowed() override { return false; }
-
- void initialise(const String &commandLine) override {
- // This method is where you should put your application's initialisation code..
- ignoreUnused(commandLine);
-
- mainWindow = std::make_unique(getApplicationName());
- }
-
- void shutdown() override {
- mainWindow = nullptr; // (deletes our window)
- }
-
- void systemRequestedQuit() override {
- // This is called when the app is being asked to quit: you can ignore this
- // request and let the app carry on running, or call quit() to allow the app to close.
- quit();
- }
-
- void anotherInstanceStarted(const String &commandLine) override {
- // When another instance of the app is launched while this one is running,
- // this method is invoked, and the commandLine parameter tells you what
- // the other instance's command-line arguments were.
- ignoreUnused(commandLine);
- }
-
- /*
- This class implements the desktop window that contains an instance of
- our MainComponent class.
- */
- class MainWindow final : public DocumentWindow {
- public:
- explicit MainWindow (String name)
- : DocumentWindow (name,
- Desktop::getInstance().getDefaultLookAndFeel()
- .findColour (backgroundColourId),
- allButtons)
- {
- setUsingNativeTitleBar (true);
- Pedalboard* pedalboard = new Pedalboard();
- pedalboard->appendAll(EffectsFactory::createAllEffects());
- Manager* manager = new Manager(pedalboard);
- setContentOwned (new MainComponent(*manager), true);
+ GuiAppApplication() = default;
+
+ const String getApplicationName() override {
+ return JUCE_APPLICATION_NAME_STRING;
+ }
+
+ const String getApplicationVersion() override {
+ return JUCE_APPLICATION_VERSION_STRING;
+ }
+
+ bool moreThanOneInstanceAllowed() override { return false; }
+
+ void initialise(const String& commandLine) override {
+ // This method is where you should put your application's initialisation code..
+ ignoreUnused(commandLine);
+
+ mainWindow = std::make_unique(getApplicationName());
+ }
+
+ void shutdown() override {
+ mainWindow = nullptr; // (deletes our window)
+ }
+
+ void systemRequestedQuit() override {
+ // This is called when the app is being asked to quit: you can ignore this
+ // request and let the app carry on running, or call quit() to allow the app to close.
+ quit();
+ }
+
+ void anotherInstanceStarted(const String& commandLine) override {
+ // When another instance of the app is launched while this one is running,
+ // this method is invoked, and the commandLine parameter tells you what
+ // the other instance's command-line arguments were.
+ ignoreUnused(commandLine);
+ }
+
+ class MainWindow final : public DocumentWindow {
+ public:
+ explicit MainWindow(const String& name) :
+ DocumentWindow(
+ name, Desktop::getInstance().getDefaultLookAndFeel().findColour(
+ backgroundColourId), allButtons) {
+ setUsingNativeTitleBar(true);
+ Pedalboard* pedalboard = new Pedalboard();
+ pedalboard->appendAll(EffectsFactory::createAllEffects());
+ Manager* manager = new Manager(pedalboard);
+ setContentOwned(new MainComponent(*manager), true);
#if JUCE_IOS || JUCE_ANDROID
setFullScreen (true);
#else
- setResizable(false, false);
- centreWithSize(1280, 720);
+ setResizable(true, true);
+ setSize(1280, 854);
+ centreWithSize(1280, 854);
#endif
+ Component::setVisible(true);
+ }
- Component::setVisible(true);
- }
-
- void closeButtonPressed() override {
- // This is called when the user tries to close this window. Here, we'll just
- // ask the app to quit when this happens, but you can change this to do
- // whatever you need.
- getInstance()->systemRequestedQuit();
- }
-
- /* Note: Be careful if you override any DocumentWindow methods - the base
- class uses a lot of them, so by overriding you might break its functionality.
- It's best to do all your work in your content component instead, but if
- you really have to override any DocumentWindow methods, make sure your
- subclass also calls the superclass's method.
- */
+ void closeButtonPressed() override {
+ // This is called when the user tries to close this window. Here, we'll just
+ // ask the app to quit when this happens, but you can change this to do
+ // whatever you need.
+ getInstance()->systemRequestedQuit();
+ }
- // private:
- // JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainWindow)
- };
+ private:
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainWindow)
+ };
private:
- std::unique_ptr mainWindow;
+ std::unique_ptr mainWindow;
};
// This macro generates the main() routine that launches the app.
diff --git a/src/MainComponent.cpp b/src/MainComponent.cpp
index 1d3a185..275967a 100644
--- a/src/MainComponent.cpp
+++ b/src/MainComponent.cpp
@@ -1,84 +1,71 @@
#include "MainComponent.h"
-#include "SettingsComponent.h"
#include "ResourceManager.h"
-
-
-
-MainComponent::MainComponent(const Manager &manager): pedalboardComponent(manager.getPedalboard()),
- topMenuBarComponent(this->deviceManager, &isSoundMuted), manager(manager)
-{
- setAudioChannels(2, 2);
-
- Image background = ResourceManager::loadImage("resources/images/background.png");
- if (background.isValid()) {
- backgroundImage.setImage(background);
- backgroundImage.setImagePlacement(juce::RectanglePlacement::stretchToFit);
- addAndMakeVisible(backgroundImage);
- } else {
- DBG("Erreur : image de fond introuvable ou invalide.");
- }
-
- pedalboardContainer.setViewedComponent(&pedalboardComponent, true);
- pedalboardContainer.setScrollBarsShown(true, false);
-
- addAndMakeVisible(pedalboardContainer);
- addAndMakeVisible(topMenuBarComponent);
- addAndMakeVisible(bottomMenuBarComponent);
- addAndMakeVisible(connectionComponent);
+MainComponent::MainComponent(const Manager& manager):
+ pedalboardComponent(manager.getPedalboard()),
+ topMenuBarComponent(this->deviceManager, &isSoundMuted), manager(manager) {
+ setAudioChannels(2, 2);
+
+ const Image background = ResourceManager::loadImage(
+ "resources/images/background.png");
+ if (background.isValid()) {
+ backgroundImage.setImage(background);
+ backgroundImage.setImagePlacement(RectanglePlacement::stretchToFit);
+ addAndMakeVisible(backgroundImage);
+ } else {
+ DBG("Error : resources/images/background.png not found.");
+ }
+
+ pedalboardContainer.setViewedComponent(&pedalboardComponent, true);
+ pedalboardContainer.setScrollBarsShown(true, false);
+
+ addAndMakeVisible(pedalboardContainer);
+ addAndMakeVisible(topMenuBarComponent);
+ addAndMakeVisible(bottomMenuBarComponent);
+ addAndMakeVisible(connectionComponent);
}
//==============================================================================
-void MainComponent::paint (juce::Graphics& g)
-{
-}
-
-void MainComponent::resized()
-{
- // This is called when the MainComponent is resized.
- // If you add any child components, this is where you should
- // update their positions.
- backgroundImage.setBounds(getLocalBounds());
- connectionComponent.setBounds(getLocalBounds());
-
- int pedalboardWidth = getWidth();
- int pedalboardHeight = pedalboardComponent.getRequiredHeight(getWidth());
- pedalboardComponent.setSize(pedalboardWidth, pedalboardHeight);
-
- using Track = juce::Grid::TrackInfo;
- using Px = juce::Grid::Px;
- using Fr = juce::Grid::Fr;
- grid.templateRows = { Track (Px (50)), Track (Fr(1)) };
- grid.templateColumns = { Track (Fr(1)) };
- grid.items = {
- juce::GridItem(topMenuBarComponent),
- juce::GridItem(pedalboardContainer)
- };
- grid.performLayout(getLocalBounds());
+void MainComponent::paint(Graphics& g) {}
+
+void MainComponent::resized() {
+ backgroundImage.setBounds(getLocalBounds());
+ connectionComponent.setBounds(getLocalBounds());
+
+ int pedalboardWidth = getWidth();
+ int pedalboardHeight = pedalboardComponent.getRequiredHeight(getWidth());
+ pedalboardComponent.setSize(pedalboardWidth, pedalboardHeight);
+
+ using Track = Grid::TrackInfo;
+ using Px = Grid::Px;
+ using Fr = Grid::Fr;
+ grid.templateRows = {Track(Px(50)), Track(Fr(1))};
+ grid.templateColumns = {Track(Fr(1))};
+ grid.items = {
+ GridItem(topMenuBarComponent),
+ GridItem(pedalboardContainer)
+ };
+ grid.performLayout(getLocalBounds());
}
-void MainComponent::prepareToPlay(int samplesPerBlockExpected, double sampleRate) {
-
+void MainComponent::prepareToPlay(int samplesPerBlockExpected,
+ double sampleRate) {}
+
+void MainComponent::getNextAudioBlock(
+ const AudioSourceChannelInfo& bufferToFill) {
+ if (!this->isSoundMuted) {
+ if (&bufferToFill == nullptr) {
+ return;
+ }
+ if (bufferToFill.buffer == nullptr) {
+ return;
+ }
+ this->manager.apply(bufferToFill);
+ } else {
+ bufferToFill.clearActiveBufferRegion();
+ }
}
-void MainComponent::getNextAudioBlock(const AudioSourceChannelInfo &bufferToFill) {
- if (!this->isSoundMuted)
- {
- if (&bufferToFill == nullptr) {
- return;
- }
- if (bufferToFill.buffer == nullptr) {
- return;
- }
- this->manager.apply(bufferToFill);
- }
- else
- {
- bufferToFill.clearActiveBufferRegion();
- }
-}
-
-void MainComponent::releaseResources() {
-}
+void MainComponent::releaseResources() {}
diff --git a/src/components/AccountComponent.cpp b/src/components/AccountComponent.cpp
index c5a0f2d..09662e2 100644
--- a/src/components/AccountComponent.cpp
+++ b/src/components/AccountComponent.cpp
@@ -1,122 +1,104 @@
#include "AccountComponent.h"
#include "ApiClient.h"
-AccountComponent::AccountComponent()
-{
- // --- Titre ---
- titleLabel.setText("Mon compte", juce::dontSendNotification);
- titleLabel.setFont(juce::Font(24.0f, juce::Font::bold));
- titleLabel.setJustificationType(juce::Justification::centred);
- addAndMakeVisible(titleLabel);
-
- // --- Labels de champs ---
- emailLabel.setText("Adresse mail :", juce::dontSendNotification);
- usernameLabel.setText("Nom d'utilisateur :", juce::dontSendNotification);
-
- for (auto* label : { &emailLabel, &usernameLabel })
- {
- label->setFont(juce::Font(16.0f));
- label->setJustificationType(juce::Justification::centredLeft);
- addAndMakeVisible(*label);
- }
-
- // --- Valeurs (non éditables) ---
- emailValueLabel.setText("utilisateur@example.com", juce::dontSendNotification);
- usernameValueLabel.setText("NomUtilisateur", juce::dontSendNotification);
-
- for (auto* val : { &emailValueLabel, &usernameValueLabel })
- {
- val->setFont(juce::Font(16.0f));
- val->setJustificationType(juce::Justification::centredLeft);
- val->setColour(juce::Label::textColourId, juce::Colours::black);
- addAndMakeVisible(*val);
- }
-
- // --- Boutons ---
- saveButton.setButtonText("Sauvegarder les réglages");
- importButton.setButtonText("Importer les réglages");
- changePasswordButton.setButtonText("Changer le mot de passe");
-
- saveButton.onClick = [this]() { saveSettings(); };
- importButton.onClick = [this]() { importSettings(); };
- changePasswordButton.onClick = [this]() { changePassword(); };
-
- for (auto* button : { &saveButton, &importButton, &changePasswordButton })
- addAndMakeVisible(*button);
-
- // --- Label de réponse (API ou autres actions) ---
- responseLabel.setFont(juce::Font(14.0f));
- responseLabel.setJustificationType(juce::Justification::centred);
- responseLabel.setColour(juce::Label::textColourId, juce::Colours::darkgrey);
- responseLabel.setText("En attente de réponse...", juce::dontSendNotification);
- addAndMakeVisible(responseLabel);
-
- // --- Appel API fictif ---
- auto replyFunc = [this](const juce::String& content) {
- apiResponseReceived(content);
- };
- ApiClient::runHTTP({ "https://dummyjson.com/test" }, replyFunc);
+namespace {
+constexpr float titleFontSize = 24.0f;
+constexpr float labelFontSize = 16.0f;
+constexpr float responseFontSize = 14.0f;
}
-void AccountComponent::paint(juce::Graphics& g)
-{
- g.fillAll(juce::Colours::lightgrey);
+AccountComponent::AccountComponent() {
+ setupLabels();
+ setupButtons();
+ setupGrid();
+
+ // Dummy API call
+ auto replyFunc = [this](const String& content) {
+ apiResponseReceived(content);
+ };
+ ApiClient::runHTTP({"https://dummyjson.com/test"}, replyFunc);
+}
+
+void AccountComponent::setupLabels() {
+ titleLabel.setFont(FontOptions(titleFontSize, Font::bold));
+ titleLabel.setJustificationType(Justification::centred);
+ addAndMakeVisible(titleLabel);
+
+ for (auto* label : {&emailLabel, &usernameLabel}) {
+ label->setFont(FontOptions(labelFontSize));
+ label->setJustificationType(Justification::centredLeft);
+ addAndMakeVisible(*label);
+ }
+
+ for (auto* val : {&emailValueLabel, &usernameValueLabel}) {
+ val->setFont(FontOptions(labelFontSize));
+ val->setJustificationType(Justification::centredLeft);
+ val->setColour(Label::textColourId, Colours::black);
+ addAndMakeVisible(*val);
+ }
+
+ responseLabel.setFont(FontOptions(responseFontSize));
+ responseLabel.setJustificationType(Justification::centred);
+ responseLabel.setColour(Label::textColourId, Colours::darkgrey);
+ addAndMakeVisible(responseLabel);
+}
+
+void AccountComponent::setupButtons() {
+ saveButton.onClick = [this] { saveSettings(); };
+ importButton.onClick = [this] { importSettings(); };
+
+ for (auto* button : {&saveButton, &importButton})
+ addAndMakeVisible(*button);
+}
+
+void AccountComponent::setupGrid() {
+ using namespace juce;
+ grid.templateRows = {
+ Grid::TrackInfo(40_px), // Title
+ Grid::TrackInfo(30_px), // Email label
+ Grid::TrackInfo(30_px), // Email value
+ Grid::TrackInfo(30_px), // Username label
+ Grid::TrackInfo(30_px), // Username value
+ Grid::TrackInfo(20_px), // Spacer
+ Grid::TrackInfo(40_px), // Change password button
+ Grid::TrackInfo(40_px), // Save button
+ Grid::TrackInfo(40_px), // Import button
+ Grid::TrackInfo(30_px) // Response label
+ };
+
+ grid.templateColumns = {Grid::TrackInfo(1_fr)};
+
+ grid.items = {
+ GridItem(titleLabel),
+ GridItem(emailLabel),
+ GridItem(emailValueLabel),
+ GridItem(usernameLabel),
+ GridItem(usernameValueLabel),
+ GridItem().withArea(6, 1), // Spacer
+ GridItem(saveButton),
+ GridItem(importButton),
+ GridItem(responseLabel)
+ };
}
-void AccountComponent::resized()
-{
- using namespace juce;
-
- grid.templateRows = {
- Grid::TrackInfo(40_px), // Titre
- Grid::TrackInfo(30_px), // Label email
- Grid::TrackInfo(30_px), // Valeur email
- Grid::TrackInfo(30_px), // Label username
- Grid::TrackInfo(30_px), // Valeur username
- Grid::TrackInfo(20_px),
- Grid::TrackInfo(40_px), // Bouton changer mdp
- Grid::TrackInfo(40_px), // Bouton sauvegarder
- Grid::TrackInfo(40_px), // Bouton importer
- Grid::TrackInfo(30_px) // Label réponse
- };
-
- grid.templateColumns = { Grid::TrackInfo(1_fr) };
-
- grid.items = {
- GridItem(titleLabel),
- GridItem(emailLabel),
- GridItem(emailValueLabel),
- GridItem(usernameLabel),
- GridItem(usernameValueLabel),
- GridItem().withArea(6, 1), // espacement
- GridItem(changePasswordButton),
- GridItem(saveButton),
- GridItem(importButton),
- GridItem(responseLabel)
- };
-
- grid.performLayout(getLocalBounds().reduced(40));
+void AccountComponent::paint(Graphics& g) {
+ g.fillAll(Colours::lightgrey);
}
-void AccountComponent::apiResponseReceived(const juce::String& content)
-{
- responseLabel.setText("Réponse API : " + content, juce::dontSendNotification);
+void AccountComponent::resized() {
+ grid.performLayout(getLocalBounds().reduced(40));
}
-void AccountComponent::saveSettings()
-{
- responseLabel.setText("✅ Réglages sauvegardés !", juce::dontSendNotification);
+void AccountComponent::apiResponseReceived(const String& content) {
+ responseLabel.setText("Réponse API : " + content, dontSendNotification);
}
-void AccountComponent::importSettings()
-{
- emailValueLabel.setText("import@example.com", juce::dontSendNotification);
- usernameValueLabel.setText("UtilisateurImporté", juce::dontSendNotification);
- responseLabel.setText("📥 Réglages importés", juce::dontSendNotification);
+void AccountComponent::saveSettings() {
+ responseLabel.setText("✅ Réglages sauvegardés !", dontSendNotification);
}
-void AccountComponent::changePassword()
-{
- // Action fictive pour changer le mot de passe
- responseLabel.setText("🔐 Redirection vers le changement de mot de passe...", juce::dontSendNotification);
+void AccountComponent::importSettings() {
+ emailValueLabel.setText("import@example.com", dontSendNotification);
+ usernameValueLabel.setText("UtilisateurImporté", dontSendNotification);
+ responseLabel.setText("📥 Réglages importés", dontSendNotification);
}
diff --git a/src/components/LoginComponent.cpp b/src/components/LoginComponent.cpp
index 0325044..77dbaaa 100644
--- a/src/components/LoginComponent.cpp
+++ b/src/components/LoginComponent.cpp
@@ -1,36 +1,49 @@
-#include "ConnectionComponent.h"
+#include "LoginComponent.h"
LoginComponent::LoginComponent() {
- usernameField.setTextToShowWhenEmpty("Username", juce::Colours::grey);
- passwordField.setTextToShowWhenEmpty("Password", juce::Colours::grey);
- passwordField.setPasswordCharacter('*');
- skipButton.setButtonText("Skip");
- loginButton.setButtonText("Login");
- skipButton.onClick = [this] { skipButtonClicked(); };
+ setupFields();
+ setupButtons();
+ layoutComponents();
}
LoginComponent::~LoginComponent() = default;
-void LoginComponent::skipButtonClicked() {
- //addAndMakeVisible(new PedalboardComponent(manager.getPedalboard()));
- setVisible(false);
+void LoginComponent::setupFields() {
+ usernameField.setTextToShowWhenEmpty("Username", Colours::grey);
+ passwordField.setTextToShowWhenEmpty("Password", Colours::grey);
+ passwordField.setPasswordCharacter('*');
+ addAndMakeVisible(usernameField);
+ addAndMakeVisible(passwordField);
+}
+
+void LoginComponent::setupButtons() {
+ loginButton.onClick = [] {
+ // TODO: Implement login logic
+ };
+ skipButton.onClick = [this] { skipButtonClicked(); };
+ addAndMakeVisible(loginButton);
+ addAndMakeVisible(skipButton);
}
-void LoginComponent::paint(juce::Graphics &g) {
- g.fillAll(juce::Colours::white);
- addAndMakeVisible(usernameField);
- addAndMakeVisible(passwordField);
- addAndMakeVisible(loginButton);
- addAndMakeVisible(skipButton);
+void LoginComponent::paint(Graphics& g) {
+ g.fillAll(Colours::white);
}
void LoginComponent::resized() {
- const auto area = getLocalBounds().reduced(50);
- const auto halfWidth = area.getWidth() / 2;
- const auto halfHeight = area.getHeight() / 2;
-
- usernameField.setBounds(halfWidth - 100, halfHeight - 80, 300, 40);
- passwordField.setBounds(halfWidth - 100, halfHeight - 30, 300, 40);
- loginButton.setBounds(halfWidth - 100, halfHeight + 30, 300, 40);
- skipButton.setBounds(halfWidth - 100, halfHeight + 80, 300, 40);
+ layoutComponents();
+}
+
+void LoginComponent::layoutComponents() {
+ auto area = getLocalBounds().reduced(50);
+ auto halfWidth = area.getWidth() / 2;
+ auto halfHeight = area.getHeight() / 2;
+
+ usernameField.setBounds(halfWidth - 100, halfHeight - 80, 300, 40);
+ passwordField.setBounds(halfWidth - 100, halfHeight - 30, 300, 40);
+ loginButton.setBounds(halfWidth - 100, halfHeight + 30, 300, 40);
+ skipButton.setBounds(halfWidth - 100, halfHeight + 80, 300, 40);
+}
+
+void LoginComponent::skipButtonClicked() {
+ setVisible(false);
}
\ No newline at end of file
diff --git a/src/components/TopMenuBarComponent.cpp b/src/components/TopMenuBarComponent.cpp
index 970fe4e..322d024 100644
--- a/src/components/TopMenuBarComponent.cpp
+++ b/src/components/TopMenuBarComponent.cpp
@@ -1,136 +1,148 @@
#include "AccountComponent.h"
+#include "ModalOverlayComponent.h"
#include "PopupContentComponent.h"
#include "SettingsComponent.h"
#include "TopMenuBarComponent.h"
-
-#include "ModalOverlayComponent.h"
#include "ResourceManager.h"
-
-TopMenuBarComponent::TopMenuBarComponent(juce::AudioDeviceManager& deviceManager, bool* isSoundMuted)
-{
- this->isSoundMuted = isSoundMuted;
-
-
- juce::Image settingsImage = ResourceManager::loadImage("resources/icons/settings.png");
- if (settingsImage.isValid()) {
- settingsButton.setImages(true, true, true,settingsImage, 1.0f, {},settingsImage, 1.0f, {},settingsImage, 1.0f, {});
- settingsButton.setSize(settingsImage.getWidth(), settingsImage.getHeight());
- addAndMakeVisible(settingsButton);
- } else {
- DBG("Erreur : image settings.png introuvable ou invalide.");
- }
-
- juce::Image accountImage = ResourceManager::loadImage("resources/icons/account.png");
- if (accountImage.isValid()) {
- accountButton.setImages(true, true, true,accountImage, 1.0f, {}, accountImage, 1.0f, {},accountImage, 1.0f, {});
- accountButton.setSize(accountImage.getWidth(), accountImage.getHeight());
- addAndMakeVisible(accountButton);
- } else {
- DBG("Erreur : image account.png introuvable ou invalide.");
- }
-
- juce::Image muteImage = ResourceManager::loadImage("resources/icons/unmute.png");
- if (muteImage.isValid()) {
- muteButton.setImages(true, true, true, muteImage, 1.0f, {}, muteImage, 1.0f, {}, muteImage, 1.0f, {});
- muteButton.setSize(muteImage.getWidth(), muteImage.getHeight());
- addAndMakeVisible(muteButton);
- } else {
- DBG("Erreur : image mute.png introuvable ou invalide.");
- }
-
-
- #if !JUCE_IOS
- settingsButton.onClick = [this, &deviceManager]() { openSettingsPopup(deviceManager); };
- #endif
- accountButton.onClick = [this]() { openAccountPopup(); };
- muteButton.onClick = [this]() { toggleMute(); };
-
- settingsButton.setBounds(0, 0, 100, 50);
- accountButton.setBounds(0, 0, 100, 50);
- muteButton.setBounds(0, 0, 100, 50);
- flexBox.justifyContent = juce::FlexBox::JustifyContent::flexEnd;
- flexBox.alignItems = juce::FlexBox::AlignItems::center;
- flexBox.items.add(
- juce::FlexItem(muteButton).withWidth(muteButton.getWidth()).withHeight(muteButton.getHeight()));
- flexBox.items.add(
- juce::FlexItem(settingsButton).withWidth(settingsButton.getWidth()).withHeight(settingsButton.getHeight()));
- flexBox.items.add(
- juce::FlexItem(accountButton).withWidth(accountButton.getWidth()).withHeight(accountButton.getHeight()));
+TopMenuBarComponent::TopMenuBarComponent(AudioDeviceManager& deviceManager,
+ bool* isMuted) {
+ this->isSoundMuted = isMuted;
+
+ Image settingsImage = ResourceManager::loadImage(
+ "resources/icons/settings.png");
+ if (settingsImage.isValid()) {
+ settingsButton.setImages(true, true, true, settingsImage, 1.0f, {},
+ settingsImage, 1.0f, {}, settingsImage, 1.0f,
+ {});
+ settingsButton.setSize(settingsImage.getWidth(),
+ settingsImage.getHeight());
+ addAndMakeVisible(settingsButton);
+ } else {
+ DBG("Erreur : image settings.png introuvable ou invalide.");
+ }
+
+ Image accountImage = ResourceManager::loadImage(
+ "resources/icons/account.png");
+ if (accountImage.isValid()) {
+ accountButton.setImages(true, true, true, accountImage, 1.0f, {},
+ accountImage, 1.0f, {}, accountImage, 1.0f, {});
+ accountButton.setSize(accountImage.getWidth(),
+ accountImage.getHeight());
+ addAndMakeVisible(accountButton);
+ } else {
+ DBG("Erreur : image account.png introuvable ou invalide.");
+ }
+
+ Image muteImage = ResourceManager::loadImage("resources/icons/unmute.png");
+ if (muteImage.isValid()) {
+ muteButton.setImages(true, true, true, muteImage, 1.0f, {}, muteImage,
+ 1.0f, {}, muteImage, 1.0f, {});
+ muteButton.setSize(muteImage.getWidth(), muteImage.getHeight());
+ addAndMakeVisible(muteButton);
+ } else {
+ DBG("Erreur : image mute.png introuvable ou invalide.");
+ }
+
+#if !JUCE_IOS
+ settingsButton.onClick = [this, &deviceManager] {
+ openSettingsPopup(deviceManager);
+ };
+#endif
+ accountButton.onClick = [this] { openAccountPopup(); };
+ muteButton.onClick = [this] { toggleMute(); };
+
+ flexBox.justifyContent = FlexBox::JustifyContent::flexEnd;
+ flexBox.alignItems = FlexBox::AlignItems::center;
+ flexBox.items.add(
+ FlexItem(muteButton).withWidth(buttonSize).withHeight(buttonSize).
+ withMargin({0, gap, 0, 0}));
+ flexBox.items.add(
+ FlexItem(settingsButton).withWidth(buttonSize).withHeight(buttonSize).
+ withMargin({0, gap, 0, 0}));
+ flexBox.items.add(
+ FlexItem(accountButton).withWidth(buttonSize).withHeight(buttonSize).
+ withMargin({0, gap, 0, 0}));
}
TopMenuBarComponent::~TopMenuBarComponent() = default;
-void TopMenuBarComponent::paint(juce::Graphics& g)
-{
+void TopMenuBarComponent::paint(Graphics& g) {
+ const ColourGradient gradient(Colours::black, 0, 0,
+ Colours::transparentBlack, 0,
+ static_cast(getHeight()), false);
+ g.setGradientFill(gradient);
+ g.fillAll();
+
+ const FontOptions font("Times New Roman", 24.0f, Font::bold | Font::italic);
+ g.setFont(font);
+ g.setColour(Colours::white);
+ const int topMargin = (getHeight() - 24) / 2;
+
+ g.drawText("kAmp", gap, topMargin, 80, 24, Justification::left);
}
-void TopMenuBarComponent::resized()
-{
- auto* mainWindow = getTopLevelComponent();
- if (mainWindow == nullptr)
- return;
- if (modalOverlay != nullptr)
- {
- modalOverlay->setBounds(mainWindow->getLocalBounds());
- }
- if (settingsComponent != nullptr)
- {
- settingsComponent->setBounds(mainWindow->getLocalBounds());
- }
- if (accountComponent != nullptr)
- {
- accountComponent->setBounds(mainWindow->getLocalBounds());
- }
- flexBox.performLayout(getLocalBounds());
+void TopMenuBarComponent::resized() {
+ auto* mainWindow = getTopLevelComponent();
+ if (mainWindow == nullptr)
+ return;
+ if (modalOverlay != nullptr) {
+ modalOverlay->setBounds(mainWindow->getLocalBounds());
+ }
+ if (settingsComponent != nullptr) {
+ settingsComponent->setBounds(mainWindow->getLocalBounds());
+ }
+ if (accountComponent != nullptr) {
+ accountComponent->setBounds(mainWindow->getLocalBounds());
+ }
+ flexBox.performLayout(getLocalBounds());
}
-void TopMenuBarComponent::openSettingsPopup(juce::AudioDeviceManager& deviceManager)
-{
- settingsComponent = new SettingsComponent(deviceManager);
- auto* mainWindow = getTopLevelComponent();
- if (mainWindow == nullptr)
- return;
+void TopMenuBarComponent::openSettingsPopup(AudioDeviceManager& deviceManager) {
+ settingsComponent = new SettingsComponent(deviceManager);
+ auto* mainWindow = getTopLevelComponent();
+ if (mainWindow == nullptr)
+ return;
- modalOverlay = new ModalOverlayComponent("Audio settings", settingsComponent);
- mainWindow->addAndMakeVisible(modalOverlay);
- modalOverlay->setBounds(mainWindow->getLocalBounds());
+ modalOverlay = new ModalOverlayComponent("Audio settings",
+ settingsComponent);
+ mainWindow->addAndMakeVisible(modalOverlay);
+ modalOverlay->setBounds(mainWindow->getLocalBounds());
}
-void TopMenuBarComponent::openAccountPopup()
-{
- accountComponent = new AccountComponent();
- auto* mainWindow = getTopLevelComponent();
- if (mainWindow == nullptr)
- return;
+void TopMenuBarComponent::openAccountPopup() {
+ accountComponent = new AccountComponent();
+ auto* mainWindow = getTopLevelComponent();
+ if (mainWindow == nullptr)
+ return;
- modalOverlay = new ModalOverlayComponent("Account", accountComponent);
- mainWindow->addAndMakeVisible(modalOverlay);
- modalOverlay->setBounds(mainWindow->getLocalBounds());
+ modalOverlay = new ModalOverlayComponent("Account", accountComponent);
+ mainWindow->addAndMakeVisible(modalOverlay);
+ modalOverlay->setBounds(mainWindow->getLocalBounds());
}
-void TopMenuBarComponent::toggleMute()
-{
- if (*this->isSoundMuted)
- {
- juce::Image muteImage = ResourceManager::loadImage("resources/icons/unmute.png");
- if (muteImage.isValid()) {
- muteButton.setImages(false, true, true, muteImage, 1.0f, {}, muteImage, 1.0f, {}, muteImage, 1.0f, {});
- addAndMakeVisible(muteButton);
- } else {
- DBG("Erreur : image mute.png introuvable ou invalide.");
- }
- }
- else
- {
- juce::Image muteImage = ResourceManager::loadImage("resources/icons/mute.png");
- if (muteImage.isValid()) {
- muteButton.setImages(false, true, true, muteImage, 1.0f, {}, muteImage, 1.0f, {}, muteImage, 1.0f, {});
- addAndMakeVisible(muteButton);
- } else {
- DBG("Erreur : image mute.png introuvable ou invalide.");
- }
- }
- *(this->isSoundMuted) = !(*(this->isSoundMuted));
+void TopMenuBarComponent::toggleMute() {
+ if (*this->isSoundMuted) {
+ Image muteImage = ResourceManager::loadImage(
+ "resources/icons/unmute.png");
+ if (muteImage.isValid()) {
+ muteButton.setImages(false, true, true, muteImage, 1.0f, {},
+ muteImage, 1.0f, {}, muteImage, 1.0f, {});
+ addAndMakeVisible(muteButton);
+ } else {
+ DBG("Erreur : image mute.png introuvable ou invalide.");
+ }
+ } else {
+ Image muteImage =
+ ResourceManager::loadImage("resources/icons/mute.png");
+ if (muteImage.isValid()) {
+ muteButton.setImages(false, true, true, muteImage, 1.0f, {},
+ muteImage, 1.0f, {}, muteImage, 1.0f, {});
+ addAndMakeVisible(muteButton);
+ } else {
+ DBG("Erreur : image mute.png introuvable ou invalide.");
+ }
+ }
+ *(this->isSoundMuted) = !(*(this->isSoundMuted));
}
diff --git a/src/components/effects/BasePedalComponent.cpp b/src/components/effects/BasePedalComponent.cpp
index c72108a..9409b25 100644
--- a/src/components/effects/BasePedalComponent.cpp
+++ b/src/components/effects/BasePedalComponent.cpp
@@ -1,68 +1,68 @@
#include "BasePedalComponent.h"
#include "ResourceManager.h"
-BasePedalComponent::BasePedalComponent(AbstractEffect* effect) : EffectComponent(effect)
-{
- isEnabled = effect->isEnabled;
+BasePedalComponent::BasePedalComponent(AbstractEffect* effect) :
+ EffectComponent(effect) {
+ isEnabled = effect->isEnabled;
}
BasePedalComponent::~BasePedalComponent() = default;
-void BasePedalComponent::paint(juce::Graphics &g) {
- g.setColour(primaryColor);
- g.fillRoundedRectangle(0, 0, getWidth(), getHeight(), 15);
+void BasePedalComponent::paint(Graphics& g) {
+ g.setColour(primaryColor);
+ g.fillRoundedRectangle(0, 0, getWidth(), getHeight(), 15);
}
void BasePedalComponent::resized() {
- pedalLayout.performLayout(getLocalBounds());
+ pedalLayout.performLayout(getLocalBounds());
}
void BasePedalComponent::onEnableButtonClicked() {
- *isEnabled = !(*isEnabled);
- enablePedalButton.setToggleState(*isEnabled, juce::dontSendNotification);
- isEnabledIndicator->togglePower(*isEnabled);
+ *isEnabled = !(*isEnabled);
+ enablePedalButton.setToggleState(*isEnabled, dontSendNotification);
+ isEnabledIndicator->togglePower(*isEnabled);
}
void BasePedalComponent::initializePedal() {
- isEnabledIndicator = new PedalPowerIndicatorComponent(*isEnabled);
- pedalLabel = new juce::Label();
- pedalLabel->setText(getEffect()->effectName, juce::dontSendNotification);
- pedalLabel->setJustificationType(juce::Justification::centred);
- pedalLabel->setFont(juce::Font(30.0f, juce::Font::bold));
+ isEnabledIndicator = new PedalPowerIndicatorComponent(*isEnabled);
+ pedalLabel = new Label();
+ pedalLabel->setText(getEffect()->effectName, dontSendNotification);
+ pedalLabel->setJustificationType(Justification::centred);
+ pedalLabel->setFont(FontOptions(30.0f, Font::bold));
- juce::Image powerImage = ResourceManager::loadImage("resources/icons/power.png");
- if (powerImage.isValid()) {
- enablePedalButton.setImages(true, true, true,
- powerImage, 1.0f, {},
- powerImage, 1.0f, {},
- powerImage, 1.0f, {});
- enablePedalButton.onClick = [this] {
- this->onEnableButtonClicked();
- };
- addAndMakeVisible(enablePedalButton);
- } else {
- DBG("Erreur : image power.png introuvable ou invalide.");
- }
+ Image powerImage = ResourceManager::loadImage("resources/icons/power.png");
+ if (powerImage.isValid()) {
+ enablePedalButton.setImages(true, true, true,
+ powerImage, 1.0f, {},
+ powerImage, 1.0f, {},
+ powerImage, 1.0f, {});
+ enablePedalButton.onClick = [this] {
+ this->onEnableButtonClicked();
+ };
+ addAndMakeVisible(enablePedalButton);
+ } else {
+ DBG("Erreur : image power.png introuvable ou invalide.");
+ }
- addAndMakeVisible(*pedalLabel);
- addAndMakeVisible(*isEnabledIndicator);
+ addAndMakeVisible(*pedalLabel);
+ addAndMakeVisible(*isEnabledIndicator);
- using Track = juce::Grid::TrackInfo;
- using Fr = juce::Grid::Fr;
- pedalLayout.templateRows = {
- Track (Fr (2)),
- Track (Fr (1)),
- Track (Fr (1)),
- Track (Fr (1))
- };
- pedalLayout.templateColumns = {
- Track (Fr (1))
- };
+ using Track = Grid::TrackInfo;
+ using Fr = Grid::Fr;
+ pedalLayout.templateRows = {
+ Track(Fr(2)),
+ Track(Fr(1)),
+ Track(Fr(1)),
+ Track(Fr(1))
+ };
+ pedalLayout.templateColumns = {
+ Track(Fr(1))
+ };
- pedalLayout.items = {
- juce::GridItem(*settingsLayout),
- juce::GridItem(enablePedalButton),
- juce::GridItem(*isEnabledIndicator),
- juce::GridItem(*pedalLabel),
- };
+ pedalLayout.items = {
+ GridItem(*settingsLayout),
+ GridItem(enablePedalButton),
+ GridItem(*isEnabledIndicator),
+ GridItem(*pedalLabel),
+ };
}
\ No newline at end of file
diff --git a/src/components/effects/DelayEffectComponent.cpp b/src/components/effects/DelayEffectComponent.cpp
index a38ade3..744780c 100644
--- a/src/components/effects/DelayEffectComponent.cpp
+++ b/src/components/effects/DelayEffectComponent.cpp
@@ -1,61 +1,71 @@
#include "DelayEffectComponent.h"
-DelayEffectComponent::DelayEffectComponent() : BasePedalComponent(new DelayEffect()) {}
-
-DelayEffectComponent::DelayEffectComponent(AbstractEffect* effect) : BasePedalComponent(effect) {
- if (DelayEffect* delayEffect = dynamic_cast(effect)) {
- primaryColor = juce::Colours::mediumblue;
- using Track = juce::Grid::TrackInfo;
- using Fr = juce::Grid::Fr;
- grid.templateRows = { Track (Fr (1)), Track (Fr (3)) };
- grid.templateColumns = { Track (Fr (1)), Track (Fr (1)) };
- grid.items = {
- juce::GridItem(rateLabel),
- juce::GridItem(delayLabel),
- juce::GridItem(rateSlider),
- juce::GridItem(delaySlider),
- };
- rateSlider.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
- rateSlider.setTextBoxStyle(juce::Slider::TextBoxBelow,false, 100, 20);
- rateSlider.setColour(juce::Slider::textBoxOutlineColourId, juce::Colours::transparentWhite);
- rateSlider.setTextValueSuffix("%");
- rateSlider.setTitle("Rate");
- rateSlider.setRange(0.0, 100.0, 1);
- rateSlider.setValue(50.0);
- rateSlider.onValueChange = [this, delayEffect] { delayEffect->setRate(rateSlider.getValue()); };
-
- rateLabel.setText("Rate", juce::dontSendNotification);
- rateLabel.setJustificationType(Justification::centred);
- rateLabel.attachToComponent(&rateSlider, false);
-
- delaySlider.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
- delaySlider.setTextValueSuffix("ms");
- delaySlider.setTitle("Delay");
- delaySlider.setTextBoxStyle(juce::Slider::TextBoxBelow,false, 100, 20);
- delaySlider.setColour(juce::Slider::textBoxOutlineColourId, juce::Colours::transparentWhite);
- delaySlider.setRange(0.0, 3000.0, 10);
- delaySlider.setValue(500.0);
- delaySlider.onValueChange = [this, delayEffect] { delayEffect->setDelay(delaySlider.getValue()); };
-
- delayLabel.setText("Delay", juce::dontSendNotification);
- delayLabel.setJustificationType(Justification::centred);
- delayLabel.attachToComponent(&delaySlider, false);
-
- rateSlider.setBounds(0, 0, 200, 200);
- delaySlider.setBounds(300, 0, 200, 200);
- rateLabel.setBounds(rateSlider.getX(), rateSlider.getY() + 20, rateSlider.getWidth(), 20);
- delayLabel.setBounds(delaySlider.getX(), delaySlider.getY() + 20, delaySlider.getWidth(), 20);
-
- settingsLayout = new PedalSettingsLayoutComponent(&grid);
-
- addAndMakeVisible(rateSlider);
- addAndMakeVisible(rateLabel);
- addAndMakeVisible(delaySlider);
- addAndMakeVisible(delayLabel);
-
- this->initializePedal();
- setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
- }
+DelayEffectComponent::DelayEffectComponent() : BasePedalComponent(
+ new DelayEffect()) {}
+
+DelayEffectComponent::DelayEffectComponent(AbstractEffect* effect) :
+ BasePedalComponent(effect) {
+ if (auto delayEffect = dynamic_cast(effect)) {
+ primaryColor = Colours::mediumblue;
+ using Track = Grid::TrackInfo;
+ using Fr = Grid::Fr;
+ grid.templateRows = {Track(Fr(1)), Track(Fr(3))};
+ grid.templateColumns = {Track(Fr(1)), Track(Fr(1))};
+ grid.items = {
+ GridItem(rateLabel),
+ GridItem(delayLabel),
+ GridItem(rateSlider),
+ GridItem(delaySlider),
+ };
+ rateSlider.setSliderStyle(Slider::SliderStyle::RotaryVerticalDrag);
+ rateSlider.setTextBoxStyle(Slider::TextBoxBelow, false, 100, 20);
+ rateSlider.setColour(Slider::textBoxOutlineColourId,
+ Colours::transparentWhite);
+ rateSlider.setTextValueSuffix("%");
+ rateSlider.setTitle("Rate");
+ rateSlider.setRange(0.0, 100.0, 1);
+ rateSlider.setValue(50.0);
+ rateSlider.onValueChange = [this, delayEffect] {
+ delayEffect->setRate(rateSlider.getValue());
+ };
+
+ rateLabel.setText("Rate", dontSendNotification);
+ rateLabel.setJustificationType(Justification::centred);
+ rateLabel.attachToComponent(&rateSlider, false);
+
+ delaySlider.setSliderStyle(Slider::SliderStyle::RotaryVerticalDrag);
+ delaySlider.setTextValueSuffix("ms");
+ delaySlider.setTitle("Delay");
+ delaySlider.setTextBoxStyle(Slider::TextBoxBelow, false, 100, 20);
+ delaySlider.setColour(Slider::textBoxOutlineColourId,
+ Colours::transparentWhite);
+ delaySlider.setRange(0.0, 3000.0, 10);
+ delaySlider.setValue(500.0);
+ delaySlider.onValueChange = [this, delayEffect] {
+ delayEffect->setDelay(delaySlider.getValue());
+ };
+
+ delayLabel.setText("Delay", dontSendNotification);
+ delayLabel.setJustificationType(Justification::centred);
+ delayLabel.attachToComponent(&delaySlider, false);
+
+ rateSlider.setBounds(0, 0, 200, 200);
+ delaySlider.setBounds(300, 0, 200, 200);
+ rateLabel.setBounds(rateSlider.getX(), rateSlider.getY() + 20,
+ rateSlider.getWidth(), 20);
+ delayLabel.setBounds(delaySlider.getX(), delaySlider.getY() + 20,
+ delaySlider.getWidth(), 20);
+
+ settingsLayout = new PedalSettingsLayoutComponent(&grid);
+
+ addAndMakeVisible(rateSlider);
+ addAndMakeVisible(rateLabel);
+ addAndMakeVisible(delaySlider);
+ addAndMakeVisible(delayLabel);
+
+ this->initializePedal();
+ setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ }
}
DelayEffectComponent::~DelayEffectComponent() = default;
\ No newline at end of file
diff --git a/src/utils/ModalOverlayComponent.cpp b/src/utils/ModalOverlayComponent.cpp
index c4c7302..936a1a5 100644
--- a/src/utils/ModalOverlayComponent.cpp
+++ b/src/utils/ModalOverlayComponent.cpp
@@ -15,13 +15,13 @@ ModalOverlayComponent::ModalOverlayComponent(std::string viewName, juce::Compone
viewNameLabel.setFont(juce::FontOptions(32.0f, juce::Font::bold));
viewNameLabel.setJustificationType(juce::Justification::centred);
- juce::Image closeImage = ResourceManager::loadImage("resources/icons/close.png");
+ juce::Image closeImage = ResourceManager::loadImage("resources/icons/xmark.png");
if (closeImage.isValid()) {
closeOverlayButton.setImages(true, true, true,closeImage, 1.0f, {}, closeImage, 1.0f, {},closeImage, 1.0f, {});
closeOverlayButton.setSize(closeImage.getWidth(), closeImage.getHeight());
addAndMakeVisible(closeOverlayButton);
} else {
- DBG("Erreur : image close.png introuvable ou invalide.");
+ DBG("Erreur : image xmark.png introuvable ou invalide.");
}
closeOverlayButton.onClick = [this]() { this->onCloseOverlayButtonClicked(); };
}
diff --git a/src/utils/ToggleButtonComponent.cpp b/src/utils/ToggleButtonComponent.cpp
index dde3a5f..07b3baf 100644
--- a/src/utils/ToggleButtonComponent.cpp
+++ b/src/utils/ToggleButtonComponent.cpp
@@ -1,25 +1,42 @@
#include "ToggleButtonComponent.h"
-ToggleButtonComponent::ToggleButtonComponent()
-{
- setMouseCursor(juce::MouseCursor::PointingHandCursor);
- setSize(100, 50);
+namespace {
+constexpr int buttonWidth = 100;
+constexpr int buttonHeight = 50;
+constexpr float toggleWidth = 50.0f;
+constexpr float toggleHeight = 25.0f;
+constexpr float toggleRadius = 10.0f;
+constexpr float ellipseDiameter = 19.0f;
+constexpr float ellipseYOffset = 3.0f;
+constexpr float ellipseXOffsetOn = 0.0f;
+constexpr float ellipseXOffsetOff = -22.0f;
+}
+
+ToggleButtonComponent::ToggleButtonComponent() {
+ setMouseCursor(MouseCursor::PointingHandCursor);
+ setSize(buttonWidth, buttonHeight);
}
ToggleButtonComponent::~ToggleButtonComponent() = default;
-void ToggleButtonComponent::paint(juce::Graphics& g)
-{
- g.setColour(juce::Colours::darkgrey);
- g.fillRoundedRectangle(getWidth() / 2 - 25, getHeight() / 2 - 12.5, 50, 25, 10.0f);
- if (getToggleState())
- {
- g.setColour(juce::Colours::green);
- g.fillEllipse(getWidth() / 2, (getHeight() / 2 - 12.5) + 3, 19, 19);
- }
- else
- {
- g.setColour(juce::Colours::red);
- g.fillEllipse(getWidth() / 2 - 22, (getHeight() / 2 - 12.5) + 3, 19, 19);
- }
+void ToggleButtonComponent::paint(Graphics& g) {
+ const auto centerX = static_cast(getWidth()) / 2.0f;
+ const auto centerY = static_cast(getHeight()) / 2.0f;
+
+ g.setColour(Colours::darkgrey);
+ g.fillRoundedRectangle(centerX - toggleWidth / 2.0f,
+ centerY - toggleHeight / 2.0f,
+ toggleWidth, toggleHeight, toggleRadius);
+
+ if (getToggleState()) {
+ g.setColour(Colours::green);
+ g.fillEllipse(centerX + ellipseXOffsetOn,
+ centerY - toggleHeight / 2.0f + ellipseYOffset,
+ ellipseDiameter, ellipseDiameter);
+ } else {
+ g.setColour(Colours::red);
+ g.fillEllipse(centerX + ellipseXOffsetOff,
+ centerY - toggleHeight / 2.0f + ellipseYOffset,
+ ellipseDiameter, ellipseDiameter);
+ }
}
\ No newline at end of file