ca8bdbc7a88b7e70f511bcd2591118ae16604975
[winnie] / src / window.cc
1 #include <algorithm>
2 #include <stdio.h> //TODO
3 #include <string.h>
4
5 #include "gfx.h"
6 #include "window.h"
7 #include "wm.h"
8
9 Window::Window()
10 {
11         parent = 0;
12         title = 0;
13         rect.x = rect.y = 0;
14         rect.width = rect.height = 128;
15         memset(&callbacks, 0, sizeof callbacks);
16         dirty = true;
17         managed = true;
18         focusable = true;
19         state = STATE_NORMAL;
20 }
21
22 Window::~Window()
23 {
24         for(size_t i=0; i<children.size(); i++) {
25                 wm->remove_window(children[i]);
26                 delete children[i];
27         }
28
29         delete [] title;
30 }
31
32 const Rect &Window::get_rect() const
33 {
34         return rect;
35 }
36
37 Rect Window::get_absolute_rect() const
38 {
39         if(!parent) {
40                 return rect;
41         }
42
43         Rect absolute_rect;
44         absolute_rect = parent->get_absolute_rect();
45
46         absolute_rect.x += rect.x;
47         absolute_rect.y += rect.y;
48         absolute_rect.width = rect.width;
49         absolute_rect.height = rect.height;
50
51         return absolute_rect;
52 }
53
54 bool Window::contains_point(int ptr_x, int ptr_y)
55 {
56         Rect abs_rect = get_absolute_rect();
57         return ptr_x >= abs_rect.x && ptr_x < abs_rect.x + abs_rect.width &&
58                         ptr_y >= abs_rect.y && ptr_y < abs_rect.y + abs_rect.height;
59 }
60
61 void Window::move(int x, int y)
62 {
63         invalidate();   // moved, should redraw, MUST BE CALLED FIRST
64         rect.x = x;
65         rect.y = y;
66 }
67
68 void Window::resize(int x, int y)
69 {
70         invalidate();   // resized, should redraw, MUST BE CALLED FIRST
71         rect.width = x;
72         rect.height = y;
73 }
74
75 void Window::set_title(const char *s)
76 {
77         delete [] title;
78
79         title = new char[strlen(s) + 1];
80         strcpy(title, s);
81 }
82
83 const char *Window::get_title() const
84 {
85         return title;
86 }
87
88 void Window::invalidate()
89 {
90         dirty = true;
91         Rect abs_rect = get_absolute_rect();
92         wm->invalidate_region(abs_rect);
93 }
94
95 void Window::draw(Rect *dirty_region)
96 {
97         Rect abs_rect = get_absolute_rect();
98         Rect intersect = rect_intersection(abs_rect, *dirty_region);
99         if(intersect.width && intersect.height) {
100                 Rect prev_clip = get_clipping_rect();
101                 set_clipping_rect(abs_rect);
102                 
103                 if(callbacks.display) {
104                         callbacks.display(this);
105                 }
106                 dirty = false;
107
108                 draw_children(abs_rect);
109                 
110                 *dirty_region = rect_union(*dirty_region, abs_rect);
111                 set_clipping_rect(prev_clip);
112         }
113 }
114
115 void Window::draw_children(const Rect &dirty_region)
116 {
117         Rect drect = dirty_region;
118         for(size_t i=0; i<children.size(); i++) {
119                 children[i]->draw(&drect);
120         }
121 }
122
123 unsigned char *Window::get_win_start_on_fb()
124 {
125         unsigned char *fb = get_framebuffer();
126         Rect abs_rect = get_absolute_rect();
127         return fb + get_color_depth() * (get_screen_size().x * abs_rect.y + abs_rect.x) / 8;
128 }
129
130 int Window::get_scanline_width()
131 {
132         return get_screen_size().x;
133 }
134
135 void Window::set_managed(bool managed)
136 {
137         this->managed = managed;
138 }
139
140 bool Window::get_managed() const
141 {
142         return managed;
143 }
144
145 void Window::set_focusable(bool focusable)
146 {
147         this->focusable = focusable;
148 }
149
150 bool Window::get_focusable() const
151 {
152         return focusable;
153 }
154
155 bool Window::get_dirty() const
156 {
157         return dirty;
158 }
159
160 void Window::set_display_callback(DisplayFuncType func)
161 {
162         callbacks.display = func;
163 }
164
165 void Window::set_keyboard_callback(KeyboardFuncType func)
166 {
167         callbacks.keyboard = func;
168 }
169
170 void Window::set_mouse_button_callback(MouseButtonFuncType func)
171 {
172         callbacks.button = func;
173 }
174
175 void Window::set_mouse_motion_callback(MouseMotionFuncType func)
176 {
177         callbacks.motion = func;
178 }
179
180 const DisplayFuncType Window::get_display_callback() const
181 {
182         return callbacks.display;
183 }
184
185 const KeyboardFuncType Window::get_keyboard_callback() const
186 {
187         return callbacks.keyboard;
188 }
189
190 const MouseButtonFuncType Window::get_mouse_button_callback() const
191 {
192         return callbacks.button;
193 }
194
195 const MouseMotionFuncType Window::get_mouse_motion_callback() const
196 {
197         return callbacks.motion;
198 }
199
200 void Window::add_child(Window *win)
201 {
202         children.push_back(win);
203         if(win->parent) {
204                 win->parent->remove_child(win);
205         }
206         win->parent = this;
207 }
208
209 void Window::remove_child(Window *win)
210 {
211         std::vector<Window*>::iterator it;
212         it = std::find(children.begin(), children.end(), win);
213         if(it != children.end()) {
214                 children.erase(it);
215                 win->parent = 0;
216         }
217 }
218
219 Window **Window::get_children()
220 {
221         if(children.empty()) {
222                 return 0;
223         }
224         return &children[0];
225 }
226
227 int Window::get_children_count() const
228 {
229         return (int)children.size();
230 }
231
232 const Window *Window::get_parent() const
233 {
234         return parent;
235 }
236
237 Window *Window::get_parent()
238 {
239         return parent;
240 }
241
242 void Window::set_state(State state)
243 {
244         this->state = state;
245 }
246
247 Window::State Window::get_state() const
248 {
249         return state;
250 }