1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /***************************************************************************
3 * window.cc
4 *
5 * Sun Oct 9 13:11:53 CEST 2011
6 * Copyright 2011 Bent Bisballe Nyeng
7 * deva@aasimon.org
8 ****************************************************************************/
9
10 /*
11 * This file is part of DrumGizmo.
12 *
13 * DrumGizmo is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * DrumGizmo is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with DrumGizmo; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 */
27 #include "window.h"
28
29 #include <cstring>
30
31 #include "painter.h"
32
33 #ifndef UI_PUGL
34 #ifdef UI_X11
35 #include "nativewindow_x11.h"
36 #endif // UI_X11
37 #ifdef UI_WIN32
38 #include "nativewindow_win32.h"
39 #endif // UI_WIN32
40 #ifdef UI_COCOA
41 #include "nativewindow_cocoa.h"
42 #endif // UI_COCOA
43 #else
44 #include "nativewindow_pugl.h"
45 #endif // !UI_PUGL
46
47 namespace GUI
48 {
49
Window(void * native_window)50 Window::Window(void* native_window)
51 : Widget(nullptr)
52 , wpixbuf(1, 1)
53 {
54 // Make sure we have a valid size when initialising the NativeWindow
55 _width = wpixbuf.width;
56 _height = wpixbuf.height;
57
58 #ifndef UI_PUGL
59 #ifdef UI_X11
60 native = new NativeWindowX11(native_window, *this);
61 #endif // UI_X11
62 #ifdef UI_WIN32
63 native = new NativeWindowWin32(native_window, *this);
64 #endif // UI_WIN32
65 #ifdef UI_COCOA
66 native = new NativeWindowCocoa(native_window, *this);
67 #endif // UI_COCOA
68 #else
69 // Use pugl
70 native = new NativeWindowPugl(native_window, *this);
71 #endif // !UI_PUGL
72
73 eventhandler = new EventHandler(*native, *this);
74
75 setVisible(true); // The root widget is always visible.
76 }
77
~Window()78 Window::~Window()
79 {
80 delete native;
81 delete eventhandler;
82 }
83
setFixedSize(int w,int h)84 void Window::setFixedSize(int w, int h)
85 {
86 native->setFixedSize(w, h);
87 }
88
setAlwaysOnTop(bool always_on_top)89 void Window::setAlwaysOnTop(bool always_on_top)
90 {
91 native->setAlwaysOnTop(always_on_top);
92 }
93
setCaption(const std::string & caption)94 void Window::setCaption(const std::string& caption)
95 {
96 native->setCaption(caption);
97 }
98
99 //! This overload the resize method on Widget and simply requests a window resize
100 //! on the windowmanager/OS. The resized() method is called by the event handler
101 //! once the window has been resized.
resize(std::size_t width,std::size_t height)102 void Window::resize(std::size_t width, std::size_t height)
103 {
104 native->resize(width, height);
105 }
106
107 //! This overload the move method on Widget and simply requests a window move
108 //! on the windowmanager/OS. The moved() method is called by the event handler
109 //! once the window has been moved.
move(int x,int y)110 void Window::move(int x, int y)
111 {
112 native->move(x, y);
113 }
114
show()115 void Window::show()
116 {
117 Widget::show();
118 redraw();
119 native->show();
120 }
121
hide()122 void Window::hide()
123 {
124 native->hide();
125 Widget::hide();
126 }
127
window()128 Window* Window::window()
129 {
130 return this;
131 }
132
getNativeSize()133 Size Window::getNativeSize()
134 {
135 auto sz = native->getSize();
136 return {sz.first, sz.second};
137 }
138
getImageCache()139 ImageCache& Window::getImageCache()
140 {
141 return image_cache;
142 }
143
eventHandler()144 EventHandler* Window::eventHandler()
145 {
146 return eventhandler;
147 }
148
keyboardFocus()149 Widget* Window::keyboardFocus()
150 {
151 return _keyboardFocus;
152 }
153
setKeyboardFocus(Widget * widget)154 void Window::setKeyboardFocus(Widget* widget)
155 {
156 auto oldFocusWidget = _keyboardFocus;
157 _keyboardFocus = widget;
158
159 if(oldFocusWidget)
160 {
161 oldFocusWidget->redraw();
162 }
163
164 if(_keyboardFocus)
165 {
166 _keyboardFocus->redraw();
167 }
168 }
169
buttonDownFocus()170 Widget* Window::buttonDownFocus()
171 {
172 return _buttonDownFocus;
173 }
174
setButtonDownFocus(Widget * widget)175 void Window::setButtonDownFocus(Widget* widget)
176 {
177 _buttonDownFocus = widget;
178 native->grabMouse(widget != nullptr);
179 }
180
mouseFocus()181 Widget* Window::mouseFocus()
182 {
183 return _mouseFocus;
184 }
185
setMouseFocus(Widget * widget)186 void Window::setMouseFocus(Widget* widget)
187 {
188 _mouseFocus = widget;
189
190 }
191
needsRedraw()192 void Window::needsRedraw()
193 {
194 needs_redraw = true;
195 }
196
getNativeWindowHandle() const197 void* Window::getNativeWindowHandle() const
198 {
199 return native->getNativeWindowHandle();
200 }
201
translateToScreen(const Point & point)202 Point Window::translateToScreen(const Point& point)
203 {
204 return native->translateToScreen(point);
205 }
206
translateToWindowX()207 std::size_t Window::translateToWindowX()
208 {
209 return 0;
210 }
211
translateToWindowY()212 std::size_t Window::translateToWindowY()
213 {
214 return 0;
215 }
216
217 //! Called by event handler when an windowmanager/OS window resize event has
218 //! been received. Do not call this directly.
resized(std::size_t width,std::size_t height)219 void Window::resized(std::size_t width, std::size_t height)
220 {
221 auto size = native->getSize();
222 if((wpixbuf.width != size.first) ||
223 (wpixbuf.height != size.second))
224 {
225 wpixbuf.realloc(size.first, size.second);
226 Widget::resize(size.first, size.second);
227 }
228
229 updateBuffer();
230 }
231
232 //! Called by event handler when an windowmanager/OS window move event has
233 //! been received. Do not call this directly.
moved(int x,int y)234 void Window::moved(int x, int y)
235 {
236 // Make sure widget coordinates are updated.
237 Widget::move(x, y);
238 }
239
updateBuffer()240 bool Window::updateBuffer()
241 {
242 if(!native)
243 {
244 return false;
245 }
246
247 if(!needs_redraw)
248 {
249 // Nothing changed, don't update anything.
250 return false;
251 }
252
253 auto pixel_buffers = getPixelBuffers();
254
255 auto dirty_rect = wpixbuf.updateBuffer(pixel_buffers);
256
257 if(!dirty_rect.empty())
258 {
259 native->redraw(dirty_rect);
260 }
261 needs_redraw = false;
262
263 return true;
264 }
265
266 } // GUI::
267