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