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