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){
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 }
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
uint32_t mouse_x
Позиция мыши по X.
Definition: mouse.c:19
uint32_t mouse_y
Позиция мыши по Y.
Definition: mouse.c:20
Definition: widget.h:12
Definition: window.h:25