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