Skip to content

Instantly share code, notes, and snippets.

@Xenakios
Last active January 4, 2022 21:21
Show Gist options
  • Save Xenakios/600c684c202d8c44cbd1b6649f880c34 to your computer and use it in GitHub Desktop.
Save Xenakios/600c684c202d8c44cbd1b6649f880c34 to your computer and use it in GitHub Desktop.
/*
==============================================================================
Articulations.cpp
Created: 1 Jan 2022 8:34:26am
Author: Gene Brown
==============================================================================
*/
#include <JuceHeader.h>
#include "Articulations.h"
//==============================================================================
Articulations::Articulations()
{
fileComp.reset(new FilenameComponent("fileComp",
{ DefPath }, // current file
false, // can edit file name,
false, // is directory,
false, // is for saving,
{"*.rcCTRL"}, // browser wildcard suffix,
{}, // enforced suffix,
"Select RC control set file to open")); // text when nothing selected
addAndMakeVisible(fileComp.get());
fileComp->addListener(this);
textContent.reset(new TextEditor());
addAndMakeVisible(textContent.get());
textContent->setMultiLine(true);
textContent->setReadOnly(true);
textContent->setCaretVisible(false);
// addAndMakeVisible(TestcontrollerSet);
// TestcontrollerSet.setText("----", dontSendNotification);
// addAndMakeVisible(TestArticulationSet);
// TestArticulationSet.setText("----", dontSendNotification);
// addAndMakeVisible(Position);
// addAndMakeVisible(TheBar);
addAndMakeVisible(InstName);
InstName.setText("Instrument", dontSendNotification);
addAndMakeVisible(ArtName);
ArtName.setText("Articulation", dontSendNotification);
// addAndMakeVisible(KeyName);
addAndMakeVisible(groupComboBox);
groupComboBox.setEditableText(true);
groupComboBox.setJustificationType(juce::Justification::centredLeft);
groupComboBox.setTextWhenNothingSelected(TRANS("- Nothing Selected -"));
groupComboBox.setTextWhenNoChoicesAvailable(TRANS("(no choices)"));
// groupComboBox.addItem(TRANS("Strings - Ensemble - 14 + 1st Violin"), 1);
groupComboBox.addListener(this);
groupComboBox.setBounds(100, 120, 296, 30);
addAndMakeVisible(artComboBox);
artComboBox.setEditableText(true);
artComboBox.setJustificationType(juce::Justification::centredLeft);
artComboBox.setTextWhenNothingSelected(TRANS("----"));
artComboBox.setTextWhenNoChoicesAvailable(TRANS("(no choices)"));
artComboBox.addListener(this);
artComboBox.setBounds(100, 220, 288, 30);
InstName.attachToComponent(&groupComboBox, true);
ArtName.attachToComponent(&artComboBox, true);
addChildComponent(TheBar);
setSize(900, 200);
}
Articulations::~Articulations()
{
}
void Articulations::paint (juce::Graphics& g)
{
/* This demo code just fills the component's background and
draws some placeholder text to get you started.
You should replace everything in this method with your own
drawing code..
*/
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background
g.setColour (juce::Colours::grey);
g.drawRect (getLocalBounds(), 1); // draw an outline around the component
// g.setColour (juce::Colours::white);
// g.setFont (14.0f);
// g.drawText ("Articulations", getLocalBounds(),
// juce::Justification::centred, true); // draw some placeholder text
}
void Articulations::resized()
{
auto area = getLocalBounds();
fileComp->setBounds(10, 10, getWidth() - 20, 20);
textContent->setBounds(10, 40, 100, 50);
//TestcontrollerSet.setBounds(10,400,500,50);
//TestArticulationSet.setBounds(10,450,500,50);
//Position.setBounds(10, 50, 25, 40);
// InstName.setBounds(10, 70, 100, 40);
// ArtName.setBounds(10, 90, 100, 40);
//KeyName.setBounds(10, 555, 100, 40);
TheBar.setBounds(1, 100, getWidth() - 2, 20);
}
void Articulations::comboBoxChanged(ComboBox* comboBoxThatHasChanged)
{
//[UsercomboBoxChanged_Pre]
//[/UsercomboBoxChanged_Pre]
if (comboBoxThatHasChanged == &groupComboBox)
{
//[UserComboBoxCode_groupComboBox] -- add your combo box handling code here..
// groupComboBox.addItem(TRANS("Strings - Ensemble - 14 + 1st Violin"), 1);
//[/UserComboBoxCode_groupComboBox]
}
else if (comboBoxThatHasChanged == &artComboBox)
{
//[UserComboBoxCode_artComboBox] -- add your combo box handling code here..
//[/UserComboBoxCode_artComboBox]
}
//[UsercomboBoxChanged_Post]
//[/UsercomboBoxChanged_Post]
}
void Articulations::filenameComponentChanged(FilenameComponent* fileComponentThatHasChanged)
{
if (fileComponentThatHasChanged == fileComp.get()) // also clear combo boxes and anything else here analize the file here too
readFile(fileComp->getCurrentFile());
}
void Articulations::readFile(const File& fileToRead)
{
if (!fileToRead.existsAsFile())
return; // file doesn't exist
TheBar.setVisible(true); // not inside another thread yet, so these are allowed
setEnabled(false);
juce::Thread::launch([this, fileToRead]()
{
// Running in the new thread now!
// Note that none of this code can call any of the GUI object methods, like
// addItem, setText, setFont, setEnabled, setVisible, setBounds, repaint etc,
// all that stuff needs to be deferred to the end inside the
// the MessageManager::callAsync
FileInputStream inputStream(fileToRead); // [2]
if (!inputStream.openedOk())
{
MessageManager::callAsync([this]() { TheBar.setVisible(false); setEnabled(true); });
return; // failed to open
}
//textContent->clear();
//auto normalFont = textContent->getFont();
//auto titleFont = normalFont.withHeight(normalFont.getHeight() * 1.5f).boldened();
auto groupitemcount = 0;
auto articitemcount = 0;
double linecount = 0;
// delimiters
String comment("##");
String controllerset("controllerset=");
String controller("controller=");
String seperator(";");
String articulationSet("group=");
String articulation("articulation=");
String keyswitch("keyswitch=");
String quote("\"");
String SubString("");
String LastInstrument("");
std::vector<juce::String> groupTexts;
std::vector<juce::String> artTexts;
while (!inputStream.isExhausted())
{
auto line = inputStream.readNextLine();
linecount++;
if (line.startsWith(comment))
{
// line = line.removeCharacters(comment);
//textContent->setFont(titleFont);
//DBG("Found comment");
}
else
{
//textContent->setFont(normalFont);
}
if (line.startsWith(controllerset))
{
// this is the also the file name
//DBG("Found controller set name");
}
if (line.startsWith(controller))
{
//DBG("Found controller defaults");
}
if (line.startsWith(articulationSet))
{
// the meat and potatoes
auto startIn = 0;
auto endIn = 0;
String tempstr = "";
// first field
startIn = line.indexOf(0, quote);
endIn = line.indexOf(startIn + 1, quote);
tempstr = line.substring(startIn, endIn);
tempstr = tempstr.unquoted();
groupitemcount++;
if (tempstr != LastInstrument) // only add item once to combobox
{
LastInstrument = tempstr;
groupTexts.push_back(tempstr);
// InstName.setText(tempstr, dontSendNotification);
}
// second field
startIn = endIn;
endIn = line.indexOf(startIn + 1, quote);
startIn = endIn;
endIn = line.indexOf(startIn + 1, quote);
tempstr = line.substring(startIn, endIn);
tempstr = tempstr.unquoted();
// ArtName.setText(tempstr, dontSendNotification);
articitemcount++;
artTexts.push_back(tempstr);
// third field
startIn = endIn;
endIn = line.indexOf(startIn + 1, quote);
startIn = endIn;
endIn = line.indexOf(startIn + 1, quote);
tempstr = line.substring(startIn, endIn);
tempstr = tempstr.unquoted();
tempstr = line.substring(startIn, endIn);
tempstr = tempstr.unquoted();
// not used yet (so commented out by Xenakios, because the setText call can't be done in this threaded code
//KeyName.setText(tempstr, dontSendNotification);
// DBG("group name stuff string home run");
}
// set the variable value that the ProgressBar is monitoring
mProgress = 1.0 / inputStream.getTotalLength() * inputStream.getPosition();
// artificial sleep slowdown so that we can see the ProgressBar actually appearing and moving :-)
juce::Thread::sleep(5);
// append the text to the textContent
// Xenakios : this is a SUPER slow call, don't do text appending like this into a JUCE TextEditor!
//textContent->insertTextAtCaret(line + newLine); // for debug use
}
// call into the GUI thread async to actually fill the comboboxes etc
// tip : do NOT change the lambda capture variables to references, they
// must be captured by copy here!
MessageManager::callAsync([this,groupTexts,artTexts]()
{
for (size_t i = 0; i < groupTexts.size(); ++i)
{
groupComboBox.addItem(groupTexts[i], (int)i + 1);
}
for (size_t i = 0; i < artTexts.size(); ++i)
{
artComboBox.addItem(artTexts[i], (int)i + 1);
}
TheBar.setVisible(false);
setEnabled(true);
});
});
}
/*
==============================================================================
Articulations.h
Created: 1 Jan 2022 8:34:26am
Author: Gene Brown
==============================================================================
*/
#pragma once
#include <JuceHeader.h>
using namespace juce;
//==============================================================================
/*
*/
class Articulations : public Component,
public FilenameComponentListener,
public ComboBox::Listener
{
public:
Articulations();
~Articulations() override;
void paint (juce::Graphics&) override;
void resized() override;
void filenameComponentChanged(FilenameComponent* fileComponentThatHasChanged) override;
void readFile(const File& fileToRead);
void comboBoxChanged(ComboBox* comboBoxThatHasChanged) override;
// move the fields from editpage to here
// Label TestcontrollerSet;
// Label TestArticulationSet;
// Label Position;
String DefPath = "C:/ProgrammingProjects/_experiments2021/sqlite_test/Source";
Label InstName;
Label ArtName ;
Label KeyName ;
ComboBox groupComboBox;
ComboBox artComboBox;
// ProgressBar needs a reference to a double that it monitors for the progress amount
double mProgress = 0.0;
ProgressBar TheBar{ mProgress };
private:
std::unique_ptr<TextEditor> textContent;
std::unique_ptr<FilenameComponent> fileComp;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Articulations)
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment