summaryrefslogtreecommitdiff
path: root/applications/goldman/source
diff options
context:
space:
mode:
authorBenji Dial <benji@benjidial.net>2024-07-29 23:03:57 -0400
committerBenji Dial <benji@benjidial.net>2024-07-29 23:03:57 -0400
commit6cf7cd267b50fa68d7531655911620f17dde4a63 (patch)
treee936ab19c3176d1c5eced6e17847550ed1f420e3 /applications/goldman/source
parentc34b9191f258ddc15c5b45c000cd0266aed9dead (diff)
downloadhilbert-os-6cf7cd267b50fa68d7531655911620f17dde4a63.tar.gz
window moving and focusing
Diffstat (limited to 'applications/goldman/source')
-rw-r--r--applications/goldman/source/input.cpp36
-rw-r--r--applications/goldman/source/renderer.cpp29
-rw-r--r--applications/goldman/source/renderer.hpp20
-rw-r--r--applications/goldman/source/socket.cpp5
-rw-r--r--applications/goldman/source/window.cpp5
-rw-r--r--applications/goldman/source/window.hpp6
6 files changed, 89 insertions, 12 deletions
diff --git a/applications/goldman/source/input.cpp b/applications/goldman/source/input.cpp
index 0cd6922..c71068c 100644
--- a/applications/goldman/source/input.cpp
+++ b/applications/goldman/source/input.cpp
@@ -5,15 +5,51 @@
euler::syscall::set_thread_name("input thread");
+ window *window_being_moved = 0;
+ bool was_mouse_down_before = false;
+
while (true) {
auto result = euler::syscall::get_input_packet();
if (std::holds_alternative<euler::syscall::mouse_packet>(result)) {
auto packet = std::get<euler::syscall::mouse_packet>(result);
+
r->lock();
+
+ int old_x, old_y;
+ r->get_cursor(old_x, old_y);
r->bump_cursor(packet.x_changed, packet.y_changed);
+ int new_x, new_y;
+ r->get_cursor(new_x, new_y);
+
+ if (window_being_moved != 0) {
+ if (r->windows.size() == 0 || r->windows.back() != window_being_moved)
+ window_being_moved = 0;
+ else {
+ r->windows.back()->x += new_x - old_x;
+ r->windows.back()->y += new_y - old_y;
+ if (!packet.left_button_down)
+ window_being_moved = 0;
+ }
+ }
+
+ else if (packet.left_button_down && !was_mouse_down_before)
+ for (auto it = r->windows.rbegin(); it != r->windows.rend(); ++it)
+ if (new_x >= (*it)->x && new_y >= (*it)->y &&
+ new_x < (*it)->x + (*it)->contents_with_decorations. width &&
+ new_y < (*it)->y + (*it)->contents_with_decorations.height) {
+ r->move_window_to_front(--it.base());
+ //it is now invalidated, but our window is now r->windows.back()
+ if (new_y < r->windows.back()->y + window::title_height)
+ window_being_moved = r->windows.back();
+ break;
+ }
+
r->unlock();
r->dispatch_render();
+
+ was_mouse_down_before = packet.left_button_down;
+
}
}
diff --git a/applications/goldman/source/renderer.cpp b/applications/goldman/source/renderer.cpp
index 7a5e6b5..4d9beda 100644
--- a/applications/goldman/source/renderer.cpp
+++ b/applications/goldman/source/renderer.cpp
@@ -49,14 +49,15 @@ void renderer::do_render() {
double_buffer.copy_from(background, 0, 0);
- for (auto it = windows.begin(); it != windows.end(); ++it)
-
+ for (auto it = windows.begin(); it != windows.end(); ++it) {
+ int tx = (*it)->x, ty = (*it)->y, fx = 0, fy = 0;
+ int w = (*it)->contents_with_decorations.width;
+ int h = (*it)->contents_with_decorations.height;
+ daguerre::make_safe(tx, fx, w, 0, double_buffer.width);
+ daguerre::make_safe(ty, fy, h, 0, double_buffer.height);
double_buffer.copy_from(
- (*it)->contents_with_decorations, (*it)->x, (*it)->y, 0, 0,
- std::min((*it)->contents_with_decorations.width,
- double_buffer.width - (*it)->x),
- std::min((*it)->contents_with_decorations.height,
- double_buffer.height - (*it)->y));
+ (*it)->contents_with_decorations, tx, ty, fx, fy, w, h);
+ }
double_buffer.convert_from(
cursor_background, cursor, cursor_x, cursor_y, 0, 0,
@@ -79,6 +80,11 @@ void renderer::do_render() {
}
}
+void renderer::get_cursor(int &x_out, int &y_out) {
+ x_out = cursor_x;
+ y_out = cursor_y;
+}
+
void renderer::bump_cursor(int x_offset, int y_offset) {
cursor_x += x_offset;
@@ -95,6 +101,15 @@ void renderer::bump_cursor(int x_offset, int y_offset) {
}
+void renderer::move_window_to_front(std::list<window *>::iterator w) {
+ window *wp = *w;
+ windows.erase(w);
+ if (windows.size() != 0)
+ windows.back()->draw_decorations(false);
+ windows.push_back(wp);
+ wp->draw_decorations(true);
+}
+
void renderer::add_window(window *w) {
if (windows.size() != 0)
windows.back()->draw_decorations(false);
diff --git a/applications/goldman/source/renderer.hpp b/applications/goldman/source/renderer.hpp
index 91afe88..c2e82b2 100644
--- a/applications/goldman/source/renderer.hpp
+++ b/applications/goldman/source/renderer.hpp
@@ -17,9 +17,6 @@ class renderer {
int cursor_x;
int cursor_y;
- //bottom to top
- std::list<window *> windows;
-
std::mutex mut;
euler::syscall::stream_handle
@@ -28,6 +25,12 @@ class renderer {
void do_render();
public:
+ //all of the shown windows, sorted from furthest back to furthest front.
+ //while the renderer is not locked, the contents of this can change and
+ //iterators can be invalided. this should not be reordered, added to, or
+ //have elements removed from outside the renderer.
+ std::list<window *> windows;
+
renderer(
daguerre::image<daguerre::hilbert_color> &&framebuffer,
daguerre::image<daguerre::hilbert_color> &&background,
@@ -53,8 +56,19 @@ public:
euler::syscall::write_to_stream(dispatcher_handle_1, 1, &byte);
}
+ //gets the current position of the cursor. this should
+ //only be called while the renderer is locked.
+ void get_cursor(int &x_out, int &y_out);
+
+ //this adds x_offset and y_offset to the current cursor position, and then
+ //clamps the cursor position to have its top-left pixel inside the frame.
+ //this should only be called while the renderer is locked.
void bump_cursor(int x_offset, int y_offset);
+ //moves the pointed to window to the front of the window stack.
+ //this should only be called while the renderer is locked.
+ void move_window_to_front(std::list<window *>::iterator w);
+
void add_window(window *w);
void remove_window(window *w);
diff --git a/applications/goldman/source/socket.cpp b/applications/goldman/source/socket.cpp
index aa9b85e..79849df 100644
--- a/applications/goldman/source/socket.cpp
+++ b/applications/goldman/source/socket.cpp
@@ -129,7 +129,10 @@ struct socket_state {
euler::syscall::set_thread_name("socket thread");
- window *w = new window();
+ int x, y;
+ r->get_cursor(x, y);
+
+ window *w = new window(x, y);
socket_state *state = new socket_state {
.socket = socket, .w = w };
diff --git a/applications/goldman/source/window.cpp b/applications/goldman/source/window.cpp
index fe5212a..3f122ca 100644
--- a/applications/goldman/source/window.cpp
+++ b/applications/goldman/source/window.cpp
@@ -11,12 +11,16 @@ daguerre::hilbert_color border_color_not_top;
daguerre::hilbert_color title_color;
void window::set_size(int width, int height) {
+ int center_x = x + contents_with_decorations. width / 2;
+ int center_y = y + contents_with_decorations.height / 2;
contents_with_decorations =
daguerre::image<daguerre::hilbert_color>(width + 4, height + 18);
contents = daguerre::image<daguerre::hilbert_color>(
width, height,
&contents_with_decorations.at(2, 16),
contents_with_decorations.buffer_pitch, false);
+ x = center_x - contents_with_decorations. width / 2;
+ y = center_y - contents_with_decorations.height / 2;
}
void title_converter(
@@ -40,6 +44,7 @@ void window::draw_decorations(bool top) {
static_assert( decorations_extra_width == 4);
static_assert(decorations_extra_height == 18);
+ static_assert( title_height == 16);
auto border_color = top ? border_color_top : border_color_not_top;
diff --git a/applications/goldman/source/window.hpp b/applications/goldman/source/window.hpp
index 5c2d7a0..380e25b 100644
--- a/applications/goldman/source/window.hpp
+++ b/applications/goldman/source/window.hpp
@@ -6,6 +6,7 @@ struct window {
static constexpr int decorations_extra_width = 4;
static constexpr int decorations_extra_height = 18;
+ static constexpr int title_height = 16;
daguerre::image<daguerre::hilbert_color> contents_with_decorations;
daguerre::image<daguerre::hilbert_color> contents;
@@ -20,7 +21,10 @@ struct window {
void set_size(int width, int height);
void draw_decorations(bool top);
- inline window() : x(0), y(0), is_shown(false) {
+ inline window(int center_x, int center_y)
+ : x(center_x - decorations_extra_width / 2),
+ y(center_y - decorations_extra_height / 2),
+ is_shown(false) {
set_size(0, 0);
draw_decorations(false);
}