Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
@@ -100,9 +100,11 @@ void SubWidget::setAbsolutePos(const Point<int>& pos) noexcept | |||
pData->parentWidget->repaint(); | |||
} | |||
void SubWidget::repaint() noexcept | |||
{ | |||
if (! isVisible()) | |||
return; | |||
if (TopLevelWidget* const topw = getTopLevelWidget()) | |||
topw->repaint(getConstrainedAbsoluteArea()); | |||
} | |||
@@ -21,12 +21,6 @@ | |||
START_NAMESPACE_DGL | |||
#define FOR_EACH_WIDGET(it) \ | |||
for (std::list<Widget*>::iterator it = widgets.begin(); it != widgets.end(); ++it) | |||
#define FOR_EACH_WIDGET_INV(rit) \ | |||
for (std::list<Widget*>::reverse_iterator rit = widgets.rbegin(); rit != widgets.rend(); ++rit) | |||
// ----------------------------------------------------------------------- | |||
TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w) | |||
@@ -45,13 +39,10 @@ TopLevelWidget::PrivateData::~PrivateData() | |||
void TopLevelWidget::PrivateData::display() | |||
{ | |||
printf("TopLevelWidget::PrivateData::display INIT\n"); | |||
const Size<uint> size(window.getSize()); | |||
const uint width = size.getWidth(); | |||
const uint height = size.getHeight(); | |||
const double autoScaling = window.pData->autoScaling; | |||
printf("TopLevelWidget::PrivateData::display %i %i\n", width, height); | |||
// full viewport size | |||
glViewport(0, -(height * autoScaling - height), width * autoScaling, height * autoScaling); | |||
@@ -63,6 +54,26 @@ void TopLevelWidget::PrivateData::display() | |||
selfw->pData->displaySubWidgets(width, height, autoScaling); | |||
} | |||
void TopLevelWidget::PrivateData::mouseEvent(const Events::MouseEvent& ev) | |||
{ | |||
Events::MouseEvent rev = ev; | |||
const double autoScaling = window.pData->autoScaling; | |||
if (autoScaling != 1.0) | |||
{ | |||
rev.pos.setX(ev.pos.getX() / autoScaling); | |||
rev.pos.setY(ev.pos.getY() / autoScaling); | |||
} | |||
// give top-level widget chance to catch this event first | |||
if (self->onMouse(ev)) | |||
return; | |||
// propagate event to all subwidgets recursively | |||
selfw->pData->giveMouseEventForSubWidgets(rev); | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DGL |
@@ -33,6 +33,7 @@ struct TopLevelWidget::PrivateData { | |||
explicit PrivateData(TopLevelWidget* const s, Window& w); | |||
~PrivateData(); | |||
void display(); | |||
void mouseEvent(const Events::MouseEvent& ev); | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | |||
}; | |||
@@ -15,10 +15,17 @@ | |||
*/ | |||
#include "WidgetPrivateData.hpp" | |||
#include "../SubWidget.hpp" | |||
#include "../TopLevelWidget.hpp" | |||
START_NAMESPACE_DGL | |||
#define FOR_EACH_SUBWIDGET(it) \ | |||
for (std::list<SubWidget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) | |||
#define FOR_EACH_SUBWIDGET_INV(rit) \ | |||
for (std::list<SubWidget*>::reverse_iterator rit = subWidgets.rbegin(); rit != subWidgets.rend(); ++rit) | |||
// ----------------------------------------------------------------------- | |||
Widget::PrivateData::PrivateData(Widget* const s, TopLevelWidget* const tlw) | |||
@@ -48,17 +55,40 @@ Widget::PrivateData::~PrivateData() | |||
void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, const double scaling) | |||
{ | |||
printf("Widget::PrivateData::displaySubWidgets INIT | %lu\n", subWidgets.size()); | |||
if (subWidgets.size() == 0) | |||
return; | |||
for (std::list<SubWidget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) | |||
{ | |||
SubWidget* const subwidget(*it); | |||
printf("Widget::PrivateData::displaySubWidgets %i %i -> %p\n", width, height, subwidget); | |||
subwidget->pData->display(width, height, scaling); | |||
if (subwidget->isVisible()) | |||
subwidget->pData->display(width, height, scaling); | |||
} | |||
} | |||
void Widget::PrivateData::giveMouseEventForSubWidgets(Events::MouseEvent& ev) | |||
{ | |||
if (! visible) | |||
return; | |||
if (subWidgets.size() == 0) | |||
return; | |||
const double x = ev.pos.getX(); | |||
const double y = ev.pos.getY(); | |||
FOR_EACH_SUBWIDGET_INV(rit) | |||
{ | |||
SubWidget* const widget(*rit); | |||
if (! widget->isVisible()) | |||
continue; | |||
ev.pos = Point<double>(x - widget->getAbsoluteX(), | |||
y - widget->getAbsoluteY()); | |||
if (widget->onMouse(ev)) | |||
return; | |||
} | |||
} | |||
@@ -66,8 +96,6 @@ void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, | |||
TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const w) | |||
{ | |||
// if (TopLevelWidget* const tlw = dynamic_cast<TopLevelWidget*>(w)) | |||
// return tlw; | |||
if (w->pData->topLevelWidget != nullptr) | |||
return w->pData->topLevelWidget; | |||
if (w->pData->parentWidget != nullptr) | |||
@@ -41,10 +41,8 @@ struct Widget::PrivateData { | |||
explicit PrivateData(Widget* const s, Widget* const pw); | |||
~PrivateData(); | |||
// NOTE display function is different depending on build type, must call displaySubWidgets at the end | |||
// void display(uint width, uint height, double autoScaling, bool renderingSubWidget); | |||
void displaySubWidgets(uint width, uint height, double autoScaling); | |||
void giveMouseEventForSubWidgets(Events::MouseEvent& ev); | |||
static TopLevelWidget* findTopLevelWidget(Widget* const w); | |||
@@ -323,6 +323,19 @@ void Window::PrivateData::onPuglClose() | |||
close(); | |||
} | |||
void Window::PrivateData::onPuglMouse(const Events::MouseEvent& ev) | |||
{ | |||
DGL_DBGp("PUGL: onMouse : %i %i %f %f\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY()); | |||
// if (fModal.childFocus != nullptr) | |||
// return fModal.childFocus->focus(); | |||
#ifndef DPF_TEST_WINDOW_CPP | |||
if (topLevelWidget != nullptr) | |||
topLevelWidget->pData->mouseEvent(ev); | |||
#endif | |||
} | |||
static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose); | |||
PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) | |||
@@ -355,6 +368,20 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||
pData->onPuglCreate(); | |||
break; | |||
case PUGL_BUTTON_PRESS: ///< Mouse button pressed, a #PuglEventButton | |||
case PUGL_BUTTON_RELEASE: ///< Mouse button released, a #PuglEventButton | |||
{ | |||
Events::MouseEvent ev; | |||
ev.mod = event->button.state; | |||
ev.flags = event->button.flags; | |||
ev.time = static_cast<uint>(event->button.time * 1000.0 + 0.5); | |||
ev.button = event->button.button; | |||
ev.press = event->type == PUGL_BUTTON_PRESS; | |||
ev.pos = Point<double>(event->button.x, event->button.y); | |||
pData->onPuglMouse(ev); | |||
break; | |||
} | |||
// TODO | |||
default: | |||
break; | |||
@@ -18,6 +18,7 @@ | |||
#define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED | |||
#include "../Window.hpp" | |||
#include "../Events.hpp" | |||
#include "ApplicationPrivateData.hpp" | |||
#include "pugl.hpp" | |||
@@ -107,6 +108,7 @@ struct Window::PrivateData : IdleCallback { | |||
void onPuglReshape(int width, int height); | |||
void onPuglCreate(); | |||
void onPuglClose(); | |||
void onPuglMouse(const Events::MouseEvent& ev); | |||
// Pugl event handling entry point | |||
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); | |||
@@ -80,7 +80,6 @@ protected: | |||
void onDisplay() override | |||
{ | |||
const int iconSize = bgIcon.getWidth(); | |||
printf("LEFT SIDE WIDGET onDisplay %i\n", iconSize); | |||
glColor3f(0.027f, 0.027f, 0.027f); | |||
Rectangle<uint>(0, 0, getSize()).draw(); | |||
@@ -201,8 +200,8 @@ protected: | |||
void onResize(const ResizeEvent& ev) override | |||
{ | |||
const int width = ev.size.getWidth(); | |||
const int height = ev.size.getHeight(); | |||
const uint width = ev.size.getWidth(); | |||
const uint height = ev.size.getHeight(); | |||
bgIcon.setWidth(width-4); | |||
bgIcon.setHeight(width-4); | |||
@@ -299,11 +298,6 @@ protected: | |||
void onDisplay() override | |||
{ | |||
static int counter = 0; | |||
printf("print %i\n", ++counter); | |||
glColor3f(0.471f, 0.971f, 0.171f); | |||
Rectangle<uint>(0, 0, getSize()).draw(); | |||
} | |||
void onReshape(uint width, uint height) override | |||
@@ -340,28 +334,6 @@ 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 | |||
@@ -396,8 +368,6 @@ int main(int argc, char* argv[]) | |||
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"); | |||
} | |||
@@ -56,7 +56,7 @@ public: | |||
void init() | |||
{ | |||
this->setSize(300, 300); | |||
BaseWidget::setSize(300, 300); | |||
for (int i=0; i<9; ++i) | |||
clicked[i] = false; | |||
@@ -65,8 +65,8 @@ public: | |||
protected: | |||
void onDisplay() override | |||
{ | |||
const uint width = this->getWidth(); | |||
const uint height = this->getHeight(); | |||
const uint width = BaseWidget::getWidth(); | |||
const uint height = BaseWidget::getHeight(); | |||
Rectangle<double> r; | |||
@@ -115,8 +115,8 @@ protected: | |||
if (ev.button != 1 || ! ev.press) | |||
return false; | |||
const uint width = this->getWidth(); | |||
const uint height = this->getHeight(); | |||
const uint width = BaseWidget::getWidth(); | |||
const uint height = BaseWidget::getHeight(); | |||
Rectangle<double> r; | |||
@@ -134,7 +134,7 @@ protected: | |||
if (r.contains(ev.pos)) | |||
{ | |||
clicked[0+i] = !clicked[0+i]; | |||
this->repaint(); | |||
BaseWidget::repaint(); | |||
break; | |||
} | |||
@@ -144,7 +144,7 @@ protected: | |||
if (r.contains(ev.pos)) | |||
{ | |||
clicked[3+i] = !clicked[3+i]; | |||
this->repaint(); | |||
BaseWidget::repaint(); | |||
break; | |||
} | |||
@@ -154,7 +154,7 @@ protected: | |||
if (r.contains(ev.pos)) | |||
{ | |||
clicked[6+i] = !clicked[6+i]; | |||
this->repaint(); | |||
BaseWidget::repaint(); | |||
break; | |||
} | |||
} | |||