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