Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
@@ -210,6 +210,8 @@ public: | |||
*/ | |||
bool isInvalid() const noexcept; | |||
Size<int> toInt() const noexcept; | |||
Size<T> operator+(const Size<T>& size) noexcept; | |||
Size<T> operator-(const Size<T>& size) noexcept; | |||
Size<T>& operator=(const Size<T>& size) noexcept; | |||
@@ -45,6 +45,7 @@ public: | |||
uint getWidth() const noexcept { return Window::getWidth(); } | |||
uint getHeight() const noexcept { return Window::getHeight(); } | |||
const Size<uint> getSize() const noexcept { return Window::getSize(); } | |||
void repaint() noexcept { Window::repaint(); } | |||
/** | |||
Overloaded functions to ensure size changes apply on both TopLevelWidget and Window classes. | |||
@@ -42,7 +42,7 @@ public: | |||
/** | |||
Constructor. | |||
*/ | |||
explicit SubWidget(Widget* widgetToGroupTo); | |||
explicit SubWidget(Widget* parentWidget); | |||
/** | |||
Destructor. | |||
@@ -76,6 +76,19 @@ public: | |||
*/ | |||
Point<int> getAbsolutePos() const noexcept; | |||
/** | |||
Get absolute area of this subwidget. | |||
This is the same as `Rectangle<int>(getAbsolutePos(), getSize());` | |||
@see getConstrainedAbsoluteArea() | |||
*/ | |||
Rectangle<int> getAbsoluteArea() const noexcept; | |||
/** | |||
Get absolute area of this subwidget, with special consideration for not allowing negative values. | |||
@see getAbsoluteArea() | |||
*/ | |||
Rectangle<uint> getConstrainedAbsoluteArea() const noexcept; | |||
/** | |||
Set absolute X. | |||
*/ | |||
@@ -96,6 +109,11 @@ public: | |||
*/ | |||
void setAbsolutePos(const Point<int>& pos) noexcept; | |||
/** | |||
Request repaint of this subwidget's area to the window this widget belongs to. | |||
*/ | |||
void repaint() noexcept override; | |||
protected: | |||
/** | |||
A function called when the subwidget's absolute position is changed. | |||
@@ -50,6 +50,14 @@ public: | |||
*/ | |||
virtual ~TopLevelWidget(); | |||
/** | |||
Get the application associated with this top-level widget's window. | |||
*/ | |||
Application& getApp() const noexcept; | |||
void repaint() noexcept; | |||
void repaint(const Rectangle<uint>& rect) noexcept; | |||
private: | |||
struct PrivateData; | |||
PrivateData* const pData; | |||
@@ -169,10 +169,10 @@ public: | |||
TopLevelWidget* getTopLevelWidget() const noexcept; | |||
/** | |||
Tell this widget's window to repaint itself. | |||
FIXME better description, partial redraw | |||
Request repaint of this widget's area to the window this widget belongs to. | |||
On the raw Widget class this function does nothing. | |||
*/ | |||
void repaint() noexcept; | |||
virtual void repaint() noexcept; | |||
protected: | |||
/** | |||
@@ -246,6 +246,12 @@ bool Size<T>::isInvalid() const noexcept | |||
return fWidth <= 0 || fHeight <= 0; | |||
} | |||
template<typename T> | |||
Size<int> Size<T>::toInt() const noexcept | |||
{ | |||
return Size<int>(fWidth, fHeight); | |||
} | |||
template<typename T> | |||
Size<T> Size<T>::operator+(const Size<T>& size) noexcept | |||
{ | |||
@@ -15,14 +15,15 @@ | |||
*/ | |||
#include "SubWidgetPrivateData.hpp" | |||
#include "../TopLevelWidget.hpp" | |||
START_NAMESPACE_DGL | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
SubWidget::SubWidget(Widget* const widgetToGroupTo) | |||
: Widget(widgetToGroupTo), | |||
pData(new PrivateData(this, widgetToGroupTo)) {} | |||
SubWidget::SubWidget(Widget* const parentWidget) | |||
: Widget(parentWidget), | |||
pData(new PrivateData(this, parentWidget)) {} | |||
SubWidget::~SubWidget() | |||
{ | |||
@@ -56,6 +57,18 @@ Point<int> SubWidget::getAbsolutePos() const noexcept | |||
return pData->absolutePos; | |||
} | |||
Rectangle<int> SubWidget::getAbsoluteArea() const noexcept | |||
{ | |||
return Rectangle<int>(getAbsolutePos(), getSize().toInt()); | |||
} | |||
Rectangle<uint> SubWidget::getConstrainedAbsoluteArea() const noexcept | |||
{ | |||
return Rectangle<uint>(std::max(0, getAbsoluteX()), | |||
std::max(0, getAbsoluteY()), | |||
getSize()); | |||
} | |||
void SubWidget::setAbsoluteX(int x) noexcept | |||
{ | |||
setAbsolutePos(Point<int>(x, getAbsoluteY())); | |||
@@ -83,8 +96,15 @@ void SubWidget::setAbsolutePos(const Point<int>& pos) noexcept | |||
pData->absolutePos = pos; | |||
onPositionChanged(ev); | |||
// repaint the whole thing | |||
pData->parent->repaint(); | |||
// repaint the bounds of parent | |||
pData->parentWidget->repaint(); | |||
} | |||
void SubWidget::repaint() noexcept | |||
{ | |||
if (TopLevelWidget* const topw = getTopLevelWidget()) | |||
topw->repaint(getConstrainedAbsoluteArea()); | |||
} | |||
void SubWidget::onPositionChanged(const PositionChangedEvent&) | |||
@@ -21,17 +21,17 @@ START_NAMESPACE_DGL | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
SubWidget::PrivateData::PrivateData(SubWidget* const s, Widget* const p) | |||
SubWidget::PrivateData::PrivateData(SubWidget* const s, Widget* const pw) | |||
: self(s), | |||
parent(p), | |||
parentWidget(pw), | |||
absolutePos() | |||
{ | |||
parent->pData->subWidgets.push_back(self); | |||
parentWidget->pData->subWidgets.push_back(self); | |||
} | |||
SubWidget::PrivateData::~PrivateData() | |||
{ | |||
parent->pData->subWidgets.remove(self); | |||
parentWidget->pData->subWidgets.remove(self); | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
@@ -25,10 +25,10 @@ START_NAMESPACE_DGL | |||
struct SubWidget::PrivateData { | |||
SubWidget* const self; | |||
Widget* const parent; | |||
Widget* const parentWidget; | |||
Point<int> absolutePos; | |||
explicit PrivateData(SubWidget* const s, Widget* const p); | |||
explicit PrivateData(SubWidget* const s, Widget* const pw); | |||
~PrivateData(); | |||
// NOTE display function is different depending on build type, must call displaySubWidgets at the end | |||
@@ -29,6 +29,21 @@ TopLevelWidget::~TopLevelWidget() | |||
delete pData; | |||
} | |||
Application& TopLevelWidget::getApp() const noexcept | |||
{ | |||
return pData->window.getApp(); | |||
} | |||
void TopLevelWidget::repaint() noexcept | |||
{ | |||
pData->window.repaint(); | |||
} | |||
void TopLevelWidget::repaint(const Rectangle<uint>& rect) noexcept | |||
{ | |||
pData->window.repaint(rect); | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DGL |
@@ -15,6 +15,7 @@ | |||
*/ | |||
#include "WidgetPrivateData.hpp" | |||
#include "../TopLevelWidget.hpp" | |||
START_NAMESPACE_DGL | |||
@@ -24,8 +25,8 @@ START_NAMESPACE_DGL | |||
Widget::Widget(TopLevelWidget* const topLevelWidget) | |||
: pData(new PrivateData(this, topLevelWidget)) {} | |||
Widget::Widget(Widget* const widgetToGroupTo) | |||
: pData(new PrivateData(this, widgetToGroupTo)) {} | |||
Widget::Widget(Widget* const parentWidget) | |||
: pData(new PrivateData(this, parentWidget)) {} | |||
Widget::~Widget() | |||
{ | |||
@@ -83,7 +84,7 @@ void Widget::setWidth(uint width) noexcept | |||
pData->size.setWidth(width); | |||
onResize(ev); | |||
pData->repaint(); | |||
repaint(); | |||
} | |||
void Widget::setHeight(uint height) noexcept | |||
@@ -98,7 +99,7 @@ void Widget::setHeight(uint height) noexcept | |||
pData->size.setHeight(height); | |||
onResize(ev); | |||
pData->repaint(); | |||
repaint(); | |||
} | |||
void Widget::setSize(uint width, uint height) noexcept | |||
@@ -118,7 +119,7 @@ void Widget::setSize(const Size<uint>& size) noexcept | |||
pData->size = size; | |||
onResize(ev); | |||
pData->repaint(); | |||
repaint(); | |||
} | |||
Application& Widget::getApp() const noexcept | |||
@@ -133,8 +134,6 @@ TopLevelWidget* Widget::getTopLevelWidget() const noexcept | |||
void Widget::repaint() noexcept | |||
{ | |||
// FIXME partial repaint | |||
// pData->topLevelWidget.repaint(); | |||
} | |||
uint Widget::getId() const noexcept | |||
@@ -24,17 +24,17 @@ START_NAMESPACE_DGL | |||
Widget::PrivateData::PrivateData(Widget* const s, TopLevelWidget* const tlw) | |||
: self(s), | |||
topLevelWidget(tlw), | |||
parentGroupWidget(nullptr), | |||
parentWidget(nullptr), | |||
id(0), | |||
needsScaling(false), | |||
visible(true), | |||
size(0, 0), | |||
subWidgets() {} | |||
Widget::PrivateData::PrivateData(Widget* const s, Widget* const g) | |||
Widget::PrivateData::PrivateData(Widget* const s, Widget* const pw) | |||
: self(s), | |||
topLevelWidget(findTopLevelWidget(g)), | |||
parentGroupWidget(g), | |||
topLevelWidget(findTopLevelWidget(pw)), | |||
parentWidget(pw), | |||
id(0), | |||
needsScaling(false), | |||
visible(true), | |||
@@ -62,14 +62,6 @@ void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, | |||
} | |||
} | |||
void Widget::PrivateData::repaint() | |||
{ | |||
// if (parentGroupWidget != nullptr) | |||
// parentGroupWidget->repaint(); | |||
// else if (topLevelWidget != nullptr) | |||
// topLevelWidget->repaint(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const w) | |||
@@ -78,8 +70,8 @@ TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const w) | |||
// return tlw; | |||
if (w->pData->topLevelWidget != nullptr) | |||
return w->pData->topLevelWidget; | |||
if (w->pData->parentGroupWidget != nullptr) | |||
return findTopLevelWidget(w->pData->parentGroupWidget); | |||
if (w->pData->parentWidget != nullptr) | |||
return findTopLevelWidget(w->pData->parentWidget); | |||
return nullptr; | |||
} | |||
@@ -28,7 +28,7 @@ START_NAMESPACE_DGL | |||
struct Widget::PrivateData { | |||
Widget* const self; | |||
TopLevelWidget* const topLevelWidget; | |||
Widget* const parentGroupWidget; | |||
Widget* const parentWidget; | |||
uint id; | |||
bool needsScaling; | |||
bool visible; | |||
@@ -38,7 +38,7 @@ struct Widget::PrivateData { | |||
// called via TopLevelWidget | |||
explicit PrivateData(Widget* const s, TopLevelWidget* const tlw); | |||
// called via SubWidget | |||
explicit PrivateData(Widget* const s, Widget* const pgw); | |||
explicit PrivateData(Widget* const s, Widget* const pw); | |||
~PrivateData(); | |||
// NOTE display function is different depending on build type, must call displaySubWidgets at the end | |||
@@ -46,8 +46,6 @@ struct Widget::PrivateData { | |||
void displaySubWidgets(uint width, uint height, double autoScaling); | |||
void repaint(); | |||
static TopLevelWidget* findTopLevelWidget(Widget* const w); | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | |||
@@ -149,7 +149,7 @@ void Window::repaint(const Rectangle<uint>& rect) noexcept | |||
puglPostRedisplayRect(pData->view, prect); | |||
} | |||
void Window::onReshape(const uint width, const uint height) | |||
void Window::onReshape(uint, uint) | |||
{ | |||
puglFallbackOnResize(pData->view); | |||
} | |||
@@ -48,7 +48,10 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) | |||
topLevelWidget(nullptr), | |||
isClosed(true), | |||
isVisible(false), | |||
isEmbed(false) | |||
isEmbed(false), | |||
scaling(1.0), | |||
autoScaling(1.0), | |||
pendingVisibility(kPendingVisibilityNone) | |||
{ | |||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | |||
} | |||
@@ -63,7 +66,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, Window& transi | |||
isVisible(false), | |||
isEmbed(false), | |||
scaling(1.0), | |||
autoScaling(1.0) | |||
autoScaling(1.0), | |||
pendingVisibility(kPendingVisibilityNone) | |||
{ | |||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | |||
@@ -83,7 +87,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
isVisible(parentWindowHandle != 0), | |||
isEmbed(parentWindowHandle != 0), | |||
scaling(scale), | |||
autoScaling(1.0) | |||
autoScaling(1.0), | |||
pendingVisibility(kPendingVisibilityNone) | |||
{ | |||
init(width, height, resizable); | |||
@@ -132,6 +137,9 @@ void Window::PrivateData::init(const uint width, const uint height, const bool r | |||
puglSetHandle(view, this); | |||
puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); | |||
puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE); | |||
puglSetViewHint(view, PUGL_DEPTH_BITS, 8); | |||
puglSetViewHint(view, PUGL_STENCIL_BITS, 8); | |||
// PUGL_SAMPLES ?? | |||
puglSetEventFunc(view, puglEventCallback); | |||
// #ifndef DGL_FILE_BROWSER_DISABLED | |||
// puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | |||
@@ -174,14 +182,9 @@ void Window::PrivateData::show() | |||
isClosed = false; | |||
appData->oneWindowShown(); | |||
pendingVisibility = kPendingVisibilityShow; | |||
const PuglStatus status = puglRealize(view); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(status == PUGL_SUCCESS, status, close()); | |||
#ifdef DISTRHO_OS_WINDOWS | |||
puglWin32ShowWindowCentered(view); | |||
#else | |||
puglShow(view); | |||
#endif | |||
} | |||
else | |||
{ | |||
@@ -197,14 +200,17 @@ void Window::PrivateData::show() | |||
void Window::PrivateData::hide() | |||
{ | |||
if (! isVisible) | |||
if (isEmbed) | |||
{ | |||
DGL_DBG("Window hide matches current visible state, ignoring request\n"); | |||
DGL_DBG("Window hide cannot be called when embedded\n"); | |||
return; | |||
} | |||
if (isEmbed) | |||
pendingVisibility = kPendingVisibilityHide; | |||
if (! isVisible) | |||
{ | |||
DGL_DBG("Window hide cannot be called when embedded\n"); | |||
DGL_DBG("Window hide matches current visible state, ignoring request\n"); | |||
return; | |||
} | |||
@@ -262,6 +268,8 @@ void Window::PrivateData::idleCallback() | |||
void Window::PrivateData::onPuglDisplay() | |||
{ | |||
DGL_DBGp("PUGL: onPuglDisplay : %p\n", topLevelWidget); | |||
puglOnDisplayPrepare(view); | |||
#ifndef DPF_TEST_WINDOW_CPP | |||
@@ -284,6 +292,21 @@ void Window::PrivateData::onPuglReshape(const int width, const int height) | |||
#endif | |||
} | |||
void Window::PrivateData::onPuglCreate() | |||
{ | |||
DGL_DBGp("PUGL: onPuglCreate %i\n", pendingVisibility); | |||
if (pendingVisibility != kPendingVisibilityShow) | |||
return; | |||
pendingVisibility = kPendingVisibilityNone; | |||
#ifdef DISTRHO_OS_WINDOWS | |||
puglWin32ShowWindowCentered(view); | |||
#else | |||
puglShow(view); | |||
#endif | |||
} | |||
void Window::PrivateData::onPuglClose() | |||
{ | |||
DGL_DBG("PUGL: onClose\n"); | |||
@@ -328,6 +351,10 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||
pData->onPuglClose(); | |||
break; | |||
case PUGL_CREATE: | |||
pData->onPuglCreate(); | |||
break; | |||
// TODO | |||
default: | |||
break; | |||
@@ -63,6 +63,13 @@ struct Window::PrivateData : IdleCallback { | |||
/** Automatic scaling to apply on widgets, implemented internally. */ | |||
double autoScaling; | |||
/** Pending state of visility, used for the action to be triggered during Pugl create events. */ | |||
enum PendingVisibility { | |||
kPendingVisibilityNone, | |||
kPendingVisibilityShow, | |||
kPendingVisibilityHide | |||
} pendingVisibility; | |||
/** Constructor for a regular, standalone window. */ | |||
explicit PrivateData(Application& app, Window* self); | |||
@@ -98,6 +105,7 @@ struct Window::PrivateData : IdleCallback { | |||
// pugl events | |||
void onPuglDisplay(); | |||
void onPuglReshape(int width, int height); | |||
void onPuglCreate(); | |||
void onPuglClose(); | |||
// Pugl event handling entry point | |||
@@ -37,12 +37,12 @@ | |||
#include "dgl/StandaloneWindow.hpp" | |||
#include "widgets/ExampleColorWidget.hpp" | |||
#include "widgets/ExampleRectanglesWidget.hpp" | |||
#include "widgets/ExampleShapesWidget.hpp" | |||
START_NAMESPACE_DGL | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// ------------------------------------------------------ | |||
// Left side tab-like widget | |||
class LeftSideWidget : public SubWidget | |||
@@ -225,8 +225,8 @@ private: | |||
#endif | |||
}; | |||
// ------------------------------------------------------ | |||
// Our Demo Window | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// Main Demo Window, having a left-side tab-like widget and main area for current widget | |||
class DemoWindow : public StandaloneWindow, | |||
public LeftSideWidget::Callback | |||
@@ -234,23 +234,27 @@ class DemoWindow : public StandaloneWindow, | |||
static const int kSidebarWidth = 81; | |||
public: | |||
static constexpr const char* const kExampleWidgetName = "Demo"; | |||
DemoWindow(Application& app) | |||
: StandaloneWindow(app), | |||
wColor(this), | |||
wRects(this), | |||
wShapes(this), | |||
wLeft(this, this), | |||
curWidget(nullptr) | |||
{ | |||
wColor.hide(); | |||
// wImages.hide(); | |||
// wRects.hide(); | |||
// wShapes.hide(); | |||
wRects.hide(); | |||
wShapes.hide(); | |||
// wText.hide(); | |||
// //wPerf.hide(); | |||
wColor.setAbsoluteX(kSidebarWidth); | |||
// wImages.setAbsoluteX(kSidebarWidth); | |||
// wRects.setAbsoluteX(kSidebarWidth); | |||
// wShapes.setAbsoluteX(kSidebarWidth); | |||
wRects.setAbsoluteX(kSidebarWidth); | |||
wShapes.setAbsoluteX(kSidebarWidth); | |||
// wText.setAbsoluteX(kSidebarWidth); | |||
wLeft.setAbsolutePos(2, 2); | |||
// wPerf.setAbsoluteY(5); | |||
@@ -265,10 +269,7 @@ protected: | |||
void curPageChanged(int curPage) override | |||
{ | |||
if (curWidget != nullptr) | |||
{ | |||
curWidget->hide(); | |||
curWidget = nullptr; | |||
} | |||
switch (curPage) | |||
{ | |||
@@ -278,15 +279,18 @@ protected: | |||
// case 1: | |||
// curWidget = &wImages; | |||
// break; | |||
// case 2: | |||
// curWidget = &wRects; | |||
// break; | |||
// case 3: | |||
// curWidget = &wShapes; | |||
// break; | |||
case 2: | |||
curWidget = &wRects; | |||
break; | |||
case 3: | |||
curWidget = &wShapes; | |||
break; | |||
// case 4: | |||
// curWidget = &wText; | |||
// break; | |||
default: | |||
curWidget = nullptr; | |||
break; | |||
} | |||
if (curWidget != nullptr) | |||
@@ -312,8 +316,8 @@ protected: | |||
Size<uint> size(width-kSidebarWidth, height); | |||
wColor.setSize(size); | |||
// wImages.setSize(size); | |||
// wRects.setSize(size); | |||
// wShapes.setSize(size); | |||
wRects.setSize(size); | |||
wShapes.setSize(size); | |||
// wText.setSize(size); | |||
wLeft.setSize(kSidebarWidth-4, height-4); | |||
@@ -324,10 +328,10 @@ protected: | |||
} | |||
private: | |||
ExampleColorWidget wColor; | |||
ExampleColorSubWidget wColor; | |||
// ExampleImagesWidget wImages; | |||
// ExampleRectanglesWidget wRects; | |||
// ExampleShapesWidget wShapes; | |||
ExampleRectanglesSubWidget wRects; | |||
ExampleShapesSubWidget wShapes; | |||
// ExampleTextWidget wText; | |||
LeftSideWidget wLeft; | |||
//ResizeHandle wRezHandle; | |||
@@ -336,19 +340,71 @@ private: | |||
Widget* curWidget; | |||
}; | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// Testing StandaloneWindow, for custom local widget drawing code | |||
class TestingWidgetStandaloneWindow : public StandaloneWindow | |||
{ | |||
public: | |||
static constexpr const char* kExampleWidgetName = "Testing"; | |||
TestingWidgetStandaloneWindow(Application& app) | |||
: StandaloneWindow(app) | |||
{ | |||
} | |||
protected: | |||
void onDisplay() override | |||
{ | |||
glColor3f(0.5f, 0.3f, 0.9f); | |||
Rectangle<uint>(0, 0, 500, 500).draw(); | |||
// getWidth(), getHeight() | |||
} | |||
}; | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// Special handy function that runs a StandaloneWindow inside the function scope | |||
template <class ExampleWidgetStandaloneWindow> | |||
void createAndShowExampleWidgetStandaloneWindow(Application& app) | |||
{ | |||
ExampleWidgetStandaloneWindow swin(app); | |||
swin.setSize(600, 500); | |||
swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName); | |||
swin.show(); | |||
app.exec(); | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
END_NAMESPACE_DGL | |||
int main() | |||
int main(int argc, char* argv[]) | |||
{ | |||
USE_NAMESPACE_DGL; | |||
using DGL_NAMESPACE::Window; | |||
Application app; | |||
DemoWindow win(app); | |||
win.show(); | |||
app.exec(); | |||
if (argc > 1) | |||
{ | |||
// TODO images, text | |||
/**/ if (std::strcmp(argv[1], "color") == 0) | |||
createAndShowExampleWidgetStandaloneWindow<ExampleColorStandaloneWindow>(app); | |||
else if (std::strcmp(argv[1], "rectangles") == 0) | |||
createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app); | |||
else if (std::strcmp(argv[1], "shapes") == 0) | |||
createAndShowExampleWidgetStandaloneWindow<ExampleShapesStandaloneWindow>(app); | |||
else if (std::strcmp(argv[1], "testing") == 0) | |||
createAndShowExampleWidgetStandaloneWindow<TestingWidgetStandaloneWindow>(app); | |||
else | |||
d_stderr2("Invalid demo mode, must be one of: color, rectangles, shapes"); | |||
} | |||
else | |||
{ | |||
createAndShowExampleWidgetStandaloneWindow<DemoWindow>(app); | |||
} | |||
return 0; | |||
} | |||
@@ -93,6 +93,11 @@ clean: | |||
@echo "Compiling $< (OpenGL)" | |||
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_OPENGL -c -o $@ | |||
../build/tests/Testing.cpp.o: Testing.cpp | |||
-@mkdir -p ../build/tests | |||
@echo "Compiling $< (OpenGL)" | |||
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_OPENGL -c -o $@ | |||
../build/tests/%.cpp.opengl.o: %.cpp | |||
-@mkdir -p ../build/tests | |||
@echo "Compiling $< (OpenGL)" | |||
@@ -118,6 +123,10 @@ clean: | |||
@echo "Linking Demo" | |||
$(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | |||
../build/tests/Testing: ../build/tests/Testing.cpp.o | |||
@echo "Linking Testing" | |||
$(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | |||
../build/tests/%.opengl: ../build/tests/%.cpp.opengl.o | |||
@echo "Linking $*" | |||
$(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | |||
@@ -31,11 +31,13 @@ START_NAMESPACE_DGL | |||
class ApplicationQuitter : public Thread | |||
{ | |||
Application& app; | |||
const int numSecondsToWait; | |||
public: | |||
ApplicationQuitter(Application& a) | |||
ApplicationQuitter(Application& a, const int s = 2) | |||
: Thread("ApplicationQuitter"), | |||
app(a) | |||
app(a), | |||
numSecondsToWait(s) | |||
{ | |||
startThread(); | |||
} | |||
@@ -43,7 +45,7 @@ public: | |||
private: | |||
void run() override | |||
{ | |||
d_sleep(2); | |||
d_sleep(numSecondsToWait); | |||
app.quit(); | |||
} | |||
}; | |||
@@ -21,13 +21,15 @@ | |||
// DGL Stuff | |||
#include "../../dgl/SubWidget.hpp" | |||
#include "../../dgl/TopLevelWidget.hpp" | |||
START_NAMESPACE_DGL | |||
// ------------------------------------------------------ | |||
// our widget | |||
class ExampleColorWidget : public SubWidget, | |||
template <class BaseWidget> | |||
class ExampleColorWidget : public BaseWidget, | |||
public IdleCallback | |||
{ | |||
char cur; | |||
@@ -37,13 +39,32 @@ class ExampleColorWidget : public SubWidget, | |||
Rectangle<uint> bgFull, bgSmall; | |||
public: | |||
ExampleColorWidget(TopLevelWidget* const topWidget) | |||
: SubWidget(topWidget), | |||
static constexpr const char* kExampleWidgetName = "Color"; | |||
explicit ExampleColorWidget(Widget* const parent) | |||
: BaseWidget(parent), | |||
cur('r'), | |||
reverse(false), | |||
r(0), g(99), b(32) | |||
{ | |||
setSize(300, 300); | |||
init(); | |||
} | |||
explicit ExampleColorWidget(Window& windowToMapTo) | |||
: BaseWidget(windowToMapTo) | |||
{ | |||
init(); | |||
} | |||
explicit ExampleColorWidget(Application& app) | |||
: BaseWidget(app) | |||
{ | |||
init(); | |||
} | |||
void init() | |||
{ | |||
BaseWidget::setSize(300, 300); | |||
// topWidget->getApp().addIdleCallback(this); | |||
} | |||
@@ -99,7 +120,7 @@ protected: | |||
break; | |||
} | |||
repaint(); | |||
BaseWidget::repaint(); | |||
} | |||
void onDisplay() override | |||
@@ -126,6 +147,10 @@ protected: | |||
} | |||
}; | |||
typedef ExampleColorWidget<SubWidget> ExampleColorSubWidget; | |||
typedef ExampleColorWidget<TopLevelWidget> ExampleColorTopLevelWidget; | |||
typedef ExampleColorWidget<StandaloneWindow> ExampleColorStandaloneWindow; | |||
// ------------------------------------------------------ | |||
END_NAMESPACE_DGL | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2012-2021 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 | |||
@@ -20,40 +20,55 @@ | |||
// ------------------------------------------------------ | |||
// DGL Stuff | |||
#include "Widget.hpp" | |||
#include "Window.hpp" | |||
#include "../../dgl/SubWidget.hpp" | |||
#include "../../dgl/TopLevelWidget.hpp" | |||
START_NAMESPACE_DGL | |||
// ------------------------------------------------------ | |||
// our widget | |||
class ExampleRectanglesWidget : public Widget | |||
template <class BaseWidget> | |||
class ExampleRectanglesWidget : public BaseWidget | |||
{ | |||
bool clicked[9]; | |||
public: | |||
ExampleRectanglesWidget(Window& parent) | |||
: Widget(parent) | |||
static constexpr const char* const kExampleWidgetName = "Rectangles"; | |||
explicit ExampleRectanglesWidget(Widget* const parentWidget) | |||
: BaseWidget(parentWidget) | |||
{ | |||
setSize(300, 300); | |||
init(); | |||
} | |||
for (int i=0; i<9; ++i) | |||
fClicked[i] = false; | |||
explicit ExampleRectanglesWidget(Window& windowToMapTo) | |||
: BaseWidget(windowToMapTo) | |||
{ | |||
init(); | |||
} | |||
ExampleRectanglesWidget(Widget* groupWidget) | |||
: Widget(groupWidget) | |||
explicit ExampleRectanglesWidget(Application& app) | |||
: BaseWidget(app) | |||
{ | |||
setSize(300, 300); | |||
init(); | |||
} | |||
void init() | |||
{ | |||
this->setSize(300, 300); | |||
for (int i=0; i<9; ++i) | |||
fClicked[i] = false; | |||
clicked[i] = false; | |||
} | |||
protected: | |||
void onDisplay() override | |||
{ | |||
const int width = getWidth(); | |||
const int height = getHeight(); | |||
const uint width = this->getWidth(); | |||
const uint height = this->getHeight(); | |||
Rectangle<int> r; | |||
Rectangle<double> r; | |||
r.setWidth(width/3 - 6); | |||
r.setHeight(height/3 - 6); | |||
@@ -66,7 +81,7 @@ protected: | |||
// 1st | |||
r.setY(3); | |||
if (fClicked[0+i]) | |||
if (clicked[0+i]) | |||
glColor3f(0.8f, 0.5f, 0.3f); | |||
else | |||
glColor3f(0.3f, 0.5f, 0.8f); | |||
@@ -76,7 +91,7 @@ protected: | |||
// 2nd | |||
r.setY(3 + height/3); | |||
if (fClicked[3+i]) | |||
if (clicked[3+i]) | |||
glColor3f(0.8f, 0.5f, 0.3f); | |||
else | |||
glColor3f(0.3f, 0.5f, 0.8f); | |||
@@ -86,7 +101,7 @@ protected: | |||
// 3rd | |||
r.setY(3 + height*2/3); | |||
if (fClicked[6+i]) | |||
if (clicked[6+i]) | |||
glColor3f(0.8f, 0.5f, 0.3f); | |||
else | |||
glColor3f(0.3f, 0.5f, 0.8f); | |||
@@ -100,10 +115,10 @@ protected: | |||
if (ev.button != 1 || ! ev.press) | |||
return false; | |||
const int width = getWidth(); | |||
const int height = getHeight(); | |||
const uint width = this->getWidth(); | |||
const uint height = this->getHeight(); | |||
Rectangle<int> r; | |||
Rectangle<double> r; | |||
r.setWidth(width/3 - 6); | |||
r.setHeight(height/3 - 6); | |||
@@ -118,8 +133,8 @@ protected: | |||
if (r.contains(ev.pos)) | |||
{ | |||
fClicked[0+i] = !fClicked[0+i]; | |||
repaint(); | |||
clicked[0+i] = !clicked[0+i]; | |||
this->repaint(); | |||
break; | |||
} | |||
@@ -128,8 +143,8 @@ protected: | |||
if (r.contains(ev.pos)) | |||
{ | |||
fClicked[3+i] = !fClicked[3+i]; | |||
repaint(); | |||
clicked[3+i] = !clicked[3+i]; | |||
this->repaint(); | |||
break; | |||
} | |||
@@ -138,19 +153,22 @@ protected: | |||
if (r.contains(ev.pos)) | |||
{ | |||
fClicked[6+i] = !fClicked[6+i]; | |||
repaint(); | |||
clicked[6+i] = !clicked[6+i]; | |||
this->repaint(); | |||
break; | |||
} | |||
} | |||
return true; | |||
} | |||
private: | |||
bool fClicked[9]; | |||
}; | |||
typedef ExampleRectanglesWidget<SubWidget> ExampleRectanglesSubWidget; | |||
typedef ExampleRectanglesWidget<TopLevelWidget> ExampleRectanglesTopLevelWidget; | |||
typedef ExampleRectanglesWidget<StandaloneWindow> ExampleRectanglesStandaloneWindow; | |||
// ------------------------------------------------------ | |||
END_NAMESPACE_DGL | |||
#endif // EXAMPLE_RECTANGLES_WIDGET_HPP_INCLUDED |
@@ -1,6 +1,6 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2012-2021 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 | |||
@@ -20,25 +20,41 @@ | |||
// ------------------------------------------------------ | |||
// DGL Stuff | |||
#include "Widget.hpp" | |||
#include "Window.hpp" | |||
#include "../../dgl/SubWidget.hpp" | |||
#include "../../dgl/TopLevelWidget.hpp" | |||
START_NAMESPACE_DGL | |||
// ------------------------------------------------------ | |||
// our widget | |||
class ExampleShapesWidget : public Widget | |||
template <class BaseWidget> | |||
class ExampleShapesWidget : public BaseWidget | |||
{ | |||
Rectangle<int> bg; | |||
Rectangle<int> rect; | |||
Triangle<int> tri; | |||
Circle<int> cir; | |||
public: | |||
ExampleShapesWidget(Window& parent) | |||
: Widget(parent) | |||
static constexpr const char* const kExampleWidgetName = "Shapes"; | |||
explicit ExampleShapesWidget(Widget* const parentWidget) | |||
: BaseWidget(parentWidget) | |||
{ | |||
setSize(300, 300); | |||
this->setSize(300, 300); | |||
} | |||
ExampleShapesWidget(Widget* groupWidget) | |||
: Widget(groupWidget) | |||
explicit ExampleShapesWidget(Window& windowToMapTo) | |||
: BaseWidget(windowToMapTo) | |||
{ | |||
setSize(300, 300); | |||
this->setSize(300, 300); | |||
} | |||
explicit ExampleShapesWidget(Application& app) | |||
: BaseWidget(app) | |||
{ | |||
this->setSize(300, 300); | |||
} | |||
protected: | |||
@@ -95,14 +111,14 @@ protected: | |||
// circle | |||
cir = Circle<int>(width/2, height*2/3, height/6, 300); | |||
} | |||
private: | |||
Rectangle<int> bg; | |||
Rectangle<int> rect; | |||
Triangle<int> tri; | |||
Circle<int> cir; | |||
}; | |||
typedef ExampleShapesWidget<SubWidget> ExampleShapesSubWidget; | |||
typedef ExampleShapesWidget<TopLevelWidget> ExampleShapesTopLevelWidget; | |||
typedef ExampleShapesWidget<StandaloneWindow> ExampleShapesStandaloneWindow; | |||
// ------------------------------------------------------ | |||
END_NAMESPACE_DGL | |||
#endif // EXAMPLE_SHAPES_WIDGET_HPP_INCLUDED |