egui icon indicating copy to clipboard operation
egui copied to clipboard

Specify Frame's stroke for each side

Open B-Reif opened this issue 3 years ago • 4 comments

Is your feature request related to a problem? Please describe. I'd like to have a Frame with different Stroke properties on each side.

Describe the solution you'd like Change Frame's API to include a stroke for each side.

    let frame = egui::Frame {
        stroke_top: egui::Stroke {
            width: 2.,
            color: egui::Color32::BLACK,,
        },
        stroke_bottom: egui::Stroke {
            width: 1.,
            color: egui::Color32::WHITE,
        },
        ..egui::Frame::default()
    };

Change the stroke builder method to set all sides simultaneously:

    pub fn stroke(mut self, stroke: Stroke) -> Self {
        self.stroke_top = stroke;
        self.stroke_bottom = stroke;
        // etc
        self
    }

This would break existing usages which set the fields directly, but would still work for usage with the builder method.

Alternatively, these fields could be encapsulated in their own struct like a StrokeSet with fields top, bottom, etc. Margin already works this way.

Describe alternatives you've considered

I considered placing horizontal and vertical lines with differing strokes, or creating a custom widget. These seem like poor workarounds for a fairly common use case.

B-Reif avatar May 05 '22 23:05 B-Reif

What is the use case for this?

How would the rounded corners work?

emilk avatar May 06 '22 08:05 emilk

My use case is that I’d like to display frames with borders which vary per-side.

For the corner radius, we could follow the CSS spec and interpolate the values (see https://www.w3.org/TR/css-backgrounds-3/#corner-shaping)

B-Reif avatar May 06 '22 16:05 B-Reif

I am also interested in seeing this happen. My current use case would be that I have two different side-by-side TextEdit's that I want to have a separating line, and each is already contained within a Frame. I don't want there to be a border around each one, just in between.

newcomb-luke avatar May 06 '22 20:05 newcomb-luke

I think both of your use cases can be done in the current version of egui. Different border widths can be emulated by using two frames within each other, where both frames would be something like Frame::none(). By changing the fill of the outer frame to the stroke color, the outer frame would essentially be the inner frame's border. Then the border can be adjusted by changing the inner frames margins with inner_margin. It's convoluted, but it should give pretty good results. I have used this to technique to make blender style viewports before. I think it this should work with rounding corners too.

lampsitter avatar May 07 '22 15:05 lampsitter