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