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.

1039 lines
29KB

  1. #pragma once
  2. #include <widget/FramebufferWidget.hpp>
  3. #include <widget/SvgWidget.hpp>
  4. #include <app/SvgKnob.hpp>
  5. #include <app/SvgSlider.hpp>
  6. #include <app/SvgPort.hpp>
  7. #include <app/ModuleLightWidget.hpp>
  8. #include <app/SvgSwitch.hpp>
  9. #include <app/SvgScrew.hpp>
  10. #include <app/AudioWidget.hpp>
  11. #include <app/MidiWidget.hpp>
  12. #include <asset.hpp>
  13. namespace rack {
  14. /** Library of Rack components: knobs, ports, lights, switches, buttons, etc.
  15. See LICENSE.md for legal details about using Rack component graphics in your Rack plugin.
  16. */
  17. namespace componentlibrary {
  18. using namespace window;
  19. ////////////////////
  20. // Color scheme
  21. ////////////////////
  22. static const NVGcolor SCHEME_BLACK_TRANSPARENT = nvgRGBA(0x00, 0x00, 0x00, 0x00);
  23. static const NVGcolor SCHEME_BLACK = nvgRGB(0x00, 0x00, 0x00);
  24. static const NVGcolor SCHEME_WHITE = nvgRGB(0xff, 0xff, 0xff);
  25. static const NVGcolor SCHEME_RED = nvgRGB(0xed, 0x2c, 0x24);
  26. static const NVGcolor SCHEME_ORANGE = nvgRGB(0xf2, 0xb1, 0x20);
  27. static const NVGcolor SCHEME_YELLOW = nvgRGB(0xf9, 0xdf, 0x1c);
  28. static const NVGcolor SCHEME_GREEN = nvgRGB(0x90, 0xc7, 0x3e);
  29. static const NVGcolor SCHEME_CYAN = nvgRGB(0x22, 0xe6, 0xef);
  30. static const NVGcolor SCHEME_BLUE = nvgRGB(0x29, 0xb2, 0xef);
  31. static const NVGcolor SCHEME_PURPLE = nvgRGB(0xd5, 0x2b, 0xed);
  32. static const NVGcolor SCHEME_LIGHT_GRAY = nvgRGB(0xe6, 0xe6, 0xe6);
  33. static const NVGcolor SCHEME_DARK_GRAY = nvgRGB(0x17, 0x17, 0x17);
  34. ////////////////////
  35. // Lights
  36. ////////////////////
  37. /*
  38. Many of these classes use CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
  39. To use a red light with its default base class for example, use `RedLight` or `TRedLight<>`. (They are synonymous.)
  40. Use the `TBase` template argument if you want a different base class.
  41. E.g. `RectangleLight<RedLight>`
  42. Although this paradigm might seem confusing at first, it ends up being extremely simple in your plugin code and perfect for "decorating" your classes with appearance traits and behavioral properties.
  43. For example, need a slider with a green LED? Just use
  44. createLightParamCentered<VCVLightSlider<GreenLight>>(...)
  45. */
  46. template <typename TBase = app::ModuleLightWidget>
  47. struct TSvgLight : TBase {
  48. widget::FramebufferWidget* fb;
  49. widget::SvgWidget* sw;
  50. TSvgLight() {
  51. fb = new widget::FramebufferWidget;
  52. this->addChild(fb);
  53. sw = new widget::SvgWidget;
  54. fb->addChild(sw);
  55. }
  56. void setSvg(std::shared_ptr<Svg> svg) {
  57. sw->setSvg(svg);
  58. fb->box.size = sw->box.size;
  59. this->box.size = sw->box.size;
  60. }
  61. };
  62. using SvgLight = TSvgLight<>;
  63. template <typename TBase = app::ModuleLightWidget>
  64. struct TGrayModuleLightWidget : TBase {
  65. TGrayModuleLightWidget() {
  66. this->bgColor = nvgRGBA(0x33, 0x33, 0x33, 0xff);
  67. this->borderColor = nvgRGBA(0, 0, 0, 53);
  68. }
  69. };
  70. using GrayModuleLightWidget = TGrayModuleLightWidget<>;
  71. template <typename TBase = GrayModuleLightWidget>
  72. struct TWhiteLight : TBase {
  73. TWhiteLight() {
  74. this->addBaseColor(SCHEME_WHITE);
  75. }
  76. };
  77. using WhiteLight = TWhiteLight<>;
  78. template <typename TBase = GrayModuleLightWidget>
  79. struct TRedLight : TBase {
  80. TRedLight() {
  81. this->addBaseColor(SCHEME_RED);
  82. }
  83. };
  84. using RedLight = TRedLight<>;
  85. template <typename TBase = GrayModuleLightWidget>
  86. struct TGreenLight : TBase {
  87. TGreenLight() {
  88. this->addBaseColor(SCHEME_GREEN);
  89. }
  90. };
  91. using GreenLight = TGreenLight<>;
  92. template <typename TBase = GrayModuleLightWidget>
  93. struct TBlueLight : TBase {
  94. TBlueLight() {
  95. this->addBaseColor(SCHEME_BLUE);
  96. }
  97. };
  98. using BlueLight = TBlueLight<>;
  99. template <typename TBase = GrayModuleLightWidget>
  100. struct TYellowLight : TBase {
  101. TYellowLight() {
  102. this->addBaseColor(SCHEME_YELLOW);
  103. }
  104. };
  105. using YellowLight = TYellowLight<>;
  106. /** Reads two adjacent lightIds, so `lightId` and `lightId + 1` must be defined */
  107. template <typename TBase = GrayModuleLightWidget>
  108. struct TGreenRedLight : TBase {
  109. TGreenRedLight() {
  110. this->addBaseColor(SCHEME_GREEN);
  111. this->addBaseColor(SCHEME_RED);
  112. }
  113. };
  114. using GreenRedLight = TGreenRedLight<>;
  115. template <typename TBase = GrayModuleLightWidget>
  116. struct TRedGreenBlueLight : TBase {
  117. TRedGreenBlueLight() {
  118. this->addBaseColor(SCHEME_RED);
  119. this->addBaseColor(SCHEME_GREEN);
  120. this->addBaseColor(SCHEME_BLUE);
  121. }
  122. };
  123. using RedGreenBlueLight = TRedGreenBlueLight<>;
  124. /** Based on the size of 5mm LEDs */
  125. template <typename TBase>
  126. struct LargeLight : TSvgLight<TBase> {
  127. LargeLight() {
  128. this->setSvg(Svg::load(asset::system("res/ComponentLibrary/LargeLight.svg")));
  129. }
  130. };
  131. /** Based on the size of 3mm LEDs */
  132. template <typename TBase>
  133. struct MediumLight : TSvgLight<TBase> {
  134. MediumLight() {
  135. this->setSvg(Svg::load(asset::system("res/ComponentLibrary/MediumLight.svg")));
  136. }
  137. };
  138. /** Based on the size of 2mm LEDs */
  139. template <typename TBase>
  140. struct SmallLight : TSvgLight<TBase> {
  141. SmallLight() {
  142. this->setSvg(Svg::load(asset::system("res/ComponentLibrary/SmallLight.svg")));
  143. }
  144. };
  145. /** Based on the size of 1mm LEDs */
  146. template <typename TBase>
  147. struct TinyLight : TSvgLight<TBase> {
  148. TinyLight() {
  149. this->setSvg(Svg::load(asset::system("res/ComponentLibrary/TinyLight.svg")));
  150. }
  151. };
  152. /** Based on the size of 5mm LEDs */
  153. template <typename TBase = GrayModuleLightWidget>
  154. struct LargeSimpleLight : TBase {
  155. LargeSimpleLight() {
  156. this->box.size = mm2px(math::Vec(5, 5));
  157. }
  158. };
  159. /** Based on the size of 3mm LEDs */
  160. template <typename TBase = GrayModuleLightWidget>
  161. struct MediumSimpleLight : TBase {
  162. MediumSimpleLight() {
  163. this->box.size = mm2px(math::Vec(3, 3));
  164. }
  165. };
  166. /** Based on the size of 2mm LEDs */
  167. template <typename TBase = GrayModuleLightWidget>
  168. struct SmallSimpleLight : TBase {
  169. SmallSimpleLight() {
  170. this->box.size = mm2px(math::Vec(2, 2));
  171. }
  172. };
  173. /** Based on the size of 1mm LEDs */
  174. template <typename TBase = GrayModuleLightWidget>
  175. struct TinySimpleLight : TBase {
  176. TinySimpleLight() {
  177. this->box.size = mm2px(math::Vec(1, 1));
  178. }
  179. };
  180. template <typename TBase>
  181. struct RectangleLight : TBase {
  182. void drawBackground(const widget::Widget::DrawArgs& args) override {
  183. // Derived from LightWidget::drawBackground()
  184. nvgBeginPath(args.vg);
  185. nvgRect(args.vg, 0, 0, this->box.size.x, this->box.size.y);
  186. // Background
  187. if (this->bgColor.a > 0.0) {
  188. nvgFillColor(args.vg, this->bgColor);
  189. nvgFill(args.vg);
  190. }
  191. // Border
  192. if (this->borderColor.a > 0.0) {
  193. nvgStrokeWidth(args.vg, 0.5);
  194. nvgStrokeColor(args.vg, this->borderColor);
  195. nvgStroke(args.vg);
  196. }
  197. }
  198. void drawLight(const widget::Widget::DrawArgs& args) override {
  199. // Derived from LightWidget::drawLight()
  200. // Foreground
  201. if (this->color.a > 0.0) {
  202. nvgBeginPath(args.vg);
  203. nvgRect(args.vg, 0, 0, this->box.size.x, this->box.size.y);
  204. nvgFillColor(args.vg, this->color);
  205. nvgFill(args.vg);
  206. }
  207. }
  208. };
  209. /** A light for displaying on top of VCVBezel. Must add a color by subclassing or templating. */
  210. template <typename TBase>
  211. struct VCVBezelLight : TBase {
  212. VCVBezelLight() {
  213. this->borderColor = color::BLACK_TRANSPARENT;
  214. this->bgColor = color::BLACK_TRANSPARENT;
  215. this->box.size = math::Vec(17.545, 17.545);
  216. }
  217. };
  218. template <typename TBase>
  219. using LEDBezelLight = VCVBezelLight<TBase>;
  220. /** A light to displayed over PB61303. Must add a color by subclassing or templating.
  221. */
  222. template <typename TBase>
  223. struct PB61303Light : TBase {
  224. PB61303Light() {
  225. this->bgColor = color::BLACK_TRANSPARENT;
  226. this->box.size = mm2px(math::Vec(9.0, 9.0));
  227. }
  228. };
  229. ////////////////////
  230. // Knobs
  231. ////////////////////
  232. struct RoundKnob : app::SvgKnob {
  233. widget::SvgWidget* bg;
  234. RoundKnob() {
  235. minAngle = -0.83 * M_PI;
  236. maxAngle = 0.83 * M_PI;
  237. bg = new widget::SvgWidget;
  238. fb->addChildBelow(bg, tw);
  239. }
  240. };
  241. struct RoundBlackKnob : RoundKnob {
  242. RoundBlackKnob() {
  243. setSvg(Svg::load(asset::system("res/ComponentLibrary/RoundBlackKnob.svg")));
  244. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/RoundBlackKnob-bg.svg")));
  245. }
  246. };
  247. struct RoundSmallBlackKnob : RoundKnob {
  248. RoundSmallBlackKnob() {
  249. setSvg(Svg::load(asset::system("res/ComponentLibrary/RoundSmallBlackKnob.svg")));
  250. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/RoundSmallBlackKnob-bg.svg")));
  251. }
  252. };
  253. struct RoundLargeBlackKnob : RoundKnob {
  254. RoundLargeBlackKnob() {
  255. setSvg(Svg::load(asset::system("res/ComponentLibrary/RoundLargeBlackKnob.svg")));
  256. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/RoundLargeBlackKnob-bg.svg")));
  257. }
  258. };
  259. struct RoundBigBlackKnob : RoundKnob {
  260. RoundBigBlackKnob() {
  261. setSvg(Svg::load(asset::system("res/ComponentLibrary/RoundBigBlackKnob.svg")));
  262. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/RoundBigBlackKnob-bg.svg")));
  263. }
  264. };
  265. struct RoundHugeBlackKnob : RoundKnob {
  266. RoundHugeBlackKnob() {
  267. setSvg(Svg::load(asset::system("res/ComponentLibrary/RoundHugeBlackKnob.svg")));
  268. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/RoundHugeBlackKnob-bg.svg")));
  269. }
  270. };
  271. struct RoundBlackSnapKnob : RoundBlackKnob {
  272. RoundBlackSnapKnob() {
  273. snap = true;
  274. }
  275. };
  276. struct Davies1900hKnob : app::SvgKnob {
  277. Davies1900hKnob() {
  278. minAngle = -0.83 * M_PI;
  279. maxAngle = 0.83 * M_PI;
  280. }
  281. };
  282. struct Davies1900hWhiteKnob : Davies1900hKnob {
  283. Davies1900hWhiteKnob() {
  284. setSvg(Svg::load(asset::system("res/ComponentLibrary/Davies1900hWhite.svg")));
  285. }
  286. };
  287. struct Davies1900hBlackKnob : Davies1900hKnob {
  288. Davies1900hBlackKnob() {
  289. setSvg(Svg::load(asset::system("res/ComponentLibrary/Davies1900hBlack.svg")));
  290. }
  291. };
  292. struct Davies1900hRedKnob : Davies1900hKnob {
  293. Davies1900hRedKnob() {
  294. setSvg(Svg::load(asset::system("res/ComponentLibrary/Davies1900hRed.svg")));
  295. }
  296. };
  297. struct Davies1900hLargeWhiteKnob : Davies1900hKnob {
  298. Davies1900hLargeWhiteKnob() {
  299. setSvg(Svg::load(asset::system("res/ComponentLibrary/Davies1900hLargeWhite.svg")));
  300. }
  301. };
  302. struct Davies1900hLargeBlackKnob : Davies1900hKnob {
  303. Davies1900hLargeBlackKnob() {
  304. setSvg(Svg::load(asset::system("res/ComponentLibrary/Davies1900hLargeBlack.svg")));
  305. }
  306. };
  307. struct Davies1900hLargeRedKnob : Davies1900hKnob {
  308. Davies1900hLargeRedKnob() {
  309. setSvg(Svg::load(asset::system("res/ComponentLibrary/Davies1900hLargeRed.svg")));
  310. }
  311. };
  312. struct Rogan : app::SvgKnob {
  313. widget::SvgWidget* bg;
  314. widget::SvgWidget* fg;
  315. Rogan() {
  316. minAngle = -0.83 * M_PI;
  317. maxAngle = 0.83 * M_PI;
  318. bg = new widget::SvgWidget;
  319. fb->addChildBelow(bg, tw);
  320. fg = new widget::SvgWidget;
  321. fb->addChildAbove(fg, tw);
  322. }
  323. };
  324. struct Rogan6PSWhite : Rogan {
  325. Rogan6PSWhite() {
  326. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan6PSWhite.svg")));
  327. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan6PS-bg.svg")));
  328. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan6PSWhite-fg.svg")));
  329. }
  330. };
  331. struct Rogan5PSGray : Rogan {
  332. Rogan5PSGray() {
  333. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan5PSGray.svg")));
  334. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan5PS-bg.svg")));
  335. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan5PSGray-fg.svg")));
  336. }
  337. };
  338. struct Rogan3PSBlue : Rogan {
  339. Rogan3PSBlue() {
  340. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PSBlue.svg")));
  341. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PS-bg.svg")));
  342. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PSBlue-fg.svg")));
  343. }
  344. };
  345. struct Rogan3PSRed : Rogan {
  346. Rogan3PSRed() {
  347. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PSRed.svg")));
  348. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PS-bg.svg")));
  349. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PSRed-fg.svg")));
  350. }
  351. };
  352. struct Rogan3PSGreen : Rogan {
  353. Rogan3PSGreen() {
  354. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PSGreen.svg")));
  355. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PS-bg.svg")));
  356. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PSGreen-fg.svg")));
  357. }
  358. };
  359. struct Rogan3PSWhite : Rogan {
  360. Rogan3PSWhite() {
  361. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PSWhite.svg")));
  362. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PS-bg.svg")));
  363. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PSWhite-fg.svg")));
  364. }
  365. };
  366. struct Rogan3PBlue : Rogan {
  367. Rogan3PBlue() {
  368. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PBlue.svg")));
  369. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3P-bg.svg")));
  370. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PBlue-fg.svg")));
  371. }
  372. };
  373. struct Rogan3PRed : Rogan {
  374. Rogan3PRed() {
  375. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PRed.svg")));
  376. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3P-bg.svg")));
  377. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PRed-fg.svg")));
  378. }
  379. };
  380. struct Rogan3PGreen : Rogan {
  381. Rogan3PGreen() {
  382. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PGreen.svg")));
  383. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3P-bg.svg")));
  384. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PGreen-fg.svg")));
  385. }
  386. };
  387. struct Rogan3PWhite : Rogan {
  388. Rogan3PWhite() {
  389. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PWhite.svg")));
  390. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3P-bg.svg")));
  391. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan3PWhite-fg.svg")));
  392. }
  393. };
  394. struct Rogan2SGray : Rogan {
  395. Rogan2SGray() {
  396. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2SGray.svg")));
  397. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2S-bg.svg")));
  398. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2SGray-fg.svg")));
  399. }
  400. };
  401. struct Rogan2PSBlue : Rogan {
  402. Rogan2PSBlue() {
  403. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PSBlue.svg")));
  404. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PS-bg.svg")));
  405. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PSBlue-fg.svg")));
  406. }
  407. };
  408. struct Rogan2PSRed : Rogan {
  409. Rogan2PSRed() {
  410. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PSRed.svg")));
  411. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PS-bg.svg")));
  412. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PSRed-fg.svg")));
  413. }
  414. };
  415. struct Rogan2PSGreen : Rogan {
  416. Rogan2PSGreen() {
  417. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PSGreen.svg")));
  418. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PS-bg.svg")));
  419. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PSGreen-fg.svg")));
  420. }
  421. };
  422. struct Rogan2PSWhite : Rogan {
  423. Rogan2PSWhite() {
  424. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PSWhite.svg")));
  425. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PS-bg.svg")));
  426. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PSWhite-fg.svg")));
  427. }
  428. };
  429. struct Rogan2PBlue : Rogan {
  430. Rogan2PBlue() {
  431. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PBlue.svg")));
  432. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2P-bg.svg")));
  433. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PBlue-fg.svg")));
  434. }
  435. };
  436. struct Rogan2PRed : Rogan {
  437. Rogan2PRed() {
  438. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PRed.svg")));
  439. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2P-bg.svg")));
  440. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PRed-fg.svg")));
  441. }
  442. };
  443. struct Rogan2PGreen : Rogan {
  444. Rogan2PGreen() {
  445. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PGreen.svg")));
  446. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2P-bg.svg")));
  447. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PGreen-fg.svg")));
  448. }
  449. };
  450. struct Rogan2PWhite : Rogan {
  451. Rogan2PWhite() {
  452. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PWhite.svg")));
  453. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2P-bg.svg")));
  454. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan2PWhite-fg.svg")));
  455. }
  456. };
  457. struct Rogan1PSBlue : Rogan {
  458. Rogan1PSBlue() {
  459. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PSBlue.svg")));
  460. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PS-bg.svg")));
  461. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PSBlue-fg.svg")));
  462. }
  463. };
  464. struct Rogan1PSRed : Rogan {
  465. Rogan1PSRed() {
  466. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PSRed.svg")));
  467. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PS-bg.svg")));
  468. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PSRed-fg.svg")));
  469. }
  470. };
  471. struct Rogan1PSGreen : Rogan {
  472. Rogan1PSGreen() {
  473. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PSGreen.svg")));
  474. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PS-bg.svg")));
  475. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PSGreen-fg.svg")));
  476. }
  477. };
  478. struct Rogan1PSWhite : Rogan {
  479. Rogan1PSWhite() {
  480. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PSWhite.svg")));
  481. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PS-bg.svg")));
  482. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PSWhite-fg.svg")));
  483. }
  484. };
  485. struct Rogan1PBlue : Rogan {
  486. Rogan1PBlue() {
  487. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PBlue.svg")));
  488. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1P-bg.svg")));
  489. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PBlue-fg.svg")));
  490. }
  491. };
  492. struct Rogan1PRed : Rogan {
  493. Rogan1PRed() {
  494. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PRed.svg")));
  495. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1P-bg.svg")));
  496. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PRed-fg.svg")));
  497. }
  498. };
  499. struct Rogan1PGreen : Rogan {
  500. Rogan1PGreen() {
  501. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PGreen.svg")));
  502. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1P-bg.svg")));
  503. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PGreen-fg.svg")));
  504. }
  505. };
  506. struct Rogan1PWhite : Rogan {
  507. Rogan1PWhite() {
  508. setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PWhite.svg")));
  509. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1P-bg.svg")));
  510. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Rogan1PWhite-fg.svg")));
  511. }
  512. };
  513. struct SynthTechAlco : app::SvgKnob {
  514. widget::SvgWidget* bg;
  515. widget::SvgWidget* fg;
  516. SynthTechAlco() {
  517. bg = new widget::SvgWidget;
  518. fb->addChildBelow(bg, tw);
  519. fg = new widget::SvgWidget;
  520. fb->addChildAbove(fg, tw);
  521. minAngle = -0.82 * M_PI;
  522. maxAngle = 0.82 * M_PI;
  523. setSvg(Svg::load(asset::system("res/ComponentLibrary/SynthTechAlco.svg")));
  524. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/SynthTechAlco-bg.svg")));
  525. fg->setSvg(Svg::load(asset::system("res/ComponentLibrary/SynthTechAlco-fg.svg")));
  526. }
  527. };
  528. struct Trimpot : app::SvgKnob {
  529. widget::SvgWidget* bg;
  530. Trimpot() {
  531. minAngle = -0.75 * M_PI;
  532. maxAngle = 0.75 * M_PI;
  533. bg = new widget::SvgWidget;
  534. fb->addChildBelow(bg, tw);
  535. setSvg(Svg::load(asset::system("res/ComponentLibrary/Trimpot.svg")));
  536. bg->setSvg(Svg::load(asset::system("res/ComponentLibrary/Trimpot-bg.svg")));
  537. }
  538. };
  539. struct BefacoBigKnob : app::SvgKnob {
  540. BefacoBigKnob() {
  541. minAngle = -0.75 * M_PI;
  542. maxAngle = 0.75 * M_PI;
  543. setSvg(Svg::load(asset::system("res/ComponentLibrary/BefacoBigKnob.svg")));
  544. }
  545. };
  546. struct BefacoBigSnapKnob : BefacoBigKnob {
  547. BefacoBigSnapKnob() {
  548. snap = true;
  549. }
  550. };
  551. struct BefacoTinyKnob : app::SvgKnob {
  552. BefacoTinyKnob() {
  553. minAngle = -0.75 * M_PI;
  554. maxAngle = 0.75 * M_PI;
  555. setSvg(Svg::load(asset::system("res/ComponentLibrary/BefacoTinyKnob.svg")));
  556. }
  557. };
  558. struct BefacoSlidePot : app::SvgSlider {
  559. BefacoSlidePot() {
  560. math::Vec margin = math::Vec(3.5, 3.5);
  561. maxHandlePos = math::Vec(-1, -2).plus(margin);
  562. minHandlePos = math::Vec(-1, 87).plus(margin);
  563. setBackgroundSvg(Svg::load(asset::system("res/ComponentLibrary/BefacoSlidePot.svg")));
  564. setHandleSvg(Svg::load(asset::system("res/ComponentLibrary/BefacoSlidePotHandle.svg")));
  565. background->box.pos = margin;
  566. box.size = background->box.size.plus(margin.mult(2));
  567. }
  568. };
  569. struct VCVSlider : app::SvgSlider {
  570. VCVSlider() {
  571. setBackgroundSvg(Svg::load(asset::system("res/ComponentLibrary/VCVSlider.svg")));
  572. setHandleSvg(Svg::load(asset::system("res/ComponentLibrary/VCVSliderHandle.svg")));
  573. setHandlePosCentered(
  574. math::Vec(19.84260/2, 76.53517 - 11.74218/2),
  575. math::Vec(19.84260/2, 0.0 + 11.74218/2)
  576. );
  577. }
  578. };
  579. using LEDSlider = VCVSlider;
  580. struct VCVSliderHorizontal : app::SvgSlider {
  581. VCVSliderHorizontal() {
  582. horizontal = true;
  583. // TODO Fix positions
  584. maxHandlePos = mm2px(math::Vec(22.078, 0.738).plus(math::Vec(0, 2)));
  585. minHandlePos = mm2px(math::Vec(0.738, 0.738).plus(math::Vec(0, 2)));
  586. // TODO Fix SVG
  587. setBackgroundSvg(Svg::load(asset::system("res/ComponentLibrary/VCVSliderHorizontal.svg")));
  588. }
  589. };
  590. using LEDSliderHorizontal = VCVSliderHorizontal;
  591. /** An SvgSlider with an attached light.
  592. Construct with createLightParamCentered() helper function.
  593. */
  594. template <typename TBase, typename TLightBase = RedLight>
  595. struct LightSlider : TBase {
  596. app::ModuleLightWidget* light;
  597. LightSlider() {
  598. light = new TLightBase;
  599. this->addChild(light);
  600. }
  601. app::ModuleLightWidget* getLight() {
  602. return light;
  603. }
  604. void step() override {
  605. TBase::step();
  606. // Move center of light to center of handle
  607. light->box.pos = this->handle->box.pos
  608. .plus(this->handle->box.size.div(2))
  609. .minus(light->box.size.div(2));
  610. }
  611. };
  612. template <typename TBase>
  613. struct VCVSliderLight : RectangleLight<TSvgLight<TBase>> {
  614. VCVSliderLight() {
  615. this->setSvg(Svg::load(asset::system("res/ComponentLibrary/VCVSliderLight.svg")));
  616. }
  617. };
  618. template <typename TBase>
  619. using LEDSliderLight = VCVSliderLight<TBase>;
  620. template <typename TLightBase = RedLight>
  621. struct VCVLightSlider : LightSlider<VCVSlider, VCVSliderLight<TLightBase>> {
  622. VCVLightSlider() {}
  623. };
  624. template <typename TLightBase = RedLight>
  625. using LEDLightSlider = VCVLightSlider<TLightBase>;
  626. /** Deprecated. Use VCVSliderLight with your preferred LightWidget. */
  627. struct LEDSliderGreen : VCVLightSlider<GreenLight> {};
  628. struct LEDSliderRed : VCVLightSlider<RedLight> {};
  629. struct LEDSliderYellow : VCVLightSlider<YellowLight> {};
  630. struct LEDSliderBlue : VCVLightSlider<BlueLight> {};
  631. struct LEDSliderWhite : VCVLightSlider<WhiteLight> {};
  632. template <typename TLightBase = RedLight>
  633. struct VCVLightSliderHorizontal : LightSlider<VCVSliderHorizontal, TLightBase> {
  634. VCVLightSliderHorizontal() {
  635. // TODO Fix positions
  636. this->light->box.size = mm2px(math::Vec(3.276, 1.524));
  637. // TODO Fix SVG
  638. this->setHandleSvg(Svg::load(asset::system("res/ComponentLibrary/VCVSliderHorizontalHandle.svg")));
  639. }
  640. };
  641. template <typename TLightBase = RedLight>
  642. using LEDLightSliderHorizontal = VCVLightSliderHorizontal<TLightBase>;
  643. ////////////////////
  644. // Ports
  645. ////////////////////
  646. struct PJ301MPort : app::SvgPort {
  647. PJ301MPort() {
  648. setSvg(Svg::load(asset::system("res/ComponentLibrary/PJ301M.svg")));
  649. }
  650. };
  651. struct PJ3410Port : app::SvgPort {
  652. PJ3410Port() {
  653. setSvg(Svg::load(asset::system("res/ComponentLibrary/PJ3410.svg")));
  654. }
  655. };
  656. struct CL1362Port : app::SvgPort {
  657. CL1362Port() {
  658. setSvg(Svg::load(asset::system("res/ComponentLibrary/CL1362.svg")));
  659. }
  660. };
  661. ////////////////////
  662. // Switches
  663. ////////////////////
  664. template <typename TSwitch>
  665. struct MomentarySwitch : TSwitch {
  666. MomentarySwitch() {
  667. this->momentary = true;
  668. }
  669. };
  670. struct NKK : app::SvgSwitch {
  671. NKK() {
  672. addFrame(Svg::load(asset::system("res/ComponentLibrary/NKK_0.svg")));
  673. addFrame(Svg::load(asset::system("res/ComponentLibrary/NKK_1.svg")));
  674. addFrame(Svg::load(asset::system("res/ComponentLibrary/NKK_2.svg")));
  675. }
  676. };
  677. struct CKSS : app::SvgSwitch {
  678. CKSS() {
  679. shadow->opacity = 0.0;
  680. addFrame(Svg::load(asset::system("res/ComponentLibrary/CKSS_0.svg")));
  681. addFrame(Svg::load(asset::system("res/ComponentLibrary/CKSS_1.svg")));
  682. }
  683. };
  684. struct CKSSThree : app::SvgSwitch {
  685. CKSSThree() {
  686. shadow->opacity = 0.0;
  687. addFrame(Svg::load(asset::system("res/ComponentLibrary/CKSSThree_0.svg")));
  688. addFrame(Svg::load(asset::system("res/ComponentLibrary/CKSSThree_1.svg")));
  689. addFrame(Svg::load(asset::system("res/ComponentLibrary/CKSSThree_2.svg")));
  690. }
  691. };
  692. struct CKSSThreeHorizontal : app::SvgSwitch {
  693. CKSSThreeHorizontal() {
  694. shadow->opacity = 0.0;
  695. addFrame(Svg::load(asset::system("res/ComponentLibrary/CKSSThreeHorizontal_0.svg")));
  696. addFrame(Svg::load(asset::system("res/ComponentLibrary/CKSSThreeHorizontal_1.svg")));
  697. addFrame(Svg::load(asset::system("res/ComponentLibrary/CKSSThreeHorizontal_2.svg")));
  698. }
  699. };
  700. struct CKD6 : app::SvgSwitch {
  701. CKD6() {
  702. momentary = true;
  703. addFrame(Svg::load(asset::system("res/ComponentLibrary/CKD6_0.svg")));
  704. addFrame(Svg::load(asset::system("res/ComponentLibrary/CKD6_1.svg")));
  705. }
  706. };
  707. struct TL1105 : app::SvgSwitch {
  708. TL1105() {
  709. momentary = true;
  710. addFrame(Svg::load(asset::system("res/ComponentLibrary/TL1105_0.svg")));
  711. addFrame(Svg::load(asset::system("res/ComponentLibrary/TL1105_1.svg")));
  712. }
  713. };
  714. struct VCVButton : app::SvgSwitch {
  715. VCVButton() {
  716. momentary = true;
  717. addFrame(Svg::load(asset::system("res/ComponentLibrary/VCVButton_0.svg")));
  718. addFrame(Svg::load(asset::system("res/ComponentLibrary/VCVButton_1.svg")));
  719. }
  720. };
  721. using LEDButton = VCVButton;
  722. struct VCVLatch : VCVButton {
  723. VCVLatch() {
  724. momentary = false;
  725. latch = true;
  726. }
  727. };
  728. /** Looks best with MediumSimpleLight<WhiteLight> or a color of your choice.
  729. */
  730. template <typename TLight>
  731. struct VCVLightButton : VCVButton {
  732. app::ModuleLightWidget* light;
  733. VCVLightButton() {
  734. light = new TLight;
  735. // Move center of light to center of box
  736. light->box.pos = box.size.div(2).minus(light->box.size.div(2));
  737. addChild(light);
  738. }
  739. app::ModuleLightWidget* getLight() {
  740. return light;
  741. }
  742. };
  743. template <typename TLight>
  744. using LEDLightButton = VCVLightButton<TLight>;
  745. template <typename TLight>
  746. struct VCVLightLatch : VCVLightButton<TLight> {
  747. VCVLightLatch() {
  748. this->momentary = false;
  749. this->latch = true;
  750. }
  751. };
  752. struct BefacoSwitch : app::SvgSwitch {
  753. BefacoSwitch() {
  754. addFrame(Svg::load(asset::system("res/ComponentLibrary/BefacoSwitch_0.svg")));
  755. addFrame(Svg::load(asset::system("res/ComponentLibrary/BefacoSwitch_1.svg")));
  756. addFrame(Svg::load(asset::system("res/ComponentLibrary/BefacoSwitch_2.svg")));
  757. }
  758. };
  759. struct BefacoPush : app::SvgSwitch {
  760. BefacoPush() {
  761. momentary = true;
  762. addFrame(Svg::load(asset::system("res/ComponentLibrary/BefacoPush_0.svg")));
  763. addFrame(Svg::load(asset::system("res/ComponentLibrary/BefacoPush_1.svg")));
  764. }
  765. };
  766. struct VCVBezel : app::SvgSwitch {
  767. VCVBezel() {
  768. momentary = true;
  769. addFrame(Svg::load(asset::system("res/ComponentLibrary/VCVBezel.svg")));
  770. }
  771. };
  772. using LEDBezel = VCVBezel;
  773. struct VCVBezelLatch : VCVBezel {
  774. VCVBezelLatch() {
  775. momentary = false;
  776. latch = true;
  777. }
  778. };
  779. template <typename TLightBase = WhiteLight>
  780. struct VCVLightBezel : VCVBezel {
  781. app::ModuleLightWidget* light;
  782. VCVLightBezel() {
  783. light = new VCVBezelLight<TLightBase>;
  784. // Move center of light to center of box
  785. light->box.pos = box.size.div(2).minus(light->box.size.div(2));
  786. addChild(light);
  787. }
  788. app::ModuleLightWidget* getLight() {
  789. return light;
  790. }
  791. };
  792. template <typename TLightBase = WhiteLight>
  793. using LEDLightBezel = VCVLightBezel<TLightBase>;
  794. template <typename TLightBase = WhiteLight>
  795. struct VCVLightBezelLatch : VCVLightBezel<TLightBase> {
  796. VCVLightBezelLatch() {
  797. this->momentary = false;
  798. this->latch = true;
  799. }
  800. };
  801. struct PB61303 : app::SvgSwitch {
  802. PB61303() {
  803. momentary = true;
  804. addFrame(Svg::load(asset::system("res/ComponentLibrary/PB61303.svg")));
  805. }
  806. };
  807. ////////////////////
  808. // Misc
  809. ////////////////////
  810. struct ScrewSilver : app::SvgScrew {
  811. ScrewSilver() {
  812. setSvg(Svg::load(asset::system("res/ComponentLibrary/ScrewSilver.svg")));
  813. }
  814. };
  815. struct ScrewBlack : app::SvgScrew {
  816. ScrewBlack() {
  817. setSvg(Svg::load(asset::system("res/ComponentLibrary/ScrewBlack.svg")));
  818. }
  819. };
  820. struct SegmentDisplay : widget::Widget {
  821. int lightsLen = 0;
  822. bool vertical = false;
  823. float margin = mm2px(0.5);
  824. void draw(const DrawArgs& args) override {
  825. // Background
  826. nvgBeginPath(args.vg);
  827. nvgRect(args.vg, 0, 0, box.size.x, box.size.y);
  828. nvgFillColor(args.vg, color::BLACK);
  829. nvgFill(args.vg);
  830. Widget::draw(args);
  831. }
  832. template <typename TLightBase = WhiteLight>
  833. void setLights(engine::Module* module, int firstLightId, int lightsLen) {
  834. clearChildren();
  835. this->lightsLen = lightsLen;
  836. float r = (vertical ? box.size.y : box.size.x) - margin;
  837. for (int i = 0; i < lightsLen; i++) {
  838. float p = float(i) / lightsLen;
  839. app::ModuleLightWidget* light = new RectangleLight<TLightBase>;
  840. if (vertical) {
  841. light->box.pos.y = p * r + margin;
  842. light->box.size.y = r / lightsLen - margin;
  843. light->box.size.x = box.size.x;
  844. }
  845. else {
  846. light->box.pos.x = p * r + margin;
  847. light->box.size.x = r / lightsLen - margin;
  848. light->box.size.y = box.size.y;
  849. }
  850. light->module = module;
  851. light->firstLightId = firstLightId;
  852. firstLightId += light->baseColors.size();
  853. addChild(light);
  854. }
  855. }
  856. };
  857. struct AudioButton_ADAT : app::AudioButton {
  858. AudioButton_ADAT() {
  859. addFrame(Svg::load(asset::system("res/ComponentLibrary/ADAT.svg")));
  860. shadow->opacity = 0.0;
  861. }
  862. };
  863. struct AudioButton_USB_B : app::AudioButton {
  864. AudioButton_USB_B() {
  865. addFrame(Svg::load(asset::system("res/ComponentLibrary/USB-B.svg")));
  866. shadow->opacity = 0.0;
  867. }
  868. };
  869. struct MidiButton_MIDI_DIN : app::MidiButton {
  870. MidiButton_MIDI_DIN() {
  871. addFrame(Svg::load(asset::system("res/ComponentLibrary/MIDI_DIN.svg")));
  872. shadow->opacity = 0.0;
  873. }
  874. };
  875. } // namespace componentlibrary
  876. } // namespace rack