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.

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