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.

938 lines
27KB

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