gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

partbutton.cpp (4628B)


      1 #include "partbutton.h"
      2 
      3 #include "pluginEditor.h"
      4 #include "pluginProcessor.h"
      5 
      6 #include "patchmanager/patchmanager.h"
      7 #include "patchmanager/savepatchdesc.h"
      8 #include "patchmanager/listmodel.h"
      9 
     10 namespace jucePluginEditorLib
     11 {
     12 	namespace
     13 	{
     14 		std::pair<pluginLib::patchDB::PatchPtr, patchManager::ListModel*> getPatchFromDragSource(const juce::DragAndDropTarget::SourceDetails& _source)
     15 		{
     16 			auto* list = dynamic_cast<patchManager::ListModel*>(_source.sourceComponent.get());
     17 			if(!list)
     18 				return {};
     19 
     20 			const auto& patches = patchManager::SavePatchDesc::getPatchesFromDragSource(_source);
     21 
     22 			if (patches.size() != 1)
     23 				return {};
     24 
     25 			return {patches.front(), list};
     26 		}
     27 	}
     28 
     29 	template <typename T> bool PartButton<T>::isInterestedInDragSource(const SourceDetails& _dragSourceDetails)
     30 	{
     31 		const auto* savePatchDesc = patchManager::SavePatchDesc::fromDragSource(_dragSourceDetails);
     32 
     33 		if(savePatchDesc)
     34 			return !savePatchDesc->isPartValid() || savePatchDesc->getPart() != getPart();
     35 
     36 		const auto patch = getPatchFromDragSource(_dragSourceDetails);
     37 		return patch.first != nullptr;
     38 	}
     39 
     40 	template <typename T> bool PartButton<T>::isInterestedInFileDrag(const juce::StringArray& _files)
     41 	{
     42 		if(_files.size() != 1)
     43 			return false;
     44 		return true;
     45 	}
     46 
     47 	template <typename T> void PartButton<T>::fileDragEnter(const juce::StringArray& files, int x, int y)
     48 	{
     49 		if(isInterestedInFileDrag(files))
     50 			setIsDragTarget(true);
     51 		FileDragAndDropTarget::fileDragEnter(files, x, y);
     52 	}
     53 
     54 	template <typename T> void PartButton<T>::fileDragExit(const juce::StringArray& files)
     55 	{
     56 		FileDragAndDropTarget::fileDragExit(files);
     57 		setIsDragTarget(false);
     58 	}
     59 
     60 	template <typename T> void PartButton<T>::filesDropped(const juce::StringArray& _files, int, int)
     61 	{
     62 		setIsDragTarget(false);
     63 
     64 		auto* pm = m_editor.getPatchManager();
     65 		if(!pm)
     66 			return;
     67 
     68 		if(!pm->activatePatch(_files.begin()->toStdString(), getPart()))
     69 		{
     70 			genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, 
     71 				m_editor.getProcessor().getProperties().name, 
     72 				"Failed to load patch. Make sure that the format is supported and that the file only contains one patch.\n"
     73 				"\n"
     74 				"Drag files with multiple patches onto the Patch Manager instead to import them");
     75 		}
     76 	}
     77 
     78 	template <typename T> void PartButton<T>::itemDragEnter(const SourceDetails& dragSourceDetails)
     79 	{
     80 		if(isInterestedInDragSource(dragSourceDetails))
     81 			setIsDragTarget(true);
     82 	}
     83 
     84 	template <typename T> void PartButton<T>::itemDragExit(const SourceDetails& _dragSourceDetails)
     85 	{
     86 		DragAndDropTarget::itemDragExit(_dragSourceDetails);
     87 		setIsDragTarget(false);
     88 	}
     89 
     90 	template <typename T> void PartButton<T>::itemDropped(const SourceDetails& _dragSourceDetails)
     91 	{
     92 		setIsDragTarget(false);
     93 
     94 		const auto* savePatchDesc = patchManager::SavePatchDesc::fromDragSource(_dragSourceDetails);
     95 
     96 		auto* pm = m_editor.getPatchManager();
     97 
     98 		if(savePatchDesc)
     99 		{
    100 			// part is not valid if the drag source is the patch manager
    101 			if(savePatchDesc->isPartValid())
    102 			{
    103 				if(savePatchDesc->getPart() == getPart())
    104 					return;
    105 				pm->copyPart(m_part, static_cast<uint8_t>(savePatchDesc->getPart()));
    106 			}
    107 		}
    108 
    109 		const auto [patch, list] = getPatchFromDragSource(_dragSourceDetails);
    110 		if(!patch)
    111 			return;
    112 
    113 		if(pm->getCurrentPart() == m_part)
    114 		{
    115 			list->setSelectedPatches({patch});
    116 			list->activateSelectedPatch();
    117 		}
    118 		else
    119 		{
    120 			pm->setSelectedPatch(m_part, patch, list->getSearchHandle());
    121 		}
    122 	}
    123 
    124 	template <typename T> void PartButton<T>::paint(juce::Graphics& g)
    125 	{
    126 		genericUI::Button<T>::paint(g);
    127 
    128 		if(m_isDragTarget)
    129 		{
    130 			g.setColour(juce::Colour(0xff00ff00));
    131 			g.drawRect(0, 0, genericUI::Button<T>::getWidth(), genericUI::Button<T>::getHeight(), 3);
    132 		}
    133 	}
    134 	
    135 	template <typename T> void PartButton<T>::mouseDrag(const juce::MouseEvent& _event)
    136 	{
    137 		auto* patchManager = m_editor.getPatchManager();
    138 		if(patchManager)
    139 			m_editor.startDragging(new patchManager::SavePatchDesc(*patchManager, m_part), this);
    140 		genericUI::Button<T>::mouseDrag(_event);
    141 	}
    142 
    143 	template <typename T> void PartButton<T>::mouseUp(const juce::MouseEvent& _event)
    144 	{
    145 		if(!_event.mods.isPopupMenu() && genericUI::Button<T>::isDown() && genericUI::Button<T>::isOver())
    146 			onClick();
    147 
    148 		genericUI::Button<T>::mouseUp(_event);
    149 	}
    150 
    151 	template <typename T> void PartButton<T>::setIsDragTarget(const bool _isDragTarget)
    152 	{
    153 		if(m_isDragTarget == _isDragTarget)
    154 			return;
    155 		m_isDragTarget = _isDragTarget;
    156 		genericUI::Button<T>::repaint();
    157 	}
    158 
    159 	template class PartButton<juce::TextButton>;
    160 	template class PartButton<juce::DrawableButton>;
    161 	template class PartButton<juce::ImageButton>;
    162 }