21ff70f00f4400e9eca1d03ceb9b2be1caab2684
[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 void Window::set_display_callback(DisplayFuncType func)
147 {
148         callbacks.display = func;
149 }
150
151 void Window::set_keyboard_callback(KeyboardFuncType func)
152 {
153         callbacks.keyboard = func;
154 }
155
156 void Window::set_mouse_button_callback(MouseButtonFuncType func)
157 {
158         callbacks.button = func;
159 }
160
161 void Window::set_mouse_motion_callback(MouseMotionFuncType func)
162 {
163         callbacks.motion = func;
164 }
165
166 const DisplayFuncType Window::get_display_callback() const
167 {
168         return callbacks.display;
169 }
170
171 const KeyboardFuncType Window::get_keyboard_callback() const
172 {
173         return callbacks.keyboard;
174 }
175
176 const MouseButtonFuncType Window::get_mouse_button_callback() const
177 {
178         return callbacks.button;
179 }
180
181 const MouseMotionFuncType Window::get_mouse_motion_callback() const
182 {
183         return callbacks.motion;
184 }
185
186 void Window::add_child(Window *win)
187 {
188         children.push_back(win);
189         if(win->parent) {
190                 win->parent->remove_child(win);
191         }
192         win->parent = this;
193 }
194
195 void Window::remove_child(Window *win)
196 {
197         std::vector<Window*>::iterator it;
198         it = std::find(children.begin(), children.end(), win);
199         if(it != children.end()) {
200                 children.erase(it);
201                 win->parent = 0;
202         }
203 }
204
205 Window **Window::get_children()
206 {
207         if(children.empty()) {
208                 return 0;
209         }
210         return &children[0];
211 }
212
213 int Window::get_children_count() const
214 {
215         return (int)children.size();
216 }
217
218 const Window *Window::get_parent() const
219 {
220         return parent;
221 }
222
223 Window *Window::get_parent()
224 {
225         return parent;
226 }