diff --git a/base/usr/share/icons/16x16/app-close.tga b/base/usr/share/icons/16x16/app-close.tga new file mode 100644 index 00000000..9ced1838 Binary files /dev/null and b/base/usr/share/icons/16x16/app-close.tga differ diff --git a/wind/Mouse.cpp b/wind/Mouse.cpp index 546e7765..d0518ff2 100644 --- a/wind/Mouse.cpp +++ b/wind/Mouse.cpp @@ -43,19 +43,29 @@ void Mouse::update(const moon::MousePacket& packet) for (Window* window = g_windows.last().value_or(nullptr); window; window = g_windows.previous(window).value_or(nullptr)) { - if (window->surface.absolute(window->titlebar).contains(m_position)) + if (window->surface.absolute(window->close_button).contains(m_position)) + { + // Close button pressed + g_windows.remove(window); + delete window; + break; + } + else if (window->surface.absolute(window->titlebar).contains(m_position)) { m_dragging_window = window; - m_initial_drag_position = - ui::Point { m_position.x - window->surface.pos.x, m_position.y - window->surface.pos.y }; + m_initial_drag_position = window->surface.relative(m_position); os::println("Started drag: window at (%d,%d,%d,%d) with offset (%d,%d)", window->surface.pos.x, window->surface.pos.y, window->surface.width, window->surface.height, m_initial_drag_position.x, m_initial_drag_position.y); window->focus(); + break; } else if (window->surface.absolute(window->contents).contains(m_position)) + { + window->focus(); break; // We don't want to continue iterating, otherwise this would take into account windows whose // titlebar is underneath another window's contents! + } } } } diff --git a/wind/Window.cpp b/wind/Window.cpp index 66638f2b..09306bef 100644 --- a/wind/Window.cpp +++ b/wind/Window.cpp @@ -2,9 +2,12 @@ #include #include #include +#include LinkedList g_windows; +static SharedPtr g_close_icon; + void Window::draw(ui::Canvas& screen) { auto window = screen.subcanvas(surface); @@ -21,6 +24,12 @@ void Window::draw(ui::Canvas& screen) auto textarea = titlebar_canvas.subcanvas(ui::Rect { 10, 10, titlebar_canvas.width - 10, titlebar_canvas.height }); font->render(buffer, ui::BLACK, textarea); + + if (g_close_icon) + { + auto close_area = window.subcanvas(close_button); + close_area.fill(g_close_icon->pixels(), g_close_icon->width()); + } } void Window::focus() @@ -34,6 +43,9 @@ Window::Window(ui::Rect r, ui::Color c, StringView n) : surface(r), color(c), na { auto font = ui::Font::default_font(); titlebar = ui::Rect { 0, 0, surface.width, font->height() + 20 }; + close_button = ui::Rect { surface.width - 26, 10, 16, 16 }; contents = ui::Rect { 0, font->height() + 20, surface.width, surface.height - (font->height() + 20) }; g_windows.append(this); + + if (!g_close_icon) g_close_icon = ui::Image::load("/usr/share/icons/16x16/app-close.tga").value_or({}); } diff --git a/wind/Window.h b/wind/Window.h index 7b529413..86f638d2 100644 --- a/wind/Window.h +++ b/wind/Window.h @@ -9,6 +9,7 @@ struct Window : public LinkedListNode { ui::Rect surface; ui::Rect titlebar; + ui::Rect close_button; ui::Rect contents; ui::Color color; StringView name;