Skip to content

Commit

Permalink
Merge branch 'emilk:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
rustbasic authored Jan 22, 2024
2 parents 5e03f94 + aa67d31 commit c6678b4
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 28 deletions.
2 changes: 0 additions & 2 deletions crates/egui/src/containers/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,6 @@ pub fn popup_above_or_below_widget<R>(
.fixed_pos(pos)
.pivot(pivot)
.show(ui.ctx(), |ui| {
// Note: we use a separate clip-rect for this area, so the popup can be outside the parent.
// See https://github.com/emilk/egui/issues/825
let frame = Frame::popup(ui.style());
let frame_margin = frame.total_margin();
frame
Expand Down
89 changes: 89 additions & 0 deletions crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ impl ViewportRepaintInfo {

// ----------------------------------------------------------------------------

struct DebugText {
location: String,
text: WidgetText,
}

#[derive(Default)]
struct ContextImpl {
/// Since we could have multiple viewport across multiple monitors with
Expand Down Expand Up @@ -278,6 +283,8 @@ struct ContextImpl {
accesskit_node_classes: accesskit::NodeClassSet,

loaders: Arc<Loaders>,

debug_texts: Vec<DebugText>,
}

impl ContextImpl {
Expand Down Expand Up @@ -1060,6 +1067,31 @@ impl Context {
Self::layer_painter(self, LayerId::debug())
}

/// Print this text next to the cursor at the end of the frame.
///
/// If you call this multiple times, the text will be appended.
///
/// This only works if compiled with `debug_assertions`.
///
/// ```
/// # let ctx = egui::Context::default();
/// # let state = true;
/// ctx.debug_text(format!("State: {state:?}"));
/// ```
#[track_caller]
pub fn debug_text(&self, text: impl Into<WidgetText>) {
if cfg!(debug_assertions) {
let location = std::panic::Location::caller();
let location = format!("{}:{}", location.file(), location.line());
self.write(|c| {
c.debug_texts.push(DebugText {
location,
text: text.into(),
});
});
}
}

/// What operating system are we running on?
///
/// When compiling natively, this is
Expand Down Expand Up @@ -1578,6 +1610,63 @@ impl Context {
crate::gui_zoom::zoom_with_keyboard(self);
}

let debug_texts = self.write(|ctx| std::mem::take(&mut ctx.debug_texts));
if !debug_texts.is_empty() {
// Show debug-text next to the cursor.
let mut pos = self
.input(|i| i.pointer.latest_pos())
.unwrap_or_else(|| self.screen_rect().center())
+ 8.0 * Vec2::Y;

let painter = self.debug_painter();
let where_to_put_background = painter.add(Shape::Noop);

let mut bounding_rect = Rect::from_points(&[pos]);

let color = Color32::GRAY;
let font_id = FontId::new(10.0, FontFamily::Proportional);

for DebugText { location, text } in debug_texts {
{
// Paint location to left of `pos`:
let location_galley =
self.fonts(|f| f.layout(location, font_id.clone(), color, f32::INFINITY));
let location_rect =
Align2::RIGHT_TOP.anchor_size(pos - 4.0 * Vec2::X, location_galley.size());
painter.galley(location_rect.min, location_galley, color);
bounding_rect = bounding_rect.union(location_rect);
}

{
// Paint `text` to right of `pos`:
let wrap = true;
let available_width = self.screen_rect().max.x - pos.x;
let galley = text.into_galley_impl(
self,
&self.style(),
wrap,
available_width,
font_id.clone().into(),
Align::TOP,
);
let rect = Align2::LEFT_TOP.anchor_size(pos, galley.size());
painter.galley(rect.min, galley, color);
bounding_rect = bounding_rect.union(rect);
}

pos.y = bounding_rect.max.y + 4.0;
}

painter.set(
where_to_put_background,
Shape::rect_filled(
bounding_rect.expand(4.0),
2.0,
Color32::from_black_alpha(192),
),
);
}

self.write(|ctx| ctx.end_frame())
}
}
Expand Down
8 changes: 5 additions & 3 deletions crates/egui/src/painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@ impl Painter {
self.debug_text(pos, Align2::LEFT_TOP, color, format!("🔥 {text}"))
}

/// text with a background
/// Text with a background.
///
/// See also [`Context::debug_text`].
#[allow(clippy::needless_pass_by_value)]
pub fn debug_text(
&self,
Expand All @@ -229,7 +231,7 @@ impl Painter {
text: impl ToString,
) -> Rect {
let galley = self.layout_no_wrap(text.to_string(), FontId::monospace(12.0), color);
let rect = anchor.anchor_rect(Rect::from_min_size(pos, galley.size()));
let rect = anchor.anchor_size(pos, galley.size());
let frame_rect = rect.expand(2.0);
self.add(Shape::rect_filled(
frame_rect,
Expand Down Expand Up @@ -378,7 +380,7 @@ impl Painter {
text_color: Color32,
) -> Rect {
let galley = self.layout_no_wrap(text.to_string(), font_id, text_color);
let rect = anchor.anchor_rect(Rect::from_min_size(pos, galley.size()));
let rect = anchor.anchor_size(pos, galley.size());
self.galley(rect.min, galley, text_color);
rect
}
Expand Down
29 changes: 25 additions & 4 deletions crates/egui/src/widget_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,18 +649,39 @@ impl WidgetText {
fallback_font: impl Into<FontSelection>,
) -> Arc<Galley> {
let wrap = wrap.unwrap_or_else(|| ui.wrap_text());
let valign = ui.layout().vertical_align();
let style = ui.style();

self.into_galley_impl(
ui.ctx(),
style,
wrap,
available_width,
fallback_font.into(),
valign,
)
}

pub fn into_galley_impl(
self,
ctx: &crate::Context,
style: &Style,
wrap: bool,
available_width: f32,
fallback_font: FontSelection,
default_valign: Align,
) -> Arc<Galley> {
let wrap_width = if wrap { available_width } else { f32::INFINITY };

match self {
Self::RichText(text) => {
let valign = ui.layout().vertical_align();
let mut layout_job = text.into_layout_job(ui.style(), fallback_font.into(), valign);
let mut layout_job = text.into_layout_job(style, fallback_font, default_valign);
layout_job.wrap.max_width = wrap_width;
ui.fonts(|f| f.layout_job(layout_job))
ctx.fonts(|f| f.layout_job(layout_job))
}
Self::LayoutJob(mut job) => {
job.wrap.max_width = wrap_width;
ui.fonts(|f| f.layout_job(job))
ctx.fonts(|f| f.layout_job(job))
}
Self::Galley(galley) => galley,
}
Expand Down
18 changes: 3 additions & 15 deletions crates/egui_extras/src/syntax_highlighting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,11 @@ use egui::text::LayoutJob;
pub fn code_view_ui(
ui: &mut egui::Ui,
theme: &CodeTheme,
mut code: &str,
code: &str,
language: &str,
) -> egui::Response {
let mut layouter = |ui: &egui::Ui, string: &str, _wrap_width: f32| {
let layout_job = highlight(ui.ctx(), theme, string, language);
// layout_job.wrap.max_width = wrap_width; // no wrapping
ui.fonts(|f| f.layout_job(layout_job))
};

ui.add(
egui::TextEdit::multiline(&mut code)
.font(egui::TextStyle::Monospace) // for cursor height
.code_editor()
.desired_rows(1)
.lock_focus(true)
.layouter(&mut layouter),
)
let layout_job = highlight(ui.ctx(), theme, code, language);
ui.add(egui::Label::new(layout_job).selectable(true))
}

/// Add syntax highlighting to a code string.
Expand Down
4 changes: 1 addition & 3 deletions crates/egui_plot/src/items/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,9 +728,7 @@ impl PlotItem for Text {
.into_galley(ui, Some(false), f32::INFINITY, TextStyle::Small);

let pos = transform.position_from_point(&self.position);
let rect = self
.anchor
.anchor_rect(Rect::from_min_size(pos, galley.size()));
let rect = self.anchor.anchor_size(pos, galley.size());

shapes.push(epaint::TextShape::new(rect.min, galley, color).into());

Expand Down
17 changes: 17 additions & 0 deletions crates/emath/src/align.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,23 @@ impl Align2 {
Rect::from_min_size(pos2(x, y), rect.size())
}

/// Use this anchor to position something around `pos`,
/// e.g. [`Self::RIGHT_TOP`] means the right-top of the rect
/// will end up at `pos`.
pub fn anchor_size(self, pos: Pos2, size: Vec2) -> Rect {
let x = match self.x() {
Align::Min => pos.x,
Align::Center => pos.x - 0.5 * size.x,
Align::Max => pos.x - size.x,
};
let y = match self.y() {
Align::Min => pos.y,
Align::Center => pos.y - 0.5 * size.y,
Align::Max => pos.y - size.y,
};
Rect::from_min_size(pos2(x, y), size)
}

/// e.g. center a size within a given frame
pub fn align_size_within_rect(self, size: Vec2, frame: Rect) -> Rect {
let x_range = self.x().align_size_within_range(size.x, frame.x_range());
Expand Down
2 changes: 1 addition & 1 deletion crates/epaint/src/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ impl Shape {
color: Color32,
) -> Self {
let galley = fonts.layout_no_wrap(text.to_string(), font_id, color);
let rect = anchor.anchor_rect(Rect::from_min_size(pos, galley.size()));
let rect = anchor.anchor_size(pos, galley.size());
Self::galley(rect.min, galley, color)
}

Expand Down

0 comments on commit c6678b4

Please sign in to comment.