126 lines
5.0 KiB
Rust
126 lines
5.0 KiB
Rust
// Copyright (c) 2021 Vladyslav Batyrenko
|
|
// SPDX-License-Identifier: MIT
|
|
//
|
|
// This code is vendored from bevy_egui: https://github.com/vladbat00/bevy_egui
|
|
// Original author: Vladyslav Batyrenko <vladyslav.batyrenko@gmail.com>
|
|
|
|
use super::{
|
|
EguiContext, EguiContextSettings, EguiFullOutput, EguiGlobalSettings, EguiOutput,
|
|
EguiRenderOutput, helpers, input::WindowToEguiContextMap,
|
|
};
|
|
use bevy::ecs::{
|
|
entity::Entity,
|
|
system::{Commands, Local, Query, Res},
|
|
};
|
|
use bevy::platform::collections::HashMap;
|
|
use bevy::window::CursorIcon;
|
|
|
|
/// Reads Egui output.
|
|
#[allow(clippy::too_many_arguments)]
|
|
pub fn process_output_system(
|
|
mut commands: Commands,
|
|
mut context_query: Query<(
|
|
Entity,
|
|
&mut EguiContext,
|
|
&mut EguiFullOutput,
|
|
&mut EguiRenderOutput,
|
|
&mut EguiOutput,
|
|
&EguiContextSettings,
|
|
)>,
|
|
#[cfg(all(feature = "manage_clipboard", not(target_os = "android")))]
|
|
mut egui_clipboard: bevy::ecs::system::ResMut<crate::EguiClipboard>,
|
|
// NOTE: RequestRedraw not used since we own winit and run unbounded (continuous redraws)
|
|
// mut request_redraw_writer: MessageWriter<RequestRedraw>,
|
|
mut last_cursor_icon: Local<HashMap<Entity, egui::CursorIcon>>,
|
|
egui_global_settings: Res<EguiGlobalSettings>,
|
|
window_to_egui_context_map: Res<WindowToEguiContextMap>,
|
|
) {
|
|
let mut should_request_redraw = false;
|
|
|
|
for (entity, mut context, mut full_output, mut render_output, mut egui_output, settings) in
|
|
context_query.iter_mut()
|
|
{
|
|
let ctx = context.get_mut();
|
|
let Some(full_output) = full_output.0.take() else {
|
|
bevy::log::error!(
|
|
"bevy_egui pass output has not been prepared (if EguiSettings::run_manually is set to true, make sure to call egui::Context::run or egui::Context::begin_pass and egui::Context::end_pass)"
|
|
);
|
|
continue;
|
|
};
|
|
let egui::FullOutput {
|
|
platform_output,
|
|
shapes,
|
|
textures_delta,
|
|
pixels_per_point,
|
|
viewport_output: _,
|
|
} = full_output;
|
|
|
|
let paint_jobs = ctx.tessellate(shapes, pixels_per_point);
|
|
|
|
render_output.paint_jobs = paint_jobs;
|
|
render_output.textures_delta = textures_delta;
|
|
egui_output.platform_output = platform_output;
|
|
|
|
for command in &egui_output.platform_output.commands {
|
|
match command {
|
|
egui::OutputCommand::CopyText(_text) =>
|
|
{
|
|
#[cfg(all(feature = "manage_clipboard", not(target_os = "android")))]
|
|
if !_text.is_empty() {
|
|
egui_clipboard.set_text(_text);
|
|
}
|
|
}
|
|
egui::OutputCommand::CopyImage(_image) => {
|
|
#[cfg(all(feature = "manage_clipboard", not(target_os = "android")))]
|
|
egui_clipboard.set_image(_image);
|
|
}
|
|
egui::OutputCommand::OpenUrl(_url) => {
|
|
#[cfg(feature = "open_url")]
|
|
{
|
|
let egui::output::OpenUrl { url, new_tab } = _url;
|
|
let target = if *new_tab {
|
|
"_blank"
|
|
} else {
|
|
settings
|
|
.default_open_url_target
|
|
.as_deref()
|
|
.unwrap_or("_self")
|
|
};
|
|
if let Err(err) = webbrowser::open_browser_with_options(
|
|
webbrowser::Browser::Default,
|
|
url,
|
|
webbrowser::BrowserOptions::new().with_target_hint(target),
|
|
) {
|
|
bevy::log::error!("Failed to open '{}': {:?}", url, err);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if egui_global_settings.enable_cursor_icon_updates
|
|
&& settings.enable_cursor_icon_updates
|
|
&& let Some(window_entity) = window_to_egui_context_map.context_to_window.get(&entity)
|
|
{
|
|
let last_cursor_icon = last_cursor_icon.entry(entity).or_default();
|
|
if *last_cursor_icon != egui_output.platform_output.cursor_icon {
|
|
commands
|
|
.entity(*window_entity)
|
|
.try_insert(CursorIcon::System(
|
|
helpers::egui_to_winit_cursor_icon(egui_output.platform_output.cursor_icon)
|
|
.unwrap_or(bevy::window::SystemCursorIcon::Default),
|
|
));
|
|
*last_cursor_icon = egui_output.platform_output.cursor_icon;
|
|
}
|
|
}
|
|
|
|
let needs_repaint = !render_output.is_empty();
|
|
should_request_redraw |= ctx.has_requested_repaint() && needs_repaint;
|
|
}
|
|
|
|
// NOTE: RequestRedraw not needed - we own winit and run unbounded (continuous redraws)
|
|
// if should_request_redraw {
|
|
// request_redraw_writer.write(RequestRedraw);
|
|
// }
|
|
}
|