iced-rs / iced

A cross-platform GUI library for Rust, inspired by Elm
https://iced.rs
MIT License
24.07k stars 1.12k forks source link

tiny-skia does not truncate long text outside of Element when it is inside a Column #2173

Closed B0ney closed 6 months ago

B0ney commented 8 months ago

Is there an existing issue for this?

Is this issue related to iced?

What happened?

I'm not sure if this applies to other elements, but I noticed that if a button contains really long, unwrapped text, and is inside another element, with the tiny-skia renderer, the text bleeds out.

It was a little tricky to create an sscce, but here's the code to reproduce it:

use iced::widget::{button, column, container, row, scrollable, Button, Space};
use iced::{Element, Length, Sandbox};

// Long text mustn't contain symbols otherwise the renderer will wrap the text.
static LONG: &'static str = "looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong";
static SHORT: &'static str = "short";

pub fn main() -> iced::Result {
    Example::run(iced::Settings {
        window: iced::window::Settings {
            size: iced::Size::from([500.0, 500.0]),
            ..iced::window::Settings::default()
        },
        ..Default::default()
    })
}

struct Example;

#[derive(Debug, Clone, Copy)]
struct Message;

impl Sandbox for Example {
    type Message = Message;

    fn new() -> Self {
        Example
    }

    fn title(&self) -> String {
        "skia-bounding".into()
    }

    fn theme(&self) -> iced::Theme {
        iced::Theme::Dark
    }

    fn update(&mut self, _message: Message) {}

    fn view(&self) -> Element<Message> {
        let dummy_content = (0..100)
            .map(create_button)
            .map(|button| {
                row![
                    button
                        .width(Length::Fill) // Setting the width to anything that's NOT "Length::Shrink" will do.
                        // .width(Length::Fixed(10.0)) // Uncomment to witness abmomination
                    ,    
                    Space::with_width(1)// Also necessary, **MUST** be at least 1
                ]
            })
            .fold(column![], |row, elem| row.push(elem));

        let inner = container(scrollable(dummy_content))
            .padding(50); // set padding to see text bleeding outside

        // let inner = container(content).padding(50); // Doesn't have to be in a scrollable

        container(inner).into()
    }
}

fn create_button<'a>(i: usize) -> Button<'a, Message> {
    button(match i % 2 == 0 {
        true => LONG,
        false => SHORT,
    })
}

To add in cargo.toml:

[features]
wgpu = ["iced/wgpu"]

[dependencies.iced]
git = "https://github.com/iced-rs/iced.git"
default-features = false

Result: Screenshot 2023-12-23 122605

Putting it into a scrollable and moving it results in this: Screenshot 2023-12-23 122616

What is the expected behavior?

Compiling the sscce with features=wgpu produces the expected outcome: Screenshot 2023-12-23 122649

Version

master

Operating System

Windows

Do you have any log output?

No response

B0ney commented 8 months ago

I found another example with text_input:

use iced::widget::{column, container, text_input};
use iced::{Element, Sandbox};

// Long text mustn't contain symbols otherwise the renderer will wrap the text.
static LONG: &'static str = "looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong";

pub fn main() -> iced::Result {
    Example::run(iced::Settings {
        window: iced::window::Settings {
            size: iced::Size::from([500.0, 500.0]),
            ..iced::window::Settings::default()
        },
        ..Default::default()
    })
}

#[derive(Debug, Default)]
struct Example {
    text: String,
}

#[derive(Debug, Clone)]
enum Message {
    Text(String),
}

impl Sandbox for Example {
    type Message = Message;

    fn new() -> Self {
        Example {
            text: LONG.to_owned(),
        }
    }

    fn title(&self) -> String {
        "skia-bounding".into()
    }

    fn theme(&self) -> iced::Theme {
        iced::Theme::Dark
    }

    fn update(&mut self, message: Message) {
        match message {
            Message::Text(txt) => self.text = txt,
        }
    }

    fn view(&self) -> Element<Message> {
        let textbox = text_input("placeholder", &self.text).on_input(Message::Text);

        let inner = container(
            column![textbox], // Must be inside a Column
        )
        .padding(50); // Set padding to see text bleeding outside

        container(inner).into()
    }
}

Screenshot 2023-12-26 121250

Screenshot 2023-12-26 121414

hicaru commented 7 months ago

Agree smae issue, for OSX, linux(wayland)