commit d76a11216152c36295596c12ef29a94b9769c2ad
parent 4f906d2980b6442bbd5fad153d4dcff886e54797
Author: falkTX <falktx@falktx.com>
Date: Fri, 27 May 2022 00:34:40 +0100
Import ResizeHandle widget for tests, set Demo min size
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
2 files changed, 210 insertions(+), 150 deletions(-)
diff --git a/tests/Demo.cpp b/tests/Demo.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
+ * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -23,6 +23,7 @@
#ifdef DGL_OPENGL
#include "widgets/ExampleTextWidget.hpp"
#endif
+#include "widgets/ResizeHandle.hpp"
#include "demo_res/DemoArtwork.cpp"
#include "images_res/CatPics.cpp"
@@ -251,155 +252,6 @@ private:
};
// --------------------------------------------------------------------------------------------------------------------
-// Resize handle widget
-
-class ResizeHandle : public TopLevelWidget
-{
- Rectangle<uint> area;
- Line<double> l1, l2, l3;
- uint baseSize;
-
- // event handling state
- bool resizing;
- Point<double> lastResizePoint;
- Size<double> resizingSize;
-
-public:
- explicit ResizeHandle(TopLevelWidget* const tlw)
- : TopLevelWidget(tlw->getWindow()),
- baseSize(16),
- resizing(false)
- {
- resetArea();
- }
-
- explicit ResizeHandle(Window& window)
- : TopLevelWidget(window),
- baseSize(16),
- resizing(false)
- {
- resetArea();
- }
-
- void setBaseSize(const uint size)
- {
- baseSize = std::max(16u, size);
- resetArea();
- }
-
-protected:
- void onDisplay() override
- {
- const GraphicsContext& context(getGraphicsContext());
- const double offset = getScaleFactor();
-
- // draw white lines, 1px wide
- Color(1.0f, 1.0f, 1.0f).setFor(context);
- l1.draw(context, 1);
- l2.draw(context, 1);
- l3.draw(context, 1);
-
- // draw black lines, offset by 1px and 2px wide
- Color(0.0f, 0.0f, 0.0f).setFor(context);
- Line<double> l1b(l1), l2b(l2), l3b(l3);
- l1b.moveBy(offset, offset);
- l2b.moveBy(offset, offset);
- l3b.moveBy(offset, offset);
- l1b.draw(context, 1);
- l2b.draw(context, 1);
- l3b.draw(context, 1);
- }
-
- bool onMouse(const MouseEvent& ev) override
- {
- if (ev.button != 1)
- return false;
-
- if (ev.press && area.contains(ev.pos))
- {
- resizing = true;
- resizingSize = Size<double>(getWidth(), getHeight());
- lastResizePoint = ev.pos;
- return true;
- }
-
- if (resizing && ! ev.press)
- {
- resizing = false;
- return true;
- }
-
- return false;
- }
-
- bool onMotion(const MotionEvent& ev) override
- {
- if (! resizing)
- return false;
-
- const Size<double> offset(ev.pos.getX() - lastResizePoint.getX(),
- ev.pos.getY() - lastResizePoint.getY());
-
- resizingSize += offset;
- lastResizePoint = ev.pos;
-
- // TODO min width, min height
- const uint minWidth = 16;
- const uint minHeight = 16;
-
- if (resizingSize.getWidth() < minWidth)
- resizingSize.setWidth(minWidth);
- if (resizingSize.getHeight() < minHeight)
- resizingSize.setHeight(minHeight);
-
- setSize(resizingSize.getWidth(), resizingSize.getHeight());
- return true;
- }
-
- void onResize(const ResizeEvent& ev) override
- {
- TopLevelWidget::onResize(ev);
- resetArea();
- }
-
-private:
- void resetArea()
- {
- const double scaleFactor = getScaleFactor();
- const uint margin = 0.0 * scaleFactor;
- const uint size = baseSize * scaleFactor;
-
- area = Rectangle<uint>(getWidth() - size - margin,
- getHeight() - size - margin,
- size, size);
-
- recreateLines(area.getX(), area.getY(), size);
- }
-
- void recreateLines(const uint x, const uint y, const uint size)
- {
- uint linesize = size;
- uint offset = 0;
-
- // 1st line, full diagonal size
- l1.setStartPos(x + size, y);
- l1.setEndPos(x, y + size);
-
- // 2nd line, bit more to the right and down, cropped
- offset += size / 3;
- linesize -= size / 3;
- l2.setStartPos(x + linesize + offset, y + offset);
- l2.setEndPos(x + offset, y + linesize + offset);
-
- // 3rd line, even more right and down
- offset += size / 3;
- linesize -= size / 3;
- l3.setStartPos(x + linesize + offset, y + offset);
- l3.setEndPos(x + offset, y + linesize + offset);
- }
-};
-
-// --------------------------------------------------------------------------------------------------------------------
// Main Demo Window, having a left-side tab-like widget and main area for current widget
class DemoWindow : public StandaloneWindow,
@@ -535,6 +387,7 @@ void createAndShowExampleWidgetStandaloneWindow(Application& app)
{
ExampleWidgetStandaloneWindow swin(app);
const double scaleFactor = swin.getScaleFactor();
+ swin.setGeometryConstraints(128 * scaleFactor, 128 * scaleFactor);
swin.setResizable(true);
swin.setSize(600 * scaleFactor, 500 * scaleFactor);
swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName);
diff --git a/tests/widgets/ResizeHandle.hpp b/tests/widgets/ResizeHandle.hpp
@@ -0,0 +1,207 @@
+/*
+ * Resize handle for DPF
+ * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#pragma once
+
+#include "../../dgl/Color.hpp"
+#include "../../dgl/TopLevelWidget.hpp"
+
+START_NAMESPACE_DGL
+
+/** Resize handle for DPF windows, will sit on bottom-right. */
+class ResizeHandle : public TopLevelWidget
+{
+public:
+ /** Constructor for placing this handle on top of a window. */
+ explicit ResizeHandle(Window& window)
+ : TopLevelWidget(window),
+ handleSize(16),
+ hasCursor(false),
+ isResizing(false)
+ {
+ resetArea();
+ }
+
+ /** Overloaded constructor, will fetch the window from an existing top-level widget. */
+ explicit ResizeHandle(TopLevelWidget* const tlw)
+ : TopLevelWidget(tlw->getWindow()),
+ handleSize(16),
+ hasCursor(false),
+ isResizing(false)
+ {
+ resetArea();
+ }
+
+ /** Set the handle size, minimum 16.
+ * Scale factor is automatically applied on top of this size as needed */
+ void setHandleSize(const uint size)
+ {
+ handleSize = std::max(16u, size);
+ resetArea();
+ }
+
+protected:
+ void onDisplay() override
+ {
+ // TODO implement gl3 stuff in DPF
+#ifndef DGL_USE_OPENGL3
+ const GraphicsContext& context(getGraphicsContext());
+ const double lineWidth = 1.0 * getScaleFactor();
+
+ #if defined(DGL_OPENGL) && !defined(DGL_USE_OPENGL3)
+ glMatrixMode(GL_MODELVIEW);
+ #endif
+
+ // draw white lines, 1px wide
+ Color(1.0f, 1.0f, 1.0f).setFor(context);
+ l1.draw(context, lineWidth);
+ l2.draw(context, lineWidth);
+ l3.draw(context, lineWidth);
+
+ // draw black lines, offset by 1px and 1px wide
+ Color(0.0f, 0.0f, 0.0f).setFor(context);
+ Line<double> l1b(l1), l2b(l2), l3b(l3);
+ l1b.moveBy(lineWidth, lineWidth);
+ l2b.moveBy(lineWidth, lineWidth);
+ l3b.moveBy(lineWidth, lineWidth);
+ l1b.draw(context, lineWidth);
+ l2b.draw(context, lineWidth);
+ l3b.draw(context, lineWidth);
+#endif
+ }
+
+ bool onMouse(const MouseEvent& ev) override
+ {
+ if (ev.button != 1)
+ return false;
+
+ if (ev.press && area.contains(ev.pos))
+ {
+ isResizing = true;
+ resizingSize = Size<double>(getWidth(), getHeight());
+ lastResizePoint = ev.pos;
+ return true;
+ }
+
+ if (isResizing && ! ev.press)
+ {
+ isResizing = false;
+ recheckCursor(ev.pos);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool onMotion(const MotionEvent& ev) override
+ {
+ if (! isResizing)
+ {
+ recheckCursor(ev.pos);
+ return false;
+ }
+
+ const Size<double> offset(ev.pos.getX() - lastResizePoint.getX(),
+ ev.pos.getY() - lastResizePoint.getY());
+
+ resizingSize += offset;
+ lastResizePoint = ev.pos;
+
+ // TODO keepAspectRatio
+ bool keepAspectRatio;
+ const Size<uint> minSize(getWindow().getGeometryConstraints(keepAspectRatio));
+ const uint minWidth = minSize.getWidth();
+ const uint minHeight = minSize.getHeight();
+
+ if (resizingSize.getWidth() < minWidth)
+ resizingSize.setWidth(minWidth);
+ if (resizingSize.getWidth() > 16384)
+ resizingSize.setWidth(16384);
+ if (resizingSize.getHeight() < minHeight)
+ resizingSize.setHeight(minHeight);
+ if (resizingSize.getHeight() > 16384)
+ resizingSize.setHeight(16384);
+
+ setSize(resizingSize.getWidth(), resizingSize.getHeight());
+ return true;
+ }
+
+ void onResize(const ResizeEvent& ev) override
+ {
+ TopLevelWidget::onResize(ev);
+ resetArea();
+ }
+
+private:
+ Rectangle<uint> area;
+ Line<double> l1, l2, l3;
+ uint handleSize;
+
+ // event handling state
+ bool hasCursor, isResizing;
+ Point<double> lastResizePoint;
+ Size<double> resizingSize;
+
+ void recheckCursor(const Point<double>& pos)
+ {
+ const bool shouldHaveCursor = area.contains(pos);
+
+ if (shouldHaveCursor == hasCursor)
+ return;
+
+ hasCursor = shouldHaveCursor;
+ setCursor(shouldHaveCursor ? kMouseCursorDiagonal : kMouseCursorArrow);
+ }
+
+ void resetArea()
+ {
+ const double scaleFactor = getScaleFactor();
+ const uint margin = 0.0 * scaleFactor;
+ const uint size = handleSize * scaleFactor;
+
+ area = Rectangle<uint>(getWidth() - size - margin,
+ getHeight() - size - margin,
+ size, size);
+
+ recreateLines(area.getX(), area.getY(), size);
+ }
+
+ void recreateLines(const uint x, const uint y, const uint size)
+ {
+ uint linesize = size;
+ uint offset = 0;
+
+ // 1st line, full diagonal size
+ l1.setStartPos(x + size, y);
+ l1.setEndPos(x, y + size);
+
+ // 2nd line, bit more to the right and down, cropped
+ offset += size / 3;
+ linesize -= size / 3;
+ l2.setStartPos(x + linesize + offset, y + offset);
+ l2.setEndPos(x + offset, y + linesize + offset);
+
+ // 3rd line, even more right and down
+ offset += size / 3;
+ linesize -= size / 3;
+ l3.setStartPos(x + linesize + offset, y + offset);
+ l3.setEndPos(x + offset, y + linesize + offset);
+ }
+
+ DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ResizeHandle)
+};
+
+END_NAMESPACE_DGL