mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-11-03 19:04:23 +00:00
feat: add popup positioning
This commit is contained in:
parent
18d1391dee
commit
ec08429413
5 changed files with 77 additions and 15 deletions
|
|
@ -5,7 +5,10 @@ pub mod rendering;
|
|||
pub mod wayland;
|
||||
|
||||
pub use rendering::femtovg::popup_window::PopupWindow;
|
||||
pub use rendering::slint_integration::platform::close_current_popup;
|
||||
pub use rendering::slint_integration::platform::{
|
||||
clear_popup_position_override, close_current_popup, get_popup_position_override,
|
||||
set_popup_position_override,
|
||||
};
|
||||
|
||||
pub mod platform {
|
||||
pub use slint;
|
||||
|
|
|
|||
|
|
@ -24,11 +24,41 @@ pub fn close_current_popup() {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn set_popup_position_override(x: f32, y: f32) {
|
||||
CURRENT_PLATFORM.with(|platform| {
|
||||
if let Some(weak_platform) = platform.borrow().as_ref() {
|
||||
if let Some(strong_platform) = weak_platform.upgrade() {
|
||||
strong_platform.set_popup_position(x, y);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_popup_position_override() -> Option<(f32, f32)> {
|
||||
CURRENT_PLATFORM.with(|platform| {
|
||||
platform.borrow().as_ref()
|
||||
.and_then(Weak::upgrade)
|
||||
.and_then(|strong| strong.get_popup_position())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn clear_popup_position_override() {
|
||||
CURRENT_PLATFORM.with(|platform| {
|
||||
if let Some(weak_platform) = platform.borrow().as_ref() {
|
||||
if let Some(strong_platform) = weak_platform.upgrade() {
|
||||
strong_platform.clear_popup_position();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub struct CustomSlintPlatform {
|
||||
main_window: Weak<FemtoVGWindow>,
|
||||
popup_creator: RefCell<Option<Rc<PopupCreator>>>,
|
||||
first_call: Cell<bool>,
|
||||
last_popup: RefCell<Option<Weak<PopupWindow>>>,
|
||||
popup_position: RefCell<Option<(f32, f32)>>,
|
||||
}
|
||||
|
||||
impl CustomSlintPlatform {
|
||||
|
|
@ -39,6 +69,7 @@ impl CustomSlintPlatform {
|
|||
popup_creator: RefCell::new(None),
|
||||
first_call: Cell::new(true),
|
||||
last_popup: RefCell::new(None),
|
||||
popup_position: RefCell::new(None),
|
||||
});
|
||||
|
||||
CURRENT_PLATFORM.with(|current| {
|
||||
|
|
@ -68,6 +99,19 @@ impl CustomSlintPlatform {
|
|||
}
|
||||
*self.last_popup.borrow_mut() = None;
|
||||
}
|
||||
|
||||
pub fn set_popup_position(&self, x: f32, y: f32) {
|
||||
*self.popup_position.borrow_mut() = Some((x, y));
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_popup_position(&self) -> Option<(f32, f32)> {
|
||||
*self.popup_position.borrow()
|
||||
}
|
||||
|
||||
pub fn clear_popup_position(&self) {
|
||||
*self.popup_position.borrow_mut() = None;
|
||||
}
|
||||
}
|
||||
|
||||
impl Platform for CustomSlintPlatform {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
use crate::errors::{LayerShikaError, Result};
|
||||
use crate::rendering::egl::context::EGLContext;
|
||||
use crate::rendering::femtovg::popup_window::PopupWindow;
|
||||
use crate::rendering::slint_integration::platform::{
|
||||
clear_popup_position_override, get_popup_position_override,
|
||||
};
|
||||
use log::info;
|
||||
use slab::Slab;
|
||||
use slint::{platform::femtovg_renderer::FemtoVGRenderer, PhysicalSize, WindowSize};
|
||||
|
|
@ -93,6 +96,15 @@ impl PopupManager {
|
|||
}
|
||||
})?;
|
||||
|
||||
let pointer_position = if let Some((x, y)) = get_popup_position_override() {
|
||||
info!("Using explicit popup position: ({}, {})", x, y);
|
||||
clear_popup_position_override();
|
||||
slint::LogicalPosition::new(x, y)
|
||||
} else {
|
||||
log::error!("No popup position provided - using (0, 0) as fallback");
|
||||
slint::LogicalPosition::new(0.0, 0.0)
|
||||
};
|
||||
|
||||
let scale_factor = *self.current_scale_factor.borrow();
|
||||
let output_size = *self.current_output_size.borrow();
|
||||
info!(
|
||||
|
|
@ -120,7 +132,7 @@ impl PopupManager {
|
|||
fractional_scale_manager: self.context.fractional_scale_manager.as_ref(),
|
||||
viewporter: self.context.viewporter.as_ref(),
|
||||
queue_handle,
|
||||
position: slint::LogicalPosition::new(0.0, 0.0),
|
||||
position: pointer_position,
|
||||
size: popup_size,
|
||||
scale_factor,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -108,23 +108,23 @@ impl PopupSurface {
|
|||
.xdg_wm_base
|
||||
.create_positioner(params.queue_handle, ());
|
||||
|
||||
let x = (params.position.x * params.scale_factor) as i32;
|
||||
let y = (params.position.y * params.scale_factor) as i32;
|
||||
let width = params.size.width as i32;
|
||||
let height = params.size.height as i32;
|
||||
let x = params.position.x as i32;
|
||||
let y = params.position.y as i32;
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
let logical_width = (params.size.width as f32 / params.scale_factor) as i32;
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
let logical_height = (params.size.height as f32 / params.scale_factor) as i32;
|
||||
|
||||
positioner.set_anchor_rect(x, y, 1, 1);
|
||||
positioner.set_size(width, height);
|
||||
positioner.set_size(logical_width, logical_height);
|
||||
positioner.set_anchor(Anchor::TopLeft);
|
||||
positioner.set_gravity(Gravity::BottomRight);
|
||||
positioner.set_constraint_adjustment(
|
||||
ConstraintAdjustment::SlideX
|
||||
| ConstraintAdjustment::SlideY
|
||||
| ConstraintAdjustment::FlipX
|
||||
| ConstraintAdjustment::FlipY
|
||||
| ConstraintAdjustment::ResizeX
|
||||
| ConstraintAdjustment::ResizeY,
|
||||
);
|
||||
positioner.set_constraint_adjustment(ConstraintAdjustment::None);
|
||||
|
||||
positioner
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ pub use builder::LayerShika;
|
|||
pub use layer_shika_adapters::PopupWindow;
|
||||
pub use layer_shika_adapters::close_current_popup;
|
||||
pub use layer_shika_adapters::platform::{calloop, slint, slint_interpreter};
|
||||
pub use layer_shika_adapters::{
|
||||
clear_popup_position_override, get_popup_position_override, set_popup_position_override,
|
||||
};
|
||||
pub use layer_shika_domain::value_objects::anchor::AnchorEdges;
|
||||
|
||||
pub type Result<T> = StdResult<T, Error>;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue