|
|
@ -463,67 +463,72 @@ impl Context { |
|
|
|
/// because that's where the warning will be painted. If you don't know what size to pick, just pick [`Vec2::ZERO`].
|
|
|
|
pub fn check_for_id_clash(&self, id: Id, new_rect: Rect, what: &str) { |
|
|
|
let prev_rect = self.frame_state_mut(move |state| state.used_ids.insert(id, new_rect)); |
|
|
|
if let Some(prev_rect) = prev_rect { |
|
|
|
// it is ok to reuse the same ID for e.g. a frame around a widget,
|
|
|
|
// or to check for interaction with the same widget twice:
|
|
|
|
if prev_rect.expand(0.1).contains_rect(new_rect) |
|
|
|
|| new_rect.expand(0.1).contains_rect(prev_rect) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
let show_error = |widget_rect: Rect, text: String| { |
|
|
|
let text = format!("🔥 {}", text); |
|
|
|
let color = self.style().visuals.error_fg_color; |
|
|
|
let painter = self.debug_painter(); |
|
|
|
painter.rect_stroke(widget_rect, 0.0, (1.0, color)); |
|
|
|
|
|
|
|
let below = widget_rect.bottom() + 32.0 < self.input(|i| i.screen_rect.bottom()); |
|
|
|
|
|
|
|
let text_rect = if below { |
|
|
|
painter.debug_text( |
|
|
|
widget_rect.left_bottom() + vec2(0.0, 2.0), |
|
|
|
Align2::LEFT_TOP, |
|
|
|
color, |
|
|
|
text, |
|
|
|
) |
|
|
|
} else { |
|
|
|
painter.debug_text( |
|
|
|
widget_rect.left_top() - vec2(0.0, 2.0), |
|
|
|
Align2::LEFT_BOTTOM, |
|
|
|
color, |
|
|
|
text, |
|
|
|
) |
|
|
|
}; |
|
|
|
|
|
|
|
if let Some(pointer_pos) = self.pointer_hover_pos() { |
|
|
|
if text_rect.contains(pointer_pos) { |
|
|
|
let tooltip_pos = if below { |
|
|
|
text_rect.left_bottom() + vec2(2.0, 4.0) |
|
|
|
} else { |
|
|
|
text_rect.left_top() + vec2(2.0, -4.0) |
|
|
|
}; |
|
|
|
|
|
|
|
painter.error( |
|
|
|
tooltip_pos, |
|
|
|
format!("Widget is {} this text.\n\n\ |
|
|
|
if !self.options(|opt| opt.warn_on_id_clash) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
let Some(prev_rect) = prev_rect else { return }; |
|
|
|
|
|
|
|
// it is ok to reuse the same ID for e.g. a frame around a widget,
|
|
|
|
// or to check for interaction with the same widget twice:
|
|
|
|
if prev_rect.expand(0.1).contains_rect(new_rect) |
|
|
|
|| new_rect.expand(0.1).contains_rect(prev_rect) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
let show_error = |widget_rect: Rect, text: String| { |
|
|
|
let text = format!("🔥 {}", text); |
|
|
|
let color = self.style().visuals.error_fg_color; |
|
|
|
let painter = self.debug_painter(); |
|
|
|
painter.rect_stroke(widget_rect, 0.0, (1.0, color)); |
|
|
|
|
|
|
|
let below = widget_rect.bottom() + 32.0 < self.input(|i| i.screen_rect.bottom()); |
|
|
|
|
|
|
|
let text_rect = if below { |
|
|
|
painter.debug_text( |
|
|
|
widget_rect.left_bottom() + vec2(0.0, 2.0), |
|
|
|
Align2::LEFT_TOP, |
|
|
|
color, |
|
|
|
text, |
|
|
|
) |
|
|
|
} else { |
|
|
|
painter.debug_text( |
|
|
|
widget_rect.left_top() - vec2(0.0, 2.0), |
|
|
|
Align2::LEFT_BOTTOM, |
|
|
|
color, |
|
|
|
text, |
|
|
|
) |
|
|
|
}; |
|
|
|
|
|
|
|
if let Some(pointer_pos) = self.pointer_hover_pos() { |
|
|
|
if text_rect.contains(pointer_pos) { |
|
|
|
let tooltip_pos = if below { |
|
|
|
text_rect.left_bottom() + vec2(2.0, 4.0) |
|
|
|
} else { |
|
|
|
text_rect.left_top() + vec2(2.0, -4.0) |
|
|
|
}; |
|
|
|
|
|
|
|
painter.error( |
|
|
|
tooltip_pos, |
|
|
|
format!("Widget is {} this text.\n\n\ |
|
|
|
ID clashes happens when things like Windows or CollapsingHeaders share names,\n\ |
|
|
|
or when things like Plot and Grid:s aren't given unique id_source:s.\n\n\ |
|
|
|
Sometimes the solution is to use ui.push_id.", |
|
|
|
if below { "above" } else { "below" }) |
|
|
|
); |
|
|
|
} |
|
|
|
if below { "above" } else { "below" }) |
|
|
|
); |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
let id_str = id.short_debug_format(); |
|
|
|
let id_str = id.short_debug_format(); |
|
|
|
|
|
|
|
if prev_rect.min.distance(new_rect.min) < 4.0 { |
|
|
|
show_error(new_rect, format!("Double use of {} ID {}", what, id_str)); |
|
|
|
} else { |
|
|
|
show_error(prev_rect, format!("First use of {} ID {}", what, id_str)); |
|
|
|
show_error(new_rect, format!("Second use of {} ID {}", what, id_str)); |
|
|
|
} |
|
|
|
if prev_rect.min.distance(new_rect.min) < 4.0 { |
|
|
|
show_error(new_rect, format!("Double use of {} ID {}", what, id_str)); |
|
|
|
} else { |
|
|
|
show_error(prev_rect, format!("First use of {} ID {}", what, id_str)); |
|
|
|
show_error(new_rect, format!("Second use of {} ID {}", what, id_str)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|