diff --git a/src/utils/iced.rs b/src/utils/iced.rs index e939a864..6c966822 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -152,6 +152,7 @@ impl IcedProgram for ProgramWrapper

{ pub(crate) struct IcedElementInternal { // draw buffer + additional_scale: f64, outputs: HashSet, buffers: HashMap, (MemoryRenderBuffer, Option<(Vec, Color)>)>, pending_update: Option, @@ -204,6 +205,7 @@ impl Clone for IcedElementInternal

{ ); IcedElementInternal { + additional_scale: self.additional_scale, outputs: self.outputs.clone(), buffers: self.buffers.clone(), pending_update: self.pending_update.clone(), @@ -226,10 +228,17 @@ impl Clone for IcedElementInternal

{ impl fmt::Debug for IcedElementInternal

{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("IcedElementInternal") + .field("additional_scale", &self.additional_scale) + .field( + "outputs", + &self.outputs.iter().map(|o| o.name()).collect::>(), + ) .field("buffers", &"...") .field("size", &self.size) .field("pending_update", &self.pending_update) + .field("last_seat", &self.last_seat) .field("cursor_pos", &self.cursor_pos) + .field("touch_map", &self.touch_map) .field("theme", &"...") .field("renderer", &"...") .field("state", &"...") @@ -281,6 +290,7 @@ impl IcedElement

{ .ok(); let mut internal = IcedElementInternal { + additional_scale: 1.0, outputs: HashSet::new(), buffers: HashMap::new(), pending_update: None, @@ -352,6 +362,19 @@ impl IcedElement

{ } } + pub fn set_additional_scale(&self, scale: f64) { + { + let mut internal = self.0.lock().unwrap(); + let internal_ref = &mut *internal; + if internal_ref.additional_scale == scale { + return; + } + + internal_ref.additional_scale = scale; + } + self.refresh(); + } + pub fn force_update(&self) { self.0.lock().unwrap().update(true); } @@ -370,7 +393,12 @@ impl IcedElement

{ } pub fn current_size(&self) -> Size { - self.0.lock().unwrap().size + let internal = self.0.lock().unwrap(); + internal + .size + .to_f64() + .upscale(internal.additional_scale) + .to_i32_round() } pub fn queue_message(&self, msg: P::Message) { @@ -405,6 +433,7 @@ impl IcedElementInternal

{ .map(|p| IcedPoint::new(p.x as f32, p.y as f32)) .map(Cursor::Available) .unwrap_or(Cursor::Unavailable); + let actions = self .state .update( @@ -446,12 +475,13 @@ impl PointerTarget for IcedEle internal .state .queue_event(Event::Mouse(MouseEvent::CursorEntered)); - let position = IcedPoint::new(event.location.x as f32, event.location.y as f32); + let event_location = event.location.downscale(internal.additional_scale); + let position = IcedPoint::new(event_location.x as f32, event_location.y as f32); internal .state .queue_event(Event::Mouse(MouseEvent::CursorMoved { position })); // TODO: Update iced widgets to handle touch using event position, not cursor_pos - internal.cursor_pos = Some(event.location); + internal.cursor_pos = Some(event_location); *internal.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); let _ = internal.update(true); } @@ -463,11 +493,12 @@ impl PointerTarget for IcedEle event: &MotionEvent, ) { let mut internal = self.0.lock().unwrap(); - let position = IcedPoint::new(event.location.x as f32, event.location.y as f32); + let event_location = event.location.downscale(internal.additional_scale); + let position = IcedPoint::new(event_location.x as f32, event_location.y as f32); internal .state .queue_event(Event::Mouse(MouseEvent::CursorMoved { position })); - internal.cursor_pos = Some(event.location); + internal.cursor_pos = Some(event_location); *internal.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); let _ = internal.update(true); } @@ -610,12 +641,13 @@ impl TouchTarget for IcedEleme ) { let mut internal = self.0.lock().unwrap(); let id = Finger(i32::from(event.slot) as u64); - let position = IcedPoint::new(event.location.x as f32, event.location.y as f32); + let event_location = event.location.downscale(internal.additional_scale); + let position = IcedPoint::new(event_location.x as f32, event_location.y as f32); internal .state .queue_event(Event::Touch(TouchEvent::FingerPressed { id, position })); internal.touch_map.insert(id, position); - internal.cursor_pos = Some(event.location); + internal.cursor_pos = Some(event_location); *internal.last_seat.lock().unwrap() = Some((seat.clone(), seq)); let _ = internal.update(true); } @@ -647,13 +679,14 @@ impl TouchTarget for IcedEleme ) { let mut internal = self.0.lock().unwrap(); let id = Finger(i32::from(event.slot) as u64); - let position = IcedPoint::new(event.location.x as f32, event.location.y as f32); + let event_location = event.location.downscale(internal.additional_scale); + let position = IcedPoint::new(event_location.x as f32, event_location.y as f32); *internal.last_seat.lock().unwrap() = Some((seat.clone(), seq)); internal .state .queue_event(Event::Touch(TouchEvent::FingerMoved { id, position })); internal.touch_map.insert(id, position); - internal.cursor_pos = Some(event.location); + internal.cursor_pos = Some(event_location); let _ = internal.update(true); } @@ -767,7 +800,14 @@ impl IsAlive for IcedElement

{ impl SpaceElement for IcedElement

{ fn bbox(&self) -> Rectangle { - Rectangle::from_size(self.0.lock().unwrap().size) + let internal = self.0.lock().unwrap(); + Rectangle::from_size( + internal + .size + .to_f64() + .upscale(internal.additional_scale) + .to_i32_round(), + ) } fn is_in_input_region(&self, _point: &Point) -> bool { @@ -786,7 +826,7 @@ impl SpaceElement for IcedElement

{ fn output_enter(&self, output: &Output, _overlap: Rectangle) { let mut internal = self.0.lock().unwrap(); - let scale = output.current_scale().fractional_scale(); + let scale = output.current_scale().fractional_scale() * internal.additional_scale; let internal_size = internal.size; internal.buffers.entry(OrderedFloat(scale)).or_insert({ @@ -820,15 +860,16 @@ impl SpaceElement for IcedElement

{ // makes partial borrows easier let internal_ref = &mut *internal; internal_ref.buffers.retain(|scale, _| { - internal_ref - .outputs - .iter() - .any(|o| o.current_scale().fractional_scale() == **scale) + internal_ref.outputs.iter().any(|o| { + o.current_scale().fractional_scale() * internal_ref.additional_scale == **scale + }) }); for scale in internal_ref .outputs .iter() - .map(|o| OrderedFloat(o.current_scale().fractional_scale())) + .map(|o| { + OrderedFloat(o.current_scale().fractional_scale() * internal_ref.additional_scale) + }) .filter(|scale| !internal_ref.buffers.contains_key(scale)) .collect::>() .into_iter() @@ -868,7 +909,7 @@ where &self, renderer: &mut R, location: Point, - scale: Scale, + mut scale: Scale, alpha: f32, ) -> Vec { let mut internal = self.0.lock().unwrap(); @@ -886,6 +927,8 @@ where internal_ref.pending_update = None; } let _ = internal_ref.update(force); + + scale = scale * internal_ref.additional_scale; if let Some((buffer, ref mut old_layers)) = internal_ref.buffers.get_mut(&OrderedFloat(scale.x)) { @@ -988,7 +1031,13 @@ where .to_logical(1., Transform::Normal) .to_i32_round(), )), - Some(internal_ref.size), + Some( + internal_ref + .size + .to_f64() + .upscale(internal_ref.additional_scale) + .to_i32_round(), + ), Kind::Unspecified, ) { return vec![C::from(buffer)];