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