SayoriOS 0.3.3

render.c
1 #include "gui/basics.h"
2 #include "gui/pointutils.h"
3 #include "desktop/window.h"
4 #include "desktop/render.h"
5 #include "drv/psf.h"
6 #include "io/ports.h"
7 #include "drv/input/mouse.h"
8
9 // getConfigFonts(2) - is height of current font
10
11 Window_t* active_window = 0; // Window that should be placed over all windows (selected window)
12
13 bool dragging_mode = false;
14 bool click = false;
15 Window_t* drag_window = 0;
16
17 uint32_t dragx = 0;
18 uint32_t dragy = 0;
19
20 Window_t* focused = 0;
21
22 void gui_restore() {
23 destroy_all_windows();
24 clean_screen();
25
26 // setColorFont(0xffffff);
27 }
28
29 void gui_render_widgets(Window_t* window) {
30 for (size_t i = 0; i < window->widgets->size; i++) {
31 Widget_t* wgt = (Widget_t *) window->widgets->data[i];
32
33 wgt->x += window->x;
34 wgt->y += window->y;
35
36 wgt->renderer(wgt, window);
37
38 wgt->x -= window->x;
39 wgt->y -= window->y;
40 }
41 }
42
43 void gui_render_window(Window_t* window) {
44 if(!window) return;
45 if(window->state != DISPLAYING) return;
46
47 // Window canvas
48 draw_filled_rectangle(
49 window->x,
50 window->y,
51 window->width,
52 window->height,
53 window->canvas_bgcolor
54 );
55
56 draw_rectangle(window->x-1, window->y-1, window->width+1, window->height+1, 0x000000);
57
58 if(window->with_title_bar) {
59 // Window Titlebar
60 draw_filled_rectangle(window->x, window->y - WINDOW_TITLEBAR_HEIGHT, window->width, WINDOW_TITLEBAR_HEIGHT, WINDOW_TITLEBAR_COLOR);
61 // Window Title Text
62 draw_vga_str(window->title, strlen(window->title), window->x + 5, window->y - ((WINDOW_TITLEBAR_HEIGHT + 16) / 2), 0);
63 }
64
65 if(window->closable) {
66 draw_filled_rectangle(window->x + window->width - WINDOW_TITLEBAR_HEIGHT - 4, window->y - WINDOW_TITLEBAR_HEIGHT + 2, WINDOW_TITLEBAR_HEIGHT + 2, WINDOW_TITLEBAR_HEIGHT - 4, 0xdd0000);
67
68 draw_vga_str("X", 1,
69 window->x + window->width - WINDOW_TITLEBAR_HEIGHT + 5,
70 window->y - WINDOW_TITLEBAR_HEIGHT + 4,
71 0
72 );
73 }
74
75 gui_render_widgets(window);
76 }
77
78 Window_t* is_point_on_any_window_titlebar(size_t x, size_t y) {
79 for (size_t i = 0; i < get_window_count(); i++) {
80 struct Window* window = WINDOW(i);
81
82 if(window->with_title_bar && point_in_rect(
83 x,
84 y,
85 window->x,
86 window->y - WINDOW_TITLEBAR_HEIGHT,
87 window->width,
88 WINDOW_TITLEBAR_HEIGHT
89 )) {
90 return WINDOW(i);
91 }
92 }
93 return 0;
94 }
95
96 Window_t* is_point_on_any_window(ssize_t x, ssize_t y) {
97 for (size_t i = get_window_count() - 1; i != 0 ; i--) {
98 // qemu_log("Checking #%d (%x)", current_windows[i]->id, current_windows[i]);
99 if(point_in_rect(
100 x,
101 y,
102 WINDOW(i)->x,
103 WINDOW(i)->y,
104 WINDOW(i)->width,
105 WINDOW(i)->height
106 )) {
107 // qemu_log("It's: %d", current_windows[i]->id);
108 return WINDOW(i);
109 }
110 }
111 return 0;
112 }
113
114 size_t get_window_index(Window_t* win) {
115 for(size_t i = 0, wnds = get_window_count(); i < wnds; i++){
116 if(WINDOW(i) == win) {
117 return i;
118 }
119 }
120
121 return 0;
122 }
123
124 void gui_handle_mouse() {
125 uint32_t mouse_color = 0xff0000;
126
127 size_t mouse_x = mouse_get_x();
128 size_t mouse_y = mouse_get_y();
129
130 bool left_mouse = mouse_get_b1();
131 bool right_mouse = mouse_get_b2();
132
133 if(right_mouse){
134 mouse_color |= 0x00ff;
135 }else if(is_point_on_any_window_titlebar(mouse_x, mouse_y)) {
136 mouse_color = 0x00ff00;
137 }
138
139 if(left_mouse) {
140 Window_t* tmp = is_point_on_any_window_titlebar(mouse_x, mouse_y);
141 if(tmp && tmp->with_title_bar) {
142 if(point_in_rect(
143 mouse_x,
144 mouse_y,
145 tmp->x + tmp->width - WINDOW_TITLEBAR_HEIGHT - 4,
146 tmp->y - WINDOW_TITLEBAR_HEIGHT + 2,
147 WINDOW_TITLEBAR_HEIGHT + 2,
148 WINDOW_TITLEBAR_HEIGHT - 4
149 ) && !dragging_mode) {
150 if(tmp->on_close)
151 tmp->on_close(tmp);
152
153 window_destroy(tmp);
154 return;
155 }else if(!dragging_mode){
156 drag_window = tmp;
157 dragging_mode = true;
158
159 dragx = drag_window->x - mouse_x;
160 dragy = drag_window->y - mouse_y;
161
162 size_t sw = get_window_index(tmp);
163 size_t mw = get_window_index(focused);
164
165 if(sw < mw) {
166 // WINDOW(sw) = focused;
167 // WINDOW(mw) = tmp;
168
169 vector_swap(windows, sw, mw);
170 }
171
172 focused = tmp;
173 }
174 }else{
175 Window_t* win = is_point_on_any_window(mouse_x, mouse_y);
176 if(win && !dragging_mode && !click) {
177 click = true;
178
179 window_send_signal(win, WINDOW_CLICK, &(Coordinates_t){
180 mouse_x, mouse_y
181 });
182 qemu_log("End of click");
183 }
184 }
185 }
186
187 if(dragging_mode) {
188 // FIXME: Need correct formula to correct window dragging
189 drag_window->x = mouse_x + dragx;
190 drag_window->y = mouse_y + dragy;
191 }
192
193 if(dragging_mode && (!left_mouse)) {
194 drag_window = 0;
195 dragging_mode = false;
196 }
197
198 if(click && (!left_mouse)) {
199 click = false;
200 }
201
202 draw_filled_rectangle(mouse_x, mouse_y, 8, 8, mouse_color);
203 }
204
205 void gui_render_windows() {
206 for(size_t i = 0, wnds = get_window_count(); i < wnds; i++){
207 // qemu_warn("Rendering %x", WINDOW(i));
208 gui_render_window(WINDOW(i));
209 }
210 }
211
212 // Return exit status
213 void gui_render() {
214 if(windows == 0) {
215 draw_filled_rectangle(0, 0, getScreenWidth(), getScreenHeight(), 0x666666);
216 draw_vga_str("No windows in the system.", 25, (getScreenWidth() - 25 * 8) / 2, (getScreenHeight() - 8) / 2, 0);
217 punch();
218 return;
219 }
220
221 // qemu_log("Reached render step");
222 // qemu_log("Window count: %d", get_window_count());
223
224 gui_render_windows();
225
226 gui_handle_mouse();
227 punch();
228 }
strlen
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
mouse_x
uint32_t mouse_x
Позиция мыши по X.
Definition: mouse.c:19
mouse_y
uint32_t mouse_y
Позиция мыши по Y.
Definition: mouse.c:20
Coordinates
Definition: pointutils.h:5
Widget
Definition: widget.h:12
Window
Definition: window.h:25