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.

408 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. #ifdef DGL_VULKAN
  35. #include "../dgl/Vulkan.hpp"
  36. typedef DGL_NAMESPACE::VulkanImage DemoImage;
  37. #endif
  38. START_NAMESPACE_DGL
  39. typedef ExampleImagesWidget<SubWidget, DemoImage> ExampleImagesSubWidget;
  40. typedef ExampleImagesWidget<TopLevelWidget, DemoImage> ExampleImagesTopLevelWidget;
  41. typedef ExampleImagesWidget<StandaloneWindow, DemoImage> ExampleImagesStandaloneWindow;
  42. // --------------------------------------------------------------------------------------------------------------------
  43. // Left side tab-like widget
  44. class LeftSideWidget : public SubWidget
  45. {
  46. public:
  47. #ifdef DGL_OPENGL
  48. static const int kPageCount = 5;
  49. #else
  50. static const int kPageCount = 4;
  51. #endif
  52. class Callback
  53. {
  54. public:
  55. virtual ~Callback() {}
  56. virtual void curPageChanged(int curPage) = 0;
  57. };
  58. LeftSideWidget(Widget* parent, Callback* const cb)
  59. : SubWidget(parent),
  60. callback(cb),
  61. curPage(0),
  62. curHover(-1)
  63. {
  64. using namespace DemoArtwork;
  65. img1.loadFromMemory(ico1Data, ico1Width, ico1Height, kImageFormatBGR);
  66. img2.loadFromMemory(ico2Data, ico2Width, ico2Height, kImageFormatBGR);
  67. img3.loadFromMemory(ico3Data, ico3Width, ico2Height, kImageFormatBGR);
  68. img4.loadFromMemory(ico4Data, ico4Width, ico4Height, kImageFormatBGR);
  69. #ifdef DGL_OPENGL
  70. img5.loadFromMemory(ico5Data, ico5Width, ico5Height, kImageFormatBGR);
  71. // for text
  72. nvg.loadSharedResources();
  73. #endif
  74. }
  75. protected:
  76. void onDisplay() override
  77. {
  78. const GraphicsContext& context(getGraphicsContext());
  79. const int iconSize = bgIcon.getWidth();
  80. Color(0.027f, 0.027f, 0.027f).setFor(context);
  81. Rectangle<uint>(0, 0, getSize()).draw(context);
  82. bgIcon.setY(curPage*iconSize + curPage*3);
  83. Color(0.129f, 0.129f, 0.129f).setFor(context);
  84. bgIcon.draw(context);
  85. Color(0.184f, 0.184f, 0.184f).setFor(context);
  86. bgIcon.drawOutline(context);
  87. if (curHover != curPage && curHover != -1)
  88. {
  89. Rectangle<int> rHover(1, curHover*iconSize + curHover*3, iconSize-2, iconSize-2);
  90. Color(0.071f, 0.071f, 0.071f).setFor(context);
  91. rHover.draw(context);
  92. Color(0.102f, 0.102f, 0.102f).setFor(context);
  93. rHover.drawOutline(context);
  94. }
  95. Color(0.184f, 0.184f, 0.184f).setFor(context);
  96. lineSep.draw(context);
  97. // reset color
  98. Color(1.0f, 1.0f, 1.0f, 1.0f).setFor(context, true);
  99. const int pad = iconSize/2 - DemoArtwork::ico1Width/2;
  100. img1.drawAt(context, pad, pad);
  101. img2.drawAt(context, pad, pad + 3 + iconSize);
  102. img3.drawAt(context, pad, pad + 6 + iconSize*2);
  103. img4.drawAt(context, pad, pad + 9 + iconSize*3);
  104. #ifdef DGL_OPENGL
  105. img5.drawAt(context, pad, pad + 12 + iconSize*4);
  106. // draw some text
  107. nvg.beginFrame(this);
  108. nvg.fontSize(23.0f);
  109. nvg.textAlign(NanoVG::ALIGN_LEFT|NanoVG::ALIGN_TOP);
  110. //nvg.textLineHeight(20.0f);
  111. nvg.fillColor(220,220,220,220);
  112. nvg.textBox(10, 420, iconSize, "Haha,", nullptr);
  113. nvg.textBox(15, 440, iconSize, "Look!", nullptr);
  114. nvg.endFrame();
  115. #endif
  116. }
  117. bool onMouse(const MouseEvent& ev) override
  118. {
  119. if (ev.button != 1 || ! ev.press)
  120. return false;
  121. if (! contains(ev.pos))
  122. return false;
  123. const int iconSize = bgIcon.getWidth();
  124. for (int i=0; i<kPageCount; ++i)
  125. {
  126. bgIcon.setY(i*iconSize + i*3);
  127. if (bgIcon.contains(ev.pos))
  128. {
  129. curPage = i;
  130. callback->curPageChanged(i);
  131. repaint();
  132. break;
  133. }
  134. }
  135. return true;
  136. }
  137. bool onMotion(const MotionEvent& ev) override
  138. {
  139. if (contains(ev.pos))
  140. {
  141. const int iconSize = bgIcon.getWidth();
  142. for (int i=0; i<kPageCount; ++i)
  143. {
  144. bgIcon.setY(i*iconSize + i*3);
  145. if (bgIcon.contains(ev.pos))
  146. {
  147. if (curHover == i)
  148. return true;
  149. curHover = i;
  150. repaint();
  151. return true;
  152. }
  153. }
  154. if (curHover == -1)
  155. return true;
  156. curHover = -1;
  157. repaint();
  158. return true;
  159. }
  160. else
  161. {
  162. if (curHover == -1)
  163. return false;
  164. curHover = -1;
  165. repaint();
  166. return true;
  167. }
  168. }
  169. void onResize(const ResizeEvent& ev) override
  170. {
  171. const uint width = ev.size.getWidth();
  172. const uint height = ev.size.getHeight();
  173. bgIcon.setWidth(width-4);
  174. bgIcon.setHeight(width-4);
  175. lineSep.setStartPos(width, 0);
  176. lineSep.setEndPos(width, height);
  177. }
  178. private:
  179. Callback* const callback;
  180. int curPage, curHover;
  181. Rectangle<double> bgIcon;
  182. Line<int> lineSep;
  183. DemoImage img1, img2, img3, img4, img5;
  184. #ifdef DGL_OPENGL
  185. // for text
  186. NanoVG nvg;
  187. #endif
  188. };
  189. // --------------------------------------------------------------------------------------------------------------------
  190. // Main Demo Window, having a left-side tab-like widget and main area for current widget
  191. class DemoWindow : public StandaloneWindow,
  192. public LeftSideWidget::Callback
  193. {
  194. static const int kSidebarWidth = 81;
  195. public:
  196. #ifdef DGL_CAIRO
  197. static constexpr const char* const kExampleWidgetName = "Demo - Cairo";
  198. #endif
  199. #ifdef DGL_OPENGL
  200. static constexpr const char* const kExampleWidgetName = "Demo - OpenGL";
  201. #endif
  202. #ifdef DGL_VULKAN
  203. static constexpr const char* const kExampleWidgetName = "Demo - Vulkan";
  204. #endif
  205. DemoWindow(Application& app)
  206. : StandaloneWindow(app),
  207. wColor(this),
  208. wImages(this),
  209. wRects(this),
  210. wShapes(this),
  211. #ifdef DGL_OPENGL
  212. wText(this),
  213. #endif
  214. wLeft(this, this),
  215. curWidget(nullptr)
  216. {
  217. wColor.hide();
  218. wImages.hide();
  219. wRects.hide();
  220. wShapes.hide();
  221. #ifdef DGL_OPENGL
  222. wText.hide();
  223. #endif
  224. wColor.setAbsoluteX(kSidebarWidth);
  225. wImages.setAbsoluteX(kSidebarWidth);
  226. wRects.setAbsoluteX(kSidebarWidth);
  227. wShapes.setAbsoluteX(kSidebarWidth);
  228. #ifdef DGL_OPENGL
  229. wText.setAbsoluteX(kSidebarWidth);
  230. #endif
  231. wLeft.setAbsolutePos(2, 2);
  232. curPageChanged(0);
  233. }
  234. protected:
  235. void curPageChanged(int curPage) override
  236. {
  237. if (curWidget != nullptr)
  238. curWidget->hide();
  239. switch (curPage)
  240. {
  241. case 0:
  242. curWidget = &wColor;
  243. break;
  244. case 1:
  245. curWidget = &wImages;
  246. break;
  247. case 2:
  248. curWidget = &wRects;
  249. break;
  250. case 3:
  251. curWidget = &wShapes;
  252. break;
  253. #ifdef DGL_OPENGL
  254. case 4:
  255. curWidget = &wText;
  256. break;
  257. #endif
  258. default:
  259. curWidget = nullptr;
  260. break;
  261. }
  262. if (curWidget != nullptr)
  263. curWidget->show();
  264. }
  265. void onDisplay() override
  266. {
  267. }
  268. void onReshape(uint width, uint height) override
  269. {
  270. StandaloneWindow::onReshape(width, height);
  271. if (width < kSidebarWidth)
  272. return;
  273. Size<uint> size(width-kSidebarWidth, height);
  274. wColor.setSize(size);
  275. wImages.setSize(size);
  276. wRects.setSize(size);
  277. wShapes.setSize(size);
  278. #ifdef DGL_OPENGL
  279. wText.setSize(size);
  280. #endif
  281. wLeft.setSize(kSidebarWidth-4, height-4);
  282. }
  283. private:
  284. ExampleColorSubWidget wColor;
  285. ExampleImagesSubWidget wImages;
  286. ExampleRectanglesSubWidget wRects;
  287. ExampleShapesSubWidget wShapes;
  288. #ifdef DGL_OPENGL
  289. ExampleTextSubWidget wText;
  290. #endif
  291. LeftSideWidget wLeft;
  292. Widget* curWidget;
  293. };
  294. // --------------------------------------------------------------------------------------------------------------------
  295. // Special handy function that runs a StandaloneWindow inside the function scope
  296. template <class ExampleWidgetStandaloneWindow>
  297. void createAndShowExampleWidgetStandaloneWindow(Application& app)
  298. {
  299. ExampleWidgetStandaloneWindow swin(app);
  300. swin.setResizable(true);
  301. swin.setSize(600, 500);
  302. swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName);
  303. swin.show();
  304. app.exec();
  305. }
  306. // --------------------------------------------------------------------------------------------------------------------
  307. END_NAMESPACE_DGL
  308. int main(int argc, char* argv[])
  309. {
  310. USE_NAMESPACE_DGL;
  311. using DGL_NAMESPACE::Window;
  312. Application app;
  313. if (argc > 1)
  314. {
  315. /**/ if (std::strcmp(argv[1], "color") == 0)
  316. createAndShowExampleWidgetStandaloneWindow<ExampleColorStandaloneWindow>(app);
  317. else if (std::strcmp(argv[1], "images") == 0)
  318. createAndShowExampleWidgetStandaloneWindow<ExampleImagesStandaloneWindow>(app);
  319. else if (std::strcmp(argv[1], "rectangles") == 0)
  320. createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app);
  321. else if (std::strcmp(argv[1], "shapes") == 0)
  322. createAndShowExampleWidgetStandaloneWindow<ExampleShapesStandaloneWindow>(app);
  323. #ifdef DGL_OPENGL
  324. else if (std::strcmp(argv[1], "text") == 0)
  325. createAndShowExampleWidgetStandaloneWindow<ExampleTextStandaloneWindow>(app);
  326. #endif
  327. else
  328. d_stderr2("Invalid demo mode, must be one of: color, images, rectangles or shapes");
  329. }
  330. else
  331. {
  332. createAndShowExampleWidgetStandaloneWindow<DemoWindow>(app);
  333. }
  334. return 0;
  335. }
  336. // --------------------------------------------------------------------------------------------------------------------