kopia lustrzana https://github.com/jameshball/osci-render
Make volume button mutable, and add ability to save global settings
rodzic
3580ef5fa4
commit
cdf3e88e17
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3,9H7L12,4V20L7,15H3V9M16.59,12L14,9.41L15.41,8L18,10.59L20.59,8L22,9.41L19.41,12L22,14.59L20.59,16L18,13.41L15.41,16L14,14.59L16.59,12Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 216 B |
|
@ -17,6 +17,20 @@ CommonAudioProcessor::CommonAudioProcessor(const BusesProperties& busesPropertie
|
||||||
: AudioProcessor(busesProperties)
|
: AudioProcessor(busesProperties)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
// Initialize the global settings with the plugin name
|
||||||
|
juce::PropertiesFile::Options options;
|
||||||
|
options.applicationName = JucePlugin_Name + juce::String("_globals");
|
||||||
|
options.filenameSuffix = ".settings";
|
||||||
|
options.osxLibrarySubFolder = "Application Support";
|
||||||
|
|
||||||
|
#if JUCE_LINUX || JUCE_BSD
|
||||||
|
options.folderName = "~/.config";
|
||||||
|
#else
|
||||||
|
options.folderName = "";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
globalSettings = std::make_unique<juce::PropertiesFile>(options);
|
||||||
|
|
||||||
// locking isn't necessary here because we are in the constructor
|
// locking isn't necessary here because we are in the constructor
|
||||||
|
|
||||||
for (auto effect : visualiserParameters.effects) {
|
for (auto effect : visualiserParameters.effects) {
|
||||||
|
@ -36,6 +50,9 @@ CommonAudioProcessor::CommonAudioProcessor(const BusesProperties& busesPropertie
|
||||||
intParameters.push_back(parameter);
|
intParameters.push_back(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
muteParameter = new BooleanParameter("Mute", "mute", VERSION_HINT, false, "Mute audio output");
|
||||||
|
booleanParameters.push_back(muteParameter);
|
||||||
|
|
||||||
permanentEffects.push_back(volumeEffect);
|
permanentEffects.push_back(volumeEffect);
|
||||||
permanentEffects.push_back(thresholdEffect);
|
permanentEffects.push_back(thresholdEffect);
|
||||||
effects.push_back(volumeEffect);
|
effects.push_back(volumeEffect);
|
||||||
|
@ -67,7 +84,10 @@ void CommonAudioProcessor::addAllParameters() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonAudioProcessor::~CommonAudioProcessor() {}
|
CommonAudioProcessor::~CommonAudioProcessor()
|
||||||
|
{
|
||||||
|
saveGlobalSettings();
|
||||||
|
}
|
||||||
|
|
||||||
const juce::String CommonAudioProcessor::getName() const {
|
const juce::String CommonAudioProcessor::getName() const {
|
||||||
return JucePlugin_Name;
|
return JucePlugin_Name;
|
||||||
|
@ -301,3 +321,41 @@ void CommonAudioProcessor::loadProperties(juce::XmlElement& xml) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CommonAudioProcessor::getGlobalBoolValue(const juce::String& keyName, bool defaultValue) const
|
||||||
|
{
|
||||||
|
return globalSettings != nullptr ? globalSettings->getBoolValue(keyName, defaultValue) : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CommonAudioProcessor::getGlobalIntValue(const juce::String& keyName, int defaultValue) const
|
||||||
|
{
|
||||||
|
return globalSettings != nullptr ? globalSettings->getIntValue(keyName, defaultValue) : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double CommonAudioProcessor::getGlobalDoubleValue(const juce::String& keyName, double defaultValue) const
|
||||||
|
{
|
||||||
|
return globalSettings != nullptr ? globalSettings->getDoubleValue(keyName, defaultValue) : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
juce::String CommonAudioProcessor::getGlobalStringValue(const juce::String& keyName, const juce::String& defaultValue) const
|
||||||
|
{
|
||||||
|
return globalSettings != nullptr ? globalSettings->getValue(keyName, defaultValue) : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommonAudioProcessor::setGlobalValue(const juce::String& keyName, const juce::var& value)
|
||||||
|
{
|
||||||
|
if (globalSettings != nullptr)
|
||||||
|
globalSettings->setValue(keyName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommonAudioProcessor::removeGlobalValue(const juce::String& keyName)
|
||||||
|
{
|
||||||
|
if (globalSettings != nullptr)
|
||||||
|
globalSettings->removeValue(keyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommonAudioProcessor::saveGlobalSettings()
|
||||||
|
{
|
||||||
|
if (globalSettings != nullptr)
|
||||||
|
globalSettings->saveIfNeeded();
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
This file contains the basic framework code for a JUCE plugin processor.
|
This file contains the basic framework code for a JUCE plugin processor.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -63,12 +64,22 @@ public:
|
||||||
std::any getProperty(const std::string& key);
|
std::any getProperty(const std::string& key);
|
||||||
std::any getProperty(const std::string& key, std::any defaultValue);
|
std::any getProperty(const std::string& key, std::any defaultValue);
|
||||||
void setProperty(const std::string& key, std::any value);
|
void setProperty(const std::string& key, std::any value);
|
||||||
|
|
||||||
|
// Global settings methods
|
||||||
|
bool getGlobalBoolValue(const juce::String& keyName, bool defaultValue = false) const;
|
||||||
|
int getGlobalIntValue(const juce::String& keyName, int defaultValue = 0) const;
|
||||||
|
double getGlobalDoubleValue(const juce::String& keyName, double defaultValue = 0.0) const;
|
||||||
|
juce::String getGlobalStringValue(const juce::String& keyName, const juce::String& defaultValue = "") const;
|
||||||
|
void setGlobalValue(const juce::String& keyName, const juce::var& value);
|
||||||
|
void removeGlobalValue(const juce::String& keyName);
|
||||||
|
void saveGlobalSettings();
|
||||||
|
|
||||||
juce::SpinLock audioPlayerListenersLock;
|
juce::SpinLock audioPlayerListenersLock;
|
||||||
std::vector<AudioPlayerListener*> audioPlayerListeners;
|
std::vector<AudioPlayerListener*> audioPlayerListeners;
|
||||||
|
|
||||||
std::atomic<double> volume = 1.0;
|
std::atomic<double> volume = 1.0;
|
||||||
std::atomic<double> threshold = 1.0;
|
std::atomic<double> threshold = 1.0;
|
||||||
|
BooleanParameter* muteParameter = nullptr;
|
||||||
|
|
||||||
std::shared_ptr<Effect> volumeEffect = std::make_shared<Effect>(
|
std::shared_ptr<Effect> volumeEffect = std::make_shared<Effect>(
|
||||||
[this](int index, OsciPoint input, const std::vector<std::atomic<double>>& values, double sampleRate) {
|
[this](int index, OsciPoint input, const std::vector<std::atomic<double>>& values, double sampleRate) {
|
||||||
|
@ -132,6 +143,9 @@ protected:
|
||||||
|
|
||||||
juce::SpinLock propertiesLock;
|
juce::SpinLock propertiesLock;
|
||||||
std::unordered_map<std::string, std::any> properties;
|
std::unordered_map<std::string, std::any> properties;
|
||||||
|
|
||||||
|
// Global settings that persist across plugin instances
|
||||||
|
std::unique_ptr<juce::PropertiesFile> globalSettings;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CommonAudioProcessor)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CommonAudioProcessor)
|
||||||
|
|
|
@ -612,14 +612,20 @@ void OscirenderAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, ju
|
||||||
x = juce::jmax(-threshold, juce::jmin(threshold.load(), x));
|
x = juce::jmax(-threshold, juce::jmin(threshold.load(), x));
|
||||||
y = juce::jmax(-threshold, juce::jmin(threshold.load(), y));
|
y = juce::jmax(-threshold, juce::jmin(threshold.load(), y));
|
||||||
|
|
||||||
|
threadManager.write(OsciPoint(x, y, 1));
|
||||||
|
|
||||||
|
// Apply mute if active
|
||||||
|
if (muteParameter->getBoolValue()) {
|
||||||
|
x = 0.0;
|
||||||
|
y = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
if (totalNumOutputChannels >= 2) {
|
if (totalNumOutputChannels >= 2) {
|
||||||
channelData[0][sample] = x;
|
channelData[0][sample] = x;
|
||||||
channelData[1][sample] = y;
|
channelData[1][sample] = y;
|
||||||
} else if (totalNumOutputChannels == 1) {
|
} else if (totalNumOutputChannels == 1) {
|
||||||
channelData[0][sample] = x;
|
channelData[0][sample] = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
threadManager.write(OsciPoint(x, y, 1));
|
|
||||||
|
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
playTimeSeconds += sTimeSec;
|
playTimeSeconds += sTimeSec;
|
||||||
|
|
|
@ -69,6 +69,12 @@ void SosciAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::M
|
||||||
point.x = juce::jmax(-threshold, juce::jmin(threshold.load(), point.x));
|
point.x = juce::jmax(-threshold, juce::jmin(threshold.load(), point.x));
|
||||||
point.y = juce::jmax(-threshold, juce::jmin(threshold.load(), point.y));
|
point.y = juce::jmax(-threshold, juce::jmin(threshold.load(), point.y));
|
||||||
|
|
||||||
|
// Apply mute if active
|
||||||
|
if (muteParameter->getBoolValue()) {
|
||||||
|
point.x = 0.0;
|
||||||
|
point.y = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
// this is the point that the volume component will draw (i.e. post scale/clipping)
|
// this is the point that the volume component will draw (i.e. post scale/clipping)
|
||||||
threadManager.write(point, "VolumeComponent");
|
threadManager.write(point, "VolumeComponent");
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
class SvgButton : public juce::DrawableButton, public juce::AudioProcessorParameter::Listener, public juce::AsyncUpdater {
|
class SvgButton : public juce::DrawableButton, public juce::AudioProcessorParameter::Listener, public juce::AsyncUpdater {
|
||||||
public:
|
public:
|
||||||
SvgButton(juce::String name, juce::String svg, juce::Colour colour, juce::Colour colourOn, BooleanParameter* toggle = nullptr) : juce::DrawableButton(name, juce::DrawableButton::ButtonStyle::ImageFitted), toggle(toggle) {
|
SvgButton(juce::String name, juce::String svg, juce::Colour colour, juce::Colour colourOn, BooleanParameter* toggle = nullptr, juce::String toggledSvg = "") : juce::DrawableButton(name, juce::DrawableButton::ButtonStyle::ImageFitted), toggle(toggle) {
|
||||||
auto doc = juce::XmlDocument::parse(svg);
|
auto doc = juce::XmlDocument::parse(svg);
|
||||||
|
|
||||||
changeSvgColour(doc.get(), colour);
|
changeSvgColour(doc.get(), colour);
|
||||||
|
@ -16,14 +16,27 @@ class SvgButton : public juce::DrawableButton, public juce::AudioProcessorParame
|
||||||
changeSvgColour(doc.get(), colour.withBrightness(0.3f));
|
changeSvgColour(doc.get(), colour.withBrightness(0.3f));
|
||||||
disabledImage = juce::Drawable::createFromSVG(*doc);
|
disabledImage = juce::Drawable::createFromSVG(*doc);
|
||||||
|
|
||||||
changeSvgColour(doc.get(), colourOn);
|
// If a toggled SVG is provided, use it for the "on" state images
|
||||||
normalImageOn = juce::Drawable::createFromSVG(*doc);
|
if (toggledSvg.isNotEmpty()) {
|
||||||
changeSvgColour(doc.get(), colourOn.withBrightness(0.7f));
|
auto toggledDoc = juce::XmlDocument::parse(toggledSvg);
|
||||||
overImageOn = juce::Drawable::createFromSVG(*doc);
|
changeSvgColour(toggledDoc.get(), colourOn);
|
||||||
changeSvgColour(doc.get(), colourOn.withBrightness(0.5f));
|
normalImageOn = juce::Drawable::createFromSVG(*toggledDoc);
|
||||||
downImageOn = juce::Drawable::createFromSVG(*doc);
|
changeSvgColour(toggledDoc.get(), colourOn.withBrightness(0.7f));
|
||||||
changeSvgColour(doc.get(), colourOn.withBrightness(0.3f));
|
overImageOn = juce::Drawable::createFromSVG(*toggledDoc);
|
||||||
disabledImageOn = juce::Drawable::createFromSVG(*doc);
|
changeSvgColour(toggledDoc.get(), colourOn.withBrightness(0.5f));
|
||||||
|
downImageOn = juce::Drawable::createFromSVG(*toggledDoc);
|
||||||
|
changeSvgColour(toggledDoc.get(), colourOn.withBrightness(0.3f));
|
||||||
|
disabledImageOn = juce::Drawable::createFromSVG(*toggledDoc);
|
||||||
|
} else {
|
||||||
|
changeSvgColour(doc.get(), colourOn);
|
||||||
|
normalImageOn = juce::Drawable::createFromSVG(*doc);
|
||||||
|
changeSvgColour(doc.get(), colourOn.withBrightness(0.7f));
|
||||||
|
overImageOn = juce::Drawable::createFromSVG(*doc);
|
||||||
|
changeSvgColour(doc.get(), colourOn.withBrightness(0.5f));
|
||||||
|
downImageOn = juce::Drawable::createFromSVG(*doc);
|
||||||
|
changeSvgColour(doc.get(), colourOn.withBrightness(0.3f));
|
||||||
|
disabledImageOn = juce::Drawable::createFromSVG(*doc);
|
||||||
|
}
|
||||||
|
|
||||||
basePath = normalImage->getOutlineAsPath();
|
basePath = normalImage->getOutlineAsPath();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include "VolumeComponent.h"
|
#include "VolumeComponent.h"
|
||||||
|
|
||||||
VolumeComponent::VolumeComponent(CommonAudioProcessor& p) : AudioBackgroundThread("VolumeComponent", p.threadManager), audioProcessor(p) {
|
VolumeComponent::VolumeComponent(CommonAudioProcessor& p)
|
||||||
|
: AudioBackgroundThread("VolumeComponent", p.threadManager),
|
||||||
|
audioProcessor(p)
|
||||||
|
{
|
||||||
setOpaque(false);
|
setOpaque(false);
|
||||||
setShouldBeRunning(true);
|
setShouldBeRunning(true);
|
||||||
|
|
||||||
|
@ -38,12 +41,14 @@ VolumeComponent::VolumeComponent(CommonAudioProcessor& p) : AudioBackgroundThrea
|
||||||
audioProcessor.thresholdEffect->setValue(thresholdSlider.getValue());
|
audioProcessor.thresholdEffect->setValue(thresholdSlider.getValue());
|
||||||
};
|
};
|
||||||
|
|
||||||
auto doc = juce::XmlDocument::parse(BinaryData::volume_svg);
|
addAndMakeVisible(volumeButton);
|
||||||
volumeIcon = juce::Drawable::createFromSVG(*doc);
|
volumeButton.onClick = [this] {
|
||||||
doc = juce::XmlDocument::parse(BinaryData::threshold_svg);
|
audioProcessor.muteParameter->setBoolValueNotifyingHost(!audioProcessor.muteParameter->getBoolValue());
|
||||||
|
};
|
||||||
|
|
||||||
|
auto doc = juce::XmlDocument::parse(BinaryData::threshold_svg);
|
||||||
thresholdIcon = juce::Drawable::createFromSVG(*doc);
|
thresholdIcon = juce::Drawable::createFromSVG(*doc);
|
||||||
|
|
||||||
addAndMakeVisible(*volumeIcon);
|
|
||||||
addAndMakeVisible(*thresholdIcon);
|
addAndMakeVisible(*thresholdIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,9 +127,11 @@ void VolumeComponent::stopTask() {}
|
||||||
void VolumeComponent::resized() {
|
void VolumeComponent::resized() {
|
||||||
auto r = getLocalBounds();
|
auto r = getLocalBounds();
|
||||||
|
|
||||||
auto iconRow = r.removeFromTop(20).toFloat();
|
auto iconRow = r.removeFromTop(20);
|
||||||
volumeIcon->setTransformToFit(iconRow.removeFromLeft(iconRow.getWidth() / 2).reduced(1), juce::RectanglePlacement::centred);
|
auto volumeRect = iconRow.removeFromLeft(iconRow.getWidth() / 2);
|
||||||
thresholdIcon->setTransformToFit(iconRow.reduced(2), juce::RectanglePlacement::centred);
|
volumeButton.setBounds(volumeRect.expanded(3));
|
||||||
|
thresholdIcon->setTransformToFit(iconRow.reduced(2).toFloat(), juce::RectanglePlacement::centred);
|
||||||
|
|
||||||
volumeSlider.setBounds(r.removeFromLeft(r.getWidth() / 2));
|
volumeSlider.setBounds(r.removeFromLeft(r.getWidth() / 2));
|
||||||
auto radius = volumeSlider.getLookAndFeel().getSliderThumbRadius(volumeSlider);
|
auto radius = volumeSlider.getLookAndFeel().getSliderThumbRadius(volumeSlider);
|
||||||
thresholdSlider.setBounds(r.reduced(0, radius / 2));
|
thresholdSlider.setBounds(r.reduced(0, radius / 2));
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../CommonPluginProcessor.h"
|
#include "../CommonPluginProcessor.h"
|
||||||
#include "../LookAndFeel.h"
|
#include "../LookAndFeel.h"
|
||||||
#include "../concurrency/AudioBackgroundThread.h"
|
#include "../concurrency/AudioBackgroundThread.h"
|
||||||
|
#include "SvgButton.h"
|
||||||
|
|
||||||
class ThumbRadiusLookAndFeel : public OscirenderLookAndFeel {
|
class ThumbRadiusLookAndFeel : public OscirenderLookAndFeel {
|
||||||
public:
|
public:
|
||||||
|
@ -88,7 +89,7 @@ private:
|
||||||
ThresholdLookAndFeel thresholdLookAndFeel{7};
|
ThresholdLookAndFeel thresholdLookAndFeel{7};
|
||||||
juce::Slider thresholdSlider;
|
juce::Slider thresholdSlider;
|
||||||
|
|
||||||
std::unique_ptr<juce::Drawable> volumeIcon;
|
SvgButton volumeButton = SvgButton("VolumeButton", BinaryData::volume_svg, juce::Colours::white, juce::Colours::red, audioProcessor.muteParameter, BinaryData::mute_svg);
|
||||||
std::unique_ptr<juce::Drawable> thresholdIcon;
|
std::unique_ptr<juce::Drawable> thresholdIcon;
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VolumeComponent)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VolumeComponent)
|
||||||
|
|
|
@ -36,7 +36,7 @@ void TextParser::parse(juce::String text, juce::Font font) {
|
||||||
|
|
||||||
juce::String displayText = attributedString.getText();
|
juce::String displayText = attributedString.getText();
|
||||||
// remove all whitespace
|
// remove all whitespace
|
||||||
displayText = displayText.replaceCharacters(" \t\n\r", "");
|
displayText = displayText.removeCharacters(" \t\n\r");
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
// Iterate through all lines and all runs in each line
|
// Iterate through all lines and all runs in each line
|
||||||
|
@ -50,6 +50,9 @@ void TextParser::parse(juce::String text, juce::Font font) {
|
||||||
juce::GlyphArrangement glyphs;
|
juce::GlyphArrangement glyphs;
|
||||||
|
|
||||||
for (int k = 0; k < run->glyphs.size(); ++k) {
|
for (int k = 0; k < run->glyphs.size(); ++k) {
|
||||||
|
if (index >= displayText.length()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
juce::juce_wchar character = displayText[index];
|
juce::juce_wchar character = displayText[index];
|
||||||
juce::TextLayout::Glyph glyph = run->glyphs.getUnchecked(k);
|
juce::TextLayout::Glyph glyph = run->glyphs.getUnchecked(k);
|
||||||
juce::PositionedGlyph positionedGlyph = juce::PositionedGlyph(
|
juce::PositionedGlyph positionedGlyph = juce::PositionedGlyph(
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
<FILE id="WIkl6l" name="fullscreen.svg" compile="0" resource="1" file="Resources/svg/fullscreen.svg"/>
|
<FILE id="WIkl6l" name="fullscreen.svg" compile="0" resource="1" file="Resources/svg/fullscreen.svg"/>
|
||||||
<FILE id="n1esUp" name="left_arrow.svg" compile="0" resource="1" file="Resources/svg/left_arrow.svg"/>
|
<FILE id="n1esUp" name="left_arrow.svg" compile="0" resource="1" file="Resources/svg/left_arrow.svg"/>
|
||||||
<FILE id="PxYKbt" name="microphone.svg" compile="0" resource="1" file="Resources/svg/microphone.svg"/>
|
<FILE id="PxYKbt" name="microphone.svg" compile="0" resource="1" file="Resources/svg/microphone.svg"/>
|
||||||
|
<FILE id="eGMxwy" name="mute.svg" compile="0" resource="1" file="Resources/svg/mute.svg"/>
|
||||||
<FILE id="hJHxFY" name="open_in_new.svg" compile="0" resource="1" file="Resources/svg/open_in_new.svg"/>
|
<FILE id="hJHxFY" name="open_in_new.svg" compile="0" resource="1" file="Resources/svg/open_in_new.svg"/>
|
||||||
<FILE id="pSc1mq" name="osci.svg" compile="0" resource="1" file="Resources/svg/osci.svg"/>
|
<FILE id="pSc1mq" name="osci.svg" compile="0" resource="1" file="Resources/svg/osci.svg"/>
|
||||||
<FILE id="f2D5tv" name="pause.svg" compile="0" resource="1" file="Resources/svg/pause.svg"/>
|
<FILE id="f2D5tv" name="pause.svg" compile="0" resource="1" file="Resources/svg/pause.svg"/>
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<FILE id="WIkl6l" name="fullscreen.svg" compile="0" resource="1" file="Resources/svg/fullscreen.svg"/>
|
<FILE id="WIkl6l" name="fullscreen.svg" compile="0" resource="1" file="Resources/svg/fullscreen.svg"/>
|
||||||
<FILE id="n1esUp" name="left_arrow.svg" compile="0" resource="1" file="Resources/svg/left_arrow.svg"/>
|
<FILE id="n1esUp" name="left_arrow.svg" compile="0" resource="1" file="Resources/svg/left_arrow.svg"/>
|
||||||
<FILE id="PxYKbt" name="microphone.svg" compile="0" resource="1" file="Resources/svg/microphone.svg"/>
|
<FILE id="PxYKbt" name="microphone.svg" compile="0" resource="1" file="Resources/svg/microphone.svg"/>
|
||||||
|
<FILE id="WoY9r2" name="mute.svg" compile="0" resource="1" file="Resources/svg/mute.svg"/>
|
||||||
<FILE id="hJHxFY" name="open_in_new.svg" compile="0" resource="1" file="Resources/svg/open_in_new.svg"/>
|
<FILE id="hJHxFY" name="open_in_new.svg" compile="0" resource="1" file="Resources/svg/open_in_new.svg"/>
|
||||||
<FILE id="pSc1mq" name="osci.svg" compile="0" resource="1" file="Resources/svg/osci.svg"/>
|
<FILE id="pSc1mq" name="osci.svg" compile="0" resource="1" file="Resources/svg/osci.svg"/>
|
||||||
<FILE id="f2D5tv" name="pause.svg" compile="0" resource="1" file="Resources/svg/pause.svg"/>
|
<FILE id="f2D5tv" name="pause.svg" compile="0" resource="1" file="Resources/svg/pause.svg"/>
|
||||||
|
|
Ładowanie…
Reference in New Issue