*in progress*
[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         //TODO
96         //titlebar, frame
97
98         Rect intersect = rect_intersection(rect, dirty_region);
99         if(intersect.width && intersect.height) {
100                 if(callbacks.display) {
101                         callbacks.display(this);
102                 }
103                 dirty = false;
104
105                 draw_children(rect);
106         }
107 }
108
109 void Window::draw_children(const Rect &dirty_region)
110 {
111         for(size_t i=0; i<children.size(); i++) {
112                 children[i]->draw(dirty_region);
113         }
114 }
115
116 unsigned char *Window::get_win_start_on_fb()
117 {
118         unsigned char *fb = get_framebuffer();
119         Rect abs_rect = get_absolute_rect();
120         return fb + get_color_depth() * (get_screen_size().x * abs_rect.y + abs_rect.x) / 8;
121 }
122
123 int Window::get_scanline_width()
124 {
125         return get_screen_size().x;
126 }
127
128 void Window::set_managed(bool managed)
129 {
130         this->managed = managed;
131 }
132
133 bool Window::get_managed() const
134 {
135         return managed;
136 }
137
138 void Window::set_focusable(bool focusable)
139 {
140         this->focusable = focusable;
141 }
142
143 bool Window::get_focusable() const
144 {
145         return focusable;
146 }
147
148 void Window::set_display_callback(DisplayFuncType func)
149 {
150         callbacks.display = func;
151 }
152
153 void Window::set_keyboard_callback(KeyboardFuncType func)
154 {
155         callbacks.keyboard = func;
156 }
157
158 void Window::set_mouse_button_callback(MouseButtonFuncType func)
159 {
160         callbacks.button = func;
161 }
162
163 void Window::set_mouse_motion_callback(MouseMotionFuncType func)
164 {
165         callbacks.motion = func;
166 }
167
168 const DisplayFuncType Window::get_display_callback() const
169 {
170         return callbacks.display;
171 }
172
173 const KeyboardFuncType Window::get_keyboard_callback() const
174 {
175         return callbacks.keyboard;
176 }
177
178 const MouseButtonFuncType Window::get_mouse_button_callback() const
179 {
180         return callbacks.button;
181 }
182
183 const MouseMotionFuncType Window::get_mouse_motion_callback() const
184 {
185         return callbacks.motion;
186 }
187
188 void Window::add_child(Window *win)
189 {
190         children.push_back(win);
191         if(win->parent) {
192                 win->parent->remove_child(win);
193         }
194         win->parent = this;
195 }
196
197 void Window::remove_child(Window *win)
198 {
199         std::vector<Window*>::iterator it;
200         it = std::find(children.begin(), children.end(), win);
201         if(it != children.end()) {
202                 children.erase(it);
203                 win->parent = 0;
204         }
205 }
206
207 Window **Window::get_children()
208 {
209         if(children.empty()) {
210                 return 0;
211         }
212         return &children[0];
213 }
214
215 int Window::get_children_count() const
216 {
217         return (int)children.size();
218 }
219
220 const Window *Window::get_parent() const
221 {
222         return parent;
223 }
224
225 Window *Window::get_parent()
226 {
227         return parent;
228 }