void ConsolidatedTests::TwoPlayersSimple()
{
    beginTest("Two Players Simple");
    initialize_field_manager(4);
    set_delay(0);
    startserver(65002);
    
    register_callbacks(join_game,
                       leave_game,
                       take_cell,
                       get_size,
                       get_cell_player,
                       is_there_a_winner);
    
    
    ScopedPointer<Client> frank = new Client();
    frank->setName("Frank");
    add_instruction(frank, "sleep", 10);
    add_instruction(frank, "join", "");
    
    NamedValueSet* instruction = add_instruction(frank, "take", "");
    instruction->set("x", 0);
    instruction->set("y", 1);
    instruction->set("name", "Frank");
    
    instruction = add_instruction(frank, "take", "");
    instruction->set("x", 0);
    instruction->set("y", 0);
    instruction->set("name", "Frank");
    
    instruction = add_instruction(frank, "take", "");
    instruction->set("x", 1);
    instruction->set("y", 0);
    instruction->set("name", "Frank");
    
    instruction = add_instruction(frank, "take", "");
    instruction->set("x", 1);
    instruction->set("y", 1);
    instruction->set("name", "Frank");
    
    instruction = add_instruction(frank, "status", "");
    instruction->set("x", 0);
    instruction->set("y", 1);
    
    add_instruction(frank, "sleep", 2);
    
    ScopedPointer<Client> susy = new Client();
    susy->setName("Susy");
    add_instruction(susy, "sleep", 5);
    add_instruction(susy, "join", "");
    
    instruction = add_instruction(susy, "take", "");
    instruction->set("x", 0);
    instruction->set("y", 1);
    instruction->set("name", "Susy");
    
    instruction = add_instruction(susy, "take", "");
    instruction->set("x", 0);
    instruction->set("y", 0);
    instruction->set("name", "Susy");
    
    instruction = add_instruction(susy, "take", "");
    instruction->set("x", 1);
    instruction->set("y", 0);
    instruction->set("name", "Susy");
    
    instruction = add_instruction(susy, "take", "");
    instruction->set("x", 1);
    instruction->set("y", 1);
    instruction->set("name", "Susy");
    
    add_instruction(susy, "sleep", 3);

    
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            instruction = add_instruction(susy, "take", "");
            instruction->set("x", i);
            instruction->set("y", j);
            instruction->set("name", "Susy");
        }
    }
    
    pool.addJob(frank, false);
    pool.addJob(susy, false);
    
    while(pool.getNumJobs() > 0 )
    {
        Thread::sleep(100);
    }
    
    stopserver();
    while( server_running() > 0)
    {
        Thread::sleep(100);
    }
    release_field_manager();
    Thread::sleep(1000);
    
}
Exemplo n.º 2
0
void CtrlrWaveform::handlePopupMenu (const int popupMenuItem)
{
	if (popupMenuItem == 4096)
	{
		if (audioThumbnail->isFullyLoaded())
		{
			FileChooser fc("Load a file", currentFile.getParentDirectory(), owner.getOwner().getOwner().getAudioFormatManager().getWildcardForAllFormats(), true);
			if (fc.browseForFileToOpen())
			{
				loadFromFile (fc.getResult());
			}
		}
		else
		{
			audioThumbnail->clear();
		}
	}
	else if (popupMenuItem == 4097)
	{
		WARN("Not implemented yet :(");
	}
	else if (popupMenuItem == 4098)
	{
		FileChooser fc("Save to an audio file", currentFile.getParentDirectory(), owner.getOwner().getOwner().getAudioFormatManager().getWildcardForAllFormats(), true);

		if (fc.browseForFileToSave(true))
		{
			File outputFile = fc.getResult();

			AudioFormat *format = owner.getOwner().getOwner().getAudioFormatManager().findFormatForFileExtension (outputFile.getFileExtension());

			if (format != nullptr)
			{
				{
					ScopedPointer <AudioFormatWriter> writer (format->createWriterFor (outputFile.createOutputStream(),
																						currentSampleRate,
																						audioThumbnail->getNumChannels(),
																						32,
																						metadataForAudioFiles,
																						qualityForAudioFiles));

					if (writer != nullptr)
					{
						writer->writeFromAudioSampleBuffer (audioBufferCopy, 0, audioBufferCopy.getNumSamples());
					}
					else
					{
						if (owner.getOwner().getDialogStatus())
							WARN ("Can't create AudioFormatWriter sampleRate="+String(currentSampleRate)+", channels="+String(audioThumbnail->getNumChannels())+", bitsPerSample=32, qualityIndex="+String(qualityForAudioFiles));
					}
				}
			}
			else
			{
				if (owner.getOwner().getDialogStatus())
					WARN("Can't find AudioFormat for the file: "+outputFile.getFileName());
				return;
			}
		}
	}
}
Exemplo n.º 3
0
void SampleEditHandler::SampleEditingActions::createMultimicSampleMap(SampleEditHandler* handler)
{
	const String multimicTokens = PresetHandler::getCustomName("Multimic Tokens", "Enter a semicolon separated list of all mic position tokens starting with the existing mic position");

	auto list = StringArray::fromTokens(multimicTokens, ";", "\"");

	if (list.size() == 0)
		return;

	auto firstToken = list[0];

	String listString = "\n";

	for (auto l : list)
		listString << l << "\n";

	if (PresetHandler::showYesNoWindow("Confirm multimic tokens", "You have specified these tokens:" + listString + "\nPress OK to create a multimic samplemap with these mic positions"))
	{
		ValueTree v = handler->getSampler()->getSampleMap()->exportAsValueTree();

		for (int i = 0; i < v.getNumChildren(); i++)
		{
			auto sample = v.getChild(i);

			if (sample.getNumChildren() != 0)
			{
				PresetHandler::showMessageWindow("Already a multimic samplemap", "The samplemap has already multimics", PresetHandler::IconType::Error);
				return;
			}

			auto filename = sample.getProperty("FileName").toString();

			if (!filename.contains(firstToken))
			{
				PresetHandler::showMessageWindow("Wrong first mic position", "You have to specify the current mic position as first mic position.\nSample: " + filename, PresetHandler::IconType::Error);
				return;
			}

			sample.removeProperty("FileName", nullptr);

			for (auto token : list)
			{
				auto fChild = ValueTree("file");
				fChild.setProperty("FileName", filename.replace(firstToken, token, false), nullptr);
				sample.addChild(fChild, -1, nullptr);
			}
		}

		PresetHandler::showMessageWindow("Merge successful", "Press OK to choose a location for the multimic sample map");

		auto sampleMapDirectory = GET_PROJECT_HANDLER(handler->getSampler()).getSubDirectory(ProjectHandler::SubDirectories::SampleMaps);

		FileChooser fc("Save multimic Samplemap", sampleMapDirectory, "*.xml", true);

		v.setProperty("MicPositions", multimicTokens, nullptr);

		if (fc.browseForFileToSave(true))
		{
			auto f = fc.getResult();

			auto path = f.getRelativePathFrom(sampleMapDirectory).upToFirstOccurrenceOf(".xml", false, false).replace("\\", "/");

			v.setProperty("ID", path, nullptr);

			ScopedPointer<XmlElement> xml = v.createXml();
			f.replaceWithText(xml->createDocument(""));
		}
	}
}
void PolyWavegeneratorProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midiBuffer)
{
  // clear all the midibuffers of the voices because they still contain the events from the last process Block
  for(int index = 0; index < voices.size(); index++)
  {
    voices[index]->clearMidiBuffer();
  }
  
  // Midi and Voice Handler this is not correct yet i need to watch out for different note ons of the same note in one buffer and other stuff
  if(takesMidi && !midiBuffer.isEmpty())
  {
    MidiMessage& message1 = *new MidiMessage();
    ScopedPointer<MidiBuffer::Iterator> iterator = new MidiBuffer::Iterator(midiBuffer);
    int sampleInBuffer = 0;
    while(iterator->getNextEvent(message1, sampleInBuffer))
    {
      if(message1.isNoteOn())
      {
        // always take the first one and move it to the back => the oldest voice will be "overwritten"
        voices[0]->setIsOn(true);
        voices[0]->setMidiNote(message1.getNoteNumber());
        voices[0]->addMidiEvent(message1, sampleInBuffer);
        
        voices.move(0, voices.size()-1);
      }
      else if(message1.isNoteOff())
      {
        for(int index = 0; index < voices.size(); index++)
        {
          if(voices[index]->getMidiNote() == message1.getNoteNumber())
          {
            ScopedPointer<Voice> tempVoice = voices[index];
            
            tempVoice->setIsOn(false);
            tempVoice->addMidiEvent(message1, sampleInBuffer);
            tempVoice->setMidiNote(-1); // this should be removed but just in case for now
            
            break;
          }
        }
      }
    }
  }
  
  
  
  // Audio Handling of the voices
  AudioBuffer<float> outBuffer = getBusBuffer(buffer, false, 0);
  
  int numActive = 0; // eventually this could be a member variable
  for(int index = 0; index < voices.size(); index++)
  {
    if(voices[index]->getIsOn())
    {
      numActive++;
      
      voices[index]->clearAudioBuffer();
      voices[index]->fillBufferEnvelope();
      voices[index]->fillBufferAudio();
      
      outBuffer.addFrom(0, 0, voices[index]->getOutBuffer(), 0, 0, outBuffer.getNumSamples());
    }
  }
  
  outBuffer.applyGain(1.0f/numActive);
  
  
}
Exemplo n.º 5
0
 void sliderValueChanged (Slider* sliderThatWasMoved) override
 {
     if (sliderThatWasMoved == &zoomSlider)
         thumbnail->setZoomFactor (zoomSlider.getValue());
 }
Exemplo n.º 6
0
void MainAppWindow::runtimePermissionsCallback (bool wasGranted)
{
    int numInputChannels = wasGranted ? 2 : 0;
    sharedAudioDeviceManager->initialise (numInputChannels, 2, nullptr, true, String(), nullptr);
}
Exemplo n.º 7
0
unsigned int OpenGLContext::getFrameBufferID() const noexcept
{
    return nativeContext != nullptr ? nativeContext->getFrameBufferID() : 0;
}
bool JucerDocumentEditor::perform (const InvocationInfo& info)
{
    ComponentLayout* const currentLayout = getCurrentLayout();
    PaintRoutine* const currentPaintRoutine = getCurrentPaintRoutine();

    document->beginTransaction();

    if (info.commandID >= JucerCommandIDs::newComponentBase
         && info.commandID < JucerCommandIDs::newComponentBase + ObjectTypes::numComponentTypes)
    {
        addComponent (info.commandID - JucerCommandIDs::newComponentBase);
        return true;
    }

    if (info.commandID >= JucerCommandIDs::newElementBase
         && info.commandID < JucerCommandIDs::newElementBase + ObjectTypes::numElementTypes)
    {
        addElement (info.commandID - JucerCommandIDs::newElementBase);
        return true;
    }

    switch (info.commandID)
    {
        case StandardApplicationCommandIDs::undo:
            document->getUndoManager().undo();
            document->dispatchPendingMessages();
            break;

        case StandardApplicationCommandIDs::redo:
            document->getUndoManager().redo();
            document->dispatchPendingMessages();
            break;

        case JucerCommandIDs::test:
            TestComponent::showInDialogBox (*document);
            break;

        case JucerCommandIDs::enableSnapToGrid:
            document->setSnappingGrid (document->getSnappingGridSize(),
                                       ! document->isSnapActive (false),
                                       document->isSnapShown());
            break;

        case JucerCommandIDs::showGrid:
            document->setSnappingGrid (document->getSnappingGridSize(),
                                       document->isSnapActive (false),
                                       ! document->isSnapShown());
            break;

        case JucerCommandIDs::editCompLayout:
            showLayout();
            break;

        case JucerCommandIDs::editCompGraphics:
            showGraphics (0);
            break;

        case JucerCommandIDs::zoomIn:      setZoom (snapToIntegerZoom (getZoom() * 2.0)); break;
        case JucerCommandIDs::zoomOut:     setZoom (snapToIntegerZoom (getZoom() / 2.0)); break;
        case JucerCommandIDs::zoomNormal:  setZoom (1.0); break;

        case JucerCommandIDs::spaceBarDrag:
            if (EditingPanelBase* panel = dynamic_cast<EditingPanelBase*> (tabbedComponent.getCurrentContentComponent()))
                panel->dragKeyHeldDown (info.isKeyDown);

            break;

        case JucerCommandIDs::compOverlay0:
        case JucerCommandIDs::compOverlay33:
        case JucerCommandIDs::compOverlay66:
        case JucerCommandIDs::compOverlay100:
            {
                int amount = 0;

                if (info.commandID == JucerCommandIDs::compOverlay33)
                    amount = 33;
                else if (info.commandID == JucerCommandIDs::compOverlay66)
                    amount = 66;
                else if (info.commandID == JucerCommandIDs::compOverlay100)
                    amount = 100;

                document->setComponentOverlayOpacity (amount * 0.01f);
            }
            break;

        case JucerCommandIDs::bringBackLostItems:
            if (EditingPanelBase* panel = dynamic_cast<EditingPanelBase*> (tabbedComponent.getCurrentContentComponent()))
            {
                int w = panel->getComponentArea().getWidth();
                int h = panel->getComponentArea().getHeight();

                if (currentPaintRoutine != nullptr)
                    currentPaintRoutine->bringLostItemsBackOnScreen (panel->getComponentArea());
                else if (currentLayout != nullptr)
                    currentLayout->bringLostItemsBackOnScreen (w, h);
            }

            break;

        case JucerCommandIDs::toFront:
            if (currentLayout != nullptr)
                currentLayout->selectedToFront();
            else if (currentPaintRoutine != nullptr)
                currentPaintRoutine->selectedToFront();

            break;

        case JucerCommandIDs::toBack:
            if (currentLayout != nullptr)
                currentLayout->selectedToBack();
            else if (currentPaintRoutine != nullptr)
                currentPaintRoutine->selectedToBack();

            break;

        case JucerCommandIDs::group:
            if (currentPaintRoutine != nullptr)
                currentPaintRoutine->groupSelected();
            break;

        case JucerCommandIDs::ungroup:
            if (currentPaintRoutine != nullptr)
                currentPaintRoutine->ungroupSelected();
            break;

        case StandardApplicationCommandIDs::cut:
            if (currentLayout != nullptr)
            {
                currentLayout->copySelectedToClipboard();
                currentLayout->deleteSelected();
            }
            else if (currentPaintRoutine != nullptr)
            {
                currentPaintRoutine->copySelectedToClipboard();
                currentPaintRoutine->deleteSelected();
            }

            break;

        case StandardApplicationCommandIDs::copy:
            if (currentLayout != nullptr)
                currentLayout->copySelectedToClipboard();
            else if (currentPaintRoutine != nullptr)
                currentPaintRoutine->copySelectedToClipboard();

            break;

        case StandardApplicationCommandIDs::paste:
            {
                ScopedPointer<XmlElement> doc (XmlDocument::parse (SystemClipboard::getTextFromClipboard()));

                if (doc != nullptr)
                {
                    if (doc->hasTagName (ComponentLayout::clipboardXmlTag))
                    {
                        if (currentLayout != nullptr)
                            currentLayout->paste();
                    }
                    else if (doc->hasTagName (PaintRoutine::clipboardXmlTag))
                    {
                        if (currentPaintRoutine != nullptr)
                            currentPaintRoutine->paste();
                    }
                }
            }
            break;

        case StandardApplicationCommandIDs::del:
            if (currentLayout != nullptr)
                currentLayout->deleteSelected();
            else if (currentPaintRoutine != nullptr)
                currentPaintRoutine->deleteSelected();
            break;

        case StandardApplicationCommandIDs::selectAll:
            if (currentLayout != nullptr)
                currentLayout->selectAll();
            else if (currentPaintRoutine != nullptr)
                currentPaintRoutine->selectAll();
            break;

        case StandardApplicationCommandIDs::deselectAll:
            if (currentLayout != nullptr)
            {
                currentLayout->getSelectedSet().deselectAll();
            }
            else if (currentPaintRoutine != nullptr)
            {
                currentPaintRoutine->getSelectedElements().deselectAll();
                currentPaintRoutine->getSelectedPoints().deselectAll();
            }

            break;

        default:
            return false;
    }

    document->beginTransaction();
    return true;
}
Exemplo n.º 9
0
bool OpenGLContext::isActive() const noexcept       { return nativeContext != nullptr && nativeContext->isActive(); }
Exemplo n.º 10
0
void OpenGLContext::swapBuffers()
{
    if (nativeContext != nullptr)
        nativeContext->swapBuffers();
}
Exemplo n.º 11
0
bool OwlNestSettings::downloadFromServer(CommandID commandID) {
    String nodeString, optionString, warningString;
    PropertySet* props = ApplicationConfiguration::getApplicationProperties();
    switch (commandID){
    case ApplicationCommands::checkForFirmwareUpdates:
      warningString = "Beware that this procedure can make your OWL unresponsive!";
      nodeString = "firmwares";
      optionString = props->getValue("firmware-dfu-options");
      break;
    case ApplicationCommands::checkForBootloaderUpdates:
      warningString = "Beware that this procedure can brick your OWL!";
      nodeString = "bootloaders";
      optionString = props->getValue("bootloader-dfu-options");
      break;
    default:
      return false;
    }
    
    String xmlFilename ("updates.xml");
    URL url(props->getValue("owl-updates-dir-url")+xmlFilename);
    ScopedPointer<XmlElement> xmlUpdates;
    if(url.isWellFormed())
      xmlUpdates = url.readEntireXmlStream(0);
    if(xmlUpdates == NULL) {
      AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Connection Error", "Server connection failed");
      return false;
    }
    XmlElement* filesNode = xmlUpdates->getChildByName(nodeString);
    StringArray names;
    XmlElement* child = filesNode->getFirstChildElement();
    while(child != nullptr){
      names.add(child->getStringAttribute("name"));
      child = child->getNextElement();
    }
    AlertWindow popup("Download File From Server", "Choose file:", juce::AlertWindow::InfoIcon);
    popup.addButton("Cancel", 0, juce::KeyPress(), juce::KeyPress());
    popup.addButton("Download", 1, juce::KeyPress(), juce::KeyPress());
    popup.addComboBox("box", names);
    if(popup.runModalLoop()==0)
      return false;
    popup.setVisible(false);
    String selectedFilename(popup.getComboBoxComponent("box")->getText());
    URL fwUrl(props->getValue("owl-updates-dir-url")+selectedFilename);
    ScopedPointer<InputStream> strm;
    strm = fwUrl.createInputStream(0);
    if(strm == NULL){
      AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Connection Error", "File unavailable", "Continue");
      return false;
    }
    File theTargetFile(ApplicationConfiguration::getApplicationDirectory().getChildFile(selectedFilename));
    FileChooser chooser("Save As", theTargetFile, "*.bin");
    bool succeeded = false;
    if(!chooser.browseForFileToSave(true))
      return false;
    theTargetFile = chooser.getResult();
    TemporaryFile temp (theTargetFile);
    ScopedPointer<FileOutputStream> out(temp.getFile().createOutputStream());
    if(out != nullptr) {
      out->writeFromInputStream(*strm, strm->getTotalLength());
      out = nullptr; // deletes the stream
      succeeded = temp.overwriteTargetFileWithTemporary();
    }
    if(!succeeded){
      AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "File Error", "Failed to save file", "Continue");
      return false;
    }
    if(AlertWindow::showOkCancelBox(AlertWindow::QuestionIcon, "Update Device", 
				    "Would you like to update your OWL with this binary now? "+warningString, "Yes", "No"))
    {
        DBG("pathName"<< theTargetFile.getFullPathName());
        DBG("optionString " << optionString);
        return deviceFirmwareUpdate(theTargetFile, optionString);
    }
    return true;
}
Exemplo n.º 12
0
//==============================================================================
void Image::clear (const Rectangle<int>& area, const Colour& colourToClearTo)
{
    const ScopedPointer<LowLevelGraphicsContext> g (image->createLowLevelContext());
    g->setFill (colourToClearTo);
    g->fillRect (area, true);
}
Exemplo n.º 13
0
static String valueTreeToString (const ValueTree& v)
{
    const ScopedPointer<XmlElement> xml (v.createXml());
    return xml != nullptr ? xml->createDocument ("", true, false) : String();
}
Exemplo n.º 14
0
 void createReader()
 {
     if (reader == nullptr && source != nullptr)
         if (InputStream* audioFileStream = source->createInputStream())
             reader = owner.formatManagerToUse.createReaderFor (audioFileStream);
 }
Exemplo n.º 15
0
bool OpenGLContext::setSwapInterval (int numFramesPerSwap)
{
    return nativeContext != nullptr && nativeContext->setSwapInterval (numFramesPerSwap);
}
void JucerDocumentEditor::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)
{
    ComponentLayout* const currentLayout = getCurrentLayout();
    PaintRoutine* const currentPaintRoutine = getCurrentPaintRoutine();

    const int cmd = ModifierKeys::commandModifier;
    const int shift = ModifierKeys::shiftModifier;

    if (commandID >= JucerCommandIDs::newComponentBase
         && commandID < JucerCommandIDs::newComponentBase + ObjectTypes::numComponentTypes)
    {
        const int index = commandID - JucerCommandIDs::newComponentBase;

        result.setInfo ("New " + ObjectTypes::componentTypeHandlers [index]->getTypeName(),
                        "Creates a new " + ObjectTypes::componentTypeHandlers [index]->getTypeName(),
                        CommandCategories::editing, 0);
        return;
    }

    if (commandID >= JucerCommandIDs::newElementBase
         && commandID < JucerCommandIDs::newElementBase + ObjectTypes::numElementTypes)
    {
        const int index = commandID - JucerCommandIDs::newElementBase;

        result.setInfo (String ("New ") + ObjectTypes::elementTypeNames [index],
                        String ("Adds a new ") + ObjectTypes::elementTypeNames [index],
                        CommandCategories::editing, 0);

        result.setActive (currentPaintRoutine != nullptr);
        return;
    }

    switch (commandID)
    {
    case JucerCommandIDs::toFront:
        result.setInfo (TRANS("Bring to front"), TRANS("Brings the currently selected component to the front."), CommandCategories::editing, 0);
        result.setActive (isSomethingSelected());
        result.defaultKeypresses.add (KeyPress ('f', cmd, 0));
        break;

    case JucerCommandIDs::toBack:
        result.setInfo (TRANS("Send to back"), TRANS("Sends the currently selected component to the back."), CommandCategories::editing, 0);
        result.setActive (isSomethingSelected());
        result.defaultKeypresses.add (KeyPress ('b', cmd, 0));
        break;

    case JucerCommandIDs::group:
        result.setInfo (TRANS("Group selected items"), TRANS("Turns the currently selected elements into a single group object."), CommandCategories::editing, 0);
        result.setActive (currentPaintRoutine != nullptr && currentPaintRoutine->getSelectedElements().getNumSelected() > 1);
        result.defaultKeypresses.add (KeyPress ('k', cmd, 0));
        break;

    case JucerCommandIDs::ungroup:
        result.setInfo (TRANS("Ungroup selected items"), TRANS("Turns the currently selected elements into a single group object."), CommandCategories::editing, 0);
        result.setActive (currentPaintRoutine != nullptr
                           && currentPaintRoutine->getSelectedElements().getNumSelected() == 1
                           && currentPaintRoutine->getSelectedElements().getSelectedItem (0)->getTypeName() == "Group");
        result.defaultKeypresses.add (KeyPress ('k', cmd | shift, 0));
        break;

    case JucerCommandIDs::test:
        result.setInfo (TRANS("Test component..."), TRANS("Runs the current component interactively."), CommandCategories::view, 0);
        result.defaultKeypresses.add (KeyPress ('t', cmd, 0));
        break;

    case JucerCommandIDs::enableSnapToGrid:
        result.setInfo (TRANS("Enable snap-to-grid"), TRANS("Toggles whether components' positions are aligned to a grid."), CommandCategories::view, 0);
        result.setTicked (document != nullptr && document->isSnapActive (false));
        result.defaultKeypresses.add (KeyPress ('g', cmd, 0));
        break;

    case JucerCommandIDs::showGrid:
        result.setInfo (TRANS("Show snap-to-grid"), TRANS("Toggles whether the snapping grid is displayed on-screen."), CommandCategories::view, 0);
        result.setTicked (document != nullptr && document->isSnapShown());
        result.defaultKeypresses.add (KeyPress ('g', cmd | shift, 0));
        break;

    case JucerCommandIDs::editCompLayout:
        result.setInfo (TRANS("Edit sub-component layout"), TRANS("Switches to the sub-component editor view."), CommandCategories::view, 0);
        result.setTicked (currentLayout != nullptr);
        result.defaultKeypresses.add (KeyPress ('n', cmd, 0));
        break;

    case JucerCommandIDs::editCompGraphics:
        result.setInfo (TRANS("Edit background graphics"), TRANS("Switches to the background graphics editor view."), CommandCategories::view, 0);
        result.setTicked (currentPaintRoutine != nullptr);
        result.defaultKeypresses.add (KeyPress ('m', cmd, 0));
        break;

    case JucerCommandIDs::bringBackLostItems:
        result.setInfo (TRANS("Retrieve offscreen items"), TRANS("Moves any items that are lost beyond the edges of the screen back to the centre."), CommandCategories::editing, 0);
        result.setActive (currentPaintRoutine != nullptr || currentLayout != nullptr);
        result.defaultKeypresses.add (KeyPress ('m', cmd, 0));
        break;

    case JucerCommandIDs::zoomIn:
        result.setInfo (TRANS("Zoom in"), TRANS("Zooms in on the current component."), CommandCategories::editing, 0);
        result.setActive (currentPaintRoutine != nullptr || currentLayout != nullptr);
        result.defaultKeypresses.add (KeyPress (']', cmd, 0));
        break;

    case JucerCommandIDs::zoomOut:
        result.setInfo (TRANS("Zoom out"), TRANS("Zooms out on the current component."), CommandCategories::editing, 0);
        result.setActive (currentPaintRoutine != nullptr || currentLayout != nullptr);
        result.defaultKeypresses.add (KeyPress ('[', cmd, 0));
        break;

    case JucerCommandIDs::zoomNormal:
        result.setInfo (TRANS("Zoom to 100%"), TRANS("Restores the zoom level to normal."), CommandCategories::editing, 0);
        result.setActive (currentPaintRoutine != nullptr || currentLayout != nullptr);
        result.defaultKeypresses.add (KeyPress ('1', cmd, 0));
        break;

    case JucerCommandIDs::spaceBarDrag:
        result.setInfo (TRANS("Scroll while dragging mouse"), TRANS("When held down, this key lets you scroll around by dragging with the mouse."),
                        CommandCategories::view, ApplicationCommandInfo::wantsKeyUpDownCallbacks);
        result.setActive (currentPaintRoutine != nullptr || currentLayout != nullptr);
        result.defaultKeypresses.add (KeyPress (KeyPress::spaceKey, 0, 0));
        break;

    case JucerCommandIDs::compOverlay0:
    case JucerCommandIDs::compOverlay33:
    case JucerCommandIDs::compOverlay66:
    case JucerCommandIDs::compOverlay100:
        {
            int amount = 0, num = 0;

            if (commandID == JucerCommandIDs::compOverlay33)
            {
                amount = 33;
                num = 1;
            }
            else if (commandID == JucerCommandIDs::compOverlay66)
            {
                amount = 66;
                num = 2;
            }
            else if (commandID == JucerCommandIDs::compOverlay100)
            {
                amount = 100;
                num = 3;
            }

            result.defaultKeypresses.add (KeyPress ('2' + num, cmd, 0));

            int currentAmount = 0;
            if (document != nullptr && document->getComponentOverlayOpacity() > 0.9f)
                currentAmount = 100;
            else if (document != nullptr && document->getComponentOverlayOpacity() > 0.6f)
                currentAmount = 66;
            else if (document != nullptr && document->getComponentOverlayOpacity() > 0.3f)
                currentAmount = 33;

            result.setInfo (commandID == JucerCommandIDs::compOverlay0
                                ? TRANS("No component overlay")
                                : TRANS("Overlay with opacity of 123%").replace ("123", String (amount)),
                            TRANS("Changes the opacity of the components that are shown over the top of the graphics editor."),
                            CommandCategories::view, 0);
            result.setActive (currentPaintRoutine != nullptr && document->getComponentLayout() != nullptr);
            result.setTicked (amount == currentAmount);
        }
        break;

    case StandardApplicationCommandIDs::undo:
        result.setInfo (TRANS ("Undo"), TRANS ("Undo"), "Editing", 0);
        result.setActive (document != nullptr && document->getUndoManager().canUndo());
        result.defaultKeypresses.add (KeyPress ('z', cmd, 0));
        break;

    case StandardApplicationCommandIDs::redo:
        result.setInfo (TRANS ("Redo"), TRANS ("Redo"), "Editing", 0);
        result.setActive (document != nullptr && document->getUndoManager().canRedo());
        result.defaultKeypresses.add (KeyPress ('z', cmd | shift, 0));
        break;

    case StandardApplicationCommandIDs::cut:
        result.setInfo (TRANS ("Cut"), String::empty, "Editing", 0);
        result.setActive (isSomethingSelected());
        result.defaultKeypresses.add (KeyPress ('x', cmd, 0));
        break;

    case StandardApplicationCommandIDs::copy:
        result.setInfo (TRANS ("Copy"), String::empty, "Editing", 0);
        result.setActive (isSomethingSelected());
        result.defaultKeypresses.add (KeyPress ('c', cmd, 0));
        break;

    case StandardApplicationCommandIDs::paste:
        {
            result.setInfo (TRANS ("Paste"), String::empty, "Editing", 0);
            result.defaultKeypresses.add (KeyPress ('v', cmd, 0));

            bool canPaste = false;

            ScopedPointer<XmlElement> doc (XmlDocument::parse (SystemClipboard::getTextFromClipboard()));

            if (doc != nullptr)
            {
                if (doc->hasTagName (ComponentLayout::clipboardXmlTag))
                    canPaste = (currentLayout != nullptr);
                else if (doc->hasTagName (PaintRoutine::clipboardXmlTag))
                    canPaste = (currentPaintRoutine != nullptr);
            }

            result.setActive (canPaste);
        }

        break;

    case StandardApplicationCommandIDs::del:
        result.setInfo (TRANS ("Delete"), String::empty, "Editing", 0);
        result.setActive (isSomethingSelected());
        break;

    case StandardApplicationCommandIDs::selectAll:
        result.setInfo (TRANS ("Select All"), String::empty, "Editing", 0);
        result.setActive (currentPaintRoutine != nullptr || currentLayout != nullptr);
        result.defaultKeypresses.add (KeyPress ('a', cmd, 0));
        break;

    case StandardApplicationCommandIDs::deselectAll:
        result.setInfo (TRANS ("Deselect All"), String::empty, "Editing", 0);
        result.setActive (currentPaintRoutine != nullptr || currentLayout != nullptr);
        result.defaultKeypresses.add (KeyPress ('d', cmd, 0));
        break;

    default:
        break;
    }
}
Exemplo n.º 17
0
int OpenGLContext::getSwapInterval() const
{
    return nativeContext != nullptr ? nativeContext->getSwapInterval() : 0;
}
bool AppearanceSettings::writeToFile (const File& file) const
{
    const ScopedPointer<XmlElement> xml (settings.createXml());
    return xml != nullptr && xml->writeToFile (file, String::empty);
}
Exemplo n.º 19
0
void* OpenGLContext::getRawContext() const noexcept
{
    return nativeContext != nullptr ? nativeContext->getRawContext() : nullptr;
}
Exemplo n.º 20
0
 void changeListenerCallback (ChangeBroadcaster* source) override
 {
     if (source == thumbnail)
         showFile (thumbnail->getLastDroppedFile());
 }
Exemplo n.º 21
0
//==============================================================================
bool UndoManager::perform (UndoableAction* const command_, const String& actionName)
{
    if (command_ != nullptr)
    {
        ScopedPointer<UndoableAction> command (command_);

        if (actionName.isNotEmpty())
            currentTransactionName = actionName;

        if (reentrancyCheck)
        {
            jassertfalse;    // don't call perform() recursively from the UndoableAction::perform() or
                             // undo() methods, or else these actions won't actually get done.

            return false;
        }
        else if (command->perform())
        {
            OwnedArray<UndoableAction>* commandSet = transactions [nextIndex - 1];

            if (commandSet != nullptr && ! newTransaction)
            {
                UndoableAction* lastAction = commandSet->getLast();

                if (lastAction != nullptr)
                {
                    UndoableAction* coalescedAction = lastAction->createCoalescedAction (command);

                    if (coalescedAction != nullptr)
                    {
                        command = coalescedAction;
                        totalUnitsStored -= lastAction->getSizeInUnits();
                        commandSet->removeLast();
                    }
                }
            }
            else
            {
                commandSet = new OwnedArray<UndoableAction>();
                transactions.insert (nextIndex, commandSet);
                transactionNames.insert (nextIndex, currentTransactionName);
                ++nextIndex;
            }

            totalUnitsStored += command->getSizeInUnits();
            commandSet->add (command.release());
            newTransaction = false;

            while (nextIndex < transactions.size())
            {
                const OwnedArray <UndoableAction>* const lastSet = transactions.getLast();

                for (int i = lastSet->size(); --i >= 0;)
                    totalUnitsStored -= lastSet->getUnchecked (i)->getSizeInUnits();

                transactions.removeLast();
                transactionNames.remove (transactionNames.size() - 1);
            }

            while (nextIndex > 0
                   && totalUnitsStored > maxNumUnitsToKeep
                   && transactions.size() > minimumTransactionsToKeep)
            {
                const OwnedArray <UndoableAction>* const firstSet = transactions.getFirst();

                for (int i = firstSet->size(); --i >= 0;)
                    totalUnitsStored -= firstSet->getUnchecked (i)->getSizeInUnits();

                jassert (totalUnitsStored >= 0); // something fishy going on if this fails!

                transactions.remove (0);
                transactionNames.remove (0);
                --nextIndex;
            }

            sendChangeMessage();

            return true;
        }
    }

    return false;
}
Exemplo n.º 22
0
bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream& header)
{
    String comment;
    comment << newLine << newLine
            << "   This is an auto-generated file, created by " << JUCEApplication::getInstance()->getApplicationName() << newLine
            << "   Do not edit anything in this file!" << newLine << newLine
            << "*/" << newLine << newLine;

    header << "/* ========================================================================================="
           << comment;

    cpp << "/* ==================================== " << resourceFileIdentifierString << " ===================================="
        << comment;

    if (juceHeader.exists())
        header << CodeHelpers::createIncludeStatement (juceHeader, cppFile) << newLine;

    const String namespaceName (className);
    StringArray variableNames, returnCodes;

    int i;
    for (i = 0; i < files.size(); ++i)
    {
        String variableNameRoot (CodeHelpers::makeValidIdentifier (files.getUnchecked(i)->getFileName()
                                                                       .replaceCharacters (" .", "__")
                                                                       .retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"),
                                                                      false, true, false));
        String variableName (variableNameRoot);

        int suffix = 2;
        while (variableNames.contains (variableName))
            variableName = variableNameRoot + String (suffix++);

        variableNames.add (variableName);
        returnCodes.add ("numBytes = " + namespaceName + "::" + variableName + "Size; return "
                            + namespaceName + "::" + variableName + ";");
    }

    cpp << CodeHelpers::createIncludeStatement (cppFile.withFileExtension (".h"), cppFile) << newLine
        << newLine
        << newLine
        << "const char* " << namespaceName << "::getNamedResource (const char* resourceNameUTF8, int& numBytes) throw()" << newLine
        << "{" << newLine;

    CodeHelpers::createStringMatcher (cpp, "resourceNameUTF8", variableNames, returnCodes, 4);

    cpp << "    numBytes = 0;" << newLine
        << "    return 0;" << newLine
        << "}" << newLine
        << newLine;

    header << "namespace " << namespaceName << newLine << "{" << newLine;

    for (i = 0; i < files.size(); ++i)
    {
        const File file (*files.getUnchecked(i));
        const int64 dataSize = file.getSize();

        ScopedPointer <InputStream> fileStream (file.createInputStream());
        jassert (fileStream != 0);

        if (fileStream != 0)
        {
            const String variableName (variableNames[i]);
            const String tempVariable ("temp_" + String::toHexString (file.hashCode()));

            header << "    extern const char*   " << variableName << ";" << newLine;
            header << "    const int            " << variableName << "Size = " << (int) dataSize << ";" << newLine << newLine;

            cpp  << newLine << "//================== " << file.getFileName() << " ==================" << newLine
                << "static const unsigned char " << tempVariable
                << "[] =" << newLine;

            {
                MemoryBlock data;
                fileStream->readIntoMemoryBlock (data);
                CodeHelpers::writeDataAsCppLiteral (data, cpp);
            }

            cpp << newLine << newLine
                << "const char* " << namespaceName << "::" << variableName << " = (const char*) "
                << tempVariable << ";" << newLine;
        }
    }

    header << "    // If you provide the name of one of the binary resource variables above, this function will" << newLine
           << "    // return the corresponding data and its size (or a null pointer if the name isn't found)." << newLine
           << "    const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) throw();" << newLine
           << "}" << newLine;

    return true;
}
Exemplo n.º 23
0
bool MultiDocumentPanel::closeDocument (Component* component,
                                        const bool checkItsOkToCloseFirst)
{
    if (components.contains (component))
    {
        if (checkItsOkToCloseFirst && ! tryToCloseDocument (component))
            return false;

        component->removeComponentListener (this);

        const bool shouldDelete = MultiDocHelpers::shouldDeleteComp (component);
        component->getProperties().remove ("mdiDocumentDelete_");
        component->getProperties().remove ("mdiDocumentBkg_");

        if (mode == FloatingWindows)
        {
            for (int i = getNumChildComponents(); --i >= 0;)
            {
                MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i));

                if (dw != nullptr && dw->getContentComponent() == component)
                {
                    ScopedPointer<MultiDocumentPanelWindow> (dw)->clearContentComponent();
                    break;
                }
            }

            if (shouldDelete)
                delete component;

            components.removeFirstMatchingValue (component);

            if (isFullscreenWhenOneDocument() && components.size() == 1)
            {
                for (int i = getNumChildComponents(); --i >= 0;)
                {
                    ScopedPointer<MultiDocumentPanelWindow> dw (dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i)));

                    if (dw != nullptr)
                        dw->clearContentComponent();
                }

                addAndMakeVisible (components.getFirst());
            }
        }
        else
        {
            jassert (components.indexOf (component) >= 0);

            if (tabComponent != nullptr)
            {
                for (int i = tabComponent->getNumTabs(); --i >= 0;)
                    if (tabComponent->getTabContentComponent (i) == component)
                        tabComponent->removeTab (i);
            }
            else
            {
                removeChildComponent (component);
            }

            if (shouldDelete)
                delete component;

            if (tabComponent != nullptr && tabComponent->getNumTabs() <= numDocsBeforeTabsUsed)
                tabComponent = nullptr;

            components.removeFirstMatchingValue (component);

            if (components.size() > 0 && tabComponent == nullptr)
                addAndMakeVisible (components.getFirst());
        }

        resized();
        activeDocumentChanged();
    }
    else
    {
        jassertfalse;
    }

    return true;
}
Exemplo n.º 24
0
void AudioPath::getAudioDeviceSetup(AudioDeviceManager::AudioDeviceSetup &setup)
{
	mDevManager->getAudioDeviceSetup(setup);
}
Exemplo n.º 25
0
bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream& header)
{
    String comment;
    comment << newLine << newLine
            << "   This is an auto-generated file, created by " << JUCEApplication::getInstance()->getApplicationName() << newLine
            << "   Do not edit anything in this file!" << newLine << newLine
            << "*/" << newLine << newLine;

    header << "/* ========================================================================================="
           << comment;

    cpp << "/* ==================================== " << resourceFileIdentifierString << " ===================================="
        << comment;

    if (juceHeader.exists())
        header << CodeHelpers::createIncludeStatement (juceHeader, cppFile) << newLine;

    const String namespaceName (className);
    StringArray returnCodes;

    int i;
    for (i = 0; i < files.size(); ++i)
        returnCodes.add ("numBytes = " + namespaceName + "::" + variableNames[i] + "Size; return "
                            + namespaceName + "::" + variableNames[i] + ";");

    cpp << CodeHelpers::createIncludeStatement (cppFile.withFileExtension (".h"), cppFile) << newLine
        << newLine
        << newLine
        << "const char* " << namespaceName << "::getNamedResource (const char* resourceNameUTF8, int& numBytes) throw()" << newLine
        << "{" << newLine;

    CodeHelpers::createStringMatcher (cpp, "resourceNameUTF8", variableNames, returnCodes, 4);

    cpp << "    numBytes = 0;" << newLine
        << "    return 0;" << newLine
        << "}" << newLine
        << newLine;

    header << "namespace " << namespaceName << newLine << "{" << newLine;

    for (i = 0; i < files.size(); ++i)
    {
        const File& file = files.getReference(i);
        const int64 dataSize = file.getSize();

        ScopedPointer <InputStream> fileStream (file.createInputStream());
        jassert (fileStream != nullptr);

        if (fileStream != nullptr)
        {
            const String variableName (variableNames[i]);
            const String tempVariable ("temp_" + String::toHexString (file.hashCode()));

            header << "    extern const char*   " << variableName << ";" << newLine;
            header << "    const int            " << variableName << "Size = " << (int) dataSize << ";" << newLine << newLine;

            cpp  << newLine << "//================== " << file.getFileName() << " ==================" << newLine
                << "static const unsigned char " << tempVariable
                << "[] =" << newLine;

            {
                MemoryBlock data;
                fileStream->readIntoMemoryBlock (data);
                CodeHelpers::writeDataAsCppLiteral (data, cpp);
            }

            cpp << newLine << newLine
                << "const char* " << namespaceName << "::" << variableName << " = (const char*) "
                << tempVariable << ";" << newLine;
        }
    }

    header << "    // If you provide the name of one of the binary resource variables above, this function will" << newLine
           << "    // return the corresponding data and its size (or a null pointer if the name isn't found)." << newLine
           << "    const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) throw();" << newLine
           << "}" << newLine;

    return true;
}
Exemplo n.º 26
0
    void open (bool asSocket, bool asSender)
    {
        close();

        // Make the appropriate bits of UI visible..
        sendText.setVisible (true);
        sendButton.setVisible (true);

        incomingMessages.setText (String::empty, false);
        incomingMessages.setVisible (true);

        // and try to open the socket or pipe...
        bool openedOk = false;

        if (asSender)
        {
            // if we're connecting to an existing server, we can just create a connection object
            // directly.
            ScopedPointer<DemoInterprocessConnection> newConnection (new DemoInterprocessConnection (*this));

            if (asSocket)
            {
                openedOk = newConnection->connectToSocket (socketHost.getText(),
                                                           socketNumber.getText().getIntValue(),
                                                           1000);
            }
            else
            {
                openedOk = newConnection->connectToPipe (pipeName.getText(), 5000);
            }

            if (openedOk)
                activeConnections.add (newConnection.release());
        }
        else
        {
            // if we're starting up a server, we need to tell the server to start waiting for
            // clients to connect. It'll then create connection objects for us when clients arrive.
            if (asSocket)
            {
                openedOk = server->beginWaitingForSocket (socketNumber.getText().getIntValue());

                if (openedOk)
                    appendMessage ("Waiting for another app to connect to this socket..");
            }
            else
            {
                ScopedPointer<DemoInterprocessConnection> newConnection (new DemoInterprocessConnection (*this));

                openedOk = newConnection->createPipe (pipeName.getText(), 2000);

                if (openedOk)
                {
                    appendMessage ("Waiting for another app to connect to this pipe..");
                    activeConnections.add (newConnection.release());
                }
            }
        }

        if (! openedOk)
        {
            modeSelector.setSelectedId (8);

            AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
                                              "Interprocess Comms Demo",
                                              "Failed to open the socket or pipe...");
        }
    }
void SignalProcessorAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
        
    // Restore the parameters from this memory block,
    // whose contents will have been created by the getStateInformation() call.
    // This getXmlFromBinary() helper function retrieves our XML from the binary blob..
    ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
    
    if (xmlState != nullptr)
    {
        // make sure that it's actually our type of XML object
        if (xmlState->hasTagName ("MYPLUGINSETTINGS"))
        {
            // now pull out our parameters..
            averagingBufferSize     = xmlState->getIntAttribute  ("averagingBufferSize", averagingBufferSize);
            fftAveragingWindow      = (float) xmlState->getDoubleAttribute ("fftAveragingWindow", fftAveragingWindow);
            inputSensitivity        = (float) xmlState->getDoubleAttribute ("inputSensitivity", inputSensitivity);
            sendTimeInfo            = xmlState->getBoolAttribute ("sendTimeInfo", sendTimeInfo);
            sendSignalLevel         = xmlState->getBoolAttribute ("sendSignalLevel", sendSignalLevel);
            sendImpulse             = xmlState->getBoolAttribute ("sendImpulse", sendImpulse);
            sendFFT                 = xmlState->getBoolAttribute ("sendFFT", sendFFT);
            channel                 = xmlState->getIntAttribute  ("channel", channel);
            monoStereo              = xmlState->getBoolAttribute ("monoStereo", monoStereo);
            logarithmicFFT          = xmlState->getBoolAttribute ("logarithmicFFT", logarithmicFFT);
            averageEnergyBufferSize = xmlState->getIntAttribute  ("averageEnergyBufferSize", averageEnergyBufferSize);
            sendOSC                 = xmlState->getBoolAttribute ("sendOSC", sendOSC);
            sendBinaryUDP           = xmlState->getBoolAttribute ("sendBinaryUDP", sendBinaryUDP);
            instantSigValGain       = (float) xmlState->getDoubleAttribute ("instantSigValGain", instantSigValGain);
            instantSigValNbOfSamplesSkipped = (float) xmlState->getDoubleAttribute ("instantSigValNbOfSamplesSkipped", instantSigValNbOfSamplesSkipped);
        }
    }
    
    //Build the default Signal Messages, and preallocate the char* which will receive their serialized data
    defineDefaultSignalMessages();
}
void ComponentLayoutEditor::refreshAllComponents()
{
    for (int i = getNumChildComponents(); --i >= 0;)
    {
        ScopedPointer<ComponentOverlayComponent> overlay (dynamic_cast <ComponentOverlayComponent*> (getChildComponent (i)));

        if (overlay != nullptr && layout.containsComponent (overlay->target))
            overlay.release();
    }

    for (int i = subCompHolder->getNumChildComponents(); --i >= 0;)
    {
        Component* const comp = subCompHolder->getChildComponent (i);

        if (! layout.containsComponent (comp))
            subCompHolder->removeChildComponent (comp);
    }

    Component* lastComp = nullptr;
    Component* lastOverlay = nullptr;

    for (int i = layout.getNumComponents(); --i >= 0;)
    {
        Component* const c = layout.getComponent (i);
        jassert (c != nullptr);

        ComponentOverlayComponent* overlay = getOverlayCompFor (c);

        bool isNewOverlay = false;

        if (overlay == 0)
        {
            ComponentTypeHandler* const handler = ComponentTypeHandler::getHandlerFor (*c);
            jassert (handler != nullptr);

            overlay = handler->createOverlayComponent (c, layout);

            addAndMakeVisible (overlay);
            isNewOverlay = true;
        }

        if (lastOverlay != nullptr)
            overlay->toBehind (lastOverlay);
        else
            overlay->toFront (false);

        lastOverlay = overlay;

        subCompHolder->addAndMakeVisible (c);

        if (lastComp != nullptr)
            c->toBehind (lastComp);
        else
            c->toFront (false);

        lastComp = c;

        c->setWantsKeyboardFocus (false);
        c->setFocusContainer (true);

        if (isNewOverlay)
            overlay->updateBoundsToMatchTarget();
    }

    if (grid.updateFromDesign (document))
        subCompHolder->repaint();

    subCompHolder->setBounds (getComponentArea());
    subCompHolder->resized();
}
//==============================================================================
void JucerDocument::fillInGeneratedCode (GeneratedCode& code) const
{
    code.className = className;
    code.componentName = componentName;
    code.parentClasses = parentClasses;
    code.constructorParams = constructorParams;
    code.initialisers.addLines (variableInitialisers);

    if (! componentName.isEmpty())
        code.constructorCode << "setName (" + quotedString (componentName, false) + ");\n";

    // call these now, just to make sure they're the first two methods in the list.
    code.getCallbackCode (String::empty, "void", "paint (Graphics& g)", false)
        << "//[UserPrePaint] Add your own custom painting code here..\n//[/UserPrePaint]\n\n";

    code.getCallbackCode (String::empty, "void", "resized()", false);

    if (ComponentLayout* l = getComponentLayout())
        l->fillInGeneratedCode (code);

    fillInPaintCode (code);

    ScopedPointer<XmlElement> e (createXml());
    jassert (e != nullptr);
    code.jucerMetadata = e->createDocument ("", false, false);

    resources.fillInGeneratedCode (code);

    code.constructorCode
        << "\n//[UserPreSize]\n"
           "//[/UserPreSize]\n";

    if (initialWidth > 0 || initialHeight > 0)
        code.constructorCode << "\nsetSize (" << initialWidth << ", " << initialHeight << ");\n";

    code.getCallbackCode (String::empty, "void", "paint (Graphics& g)", false)
        << "//[UserPaint] Add your own custom painting code here..\n//[/UserPaint]";

    code.getCallbackCode (String::empty, "void", "resized()", false)
        << "//[UserResized] Add your own custom resize handling here..\n//[/UserResized]";

    // add optional methods
    StringArray baseClasses, returnValues, methods, initialContents;
    getOptionalMethods (baseClasses, returnValues, methods, initialContents);

    for (int i = 0; i < methods.size(); ++i)
    {
        if (isOptionalMethodEnabled (methods[i]))
        {
            String baseClassToAdd (baseClasses[i]);

            if (baseClassToAdd == "Component" || baseClassToAdd == "Button")
                baseClassToAdd.clear();

            String& s = code.getCallbackCode (baseClassToAdd, returnValues[i], methods[i], false);

            if (! s.contains ("//["))
            {
                String userCommentTag ("UserCode_");
                userCommentTag += methods[i].upToFirstOccurrenceOf ("(", false, false).trim();

                s << "\n//[" << userCommentTag << "] -- Add your code here...\n"
                  << initialContents[i];

                if (initialContents[i].isNotEmpty() && ! initialContents[i].endsWithChar ('\n'))
                    s << '\n';

                s << "//[/" << userCommentTag << "]\n";
            }
        }
    }
}