1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
|
/**
bespoke synth, a software modular synthesizer
Copyright (C) 2021 Ryan Challinor (contact: awwbees@gmail.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
//
// IDrawableModule.h
// modularSynth
//
// Created by Ryan Challinor on 11/25/12.
//
//
#pragma once
#include "IClickable.h"
#include "IPollable.h"
#include "ModuleSaveData.h"
#include "IPatchable.h"
class Checkbox;
class IUIControl;
class FileStreamIn;
class FileStreamOut;
class FloatSlider;
class RollingBuffer;
class ofxJSONElement;
class Sample;
class PatchCable;
class PatchCableSource;
class ModuleContainer;
class UIGrid;
enum ModuleCategory
{
kModuleCategory_Note,
kModuleCategory_Synth,
kModuleCategory_Audio,
kModuleCategory_Instrument,
kModuleCategory_Processor,
kModuleCategory_Modulator,
kModuleCategory_Pulse,
kModuleCategory_Other,
kModuleCategory_Unknown
};
struct PatchCableOld
{
ofVec2f start;
ofVec2f end;
ofVec2f plug;
};
class IDrawableModule : public IClickable, public IPollable, public virtual IPatchable
{
public:
IDrawableModule();
virtual ~IDrawableModule();
static bool CanCreate() { return true; }
static bool AcceptsAudio() { return false; }
static bool AcceptsNotes() { return false; }
static bool AcceptsPulses() { return false; }
void Render() override;
void RenderUnclipped();
virtual void PostRender() {}
void DrawFrame(float width, float height, bool drawModule, float& titleBarHeight, float& highlight);
void DrawPatchCables(bool parentMinimized, bool inFront);
bool CheckNeedsDraw() override;
virtual bool AlwaysOnTop() { return false; }
void ToggleMinimized();
void SetMinimized(bool minimized, bool animate = true)
{
if (!HasTitleBar())
return;
mMinimized = minimized;
if (!animate)
mMinimizeAnimation = minimized ? 1 : 0;
}
void TogglePinned();
void SetPinned(bool pinned);
bool Pinned() const { return mPinned; }
virtual void KeyPressed(int key, bool isRepeat);
virtual void KeyReleased(int key);
void DrawConnection(IClickable* target);
void AddUIControl(IUIControl* control);
void RemoveUIControl(IUIControl* control, bool cleanUpReferences = true);
void AddUIGrid(UIGrid* grid);
IUIControl* FindUIControl(const char* name, bool fail = true) const;
std::vector<IUIControl*> GetUIControls() const;
std::vector<UIGrid*> GetUIGrids() const;
virtual void OnUIControlRequested(const char* name) {}
void AddChild(IDrawableModule* child);
void RemoveChild(IDrawableModule* child);
IDrawableModule* FindChild(const std::string name, bool fail) const;
void GetDimensions(float& width, float& height) override;
virtual void GetModuleDimensions(float& width, float& height)
{
width = 10;
height = 10;
}
virtual void Init();
virtual void Exit();
bool IsInitialized() const { return mInitialized; }
bool Minimized() const { return mMinimizeAnimation > 0; }
bool WasMinimizeAreaClicked() const { return mWasMinimizeAreaClicked; }
virtual void MouseReleased() override;
virtual void FilesDropped(std::vector<std::string> files, int x, int y) {}
virtual std::string GetTitleLabel() const { return Name(); }
virtual bool HasTitleBar() const { return true; }
static float TitleBarHeight() { return mTitleBarHeight; }
static ofColor GetColor(ModuleCategory type);
virtual void SetEnabled(bool enabled) {}
virtual bool IsEnabled() const { return true; }
virtual bool CanMinimize() { return true; }
virtual void SampleDropped(int x, int y, Sample* sample) {}
virtual bool CanDropSample() const { return false; }
void BasePoll(); //calls poll, using this to guarantee base poll is always called
bool IsWithinRect(const ofRectangle& rect);
bool IsVisible();
std::vector<IDrawableModule*> GetChildren() const { return mChildren; }
virtual bool IsResizable() const { return false; }
virtual void Resize(float width, float height) { assert(false); }
bool IsHoveringOverResizeHandle() const { return mHoveringOverResizeHandle; }
void SetTypeName(std::string type, ModuleCategory category)
{
mTypeName = type;
mModuleCategory = category;
}
void SetTarget(IClickable* target);
void SetUpPatchCables(std::string targets);
void AddPatchCableSource(PatchCableSource* source);
void RemovePatchCableSource(PatchCableSource* source);
bool TestClick(float x, float y, bool right, bool testOnly = false) override;
std::string GetTypeName() const { return mTypeName; }
ModuleCategory GetModuleCategory() const { return mModuleCategory; }
virtual bool IsSingleton() const { return false; }
virtual bool CanBeDeleted() const { return (IsSingleton() ? false : true); }
virtual bool HasSpecialDelete() const { return false; }
virtual void DoSpecialDelete() {}
void ComputeSliders(int samplesIn);
void SetOwningContainer(ModuleContainer* container) { mOwningContainer = container; }
ModuleContainer* GetOwningContainer() const { return mOwningContainer; }
virtual ModuleContainer* GetContainer() { return nullptr; }
void SetShouldDrawOutline(bool should) { mShouldDrawOutline = should; }
ofVec2f GetMinimumDimensions();
bool HasEnabledCheckbox() const { return mEnabledCheckbox != nullptr; }
Checkbox* GetEnabledCheckbox() const { return mEnabledCheckbox; }
void MarkAsDeleted() { mDeleted = true; }
bool IsDeleted() const { return mDeleted; }
virtual bool ShouldClipContents() { return true; }
bool CanReceiveAudio() { return mCanReceiveAudio; }
bool CanReceiveNotes() { return mCanReceiveNotes; }
bool CanReceivePulses() { return mCanReceivePulses; }
virtual bool ShouldSuppressAutomaticOutputCable() { return false; }
virtual void CheckboxUpdated(Checkbox* checkbox, double time) {}
virtual void LoadBasics(const ofxJSONElement& moduleInfo, std::string typeName);
virtual void CreateUIControls();
void LoadLayoutBase(const ofxJSONElement& moduleInfo);
void SaveLayoutBase(ofxJSONElement& moduleInfo);
void SetUpFromSaveDataBase();
virtual bool IsSaveable() { return true; }
ModuleSaveData& GetSaveData() { return mModuleSaveData; }
virtual void SaveState(FileStreamOut& out);
virtual void LoadState(FileStreamIn& in, int rev);
int LoadModuleSaveStateRev(FileStreamIn& in);
virtual int GetModuleSaveStateRev() const { return -1; }
virtual void PostLoadState() {}
virtual std::vector<IUIControl*> ControlsToNotSetDuringLoadState() const;
virtual std::vector<IUIControl*> ControlsToIgnoreInSaveState() const;
virtual void UpdateOldControlName(std::string& oldName) {}
virtual bool LoadOldControl(FileStreamIn& in, std::string& oldName) { return false; }
virtual bool CanModuleTypeSaveState() const { return true; }
bool IsSpawningOnTheFly(const ofxJSONElement& moduleInfo);
virtual bool HasDebugDraw() const { return false; }
virtual bool HasPush2OverrideControls() const { return false; }
virtual void GetPush2OverrideControls(std::vector<IUIControl*>& controls) const {}
virtual bool DrawToPush2Screen() { return false; }
//IPatchable
PatchCableSource* GetPatchCableSource(int index = 0) override
{
if (index < mPatchCableSources.size())
return mPatchCableSources[index];
return nullptr;
}
std::vector<PatchCableSource*> GetPatchCableSources() { return mPatchCableSources; }
static void FindClosestSides(float xThis, float yThis, float wThis, float hThis, float xThat, float yThat, float wThat, float hThat, float& startX, float& startY, float& endX, float& endY, bool sidesOnly = false);
static float sHueNote;
static float sHueAudio;
static float sHueInstrument;
static float sHueNoteSource;
static float sSaturation;
static float sBrightness;
bool mDrawDebug{ false };
static constexpr int kMaxOutputsPerPatchCableSource = 32;
protected:
void Poll() override {}
void OnClicked(float x, float y, bool right) override;
bool MouseMoved(float x, float y) override;
void AddDebugLine(std::string text, int maxLines);
ModuleSaveData mModuleSaveData;
Checkbox* mEnabledCheckbox{ nullptr };
bool mEnabled{ true };
ModuleCategory mModuleCategory{ ModuleCategory::kModuleCategory_Unknown };
std::string mDebugDisplayText;
private:
virtual void PreDrawModule() {}
virtual void DrawModule() = 0;
virtual void DrawModuleUnclipped() {}
float GetMinimizedWidth();
PatchCableOld GetPatchCableOld(IClickable* target);
virtual void LoadLayout(const ofxJSONElement& moduleInfo) {}
virtual void SaveLayout(ofxJSONElement& moduleInfo) {}
virtual void SetUpFromSaveData() {}
virtual bool ShouldSavePatchCableSources() const { return true; }
void ForcePosition();
std::vector<IUIControl*> mUIControls;
std::vector<IDrawableModule*> mChildren;
std::vector<FloatSlider*> mFloatSliders;
std::vector<UIGrid*> mUIGrids;
static const int mTitleBarHeight = 12;
std::string mTypeName;
static const int sResizeCornerSize = 8;
ModuleContainer* mOwningContainer{ nullptr };
bool mMinimized{ false };
bool mPinned{ false };
ofVec2f mPinnedPosition{ 0, 0 };
bool mWasMinimizeAreaClicked{ false };
float mMinimizeAnimation{ 0 };
bool mUIControlsCreated{ false };
bool mInitialized{ false };
std::string mLastTitleLabel;
float mTitleLabelWidth{ 0 };
bool mShouldDrawOutline{ true };
bool mHoveringOverResizeHandle{ false };
bool mDeleted{ false };
bool mCanReceiveAudio{ false };
bool mCanReceiveNotes{ false };
bool mCanReceivePulses{ false };
IKeyboardFocusListener* mKeyboardFocusListener{ nullptr };
ofMutex mSliderMutex;
std::vector<PatchCableSource*> mPatchCableSources;
};
|