Browse Source

fix some corner cases for repaint requests

pull/20/head
Emil Ernerfeldt 4 years ago
parent
commit
a2160a5e12
  1. 2
      egui/src/containers/area.rs
  2. 1
      egui/src/containers/collapsing_header.rs
  3. 2
      egui/src/containers/resize.rs
  4. 27
      egui/src/context.rs
  5. 6
      egui/src/types.rs

2
egui/src/containers/area.rs

@ -190,7 +190,6 @@ impl Prepared {
if move_interact.active {
state.pos += input.mouse.delta;
state.vel = input.mouse.velocity;
ctx.request_repaint();
} else {
let stop_speed = 20.0; // Pixels per second.
let friction_coeff = 1000.0; // Pixels per second squared.
@ -225,6 +224,7 @@ impl Prepared {
|| !ctx.memory().areas.visible_last_frame(&layer)
{
ctx.memory().areas.move_to_top(layer);
ctx.request_repaint();
}
ctx.memory().areas.set_state(layer, state);

1
egui/src/containers/collapsing_header.rs

@ -104,7 +104,6 @@ impl State {
let openness = self.openness(ui);
let animate = 0.0 < openness && openness < 1.0;
if animate {
ui.ctx().request_repaint();
Some(ui.add_custom(|child_ui| {
let max_height = if self.open {
if let Some(full_height) = self.open_height {

2
egui/src/containers/resize.rs

@ -128,6 +128,8 @@ impl Resize {
let id = self.id.unwrap_or_else(|| ui.make_child_id("resize"));
let mut state = ui.memory().resize.get(&id).cloned().unwrap_or_else(|| {
ui.ctx().request_repaint(); // counter frame delay
let default_size = self.default_size.max(self.min_size);
State {

27
egui/src/context.rs

@ -1,4 +1,7 @@
use std::sync::Arc;
use std::sync::{
atomic::{AtomicU32, Ordering::SeqCst},
Arc,
};
use {
ahash::AHashMap,
@ -38,6 +41,9 @@ pub struct Context {
used_ids: Mutex<AHashMap<Id, Pos2>>,
paint_stats: Mutex<PaintStats>,
/// While positive, keep requesting repaints. Decrement at the end of each frame.
repaint_requests: AtomicU32,
}
impl Clone for Context {
@ -53,6 +59,7 @@ impl Clone for Context {
output: Mutex::new(self.output.lock().clone()),
used_ids: Mutex::new(self.used_ids.lock().clone()),
paint_stats: Mutex::new(*self.paint_stats.lock()),
repaint_requests: self.repaint_requests.load(SeqCst).into(),
}
}
}
@ -82,7 +89,9 @@ impl Context {
/// If this is called at least once in a frame, then there will be another frame right after this.
/// Call as many times as you wish, only one repaint will be issued.
pub fn request_repaint(&self) {
self.output().needs_repaint = true;
// request two frames of repaint, just to cover some corner cases (frame delays):
let times_to_repaint = 2;
self.repaint_requests.store(times_to_repaint, SeqCst);
}
pub fn input(&self) -> &InputState {
@ -95,7 +104,7 @@ impl Context {
&*self
.fonts
.as_ref()
.expect("No fonts available until first call to Contex::begin_frame()`")
.expect("No fonts available until first call to Context::begin_frame()`")
}
/// Not valid until first call to `begin_frame()`
@ -105,7 +114,7 @@ impl Context {
}
/// Will become active at the start of the next frame.
/// `pixels_per_point` will be ignored (overwitten at start of each frame with the contents of input)
/// `pixels_per_point` will be ignored (overwritten at start of each frame with the contents of input)
pub fn set_fonts(&self, font_definitions: FontDefinitions) {
*self.font_definitions.lock() = font_definitions;
}
@ -180,7 +189,13 @@ impl Context {
}
self.memory().end_frame();
let output: Output = std::mem::take(&mut self.output());
let mut output: Output = std::mem::take(&mut self.output());
if self.repaint_requests.load(SeqCst) > 0 {
self.repaint_requests.fetch_sub(1, SeqCst);
output.needs_repaint = true;
}
let paint_jobs = self.paint();
(output, paint_jobs)
}
@ -574,7 +589,7 @@ impl paint::PaintOptions {
impl PaintStats {
pub fn ui(&self, ui: &mut Ui) {
ui.add(label!("Jobs: {}", self.num_jobs))
.tooltip_text("Number of separate clip rectanlges");
.tooltip_text("Number of separate clip rectangles");
ui.add(label!("Primitives: {}", self.num_primitives))
.tooltip_text("Boxes, circles, text areas etc");
ui.add(label!("Vertices: {}", self.num_vertices));

6
egui/src/types.rs

@ -18,9 +18,9 @@ pub struct Output {
/// Response to Event::Copy or Event::Cut. Ignore if empty.
pub copied_text: String,
/// Set to `true` to request another repaint right after this one.
/// This is only used in reactive backends (i.e. backends where we repaint on new input).
/// For instance, you may want to set this to `true` while there is an animation.
/// If `true`, Egui or a user is indicating that the UI needs immediate repaint (e.g. on the next frame).
/// This happens for instance when there is an animation, or if a user has called `Context::request_repaint()`.
/// Don't set this manually, but call `Context::request_repaint()` instead.
pub needs_repaint: bool,
}

Loading…
Cancel
Save