use super::init::format_entity_name;
use crate::ecs::drag::WindowDragging;
use crate::ecs::graphics::GraphicsCore;
use crate::ecs::graphics::wuc_resource::WucGraphicsResource;
use crate::ecs::widget::bitmap_source::BitmapSourceGraphics;
use crate::ecs::window::transition_diag::{ORIGIN_WINDOW_POS, WriteTag};
use crate::ecs::window::{SetWindowPosCommand, Window, WindowHandle, WindowPos};
use bevy_ecs::name::Name;
use bevy_ecs::prelude::*;
use tracing::{debug, trace, warn};
use windows::Win32::UI::WindowsAndMessaging::SWP_NOMOVE;
pub fn apply_window_pos_changes(
query: Query<
(
Entity,
&WindowHandle,
&WindowPos,
Option<&Name>,
Has<WindowDragging>,
),
(Changed<WindowPos>, With<Window>),
>,
) {
for (entity, window_handle, window_pos, name, is_dragging) in query.iter() {
let entity_name = format_entity_name(entity, name);
let position = window_pos.position.unwrap_or_default();
let size = window_pos.size.unwrap_or_default();
if position.x == windows::Win32::UI::WindowsAndMessaging::CW_USEDEFAULT
|| size.width == windows::Win32::UI::WindowsAndMessaging::CW_USEDEFAULT
{
trace!(
entity = %entity_name,
x = position.x,
y = position.y,
width = size.width,
height = size.height,
"[apply_window_pos_changes] CW_USEDEFAULT detected, skipping"
);
continue;
}
let (x, y, width, height) = match window_pos.to_window_coords(window_handle) {
Ok(coords) => coords,
Err(e) => {
warn!(
entity = %entity_name,
error = %e,
"[apply_window_pos_changes] Failed to transform window coordinates. Using original values."
);
(position.x, position.y, size.width, size.height)
}
};
let mut flags = window_pos.build_flags_for_system();
let hwnd_insert_after = window_pos.get_hwnd_insert_after();
if is_dragging {
flags |= SWP_NOMOVE;
}
debug!(
entity = %entity_name,
client_xy = format_args!("({},{})", position.x, position.y),
client_size = format_args!("{}x{}", size.width, size.height),
win_xy = format_args!("({},{})", x, y),
win_size = format_args!("{}x{}", width, height),
is_dragging = is_dragging,
"[apply_window_pos] Enqueue SetWindowPos"
);
let cmd = SetWindowPosCommand::new(
window_handle.hwnd,
x,
y,
width,
height,
flags,
hwnd_insert_after,
)
.with_tag(WriteTag {
origin: ORIGIN_WINDOW_POS,
..WriteTag::UNTAGGED
});
SetWindowPosCommand::enqueue(cmd);
debug!(
entity = %entity_name,
x = position.x,
y = position.y,
width = size.width,
height = size.height,
"[apply_window_pos_changes] Command enqueued"
);
}
}
pub fn invalidate_dependent_components(
graphics: Option<Res<GraphicsCore>>,
wuc_resource: Option<ResMut<WucGraphicsResource>>,
mut bitmap_source_query: Query<&mut BitmapSourceGraphics>,
) {
if let Some(gc) = graphics {
if !gc.is_valid() {
warn!(
"[invalidate_dependent_components] GraphicsCore invalid - invalidating all dependent components"
);
if let Some(mut wgr) = wuc_resource {
wgr.invalidate();
}
for mut bsg in bitmap_source_query.iter_mut() {
bsg.invalidate();
}
}
}
}