Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text interactions break on transformed layers #4177

Open
CrazyCraftix opened this issue Mar 15, 2024 · 2 comments
Open

Text interactions break on transformed layers #4177

CrazyCraftix opened this issue Mar 15, 2024 · 2 comments
Labels
bug Something is broken

Comments

@CrazyCraftix
Copy link
Contributor

Description

When working on a transformed layer, selecting a region of text by dragging on egui::TextEdit or egui::Label doesn't work properly.

Clicking on a transformed egui::TextEdit doesn't focus the widget. Holding the button for a bit before releasing works for some reason. Interestingly, this also happens when clicking the edge of the widget, even without transformation.

2024-03-15.21-49-13.mp4

Steps to reproduce

use egui::{emath::TSTransform, Label, LayerId, Pos2, Rect, TextEdit, Vec2};

// let transform = TSTransform::IDENTITY;
// let transform = TSTransform::from_translation(egui::Vec2::new(50., 0.));
let transform = TSTransform::from_translation(egui::Vec2::new(150., 0.));
                                                                                   
let layer_id = LayerId::new(egui::Order::Middle, ui.id().with("child"));
ui.ctx().set_transform_layer(layer_id, transform);
                                                                                   
ui.with_layer_id(layer_id, |ui| {
    let mut rect = Rect::from_min_size(Pos2::new(20., 30.), Vec2::new(100., 20.));
    ui.put(rect, Label::new("this is a test label"));
                                                                                   
    rect.min.y += 20.;
    rect.max.y += 20.;
    static mut STR: String = String::new();
    ui.put(rect, TextEdit::singleline(unsafe { &mut STR }));
});

Thoughts

It seems like when handling these interactions, the transformation isn't applied properly.

For the focus issue, I think I have identified the relevant code snippet:

// We detect clicks/hover on a "interact_rect" that is slightly larger than
// self.rect. See Context::interact.
// This means we can be hovered and clicked even though `!self.rect.contains(pos)` is true,
// hence the extra complexity here.
if self.contains_pointer() {
false
} else if let Some(pos) = pointer.interact_pos() {
!self.rect.contains(pos)
} else {
false // clicked without a pointer, weird
}

In line 188, the untransformed rect is checked against the untransformed pointer position.
When the widget is transformed away, the click happens outside the original area and the focus is removed.
I tried accessing the transform from this function using self.ctx.memory(), however this freezes the app, probably because the memory is already being accessed at this point?

I don't know the code well enough yet to be able to fix this.

@CrazyCraftix CrazyCraftix added the bug Something is broken label Mar 15, 2024
@Dampfwalze
Copy link

I also encountered this and I posted a comment on the PR that introduced the set_transform_layer method: #3906 (comment)

@QuantumEntangledAndy
Copy link

QuantumEntangledAndy commented Jun 26, 2024

Rather then opening a new issue I will update here:

The relevant line of code causing this I believe is here

if let Some(pointer_pos) = ui.ctx().pointer_interact_pos() {
if response.hovered() && text.is_mutable() {
ui.output_mut(|o| o.mutable_text_under_cursor = true);

Changing it to something like this

if let Some(pointer_pos) = ui.ctx().pointer_interact_pos() {
    let t = ui.ctx().memory(|m| {
        m.layer_transforms
            .get(&ui.layer_id())
            .map(TSTransform::inverse)
            .unwrap_or_default()
    });
    let pointer_pos = t * pointer_pos;
    if response.hovered() && text.is_mutable() { 
         ui.output_mut(|o| o.mutable_text_under_cursor = true); 

should work

I'm a bit afk atm but I will see about opening a PR when I have time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is broken
Projects
None yet
Development

No branches or pull requests

3 participants