Skip to content

Commit

Permalink
Add culling of the painting for most widgets
Browse files Browse the repository at this point in the history
This is a good early-out for widgets in `ScrollAreas`, but
also prepares for speeding up the first pass of a possible two-pass
version of egui: #843
  • Loading branch information
emilk committed Nov 1, 2021
1 parent 461f380 commit eda1d91
Show file tree
Hide file tree
Showing 17 changed files with 524 additions and 461 deletions.
72 changes: 37 additions & 35 deletions egui/src/containers/collapsing_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,45 +295,47 @@ impl CollapsingHeader {
header_response
.widget_info(|| WidgetInfo::labeled(WidgetType::CollapsingHeader, text.text()));

let visuals = ui
.style()
.interact_selectable(&header_response, self.selected);

if ui.visuals().collapsing_header_frame || self.show_background {
ui.painter().add(epaint::RectShape {
rect: header_response.rect.expand(visuals.expansion),
corner_radius: visuals.corner_radius,
fill: visuals.bg_fill,
stroke: visuals.bg_stroke,
// stroke: Default::default(),
});
}
if ui.is_rect_visible(rect) {
let visuals = ui
.style()
.interact_selectable(&header_response, self.selected);

if ui.visuals().collapsing_header_frame || self.show_background {
ui.painter().add(epaint::RectShape {
rect: header_response.rect.expand(visuals.expansion),
corner_radius: visuals.corner_radius,
fill: visuals.bg_fill,
stroke: visuals.bg_stroke,
// stroke: Default::default(),
});
}

if self.selected
|| self.selectable && (header_response.hovered() || header_response.has_focus())
{
let rect = rect.expand(visuals.expansion);
if self.selected
|| self.selectable && (header_response.hovered() || header_response.has_focus())
{
let rect = rect.expand(visuals.expansion);

let corner_radius = 2.0;
ui.painter()
.rect(rect, corner_radius, visuals.bg_fill, visuals.bg_stroke);
}
let corner_radius = 2.0;
ui.painter()
.rect(rect, corner_radius, visuals.bg_fill, visuals.bg_stroke);
}

{
let (mut icon_rect, _) = ui.spacing().icon_rectangles(header_response.rect);
icon_rect.set_center(pos2(
header_response.rect.left() + ui.spacing().indent / 2.0,
header_response.rect.center().y,
));
let icon_response = Response {
rect: icon_rect,
..header_response.clone()
};
let openness = state.openness(ui.ctx(), id);
paint_icon(ui, openness, &icon_response);
}
{
let (mut icon_rect, _) = ui.spacing().icon_rectangles(header_response.rect);
icon_rect.set_center(pos2(
header_response.rect.left() + ui.spacing().indent / 2.0,
header_response.rect.center().y,
));
let icon_response = Response {
rect: icon_rect,
..header_response.clone()
};
let openness = state.openness(ui.ctx(), id);
paint_icon(ui, openness, &icon_response);
}

text.paint_with_visuals(ui.painter(), text_pos, &visuals);
text.paint_with_visuals(ui.painter(), text_pos, &visuals);
}

Prepared {
id,
Expand Down
53 changes: 29 additions & 24 deletions egui/src/containers/combo_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,18 @@ fn combo_box_dyn<'c, R>(
let response = ui.interact(button_rect, button_id, Sense::click());
// response.active |= is_popup_open;

let icon_rect = Align2::RIGHT_CENTER.align_size_within_rect(icon_size, rect);
let visuals = if is_popup_open {
&ui.visuals().widgets.open
} else {
ui.style().interact(&response)
};
paint_icon(ui.painter(), icon_rect.expand(visuals.expansion), visuals);
if ui.is_rect_visible(rect) {
let icon_rect = Align2::RIGHT_CENTER.align_size_within_rect(icon_size, rect);
let visuals = if is_popup_open {
&ui.visuals().widgets.open
} else {
ui.style().interact(&response)
};
paint_icon(ui.painter(), icon_rect.expand(visuals.expansion), visuals);

let text_rect = Align2::LEFT_CENTER.align_size_within_rect(galley.size(), rect);
galley.paint_with_visuals(ui.painter(), text_rect.min, visuals);
let text_rect = Align2::LEFT_CENTER.align_size_within_rect(galley.size(), rect);
galley.paint_with_visuals(ui.painter(), text_rect.min, visuals);
}
});

