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.

app.hpp 12KB

7 years ago
7 years ago
6 years ago
6 years ago
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. #pragma once
  2. #include <vector>
  3. #include <jansson.h>
  4. #include "widgets.hpp"
  5. #include "ui.hpp"
  6. static const float SVG_DPI = 75.0;
  7. static const float MM_PER_IN = 25.4;
  8. #define CHECKMARK_STRING "✔"
  9. #define CHECKMARK(_cond) ((_cond) ? CHECKMARK_STRING : "")
  10. namespace rack {
  11. inline float in2px(float inches) {
  12. return inches * SVG_DPI;
  13. }
  14. inline Vec in2px(Vec inches) {
  15. return inches.mult(SVG_DPI);
  16. }
  17. inline float mm2px(float millimeters) {
  18. return millimeters * (SVG_DPI / MM_PER_IN);
  19. }
  20. inline Vec mm2px(Vec millimeters) {
  21. return millimeters.mult(SVG_DPI / MM_PER_IN);
  22. }
  23. struct Model;
  24. struct Module;
  25. struct Wire;
  26. struct RackWidget;
  27. struct ParamWidget;
  28. struct Port;
  29. struct SVGPanel;
  30. ////////////////////
  31. // module
  32. ////////////////////
  33. // A 1HPx3U module should be 15x380 pixels. Thus the width of a module should be a factor of 15.
  34. static const float RACK_GRID_WIDTH = 15;
  35. static const float RACK_GRID_HEIGHT = 380;
  36. static const Vec RACK_GRID_SIZE = Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  37. struct ModuleWidget : OpaqueWidget {
  38. Model *model = NULL;
  39. /** Owns the module pointer */
  40. Module *module = NULL;
  41. SVGPanel *panel = NULL;
  42. std::vector<Port*> inputs;
  43. std::vector<Port*> outputs;
  44. std::vector<ParamWidget*> params;
  45. ModuleWidget(Module *module);
  46. ~ModuleWidget();
  47. /** Convenience functions for adding special widgets (calls addChild()) */
  48. void addInput(Port *input);
  49. void addOutput(Port *output);
  50. void addParam(ParamWidget *param);
  51. void setPanel(std::shared_ptr<SVG> svg);
  52. virtual json_t *toJson();
  53. virtual void fromJson(json_t *rootJ);
  54. virtual void create();
  55. virtual void _delete();
  56. /** Disconnects cables from all ports
  57. Called when the user clicks Disconnect Cables in the context menu.
  58. */
  59. virtual void disconnect();
  60. /** Resets the parameters of the module and calls the Module's randomize().
  61. Called when the user clicks Initialize in the context menu.
  62. */
  63. virtual void reset();
  64. /** Deprecated */
  65. virtual void initialize() final {}
  66. /** Randomizes the parameters of the module and calls the Module's randomize().
  67. Called when the user clicks Randomize in the context menu.
  68. */
  69. virtual void randomize();
  70. virtual Menu *createContextMenu();
  71. void draw(NVGcontext *vg) override;
  72. void drawShadow(NVGcontext *vg);
  73. Vec dragPos;
  74. void onMouseDown(EventMouseDown &e) override;
  75. void onMouseMove(EventMouseMove &e) override;
  76. void onHoverKey(EventHoverKey &e) override;
  77. void onDragStart(EventDragStart &e) override;
  78. void onDragEnd(EventDragEnd &e) override;
  79. void onDragMove(EventDragMove &e) override;
  80. };
  81. struct WireWidget : OpaqueWidget {
  82. Port *outputPort = NULL;
  83. Port *inputPort = NULL;
  84. Port *hoveredOutputPort = NULL;
  85. Port *hoveredInputPort = NULL;
  86. Wire *wire = NULL;
  87. NVGcolor color;
  88. WireWidget();
  89. ~WireWidget();
  90. /** Synchronizes the plugged state of the widget to the owned wire */
  91. void updateWire();
  92. Vec getOutputPos();
  93. Vec getInputPos();
  94. json_t *toJson();
  95. void fromJson(json_t *rootJ);
  96. void draw(NVGcontext *vg) override;
  97. void drawPlugs(NVGcontext *vg);
  98. };
  99. struct WireContainer : TransparentWidget {
  100. WireWidget *activeWire = NULL;
  101. /** Takes ownership of `w` and adds it as a child if it isn't already */
  102. void setActiveWire(WireWidget *w);
  103. /** "Drops" the wire onto the port, making an engine connection if successful */
  104. void commitActiveWire();
  105. void removeTopWire(Port *port);
  106. void removeAllWires(Port *port);
  107. /** Returns the most recently added wire connected to the given Port, i.e. the top of the stack */
  108. WireWidget *getTopWire(Port *port);
  109. void draw(NVGcontext *vg) override;
  110. };
  111. struct RackWidget : OpaqueWidget {
  112. FramebufferWidget *rails;
  113. // Only put ModuleWidgets in here
  114. Widget *moduleContainer;
  115. // Only put WireWidgets in here
  116. WireContainer *wireContainer;
  117. std::string lastPath;
  118. Vec lastMousePos;
  119. RackWidget();
  120. ~RackWidget();
  121. /** Completely clear the rack's modules and wires */
  122. void clear();
  123. /** Clears the rack and loads the template patch */
  124. void reset();
  125. void openDialog();
  126. void saveDialog();
  127. void saveAsDialog();
  128. void savePatch(std::string filename);
  129. void loadPatch(std::string filename);
  130. json_t *toJson();
  131. void fromJson(json_t *rootJ);
  132. void addModule(ModuleWidget *m);
  133. /** Removes the module and transfers ownership to the caller */
  134. void deleteModule(ModuleWidget *m);
  135. void cloneModule(ModuleWidget *m);
  136. /** Sets a module's box if non-colliding. Returns true if set */
  137. bool requestModuleBox(ModuleWidget *m, Rect box);
  138. /** Moves a module to the closest non-colliding position */
  139. bool requestModuleBoxNearest(ModuleWidget *m, Rect box);
  140. void step() override;
  141. void draw(NVGcontext *vg) override;
  142. void onMouseMove(EventMouseMove &e) override;
  143. void onMouseDown(EventMouseDown &e) override;
  144. void onZoom(EventZoom &e) override;
  145. };
  146. struct RackRail : TransparentWidget {
  147. void draw(NVGcontext *vg) override;
  148. };
  149. struct AddModuleWindow : Window {
  150. Vec modulePos;
  151. AddModuleWindow();
  152. void step() override;
  153. };
  154. struct Panel : TransparentWidget {
  155. NVGcolor backgroundColor;
  156. std::shared_ptr<Image> backgroundImage;
  157. void draw(NVGcontext *vg) override;
  158. };
  159. struct SVGPanel : FramebufferWidget {
  160. void step() override;
  161. void setBackground(std::shared_ptr<SVG> svg);
  162. };
  163. ////////////////////
  164. // params
  165. ////////////////////
  166. struct CircularShadow : TransparentWidget {
  167. float blur = 0.0;
  168. void draw(NVGcontext *vg) override;
  169. };
  170. struct ParamWidget : OpaqueWidget, QuantityWidget {
  171. Module *module = NULL;
  172. int paramId;
  173. /** Used to momentarily disable value randomization
  174. To permanently disable or change randomization behavior, override the randomize() method instead of changing this.
  175. */
  176. bool randomizable = true;
  177. json_t *toJson();
  178. void fromJson(json_t *rootJ);
  179. virtual void reset();
  180. virtual void randomize();
  181. void onMouseDown(EventMouseDown &e) override;
  182. void onChange(EventChange &e) override;
  183. template <typename T = ParamWidget>
  184. static T *create(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) {
  185. T *o = Widget::create<T>(pos);
  186. o->module = module;
  187. o->paramId = paramId;
  188. o->setLimits(minValue, maxValue);
  189. o->setDefaultValue(defaultValue);
  190. return o;
  191. }
  192. };
  193. /** Implements vertical dragging behavior for ParamWidgets */
  194. struct Knob : ParamWidget {
  195. /** Snap to nearest integer while dragging */
  196. bool snap = false;
  197. /** Multiplier for mouse movement to adjust knob value */
  198. float speed = 1.0;
  199. float dragValue;
  200. void onDragStart(EventDragStart &e) override;
  201. void onDragMove(EventDragMove &e) override;
  202. void onDragEnd(EventDragEnd &e) override;
  203. /** Tell engine to smoothly vary this parameter */
  204. void onChange(EventChange &e) override;
  205. };
  206. struct SpriteKnob : virtual Knob, SpriteWidget {
  207. int minIndex, maxIndex, spriteCount;
  208. void step() override;
  209. };
  210. /** A knob which rotates an SVG and caches it in a framebuffer */
  211. struct SVGKnob : virtual Knob, FramebufferWidget {
  212. /** Angles in radians */
  213. float minAngle, maxAngle;
  214. /** Not owned */
  215. TransformWidget *tw;
  216. SVGWidget *sw;
  217. SVGKnob();
  218. void setSVG(std::shared_ptr<SVG> svg);
  219. void step() override;
  220. void onChange(EventChange &e) override;
  221. };
  222. struct SVGFader : Knob, FramebufferWidget {
  223. /** Intermediate positions will be interpolated between these positions */
  224. Vec minHandlePos, maxHandlePos;
  225. /** Not owned */
  226. SVGWidget *background;
  227. SVGWidget *handle;
  228. SVGFader();
  229. void step() override;
  230. void onChange(EventChange &e) override;
  231. };
  232. struct Switch : ParamWidget {
  233. };
  234. struct SVGSwitch : virtual Switch, FramebufferWidget {
  235. std::vector<std::shared_ptr<SVG>> frames;
  236. /** Not owned */
  237. SVGWidget *sw;
  238. SVGSwitch();
  239. /** Adds an SVG file to represent the next switch position */
  240. void addFrame(std::shared_ptr<SVG> svg);
  241. void onChange(EventChange &e) override;
  242. };
  243. /** A switch that cycles through each mechanical position */
  244. struct ToggleSwitch : virtual Switch {
  245. void onDragStart(EventDragStart &e) override {
  246. // Cycle through values
  247. // e.g. a range of [0.0, 3.0] would have modes 0, 1, 2, and 3.
  248. if (value >= maxValue)
  249. setValue(minValue);
  250. else
  251. setValue(value + 1.0);
  252. }
  253. };
  254. /** A switch that is turned on when held */
  255. struct MomentarySwitch : virtual Switch {
  256. /** Don't randomize state */
  257. void randomize() override {}
  258. void onDragStart(EventDragStart &e) override {
  259. setValue(maxValue);
  260. EventAction eAction;
  261. onAction(eAction);
  262. }
  263. void onDragEnd(EventDragEnd &e) override {
  264. setValue(minValue);
  265. }
  266. };
  267. ////////////////////
  268. // IO widgets
  269. ////////////////////
  270. struct AudioIO;
  271. struct MidiIO;
  272. struct AudioWidget : OpaqueWidget {
  273. /** Not owned */
  274. AudioIO *audioIO = NULL;
  275. void onMouseDown(EventMouseDown &e) override;
  276. };
  277. struct MidiWidget : OpaqueWidget {
  278. /** Not owned */
  279. MidiIO *midiIO = NULL;
  280. void onMouseDown(EventMouseDown &e) override;
  281. };
  282. ////////////////////
  283. // lights
  284. ////////////////////
  285. struct LightWidget : TransparentWidget {
  286. NVGcolor bgColor = nvgRGBf(0, 0, 0);
  287. NVGcolor color = nvgRGBf(1, 1, 1);
  288. void draw(NVGcontext *vg) override;
  289. virtual void drawLight(NVGcontext *vg);
  290. virtual void drawHalo(NVGcontext *vg);
  291. };
  292. /** Mixes a list of colors based on a list of brightness values */
  293. struct MultiLightWidget : LightWidget {
  294. std::vector<NVGcolor> baseColors;
  295. void addBaseColor(NVGcolor baseColor);
  296. /** Sets the color to a linear combination of the baseColors with the given weights */
  297. void setValues(const std::vector<float> &values);
  298. };
  299. /** A MultiLightWidget that points to a module's Light or a range of lights
  300. Will access firstLightId, firstLightId + 1, etc. for each added color
  301. */
  302. struct ModuleLightWidget : MultiLightWidget {
  303. Module *module = NULL;
  304. int firstLightId;
  305. void step() override;
  306. template <typename T = ModuleLightWidget>
  307. static T *create(Vec pos, Module *module, int firstLightId) {
  308. T *o = Widget::create<T>(pos);
  309. o->module = module;
  310. o->firstLightId = firstLightId;
  311. return o;
  312. }
  313. };
  314. ////////////////////
  315. // ports
  316. ////////////////////
  317. struct Port : OpaqueWidget {
  318. enum PortType {
  319. INPUT,
  320. OUTPUT
  321. };
  322. Module *module = NULL;
  323. PortType type = INPUT;
  324. int portId;
  325. MultiLightWidget *plugLight;
  326. Port();
  327. ~Port();
  328. void step() override;
  329. void draw(NVGcontext *vg) override;
  330. void onMouseDown(EventMouseDown &e) override;
  331. void onDragStart(EventDragStart &e) override;
  332. void onDragEnd(EventDragEnd &e) override;
  333. void onDragDrop(EventDragDrop &e) override;
  334. void onDragEnter(EventDragEnter &e) override;
  335. void onDragLeave(EventDragEnter &e) override;
  336. template <typename T = Port>
  337. static T *create(Vec pos, PortType type, Module *module, int portId) {
  338. T *o = Widget::create<T>(pos);
  339. o->type = type;
  340. o->module = module;
  341. o->portId = portId;
  342. return o;
  343. }
  344. };
  345. struct SVGPort : Port, FramebufferWidget {
  346. SVGWidget *background;
  347. SVGPort();
  348. void draw(NVGcontext *vg) override;
  349. };
  350. /** If you don't add these to your ModuleWidget, they will fall out of the rack... */
  351. struct SVGScrew : FramebufferWidget {
  352. SVGWidget *sw;
  353. SVGScrew();
  354. };
  355. ////////////////////
  356. // scene
  357. ////////////////////
  358. struct Toolbar : OpaqueWidget {
  359. Slider *wireOpacitySlider;
  360. Slider *wireTensionSlider;
  361. Slider *zoomSlider;
  362. RadioButton *cpuUsageButton;
  363. Toolbar();
  364. void draw(NVGcontext *vg) override;
  365. };
  366. struct PluginManagerWidget : Widget {
  367. Widget *loginWidget;
  368. Widget *manageWidget;
  369. Widget *downloadWidget;
  370. PluginManagerWidget();
  371. void step() override;
  372. };
  373. struct RackScrollWidget : ScrollWidget {
  374. void step() override;
  375. };
  376. struct RackScene : Scene {
  377. ScrollWidget *scrollWidget;
  378. ZoomWidget *zoomWidget;
  379. RackScene();
  380. void step() override;
  381. void draw(NVGcontext *vg) override;
  382. void onHoverKey(EventHoverKey &e) override;
  383. void onPathDrop(EventPathDrop &e) override;
  384. };
  385. ////////////////////
  386. // globals
  387. ////////////////////
  388. extern std::string gApplicationName;
  389. extern std::string gApplicationVersion;
  390. extern std::string gApiHost;
  391. // Easy access to "singleton" widgets
  392. extern RackScene *gRackScene;
  393. extern RackWidget *gRackWidget;
  394. extern Toolbar *gToolbar;
  395. void sceneInit();
  396. void sceneDestroy();
  397. json_t *colorToJson(NVGcolor color);
  398. NVGcolor jsonToColor(json_t *colorJ);
  399. } // namespace rack