Demo.cpp (13054B)
1 /* 2 * DISTRHO Plugin Framework (DPF) 3 * Copyright (C) 2012-2022 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 17 #include "tests.hpp" 18 19 #include "widgets/ExampleColorWidget.hpp" 20 #include "widgets/ExampleImagesWidget.hpp" 21 #include "widgets/ExampleRectanglesWidget.hpp" 22 #include "widgets/ExampleShapesWidget.hpp" 23 #ifdef DGL_OPENGL 24 #include "widgets/ExampleTextWidget.hpp" 25 #endif 26 #include "widgets/ResizeHandle.hpp" 27 28 #include "demo_res/DemoArtwork.cpp" 29 #include "images_res/CatPics.cpp" 30 31 #ifdef DGL_CAIRO 32 #include "../dgl/Cairo.hpp" 33 typedef DGL_NAMESPACE::CairoImage DemoImage; 34 #endif 35 #ifdef DGL_OPENGL 36 #include "../dgl/OpenGL.hpp" 37 typedef DGL_NAMESPACE::OpenGLImage DemoImage; 38 #endif 39 #ifdef DGL_VULKAN 40 #include "../dgl/Vulkan.hpp" 41 typedef DGL_NAMESPACE::VulkanImage DemoImage; 42 #endif 43 44 START_NAMESPACE_DGL 45 46 // Partial specialization is not allowed in C++, so we need to define these here 47 template<> inline 48 ExampleImagesWidget<SubWidget, DemoImage>::ExampleImagesWidget(Widget* const parentWidget) 49 : SubWidget(parentWidget) { init(parentWidget->getApp()); } 50 51 template<> inline 52 ExampleImagesWidget<TopLevelWidget, DemoImage>::ExampleImagesWidget(Window& windowToMapTo) 53 : TopLevelWidget(windowToMapTo) { init(windowToMapTo.getApp()); } 54 55 template<> 56 ExampleImagesWidget<StandaloneWindow, DemoImage>::ExampleImagesWidget(Application& app) 57 : StandaloneWindow(app) { init(app); done(); } 58 59 typedef ExampleImagesWidget<SubWidget, DemoImage> ExampleImagesSubWidget; 60 typedef ExampleImagesWidget<TopLevelWidget, DemoImage> ExampleImagesTopLevelWidget; 61 typedef ExampleImagesWidget<StandaloneWindow, DemoImage> ExampleImagesStandaloneWindow; 62 63 // -------------------------------------------------------------------------------------------------------------------- 64 // Left side tab-like widget 65 66 class LeftSideWidget : public SubWidget 67 { 68 public: 69 #ifdef DGL_OPENGL 70 static const int kPageCount = 5; 71 #else 72 static const int kPageCount = 4; 73 #endif 74 75 class Callback 76 { 77 public: 78 virtual ~Callback() {} 79 virtual void curPageChanged(int curPage) = 0; 80 }; 81 82 LeftSideWidget(Widget* parent, Callback* const cb) 83 : SubWidget(parent), 84 callback(cb), 85 curPage(0), 86 curHover(-1) 87 { 88 89 using namespace DemoArtwork; 90 img1.loadFromMemory(ico1Data, ico1Width, ico1Height, kImageFormatBGR); 91 img2.loadFromMemory(ico2Data, ico2Width, ico2Height, kImageFormatBGR); 92 img3.loadFromMemory(ico3Data, ico3Width, ico2Height, kImageFormatBGR); 93 img4.loadFromMemory(ico4Data, ico4Width, ico4Height, kImageFormatBGR); 94 95 #ifdef DGL_OPENGL 96 img5.loadFromMemory(ico5Data, ico5Width, ico5Height, kImageFormatBGR); 97 98 // for text 99 nvg.loadSharedResources(); 100 #endif 101 } 102 103 protected: 104 void onDisplay() override 105 { 106 const GraphicsContext& context(getGraphicsContext()); 107 const double scaleFactor = getWindow().getScaleFactor(); 108 const int iconSize = bgIcon.getWidth(); 109 110 Color(0.027f, 0.027f, 0.027f).setFor(context); 111 Rectangle<uint>(0, 0, getSize()).draw(context); 112 113 bgIcon.setY(curPage * iconSize + curPage * 3 * scaleFactor); 114 115 Color(0.129f, 0.129f, 0.129f).setFor(context); 116 bgIcon.draw(context); 117 118 Color(0.184f, 0.184f, 0.184f).setFor(context); 119 bgIcon.drawOutline(context); 120 121 if (curHover != curPage && curHover != -1) 122 { 123 Rectangle<int> rHover(1 * scaleFactor, curHover * iconSize + curHover * 3 * scaleFactor, 124 iconSize - 2 * scaleFactor, iconSize - 2 * scaleFactor); 125 126 Color(0.071f, 0.071f, 0.071f).setFor(context); 127 rHover.draw(context); 128 129 Color(0.102f, 0.102f, 0.102f).setFor(context); 130 rHover.drawOutline(context); 131 } 132 133 Color(0.184f, 0.184f, 0.184f).setFor(context); 134 lineSep.draw(context); 135 136 // reset color 137 Color(1.0f, 1.0f, 1.0f, 1.0f).setFor(context, true); 138 139 const int pad = iconSize/2 - DemoArtwork::ico1Width/2; 140 141 img1.drawAt(context, pad, pad); 142 img2.drawAt(context, pad, pad + 3 + iconSize); 143 img3.drawAt(context, pad, pad + 6 + iconSize*2); 144 img4.drawAt(context, pad, pad + 9 + iconSize*3); 145 146 #ifdef DGL_OPENGL 147 img5.drawAt(context, pad, pad + 12 + iconSize*4); 148 149 // draw some text 150 nvg.beginFrame(this); 151 152 nvg.fontSize(23.0f * scaleFactor); 153 nvg.textAlign(NanoVG::ALIGN_LEFT|NanoVG::ALIGN_TOP); 154 //nvg.textLineHeight(20.0f); 155 156 nvg.fillColor(220,220,220,220); 157 nvg.textBox(10 * scaleFactor, 420 * scaleFactor, iconSize, "Haha,", nullptr); 158 nvg.textBox(15 * scaleFactor, 440 * scaleFactor, iconSize, "Look!", nullptr); 159 160 nvg.endFrame(); 161 #endif 162 } 163 164 bool onMouse(const MouseEvent& ev) override 165 { 166 if (ev.button != 1 || ! ev.press) 167 return false; 168 if (! contains(ev.pos)) 169 return false; 170 171 const int iconSize = bgIcon.getWidth(); 172 173 for (int i=0; i<kPageCount; ++i) 174 { 175 bgIcon.setY(i*iconSize + i*3); 176 177 if (bgIcon.contains(ev.pos)) 178 { 179 curPage = i; 180 callback->curPageChanged(i); 181 repaint(); 182 break; 183 } 184 } 185 186 return true; 187 } 188 189 bool onMotion(const MotionEvent& ev) override 190 { 191 if (contains(ev.pos)) 192 { 193 const int iconSize = bgIcon.getWidth(); 194 195 for (int i=0; i<kPageCount; ++i) 196 { 197 bgIcon.setY(i*iconSize + i*3); 198 199 if (bgIcon.contains(ev.pos)) 200 { 201 if (curHover == i) 202 return true; 203 204 curHover = i; 205 repaint(); 206 return true; 207 } 208 } 209 210 if (curHover == -1) 211 return true; 212 213 curHover = -1; 214 repaint(); 215 return true; 216 } 217 else 218 { 219 if (curHover == -1) 220 return false; 221 222 curHover = -1; 223 repaint(); 224 return true; 225 } 226 } 227 228 void onResize(const ResizeEvent& ev) override 229 { 230 const uint width = ev.size.getWidth(); 231 const uint height = ev.size.getHeight(); 232 const double scaleFactor = getWindow().getScaleFactor(); 233 234 bgIcon.setWidth(width - 4 * scaleFactor); 235 bgIcon.setHeight(width - 4 * scaleFactor); 236 237 lineSep.setStartPos(width, 0); 238 lineSep.setEndPos(width, height); 239 } 240 241 private: 242 Callback* const callback; 243 int curPage, curHover; 244 Rectangle<double> bgIcon; 245 Line<int> lineSep; 246 DemoImage img1, img2, img3, img4, img5; 247 248 #ifdef DGL_OPENGL 249 // for text 250 NanoVG nvg; 251 #endif 252 }; 253 254 // -------------------------------------------------------------------------------------------------------------------- 255 // Main Demo Window, having a left-side tab-like widget and main area for current widget 256 257 class DemoWindow : public StandaloneWindow, 258 public LeftSideWidget::Callback 259 { 260 static const int kSidebarWidth = 81; 261 262 public: 263 #ifdef DGL_CAIRO 264 static constexpr const char* const kExampleWidgetName = "Demo - Cairo"; 265 #endif 266 #ifdef DGL_OPENGL 267 static constexpr const char* const kExampleWidgetName = "Demo - OpenGL"; 268 #endif 269 #ifdef DGL_VULKAN 270 static constexpr const char* const kExampleWidgetName = "Demo - Vulkan"; 271 #endif 272 273 DemoWindow(Application& app) 274 : StandaloneWindow(app), 275 curWidget(nullptr) 276 { 277 const ScopedGraphicsContext sgc(*this); 278 const double scaleFactor = getScaleFactor(); 279 280 wColor = new ExampleColorSubWidget(this); 281 wColor->hide(); 282 wColor->setAbsoluteX(kSidebarWidth * scaleFactor); 283 284 wImages = new ExampleImagesSubWidget(this); 285 wImages->hide(); 286 wImages->setAbsoluteX(kSidebarWidth * scaleFactor); 287 288 wRects = new ExampleRectanglesSubWidget(this); 289 wRects->hide(); 290 wRects->setAbsoluteX(kSidebarWidth * scaleFactor); 291 292 wShapes = new ExampleShapesSubWidget(this); 293 wShapes->hide(); 294 wShapes->setAbsoluteX(kSidebarWidth * scaleFactor); 295 296 #ifdef DGL_OPENGL 297 wText = new ExampleTextSubWidget(this), 298 wText->hide(); 299 wText->setAbsoluteX(kSidebarWidth * scaleFactor); 300 #endif 301 wLeft = new LeftSideWidget(this, this), 302 wLeft->setAbsolutePos(2 * scaleFactor, 2 * scaleFactor); 303 304 resizer = new ResizeHandle(this); 305 306 curPageChanged(0); 307 done(); 308 } 309 310 protected: 311 void curPageChanged(int curPage) override 312 { 313 if (curWidget != nullptr) 314 curWidget->hide(); 315 316 switch (curPage) 317 { 318 case 0: 319 curWidget = wColor; 320 break; 321 case 1: 322 curWidget = wImages; 323 break; 324 case 2: 325 curWidget = wRects; 326 break; 327 case 3: 328 curWidget = wShapes; 329 break; 330 #ifdef DGL_OPENGL 331 case 4: 332 curWidget = wText; 333 break; 334 #endif 335 default: 336 curWidget = nullptr; 337 break; 338 } 339 340 if (curWidget != nullptr) 341 curWidget->show(); 342 } 343 344 void onDisplay() override 345 { 346 } 347 348 void onReshape(uint width, uint height) override 349 { 350 StandaloneWindow::onReshape(width, height); 351 352 const double scaleFactor = getScaleFactor(); 353 354 if (width < kSidebarWidth * scaleFactor) 355 return; 356 357 const Size<uint> size(width - kSidebarWidth * scaleFactor, height); 358 wColor->setSize(size); 359 wImages->setSize(size); 360 wRects->setSize(size); 361 wShapes->setSize(size); 362 #ifdef DGL_OPENGL 363 wText->setSize(size); 364 #endif 365 wLeft->setSize((kSidebarWidth - 4) * scaleFactor, (height - 4) * scaleFactor); 366 } 367 368 private: 369 ScopedPointer<ExampleColorSubWidget> wColor; 370 ScopedPointer<ExampleImagesSubWidget> wImages; 371 ScopedPointer<ExampleRectanglesSubWidget> wRects; 372 ScopedPointer<ExampleShapesSubWidget> wShapes; 373 #ifdef DGL_OPENGL 374 ScopedPointer<ExampleTextSubWidget> wText; 375 #endif 376 ScopedPointer<LeftSideWidget> wLeft; 377 ScopedPointer<ResizeHandle> resizer; 378 379 Widget* curWidget; 380 }; 381 382 // -------------------------------------------------------------------------------------------------------------------- 383 // Special handy function that runs a StandaloneWindow inside the function scope 384 385 template <class ExampleWidgetStandaloneWindow> 386 void createAndShowExampleWidgetStandaloneWindow(Application& app) 387 { 388 ExampleWidgetStandaloneWindow swin(app); 389 const double scaleFactor = swin.getScaleFactor(); 390 swin.setGeometryConstraints(128 * scaleFactor, 128 * scaleFactor); 391 swin.setResizable(true); 392 swin.setSize(600 * scaleFactor, 500 * scaleFactor); 393 swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName); 394 swin.show(); 395 app.exec(); 396 } 397 398 // -------------------------------------------------------------------------------------------------------------------- 399 400 END_NAMESPACE_DGL 401 402 int main(int argc, char* argv[]) 403 { 404 USE_NAMESPACE_DGL; 405 using DGL_NAMESPACE::Window; 406 407 Application app; 408 409 if (argc > 1) 410 { 411 /**/ if (std::strcmp(argv[1], "color") == 0) 412 createAndShowExampleWidgetStandaloneWindow<ExampleColorStandaloneWindow>(app); 413 else if (std::strcmp(argv[1], "images") == 0) 414 createAndShowExampleWidgetStandaloneWindow<ExampleImagesStandaloneWindow>(app); 415 else if (std::strcmp(argv[1], "rectangles") == 0) 416 createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app); 417 else if (std::strcmp(argv[1], "shapes") == 0) 418 createAndShowExampleWidgetStandaloneWindow<ExampleShapesStandaloneWindow>(app); 419 #ifdef DGL_OPENGL 420 else if (std::strcmp(argv[1], "text") == 0) 421 createAndShowExampleWidgetStandaloneWindow<ExampleTextStandaloneWindow>(app); 422 #endif 423 else 424 d_stderr2("Invalid demo mode, must be one of: color, images, rectangles or shapes"); 425 } 426 else 427 { 428 createAndShowExampleWidgetStandaloneWindow<DemoWindow>(app); 429 } 430 431 return 0; 432 } 433 434 // --------------------------------------------------------------------------------------------------------------------