/** * @file Window.cpp * @author apio (cloudapio.eu) * @brief UI windows. * * @copyright Copyright (c) 2023, the Luna authors. * */ #include #include #include #include #include #include namespace ui { Result Window::create(Rect rect, bool decorated) { auto window = TRY(make_owned()); ui::CreateWindowRequest request; request.rect = rect; request.decorated = decorated; auto response = TRY(os::IPC::send_sync(App::the().client(), request)); auto path = COPY_IPC_STRING(response.shm_path); u32* pixels = (u32*)TRY(os::SharedMemory::adopt(path.view(), rect.height * rect.width * 4)); window->m_canvas = ui::Canvas { rect.width, rect.height, rect.width, (u8*)pixels }; window->m_id = response.window; Window* p = window.ptr(); App::the().register_window(move(window), {}); return p; } Window::~Window() { if (m_canvas.ptr) munmap(m_canvas.ptr, ((usize)m_canvas.width) * ((usize)m_canvas.height) * 4); } void Window::set_title(StringView title) { ui::SetWindowTitleRequest request; request.window = m_id; SET_IPC_STRING(request.title, title.chars()); os::IPC::send_async(App::the().client(), request); } void Window::update() { ui::InvalidateRequest request; request.window = m_id; os::IPC::send_async(App::the().client(), request); } void Window::close() { App& app = App::the(); ui::CloseWindowRequest request; request.window = m_id; os::IPC::send_async(app.client(), request); if (this == app.main_window()) app.set_should_close(true); app.unregister_window(this, {}); } Result Window::draw() { if (m_background.has_value()) m_canvas.fill(*m_background); if (m_main_widget) TRY(m_main_widget->draw(m_canvas)); update(); return {}; } Result Window::handle_mouse_leave() { if (!m_main_widget) return ui::EventResult::DidNotHandle; return m_main_widget->handle_mouse_leave(); } Result Window::handle_mouse_move(ui::Point position) { if (!m_main_widget) return ui::EventResult::DidNotHandle; return m_main_widget->handle_mouse_move(position); } Result Window::handle_mouse_buttons(ui::Point position, int buttons) { if (!m_main_widget) return ui::EventResult::DidNotHandle; auto result = ui::EventResult::DidNotHandle; if (buttons) { auto rc = TRY(m_main_widget->handle_mouse_down(position, buttons)); if (rc == ui::EventResult::DidHandle) result = rc; } if (m_old_mouse_buttons.has_value()) { int old_buttons = m_old_mouse_buttons.value(); int diff = old_buttons & ~buttons; if (diff) { auto rc = TRY(m_main_widget->handle_mouse_up(position, diff)); if (rc == ui::EventResult::DidHandle) result = rc; } } m_old_mouse_buttons = buttons; return result; } Result Window::handle_key_event(const ui::KeyEventRequest& request) { if (!m_main_widget) return ui::EventResult::DidNotHandle; return m_main_widget->handle_key_event(request); } }