if button_response.clicked() {
Expand Down Expand Up @@ -223,21 +225,24 @@ fn button_frame(
outer_rect.set_height(outer_rect.height().at_least(interact_size.y));

let response = ui.interact(outer_rect, id, sense);
let visuals = if is_popup_open {
&ui.visuals().widgets.open
} else {
ui.style().interact(&response)
};

ui.painter().set(
where_to_put_background,
epaint::RectShape {
rect: outer_rect.expand(visuals.expansion),
corner_radius: visuals.corner_radius,
fill: visuals.bg_fill,
stroke: visuals.bg_stroke,
},
);

if ui.is_rect_visible(outer_rect) {
let visuals = if is_popup_open {
&ui.visuals().widgets.open
} else {
ui.style().interact(&response)
};

ui.painter().set(
where_to_put_background,
epaint::RectShape {
rect: outer_rect.expand(visuals.expansion),
corner_radius: visuals.corner_radius,
fill: visuals.bg_fill,
stroke: visuals.bg_stroke,
},
);
}

ui.advance_cursor_after_rect(outer_rect);

Expand Down
7 changes: 5 additions & 2 deletions egui/src/containers/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,11 @@ impl Prepared {
..
} = self;

let shape = frame.paint(outer_rect);
ui.painter().set(where_to_put_background, shape);
if ui.is_rect_visible(outer_rect) {
let shape = frame.paint(outer_rect);
ui.painter().set(where_to_put_background, shape);
}

ui.allocate_rect(outer_rect, Sense::hover())
}
}
86 changes: 44 additions & 42 deletions egui/src/containers/scroll_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,50 +671,52 @@ impl Prepared {
state.vel[d] = 0.0;
}

// Avoid frame-delay by calculating a new handle rect:
let mut handle_rect = if d == 0 {
Rect::from_min_max(
pos2(from_content(state.offset.x), min_cross),
pos2(from_content(state.offset.x + inner_rect.width()), max_cross),
)
} else {
Rect::from_min_max(
pos2(min_cross, from_content(state.offset.y)),
pos2(
max_cross,
from_content(state.offset.y + inner_rect.height()),
),
)
};
let min_handle_size = ui.spacing().scroll_bar_width;
if handle_rect.size()[d] < min_handle_size {
handle_rect = Rect::from_center_size(
handle_rect.center(),
if d == 0 {
vec2(min_handle_size, handle_rect.size().y)
} else {
vec2(handle_rect.size().x, min_handle_size)
},
);
}
if ui.is_rect_visible(outer_scroll_rect) {
// Avoid frame-delay by calculating a new handle rect:
let mut handle_rect = if d == 0 {
Rect::from_min_max(
pos2(from_content(state.offset.x), min_cross),
pos2(from_content(state.offset.x + inner_rect.width()), max_cross),
)
} else {
Rect::from_min_max(
pos2(min_cross, from_content(state.offset.y)),
pos2(
max_cross,
from_content(state.offset.y + inner_rect.height()),
),
)
};
let min_handle_size = ui.spacing().scroll_bar_width;
if handle_rect.size()[d] < min_handle_size {
handle_rect = Rect::from_center_size(
handle_rect.center(),
if d == 0 {
vec2(min_handle_size, handle_rect.size().y)
} else {
vec2(handle_rect.size().x, min_handle_size)
},
);
}

let visuals = if scrolling_enabled {
ui.style().interact(&response)
} else {
&ui.style().visuals.widgets.inactive
};
let visuals = if scrolling_enabled {
ui.style().interact(&response)
} else {
&ui.style().visuals.widgets.inactive
};

ui.painter().add(epaint::Shape::rect_filled(
outer_scroll_rect,
visuals.corner_radius,
ui.visuals().extreme_bg_color,
));

ui.painter().add(epaint::Shape::rect_filled(
handle_rect,
visuals.corner_radius,
visuals.bg_fill,
));
ui.painter().add(epaint::Shape::rect_filled(
outer_scroll_rect,
visuals.corner_radius,
ui.visuals().extreme_bg_color,
));

ui.painter().add(epaint::Shape::rect_filled(
handle_rect,
visuals.corner_radius,
visuals.bg_fill,
));
}
}

ui.advance_cursor_after_rect(outer_rect);
Expand Down
2 changes: 1 addition & 1 deletion egui/src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ impl SubMenuButton {
crate::WidgetInfo::labeled(crate::WidgetType::Button, &text_galley.text())
});

if ui.clip_rect().intersects(rect) {
if ui.is_rect_visible(rect) {
let visuals = Self::visuals(ui, &response, menu_state, sub_id);
let text_pos = Align2::LEFT_CENTER
.align_size_within_rect(text_galley.size(), rect.shrink2(button_padding))
Expand Down
Loading

0 comments on commit eda1d91

Please sign in to comment.