Issue with IRECT and horizontal frame IBitmap constructor
[wdl/wdl-ol.git] / WDL / IPlug / IPlugStructs.h
blob3579be2d085176be369fb3bf2782778dd2b24403
1 #ifndef _IPLUGSTRUCTS_
2 #define _IPLUGSTRUCTS_
4 #include "Containers.h"
5 #include "IPlugOSDetect.h"
7 #include "../swell/swell.h"
8 #include "../lice/lice_text.h"
10 enum EFileAction { kFileOpen, kFileSave };
12 struct IBitmap
14 void* mData;
15 int W, H, N; // N = number of states (for multibitmaps).
16 bool mFramesAreHorizontal;
17 IBitmap(void* pData = 0, int w = 0, int h = 0, int n = 1, bool framesAreHorizontal = false)
18 : mData(pData)
19 , W(w)
20 , H(h)
21 , N(n)
22 , mFramesAreHorizontal(framesAreHorizontal)
25 inline int frameHeight() const { return H / N; }
28 struct IColor
30 int A, R, G, B;
31 IColor(int a = 255, int r = 0, int g = 0, int b = 0) : A(a), R(r), G(g), B(b) {}
32 bool operator==(const IColor& rhs) { return (rhs.A == A && rhs.R == R && rhs.G == G && rhs.B == B); }
33 bool operator!=(const IColor& rhs) { return !operator==(rhs); }
34 bool Empty() const { return A == 0 && R == 0 && G == 0 && B == 0; }
35 void Clamp() { A = IPMIN(A, 255); R = IPMIN(R, 255); G = IPMIN(G, 255); B = IPMIN(B, 255); }
38 const IColor COLOR_TRANSPARENT(0, 0, 0, 0);
39 const IColor COLOR_BLACK(255, 0, 0, 0);
40 const IColor COLOR_GRAY(255, 127, 127, 127);
41 const IColor COLOR_WHITE(255, 255, 255, 255);
42 const IColor COLOR_RED(255, 255, 0, 0);
43 const IColor COLOR_GREEN(255, 0, 255, 0);
44 const IColor COLOR_BLUE(255, 0, 0, 255);
45 const IColor COLOR_YELLOW(255, 255, 255, 0);
46 const IColor COLOR_ORANGE(255, 255, 127, 0);
48 struct IChannelBlend
50 enum EBlendMethod
52 kBlendNone, // Copy over whatever is already there, but look at src alpha.
53 kBlendClobber, // Copy completely over whatever is already there.
54 kBlendAdd,
55 kBlendColorDodge,
56 // etc
58 EBlendMethod mMethod;
59 float mWeight;
61 IChannelBlend(EBlendMethod method = kBlendNone, float weight = 1.0f) : mMethod(method), mWeight(weight) {}
64 const IColor DEFAULT_TEXT_COLOR = COLOR_BLACK;
65 const IColor DEFAULT_TEXT_ENTRY_BGCOLOR = COLOR_WHITE;
66 const IColor DEFAULT_TEXT_ENTRY_FGCOLOR = COLOR_BLACK;
68 #ifdef OS_WIN
69 const char* const DEFAULT_FONT = "Verdana";
70 const int DEFAULT_TEXT_SIZE = 12;
71 #elif defined OS_OSX
72 const char* const DEFAULT_FONT = "Monaco";
73 const int DEFAULT_TEXT_SIZE = 10;
74 #endif
76 const int FONT_LEN = 32;
78 struct IText
80 char mFont[FONT_LEN];
81 int mSize;
82 IColor mColor, mTextEntryBGColor, mTextEntryFGColor;
83 enum EStyle { kStyleNormal, kStyleBold, kStyleItalic } mStyle;
84 enum EAlign { kAlignNear, kAlignCenter, kAlignFar } mAlign;
85 int mOrientation; // Degrees ccwise from normal.
86 enum EQuality { kQualityDefault, kQualityNonAntiAliased, kQualityAntiAliased, kQualityClearType } mQuality;
87 LICE_IFont* mCached;
89 IText(int size = DEFAULT_TEXT_SIZE,
90 const IColor* pColor = 0,
91 char* font = 0,
92 EStyle style = kStyleNormal,
93 EAlign align = kAlignCenter,
94 int orientation = 0,
95 EQuality quality = kQualityDefault,
96 const IColor* pTEBGColor = 0,
97 const IColor* pTEFGColor = 0)
98 : mSize(size)
99 , mColor(pColor ? *pColor : DEFAULT_TEXT_COLOR)
100 , mStyle(style)
101 , mAlign(align)
102 , mOrientation(orientation)
103 , mQuality(quality)
104 , mCached(0)
105 , mTextEntryBGColor(pTEBGColor ? *pTEBGColor : DEFAULT_TEXT_ENTRY_BGCOLOR)
106 , mTextEntryFGColor(pTEFGColor ? *pTEFGColor : DEFAULT_TEXT_ENTRY_FGCOLOR)
108 strcpy(mFont, (font ? font : DEFAULT_FONT));
111 IText(const IColor* pColor)
112 : mSize(DEFAULT_TEXT_SIZE)
113 , mColor(*pColor)
114 , mStyle(kStyleNormal)
115 , mAlign(kAlignCenter)
116 , mOrientation(0)
117 , mQuality(kQualityDefault)
118 , mCached(0)
119 , mTextEntryBGColor(DEFAULT_TEXT_ENTRY_BGCOLOR)
120 , mTextEntryFGColor(DEFAULT_TEXT_ENTRY_FGCOLOR)
122 strcpy(mFont, DEFAULT_FONT);
127 // these are macros to shorten the instantiation of IControls
128 // for a paramater ID MyParam, define constants named MyParam_X, MyParam_Y, MyParam_W, MyParam_H to specify the Control's IRect
129 // then when instantiating a Control you can just call MakeIRect(MyParam) to specify the IRect
130 #define MakeIRect(a) IRECT(a##_X, a##_Y, a##_X + a##_W, a##_Y + a##_H)
131 #define MakeIRectHOffset(a, xoffs) IRECT(a##_X + xoffs, a##_Y, a##_X + a##_W + xoffs, a##_Y + a##_H)
132 #define MakeIRectVOffset(a, yoffs) IRECT(a##_X, a##_Y + yoffs, a##_X + a##_W, a##_Y + a##_H + yoffs)
133 #define MakeIRectHVOffset(a, xoffs, yoffs) IRECT(a##_X + xoffs, a##_Y + yoffs, a##_X + a##_W + xoffs, a##_Y + a##_H + yoffs)
135 struct IRECT
137 int L, T, R, B;
139 IRECT() { L = T = R = B = 0; }
140 IRECT(int l, int t, int r, int b) : L(l), R(r), T(t), B(b) {}
142 IRECT(int x, int y, IBitmap *pBitmap)
144 L = x;
145 T = y;
146 if (pBitmap->mFramesAreHorizontal)
148 R = L + pBitmap->W / pBitmap->N;
149 B = T + pBitmap->H;
151 else
153 R = L + pBitmap->W;
154 B = T + pBitmap->H / pBitmap->N;
158 bool Empty() const
160 return (L == 0 && T == 0 && R == 0 && B == 0);
163 void Clear()
165 L = T = R = B = 0;
168 bool operator==(const IRECT& rhs) const
170 return (L == rhs.L && T == rhs.T && R == rhs.R && B == rhs.B);
173 bool operator!=(const IRECT& rhs) const
175 return !(*this == rhs);
178 inline int W() const { return R - L; }
179 inline int H() const { return B - T; }
180 inline float MW() const { return 0.5f * (float) (L + R); }
181 inline float MH() const { return 0.5f * (float) (T + B); }
183 inline IRECT Union(IRECT* pRHS)
185 if (Empty()) { return *pRHS; }
186 if (pRHS->Empty()) { return *this; }
187 return IRECT(IPMIN(L, pRHS->L), IPMIN(T, pRHS->T), IPMAX(R, pRHS->R), IPMAX(B, pRHS->B));
190 inline IRECT Intersect(IRECT* pRHS)
192 if (Intersects(pRHS))
194 return IRECT(IPMAX(L, pRHS->L), IPMAX(T, pRHS->T), IPMIN(R, pRHS->R), IPMIN(B, pRHS->B));
196 return IRECT();
199 inline bool Intersects(IRECT* pRHS)
201 return (!Empty() && !pRHS->Empty() && R >= pRHS->L && L < pRHS->R && B >= pRHS->T && T < pRHS->B);
204 inline bool Contains(IRECT* pRHS)
206 return (!Empty() && !pRHS->Empty() && pRHS->L >= L && pRHS->R <= R && pRHS->T >= T && pRHS->B <= B);
209 inline bool Contains(int x, int y)
211 return (!Empty() && x >= L && x < R && y >= T && y < B);
214 inline void Constrain(int* x, int* y)
216 if (*x < L)
218 *x = L;
220 else if (*x > R)
222 *x = R;
225 if (*y < T)
227 *y = T;
229 else if (*y > B)
231 *y = B;
235 inline IRECT SubRectVertical(int numSlices, int sliceIdx)
237 float heightOfSubRect = (float(H()) / numSlices);
238 int t = heightOfSubRect * sliceIdx;
240 return IRECT(L, T + t, R, T + t + heightOfSubRect);
243 inline IRECT SubRectHorizontal(int numSlices, int sliceIdx)
245 float widthOfSubRect = (float(W()) / numSlices);
246 int l = widthOfSubRect * sliceIdx;
248 return IRECT(L + l, T, L + l + widthOfSubRect, B);
251 inline IRECT GetPadded(int padding)
253 return IRECT(L-padding, T-padding, R+padding, B+padding);
256 inline IRECT GetPadded(int padL, int padT, int padR, int padB)
258 return IRECT(L+padL, T+padT, R+padR, B+padB);
261 inline IRECT GetHPadded(int padding)
263 return IRECT(L-padding, T, R+padding, B);
266 inline IRECT GetVPadded(int padding)
268 return IRECT(L, T-padding, R, B+padding);
271 void Clank(IRECT* pRHS)
273 if (L < pRHS->L)
275 R = IPMIN(pRHS->R - 1, R + pRHS->L - L);
276 L = pRHS->L;
278 if (T < pRHS->T)
280 B = IPMIN(pRHS->B - 1, B + pRHS->T - T);
281 T = pRHS->T;
283 if (R >= pRHS->R)
285 L = IPMAX(pRHS->L, L - (R - pRHS->R + 1));
286 R = pRHS->R - 1;
288 if (B >= pRHS->B)
290 T = IPMAX(pRHS->T, T - (B - pRHS->B + 1));
291 B = pRHS->B - 1;
296 struct IMouseMod
298 bool L, R, S, C, A;
299 IMouseMod(bool l = false, bool r = false, bool s = false, bool c = false, bool a = false)
300 : L(l), R(r), S(s), C(c), A(a) {}
303 struct IMidiMsg
305 int mOffset;
306 BYTE mStatus, mData1, mData2;
308 enum EStatusMsg
310 kNone = 0,
311 kNoteOff = 8,
312 kNoteOn = 9,
313 kPolyAftertouch = 10,
314 kControlChange = 11,
315 kProgramChange = 12,
316 kChannelAftertouch = 13,
317 kPitchWheel = 14
320 enum EControlChangeMsg
322 kModWheel = 1,
323 kBreathController = 2,
324 kUndefined003 = 3,
325 kFootController = 4,
326 kPortamentoTime = 5,
327 kChannelVolume = 7,
328 kBalance = 8,
329 kUndefined009 = 9,
330 kPan = 10,
331 kExpressionController = 11,
332 kEffectControl1 = 12,
333 kEffectControl2 = 13,
334 kUndefined014 = 14,
335 kUndefined015 = 15,
336 kGeneralPurposeController1 = 16,
337 kGeneralPurposeController2 = 17,
338 kGeneralPurposeController3 = 18,
339 kGeneralPurposeController4 = 19,
340 kUndefined020 = 20,
341 kUndefined021 = 21,
342 kUndefined022 = 22,
343 kUndefined023 = 23,
344 kUndefined024 = 24,
345 kUndefined025 = 25,
346 kUndefined026 = 26,
347 kUndefined027 = 27,
348 kUndefined028 = 28,
349 kUndefined029 = 29,
350 kUndefined030 = 30,
351 kUndefined031 = 31,
352 kSustainOnOff = 64,
353 kPortamentoOnOff = 65,
354 kSustenutoOnOff = 66,
355 kSoftPedalOnOff = 67,
356 kLegatoOnOff = 68,
357 kHold2OnOff = 69,
358 kSoundVariation = 70,
359 kResonance = 71,
360 kReleaseTime = 72,
361 kAttackTime = 73,
362 kCutoffFrequency = 74,
363 kDecayTime = 75,
364 kVibratoRate = 76,
365 kVibratoDepth = 77,
366 kVibratoDelay = 78,
367 kSoundControllerUndefined = 79,
368 kUndefined085 = 85,
369 kUndefined086 = 86,
370 kUndefined087 = 87,
371 kUndefined088 = 88,
372 kUndefined089 = 89,
373 kUndefined090 = 90,
374 kTremoloDepth = 92,
375 kChorusDepth = 93,
376 kPhaserDepth = 95,
377 kUndefined102 = 102,
378 kUndefined103 = 103,
379 kUndefined104 = 104,
380 kUndefined105 = 105,
381 kUndefined106 = 106,
382 kUndefined107 = 107,
383 kUndefined108 = 108,
384 kUndefined109 = 109,
385 kUndefined110 = 110,
386 kUndefined111 = 111,
387 kUndefined112 = 112,
388 kUndefined113 = 113,
389 kUndefined114 = 114,
390 kUndefined115 = 115,
391 kUndefined116 = 116,
392 kUndefined117 = 117,
393 kUndefined118 = 118,
394 kUndefined119 = 119,
395 kAllNotesOff = 123
398 IMidiMsg(int offs = 0, BYTE s = 0, BYTE d1 = 0, BYTE d2 = 0) : mOffset(offs), mStatus(s), mData1(d1), mData2(d2) {}
400 void MakeNoteOnMsg(int noteNumber, int velocity, int offset, int channel=0);
401 void MakeNoteOffMsg(int noteNumber, int offset, int channel=0);
402 void MakePitchWheelMsg(double value, int channel=0); // Value in [-1, 1], converts to [0, 16384) where 8192 = no pitch change.
403 void MakeControlChangeMsg(EControlChangeMsg idx, double value, int channel=0); // Value in [0, 1].
404 int Channel(); // returns [0, 15] for midi channels 1 ... 16
406 EStatusMsg StatusMsg() const;
407 int NoteNumber() const; // Returns [0, 127), -1 if NA.
408 int Velocity() const; // Returns [0, 127), -1 if NA.
409 int PolyAfterTouch() const; // Returns [0, 127), -1 if NA.
410 int ChannelAfterTouch() const; // Returns [0, 127), -1 if NA.
411 int Program() const; // Returns [0, 127), -1 if NA.
412 double PitchWheel() const; // Returns [-1.0, 1.0], zero if NA.
413 EControlChangeMsg ControlChangeIdx() const;
414 double ControlChange(EControlChangeMsg idx) const; // return [0, 1], -1 if NA.
415 static bool ControlChangeOnOff(double msgValue) { return (msgValue >= 0.5); } // true = on.
416 void Clear();
417 void LogMsg();
420 struct ITimeInfo
422 double mTempo;
423 double mSamplePos;
424 double mPPQPos;
425 double mLastBar;
426 double mCycleStart;
427 double mCycleEnd;
429 int mNumerator;
430 int mDenominator;
432 bool mTransportIsRunning;
433 bool mTransportLoopEnabled;
435 ITimeInfo()
437 mSamplePos = mSamplePos = mTempo = mPPQPos = mLastBar = mCycleStart = mCycleEnd = -1.0;
438 mTempo = 120.;
439 mNumerator = mDenominator = 4;
440 mTransportIsRunning = mTransportLoopEnabled = false;
444 struct ISysEx
446 int mOffset, mSize;
447 const BYTE* mData;
449 ISysEx(int offs = 0, const BYTE* pData = NULL, int size = 0) : mOffset(offs), mData(pData), mSize(size) {}
451 void Clear();
452 void LogMsg();
455 const int MAX_PRESET_NAME_LEN = 256;
456 #define UNUSED_PRESET_NAME "empty"
458 struct IPreset
460 bool mInitialized;
461 char mName[MAX_PRESET_NAME_LEN];
463 ByteChunk mChunk;
465 IPreset(int idx)
466 : mInitialized(false)
468 sprintf(mName, "%s", UNUSED_PRESET_NAME);
472 enum
474 KEY_SPACE,
475 KEY_UPARROW,
476 KEY_DOWNARROW,
477 KEY_LEFTARROW,
478 KEY_RIGHTARROW,
479 KEY_DIGIT_0,
480 KEY_DIGIT_9=KEY_DIGIT_0+9,
481 KEY_ALPHA_A,
482 KEY_ALPHA_Z=KEY_ALPHA_A+25
485 #endif