You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2631 lines
72KB

  1. #pragma once
  2. #define PI 3.14159f
  3. #define DEG2RAD( x ) ( ( x ) * ( PI / 180.0f ) )
  4. #define RAD2DEG( x ) ( ( x ) * ( 180.0f / PI ) )
  5. struct CyanValueLight : ModuleLightWidget
  6. {
  7. CyanValueLight()
  8. {
  9. addBaseColor( COLOR_CYAN );
  10. }
  11. };
  12. struct OrangeValueLight : ModuleLightWidget
  13. {
  14. OrangeValueLight()
  15. {
  16. addBaseColor( nvgRGB( 242, 79, 0 ) );
  17. }
  18. };
  19. struct DarkRedValueLight : ModuleLightWidget
  20. {
  21. DarkRedValueLight()
  22. {
  23. addBaseColor( nvgRGB(0x70, 0, 0x30) );
  24. }
  25. };
  26. struct DarkGreenValueLight : ModuleLightWidget
  27. {
  28. DarkGreenValueLight()
  29. {
  30. addBaseColor( nvgRGB(0, 0x90, 0x40) );;
  31. }
  32. };
  33. struct DarkGreen2ValueLight : ModuleLightWidget
  34. {
  35. DarkGreen2ValueLight()
  36. {
  37. addBaseColor( nvgRGB(0, 0x40, 0) );;
  38. }
  39. };
  40. struct DarkYellow2ValueLight : ModuleLightWidget
  41. {
  42. DarkYellow2ValueLight()
  43. {
  44. addBaseColor( nvgRGB(0x40, 0x40, 0) );;
  45. }
  46. };
  47. #define lvl_to_db( x ) ( 20.0 * log10( x ) )
  48. #define db_to_lvl( x ) ( 1.0 / pow( 10, x / 20.0 ) )
  49. typedef struct
  50. {
  51. union
  52. {
  53. unsigned int dwCol;
  54. unsigned char Col[ 4 ];
  55. };
  56. }RGB_STRUCT;
  57. #define DWRGB( r, g, b ) (b | g<<8 | r<<16)
  58. typedef struct
  59. {
  60. int x, y, x2, y2;
  61. }RECT_STRUCT;
  62. typedef struct
  63. {
  64. float fx, fy, fx2, fy2;
  65. }fRECT_STRUCT;
  66. typedef struct
  67. {
  68. float fx, fy;
  69. }POINT_STRUCT;
  70. typedef struct
  71. {
  72. int nUsed;
  73. POINT_STRUCT p[ 8 ];
  74. }DRAW_VECT_STRUCT;
  75. typedef struct
  76. {
  77. float fx, fy;
  78. float fmx; // as in function y = fx + fn
  79. float fb;
  80. bool bVert;
  81. bool bHorz;
  82. bool bSet;
  83. }fLine;
  84. //-----------------------------------------------------
  85. // Widget_EnvelopeEdit
  86. //-----------------------------------------------------
  87. #define ENVELOPE_VDIV 8
  88. #define ENVELOPE_DIVISIONS 16
  89. #define ENVELOPE_HANDLES ( ENVELOPE_DIVISIONS + 1 )
  90. #define MAX_ENVELOPE_CHANNELS 9
  91. typedef struct
  92. {
  93. int state, prevstate;
  94. float fpos;
  95. float syncInc;
  96. }EE_CTRL;
  97. struct EnvelopeData
  98. {
  99. enum EnvelopeData_Modes
  100. {
  101. MODE_LOOP,
  102. MODE_REVERSE,
  103. MODE_PINGPONG,
  104. MODE_ONESHOT,
  105. MODE_TWOSHOT,
  106. nMODES
  107. };
  108. enum EnvelopeData_Ranges
  109. {
  110. RANGE_0to5,
  111. RANGE_n5to5,
  112. RANGE_0to10,
  113. RANGE_n10to10,
  114. RANGE_0to1,
  115. RANGE_n1to1,
  116. RANGE_Audio,
  117. nRANGES
  118. };
  119. enum EnvelopeData_States
  120. {
  121. STATE_RUN,
  122. STATE_RUN_REV,
  123. STATE_WAIT_TRIG,
  124. STATE_WAIT_TRIG_REV,
  125. STATE_HOLD,
  126. nSTATES
  127. };
  128. enum EnvelopeData_Presets
  129. {
  130. PRESET_CLEAR,
  131. PRESET_HALF,
  132. PRESET_SIN,
  133. PRESET_COS,
  134. PRESET_COS_HALF,
  135. PRESET_TRI_FULL,
  136. PRESET_TRI_HALF,
  137. PRESET_SQR,
  138. PRESET_SET,
  139. nPRESETS
  140. };
  141. bool m_bInitialized=false;
  142. bool m_bGateMode = false;
  143. int m_Mode = MODE_LOOP;
  144. int m_Range= RANGE_0to5;
  145. float m_HandleVal[ ENVELOPE_HANDLES ]={};
  146. fLine m_Lines[ ENVELOPE_HANDLES ]={};
  147. float m_fsegsize = 1.0f;
  148. float m_fIndicator = 0.0f;
  149. EE_CTRL m_Clock = {};
  150. EnvelopeData(){};
  151. void Init( int mode, int range, bool bGate, float fsegsize );
  152. void Preset( int preset );
  153. void resetValAll( float val );
  154. void setVal( int handle, float val );
  155. void setMode( int Mode );
  156. void setDataAll( int *pint );
  157. void getDataAll( int *pint );
  158. float getActualVal( float val );
  159. void line_from_points( float x1, float y1, float x2, float y2, fLine *L );
  160. float valfromline ( int handle, float x );
  161. void recalcLine( int handle );
  162. bool process_state( bool bTrig, bool bHold );
  163. float procStep( bool bTrig, bool bHold );
  164. };
  165. struct Widget_EnvelopeEdit : OpaqueWidget
  166. {
  167. enum Widget_EnvelopeEdit_TimeDivs
  168. {
  169. TIME_64th,
  170. TIME_32nd,
  171. TIME_16th,
  172. TIME_8th,
  173. TIME_4tr,
  174. TIME_Bar,
  175. nTIMEDIVS
  176. };
  177. typedef void EnvelopeEditCALLBACK ( void *pClass, float val );
  178. EnvelopeData m_EnvData[ MAX_ENVELOPE_CHANNELS ] = {};
  179. bool m_bInitialized=false;
  180. int m_TimeDiv[ MAX_ENVELOPE_CHANNELS ]={TIME_64th};
  181. float m_divw=0;
  182. float m_handleSize=0, m_handleSizeD2;
  183. int m_currentChannel = 0;
  184. int m_Drag = -1;
  185. float m_fband = 0.0f;
  186. int m_MaxChannels;
  187. bool m_bDrag = false, m_bDraw = false;
  188. float m_Drawy = 0.0f;
  189. bool m_bClkReset = false;
  190. int m_BeatLen = 0;
  191. RGB_STRUCT m_HandleCol[ ENVELOPE_HANDLES ];
  192. EnvelopeEditCALLBACK *m_pCallback = NULL;
  193. void *m_pClass = NULL;
  194. bool m_bClkd = false;
  195. Widget_EnvelopeEdit( int x, int y, int w, int h, int handleSize, void *pClass, EnvelopeEditCALLBACK *pCallback, int nchannels );
  196. void setView( int ch );
  197. void resetValAll( int ch, float val );
  198. void setVal( int ch, int handle, float val );
  199. void setMode( int ch, int Mode );
  200. void setRange( int ch, int Range );
  201. void setGateMode( int ch, bool bGate );
  202. void setTimeDiv( int ch, int timediv );
  203. void setBeatLen( int len );
  204. int getPos( int ch );
  205. void setPos( int ch, int pos );
  206. void setDataAll( int *pint );
  207. void getDataAll( int *pint );
  208. float getActualVal( int ch, float val );
  209. bool process_state( int ch, bool bTrig, bool bHold );
  210. float procStep( int ch, bool bTrig, bool bHold );
  211. float Val2y( float fval );
  212. float y2Val( float fy );
  213. void recalcLine( int ch, int handle );
  214. // overrides
  215. void draw( NVGcontext *vg ) override;
  216. void onMouseMove( EventMouseMove &e ) override;
  217. void onMouseDown( EventMouseDown &e ) override;
  218. void onDragStart(EventDragStart &e) override;
  219. void onDragEnd(EventDragEnd &e) override;
  220. void onDragMove(EventDragMove &e) override;
  221. };
  222. //-----------------------------------------------------
  223. // MySimpleKnob
  224. //-----------------------------------------------------
  225. #define MAX_ANGLE 140.0f
  226. #define MIN_ANGLE ( 360.0f - MAX_ANGLE )
  227. #define RANGE_ANGLE (( MAX_ANGLE * 2.0f ) + 1.0f )
  228. struct MySimpleKnob : OpaqueWidget, FramebufferWidget
  229. {
  230. bool m_bInitialized;
  231. Vec m_Loc;
  232. RGB_STRUCT m_Colour, m_BgColour;
  233. bool m_bNegMode;
  234. float m_radius;
  235. int m_id, m_ch;
  236. float m_fVal;
  237. float m_fangle;
  238. Vec m_Vecpos;
  239. float m_max, m_min, m_default;
  240. int m_nSteps;
  241. void *m_pClass;
  242. typedef void MySimpleKnobCALLBACK ( void *pClass, int ch, int id, float fval );
  243. MySimpleKnobCALLBACK *m_pCallback;
  244. //-----------------------------------------------------
  245. // Procedure: constructor
  246. //-----------------------------------------------------
  247. MySimpleKnob( void *pClass, float x, float y, float width, unsigned int dwCol, unsigned int dwBgCol, int ch, int id, int nsteps, MySimpleKnobCALLBACK *pCallback, float min, float max, float def )
  248. {
  249. m_radius = width / 2.0;
  250. m_Loc.x = x + m_radius;
  251. m_Loc.y = y + m_radius;
  252. m_id = id;
  253. m_ch = ch;
  254. m_pClass = pClass;
  255. m_pCallback = pCallback;
  256. m_Colour.dwCol = dwCol;
  257. m_BgColour.dwCol= dwBgCol;
  258. m_nSteps = nsteps;
  259. m_max = max;
  260. m_min = min;
  261. m_default = def;
  262. m_fVal = def;
  263. m_fangle = val2a( def );
  264. box.pos = Vec( x, y );
  265. box.size = Vec( width, width );
  266. m_bInitialized = true;
  267. }
  268. //-----------------------------------------------------
  269. // Procedure: val2a
  270. //-----------------------------------------------------
  271. float val2a( float val )
  272. {
  273. float a = 0.0f;
  274. if( m_nSteps )
  275. {
  276. }
  277. else
  278. {
  279. a = RANGE_ANGLE * val;
  280. a -= MAX_ANGLE;
  281. }
  282. return a;
  283. }
  284. //-----------------------------------------------------
  285. // Procedure: a2val
  286. //-----------------------------------------------------
  287. float a2val( float a )
  288. {
  289. float val = 0.0f;
  290. if( m_nSteps )
  291. {
  292. }
  293. else
  294. {
  295. a += MAX_ANGLE;
  296. val = a / RANGE_ANGLE;
  297. }
  298. return val;
  299. }
  300. //-----------------------------------------------------
  301. // Procedure: draw
  302. //-----------------------------------------------------
  303. void draw( NVGcontext *vg ) override
  304. {
  305. float a1, a2;
  306. float linewidth = m_radius * 0.15f;
  307. if( !m_bInitialized )
  308. return;
  309. a1 = DEG2RAD( 135.0f );
  310. a2 = DEG2RAD( 45.0f );
  311. nvgBeginPath( vg );
  312. nvgCircle( vg, m_radius, m_radius, m_radius );
  313. nvgFillColor( vg, nvgRGBA( m_Colour.Col[ 2 ], m_Colour.Col[ 1 ], m_Colour.Col[ 0 ], 255 ) );
  314. nvgFill( vg );
  315. nvgStrokeWidth( vg, linewidth );
  316. /*nvgBeginPath( vg );
  317. nvgStrokeColor( vg, nvgRGBA( m_Colour.Col[ 2 ], m_Colour.Col[ 1 ], m_Colour.Col[ 0 ], 100 ) );
  318. nvgArc( vg, m_radius, m_radius, m_radius - ( linewidth / 2.0f ), a1, a2, NVG_CW );
  319. nvgStroke( vg );*/
  320. a1 = DEG2RAD( 20.0f );
  321. a2 = DEG2RAD( 20.0f );
  322. nvgBeginPath( vg );
  323. nvgStrokeColor( vg, nvgRGBA( m_BgColour.Col[ 2 ], m_BgColour.Col[ 1 ], m_BgColour.Col[ 0 ], 255 ) );
  324. //nvgStrokeColor( vg, nvgRGBA( 255, 255, 255, 160 ) );
  325. nvgArc( vg, m_radius, m_radius, m_radius, a1, a2, NVG_CW );
  326. nvgLineTo( vg, m_radius, m_radius );
  327. nvgStroke( vg );
  328. nvgBeginPath( vg );
  329. nvgCircle( vg, m_radius, m_radius, m_radius * 0.2f );
  330. nvgFillColor( vg, nvgRGBA( m_Colour.Col[ 2 ], m_Colour.Col[ 1 ], m_Colour.Col[ 0 ], 255 ) );
  331. nvgFill( vg );
  332. dirty = false;
  333. }
  334. //-----------------------------------------------------
  335. // Procedure: setPos
  336. //-----------------------------------------------------
  337. void setVal( float val )
  338. {
  339. if( !m_bInitialized )
  340. return;
  341. if( val < m_min )
  342. val = m_min;
  343. else if( val > m_max )
  344. val = m_max;
  345. m_fVal = val;
  346. dirty = true;
  347. }
  348. //-----------------------------------------------------
  349. // Procedure: setCol
  350. //-----------------------------------------------------
  351. void setCol( unsigned int dwCol )
  352. {
  353. if( !m_bInitialized )
  354. return;
  355. m_Colour.dwCol = dwCol;
  356. dirty = true;
  357. }
  358. //-----------------------------------------------------
  359. // Procedure: setBgCol
  360. //-----------------------------------------------------
  361. void setBgCol( unsigned int dwCol )
  362. {
  363. if( !m_bInitialized )
  364. return;
  365. m_BgColour.dwCol = dwCol;
  366. dirty = true;
  367. }
  368. //-----------------------------------------------------
  369. // Procedure: onDragStart
  370. //-----------------------------------------------------
  371. void onDragStart(EventDragStart &e) override
  372. {
  373. e.consumed = true;
  374. }
  375. //-----------------------------------------------------
  376. // Procedure: onDragEnd
  377. //-----------------------------------------------------
  378. void onDragEnd(EventDragEnd &e) override
  379. {
  380. e.consumed = true;
  381. }
  382. //-----------------------------------------------------
  383. // Procedure: onDragMove
  384. //-----------------------------------------------------
  385. void onDragMove(EventDragMove &e) override
  386. {
  387. m_Vecpos.x = e.mouseRel.x;
  388. m_Vecpos.y = e.mouseRel.y;
  389. if( m_pCallback )
  390. m_pCallback( m_pClass, m_ch, m_id, m_fVal );
  391. e.consumed = true;
  392. dirty = true;
  393. }
  394. };
  395. //-----------------------------------------------------
  396. // MyLED7DigitDisplay
  397. //-----------------------------------------------------
  398. struct MyLED7DigitDisplay : TransparentWidget, FramebufferWidget
  399. {
  400. bool m_bInitialized = false;
  401. int m_Type;
  402. RGB_STRUCT m_Colour;
  403. RGB_STRUCT m_LEDColour;
  404. int m_iVal;
  405. float m_fVal;
  406. float m_fScale;
  407. float m_fSpace;
  408. float m_MaxDigits;
  409. enum MyLEDDisplay_Types
  410. {
  411. TYPE_INT,
  412. TYPE_FLOAT
  413. };
  414. DRAW_VECT_STRUCT DigitDrawVects[ 8 ] =
  415. {
  416. { 8, { {58, 0}, {143, 0}, {148, 5}, {148, 9}, {130, 27}, {68, 27}, {51, 10}, {51, 7} } }, // top 0
  417. { 8, { {39, 17}, {32, 24}, {18, 124}, {24, 130}, {30, 130}, {48, 117}, {59, 33}, {43, 17} } }, // top left 1
  418. { 8, { {153, 18}, {135, 36}, {124, 118}, {137, 129}, {142, 129}, {151, 122}, {164, 23}, {159, 18} } }, // top right 2
  419. { 8, { {56, 123}, {35, 137}, {35, 140}, {50, 152}, {111, 152}, {128, 140}, {128, 136}, {114, 123} } }, // middle 3
  420. { 8, { {24, 145}, {14, 152}, {1, 251}, {7, 257}, {11, 257}, {31, 239}, {41, 156}, {27, 145} } }, // bottom left 4
  421. { 8, { {137, 145}, {117, 158}, {104, 243}, {119, 258}, {122, 258}, {131, 251}, {147, 152}, {140, 145} } }, // bottom right 5
  422. { 8, { {38, 247}, {16, 265}, {16, 269}, {22, 275}, {104, 275}, {112, 267}, {112, 264}, {98, 247} } }, // bottom 6
  423. { 4, { {4 + 154, 240}, {0 + 154, 275}, {32 + 154, 275}, {36 + 154, 240}, {0, 0}, {0, 0}, {0, 0}, {0, 0} } }, // dot
  424. };
  425. #define LED_DIGITAL_SCALE_W 160.0f
  426. #define LED_DIGITAL_SCALE_H 275.0f
  427. #define LED_SPACE 210.0f
  428. #define LED_DISPLAY_DIGITS 5
  429. int DigitToDisplay[ 10 ][ 8 ] =
  430. {
  431. { 6, 0, 1, 2, 4, 5, 6, 0 }, // 0
  432. { 2, 2, 5, 0, 0, 0, 0, 0 }, // 1
  433. { 5, 0, 2, 3, 4, 6, 0, 0 }, // 2
  434. { 6, 0, 2, 3, 5, 6, 0, 0 }, // 3
  435. { 4, 1, 2, 3, 5, 0, 0, 0 }, // 4
  436. { 5, 0, 1, 3, 5, 6, 0, 0 }, // 5
  437. { 6, 0, 1, 3, 4, 5, 6, 0 }, // 6
  438. { 3, 0, 2, 5, 0, 0, 0, 0 }, // 7
  439. { 7, 0, 1, 2, 3, 4, 5, 6 }, // 8
  440. { 6, 0, 1, 2, 3, 5, 6, 0 }, // 9
  441. };
  442. //-----------------------------------------------------
  443. // Procedure: Constructor
  444. //-----------------------------------------------------
  445. MyLED7DigitDisplay( int x, int y, float fscale, int colour, int LEDcolour, int type, int maxdigits )
  446. {
  447. int i, j;
  448. m_Type = type;
  449. m_Colour.dwCol = colour;
  450. m_LEDColour.dwCol = LEDcolour;
  451. m_fScale = fscale;
  452. m_fSpace = fscale * LED_SPACE;
  453. m_MaxDigits = maxdigits;
  454. box.pos = Vec( x, y );
  455. box.size = Vec( ( ( 5.0f * LED_DIGITAL_SCALE_W ) + ( 4.0f * LED_SPACE ) ) * fscale, LED_DIGITAL_SCALE_H * fscale );
  456. // rescale the LED vectors
  457. for( i = 0; i < 8; i++ )
  458. {
  459. for( j = 0; j < 8; j++ )
  460. {
  461. DigitDrawVects[ i ].p[ j ].fx *= fscale;
  462. DigitDrawVects[ i ].p[ j ].fy *= fscale;
  463. }
  464. }
  465. m_bInitialized = true;
  466. }
  467. //-----------------------------------------------------
  468. // Procedure: SetInt
  469. //-----------------------------------------------------
  470. void SetInt( int ival )
  471. {
  472. if( !m_bInitialized )
  473. return;
  474. if( ival == m_iVal )
  475. return;
  476. m_iVal = ival;
  477. dirty = true;
  478. }
  479. //-----------------------------------------------------
  480. // Procedure: SetFloat
  481. //-----------------------------------------------------
  482. void SetFloat( float fval )
  483. {
  484. if( !m_bInitialized )
  485. return;
  486. if( fval == m_fVal )
  487. return;
  488. m_fVal = fval;
  489. dirty = true;
  490. }
  491. //-----------------------------------------------------
  492. // Procedure: Set
  493. //-----------------------------------------------------
  494. void SetLEDCol( int colour )
  495. {
  496. m_LEDColour.dwCol = colour;
  497. dirty = true;
  498. }
  499. //-----------------------------------------------------
  500. // Procedure: Val2Digits
  501. //-----------------------------------------------------
  502. void Val2Digits( int *pdigits )
  503. {
  504. int temp;
  505. if( m_Type == TYPE_FLOAT )
  506. temp = (int)( m_fVal * 100.0 );
  507. else
  508. temp = m_iVal;
  509. pdigits[ 0 ] = temp / 10000;
  510. temp -= (pdigits[ 0 ] * 10000 );
  511. pdigits[ 1 ] = temp / 1000;
  512. temp -= (pdigits[ 1 ] * 1000 );
  513. pdigits[ 2 ] = temp / 100;
  514. temp -= (pdigits[ 2 ] * 100 );
  515. pdigits[ 3 ] = temp / 10;
  516. temp -= (pdigits[ 3 ] * 10 );
  517. pdigits[ 4 ] = temp;
  518. }
  519. //-----------------------------------------------------
  520. // Procedure: drawvect
  521. //-----------------------------------------------------
  522. void drawvect( NVGcontext *vg, float fx, float fy, DRAW_VECT_STRUCT *pvect, RGB_STRUCT *pRGB, bool bLeadingZero )
  523. {
  524. int i;
  525. if( !m_bInitialized )
  526. return;
  527. if( bLeadingZero )
  528. nvgFillColor(vg, nvgRGBA( pRGB->Col[ 2 ], pRGB->Col[ 1 ], pRGB->Col[ 0 ], 0x40 ) );
  529. else
  530. nvgFillColor(vg, nvgRGB( pRGB->Col[ 2 ], pRGB->Col[ 1 ], pRGB->Col[ 0 ] ) );
  531. nvgBeginPath(vg);
  532. for( i = 0; i < pvect->nUsed; i++ )
  533. {
  534. if( i == 0 )
  535. nvgMoveTo(vg, pvect->p[ i ].fx + fx, pvect->p[ i ].fy + fy );
  536. else
  537. nvgLineTo(vg, pvect->p[ i ].fx + fx, pvect->p[ i ].fy + fy );
  538. }
  539. nvgClosePath(vg);
  540. nvgFill(vg);
  541. }
  542. //-----------------------------------------------------
  543. // Procedure: draw
  544. //-----------------------------------------------------
  545. void draw( NVGcontext *vg ) override
  546. {
  547. int digits[ LED_DISPLAY_DIGITS ] = {};
  548. float xi;
  549. int i, j;
  550. bool bLeadingZero = true, bLead;
  551. if( !m_bInitialized )
  552. return;
  553. xi = 0;
  554. // get digits from value
  555. Val2Digits( digits );
  556. // draw digits
  557. for( i = (LED_DISPLAY_DIGITS - m_MaxDigits); i < LED_DISPLAY_DIGITS; i++ )
  558. {
  559. bLead = false;
  560. if( ( m_Type == TYPE_FLOAT ) && ( i < 2 ) )
  561. bLead = ( bLeadingZero && digits[ i ] == 0 );
  562. else if( ( m_Type == TYPE_INT ) && ( i < 4 ) )
  563. bLead = ( bLeadingZero && digits[ i ] == 0 );
  564. for( j = 0; j < DigitToDisplay[ digits[ i ] ][ 0 ]; j++ )
  565. drawvect( vg, xi, 0, &DigitDrawVects[ DigitToDisplay[ digits[ i ] ][ j + 1 ] ], &m_LEDColour, bLead );
  566. if( digits[ i ] != 0 )
  567. bLeadingZero = false;
  568. // draw decimal
  569. if( i == 2 && m_Type == TYPE_FLOAT )
  570. drawvect( vg, xi, 0, &DigitDrawVects[ 7 ], &m_LEDColour, false );
  571. xi += m_fSpace;
  572. }
  573. }
  574. };
  575. //-----------------------------------------------------
  576. // MyLEDButtonStrip
  577. //-----------------------------------------------------
  578. #define nMAX_STRIP_BUTTONS 32
  579. struct MyLEDButtonStrip : OpaqueWidget, FramebufferWidget
  580. {
  581. typedef void MyLEDButtonStripCALLBACK ( void *pClass, int id, int nbutton, bool bOn );
  582. bool m_bInitialized = false;
  583. int m_Id;
  584. int m_Type;
  585. int m_nButtons;
  586. bool m_bOn[ nMAX_STRIP_BUTTONS ] = {};
  587. int m_ExclusiveOn = 0;
  588. int m_HiLightOn = -1;
  589. RGB_STRUCT m_Colour;
  590. RGB_STRUCT m_LEDColour[ nMAX_STRIP_BUTTONS ] = {};
  591. float m_fLEDsize;
  592. float m_fLEDsize_d2;
  593. MyLEDButtonStripCALLBACK *m_pCallback;
  594. void *m_pClass;
  595. RECT_STRUCT m_Rect[ nMAX_STRIP_BUTTONS ];
  596. enum MyLEDButton_Types
  597. {
  598. TYPE_EXCLUSIVE,
  599. TYPE_EXCLUSIVE_WOFF,
  600. TYPE_INDEPENDANT
  601. };
  602. //-----------------------------------------------------
  603. // Procedure: Constructor
  604. //-----------------------------------------------------
  605. MyLEDButtonStrip( int x, int y, int w, int h, int space, float LEDsize, int nbuttons, bool bVert, int colour, int LEDcolour, int type, int id, void *pClass, MyLEDButtonStripCALLBACK *pCallback )
  606. {
  607. int i;
  608. if( nbuttons < 0 || nbuttons > nMAX_STRIP_BUTTONS )
  609. return;
  610. m_Id = id;
  611. m_pCallback = pCallback;
  612. m_pClass = pClass;
  613. m_Type = type;
  614. m_Colour.dwCol = colour;
  615. m_nButtons = nbuttons;
  616. m_fLEDsize = LEDsize;
  617. m_fLEDsize_d2 = LEDsize / 2.0f;
  618. box.pos = Vec( x, y );
  619. if( bVert )
  620. box.size = Vec( w, h * ( nbuttons + space ) );
  621. else
  622. box.size = Vec( w * ( nbuttons + space ), h );
  623. x = 0;
  624. y = 0;
  625. for( i = 0; i < m_nButtons; i ++)
  626. {
  627. m_LEDColour[ i ].dwCol = LEDcolour;
  628. m_Rect[ i ].x = x;
  629. m_Rect[ i ].y = y;
  630. m_Rect[ i ].x2 = x + w - 1;
  631. m_Rect[ i ].y2 = y + h - 1;
  632. if( bVert )
  633. y += space + h;
  634. else
  635. x += space + w;
  636. }
  637. m_bInitialized = true;
  638. }
  639. //-----------------------------------------------------
  640. // Procedure: Set
  641. //-----------------------------------------------------
  642. void SetHiLightOn( int button )
  643. {
  644. m_HiLightOn = button;
  645. dirty = true;
  646. }
  647. //-----------------------------------------------------
  648. // Procedure: Set
  649. //-----------------------------------------------------
  650. void Set( int button, bool bOn )
  651. {
  652. if( !m_bInitialized || button < 0 )
  653. return;
  654. if( m_Type == TYPE_EXCLUSIVE_WOFF )
  655. {
  656. if( button > m_nButtons )
  657. return;
  658. m_ExclusiveOn = button;
  659. }
  660. else
  661. {
  662. if( button >= m_nButtons )
  663. return;
  664. if( m_Type == TYPE_EXCLUSIVE )
  665. m_ExclusiveOn = button;
  666. m_bOn[ button ] = bOn;
  667. }
  668. dirty = true;
  669. }
  670. //-----------------------------------------------------
  671. // Procedure: SetLEDCol
  672. //-----------------------------------------------------
  673. void SetLEDCol( int button, int colour )
  674. {
  675. if( !m_bInitialized || button < 0 || button >= m_nButtons )
  676. return;
  677. m_LEDColour[ button ].dwCol = colour;
  678. dirty = true;
  679. }
  680. //-----------------------------------------------------
  681. // Procedure: draw
  682. //-----------------------------------------------------
  683. void draw(NVGcontext *vg) override
  684. {
  685. float xi, yi;
  686. int i;
  687. char alpha = 0xFF;
  688. if( !m_bInitialized )
  689. return;
  690. for( i = 0; i < m_nButtons; i ++)
  691. {
  692. if( m_HiLightOn == i )
  693. nvgFillColor( vg, nvgRGB( 255, 255, 255 ) );
  694. else
  695. nvgFillColor( vg, nvgRGB( m_Colour.Col[ 2 ], m_Colour.Col[ 1 ], m_Colour.Col[ 0 ] ) );
  696. // background
  697. nvgBeginPath( vg );
  698. nvgMoveTo(vg, m_Rect[ i ].x, m_Rect[ i ].y );
  699. nvgLineTo(vg, m_Rect[ i ].x2, m_Rect[ i ].y );
  700. nvgLineTo(vg, m_Rect[ i ].x2, m_Rect[ i ].y2 );
  701. nvgLineTo(vg, m_Rect[ i ].x, m_Rect[ i ].y2 );
  702. nvgClosePath( vg );
  703. nvgFill( vg );
  704. nvgFillColor( vg, nvgRGB(0x40, 0x40, 0x40) );
  705. if( m_HiLightOn == i )
  706. alpha = 0x40;
  707. if( m_Type == TYPE_EXCLUSIVE_WOFF )
  708. {
  709. if( i == ( m_ExclusiveOn - 1 ) )
  710. nvgFillColor( vg, nvgRGBA( m_LEDColour[ i ].Col[ 2 ], m_LEDColour[ i ].Col[ 1 ], m_LEDColour[ i ].Col[ 0 ], alpha ) );
  711. }
  712. else if( m_Type == TYPE_EXCLUSIVE )
  713. {
  714. if( i == m_ExclusiveOn )
  715. nvgFillColor( vg, nvgRGBA( m_LEDColour[ i ].Col[ 2 ], m_LEDColour[ i ].Col[ 1 ], m_LEDColour[ i ].Col[ 0 ], alpha ) );
  716. }
  717. else
  718. {
  719. if( m_bOn[ i ] )
  720. nvgFillColor( vg, nvgRGBA( m_LEDColour[ i ].Col[ 2 ], m_LEDColour[ i ].Col[ 1 ], m_LEDColour[ i ].Col[ 0 ], alpha ) );
  721. }
  722. xi = ( ( (float)m_Rect[ i ].x2 + (float)m_Rect[ i ].x ) / 2.0f ) - m_fLEDsize_d2;
  723. yi = ( ( (float)m_Rect[ i ].y2 + (float)m_Rect[ i ].y ) / 2.0f ) - m_fLEDsize_d2;
  724. nvgBeginPath( vg );
  725. nvgMoveTo(vg, xi, yi );
  726. nvgLineTo(vg, xi + m_fLEDsize, yi );
  727. nvgLineTo(vg, xi + m_fLEDsize, yi + m_fLEDsize );
  728. nvgLineTo(vg, xi, yi + m_fLEDsize );
  729. nvgClosePath( vg );
  730. nvgFill( vg );
  731. }
  732. }
  733. //-----------------------------------------------------
  734. // Procedure: isPoint
  735. //-----------------------------------------------------
  736. bool isPoint( RECT_STRUCT *prect, int x, int y )
  737. {
  738. if( x < prect->x || x > prect->x2 || y < prect->y || y > prect->y2 )
  739. return false;
  740. return true;
  741. }
  742. //-----------------------------------------------------
  743. // Procedure: onMouseDown
  744. //-----------------------------------------------------
  745. void onMouseDown( EventMouseDown &e ) override
  746. {
  747. int i;
  748. e.consumed = false;
  749. if( !m_bInitialized || e.button != 0 )
  750. return;
  751. for( i = 0; i < m_nButtons; i++ )
  752. {
  753. if( isPoint( &m_Rect[ i ], (int)e.pos.x, (int)e.pos.y ) )
  754. {
  755. m_bOn[ i ] = !m_bOn[ i ];
  756. if( m_Type == TYPE_EXCLUSIVE_WOFF )
  757. {
  758. if( m_ExclusiveOn == ( i + 1 ) )
  759. m_ExclusiveOn = 0;
  760. else
  761. m_ExclusiveOn = i + 1;
  762. if( m_pCallback )
  763. m_pCallback( m_pClass, m_Id, m_ExclusiveOn, false );
  764. }
  765. else
  766. {
  767. Set( i, m_bOn[ i ] );
  768. if( m_pCallback )
  769. m_pCallback( m_pClass, m_Id, i, m_bOn[ i ] );
  770. }
  771. dirty = true;
  772. e.consumed = true;
  773. return;
  774. }
  775. }
  776. return;
  777. }
  778. };
  779. //-----------------------------------------------------
  780. // MyLEDButton
  781. //-----------------------------------------------------
  782. struct MyLEDButton : OpaqueWidget, FramebufferWidget
  783. {
  784. typedef void MyLEDButtonCALLBACK ( void *pClass, int id, bool bOn );
  785. bool m_bInitialized = false;
  786. int m_Id;
  787. int m_Type;
  788. int m_StepCount = 0;
  789. bool m_bOn = false;
  790. RGB_STRUCT m_Colour;
  791. RGB_STRUCT m_LEDColour;
  792. float m_fLEDsize;
  793. float m_fLEDsize_d2;
  794. MyLEDButtonCALLBACK *m_pCallback;
  795. void *m_pClass;
  796. RECT_STRUCT m_Rect;
  797. enum MyLEDButton_Types
  798. {
  799. TYPE_SWITCH,
  800. TYPE_MOMENTARY
  801. };
  802. //-----------------------------------------------------
  803. // Procedure: Constructor
  804. //-----------------------------------------------------
  805. MyLEDButton( int x, int y, int w, int h, float LEDsize, int colour, int LEDcolour, int type, int id, void *pClass, MyLEDButtonCALLBACK *pCallback )
  806. {
  807. m_Id = id;
  808. m_pCallback = pCallback;
  809. m_pClass = pClass;
  810. m_Type = type;
  811. m_Colour.dwCol = colour;
  812. m_LEDColour.dwCol = LEDcolour;
  813. m_fLEDsize = LEDsize;
  814. m_fLEDsize_d2 = LEDsize / 2.0f;
  815. box.pos = Vec( x, y );
  816. box.size = Vec( w, h );
  817. m_Rect.x = 0;
  818. m_Rect.y = 0;
  819. m_Rect.x2 = w - 1;
  820. m_Rect.y2 = h - 1;
  821. m_bInitialized = true;
  822. }
  823. //-----------------------------------------------------
  824. // Procedure: Set
  825. //-----------------------------------------------------
  826. void Set( bool bOn )
  827. {
  828. m_bOn = bOn;
  829. dirty = true;
  830. if( m_Type == TYPE_MOMENTARY && bOn )
  831. m_StepCount = 8;//(int)( engineGetSampleRate() * 0.05 );
  832. }
  833. //-----------------------------------------------------
  834. // Procedure: draw
  835. //-----------------------------------------------------
  836. void draw(NVGcontext *vg) override
  837. {
  838. float xi, yi;
  839. if( !m_bInitialized )
  840. return;
  841. nvgFillColor( vg, nvgRGB( m_Colour.Col[ 2 ], m_Colour.Col[ 1 ], m_Colour.Col[ 0 ] ) );
  842. nvgBeginPath( vg );
  843. nvgRect( vg, 0, 0, box.size.x - 1, box.size.y - 1 );
  844. nvgClosePath( vg );
  845. nvgFill( vg );
  846. if( !m_bOn )
  847. nvgFillColor( vg, nvgRGB(0x40, 0x40, 0x40) );
  848. else
  849. nvgFillColor( vg, nvgRGB( m_LEDColour.Col[ 2 ], m_LEDColour.Col[ 1 ], m_LEDColour.Col[ 0 ] ) );
  850. xi = ( ( (float)m_Rect.x2 + (float)m_Rect.x ) / 2.0f ) - m_fLEDsize_d2 ;
  851. yi = ( ( (float)m_Rect.y2 + (float)m_Rect.y ) / 2.0f ) - m_fLEDsize_d2 ;
  852. nvgBeginPath( vg );
  853. nvgRoundedRect( vg, xi, yi, m_fLEDsize, m_fLEDsize, 2.5 );
  854. nvgClosePath( vg );
  855. nvgFill( vg );
  856. }
  857. //-----------------------------------------------------
  858. // Procedure: isPoint
  859. //-----------------------------------------------------
  860. bool isPoint( RECT_STRUCT *prect, int x, int y )
  861. {
  862. if( x < prect->x || x > prect->x2 || y < prect->y || y > prect->y2 )
  863. return false;
  864. return true;
  865. }
  866. //-----------------------------------------------------
  867. // Procedure: onMouseDown
  868. //-----------------------------------------------------
  869. void onMouseDown( EventMouseDown &e ) override
  870. {
  871. e.consumed = false;
  872. if( !m_bInitialized || e.button != 0 )
  873. return;
  874. if( isPoint( &m_Rect, (int)e.pos.x, (int)e.pos.y ) )
  875. {
  876. m_bOn = !m_bOn;
  877. if( m_Type == TYPE_MOMENTARY )
  878. {
  879. if( m_pCallback )
  880. {
  881. m_bOn = true;
  882. m_StepCount = 8;//(int)( engineGetSampleRate() * 0.05 );
  883. m_pCallback( m_pClass, m_Id, true );
  884. }
  885. }
  886. else
  887. {
  888. if( m_pCallback )
  889. m_pCallback( m_pClass, m_Id, m_bOn );
  890. }
  891. dirty = true;
  892. e.consumed = true;
  893. return;
  894. }
  895. return;
  896. }
  897. //-----------------------------------------------------
  898. // Procedure: draw
  899. //-----------------------------------------------------
  900. void step() override
  901. {
  902. if( m_StepCount && ( m_Type == TYPE_MOMENTARY ) )
  903. {
  904. if( --m_StepCount <= 0 )
  905. {
  906. m_bOn = false;
  907. m_StepCount = 0;
  908. dirty = true;
  909. }
  910. }
  911. FramebufferWidget::step();
  912. }
  913. };
  914. //-----------------------------------------------------
  915. // SinglePatternClocked32
  916. //-----------------------------------------------------
  917. #define MAX_CLK_PAT 32
  918. #define LEVELS 5
  919. struct SinglePatternClocked32 : OpaqueWidget, FramebufferWidget
  920. {
  921. typedef void SINGLEPAT16CALLBACK ( void *pClass, int id, int pat, int level, int maxpat );
  922. bool m_bInitialized = false;
  923. int m_Id;
  924. int m_nLEDs;
  925. int m_MaxPat = 0;
  926. int m_PatClk = 0;
  927. int m_PatSelLevel[ MAX_CLK_PAT ] = {0};
  928. int m_StepCount;
  929. SINGLEPAT16CALLBACK *m_pCallback;
  930. void *m_pClass;
  931. RECT_STRUCT m_RectsPatSel[ MAX_CLK_PAT ];
  932. RGB_STRUCT m_PatCol[ 2 ];
  933. RECT_STRUCT m_RectsMaxPat[ MAX_CLK_PAT ];
  934. RGB_STRUCT m_MaxCol[ 2 ];
  935. //-----------------------------------------------------
  936. // Procedure: Constructor
  937. //-----------------------------------------------------
  938. SinglePatternClocked32( int x, int y, int w, int h, int mh, int space, int beatspace, int colourPaton, int colourPatoff, int colourMaxon, int colourMaxoff, int nleds, int id, void *pClass, SINGLEPAT16CALLBACK *pCallback )
  939. {
  940. int i;
  941. if ( nleds < 2 || nleds > MAX_CLK_PAT )
  942. return;
  943. m_Id = id;
  944. m_pCallback = pCallback;
  945. m_pClass = pClass;
  946. m_nLEDs = nleds;
  947. m_PatCol[ 0 ].dwCol = colourPatoff;
  948. m_PatCol[ 1 ].dwCol = colourPaton;
  949. m_MaxCol[ 0 ].dwCol = colourMaxoff;
  950. m_MaxCol[ 1 ].dwCol = colourMaxon;
  951. box.pos = Vec(x, y);
  952. x = 0;
  953. for( i = 0; i < m_nLEDs; i++ )
  954. {
  955. m_RectsMaxPat[ i ].x = x;
  956. m_RectsMaxPat[ i ].y = 0;
  957. m_RectsMaxPat[ i ].x2 = x + w;
  958. m_RectsMaxPat[ i ].y2 = mh;
  959. m_RectsPatSel[ i ].x = x;
  960. m_RectsPatSel[ i ].y = mh + 2;
  961. m_RectsPatSel[ i ].x2 = x + w;
  962. m_RectsPatSel[ i ].y2 = ( h + mh ) + 2;
  963. if( ( i & 0x3 ) == 3 )
  964. x += ( w + beatspace );
  965. else
  966. x += ( w + space );
  967. }
  968. box.size = Vec( x, ( h + mh ) + 2 );
  969. m_bInitialized = true;
  970. }
  971. //-----------------------------------------------------
  972. // Procedure: SetPatAll
  973. //-----------------------------------------------------
  974. void SetPatAll( int *pPat )
  975. {
  976. if ( !pPat )
  977. return;
  978. for( int i = 0; i < m_nLEDs; i++ )
  979. m_PatSelLevel[ i ] = pPat[ i ];// & 0x3;
  980. dirty = true;
  981. }
  982. //-----------------------------------------------------
  983. // Procedure: GetPatAll
  984. //-----------------------------------------------------
  985. void GetPatAll( int *pPat )
  986. {
  987. if ( !pPat )
  988. return;
  989. for( int i = 0; i < m_nLEDs; i++ )
  990. pPat[ i ] = m_PatSelLevel[ i ];
  991. dirty = true;
  992. }
  993. //-----------------------------------------------------
  994. // Procedure: SetPat
  995. //-----------------------------------------------------
  996. void SetPat( int pat )
  997. {
  998. if ( pat < 0 || pat >= m_nLEDs )
  999. return;
  1000. m_PatSelLevel[ pat ] = ( m_PatSelLevel[ pat ] + 1 );
  1001. if( m_PatSelLevel[ pat ] > LEVELS )
  1002. m_PatSelLevel[ pat ] = 0;
  1003. dirty = true;
  1004. }
  1005. //-----------------------------------------------------
  1006. // Procedure: SetPat
  1007. //-----------------------------------------------------
  1008. void ClrPat( int pat )
  1009. {
  1010. if ( pat < 0 || pat >= m_nLEDs )
  1011. return;
  1012. m_PatSelLevel[ pat ] = 0;
  1013. dirty = true;
  1014. }
  1015. //-----------------------------------------------------
  1016. // Procedure: ClockInc
  1017. //-----------------------------------------------------
  1018. bool ClockInc( void )
  1019. {
  1020. m_PatClk ++;
  1021. if ( m_PatClk < 0 || m_PatClk > m_MaxPat || m_PatClk >= m_nLEDs )
  1022. m_PatClk = 0;
  1023. dirty = true;
  1024. if( m_PatClk == 0 )
  1025. return true;
  1026. return false;
  1027. }
  1028. //-----------------------------------------------------
  1029. // Procedure: ClockReset
  1030. //-----------------------------------------------------
  1031. void ClockReset( void )
  1032. {
  1033. m_PatClk = 0;
  1034. dirty = true;
  1035. }
  1036. //-----------------------------------------------------
  1037. // Procedure: SetMax
  1038. //-----------------------------------------------------
  1039. void SetMax( int max )
  1040. {
  1041. m_MaxPat = max;
  1042. dirty = true;
  1043. }
  1044. //-----------------------------------------------------
  1045. // Procedure: draw
  1046. //-----------------------------------------------------
  1047. void draw(NVGcontext *vg) override
  1048. {
  1049. float xi, yi;
  1050. RGB_STRUCT rgb = {0};
  1051. int i;
  1052. if( !m_bInitialized )
  1053. return;
  1054. nvgFillColor(vg, nvgRGBA(0, 0, 0, 0xc0));
  1055. nvgBeginPath(vg);
  1056. nvgMoveTo(vg, -1, -1 );
  1057. nvgLineTo(vg, box.size.x + 1, -1 );
  1058. nvgLineTo(vg, box.size.x + 1, box.size.y + 1 );
  1059. nvgLineTo(vg, -1, box.size.y + 1 );
  1060. nvgClosePath(vg);
  1061. nvgFill(vg);
  1062. nvgStrokeWidth( vg, 0.35 );
  1063. nvgStrokeColor( vg, nvgRGBA( 0xc0, 0xc0, 0xc0, 255 ) );
  1064. for( i = 0; i < m_nLEDs; i++ )
  1065. {
  1066. // max pattern display
  1067. if( i <= m_MaxPat )
  1068. nvgFillColor( vg, nvgRGB( m_MaxCol[ 1 ].Col[ 2 ], m_MaxCol[ 1 ].Col[ 1 ], m_MaxCol[ 1 ].Col[ 0 ] ) );
  1069. else
  1070. nvgFillColor( vg, nvgRGB( m_MaxCol[ 0 ].Col[ 2 ], m_MaxCol[ 0 ].Col[ 1 ], m_MaxCol[ 0 ].Col[ 0 ] ) );
  1071. nvgBeginPath(vg);
  1072. xi = ( ( (float)m_RectsPatSel[ i ].x2 + (float)m_RectsPatSel[ i ].x ) / 2.0f );
  1073. nvgMoveTo(vg, m_RectsMaxPat[ i ].x, m_RectsMaxPat[ i ].y );
  1074. nvgLineTo(vg, m_RectsMaxPat[ i ].x2, m_RectsMaxPat[ i ].y );
  1075. nvgLineTo(vg, xi, m_RectsMaxPat[ i ].y2 );
  1076. //nvgLineTo(vg, m_RectsMaxPat[ i ].x, m_RectsMaxPat[ i ].y2 );
  1077. nvgClosePath(vg);
  1078. nvgFill(vg);
  1079. //nvgStroke( vg );
  1080. // pattern select
  1081. rgb.Col[ 0 ] = ( ( m_PatCol[ 1 ].Col[ 0 ] * m_PatSelLevel[ i ] ) + ( m_PatCol[ 0 ].Col[ 0 ] * ( LEVELS - m_PatSelLevel[ i ] ) ) ) / LEVELS;
  1082. rgb.Col[ 1 ] = ( ( m_PatCol[ 1 ].Col[ 1 ] * m_PatSelLevel[ i ] ) + ( m_PatCol[ 0 ].Col[ 1 ] * ( LEVELS - m_PatSelLevel[ i ] ) ) ) / LEVELS;
  1083. rgb.Col[ 2 ] = ( ( m_PatCol[ 1 ].Col[ 2 ] * m_PatSelLevel[ i ] ) + ( m_PatCol[ 0 ].Col[ 2 ] * ( LEVELS - m_PatSelLevel[ i ] ) ) ) / LEVELS;
  1084. nvgFillColor( vg, nvgRGB( rgb.Col[ 2 ], rgb.Col[ 1 ], rgb.Col[ 0 ] ) );
  1085. nvgBeginPath(vg);
  1086. nvgMoveTo(vg, m_RectsPatSel[ i ].x, m_RectsPatSel[ i ].y );
  1087. nvgLineTo(vg, m_RectsPatSel[ i ].x2, m_RectsPatSel[ i ].y );
  1088. nvgLineTo(vg, m_RectsPatSel[ i ].x2, m_RectsPatSel[ i ].y2 );
  1089. nvgLineTo(vg, m_RectsPatSel[ i ].x, m_RectsPatSel[ i ].y2 );
  1090. nvgClosePath(vg);
  1091. nvgFill(vg);
  1092. nvgStroke( vg );
  1093. xi = ( ( (float)m_RectsPatSel[ i ].x2 + (float)m_RectsPatSel[ i ].x ) / 2.0f ) - 2.0f ;
  1094. yi = ( ( (float)m_RectsPatSel[ i ].y2 + (float)m_RectsPatSel[ i ].y ) / 2.0f ) - 2.0f ;
  1095. if( i == m_PatClk )
  1096. nvgFillColor( vg, nvgRGBA( 0, 0xFF, 0, 0xFF ) );
  1097. else
  1098. nvgFillColor( vg, nvgRGBA( 0, 0, 0, 0xFF ) );
  1099. nvgBeginPath(vg);
  1100. nvgMoveTo(vg, xi, yi );
  1101. nvgLineTo(vg, xi + 4.0f, yi );
  1102. nvgLineTo(vg, xi + 4.0f, yi + 4.0f );
  1103. nvgLineTo(vg, xi, yi + 4.0f );
  1104. nvgClosePath(vg);
  1105. nvgFill(vg);
  1106. }
  1107. }
  1108. //-----------------------------------------------------
  1109. // Procedure: isPoint
  1110. //-----------------------------------------------------
  1111. bool isPoint( RECT_STRUCT *prect, int x, int y )
  1112. {
  1113. if( x < prect->x || x > prect->x2 || y < prect->y || y > prect->y2 )
  1114. return false;
  1115. return true;
  1116. }
  1117. //-----------------------------------------------------
  1118. // Procedure: onMouseDown
  1119. //-----------------------------------------------------
  1120. void onMouseDown( EventMouseDown &e ) override
  1121. {
  1122. int i;
  1123. e.consumed = false;
  1124. if( !m_bInitialized )
  1125. return;
  1126. for( i = 0; i < m_nLEDs; i++)
  1127. {
  1128. if( isPoint( &m_RectsPatSel[ i ], (int)e.pos.x, (int)e.pos.y ) )
  1129. {
  1130. if( e.button == 0 )
  1131. SetPat( i );
  1132. else
  1133. ClrPat( i );
  1134. if( m_pCallback )
  1135. m_pCallback( m_pClass, m_Id, i, m_PatSelLevel[ i ], m_MaxPat );
  1136. dirty = true;
  1137. e.consumed = true;
  1138. return;
  1139. }
  1140. else if( isPoint( &m_RectsMaxPat[ i ], (int)e.pos.x, (int)e.pos.y ) )
  1141. {
  1142. m_MaxPat = i;
  1143. if( m_pCallback )
  1144. m_pCallback( m_pClass, m_Id, i, m_PatSelLevel[ i ], m_MaxPat );
  1145. dirty = true;
  1146. e.consumed = true;
  1147. return;
  1148. }
  1149. }
  1150. return;
  1151. }
  1152. //-----------------------------------------------------
  1153. // Procedure: draw
  1154. //-----------------------------------------------------
  1155. void step() override
  1156. {
  1157. FramebufferWidget::step();
  1158. }
  1159. };
  1160. //-----------------------------------------------------
  1161. // PatternSelectStrip
  1162. //-----------------------------------------------------
  1163. #define MAX_PAT 32
  1164. struct PatternSelectStrip : OpaqueWidget, FramebufferWidget
  1165. {
  1166. typedef void PATCHANGECALLBACK ( void *pClass, int id, int pat, int maxpat );
  1167. bool m_bInitialized = false;
  1168. int m_Id;
  1169. int m_nLEDs;
  1170. int m_MaxPat = 0;
  1171. int m_PatSel = 0;
  1172. int m_PatPending = -1;
  1173. int m_StepCount;
  1174. PATCHANGECALLBACK *m_pCallback;
  1175. void *m_pClass;
  1176. RECT_STRUCT m_RectsMaxPat[ MAX_PAT ];
  1177. RECT_STRUCT m_RectsPatSel[ MAX_PAT ];
  1178. RGB_STRUCT m_PatCol[ 2 ];
  1179. RGB_STRUCT m_MaxCol[ 2 ];
  1180. //-----------------------------------------------------
  1181. // Procedure: Constructor
  1182. //-----------------------------------------------------
  1183. PatternSelectStrip( int x, int y, int w, int h, int colourPaton, int colourPatoff, int colourMaxon, int colourMaxoff, int nleds, int id, void *pClass, PATCHANGECALLBACK *pCallback )
  1184. {
  1185. int i;
  1186. if ( nleds < 0 || nleds > MAX_PAT )
  1187. return;
  1188. m_Id = id;
  1189. m_pCallback = pCallback;
  1190. m_pClass = pClass;
  1191. m_nLEDs = nleds;
  1192. m_PatCol[ 0 ].dwCol = colourPatoff;
  1193. m_PatCol[ 1 ].dwCol = colourPaton;
  1194. m_MaxCol[ 0 ].dwCol = colourMaxoff;
  1195. m_MaxCol[ 1 ].dwCol = colourMaxon;
  1196. box.pos = Vec(x, y);
  1197. box.size = Vec( w * m_nLEDs + ( m_nLEDs * 2 ) - 1, ( h * 2 ) + 2 );
  1198. x = 0;
  1199. for( i = 0; i < m_nLEDs; i++ )
  1200. {
  1201. m_RectsMaxPat[ i ].x = x;
  1202. m_RectsMaxPat[ i ].y = 0;
  1203. m_RectsMaxPat[ i ].x2 = x + w;
  1204. m_RectsMaxPat[ i ].y2 = h;
  1205. m_RectsPatSel[ i ].x = x;
  1206. m_RectsPatSel[ i ].y = h + 2;
  1207. m_RectsPatSel[ i ].x2 = x + w;
  1208. m_RectsPatSel[ i ].y2 = ( h * 2 ) + 2;
  1209. x += ( w + 2 );
  1210. }
  1211. m_bInitialized = true;
  1212. }
  1213. //-----------------------------------------------------
  1214. // Procedure: SetPat
  1215. //-----------------------------------------------------
  1216. void SetPat( int pat, bool bPending )
  1217. {
  1218. if( bPending )
  1219. m_PatPending = pat;
  1220. else
  1221. {
  1222. m_PatPending = -1;
  1223. m_PatSel = pat;
  1224. }
  1225. dirty = true;
  1226. }
  1227. //-----------------------------------------------------
  1228. // Procedure: SetMax
  1229. //-----------------------------------------------------
  1230. void SetMax( int max )
  1231. {
  1232. m_MaxPat = max;
  1233. dirty = true;
  1234. }
  1235. //-----------------------------------------------------
  1236. // Procedure: draw
  1237. //-----------------------------------------------------
  1238. void draw(NVGcontext *vg) override
  1239. {
  1240. int i;
  1241. float xi;
  1242. if( !m_bInitialized )
  1243. return;
  1244. nvgFillColor(vg, nvgRGBA(0, 0, 0, 0xc0));
  1245. nvgBeginPath(vg);
  1246. nvgMoveTo(vg, -1, -1 );
  1247. nvgLineTo(vg, box.size.x + 1, -1 );
  1248. nvgLineTo(vg, box.size.x + 1, box.size.y + 1 );
  1249. nvgLineTo(vg, -1, box.size.y + 1 );
  1250. nvgClosePath(vg);
  1251. nvgFill(vg);
  1252. for( i = 0; i < m_nLEDs; i++ )
  1253. {
  1254. if( i <= m_MaxPat )
  1255. nvgFillColor( vg, nvgRGB( m_MaxCol[ 1 ].Col[ 2 ], m_MaxCol[ 1 ].Col[ 1 ], m_MaxCol[ 1 ].Col[ 0 ] ) );
  1256. else
  1257. nvgFillColor( vg, nvgRGB( m_MaxCol[ 0 ].Col[ 2 ], m_MaxCol[ 0 ].Col[ 1 ], m_MaxCol[ 0 ].Col[ 0 ] ) );
  1258. nvgBeginPath(vg);
  1259. xi = ( ( (float)m_RectsPatSel[ i ].x2 + (float)m_RectsPatSel[ i ].x ) / 2.0f );
  1260. nvgMoveTo(vg, m_RectsMaxPat[ i ].x, m_RectsMaxPat[ i ].y );
  1261. nvgLineTo(vg, m_RectsMaxPat[ i ].x2, m_RectsMaxPat[ i ].y );
  1262. nvgLineTo(vg, xi, m_RectsMaxPat[ i ].y2 );
  1263. nvgClosePath(vg);
  1264. nvgFill(vg);
  1265. if( m_PatSel == i )
  1266. nvgFillColor( vg, nvgRGB( m_PatCol[ 1 ].Col[ 2 ], m_PatCol[ 1 ].Col[ 1 ], m_PatCol[ 1 ].Col[ 0 ] ) );
  1267. else
  1268. nvgFillColor( vg, nvgRGB( m_PatCol[ 0 ].Col[ 2 ], m_PatCol[ 0 ].Col[ 1 ], m_PatCol[ 0 ].Col[ 0 ] ) );
  1269. nvgBeginPath(vg);
  1270. nvgMoveTo(vg, m_RectsPatSel[ i ].x, m_RectsPatSel[ i ].y );
  1271. nvgLineTo(vg, m_RectsPatSel[ i ].x2, m_RectsPatSel[ i ].y );
  1272. nvgLineTo(vg, m_RectsPatSel[ i ].x2, m_RectsPatSel[ i ].y2 );
  1273. nvgLineTo(vg, m_RectsPatSel[ i ].x, m_RectsPatSel[ i ].y2 );
  1274. nvgClosePath(vg);
  1275. nvgFill(vg);
  1276. if( m_PatPending == i )
  1277. {
  1278. nvgFillColor( vg, nvgRGBA( m_PatCol[ 1 ].Col[ 2 ], m_PatCol[ 1 ].Col[ 1 ], m_PatCol[ 1 ].Col[ 0 ], 0x50 ) );
  1279. nvgBeginPath(vg);
  1280. nvgMoveTo(vg, m_RectsPatSel[ i ].x, m_RectsPatSel[ i ].y );
  1281. nvgLineTo(vg, m_RectsPatSel[ i ].x2, m_RectsPatSel[ i ].y );
  1282. nvgLineTo(vg, m_RectsPatSel[ i ].x2, m_RectsPatSel[ i ].y2 );
  1283. nvgLineTo(vg, m_RectsPatSel[ i ].x, m_RectsPatSel[ i ].y2 );
  1284. nvgClosePath(vg);
  1285. nvgFill(vg);
  1286. }
  1287. }
  1288. }
  1289. //-----------------------------------------------------
  1290. // Procedure: isPoint
  1291. //-----------------------------------------------------
  1292. bool isPoint( RECT_STRUCT *prect, int x, int y )
  1293. {
  1294. if( x < prect->x || x > prect->x2 || y < prect->y || y > prect->y2 )
  1295. return false;
  1296. return true;
  1297. }
  1298. //-----------------------------------------------------
  1299. // Procedure: onMouseDown
  1300. //-----------------------------------------------------
  1301. void onMouseDown( EventMouseDown &e ) override
  1302. {
  1303. int i;
  1304. e.consumed = false;
  1305. if( !m_bInitialized )
  1306. return;
  1307. if( e.button != 0 )
  1308. return;
  1309. for( i = 0; i < m_nLEDs; i++)
  1310. {
  1311. if( isPoint( &m_RectsMaxPat[ i ], (int)e.pos.x, (int)e.pos.y ) )
  1312. {
  1313. m_MaxPat = i;
  1314. if( m_pCallback )
  1315. m_pCallback( m_pClass, m_Id, m_PatSel, m_MaxPat );
  1316. dirty = true;
  1317. e.consumed = true;
  1318. return;
  1319. }
  1320. else if( isPoint( &m_RectsPatSel[ i ], (int)e.pos.x, (int)e.pos.y ) )
  1321. {
  1322. m_PatSel = i;
  1323. if( m_pCallback )
  1324. m_pCallback( m_pClass, m_Id, m_PatSel, m_MaxPat );
  1325. e.consumed = true;
  1326. return;
  1327. }
  1328. }
  1329. return;
  1330. }
  1331. //-----------------------------------------------------
  1332. // Procedure: draw
  1333. //-----------------------------------------------------
  1334. void step() override
  1335. {
  1336. FramebufferWidget::step();
  1337. }
  1338. };
  1339. //-----------------------------------------------------
  1340. // CompressorLEDMeterWidget
  1341. //-----------------------------------------------------
  1342. #define nDISPLAY_LEDS 10
  1343. const float fleveldb[ nDISPLAY_LEDS ] = { 0, 3, 6, 10, 20, 30, 40, 50, 60, 80 };
  1344. struct CompressorLEDMeterWidget : TransparentWidget
  1345. {
  1346. bool m_bInitialized = false;
  1347. bool m_bOn[ nDISPLAY_LEDS ] = {};
  1348. int m_StepCount = 0;
  1349. float m_fLargest = 0;
  1350. RECT_STRUCT m_Rects[ nDISPLAY_LEDS ];
  1351. RGB_STRUCT m_ColourOn;
  1352. RGB_STRUCT m_ColourOff;
  1353. bool m_bInvert;
  1354. float flevels[ nDISPLAY_LEDS ];
  1355. //-----------------------------------------------------
  1356. // Procedure: Constructor
  1357. //-----------------------------------------------------
  1358. CompressorLEDMeterWidget( bool bInvert, int x, int y, int w, int h, int colouron, int colouroff )
  1359. {
  1360. int i;
  1361. m_bInvert = bInvert;
  1362. m_ColourOn.dwCol = colouron;
  1363. m_ColourOff.dwCol = colouroff;
  1364. box.pos = Vec(x, y);
  1365. box.size = Vec( w, h * nDISPLAY_LEDS + ( nDISPLAY_LEDS * 2 ) );
  1366. y = 1;
  1367. for( i = 0; i < nDISPLAY_LEDS; i++ )
  1368. {
  1369. flevels[ i ] = db_to_lvl( fleveldb[ i ] );
  1370. m_Rects[ i ].x = 0;
  1371. m_Rects[ i ].y = y;
  1372. m_Rects[ i ].x2 = w;
  1373. m_Rects[ i ].y2 = y + h;
  1374. y += ( h + 2 );
  1375. }
  1376. m_bInitialized = true;
  1377. }
  1378. //-----------------------------------------------------
  1379. // Procedure: draw
  1380. //-----------------------------------------------------
  1381. void draw(NVGcontext *vg) override
  1382. {
  1383. int i;
  1384. if( !m_bInitialized )
  1385. return;
  1386. nvgFillColor(vg, nvgRGBA(0, 0, 0, 0xc0));
  1387. nvgBeginPath(vg);
  1388. nvgMoveTo(vg, -1, -1 );
  1389. nvgLineTo(vg, box.size.x + 1, -1 );
  1390. nvgLineTo(vg, box.size.x + 1, box.size.y + 1 );
  1391. nvgLineTo(vg, -1, box.size.y + 1 );
  1392. nvgClosePath(vg);
  1393. nvgFill(vg);
  1394. for( i = 0; i < nDISPLAY_LEDS; i++ )
  1395. {
  1396. if( m_bOn[ i ] )
  1397. nvgFillColor( vg, nvgRGB( m_ColourOn.Col[ 2 ], m_ColourOn.Col[ 1 ], m_ColourOn.Col[ 0 ] ) );
  1398. else
  1399. nvgFillColor( vg, nvgRGB( m_ColourOff.Col[ 2 ], m_ColourOff.Col[ 1 ], m_ColourOff.Col[ 0 ] ) );
  1400. nvgBeginPath(vg);
  1401. nvgMoveTo(vg, m_Rects[ i ].x, m_Rects[ i ].y );
  1402. nvgLineTo(vg, m_Rects[ i ].x2, m_Rects[ i ].y );
  1403. nvgLineTo(vg, m_Rects[ i ].x2, m_Rects[ i ].y2 );
  1404. nvgLineTo(vg, m_Rects[ i ].x, m_Rects[ i ].y2 );
  1405. nvgClosePath(vg);
  1406. nvgFill(vg);
  1407. }
  1408. }
  1409. //-----------------------------------------------------
  1410. // Procedure: Process
  1411. //-----------------------------------------------------
  1412. void Process( float level )
  1413. {
  1414. int steptime = (int)( engineGetSampleRate() * 0.05f );
  1415. int i;
  1416. if( !m_bInitialized )
  1417. return;
  1418. if( fabs( level ) > m_fLargest )
  1419. m_fLargest = fabs( level );
  1420. // only process every 1/10th of a second
  1421. if( ++m_StepCount >= steptime )
  1422. {
  1423. m_StepCount = 0;
  1424. if( m_bInvert )
  1425. {
  1426. for( i = 0; i < nDISPLAY_LEDS; i++ )
  1427. {
  1428. if( m_fLargest >= flevels[ i ] )
  1429. m_bOn[ ( nDISPLAY_LEDS - 1 ) - i ] = true;
  1430. else
  1431. m_bOn[ ( nDISPLAY_LEDS - 1 ) - i ] = false;
  1432. }
  1433. }
  1434. else
  1435. {
  1436. for( i = 0; i < nDISPLAY_LEDS; i++ )
  1437. {
  1438. if( m_fLargest >= flevels[ i ] )
  1439. m_bOn[ i ] = true;
  1440. else
  1441. m_bOn[ i ] = false;
  1442. }
  1443. }
  1444. m_fLargest = 0.0f;
  1445. }
  1446. }
  1447. };
  1448. //-----------------------------------------------------
  1449. // LEDMeterWidget
  1450. //-----------------------------------------------------
  1451. struct LEDMeterWidget : TransparentWidget
  1452. {
  1453. bool m_bInitialized = false;
  1454. bool m_bOn[ nDISPLAY_LEDS ] = {};
  1455. int m_space;
  1456. int m_StepCount = 0;
  1457. bool m_bVert;
  1458. float m_fLargest = 0.0;
  1459. RECT_STRUCT m_Rects[ nDISPLAY_LEDS ];
  1460. RGB_STRUCT m_ColoursOn[ nDISPLAY_LEDS ];
  1461. RGB_STRUCT m_ColoursOff[ nDISPLAY_LEDS ];
  1462. float flevels[ nDISPLAY_LEDS ] = {};
  1463. //-----------------------------------------------------
  1464. // Procedure: Constructor
  1465. //-----------------------------------------------------
  1466. LEDMeterWidget( int x, int y, int w, int h, int space, bool bVert )
  1467. {
  1468. int i, xoff = 0, yoff = 0, xpos = 0, ypos = 0;
  1469. m_space = space;
  1470. box.pos = Vec(x, y);
  1471. if( bVert )
  1472. {
  1473. box.size = Vec( w, h * nDISPLAY_LEDS + (m_space * nDISPLAY_LEDS) );
  1474. yoff = h + m_space;
  1475. }
  1476. else
  1477. {
  1478. box.size = Vec( w * nDISPLAY_LEDS + (m_space * nDISPLAY_LEDS), h );
  1479. xoff = w + m_space;
  1480. }
  1481. for( i = 0; i < nDISPLAY_LEDS; i++ )
  1482. {
  1483. flevels[ i ] = db_to_lvl( fleveldb[ i ] );
  1484. m_Rects[ i ].x = xpos;
  1485. m_Rects[ i ].y = ypos;
  1486. m_Rects[ i ].x2 = xpos + w;
  1487. m_Rects[ i ].y2 = ypos + h;
  1488. // always red
  1489. if( i == 0 )
  1490. {
  1491. m_ColoursOn[ i ].dwCol = DWRGB( 0xFF, 0, 0 );
  1492. m_ColoursOff[ i ].dwCol= DWRGB( 0x80, 0, 0 );
  1493. }
  1494. // yellow
  1495. else if( i < 3 )
  1496. {
  1497. m_ColoursOn[ i ].dwCol = DWRGB( 0xFF, 0xFF, 0 );
  1498. m_ColoursOff[ i ].dwCol= DWRGB( 0x80, 0x80, 0 );
  1499. }
  1500. // green
  1501. else
  1502. {
  1503. m_ColoursOn[ i ].dwCol = DWRGB( 0, 0xFF, 0 );
  1504. m_ColoursOff[ i ].dwCol= DWRGB( 0, 0x80, 0 );
  1505. }
  1506. xpos += xoff;
  1507. ypos += yoff;
  1508. }
  1509. m_bInitialized = true;
  1510. }
  1511. //-----------------------------------------------------
  1512. // Procedure: draw
  1513. //-----------------------------------------------------
  1514. void draw(NVGcontext *vg) override
  1515. {
  1516. int i;
  1517. if( !m_bInitialized )
  1518. return;
  1519. nvgFillColor(vg, nvgRGBA(0, 0, 0, 0xc0));
  1520. nvgBeginPath(vg);
  1521. nvgMoveTo(vg, -1, -1 );
  1522. nvgLineTo(vg, box.size.x + 1, -1 );
  1523. nvgLineTo(vg, box.size.x + 1, box.size.y + 1 );
  1524. nvgLineTo(vg, -1, box.size.y + 1 );
  1525. nvgClosePath(vg);
  1526. nvgFill(vg);
  1527. for( i = 0; i < nDISPLAY_LEDS; i++ )
  1528. {
  1529. if( m_bOn[ i ] )
  1530. nvgFillColor( vg, nvgRGB( m_ColoursOn[ i ].Col[ 2 ], m_ColoursOn[ i ].Col[ 1 ], m_ColoursOn[ i ].Col[ 0 ] ) );
  1531. else
  1532. nvgFillColor( vg, nvgRGB( m_ColoursOff[ i ].Col[ 2 ], m_ColoursOff[ i ].Col[ 1 ], m_ColoursOff[ i ].Col[ 0 ] ) );
  1533. nvgBeginPath(vg);
  1534. nvgMoveTo(vg, m_Rects[ i ].x, m_Rects[ i ].y );
  1535. nvgLineTo(vg, m_Rects[ i ].x2, m_Rects[ i ].y );
  1536. nvgLineTo(vg, m_Rects[ i ].x2, m_Rects[ i ].y2 );
  1537. nvgLineTo(vg, m_Rects[ i ].x, m_Rects[ i ].y2 );
  1538. nvgClosePath(vg);
  1539. nvgFill(vg);
  1540. }
  1541. }
  1542. //-----------------------------------------------------
  1543. // Procedure: Process
  1544. //-----------------------------------------------------
  1545. void Process( float level )
  1546. {
  1547. int steptime = (int)( engineGetSampleRate() * 0.05 );
  1548. int i;
  1549. if( !m_bInitialized )
  1550. return;
  1551. if( fabs( level ) > m_fLargest )
  1552. m_fLargest = fabs( level );
  1553. // only process every 1/10th of a second
  1554. if( ++m_StepCount >= steptime )
  1555. {
  1556. m_StepCount = 0;
  1557. for( i = 0; i < nDISPLAY_LEDS; i++ )
  1558. {
  1559. if( m_fLargest >= flevels[ i ] )
  1560. m_bOn[ i ] = true;
  1561. else
  1562. m_bOn[ i ] = false;
  1563. }
  1564. m_fLargest = 0.0;
  1565. }
  1566. }
  1567. };
  1568. //-----------------------------------------------------
  1569. // Keyboard_3Oct_Widget
  1570. //-----------------------------------------------------
  1571. struct Keyboard_3Oct_Widget : OpaqueWidget, FramebufferWidget
  1572. {
  1573. typedef void NOTECHANGECALLBACK ( void *pClass, int kb, int notepressed, int *pnotes, bool bOn, int button );
  1574. #define nKEYS 37
  1575. #define MAX_MULT_KEYS 16
  1576. #define OCT_OFFSET_X 91
  1577. bool m_bInitialized = false;
  1578. RGB_STRUCT m_rgb_white, m_rgb_black, m_rgb_on;
  1579. CLog *lg;
  1580. int m_MaxMultKeys = 1;
  1581. int m_KeySave[ MAX_MULT_KEYS ] = {0};
  1582. bool m_bKeyOnList[ nKEYS ] = {false};
  1583. int m_nKeysOn = 0;
  1584. int m_KeyOn = 0;
  1585. RECT_STRUCT keyrects[ nKEYS ] ={};
  1586. NOTECHANGECALLBACK *pNoteChangeCallback = NULL;
  1587. void *m_pClass = NULL;
  1588. int m_nKb;
  1589. DRAW_VECT_STRUCT OctaveKeyDrawVects[ nKEYS ] =
  1590. {
  1591. { 6, { {1, 1}, {1, 62}, {12, 62}, {12, 39}, {7, 39}, {7, 1}, {0, 0}, {0, 0} } },
  1592. { 4, { {8, 1}, {8, 38}, {16, 38}, {16, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0} } },
  1593. { 8, { {17, 1}, {17, 39}, {14, 39}, {14, 62}, {25, 62}, {25, 39}, {22, 39}, {22, 1} } },
  1594. { 4, { {23, 1}, {23, 38}, {31, 38}, {31, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0} } },
  1595. { 6, { {32, 1}, {32, 39}, {27, 39}, {27, 62}, {38, 62}, {38, 1}, {0, 0}, {0, 0} } },
  1596. { 6, { {40, 1}, {40, 62}, {51, 62}, {51, 39}, {46, 39}, {46, 1}, {0, 0}, {0, 0} } },
  1597. { 4, { {47, 1}, {47, 38}, {55, 38}, {55, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0} } },
  1598. { 8, { {56, 1}, {56, 39}, {53, 39}, {53, 62}, {64, 62}, {64, 39}, {60, 39}, {60, 1} } },
  1599. { 4, { {61, 1}, {61, 38}, {69, 38}, {69, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0} } },
  1600. { 8, { {70, 1}, {70, 39}, {66, 39}, {66, 62}, {77, 62}, {77, 39}, {74, 39}, {74, 1} } },
  1601. { 4, { {75, 1}, {75, 38}, {83, 38}, {83, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0} } },
  1602. { 6, { {84, 1}, {84, 39}, {79, 39}, {79, 62}, {90, 62}, {90, 1}, {0, 0}, {0, 0} } },
  1603. };
  1604. int keysquare_x[ nKEYS ] =
  1605. {
  1606. 1, 8, 14, 23, 27, 40, 47, 53, 61, 66, 75, 79
  1607. };
  1608. DRAW_VECT_STRUCT OctaveKeyHighC [ 1 ] =
  1609. {
  1610. { 5, { {1, 1}, {1, 62}, {12, 62}, {12, 44}, {12, 1}, {0, 0}, {0, 0}, {0, 0} } }
  1611. };
  1612. //-----------------------------------------------------
  1613. // Procedure: Constructor
  1614. //-----------------------------------------------------
  1615. Keyboard_3Oct_Widget( int x, int y, int maxkeysel, int nKb, unsigned int rgbon, void *pClass, NOTECHANGECALLBACK *pcallback, CLog *plog )
  1616. {
  1617. int i, j, oct = 0;
  1618. if( maxkeysel > MAX_MULT_KEYS )
  1619. return;
  1620. m_MaxMultKeys = maxkeysel;
  1621. pNoteChangeCallback = pcallback;
  1622. m_pClass = pClass;
  1623. m_nKb = nKb;
  1624. m_KeyOn = -1;
  1625. m_rgb_on.dwCol = rgbon;
  1626. lg = plog;
  1627. box.pos = Vec(x, y);
  1628. // calc key rects and calculate the remainder of the key vec list
  1629. for( i = 0; i < nKEYS; i++ )
  1630. {
  1631. if( i >= 12 )
  1632. {
  1633. oct = i / 12;
  1634. if( i == (nKEYS-1) )
  1635. {
  1636. // populate the rest of the key vect table based on the first octave
  1637. memcpy( &OctaveKeyDrawVects[ i ], &OctaveKeyHighC[ 0 ], sizeof(DRAW_VECT_STRUCT) );
  1638. for( j = 0; j < 8; j++ )
  1639. OctaveKeyDrawVects[ i ].p[ j ].fx = OctaveKeyHighC[ 0 ].p[ j ].fx + ( OCT_OFFSET_X * oct );
  1640. keysquare_x[ i ] = keysquare_x[ 0 ] + ( OCT_OFFSET_X * oct );
  1641. }
  1642. else
  1643. {
  1644. // populate the rest of the key vect table based on the first octave
  1645. memcpy( &OctaveKeyDrawVects[ i ], &OctaveKeyDrawVects[ i - ( oct * 12 ) ], sizeof(DRAW_VECT_STRUCT) );
  1646. for( j = 0; j < 8; j++ )
  1647. OctaveKeyDrawVects[ i ].p[ j ].fx = OctaveKeyDrawVects[ i - ( oct * 12 ) ].p[ j ].fx + ( OCT_OFFSET_X * oct );
  1648. keysquare_x[ i ] = keysquare_x[ i - ( oct * 12 ) ] + ( OCT_OFFSET_X * oct );
  1649. }
  1650. }
  1651. // build the key rects for key press detection
  1652. keyrects[ i ].x = keysquare_x[ i ]- 1;
  1653. keyrects[ i ].y = 1;
  1654. if( OctaveKeyDrawVects[ i ].nUsed == 4 )
  1655. {
  1656. // black key
  1657. keyrects[ i ].x2 = keyrects[ i ].x + 9;
  1658. keyrects[ i ].y2 = keyrects[ i ].y + 43;
  1659. }
  1660. else
  1661. {
  1662. // white key
  1663. keyrects[ i ].x2 = keyrects[ i ].x + 14;
  1664. keyrects[ i ].y2 = keyrects[ i ].y + 67;
  1665. }
  1666. }
  1667. box.size = Vec( keyrects[ (nKEYS-1) ].x2, 62 );
  1668. m_rgb_white.dwCol = DWRGB( 215, 207, 198 );
  1669. m_rgb_black.dwCol = 0;
  1670. memset( m_KeySave, 0xFF, sizeof(m_KeySave) );
  1671. m_bInitialized = true;
  1672. }
  1673. //-----------------------------------------------------
  1674. // Procedure: addtokeylist
  1675. //-----------------------------------------------------
  1676. void addtokeylist( int key, int button )
  1677. {
  1678. int count = 0;
  1679. bool bOn = false;
  1680. // single key
  1681. if( m_MaxMultKeys == 1 )
  1682. {
  1683. m_KeySave[ 0 ] = key;
  1684. bOn = true;
  1685. }
  1686. else
  1687. {
  1688. // if key is off we are turning it on, check max keys
  1689. if( !m_bKeyOnList[ key ] )
  1690. {
  1691. // ignore if we already have max keys
  1692. if( ( m_nKeysOn + 1 ) > m_MaxMultKeys )
  1693. return;
  1694. bOn = true;
  1695. m_nKeysOn++;
  1696. m_bKeyOnList[ key ] = true;
  1697. }
  1698. else
  1699. {
  1700. m_nKeysOn--;
  1701. m_bKeyOnList[ key ] = false;
  1702. }
  1703. memset( m_KeySave, 0xFF, sizeof(m_KeySave) );
  1704. // build key list
  1705. for( int i = 0; i < nKEYS; i++ )
  1706. {
  1707. if( m_bKeyOnList[ i ] )
  1708. m_KeySave[ count++ ] = i;
  1709. }
  1710. }
  1711. if( pNoteChangeCallback )
  1712. pNoteChangeCallback( m_pClass, m_nKb, key, m_KeySave, bOn, button );
  1713. }
  1714. //-----------------------------------------------------
  1715. // Procedure: isPoint
  1716. //-----------------------------------------------------
  1717. bool isPoint( RECT_STRUCT *prect, int x, int y )
  1718. {
  1719. if( x < prect->x || x > prect->x2 || y < prect->y || y > prect->y2 )
  1720. return false;
  1721. return true;
  1722. }
  1723. //-----------------------------------------------------
  1724. // Procedure: onMouseDown
  1725. //-----------------------------------------------------
  1726. void onMouseDown( EventMouseDown &e ) override
  1727. {
  1728. int i;
  1729. e.consumed = false;
  1730. if( !m_bInitialized )
  1731. return;
  1732. // check black keys first they are on top
  1733. for( i = 0; i < nKEYS; i++)
  1734. {
  1735. if( OctaveKeyDrawVects[ i ].nUsed == 4 && isPoint( &keyrects[ i ], (int)e.pos.x, (int)e.pos.y ) )
  1736. {
  1737. addtokeylist( i, e.button );
  1738. dirty = true;
  1739. e.consumed = true;
  1740. return;
  1741. }
  1742. }
  1743. // check white keys
  1744. for( i = 0; i < nKEYS; i++)
  1745. {
  1746. if( OctaveKeyDrawVects[ i ].nUsed != 4 && isPoint( &keyrects[ i ], (int)e.pos.x, (int)e.pos.y ) )
  1747. {
  1748. addtokeylist( i, e.button );
  1749. dirty = true;
  1750. e.consumed = true;
  1751. return;
  1752. }
  1753. }
  1754. return;
  1755. }
  1756. //-----------------------------------------------------
  1757. // Procedure: setkey
  1758. //-----------------------------------------------------
  1759. void setkey( int *pkey )
  1760. {
  1761. memset( m_bKeyOnList, 0, sizeof( m_bKeyOnList ) );
  1762. memset( m_KeySave, 0xFF, sizeof( m_KeySave ) );
  1763. m_nKeysOn = 0;
  1764. // build key list
  1765. for( int i = 0; i < m_MaxMultKeys; i++ )
  1766. {
  1767. if( pkey[ i ] != -1 )
  1768. {
  1769. m_nKeysOn++;
  1770. m_bKeyOnList[ pkey[ i ] ] = true;
  1771. m_KeySave[ i ] = pkey[ i ];
  1772. }
  1773. }
  1774. dirty = true;
  1775. }
  1776. //-----------------------------------------------------
  1777. // Procedure: setkeyhighlight
  1778. //-----------------------------------------------------
  1779. void setkeyhighlight( int key )
  1780. {
  1781. m_KeyOn = key;
  1782. dirty = true;
  1783. }
  1784. //-----------------------------------------------------
  1785. // Procedure: drawkey
  1786. //-----------------------------------------------------
  1787. void drawkey( NVGcontext *vg, int key, bool bOn )
  1788. {
  1789. int i;
  1790. if( !m_bInitialized )
  1791. return;
  1792. if( key < 0 || key >= nKEYS )
  1793. return;
  1794. if( bOn )
  1795. {
  1796. // hilite on
  1797. if( key == m_KeyOn )
  1798. nvgFillColor( vg, nvgRGBA( m_rgb_on.Col[ 2 ], m_rgb_on.Col[ 1 ], m_rgb_on.Col[ 0 ], 0x80 ) );
  1799. // normal on
  1800. else
  1801. nvgFillColor( vg, nvgRGB( m_rgb_on.Col[ 2 ], m_rgb_on.Col[ 1 ], m_rgb_on.Col[ 0 ] ) );
  1802. }
  1803. else
  1804. {
  1805. if( OctaveKeyDrawVects[ key ].nUsed == 4 )
  1806. nvgFillColor( vg, nvgRGB( m_rgb_black.Col[ 2 ], m_rgb_black.Col[ 1 ], m_rgb_black.Col[ 0 ] ) );
  1807. else
  1808. nvgFillColor( vg, nvgRGB( m_rgb_white.Col[ 2 ], m_rgb_white.Col[ 1 ], m_rgb_white.Col[ 0 ] ) );
  1809. }
  1810. // draw key
  1811. nvgBeginPath(vg);
  1812. for( i = 0; i < OctaveKeyDrawVects[ key ].nUsed; i++ )
  1813. {
  1814. if( i == 0 )
  1815. nvgMoveTo(vg, (float)OctaveKeyDrawVects[ key ].p[ i ].fx, (float)OctaveKeyDrawVects[ key ].p[ i ].fy );
  1816. else
  1817. nvgLineTo(vg, (float)OctaveKeyDrawVects[ key ].p[ i ].fx, (float)OctaveKeyDrawVects[ key ].p[ i ].fy );
  1818. }
  1819. nvgClosePath(vg);
  1820. nvgFill(vg);
  1821. }
  1822. //-----------------------------------------------------
  1823. // Procedure: draw
  1824. //-----------------------------------------------------
  1825. void draw( NVGcontext *vg ) override
  1826. {
  1827. int key;
  1828. for( key = 0; key < nKEYS; key++ )
  1829. drawkey( vg, key, false );
  1830. for( key = 0; key < m_MaxMultKeys; key++ )
  1831. {
  1832. if( m_KeySave[ key ] != -1 )
  1833. drawkey( vg, m_KeySave[ key ], true );
  1834. }
  1835. }
  1836. };
  1837. //-----------------------------------------------------
  1838. // Procedure: MySquareButton
  1839. //
  1840. //-----------------------------------------------------
  1841. struct MySquareButton : SVGSwitch, MomentarySwitch
  1842. {
  1843. MySquareButton()
  1844. {
  1845. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_square_button.svg")));
  1846. sw->wrap();
  1847. box.size = sw->box.size;
  1848. }
  1849. };
  1850. //-----------------------------------------------------
  1851. // Procedure: MySquareButton2
  1852. //
  1853. //-----------------------------------------------------
  1854. struct MySquareButton2 : SVGSwitch, MomentarySwitch
  1855. {
  1856. MySquareButton2()
  1857. {
  1858. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_Square_Button2.svg")));
  1859. sw->wrap();
  1860. box.size = sw->box.size;
  1861. }
  1862. };
  1863. //-----------------------------------------------------
  1864. // Procedure: PianoWhiteKey
  1865. //
  1866. //-----------------------------------------------------
  1867. struct PianoWhiteKey : SVGSwitch, ToggleSwitch
  1868. {
  1869. PianoWhiteKey()
  1870. {
  1871. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_WhiteKeyOff.svg")));
  1872. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_WhiteKeyOn.svg")));
  1873. sw->wrap();
  1874. box.size = sw->box.size;
  1875. }
  1876. };
  1877. //-----------------------------------------------------
  1878. // Procedure: PianoBlackKey
  1879. //
  1880. //-----------------------------------------------------
  1881. struct PianoBlackKey : SVGSwitch, ToggleSwitch
  1882. {
  1883. PianoBlackKey()
  1884. {
  1885. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_BlackKeyOff.svg")));
  1886. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_BlackKeyOn.svg")));
  1887. sw->wrap();
  1888. box.size = sw->box.size;
  1889. }
  1890. };
  1891. //-----------------------------------------------------
  1892. // Procedure: MyToggle1
  1893. //
  1894. //-----------------------------------------------------
  1895. struct MyToggle1 : SVGSwitch, ToggleSwitch
  1896. {
  1897. MyToggle1()
  1898. {
  1899. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_3p_vert_simple_01.svg")));
  1900. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_3p_vert_simple_02.svg")));
  1901. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_3p_vert_simple_03.svg")));
  1902. sw->wrap();
  1903. box.size = sw->box.size;
  1904. }
  1905. };
  1906. //-----------------------------------------------------
  1907. // Procedure: FilterSelectToggle
  1908. //
  1909. //-----------------------------------------------------
  1910. struct FilterSelectToggle : SVGSwitch, ToggleSwitch
  1911. {
  1912. FilterSelectToggle()
  1913. {
  1914. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_5p_filtersel_01.svg")));
  1915. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_5p_filtersel_02.svg")));
  1916. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_5p_filtersel_03.svg")));
  1917. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_5p_filtersel_04.svg")));
  1918. addFrame(SVG::load(assetPlugin(plugin,"res/mschack_5p_filtersel_05.svg")));
  1919. sw->wrap();
  1920. box.size = sw->box.size;
  1921. }
  1922. };
  1923. //-----------------------------------------------------
  1924. // Sliders
  1925. //
  1926. //-----------------------------------------------------
  1927. struct MySlider_01 : SVGFader
  1928. {
  1929. MySlider_01()
  1930. {
  1931. Vec margin = Vec(0, 0);
  1932. maxHandlePos = Vec(0, -4).plus(margin);
  1933. minHandlePos = Vec(0, 33).plus(margin);
  1934. background->svg = SVG::load(assetPlugin(plugin,"res/mschack_sliderBG_01.svg"));
  1935. background->wrap();
  1936. background->box.pos = margin;
  1937. box.size = background->box.size.plus(margin.mult(2));
  1938. handle->svg = SVG::load(assetPlugin(plugin,"res/mschack_sliderKNOB_01.svg"));
  1939. handle->wrap();
  1940. }
  1941. };
  1942. struct Slider02_10x15 : SVGFader
  1943. {
  1944. Slider02_10x15()
  1945. {
  1946. Vec margin = Vec(4, 0);
  1947. maxHandlePos = Vec(-3, 0).plus(margin);
  1948. minHandlePos = Vec(-3, 60).plus(margin);
  1949. background->svg = SVG::load(assetPlugin(plugin,"res/mschack_sliderBG_02.svg"));
  1950. background->wrap();
  1951. background->box.pos = margin;
  1952. box.size = background->box.size.plus(margin.mult(2));
  1953. handle->svg = SVG::load(assetPlugin(plugin,"res/mschack_Slider02_10x15.svg"));
  1954. handle->wrap();
  1955. }
  1956. };
  1957. //-----------------------------------------------------
  1958. // Procedure: MyPortInSmall
  1959. //
  1960. //-----------------------------------------------------
  1961. struct MyPortInSmall : SVGPort
  1962. {
  1963. MyPortInSmall()
  1964. {
  1965. background->svg = SVG::load(assetPlugin(plugin, "res/mschack_PortIn_small.svg" ) );
  1966. background->wrap();
  1967. box.size = background->box.size;
  1968. }
  1969. };
  1970. //-----------------------------------------------------
  1971. // Procedure: MyPortOutSmall
  1972. //
  1973. //-----------------------------------------------------
  1974. struct MyPortOutSmall : SVGPort
  1975. {
  1976. MyPortOutSmall()
  1977. {
  1978. background->svg = SVG::load(assetPlugin(plugin, "res/mschack_PortOut_small.svg" ) );
  1979. background->wrap();
  1980. box.size = background->box.size;
  1981. }
  1982. };
  1983. //-----------------------------------------------------
  1984. // Red1
  1985. //
  1986. //-----------------------------------------------------
  1987. struct Knob_Red1_20 : RoundKnob
  1988. {
  1989. Knob_Red1_20()
  1990. {
  1991. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Red1_20.svg" )));
  1992. }
  1993. };
  1994. struct Knob_Red1_15 : RoundKnob
  1995. {
  1996. Knob_Red1_15()
  1997. {
  1998. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Red1_15.svg" )));
  1999. }
  2000. };
  2001. //-----------------------------------------------------
  2002. // Purp1
  2003. //
  2004. //-----------------------------------------------------
  2005. struct Knob_Purp1_20 : RoundKnob
  2006. {
  2007. Knob_Purp1_20()
  2008. {
  2009. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Purp1_20.svg" )));
  2010. }
  2011. };
  2012. struct Knob_Purp1_15 : RoundKnob
  2013. {
  2014. Knob_Purp1_15()
  2015. {
  2016. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Purp1_15.svg" )));
  2017. }
  2018. };
  2019. //-----------------------------------------------------
  2020. // Green1
  2021. //
  2022. //-----------------------------------------------------
  2023. struct Knob_Green1_15 : RoundKnob
  2024. {
  2025. Knob_Green1_15()
  2026. {
  2027. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Green1_15.svg" )));
  2028. }
  2029. };
  2030. struct Knob_Green1_40 : RoundKnob
  2031. {
  2032. Knob_Green1_40()
  2033. {
  2034. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Green1_40.svg" )));
  2035. }
  2036. };
  2037. //-----------------------------------------------------
  2038. // Blue1
  2039. //
  2040. //-----------------------------------------------------
  2041. struct Knob_Blue1_26 : RoundKnob
  2042. {
  2043. Knob_Blue1_26()
  2044. {
  2045. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Blue1_26.svg" )));
  2046. }
  2047. };
  2048. //-----------------------------------------------------
  2049. // Blue2
  2050. //
  2051. //-----------------------------------------------------
  2052. struct Knob_Blue2_26 : RoundKnob
  2053. {
  2054. Knob_Blue2_26()
  2055. {
  2056. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Blue2_26.svg" )));
  2057. }
  2058. };
  2059. struct Knob_Blue2_26_Snap : RoundKnob
  2060. {
  2061. Knob_Blue2_26_Snap()
  2062. {
  2063. snap = true;
  2064. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Blue2_26.svg" )));
  2065. }
  2066. };
  2067. struct Knob_Blue2_15 : RoundKnob
  2068. {
  2069. Knob_Blue2_15()
  2070. {
  2071. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Blue2_15.svg" )));
  2072. }
  2073. };
  2074. struct Knob_Blue2_40 : RoundKnob
  2075. {
  2076. Knob_Blue2_40()
  2077. {
  2078. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Blue2_40.svg" )));
  2079. }
  2080. };
  2081. struct Knob_Blue2_56 : RoundKnob
  2082. {
  2083. Knob_Blue2_56()
  2084. {
  2085. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Blue2_56.svg" )));
  2086. //box.size = Vec(56, 56);
  2087. }
  2088. };
  2089. //-----------------------------------------------------
  2090. // Blue3
  2091. //
  2092. //-----------------------------------------------------
  2093. struct Knob_Blue3_20 : RoundKnob
  2094. {
  2095. Knob_Blue3_20()
  2096. {
  2097. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Blue3_20.svg" )));
  2098. }
  2099. };
  2100. struct Knob_Blue3_15 : RoundKnob
  2101. {
  2102. Knob_Blue3_15()
  2103. {
  2104. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Blue3_15.svg" )));
  2105. }
  2106. };
  2107. //-----------------------------------------------------
  2108. // Yellow1
  2109. //
  2110. //-----------------------------------------------------
  2111. struct Knob_Yellow1_26 : RoundKnob
  2112. {
  2113. Knob_Yellow1_26()
  2114. {
  2115. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Yellow1_26.svg" )));
  2116. }
  2117. };
  2118. struct Knob_Yellow1_15 : RoundKnob
  2119. {
  2120. Knob_Yellow1_15()
  2121. {
  2122. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Yellow1_15.svg" )));
  2123. }
  2124. };
  2125. //-----------------------------------------------------
  2126. // Yellow2
  2127. //
  2128. //-----------------------------------------------------
  2129. struct Knob_Yellow2_26 : RoundKnob
  2130. {
  2131. Knob_Yellow2_26()
  2132. {
  2133. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Yellow2_26.svg" )));
  2134. }
  2135. };
  2136. struct Knob_Yellow2_26_Snap : RoundKnob
  2137. {
  2138. Knob_Yellow2_26_Snap()
  2139. {
  2140. snap = true;
  2141. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Yellow2_26.svg" )));
  2142. }
  2143. };
  2144. struct Knob_Yellow2_40 : RoundKnob
  2145. {
  2146. Knob_Yellow2_40()
  2147. {
  2148. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Yellow2_40.svg" )));
  2149. }
  2150. };
  2151. struct Knob_Yellow2_56 : RoundKnob
  2152. {
  2153. Knob_Yellow2_56()
  2154. {
  2155. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Yellow2_56.svg" )));
  2156. }
  2157. };
  2158. struct Knob_Yellow2_56_Snap : RoundKnob
  2159. {
  2160. Knob_Yellow2_56_Snap()
  2161. {
  2162. snap = true;
  2163. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Yellow2_56.svg" )));
  2164. }
  2165. };
  2166. //-----------------------------------------------------
  2167. // Yellow3
  2168. //
  2169. //-----------------------------------------------------
  2170. struct Knob_Yellow3_15 : RoundKnob
  2171. {
  2172. Knob_Yellow3_15()
  2173. {
  2174. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Yellow3_15.svg" )));
  2175. }
  2176. };
  2177. struct Knob_Yellow3_20 : RoundKnob
  2178. {
  2179. Knob_Yellow3_20()
  2180. {
  2181. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Yellow3_20.svg" )));
  2182. }
  2183. };
  2184. struct Knob_Yellow3_20_Snap : RoundKnob
  2185. {
  2186. Knob_Yellow3_20_Snap()
  2187. {
  2188. snap = true;
  2189. setSVG(SVG::load(assetPlugin(plugin, "res/mschack_Knob_Yellow3_20.svg" )));
  2190. }
  2191. };