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 
17 #include "TopLevelWidgetPrivateData.hpp"
18 #include "WidgetPrivateData.hpp"
19 #include "WindowPrivateData.hpp"
20 #include "pugl.hpp"
21 
22 START_NAMESPACE_DGL
23 
24 // -----------------------------------------------------------------------
25 
PrivateData(TopLevelWidget * const s,Window & w)26 TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w)
27     : self(s),
28       selfw(s),
29       window(w)
30 {
31     window.pData->topLevelWidgets.push_back(self);
32 }
33 
~PrivateData()34 TopLevelWidget::PrivateData::~PrivateData()
35 {
36     window.pData->topLevelWidgets.remove(self);
37 }
38 
keyboardEvent(const KeyboardEvent & ev)39 bool TopLevelWidget::PrivateData::keyboardEvent(const KeyboardEvent& ev)
40 {
41     // ignore event if we are not visible
42     if (! selfw->pData->visible)
43         return false;
44 
45     // give top-level widget chance to catch this event first
46     if (self->onKeyboard(ev))
47         return true;
48 
49     // propagate event to all subwidgets recursively
50     return selfw->pData->giveKeyboardEventForSubWidgets(ev);
51 }
52 
specialEvent(const SpecialEvent & ev)53 bool TopLevelWidget::PrivateData::specialEvent(const SpecialEvent& ev)
54 {
55     // ignore event if we are not visible
56     if (! selfw->pData->visible)
57         return false;
58 
59     // give top-level widget chance to catch this event first
60     if (self->onSpecial(ev))
61         return true;
62 
63     // propagate event to all subwidgets recursively
64     return selfw->pData->giveSpecialEventForSubWidgets(ev);
65 }
66 
characterInputEvent(const CharacterInputEvent & ev)67 bool TopLevelWidget::PrivateData::characterInputEvent(const CharacterInputEvent& ev)
68 {
69     // ignore event if we are not visible
70     if (! selfw->pData->visible)
71         return false;
72 
73     // give top-level widget chance to catch this event first
74     if (self->onCharacterInput(ev))
75         return true;
76 
77     // propagate event to all subwidgets recursively
78     return selfw->pData->giveCharacterInputEventForSubWidgets(ev);
79 }
80 
mouseEvent(const MouseEvent & ev)81 bool TopLevelWidget::PrivateData::mouseEvent(const MouseEvent& ev)
82 {
83     // ignore event if we are not visible
84     if (! selfw->pData->visible)
85         return false;
86 
87     MouseEvent rev = ev;
88 
89     if (window.pData->autoScaling)
90     {
91         const double autoScaleFactor = window.pData->autoScaleFactor;
92 
93         rev.pos.setX(ev.pos.getX() / autoScaleFactor);
94         rev.pos.setY(ev.pos.getY() / autoScaleFactor);
95         rev.absolutePos.setX(ev.absolutePos.getX() / autoScaleFactor);
96         rev.absolutePos.setY(ev.absolutePos.getY() / autoScaleFactor);
97     }
98 
99     // give top-level widget chance to catch this event first
100     if (self->onMouse(ev))
101         return true;
102 
103     // propagate event to all subwidgets recursively
104     return selfw->pData->giveMouseEventForSubWidgets(rev);
105 }
106 
motionEvent(const MotionEvent & ev)107 bool TopLevelWidget::PrivateData::motionEvent(const MotionEvent& ev)
108 {
109     // ignore event if we are not visible
110     if (! selfw->pData->visible)
111         return false;
112 
113     MotionEvent rev = ev;
114 
115     if (window.pData->autoScaling)
116     {
117         const double autoScaleFactor = window.pData->autoScaleFactor;
118 
119         rev.pos.setX(ev.pos.getX() / autoScaleFactor);
120         rev.pos.setY(ev.pos.getY() / autoScaleFactor);
121         rev.absolutePos.setX(ev.absolutePos.getX() / autoScaleFactor);
122         rev.absolutePos.setY(ev.absolutePos.getY() / autoScaleFactor);
123     }
124 
125     // give top-level widget chance to catch this event first
126     if (self->onMotion(ev))
127         return true;
128 
129     // propagate event to all subwidgets recursively
130     return selfw->pData->giveMotionEventForSubWidgets(rev);
131 }
132 
scrollEvent(const ScrollEvent & ev)133 bool TopLevelWidget::PrivateData::scrollEvent(const ScrollEvent& ev)
134 {
135     // ignore event if we are not visible
136     if (! selfw->pData->visible)
137         return false;
138 
139     ScrollEvent rev = ev;
140 
141     if (window.pData->autoScaling)
142     {
143         const double autoScaleFactor = window.pData->autoScaleFactor;
144 
145         rev.pos.setX(ev.pos.getX() / autoScaleFactor);
146         rev.pos.setY(ev.pos.getY() / autoScaleFactor);
147         rev.absolutePos.setX(ev.absolutePos.getX() / autoScaleFactor);
148         rev.absolutePos.setY(ev.absolutePos.getY() / autoScaleFactor);
149         rev.delta.setX(ev.delta.getX() / autoScaleFactor);
150         rev.delta.setY(ev.delta.getY() / autoScaleFactor);
151     }
152 
153     // give top-level widget chance to catch this event first
154     if (self->onScroll(ev))
155         return true;
156 
157     // propagate event to all subwidgets recursively
158     return selfw->pData->giveScrollEventForSubWidgets(rev);
159 }
160 
fallbackOnResize()161 void TopLevelWidget::PrivateData::fallbackOnResize()
162 {
163     puglFallbackOnResize(window.pData->view);
164 }
165 
166 // -----------------------------------------------------------------------
167 
168 END_NAMESPACE_DGL
169