Highlight window frame when you resize it
This commit is contained in:
parent
fac0866f73
commit
ee0ad02717
|
|
@ -91,15 +91,15 @@ impl Area {
|
|||
}
|
||||
}
|
||||
|
||||
struct Prepared {
|
||||
pub(crate) struct Prepared {
|
||||
layer: Layer,
|
||||
state: State,
|
||||
pub(crate) state: State,
|
||||
movable: bool,
|
||||
content_ui: Ui,
|
||||
pub(crate) content_ui: Ui,
|
||||
}
|
||||
|
||||
impl Area {
|
||||
fn prepare(self, ctx: &Arc<Context>) -> Prepared {
|
||||
pub(crate) fn begin(self, ctx: &Arc<Context>) -> Prepared {
|
||||
let Area {
|
||||
id,
|
||||
movable,
|
||||
|
|
@ -138,18 +138,20 @@ impl Area {
|
|||
}
|
||||
|
||||
pub fn show(self, ctx: &Arc<Context>, add_contents: impl FnOnce(&mut Ui)) -> InteractInfo {
|
||||
let mut prepared = self.prepare(ctx);
|
||||
let mut prepared = self.begin(ctx);
|
||||
add_contents(&mut prepared.content_ui);
|
||||
Self::finish(ctx, prepared)
|
||||
prepared.end(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
fn finish(ctx: &Arc<Context>, prepared: Prepared) -> InteractInfo {
|
||||
impl Prepared {
|
||||
pub(crate) fn end(self, ctx: &Arc<Context>) -> InteractInfo {
|
||||
let Prepared {
|
||||
layer,
|
||||
mut state,
|
||||
movable,
|
||||
content_ui,
|
||||
} = prepared;
|
||||
} = self;
|
||||
|
||||
state.size = (content_ui.child_bounds().max - state.pos).ceil();
|
||||
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ struct Prepared {
|
|||
}
|
||||
|
||||
impl CollapsingHeader {
|
||||
fn prepare(self, ui: &mut Ui) -> Prepared {
|
||||
fn begin(self, ui: &mut Ui) -> Prepared {
|
||||
assert!(
|
||||
ui.layout().dir() == Direction::Vertical,
|
||||
"Horizontal collapsing is unimplemented"
|
||||
|
|
@ -185,7 +185,7 @@ impl CollapsingHeader {
|
|||
|
||||
let available = ui.available_finite();
|
||||
let text_pos = available.min + vec2(ui.style().indent, 0.0);
|
||||
let galley = label.layout(available.width() - ui.style().indent, ui);
|
||||
let galley = label.layout_width(ui, available.width() - ui.style().indent);
|
||||
let text_max_x = text_pos.x + galley.size.x;
|
||||
let desired_width = text_max_x - available.left();
|
||||
let desired_width = desired_width.max(available.width());
|
||||
|
|
@ -240,7 +240,7 @@ impl CollapsingHeader {
|
|||
}
|
||||
|
||||
pub fn show<R>(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> Option<R> {
|
||||
let Prepared { id, mut state } = self.prepare(ui);
|
||||
let Prepared { id, mut state } = self.begin(ui);
|
||||
let r_interact = state.add_contents(ui, |ui| ui.indent(id, add_contents).0);
|
||||
let ret = r_interact.map(|ri| ri.0);
|
||||
ui.memory().collapsing_headers.insert(id, state);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ impl Frame {
|
|||
margin: style.window_padding,
|
||||
corner_radius: style.window.corner_radius,
|
||||
fill_color: Some(style.background_fill_color),
|
||||
outline: Some(Outline::new(1.0, color::WHITE)),
|
||||
outline: style.interact.inactive.rect_outline, // becauce we can resize windows
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -59,30 +59,58 @@ impl Frame {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Prepared {
|
||||
pub frame: Frame,
|
||||
outer_rect_bounds: Rect,
|
||||
where_to_put_background: usize,
|
||||
pub content_ui: Ui,
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
pub fn show<R>(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> R {
|
||||
let Frame {
|
||||
margin,
|
||||
corner_radius,
|
||||
fill_color,
|
||||
outline,
|
||||
} = self;
|
||||
|
||||
let outer_rect = ui.available();
|
||||
let inner_rect = outer_rect.shrink2(margin);
|
||||
pub fn begin(self, ui: &mut Ui) -> Prepared {
|
||||
let outer_rect_bounds = ui.available();
|
||||
let inner_rect = outer_rect_bounds.shrink2(self.margin);
|
||||
let where_to_put_background = ui.paint_list_len();
|
||||
let content_ui = ui.child_ui(inner_rect);
|
||||
Prepared {
|
||||
frame: self,
|
||||
outer_rect_bounds,
|
||||
where_to_put_background,
|
||||
content_ui,
|
||||
}
|
||||
}
|
||||
|
||||
let mut child_ui = ui.child_ui(inner_rect);
|
||||
let ret = add_contents(&mut child_ui);
|
||||
pub fn show<R>(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> R {
|
||||
let mut prepared = self.begin(ui);
|
||||
let ret = add_contents(&mut prepared.content_ui);
|
||||
prepared.end(ui);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
let outer_rect = Rect::from_min_max(outer_rect.min, child_ui.child_bounds().max + margin);
|
||||
impl Prepared {
|
||||
pub fn outer_rect(&self) -> Rect {
|
||||
Rect::from_min_max(
|
||||
self.outer_rect_bounds.min,
|
||||
self.content_ui.child_bounds().max + self.frame.margin,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn end(self, ui: &mut Ui) -> Rect {
|
||||
let outer_rect = self.outer_rect();
|
||||
|
||||
let Prepared {
|
||||
frame,
|
||||
where_to_put_background,
|
||||
..
|
||||
} = self;
|
||||
|
||||
ui.insert_paint_cmd(
|
||||
where_to_put_background,
|
||||
PaintCmd::Rect {
|
||||
corner_radius,
|
||||
fill_color,
|
||||
outline,
|
||||
corner_radius: frame.corner_radius,
|
||||
fill_color: frame.fill_color,
|
||||
outline: frame.outline,
|
||||
rect: outer_rect,
|
||||
},
|
||||
);
|
||||
|
|
@ -90,6 +118,6 @@ impl Frame {
|
|||
ui.expand_to_include_child(outer_rect);
|
||||
// TODO: move cursor in parent ui
|
||||
|
||||
ret
|
||||
outer_rect
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ struct Prepared {
|
|||
}
|
||||
|
||||
impl Resize {
|
||||
fn prepare(&mut self, ui: &mut Ui) -> Prepared {
|
||||
fn begin(&mut self, ui: &mut Ui) -> Prepared {
|
||||
let id = self.id.unwrap_or_else(|| ui.make_child_id("resize"));
|
||||
self.min_size = self.min_size.min(ui.available().size());
|
||||
self.max_size = self.max_size.min(ui.available().size());
|
||||
|
|
@ -267,13 +267,13 @@ impl Resize {
|
|||
}
|
||||
|
||||
pub fn show<R>(mut self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> R {
|
||||
let mut prepared = self.prepare(ui);
|
||||
let mut prepared = self.begin(ui);
|
||||
let ret = add_contents(&mut prepared.content_ui);
|
||||
self.finish(ui, prepared);
|
||||
self.end(ui, prepared);
|
||||
ret
|
||||
}
|
||||
|
||||
fn finish(self, ui: &mut Ui, prepared: Prepared) {
|
||||
fn end(self, ui: &mut Ui, prepared: Prepared) {
|
||||
let Prepared {
|
||||
id,
|
||||
mut state,
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ struct Prepared {
|
|||
}
|
||||
|
||||
impl ScrollArea {
|
||||
fn prepare(self, ui: &mut Ui) -> Prepared {
|
||||
fn begin(self, ui: &mut Ui) -> Prepared {
|
||||
let Self {
|
||||
max_height,
|
||||
always_show_scroll,
|
||||
|
|
@ -110,13 +110,15 @@ impl ScrollArea {
|
|||
}
|
||||
|
||||
pub fn show<R>(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> R {
|
||||
let mut prepared = self.prepare(ui);
|
||||
let mut prepared = self.begin(ui);
|
||||
let ret = add_contents(&mut prepared.content_ui);
|
||||
Self::finish(ui, prepared);
|
||||
prepared.end(ui);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
fn finish(ui: &mut Ui, prepared: Prepared) {
|
||||
impl Prepared {
|
||||
fn end(self, ui: &mut Ui) {
|
||||
let Prepared {
|
||||
id,
|
||||
mut state,
|
||||
|
|
@ -124,7 +126,7 @@ impl ScrollArea {
|
|||
always_show_scroll,
|
||||
current_scroll_bar_width,
|
||||
content_ui,
|
||||
} = prepared;
|
||||
} = self;
|
||||
|
||||
let content_size = content_ui.bounding_size();
|
||||
|
||||
|
|
|
|||
|
|
@ -148,22 +148,31 @@ impl<'open> Window<'open> {
|
|||
return None;
|
||||
}
|
||||
|
||||
let movable = area.is_movable();
|
||||
let area = area.movable(false); // We move it manually
|
||||
let resizable = resize.is_resizable();
|
||||
let resize = resize.resizable(false); // We move it manually
|
||||
|
||||
let window_id = Id::new(title_label.text());
|
||||
let area_layer = area.layer();
|
||||
let resize_id = window_id.with("resize");
|
||||
let collapsing_id = window_id.with("collapsing");
|
||||
|
||||
let possible = PossibleInteractions {
|
||||
movable: area.is_movable(),
|
||||
resizable: resize.is_resizable()
|
||||
&& collapsing_header::State::is_open(ctx, collapsing_id).unwrap_or_default(),
|
||||
};
|
||||
|
||||
let area = area.movable(false); // We move it manually
|
||||
let resize = resize.resizable(false); // We move it manually
|
||||
|
||||
let resize = resize.id(resize_id);
|
||||
|
||||
let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style()));
|
||||
|
||||
let full_interact = area.show(ctx, |ui| {
|
||||
frame.show(ui, |ui| {
|
||||
let mut area = area.begin(ctx);
|
||||
{
|
||||
// TODO: pick style for frame and title based on interaction
|
||||
let mut frame = frame.begin(&mut area.content_ui);
|
||||
{
|
||||
let ui = &mut frame.content_ui;
|
||||
|
||||
let default_expanded = true;
|
||||
let mut collapsing = collapsing_header::State::from_memory_with_default_open(
|
||||
ui,
|
||||
|
|
@ -182,7 +191,7 @@ impl<'open> Window<'open> {
|
|||
let content = collapsing
|
||||
.add_contents(ui, |ui| {
|
||||
resize.show(ui, |ui| {
|
||||
ui.add(Separator::new().line_width(1.0)); // TODO: nicer way to split window title from contents
|
||||
ui.add(Separator::new().line_width(0.5)); // TODO: nicer way to split window title from contents
|
||||
if let Some(scroll) = scroll {
|
||||
scroll.show(ui, add_contents)
|
||||
} else {
|
||||
|
|
@ -198,42 +207,49 @@ impl<'open> Window<'open> {
|
|||
|
||||
if let Some(open) = open {
|
||||
// Add close button now that we know our full width:
|
||||
|
||||
let right = content
|
||||
.map(|c| c.rect.right())
|
||||
.unwrap_or(title_bar.rect.right());
|
||||
|
||||
let button_size = ui.style().start_icon_width;
|
||||
let button_rect = Rect::from_min_size(
|
||||
pos2(
|
||||
right - ui.style().item_spacing.x - button_size,
|
||||
title_bar.rect.center().y - 0.5 * button_size,
|
||||
),
|
||||
Vec2::splat(button_size),
|
||||
);
|
||||
|
||||
if close_button(ui, button_rect).clicked {
|
||||
if title_bar.close_button_ui(ui, &content).clicked {
|
||||
*open = false;
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
title_bar.title_ui(ui);
|
||||
}
|
||||
|
||||
let resizable =
|
||||
resizable && collapsing_header::State::is_open(ctx, collapsing_id).unwrap_or_default();
|
||||
let outer_rect = frame.end(&mut area.content_ui);
|
||||
|
||||
if movable || resizable {
|
||||
let possible = PossibleInteractions { movable, resizable };
|
||||
let interaction = if possible.movable || possible.resizable {
|
||||
interact(
|
||||
ctx,
|
||||
possible,
|
||||
area_layer,
|
||||
&mut area.state,
|
||||
window_id,
|
||||
resize_id,
|
||||
outer_rect,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
interact(
|
||||
ctx,
|
||||
possible,
|
||||
area_layer,
|
||||
window_id,
|
||||
resize_id,
|
||||
full_interact.rect,
|
||||
);
|
||||
if let Some(interaction) = interaction {
|
||||
paint_frame_interaction(
|
||||
&mut area.content_ui,
|
||||
outer_rect,
|
||||
interaction,
|
||||
ctx.style().interact.active,
|
||||
);
|
||||
} else {
|
||||
if let Some(hover_interaction) = resize_hover(ctx, possible, area_layer, outer_rect)
|
||||
{
|
||||
paint_frame_interaction(
|
||||
&mut area.content_ui,
|
||||
outer_rect,
|
||||
hover_interaction,
|
||||
ctx.style().interact.hovered,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
let full_interact = area.end(ctx);
|
||||
|
||||
Some(full_interact)
|
||||
}
|
||||
|
|
@ -280,10 +296,11 @@ fn interact(
|
|||
ctx: &Context,
|
||||
possible: PossibleInteractions,
|
||||
area_layer: Layer,
|
||||
area_state: &mut area::State,
|
||||
window_id: Id,
|
||||
resize_id: Id,
|
||||
rect: Rect,
|
||||
) -> Option<()> {
|
||||
) -> Option<WindowInteraction> {
|
||||
let pre_resize = ctx.round_rect_to_pixels(rect);
|
||||
let window_interaction = window_interaction(
|
||||
ctx,
|
||||
|
|
@ -297,9 +314,7 @@ fn interact(
|
|||
let new_rect = ctx.round_rect_to_pixels(new_rect);
|
||||
// TODO: add this to a Window state instead as a command "move here next frame"
|
||||
|
||||
let mut area_state = ctx.memory().areas.get(area_layer.id).unwrap();
|
||||
area_state.pos = new_rect.min;
|
||||
ctx.memory().areas.set_state(area_layer, area_state);
|
||||
|
||||
let mut resize_state = ctx.memory().resize.get(&resize_id).cloned().unwrap();
|
||||
// resize_state.size += new_rect.size() - pre_resize.size();
|
||||
|
|
@ -308,7 +323,7 @@ fn interact(
|
|||
ctx.memory().resize.insert(resize_id, resize_state);
|
||||
|
||||
ctx.memory().areas.move_to_top(area_layer);
|
||||
Some(())
|
||||
Some(window_interaction)
|
||||
}
|
||||
|
||||
fn resize_window(ctx: &Context, window_interaction: &WindowInteraction) -> Option<Rect> {
|
||||
|
|
@ -446,16 +461,69 @@ fn resize_hover(
|
|||
}
|
||||
}
|
||||
|
||||
/// Fill in parts of the window frame when we resize by dragging that part
|
||||
fn paint_frame_interaction(
|
||||
ui: &mut Ui,
|
||||
rect: Rect,
|
||||
interaction: WindowInteraction,
|
||||
style: style::WidgetStyle,
|
||||
) {
|
||||
let cr = ui.style().window.corner_radius;
|
||||
let Rect { min, max } = rect;
|
||||
|
||||
let mut path = Path::default();
|
||||
|
||||
if interaction.right && !interaction.bottom && !interaction.top {
|
||||
path.add_line(&[pos2(max.x, min.y + cr), pos2(max.x, max.y - cr)]);
|
||||
}
|
||||
if interaction.right && interaction.bottom {
|
||||
path.add_line(&[pos2(max.x, min.y + cr), pos2(max.x, max.y - cr)]);
|
||||
path.add_circle_quadrant(pos2(max.x - cr, max.y - cr), cr, 0.0);
|
||||
}
|
||||
if interaction.bottom {
|
||||
path.add_line(&[pos2(max.x - cr, max.y), pos2(min.x + cr, max.y)]);
|
||||
}
|
||||
if interaction.left && interaction.bottom {
|
||||
path.add_circle_quadrant(pos2(min.x + cr, max.y - cr), cr, 1.0);
|
||||
}
|
||||
if interaction.left {
|
||||
path.add_line(&[pos2(min.x, max.y - cr), pos2(min.x, min.y + cr)]);
|
||||
}
|
||||
if interaction.left && interaction.top {
|
||||
path.add_circle_quadrant(pos2(min.x + cr, min.y + cr), cr, 2.0);
|
||||
}
|
||||
if interaction.top {
|
||||
path.add_line(&[pos2(min.x + cr, min.y), pos2(max.x - cr, min.y)]);
|
||||
}
|
||||
if interaction.right && interaction.top {
|
||||
path.add_circle_quadrant(pos2(max.x - cr, min.y + cr), cr, 3.0);
|
||||
path.add_line(&[pos2(max.x, min.y + cr), pos2(max.x, max.y - cr)]);
|
||||
}
|
||||
ui.add_paint_cmd(PaintCmd::Path {
|
||||
path,
|
||||
closed: false,
|
||||
fill_color: None,
|
||||
outline: style.rect_outline,
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct TitleBar {
|
||||
title_label: Label,
|
||||
title_galley: font::Galley,
|
||||
title_rect: Rect,
|
||||
rect: Rect,
|
||||
}
|
||||
|
||||
fn show_title_bar(
|
||||
ui: &mut Ui,
|
||||
title_label: Label,
|
||||
show_close_button: bool,
|
||||
collapsing_id: Id,
|
||||
collapsing: &mut collapsing_header::State,
|
||||
) -> InteractInfo {
|
||||
ui.inner_layout(Layout::horizontal(Align::Center), |ui| {
|
||||
) -> TitleBar {
|
||||
let tb_interact = ui.inner_layout(Layout::horizontal(Align::Center), |ui| {
|
||||
ui.set_desired_height(title_label.font_height(ui));
|
||||
|
||||
let item_spacing = ui.style().item_spacing;
|
||||
|
|
@ -474,7 +542,8 @@ fn show_title_bar(
|
|||
collapsing.paint_icon(ui, &collapse_button_interact);
|
||||
}
|
||||
|
||||
let title_rect = ui.add(title_label).rect;
|
||||
let title_galley = title_label.layout(ui);
|
||||
let title_rect = ui.reserve_space(title_galley.size, None).rect;
|
||||
|
||||
if show_close_button {
|
||||
// Reserve space for close button which will be added later:
|
||||
|
|
@ -489,8 +558,41 @@ fn show_title_bar(
|
|||
);
|
||||
ui.expand_to_include_child(close_rect);
|
||||
}
|
||||
})
|
||||
.1
|
||||
|
||||
TitleBar {
|
||||
title_label,
|
||||
title_galley,
|
||||
title_rect,
|
||||
rect: Default::default(), // Will be filled in later
|
||||
}
|
||||
});
|
||||
|
||||
TitleBar {
|
||||
rect: tb_interact.1.rect,
|
||||
..tb_interact.0
|
||||
}
|
||||
}
|
||||
|
||||
impl TitleBar {
|
||||
pub fn title_ui(self, ui: &mut Ui) {
|
||||
self.title_label
|
||||
.paint_galley(ui, self.title_rect.min, self.title_galley);
|
||||
}
|
||||
|
||||
pub fn close_button_ui(&self, ui: &mut Ui, content: &Option<InteractInfo>) -> InteractInfo {
|
||||
let right = content.map(|c| c.rect.right()).unwrap_or(self.rect.right());
|
||||
|
||||
let button_size = ui.style().start_icon_width;
|
||||
let button_rect = Rect::from_min_size(
|
||||
pos2(
|
||||
right - ui.style().item_spacing.x - button_size,
|
||||
self.rect.center().y - 0.5 * button_size,
|
||||
),
|
||||
Vec2::splat(button_size),
|
||||
);
|
||||
|
||||
close_button(ui, button_rect)
|
||||
}
|
||||
}
|
||||
|
||||
fn close_button(ui: &mut Ui, rect: Rect) -> InteractInfo {
|
||||
|
|
|
|||
|
|
@ -497,10 +497,10 @@ impl LayoutExample {
|
|||
pub fn ui(&mut self, ui: &mut Ui) {
|
||||
Resize::default()
|
||||
.default_size(vec2(200.0, 200.0))
|
||||
.show(ui, |ui| self.contents_ui(ui));
|
||||
.show(ui, |ui| self.content_ui(ui));
|
||||
}
|
||||
|
||||
pub fn contents_ui(&mut self, ui: &mut Ui) {
|
||||
pub fn content_ui(&mut self, ui: &mut Ui) {
|
||||
let layout = Layout::from_dir_align(self.dir, self.align);
|
||||
if self.reversed {
|
||||
ui.set_layout(layout.reverse());
|
||||
|
|
|
|||
|
|
@ -163,6 +163,14 @@ impl Path {
|
|||
self.0.clear();
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn add_point(&mut self, pos: Pos2, normal: Vec2) {
|
||||
self.0.push(PathPoint { pos, normal });
|
||||
|
|
@ -252,13 +260,13 @@ impl Path {
|
|||
/// with x right, and y down (GUI coords) we have:
|
||||
/// angle = dir
|
||||
/// 0 * TAU / 4 = right
|
||||
/// quadrant 0, right down
|
||||
/// 1 * TAU / 4 = down
|
||||
/// quadrant 1, down left
|
||||
/// quadrant 0, right bottom
|
||||
/// 1 * TAU / 4 = bottom
|
||||
/// quadrant 1, left bottom
|
||||
/// 2 * TAU / 4 = left
|
||||
/// quadrant 2 left up
|
||||
/// 3 * TAU / 4 = up
|
||||
/// quadrant 3 up rigth
|
||||
/// quadrant 2 left top
|
||||
/// 3 * TAU / 4 = top
|
||||
/// quadrant 3 right top
|
||||
/// 4 * TAU / 4 = right
|
||||
pub fn add_circle_quadrant(&mut self, center: Pos2, radius: f32, quadrant: f32) {
|
||||
let n = (radius * 0.5).round() as i32; // TODO: tweak a bit more
|
||||
|
|
@ -581,16 +589,18 @@ pub fn paint_command_into_triangles(
|
|||
fill_color,
|
||||
outline,
|
||||
} => {
|
||||
if let Some(fill_color) = fill_color {
|
||||
debug_assert!(
|
||||
closed,
|
||||
"You asked to fill a path that is not closed. That makes no sense."
|
||||
);
|
||||
fill_closed_path(out, options, &path.0, fill_color);
|
||||
}
|
||||
if let Some(outline) = outline {
|
||||
let typ = if closed { Closed } else { Open };
|
||||
paint_path_outline(out, options, typ, &path.0, outline.color, outline.width);
|
||||
if path.len() >= 2 {
|
||||
if let Some(fill_color) = fill_color {
|
||||
debug_assert!(
|
||||
closed,
|
||||
"You asked to fill a path that is not closed. That makes no sense."
|
||||
);
|
||||
fill_closed_path(out, options, &path.0, fill_color);
|
||||
}
|
||||
if let Some(outline) = outline {
|
||||
let typ = if closed { Closed } else { Open };
|
||||
paint_path_outline(out, options, typ, &path.0, outline.color, outline.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
PaintCmd::Rect {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ impl Default for Interact {
|
|||
fill_color: srgba(60, 60, 80, 255),
|
||||
stroke_color: gray(210, 255), // Mustn't look grayed out!
|
||||
stroke_width: 1.0,
|
||||
rect_outline: Some(Outline::new(0.5, WHITE)),
|
||||
rect_outline: Some(Outline::new(1.0, white(128))),
|
||||
corner_radius: 0.0,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,16 @@ impl Label {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn layout(&self, max_width: f32, ui: &Ui) -> font::Galley {
|
||||
pub fn layout(&self, ui: &Ui) -> font::Galley {
|
||||
let max_width = if self.auto_shrink {
|
||||
ui.available_finite().width()
|
||||
} else {
|
||||
ui.available().width()
|
||||
};
|
||||
self.layout_width(ui, max_width)
|
||||
}
|
||||
|
||||
pub fn layout_width(&self, ui: &Ui, max_width: f32) -> font::Galley {
|
||||
let font = &ui.fonts()[self.text_style];
|
||||
if self.multiline {
|
||||
font.layout_multiline(self.text.clone(), max_width) // TODO: avoid clone
|
||||
|
|
@ -83,6 +92,10 @@ impl Label {
|
|||
|
||||
// TODO: a paint method for painting anywhere in a ui.
|
||||
// This should be the easiest method of putting text anywhere.
|
||||
|
||||
pub fn paint_galley(&self, ui: &mut Ui, pos: Pos2, galley: font::Galley) {
|
||||
ui.add_galley(pos, galley, self.text_style, self.text_color);
|
||||
}
|
||||
}
|
||||
|
||||
/// Usage: label!("Foo: {}", bar)
|
||||
|
|
@ -94,14 +107,9 @@ macro_rules! label {
|
|||
|
||||
impl Widget for Label {
|
||||
fn ui(self, ui: &mut Ui) -> GuiResponse {
|
||||
let max_width = if self.auto_shrink {
|
||||
ui.available_finite().width()
|
||||
} else {
|
||||
ui.available().width()
|
||||
};
|
||||
let galley = self.layout(max_width, ui);
|
||||
let galley = self.layout(ui);
|
||||
let interact = ui.reserve_space(galley.size, None);
|
||||
ui.add_galley(interact.rect.min, galley, self.text_style, self.text_color);
|
||||
self.paint_galley(ui, interact.rect.min, galley);
|
||||
ui.response(interact)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue