DISTRHO Plugin Framework
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.

396 lines
11KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "tests.hpp"
  17. #include "widgets/ExampleColorWidget.hpp"
  18. #include "widgets/ExampleImagesWidget.hpp"
  19. #include "widgets/ExampleRectanglesWidget.hpp"
  20. #include "widgets/ExampleShapesWidget.hpp"
  21. #ifdef DGL_OPENGL
  22. #include "widgets/ExampleTextWidget.hpp"
  23. #endif
  24. #include "demo_res/DemoArtwork.cpp"
  25. #include "images_res/CatPics.cpp"
  26. #ifdef DGL_CAIRO
  27. #include "../dgl/Cairo.hpp"
  28. typedef DGL_NAMESPACE::CairoImage DemoImage;
  29. #endif
  30. #ifdef DGL_OPENGL
  31. #include "../dgl/OpenGL.hpp"
  32. typedef DGL_NAMESPACE::OpenGLImage DemoImage;
  33. #endif
  34. START_NAMESPACE_DGL
  35. typedef ExampleImagesWidget<SubWidget, DemoImage> ExampleImagesSubWidget;
  36. typedef ExampleImagesWidget<TopLevelWidget, DemoImage> ExampleImagesTopLevelWidget;
  37. typedef ExampleImagesWidget<StandaloneWindow, DemoImage> ExampleImagesStandaloneWindow;
  38. // --------------------------------------------------------------------------------------------------------------------
  39. // Left side tab-like widget
  40. class LeftSideWidget : public SubWidget
  41. {
  42. public:
  43. #ifdef DGL_OPENGL
  44. static const int kPageCount = 5;
  45. #else
  46. static const int kPageCount = 4;
  47. #endif
  48. class Callback
  49. {
  50. public:
  51. virtual ~Callback() {}
  52. virtual void curPageChanged(int curPage) = 0;
  53. };
  54. LeftSideWidget(Widget* parent, Callback* const cb)
  55. : SubWidget(parent),
  56. callback(cb),
  57. curPage(0),
  58. curHover(-1)
  59. {
  60. using namespace DemoArtwork;
  61. img1.loadFromMemory(ico1Data, ico1Width, ico1Height, kImageFormatBGR);
  62. img2.loadFromMemory(ico2Data, ico2Width, ico2Height, kImageFormatBGR);
  63. img3.loadFromMemory(ico3Data, ico3Width, ico2Height, kImageFormatBGR);
  64. img4.loadFromMemory(ico4Data, ico4Width, ico4Height, kImageFormatBGR);
  65. #ifdef DGL_OPENGL
  66. img5.loadFromMemory(ico5Data, ico5Width, ico5Height, kImageFormatBGR);
  67. // for text
  68. nvg.loadSharedResources();
  69. #endif
  70. }
  71. protected:
  72. void onDisplay() override
  73. {
  74. const GraphicsContext& context(getGraphicsContext());
  75. const int iconSize = bgIcon.getWidth();
  76. Color(0.027f, 0.027f, 0.027f).setFor(context);
  77. Rectangle<uint>(0, 0, getSize()).draw(context);
  78. bgIcon.setY(curPage*iconSize + curPage*3);
  79. Color(0.129f, 0.129f, 0.129f).setFor(context);
  80. bgIcon.draw(context);
  81. Color(0.184f, 0.184f, 0.184f).setFor(context);
  82. bgIcon.drawOutline(context);
  83. if (curHover != curPage && curHover != -1)
  84. {
  85. Rectangle<int> rHover(1, curHover*iconSize + curHover*3, iconSize-2, iconSize-2);
  86. Color(0.071f, 0.071f, 0.071f).setFor(context);
  87. rHover.draw(context);
  88. Color(0.102f, 0.102f, 0.102f).setFor(context);
  89. rHover.drawOutline(context);
  90. }
  91. Color(0.184f, 0.184f, 0.184f).setFor(context);
  92. lineSep.draw(context);
  93. // reset color
  94. Color(1.0f, 1.0f, 1.0f, 1.0f).setFor(context, true);
  95. const int pad = iconSize/2 - DemoArtwork::ico1Width/2;
  96. img1.drawAt(context, pad, pad);
  97. img2.drawAt(context, pad, pad + 3 + iconSize);
  98. img3.drawAt(context, pad, pad + 6 + iconSize*2);
  99. img4.drawAt(context, pad, pad + 9 + iconSize*3);
  100. #ifdef DGL_OPENGL
  101. img5.drawAt(context, pad, pad + 12 + iconSize*4);
  102. // draw some text
  103. nvg.beginFrame(this);
  104. nvg.fontSize(23.0f);
  105. nvg.textAlign(NanoVG::ALIGN_LEFT|NanoVG::ALIGN_TOP);
  106. //nvg.textLineHeight(20.0f);
  107. nvg.fillColor(220,220,220,220);
  108. nvg.textBox(10, 420, iconSize, "Haha,", nullptr);
  109. nvg.textBox(15, 440, iconSize, "Look!", nullptr);
  110. nvg.endFrame();
  111. #endif
  112. }
  113. bool onMouse(const MouseEvent& ev) override
  114. {
  115. if (ev.button != 1 || ! ev.press)
  116. return false;
  117. if (! contains(ev.pos))
  118. return false;
  119. const int iconSize = bgIcon.getWidth();
  120. for (int i=0; i<kPageCount; ++i)
  121. {
  122. bgIcon.setY(i*iconSize + i*3);
  123. if (bgIcon.contains(ev.pos))
  124. {
  125. curPage = i;
  126. callback->curPageChanged(i);
  127. repaint();
  128. break;
  129. }
  130. }
  131. return true;
  132. }
  133. bool onMotion(const MotionEvent& ev) override
  134. {
  135. if (contains(ev.pos))
  136. {
  137. const int iconSize = bgIcon.getWidth();
  138. for (int i=0; i<kPageCount; ++i)
  139. {
  140. bgIcon.setY(i*iconSize + i*3);
  141. if (bgIcon.contains(ev.pos))
  142. {
  143. if (curHover == i)
  144. return true;
  145. curHover = i;
  146. repaint();
  147. return true;
  148. }
  149. }
  150. if (curHover == -1)
  151. return true;
  152. curHover = -1;
  153. repaint();
  154. return true;
  155. }
  156. else
  157. {
  158. if (curHover == -1)
  159. return false;
  160. curHover = -1;
  161. repaint();
  162. return true;
  163. }
  164. }
  165. void onResize(const ResizeEvent& ev) override
  166. {
  167. const uint width = ev.size.getWidth();
  168. const uint height = ev.size.getHeight();
  169. bgIcon.setWidth(width-4);
  170. bgIcon.setHeight(width-4);
  171. lineSep.setStartPos(width, 0);
  172. lineSep.setEndPos(width, height);
  173. }
  174. private:
  175. Callback* const callback;
  176. int curPage, curHover;
  177. Rectangle<double> bgIcon;
  178. Line<int> lineSep;
  179. DemoImage img1, img2, img3, img4, img5;
  180. #ifdef DGL_OPENGL
  181. // for text
  182. NanoVG nvg;
  183. #endif
  184. };
  185. // --------------------------------------------------------------------------------------------------------------------
  186. // Main Demo Window, having a left-side tab-like widget and main area for current widget
  187. class DemoWindow : public StandaloneWindow,
  188. public LeftSideWidget::Callback
  189. {
  190. static const int kSidebarWidth = 81;
  191. public:
  192. static constexpr const char* const kExampleWidgetName = "Demo";
  193. DemoWindow(Application& app)
  194. : StandaloneWindow(app),
  195. wColor(this),
  196. wImages(this),
  197. wRects(this),
  198. wShapes(this),
  199. #ifdef DGL_OPENGL
  200. wText(this),
  201. #endif
  202. wLeft(this, this),
  203. curWidget(nullptr)
  204. {
  205. wColor.hide();
  206. wImages.hide();
  207. wRects.hide();
  208. wShapes.hide();
  209. #ifdef DGL_OPENGL
  210. wText.hide();
  211. #endif
  212. wColor.setAbsoluteX(kSidebarWidth);
  213. wImages.setAbsoluteX(kSidebarWidth);
  214. wRects.setAbsoluteX(kSidebarWidth);
  215. wShapes.setAbsoluteX(kSidebarWidth);
  216. #ifdef DGL_OPENGL
  217. wText.setAbsoluteX(kSidebarWidth);
  218. #endif
  219. wLeft.setAbsolutePos(2, 2);
  220. curPageChanged(0);
  221. }
  222. protected:
  223. void curPageChanged(int curPage) override
  224. {
  225. if (curWidget != nullptr)
  226. curWidget->hide();
  227. switch (curPage)
  228. {
  229. case 0:
  230. curWidget = &wColor;
  231. break;
  232. case 1:
  233. curWidget = &wImages;
  234. break;
  235. case 2:
  236. curWidget = &wRects;
  237. break;
  238. case 3:
  239. curWidget = &wShapes;
  240. break;
  241. #ifdef DGL_OPENGL
  242. case 4:
  243. curWidget = &wText;
  244. break;
  245. #endif
  246. default:
  247. curWidget = nullptr;
  248. break;
  249. }
  250. if (curWidget != nullptr)
  251. curWidget->show();
  252. }
  253. void onDisplay() override
  254. {
  255. }
  256. void onReshape(uint width, uint height) override
  257. {
  258. StandaloneWindow::onReshape(width, height);
  259. if (width < kSidebarWidth)
  260. return;
  261. Size<uint> size(width-kSidebarWidth, height);
  262. wColor.setSize(size);
  263. wImages.setSize(size);
  264. wRects.setSize(size);
  265. wShapes.setSize(size);
  266. #ifdef DGL_OPENGL
  267. wText.setSize(size);
  268. #endif
  269. wLeft.setSize(kSidebarWidth-4, height-4);
  270. }
  271. private:
  272. ExampleColorSubWidget wColor;
  273. ExampleImagesSubWidget wImages;
  274. ExampleRectanglesSubWidget wRects;
  275. ExampleShapesSubWidget wShapes;
  276. #ifdef DGL_OPENGL
  277. ExampleTextSubWidget wText;
  278. #endif
  279. LeftSideWidget wLeft;
  280. Widget* curWidget;
  281. };
  282. // --------------------------------------------------------------------------------------------------------------------
  283. // Special handy function that runs a StandaloneWindow inside the function scope
  284. template <class ExampleWidgetStandaloneWindow>
  285. void createAndShowExampleWidgetStandaloneWindow(Application& app)
  286. {
  287. ExampleWidgetStandaloneWindow swin(app);
  288. swin.setResizable(true);
  289. swin.setSize(600, 500);
  290. swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName);
  291. swin.show();
  292. app.exec();
  293. }
  294. // --------------------------------------------------------------------------------------------------------------------
  295. END_NAMESPACE_DGL
  296. int main(int argc, char* argv[])
  297. {
  298. USE_NAMESPACE_DGL;
  299. using DGL_NAMESPACE::Window;
  300. Application app;
  301. if (argc > 1)
  302. {
  303. /**/ if (std::strcmp(argv[1], "color") == 0)
  304. createAndShowExampleWidgetStandaloneWindow<ExampleColorStandaloneWindow>(app);
  305. else if (std::strcmp(argv[1], "images") == 0)
  306. createAndShowExampleWidgetStandaloneWindow<ExampleImagesStandaloneWindow>(app);
  307. else if (std::strcmp(argv[1], "rectangles") == 0)
  308. createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app);
  309. else if (std::strcmp(argv[1], "shapes") == 0)
  310. createAndShowExampleWidgetStandaloneWindow<ExampleShapesStandaloneWindow>(app);
  311. #ifdef DGL_OPENGL
  312. else if (std::strcmp(argv[1], "text") == 0)
  313. createAndShowExampleWidgetStandaloneWindow<ExampleTextStandaloneWindow>(app);
  314. #endif
  315. else
  316. d_stderr2("Invalid demo mode, must be one of: color, rectangles, shapes");
  317. }
  318. else
  319. {
  320. createAndShowExampleWidgetStandaloneWindow<DemoWindow>(app);
  321. }
  322. return 0;
  323. }
  324. // --------------------------------------------------------------------------------------------------------------------