Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace a special Color32::PLACEHOLDER with widget fallback color #3727

Merged
merged 1 commit into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion crates/ecolor/src/color32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use crate::{gamma_u8_from_linear_f32, linear_f32_from_gamma_u8, linear_f32_from_
///
/// Internally this uses 0-255 gamma space `sRGBA` color with premultiplied alpha.
/// Alpha channel is in linear space.
///
/// The special value of alpha=0 means the color is to be treated as an additive color.
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
Expand Down Expand Up @@ -61,7 +63,16 @@ impl Color32 {
pub const DEBUG_COLOR: Color32 = Color32::from_rgba_premultiplied(0, 200, 0, 128);

/// An ugly color that is planned to be replaced before making it to the screen.
pub const TEMPORARY_COLOR: Color32 = Color32::from_rgb(64, 254, 0);
///
/// This is an invalid color, in that it does not correspond to a valid multiplied color,
/// nor to an additive color.
///
/// This is used as a special color key,
/// i.e. often taken to mean "no color".
pub const PLACEHOLDER: Color32 = Color32::from_rgba_premultiplied(64, 254, 0, 128);

#[deprecated = "Renmaed to PLACEHOLDER"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misprint: Renamed. Strange, why wasn't catched by CI

pub const TEMPORARY_COLOR: Color32 = Self::PLACEHOLDER;

#[inline]
pub const fn from_rgb(r: u8, g: u8, b: u8) -> Self {
Expand Down
12 changes: 6 additions & 6 deletions crates/egui/src/containers/collapsing_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,22 +495,22 @@ impl CollapsingHeader {
let text_pos = available.min + vec2(ui.spacing().indent, 0.0);
let wrap_width = available.right() - text_pos.x;
let wrap = Some(false);
let text = text.into_galley(ui, wrap, wrap_width, TextStyle::Button);
let text_max_x = text_pos.x + text.size().x;
let galley = text.into_galley(ui, wrap, wrap_width, TextStyle::Button);
let text_max_x = text_pos.x + galley.size().x;

let mut desired_width = text_max_x + button_padding.x - available.left();
if ui.visuals().collapsing_header_frame {
desired_width = desired_width.max(available.width()); // fill full width
}

let mut desired_size = vec2(desired_width, text.size().y + 2.0 * button_padding.y);
let mut desired_size = vec2(desired_width, galley.size().y + 2.0 * button_padding.y);
desired_size = desired_size.at_least(ui.spacing().interact_size);
let (_, rect) = ui.allocate_space(desired_size);

let mut header_response = ui.interact(rect, id, Sense::click());
let text_pos = pos2(
text_pos.x,
header_response.rect.center().y - text.size().y / 2.0,
header_response.rect.center().y - galley.size().y / 2.0,
);

let mut state = CollapsingState::load_with_default_open(ui.ctx(), id, default_open);
Expand All @@ -525,7 +525,7 @@ impl CollapsingHeader {
}

header_response
.widget_info(|| WidgetInfo::labeled(WidgetType::CollapsingHeader, text.text()));
.widget_info(|| WidgetInfo::labeled(WidgetType::CollapsingHeader, galley.text()));

let openness = state.openness(ui.ctx());

Expand Down Expand Up @@ -563,7 +563,7 @@ impl CollapsingHeader {
}
}

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

Prepared {
Expand Down
3 changes: 2 additions & 1 deletion crates/egui/src/containers/combo_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,8 @@ fn combo_box_dyn<'c, R>(
}

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

Expand Down
12 changes: 7 additions & 5 deletions crates/egui/src/containers/window.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// WARNING: the code in here is horrible. It is a behemoth that needs breaking up into simpler parts.

use std::sync::Arc;

use crate::collapsing_header::CollapsingState;
use crate::{widget_text::WidgetTextGalley, *};
use crate::*;
use epaint::*;

use super::*;
Expand Down Expand Up @@ -885,7 +887,7 @@ struct TitleBar {
id: Id,

/// Prepared text in the title
title_galley: WidgetTextGalley,
title_galley: Arc<Galley>,

/// Size of the title bar in a collapsed state (if window is collapsible),
/// which includes all necessary space for showing the expand button, the
Expand Down Expand Up @@ -984,11 +986,11 @@ impl TitleBar {
let full_top_rect = Rect::from_x_y_ranges(self.rect.x_range(), self.min_rect.y_range());
let text_pos =
emath::align::center_size_in_rect(self.title_galley.size(), full_top_rect).left_top();
let text_pos = text_pos - self.title_galley.galley().rect.min.to_vec2();
let text_pos = text_pos - self.title_galley.rect.min.to_vec2();
let text_pos = text_pos - 1.5 * Vec2::Y; // HACK: center on x-height of text (looks better)
self.title_galley.paint_with_fallback_color(
ui.painter(),
ui.painter().galley(
text_pos,
self.title_galley.clone(),
ui.visuals().text_color(),
);

Expand Down
4 changes: 2 additions & 2 deletions crates/egui/src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,8 @@ impl SubMenuButton {
}

let text_color = visuals.text_color();
text_galley.paint_with_fallback_color(ui.painter(), text_pos, text_color);
icon_galley.paint_with_fallback_color(ui.painter(), icon_pos, text_color);
ui.painter().galley(text_pos, text_galley, text_color);
ui.painter().galley(icon_pos, icon_galley, text_color);
}
response
}
Expand Down
59 changes: 40 additions & 19 deletions crates/egui/src/painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,53 +88,53 @@ impl Painter {
/// ## Accessors etc
impl Painter {
/// Get a reference to the parent [`Context`].
#[inline(always)]
#[inline]
pub fn ctx(&self) -> &Context {
&self.ctx
}

/// Read-only access to the shared [`Fonts`].
///
/// See [`Context`] documentation for how locks work.
#[inline(always)]
#[inline]
pub fn fonts<R>(&self, reader: impl FnOnce(&Fonts) -> R) -> R {
self.ctx.fonts(reader)
}

/// Where we paint
#[inline(always)]
#[inline]
pub fn layer_id(&self) -> LayerId {
self.layer_id
}

/// Everything painted in this [`Painter`] will be clipped against this.
/// This means nothing outside of this rectangle will be visible on screen.
#[inline(always)]
#[inline]
pub fn clip_rect(&self) -> Rect {
self.clip_rect
}

/// Everything painted in this [`Painter`] will be clipped against this.
/// This means nothing outside of this rectangle will be visible on screen.
#[inline(always)]
#[inline]
pub fn set_clip_rect(&mut self, clip_rect: Rect) {
self.clip_rect = clip_rect;
}

/// Useful for pixel-perfect rendering.
#[inline(always)]
#[inline]
pub fn round_to_pixel(&self, point: f32) -> f32 {
self.ctx().round_to_pixel(point)
}

/// Useful for pixel-perfect rendering.
#[inline(always)]
#[inline]
pub fn round_vec_to_pixels(&self, vec: Vec2) -> Vec2 {
self.ctx().round_vec_to_pixels(vec)
}

/// Useful for pixel-perfect rendering.
#[inline(always)]
#[inline]
pub fn round_pos_to_pixels(&self, pos: Pos2) -> Pos2 {
self.ctx().round_pos_to_pixels(pos)
}
Expand Down Expand Up @@ -236,7 +236,7 @@ impl Painter {
0.0,
Color32::from_black_alpha(150),
));
self.galley(rect.min, galley);
self.galley(rect.min, galley, color);
frame_rect
}
}
Expand Down Expand Up @@ -379,14 +379,15 @@ impl Painter {
) -> 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()));
self.galley(rect.min, galley);
self.galley(rect.min, galley, text_color);
rect
}

/// Will wrap text at the given width and line break at `\n`.
///
/// Paint the results with [`Self::galley`].
#[inline(always)]
#[inline]
#[must_use]
pub fn layout(
&self,
text: String,
Expand All @@ -400,7 +401,8 @@ impl Painter {
/// Will line break at `\n`.
///
/// Paint the results with [`Self::galley`].
#[inline(always)]
#[inline]
#[must_use]
pub fn layout_no_wrap(
&self,
text: String,
Expand All @@ -414,23 +416,42 @@ impl Painter {
///
/// You can create the [`Galley`] with [`Self::layout`].
///
/// If you want to change the color of the text, use [`Self::galley_with_color`].
#[inline(always)]
pub fn galley(&self, pos: Pos2, galley: Arc<Galley>) {
/// Any uncolored parts of the [`Galley`] (using [`Color32::PLACEHOLDER`]) will be replaced with the given color.
///
/// Any non-placeholder color in the galley takes precedence over this fallback color.
#[inline]
pub fn galley(&self, pos: Pos2, galley: Arc<Galley>, fallback_color: Color32) {
if !galley.is_empty() {
self.add(Shape::galley(pos, galley));
self.add(Shape::galley(pos, galley, fallback_color));
}
}

/// Paint text that has already been laid out in a [`Galley`].
///
/// You can create the [`Galley`] with [`Self::layout`].
///
/// The text color in the [`Galley`] will be replaced with the given color.
#[inline(always)]
/// All text color in the [`Galley`] will be replaced with the given color.
#[inline]
pub fn galley_with_override_text_color(
&self,
pos: Pos2,
galley: Arc<Galley>,
text_color: Color32,
) {
if !galley.is_empty() {
self.add(Shape::galley_with_override_text_color(
pos, galley, text_color,
));
}
}

#[deprecated = "Use `Painter::galley` or `Painter::galley_with_override_text_color` instead"]
#[inline]
pub fn galley_with_color(&self, pos: Pos2, galley: Arc<Galley>, text_color: Color32) {
if !galley.is_empty() {
self.add(Shape::galley_with_color(pos, galley, text_color));
self.add(Shape::galley_with_override_text_color(
pos, galley, text_color,
));
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions crates/egui/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2269,7 +2269,8 @@ fn register_rect(ui: &Ui, rect: Rect) {
if !callstack.is_empty() {
let font_id = FontId::monospace(12.0);
let text = format!("{callstack}\n\n(click to copy)");
let galley = painter.layout_no_wrap(text, font_id, Color32::WHITE);
let text_color = Color32::WHITE;
let galley = painter.layout_no_wrap(text, font_id, text_color);

// Position the text either under or above:
let screen_rect = ui.ctx().screen_rect();
Expand Down Expand Up @@ -2299,7 +2300,7 @@ fn register_rect(ui: &Ui, rect: Rect) {
};
let text_rect = Rect::from_min_size(text_pos, galley.size());
painter.rect(text_rect, 0.0, text_bg_color, (1.0, text_rect_stroke_color));
painter.galley(text_pos, galley);
painter.galley(text_pos, galley, text_color);

if ui.input(|i| i.pointer.any_click()) {
ui.ctx().copy_text(callstack);
Expand Down
Loading
Loading