diff --git a/crates/ecolor/src/hex_color_runtime.rs b/crates/ecolor/src/hex_color_runtime.rs index 3163fc5af7b..a0c3744d701 100644 --- a/crates/ecolor/src/hex_color_runtime.rs +++ b/crates/ecolor/src/hex_color_runtime.rs @@ -72,7 +72,7 @@ impl Display for HexColor { impl HexColor { /// Retrieves the inner [`Color32`] #[inline] - pub fn color(&self) -> Color32 { + pub const fn color(&self) -> Color32 { match self { Self::Hex3(color) | Self::Hex4(color) | Self::Hex6(color) | Self::Hex8(color) => *color, } diff --git a/crates/ecolor/src/hsva.rs b/crates/ecolor/src/hsva.rs index 5f5430cf02d..5ef7061b374 100644 --- a/crates/ecolor/src/hsva.rs +++ b/crates/ecolor/src/hsva.rs @@ -22,7 +22,7 @@ pub struct Hsva { impl Hsva { #[inline] - pub fn new(h: f32, s: f32, v: f32, a: f32) -> Self { + pub const fn new(h: f32, s: f32, v: f32, a: f32) -> Self { Self { h, s, v, a } } @@ -110,7 +110,7 @@ impl Hsva { // ------------------------------------------------------------------------ #[inline] - pub fn to_opaque(self) -> Self { + pub const fn to_opaque(self) -> Self { Self { a: 1.0, ..self } } diff --git a/crates/ecolor/src/lib.rs b/crates/ecolor/src/lib.rs index a9400d9de61..5f783a539a6 100644 --- a/crates/ecolor/src/lib.rs +++ b/crates/ecolor/src/lib.rs @@ -137,7 +137,7 @@ pub fn gamma_from_linear(linear: f32) -> f32 { /// Cheap and ugly. /// Made for graying out disabled `Ui`s. -pub fn tint_color_towards(color: Color32, target: Color32) -> Color32 { +pub const fn tint_color_towards(color: Color32, target: Color32) -> Color32 { let [mut r, mut g, mut b, mut a] = color.to_array(); if a == 0 { diff --git a/crates/ecolor/src/rgba.rs b/crates/ecolor/src/rgba.rs index 900286cda43..1b6df0e704c 100644 --- a/crates/ecolor/src/rgba.rs +++ b/crates/ecolor/src/rgba.rs @@ -119,7 +119,7 @@ impl Rgba { /// Return an additive version of this color (alpha = 0) #[inline] - pub fn additive(self) -> Self { + pub const fn additive(self) -> Self { let [r, g, b, _] = self.0; Self([r, g, b, 0.0]) } @@ -142,22 +142,22 @@ impl Rgba { } #[inline] - pub fn r(&self) -> f32 { + pub const fn r(&self) -> f32 { self.0[0] } #[inline] - pub fn g(&self) -> f32 { + pub const fn g(&self) -> f32 { self.0[1] } #[inline] - pub fn b(&self) -> f32 { + pub const fn b(&self) -> f32 { self.0[2] } #[inline] - pub fn a(&self) -> f32 { + pub const fn a(&self) -> f32 { self.0[3] } @@ -185,13 +185,13 @@ impl Rgba { /// Premultiplied RGBA #[inline] - pub fn to_array(&self) -> [f32; 4] { + pub const fn to_array(&self) -> [f32; 4] { [self.r(), self.g(), self.b(), self.a()] } /// Premultiplied RGBA #[inline] - pub fn to_tuple(&self) -> (f32, f32, f32, f32) { + pub const fn to_tuple(&self) -> (f32, f32, f32, f32) { (self.r(), self.g(), self.b(), self.a()) } diff --git a/crates/eframe/src/epi.rs b/crates/eframe/src/epi.rs index 0fec5a070fd..4f78c6b83b4 100644 --- a/crates/eframe/src/epi.rs +++ b/crates/eframe/src/epi.rs @@ -639,12 +639,12 @@ impl Frame { /// /// Equivalent to `cfg!(target_arch = "wasm32")` #[allow(clippy::unused_self)] - pub fn is_web(&self) -> bool { + pub const fn is_web(&self) -> bool { cfg!(target_arch = "wasm32") } /// Information about the integration. - pub fn info(&self) -> &IntegrationInfo { + pub const fn info(&self) -> &IntegrationInfo { &self.info } @@ -671,7 +671,7 @@ impl Frame { /// To get a [`glow`] context you need to compile with the `glow` feature flag, /// and run eframe using [`Renderer::Glow`]. #[cfg(feature = "glow")] - pub fn gl(&self) -> Option<&std::sync::Arc> { + pub const fn gl(&self) -> Option<&std::sync::Arc> { self.gl.as_ref() } @@ -690,7 +690,7 @@ impl Frame { /// /// Can be used to manage GPU resources for custom rendering with WGPU using [`egui::PaintCallback`]s. #[cfg(feature = "wgpu")] - pub fn wgpu_render_state(&self) -> Option<&egui_wgpu::RenderState> { + pub const fn wgpu_render_state(&self) -> Option<&egui_wgpu::RenderState> { self.wgpu_render_state.as_ref() } } diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index 5f9d555e3a5..ca5982e6eac 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -228,7 +228,7 @@ impl EpiIntegration { } /// If `true`, it is time to close the native window. - pub fn should_close(&self) -> bool { + pub const fn should_close(&self) -> bool { self.close } diff --git a/crates/eframe/src/native/file_storage.rs b/crates/eframe/src/native/file_storage.rs index 439fc5463c6..c4f6ff43127 100644 --- a/crates/eframe/src/native/file_storage.rs +++ b/crates/eframe/src/native/file_storage.rs @@ -68,7 +68,7 @@ fn roaming_appdata() -> Option { ) { S_OK => { let path_slice = slice::from_raw_parts(path, wcslen(path)); - let s = OsString::from_wide(&path_slice); + let s = OsString::from_wide(path_slice); CoTaskMemFree(path.cast()); Some(PathBuf::from(s)) } diff --git a/crates/eframe/src/stopwatch.rs b/crates/eframe/src/stopwatch.rs index 9b0136189fc..b4b8bd22878 100644 --- a/crates/eframe/src/stopwatch.rs +++ b/crates/eframe/src/stopwatch.rs @@ -10,7 +10,7 @@ pub struct Stopwatch { } impl Stopwatch { - pub fn new() -> Self { + pub const fn new() -> Self { Self { total_time_ns: 0, start: None, diff --git a/crates/eframe/src/web/app_runner.rs b/crates/eframe/src/web/app_runner.rs index 88673118a91..ec5b1e0c248 100644 --- a/crates/eframe/src/web/app_runner.rs +++ b/crates/eframe/src/web/app_runner.rs @@ -127,7 +127,7 @@ impl AppRunner { Ok(runner) } - pub fn egui_ctx(&self) -> &egui::Context { + pub const fn egui_ctx(&self) -> &egui::Context { &self.egui_ctx } @@ -168,7 +168,7 @@ impl AppRunner { self.painter.destroy(); } - pub fn has_outstanding_paint_data(&self) -> bool { + pub const fn has_outstanding_paint_data(&self) -> bool { self.clipped_primitives.is_some() } diff --git a/crates/eframe/src/web/web_logger.rs b/crates/eframe/src/web/web_logger.rs index 650b2e530a8..48b89bccf62 100644 --- a/crates/eframe/src/web/web_logger.rs +++ b/crates/eframe/src/web/web_logger.rs @@ -12,7 +12,7 @@ impl WebLogger { /// Create a new [`WebLogger`] with the given filter, /// but don't install it. - pub fn new(filter: log::LevelFilter) -> Self { + pub const fn new(filter: log::LevelFilter) -> Self { Self { filter } } } diff --git a/crates/egui/src/containers/area.rs b/crates/egui/src/containers/area.rs index 378b0edc8d9..0924a5160b9 100644 --- a/crates/egui/src/containers/area.rs +++ b/crates/egui/src/containers/area.rs @@ -125,7 +125,7 @@ impl WidgetWithState for Area { impl Area { /// The `id` must be globally unique. - pub fn new(id: Id) -> Self { + pub const fn new(id: Id) -> Self { Self { id, kind: UiKind::GenericArea, @@ -149,7 +149,7 @@ impl Area { /// /// The `id` must be globally unique. #[inline] - pub fn id(mut self, id: Id) -> Self { + pub const fn id(mut self, id: Id) -> Self { self.id = id; self } @@ -158,12 +158,12 @@ impl Area { /// /// Default to [`UiKind::GenericArea`]. #[inline] - pub fn kind(mut self, kind: UiKind) -> Self { + pub const fn kind(mut self, kind: UiKind) -> Self { self.kind = kind; self } - pub fn layer(&self) -> LayerId { + pub const fn layer(&self) -> LayerId { LayerId::new(self.order, self.id) } @@ -172,24 +172,24 @@ impl Area { /// You won't be able to move the window. /// Default: `true`. #[inline] - pub fn enabled(mut self, enabled: bool) -> Self { + pub const fn enabled(mut self, enabled: bool) -> Self { self.enabled = enabled; self } /// Moveable by dragging the area? #[inline] - pub fn movable(mut self, movable: bool) -> Self { + pub const fn movable(mut self, movable: bool) -> Self { self.movable = movable; self.interactable |= movable; self } - pub fn is_enabled(&self) -> bool { + pub const fn is_enabled(&self) -> bool { self.enabled } - pub fn is_movable(&self) -> bool { + pub const fn is_movable(&self) -> bool { self.movable && self.enabled } @@ -199,7 +199,7 @@ impl Area { /// /// Default: `true`. #[inline] - pub fn interactable(mut self, interactable: bool) -> Self { + pub const fn interactable(mut self, interactable: bool) -> Self { self.interactable = interactable; self.movable &= interactable; self @@ -209,24 +209,31 @@ impl Area { /// /// If not set, this will default to `Sense::drag()` if movable, `Sense::click()` if interactable, and `Sense::hover()` otherwise. #[inline] - pub fn sense(mut self, sense: Sense) -> Self { + pub const fn sense(mut self, sense: Sense) -> Self { self.sense = Some(sense); self } /// `order(Order::Foreground)` for an Area that should always be on top #[inline] - pub fn order(mut self, order: Order) -> Self { + pub const fn order(mut self, order: Order) -> Self { self.order = order; self } #[inline] - pub fn default_pos(mut self, default_pos: impl Into) -> Self { - self.default_pos = Some(default_pos.into()); + pub const fn const_default_pos(mut self, default_pos: Pos2) -> Self { + self.default_pos = Some(default_pos); self } + /// See [`Self::const_default_pos`]. + #[inline] + pub fn default_pos(self, default_pos: impl Into) -> Self { + let default_pos = default_pos.into(); + self.const_default_pos(default_pos) + } + /// The size used for the [`Ui::max_rect`] the first frame. /// /// Text will wrap at this width, and images that expand to fill the available space @@ -237,38 +244,52 @@ impl Area { /// /// If not set, [`crate::style::Spacing::default_area_size`] will be used. #[inline] - pub fn default_size(mut self, default_size: impl Into) -> Self { - self.default_size = default_size.into(); + pub const fn const_default_size(mut self, default_size: Vec2) -> Self { + self.default_size = default_size; self } + /// See [`Self::const_default_size`]. + #[inline] + pub fn default_size(self, default_size: impl Into) -> Self { + let default_size = default_size.into(); + self.const_default_size(default_size) + } + /// See [`Self::default_size`]. #[inline] - pub fn default_width(mut self, default_width: f32) -> Self { + pub const fn default_width(mut self, default_width: f32) -> Self { self.default_size.x = default_width; self } /// See [`Self::default_size`]. #[inline] - pub fn default_height(mut self, default_height: f32) -> Self { + pub const fn default_height(mut self, default_height: f32) -> Self { self.default_size.y = default_height; self } /// Positions the window and prevents it from being moved #[inline] - pub fn fixed_pos(mut self, fixed_pos: impl Into) -> Self { - self.new_pos = Some(fixed_pos.into()); + pub const fn const_fixed_pos(mut self, fixed_pos: Pos2) -> Self { + self.new_pos = Some(fixed_pos); self.movable = false; self } + /// See [`Self::const_fixed_pos`]. + #[inline] + pub fn fixed_pos(self, fixed_pos: impl Into) -> Self { + let fixed_pos = fixed_pos.into(); + self.const_fixed_pos(fixed_pos) + } + /// Constrains this area to [`Context::screen_rect`]? /// /// Default: `true`. #[inline] - pub fn constrain(mut self, constrain: bool) -> Self { + pub const fn constrain(mut self, constrain: bool) -> Self { self.constrain = constrain; self } @@ -277,7 +298,7 @@ impl Area { /// /// For instance: `.constrain_to(ctx.screen_rect())`. #[inline] - pub fn constrain_to(mut self, constrain_rect: Rect) -> Self { + pub const fn constrain_to(mut self, constrain_rect: Rect) -> Self { self.constrain = true; self.constrain_rect = Some(constrain_rect); self @@ -291,18 +312,25 @@ impl Area { /// /// Default: [`Align2::LEFT_TOP`]. #[inline] - pub fn pivot(mut self, pivot: Align2) -> Self { + pub const fn pivot(mut self, pivot: Align2) -> Self { self.pivot = pivot; self } /// Positions the window but you can still move it. #[inline] - pub fn current_pos(mut self, current_pos: impl Into) -> Self { - self.new_pos = Some(current_pos.into()); + pub const fn const_current_pos(mut self, current_pos: Pos2) -> Self { + self.new_pos = Some(current_pos); self } + /// See [`Self::const_current_pos`]. + #[inline] + pub fn current_pos(self, current_pos: impl Into) -> Self { + let current_pos = current_pos.into(); + self.const_current_pos(current_pos) + } + /// Set anchor and distance. /// /// An anchor of `Align2::RIGHT_TOP` means "put the right-top corner of the window @@ -315,12 +343,19 @@ impl Area { /// /// It is an error to set both an anchor and a position. #[inline] - pub fn anchor(mut self, align: Align2, offset: impl Into) -> Self { - self.anchor = Some((align, offset.into())); + pub const fn const_anchor(mut self, align: Align2, offset: Vec2) -> Self { + self.anchor = Some((align, offset)); self.movable(false) } - pub(crate) fn get_pivot(&self) -> Align2 { + /// See [`Self::const_anchor`]. + #[inline] + pub fn anchor(self, align: Align2, offset: impl Into) -> Self { + let offset = offset.into(); + self.const_anchor(align, offset) + } + + pub(crate) const fn get_pivot(&self) -> Align2 { if let Some((pivot, _)) = self.anchor { pivot } else { @@ -332,7 +367,7 @@ impl Area { /// /// Default: `true`. #[inline] - pub fn fade_in(mut self, fade_in: bool) -> Self { + pub const fn fade_in(mut self, fade_in: bool) -> Self { self.fade_in = fade_in; self } @@ -516,7 +551,7 @@ impl Area { } impl Prepared { - pub(crate) fn state(&self) -> &AreaState { + pub(crate) const fn state(&self) -> &AreaState { &self.state } @@ -524,11 +559,11 @@ impl Prepared { &mut self.state } - pub(crate) fn constrain(&self) -> bool { + pub(crate) const fn constrain(&self) -> bool { self.constrain } - pub(crate) fn constrain_rect(&self) -> Rect { + pub(crate) const fn constrain_rect(&self) -> Rect { self.constrain_rect } diff --git a/crates/egui/src/containers/collapsing_header.rs b/crates/egui/src/containers/collapsing_header.rs index 298cdb47698..0d1b76f06b1 100644 --- a/crates/egui/src/containers/collapsing_header.rs +++ b/crates/egui/src/containers/collapsing_header.rs @@ -43,7 +43,7 @@ impl CollapsingState { ctx.data_mut(|d| d.remove::(self.id)); } - pub fn id(&self) -> Id { + pub const fn id(&self) -> Id { self.id } @@ -57,7 +57,7 @@ impl CollapsingState { }) } - pub fn is_open(&self) -> bool { + pub const fn is_open(&self) -> bool { self.state.open } @@ -275,7 +275,7 @@ pub struct HeaderResponse<'ui, HeaderRet> { } impl<'ui, HeaderRet> HeaderResponse<'ui, HeaderRet> { - pub fn is_open(&self) -> bool { + pub const fn is_open(&self) -> bool { self.state.is_open() } @@ -406,7 +406,7 @@ impl CollapsingHeader { /// By default, the [`CollapsingHeader`] is collapsed. /// Call `.default_open(true)` to change this. #[inline] - pub fn default_open(mut self, open: bool) -> Self { + pub const fn default_open(mut self, open: bool) -> Self { self.default_open = open; self } @@ -417,7 +417,7 @@ impl CollapsingHeader { /// /// Calling `.open(None)` has no effect (default). #[inline] - pub fn open(mut self, open: Option) -> Self { + pub const fn open(mut self, open: Option) -> Self { self.open = open; self } @@ -425,25 +425,30 @@ impl CollapsingHeader { /// Explicitly set the source of the [`Id`] of this widget, instead of using title label. /// This is useful if the title label is dynamic or not unique. #[inline] - pub fn id_salt(mut self, id_salt: impl Hash) -> Self { - self.id_salt = Id::new(id_salt); + pub const fn const_id_salt(mut self, id: Id) -> Self { + self.id_salt = id; self } + /// See [`Self::const_id_salt`]. + #[inline] + pub fn id_salt(self, id_salt: impl Hash) -> Self { + self.const_id_salt(Id::new(id_salt)) + } + /// Explicitly set the source of the [`Id`] of this widget, instead of using title label. /// This is useful if the title label is dynamic or not unique. #[deprecated = "Renamed id_salt"] #[inline] - pub fn id_source(mut self, id_salt: impl Hash) -> Self { - self.id_salt = Id::new(id_salt); - self + pub fn id_source(self, id_salt: impl Hash) -> Self { + self.id_salt(id_salt) } /// If you set this to `false`, the [`CollapsingHeader`] will be grayed out and un-clickable. /// /// This is a convenience for [`Ui::disable`]. #[inline] - pub fn enabled(mut self, enabled: bool) -> Self { + pub const fn enabled(mut self, enabled: bool) -> Self { self.enabled = enabled; self } @@ -457,7 +462,7 @@ impl CollapsingHeader { /// # }); /// ``` #[inline] - pub fn show_background(mut self, show_background: bool) -> Self { + pub const fn show_background(mut self, show_background: bool) -> Self { self.show_background = show_background; self } diff --git a/crates/egui/src/containers/combo_box.rs b/crates/egui/src/containers/combo_box.rs index 9883e2c755a..ffc64d8aa5b 100644 --- a/crates/egui/src/containers/combo_box.rs +++ b/crates/egui/src/containers/combo_box.rs @@ -98,7 +98,7 @@ impl ComboBox { /// /// Default is [`Spacing::combo_width`]. #[inline] - pub fn width(mut self, width: f32) -> Self { + pub const fn width(mut self, width: f32) -> Self { self.width = Some(width); self } @@ -107,7 +107,7 @@ impl ComboBox { /// /// Default is [`Spacing::combo_height`]. #[inline] - pub fn height(mut self, height: f32) -> Self { + pub const fn height(mut self, height: f32) -> Self { self.height = Some(height); self } @@ -164,24 +164,21 @@ impl ComboBox { /// /// Note that any `\n` in the text will always produce a new line. #[inline] - pub fn wrap_mode(mut self, wrap_mode: TextWrapMode) -> Self { + pub const fn wrap_mode(mut self, wrap_mode: TextWrapMode) -> Self { self.wrap_mode = Some(wrap_mode); self } /// Set [`Self::wrap_mode`] to [`TextWrapMode::Wrap`]. #[inline] - pub fn wrap(mut self) -> Self { - self.wrap_mode = Some(TextWrapMode::Wrap); - - self + pub const fn wrap(self) -> Self { + self.wrap_mode(TextWrapMode::Wrap) } /// Set [`Self::wrap_mode`] to [`TextWrapMode::Truncate`]. #[inline] - pub fn truncate(mut self) -> Self { - self.wrap_mode = Some(TextWrapMode::Truncate); - self + pub const fn truncate(self) -> Self { + self.wrap_mode(TextWrapMode::Truncate) } /// Show the combo box, with the given ui code for the menu contents. diff --git a/crates/egui/src/containers/frame.rs b/crates/egui/src/containers/frame.rs index 432356a870f..8731c989e02 100644 --- a/crates/egui/src/containers/frame.rs +++ b/crates/egui/src/containers/frame.rs @@ -75,6 +75,7 @@ pub struct Frame { impl Frame { pub fn none() -> Self { + // TODO(BastiDood): Use `const` when `const Default` stabilizes. Self::default() } @@ -162,39 +163,67 @@ impl Frame { impl Frame { #[inline] - pub fn fill(mut self, fill: Color32) -> Self { + pub const fn fill(mut self, fill: Color32) -> Self { self.fill = fill; self } #[inline] - pub fn stroke(mut self, stroke: impl Into) -> Self { - self.stroke = stroke.into(); + pub const fn const_stroke(mut self, stroke: Stroke) -> Self { + self.stroke = stroke; self } + /// See [`Self::const_stroke`]. #[inline] - pub fn rounding(mut self, rounding: impl Into) -> Self { - self.rounding = rounding.into(); + pub fn stroke(self, stroke: impl Into) -> Self { + let stroke = stroke.into(); + self.const_stroke(stroke) + } + + #[inline] + pub const fn const_rounding(mut self, rounding: Rounding) -> Self { + self.rounding = rounding; self } + /// See [`Self::const_rounding`]. + #[inline] + pub fn rounding(self, rounding: impl Into) -> Self { + let rounding = rounding.into(); + self.const_rounding(rounding) + } + /// Margin within the painted frame. #[inline] - pub fn inner_margin(mut self, inner_margin: impl Into) -> Self { - self.inner_margin = inner_margin.into(); + pub const fn const_inner_margin(mut self, inner_margin: Margin) -> Self { + self.inner_margin = inner_margin; self } + /// See [`Self::const_inner_margin`]. + #[inline] + pub fn inner_margin(self, inner_margin: impl Into) -> Self { + let inner_margin = inner_margin.into(); + self.const_inner_margin(inner_margin) + } + /// Margin outside the painted frame. #[inline] - pub fn outer_margin(mut self, outer_margin: impl Into) -> Self { - self.outer_margin = outer_margin.into(); + pub const fn const_outer_margin(mut self, outer_margin: Margin) -> Self { + self.outer_margin = outer_margin; self } + /// See [`Self::const_outer_margin`]. + #[inline] + pub fn outer_margin(self, outer_margin: impl Into) -> Self { + let outer_margin = outer_margin.into(); + self.const_outer_margin(outer_margin) + } + #[inline] - pub fn shadow(mut self, shadow: Shadow) -> Self { + pub const fn shadow(mut self, shadow: Shadow) -> Self { self.shadow = shadow; self } diff --git a/crates/egui/src/containers/panel.rs b/crates/egui/src/containers/panel.rs index 652a6755686..58e70c2cd5f 100644 --- a/crates/egui/src/containers/panel.rs +++ b/crates/egui/src/containers/panel.rs @@ -56,7 +56,7 @@ pub enum Side { } impl Side { - fn opposite(self) -> Self { + const fn opposite(self) -> Self { match self { Self::Left => Self::Right, Self::Right => Self::Left, @@ -70,7 +70,7 @@ impl Side { } } - fn side_x(self, rect: Rect) -> f32 { + const fn side_x(self, rect: Rect) -> f32 { match self { Self::Left => rect.left(), Self::Right => rect.right(), @@ -109,20 +109,32 @@ pub struct SidePanel { impl SidePanel { /// The id should be globally unique, e.g. `Id::new("my_left_panel")`. + pub const fn const_left(id: Id) -> Self { + Self::const_new(Side::Left, id) + } + + /// See [`Self::const_left`]. pub fn left(id: impl Into) -> Self { - Self::new(Side::Left, id) + let id = id.into(); + Self::const_left(id) } /// The id should be globally unique, e.g. `Id::new("my_right_panel")`. + pub const fn const_right(id: Id) -> Self { + Self::const_new(Side::Right, id) + } + + /// See [`Self::const_right`]. pub fn right(id: impl Into) -> Self { - Self::new(Side::Right, id) + let id = id.into(); + Self::const_right(id) } /// The id should be globally unique, e.g. `Id::new("my_panel")`. - pub fn new(side: Side, id: impl Into) -> Self { + pub const fn const_new(side: Side, id: Id) -> Self { Self { side, - id: id.into(), + id, frame: None, resizable: true, show_separator_line: true, @@ -131,6 +143,12 @@ impl SidePanel { } } + /// See [`Self::const_new`]. + pub fn new(side: Side, id: impl Into) -> Self { + let id = id.into(); + Self::const_new(side, id) + } + /// Can panel be resized by dragging the edge of it? /// /// Default is `true`. @@ -143,7 +161,7 @@ impl SidePanel { /// * A [`crate::TextEdit`]. /// * … #[inline] - pub fn resizable(mut self, resizable: bool) -> Self { + pub const fn resizable(mut self, resizable: bool) -> Self { self.resizable = resizable; self } @@ -152,7 +170,7 @@ impl SidePanel { /// /// Default: `true`. #[inline] - pub fn show_separator_line(mut self, show_separator_line: bool) -> Self { + pub const fn show_separator_line(mut self, show_separator_line: bool) -> Self { self.show_separator_line = show_separator_line; self } @@ -193,7 +211,7 @@ impl SidePanel { /// Enforce this exact width, including margins. #[inline] - pub fn exact_width(mut self, width: f32) -> Self { + pub const fn exact_width(mut self, width: f32) -> Self { self.default_width = width; self.width_range = Rangef::point(width); self @@ -201,7 +219,7 @@ impl SidePanel { /// Change the background color, margins, etc. #[inline] - pub fn frame(mut self, frame: Frame) -> Self { + pub const fn frame(mut self, frame: Frame) -> Self { self.frame = Some(frame); self } @@ -541,7 +559,7 @@ pub enum TopBottomSide { } impl TopBottomSide { - fn opposite(self) -> Self { + const fn opposite(self) -> Self { match self { Self::Top => Self::Bottom, Self::Bottom => Self::Top, @@ -555,7 +573,7 @@ impl TopBottomSide { } } - fn side_y(self, rect: Rect) -> f32 { + const fn side_y(self, rect: Rect) -> f32 { match self { Self::Top => rect.top(), Self::Bottom => rect.bottom(), @@ -594,20 +612,32 @@ pub struct TopBottomPanel { impl TopBottomPanel { /// The id should be globally unique, e.g. `Id::new("my_top_panel")`. + pub const fn const_top(id: Id) -> Self { + Self::const_new(TopBottomSide::Top, id) + } + + /// See [`Self::const_top`]. pub fn top(id: impl Into) -> Self { - Self::new(TopBottomSide::Top, id) + let id = id.into(); + Self::const_top(id) } /// The id should be globally unique, e.g. `Id::new("my_bottom_panel")`. + pub const fn const_bottom(id: Id) -> Self { + Self::const_new(TopBottomSide::Bottom, id) + } + + /// See [`Self::const_bottom`]. pub fn bottom(id: impl Into) -> Self { - Self::new(TopBottomSide::Bottom, id) + let id = id.into(); + Self::const_bottom(id) } /// The id should be globally unique, e.g. `Id::new("my_panel")`. - pub fn new(side: TopBottomSide, id: impl Into) -> Self { + pub const fn const_new(side: TopBottomSide, id: Id) -> Self { Self { side, - id: id.into(), + id, frame: None, resizable: false, show_separator_line: true, @@ -616,6 +646,12 @@ impl TopBottomPanel { } } + /// See [`Self::const_new`]. + pub fn new(side: TopBottomSide, id: impl Into) -> Self { + let id = id.into(); + Self::const_new(side, id) + } + /// Can panel be resized by dragging the edge of it? /// /// Default is `false`. @@ -628,7 +664,7 @@ impl TopBottomPanel { /// * A [`crate::TextEdit`]. /// * … #[inline] - pub fn resizable(mut self, resizable: bool) -> Self { + pub const fn resizable(mut self, resizable: bool) -> Self { self.resizable = resizable; self } @@ -637,7 +673,7 @@ impl TopBottomPanel { /// /// Default: `true`. #[inline] - pub fn show_separator_line(mut self, show_separator_line: bool) -> Self { + pub const fn show_separator_line(mut self, show_separator_line: bool) -> Self { self.show_separator_line = show_separator_line; self } @@ -681,7 +717,7 @@ impl TopBottomPanel { /// Enforce this exact height, including margins. #[inline] - pub fn exact_height(mut self, height: f32) -> Self { + pub const fn exact_height(mut self, height: f32) -> Self { self.default_height = Some(height); self.height_range = Rangef::point(height); self @@ -689,7 +725,7 @@ impl TopBottomPanel { /// Change the background color, margins, etc. #[inline] - pub fn frame(mut self, frame: Frame) -> Self { + pub const fn frame(mut self, frame: Frame) -> Self { self.frame = Some(frame); self } @@ -1079,7 +1115,7 @@ pub struct CentralPanel { impl CentralPanel { /// Change the background color, margins, etc. #[inline] - pub fn frame(mut self, frame: Frame) -> Self { + pub const fn frame(mut self, frame: Frame) -> Self { self.frame = Some(frame); self } diff --git a/crates/egui/src/containers/resize.rs b/crates/egui/src/containers/resize.rs index 458bf11229d..63dcb7329e7 100644 --- a/crates/egui/src/containers/resize.rs +++ b/crates/egui/src/containers/resize.rs @@ -64,23 +64,28 @@ impl Default for Resize { impl Resize { /// Assign an explicit and globally unique id. #[inline] - pub fn id(mut self, id: Id) -> Self { + pub const fn id(mut self, id: Id) -> Self { self.id = Some(id); self } - /// A source for the unique [`Id`], e.g. `.id_source("second_resize_area")` or `.id_source(loop_index)`. + /// A source for the unique [`Id`], e.g. `.const_id_salt("second_resize_area")` or `.const_id_salt(loop_index)`. #[inline] - #[deprecated = "Renamed id_salt"] - pub fn id_source(self, id_salt: impl std::hash::Hash) -> Self { - self.id_salt(id_salt) + pub const fn const_id_salt(mut self, id: Id) -> Self { + self.id_salt = Some(id); + self } - /// A source for the unique [`Id`], e.g. `.id_salt("second_resize_area")` or `.id_salt(loop_index)`. + /// See [`Self::const_id_salt`]. #[inline] - pub fn id_salt(mut self, id_salt: impl std::hash::Hash) -> Self { - self.id_salt = Some(Id::new(id_salt)); - self + pub fn id_salt(self, id_salt: impl std::hash::Hash) -> Self { + self.const_id_salt(Id::new(id_salt)) + } + + #[deprecated = "Renamed id_salt"] + #[inline] + pub fn id_source(self, id_salt: impl std::hash::Hash) -> Self { + self.id_salt(id_salt) } /// Preferred / suggested width. Actual width will depend on contents. @@ -90,7 +95,7 @@ impl Resize { /// * if the contents is a canvas, this decides the width of it, /// * if the contents is some buttons, this is ignored and we will auto-size. #[inline] - pub fn default_width(mut self, width: f32) -> Self { + pub const fn default_width(mut self, width: f32) -> Self { self.default_size.x = width; self } @@ -103,55 +108,76 @@ impl Resize { /// * if the contents is text and buttons, then the `default_height` is ignored /// and the height is picked automatically.. #[inline] - pub fn default_height(mut self, height: f32) -> Self { + pub const fn default_height(mut self, height: f32) -> Self { self.default_size.y = height; self } #[inline] - pub fn default_size(mut self, default_size: impl Into) -> Self { - self.default_size = default_size.into(); + pub const fn const_default_size(mut self, default_size: Vec2) -> Self { + self.default_size = default_size; self } + /// See [`Self::const_default_size`]. + #[inline] + pub fn default_size(self, default_size: impl Into) -> Self { + let default_size = default_size.into(); + self.const_default_size(default_size) + } + /// Won't shrink to smaller than this #[inline] - pub fn min_size(mut self, min_size: impl Into) -> Self { - self.min_size = min_size.into(); + pub const fn const_min_size(mut self, min_size: Vec2) -> Self { + self.min_size = min_size; self } + /// See [`Self::const_min_size`]. + #[inline] + pub fn min_size(self, min_size: impl Into) -> Self { + let min_size = min_size.into(); + self.const_min_size(min_size) + } + /// Won't shrink to smaller than this #[inline] - pub fn min_width(mut self, min_width: f32) -> Self { + pub const fn min_width(mut self, min_width: f32) -> Self { self.min_size.x = min_width; self } /// Won't shrink to smaller than this #[inline] - pub fn min_height(mut self, min_height: f32) -> Self { + pub const fn min_height(mut self, min_height: f32) -> Self { self.min_size.y = min_height; self } /// Won't expand to larger than this #[inline] - pub fn max_size(mut self, max_size: impl Into) -> Self { - self.max_size = max_size.into(); + pub const fn const_max_size(mut self, max_size: Vec2) -> Self { + self.max_size = max_size; self } + /// See [`Self::const_max_size`]. + #[inline] + pub fn max_size(self, max_size: impl Into) -> Self { + let max_size = max_size.into(); + self.const_max_size(max_size) + } + /// Won't expand to larger than this #[inline] - pub fn max_width(mut self, max_width: f32) -> Self { + pub const fn max_width(mut self, max_width: f32) -> Self { self.max_size.x = max_width; self } /// Won't expand to larger than this #[inline] - pub fn max_height(mut self, max_height: f32) -> Self { + pub const fn max_height(mut self, max_height: f32) -> Self { self.max_size.y = max_height; self } @@ -162,27 +188,33 @@ impl Resize { /// /// Default is `true`. #[inline] - pub fn resizable(mut self, resizable: impl Into) -> Self { - self.resizable = resizable.into(); + pub const fn const_resizable(mut self, resizable: Vec2b) -> Self { + self.resizable = resizable; self } + /// See [`Self::const_resizable`]. + #[inline] + pub fn resizable(self, resizable: impl Into) -> Self { + let resizable = resizable.into(); + self.const_resizable(resizable) + } + #[inline] - pub fn is_resizable(&self) -> Vec2b { + pub const fn is_resizable(&self) -> Vec2b { self.resizable } /// Not manually resizable, just takes the size of its contents. /// Text will not wrap, but will instead make your window width expand. - pub fn auto_sized(self) -> Self { - self.min_size(Vec2::ZERO) - .default_size(Vec2::splat(f32::INFINITY)) - .resizable(false) + pub const fn auto_sized(self) -> Self { + self.const_min_size(Vec2::ZERO) + .const_default_size(Vec2::splat(f32::INFINITY)) + .const_resizable(Vec2b::FALSE) } #[inline] - pub fn fixed_size(mut self, size: impl Into) -> Self { - let size = size.into(); + pub const fn const_fixed_size(mut self, size: Vec2) -> Self { self.default_size = size; self.min_size = size; self.max_size = size; @@ -190,8 +222,15 @@ impl Resize { self } + /// See [`Self::const_fixed_size`]. + #[inline] + pub fn fixed_size(self, size: impl Into) -> Self { + let size = size.into(); + self.const_fixed_size(size) + } + #[inline] - pub fn with_stroke(mut self, with_stroke: bool) -> Self { + pub const fn with_stroke(mut self, with_stroke: bool) -> Self { self.with_stroke = with_stroke; self } diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index 0921fa24615..6352ce40c11 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -73,7 +73,7 @@ impl State { } /// Get the current kinetic scrolling velocity. - pub fn velocity(&self) -> Vec2 { + pub const fn velocity(&self) -> Vec2 { self.vel } } @@ -121,11 +121,14 @@ pub enum ScrollBarVisibility { impl Default for ScrollBarVisibility { #[inline] fn default() -> Self { - Self::VisibleWhenNeeded + Self::DEFAULT } } impl ScrollBarVisibility { + /// Same as [`Self::default`]. + pub const DEFAULT: Self = Self::VisibleWhenNeeded; + pub const ALL: [Self; 3] = [ Self::AlwaysHidden, Self::VisibleWhenNeeded, @@ -192,38 +195,39 @@ pub struct ScrollArea { impl ScrollArea { /// Create a horizontal scroll area. #[inline] - pub fn horizontal() -> Self { - Self::new([true, false]) + pub const fn horizontal() -> Self { + Self::const_new(Vec2b::new(true, false)) } /// Create a vertical scroll area. #[inline] - pub fn vertical() -> Self { - Self::new([false, true]) + pub const fn vertical() -> Self { + Self::const_new(Vec2b::new(false, true)) } /// Create a bi-directional (horizontal and vertical) scroll area. #[inline] - pub fn both() -> Self { - Self::new([true, true]) + pub const fn both() -> Self { + Self::const_new(Vec2b::TRUE) } /// Create a scroll area where both direction of scrolling is disabled. /// It's unclear why you would want to do this. #[inline] - pub fn neither() -> Self { - Self::new([false, false]) + pub const fn neither() -> Self { + Self::const_new(Vec2b::FALSE) } /// Create a scroll area where you decide which axis has scrolling enabled. /// For instance, `ScrollArea::new([true, false])` enables horizontal scrolling. - pub fn new(scroll_enabled: impl Into) -> Self { + pub const fn const_new(scroll_enabled: Vec2b) -> Self { Self { - scroll_enabled: scroll_enabled.into(), + scroll_enabled, auto_shrink: Vec2b::TRUE, max_size: Vec2::INFINITY, min_scrolled_size: Vec2::splat(64.0), - scroll_bar_visibility: Default::default(), + // TODO(BastiDood): Use `Default::default` when `const` traits stabilize. + scroll_bar_visibility: ScrollBarVisibility::DEFAULT, scroll_bar_rect: None, id_salt: None, offset_x: None, @@ -235,13 +239,19 @@ impl ScrollArea { } } + /// See [`Self::const_new`]. + pub fn new(scroll_enabled: impl Into) -> Self { + let scroll_enabled = scroll_enabled.into(); + Self::const_new(scroll_enabled) + } + /// The maximum width of the outer frame of the scroll area. /// /// Use `f32::INFINITY` if you want the scroll area to expand to fit the surrounding [`Ui`] (default). /// /// See also [`Self::auto_shrink`]. #[inline] - pub fn max_width(mut self, max_width: f32) -> Self { + pub const fn max_width(mut self, max_width: f32) -> Self { self.max_size.x = max_width; self } @@ -252,7 +262,7 @@ impl ScrollArea { /// /// See also [`Self::auto_shrink`]. #[inline] - pub fn max_height(mut self, max_height: f32) -> Self { + pub const fn max_height(mut self, max_height: f32) -> Self { self.max_size.y = max_height; self } @@ -264,7 +274,7 @@ impl ScrollArea { /// /// Default: `64.0`. #[inline] - pub fn min_scrolled_width(mut self, min_scrolled_width: f32) -> Self { + pub const fn min_scrolled_width(mut self, min_scrolled_width: f32) -> Self { self.min_scrolled_size.x = min_scrolled_width; self } @@ -276,7 +286,7 @@ impl ScrollArea { /// /// Default: `64.0`. #[inline] - pub fn min_scrolled_height(mut self, min_scrolled_height: f32) -> Self { + pub const fn min_scrolled_height(mut self, min_scrolled_height: f32) -> Self { self.min_scrolled_size.y = min_scrolled_height; self } @@ -285,21 +295,27 @@ impl ScrollArea { /// /// With `ScrollBarVisibility::VisibleWhenNeeded` (default), the scroll bar will be visible only when needed. #[inline] - pub fn scroll_bar_visibility(mut self, scroll_bar_visibility: ScrollBarVisibility) -> Self { + pub const fn scroll_bar_visibility( + mut self, + scroll_bar_visibility: ScrollBarVisibility, + ) -> Self { self.scroll_bar_visibility = scroll_bar_visibility; self } - /// Specify within which screen-space rectangle to show the scroll bars. - /// - /// This can be used to move the scroll bars to a smaller region of the `ScrollArea`, - /// for instance if you are painting a sticky header on top of it. + /// A source for the unique [`Id`], e.g. `.const_id_salt("second_scroll_area")` or `.const_id_salt(loop_index)`. #[inline] - pub fn scroll_bar_rect(mut self, scroll_bar_rect: Rect) -> Self { - self.scroll_bar_rect = Some(scroll_bar_rect); + pub const fn const_id_salt(mut self, id_salt: Id) -> Self { + self.id_salt = Some(id_salt); self } + /// See [`Self::const_id_salt`]. + #[inline] + pub fn id_salt(self, id_salt: impl std::hash::Hash) -> Self { + self.const_id_salt(Id::new(id_salt)) + } + /// A source for the unique [`Id`], e.g. `.id_source("second_scroll_area")` or `.id_source(loop_index)`. #[inline] #[deprecated = "Renamed id_salt"] @@ -307,10 +323,13 @@ impl ScrollArea { self.id_salt(id_salt) } - /// A source for the unique [`Id`], e.g. `.id_salt("second_scroll_area")` or `.id_salt(loop_index)`. + /// Specify within which screen-space rectangle to show the scroll bars. + /// + /// This can be used to move the scroll bars to a smaller region of the `ScrollArea`, + /// for instance if you are painting a sticky header on top of it. #[inline] - pub fn id_salt(mut self, id_salt: impl std::hash::Hash) -> Self { - self.id_salt = Some(Id::new(id_salt)); + pub const fn scroll_bar_rect(mut self, scroll_bar_rect: Rect) -> Self { + self.scroll_bar_rect = Some(scroll_bar_rect); self } @@ -322,7 +341,7 @@ impl ScrollArea { /// [`Ui::scroll_to_cursor`](crate::ui::Ui::scroll_to_cursor) and /// [`Response::scroll_to_me`](crate::Response::scroll_to_me) #[inline] - pub fn scroll_offset(mut self, offset: Vec2) -> Self { + pub const fn scroll_offset(mut self, offset: Vec2) -> Self { self.offset_x = Some(offset.x); self.offset_y = Some(offset.y); self @@ -335,7 +354,7 @@ impl ScrollArea { /// See also: [`Self::scroll_offset`], [`Ui::scroll_to_cursor`](crate::ui::Ui::scroll_to_cursor) and /// [`Response::scroll_to_me`](crate::Response::scroll_to_me) #[inline] - pub fn vertical_scroll_offset(mut self, offset: f32) -> Self { + pub const fn vertical_scroll_offset(mut self, offset: f32) -> Self { self.offset_y = Some(offset); self } @@ -347,40 +366,46 @@ impl ScrollArea { /// See also: [`Self::scroll_offset`], [`Ui::scroll_to_cursor`](crate::ui::Ui::scroll_to_cursor) and /// [`Response::scroll_to_me`](crate::Response::scroll_to_me) #[inline] - pub fn horizontal_scroll_offset(mut self, offset: f32) -> Self { + pub const fn horizontal_scroll_offset(mut self, offset: f32) -> Self { self.offset_x = Some(offset); self } /// Turn on/off scrolling on the horizontal axis. #[inline] - pub fn hscroll(mut self, hscroll: bool) -> Self { - self.scroll_enabled[0] = hscroll; + pub const fn hscroll(mut self, hscroll: bool) -> Self { + self.scroll_enabled.x = hscroll; self } /// Turn on/off scrolling on the vertical axis. #[inline] - pub fn vscroll(mut self, vscroll: bool) -> Self { - self.scroll_enabled[1] = vscroll; + pub const fn vscroll(mut self, vscroll: bool) -> Self { + self.scroll_enabled.y = vscroll; self } /// Turn on/off scrolling on the horizontal/vertical axes. + #[inline] + pub const fn const_scroll(mut self, scroll_enabled: Vec2b) -> Self { + self.scroll_enabled = scroll_enabled; + self + } + + /// See [`Self::const_scroll`]. /// /// You can pass in `false`, `true`, `[false, true]` etc. #[inline] - pub fn scroll(mut self, scroll_enabled: impl Into) -> Self { - self.scroll_enabled = scroll_enabled.into(); - self + pub fn scroll(self, scroll_enabled: impl Into) -> Self { + let scroll_enabled = scroll_enabled.into(); + self.const_scroll(scroll_enabled) } /// Turn on/off scrolling on the horizontal/vertical axes. #[deprecated = "Renamed to `scroll`"] #[inline] - pub fn scroll2(mut self, scroll_enabled: impl Into) -> Self { - self.scroll_enabled = scroll_enabled.into(); - self + pub fn scroll2(self, scroll_enabled: impl Into) -> Self { + self.scroll(scroll_enabled) } /// Control the scrolling behavior. @@ -393,7 +418,7 @@ impl ScrollArea { /// /// This controls both scrolling directions. #[inline] - pub fn enable_scrolling(mut self, enable: bool) -> Self { + pub const fn enable_scrolling(mut self, enable: bool) -> Self { self.scrolling_enabled = enable; self } @@ -406,7 +431,7 @@ impl ScrollArea { /// /// Default: `true`. #[inline] - pub fn drag_to_scroll(mut self, drag_to_scroll: bool) -> Self { + pub const fn drag_to_scroll(mut self, drag_to_scroll: bool) -> Self { self.drag_to_scroll = drag_to_scroll; self } @@ -418,23 +443,30 @@ impl ScrollArea { /// /// Default: `true`. #[inline] - pub fn auto_shrink(mut self, auto_shrink: impl Into) -> Self { - self.auto_shrink = auto_shrink.into(); + pub const fn const_auto_shrink(mut self, auto_shrink: Vec2b) -> Self { + self.auto_shrink = auto_shrink; self } + /// See [`Self::const_auto_shrink`]. + #[inline] + pub fn auto_shrink(self, auto_shrink: impl Into) -> Self { + let auto_shrink = auto_shrink.into(); + self.const_auto_shrink(auto_shrink) + } + /// Should the scroll area animate `scroll_to_*` functions? /// /// Default: `true`. #[inline] - pub fn animated(mut self, animated: bool) -> Self { + pub const fn animated(mut self, animated: bool) -> Self { self.animated = animated; self } /// Is any scrolling enabled? - pub(crate) fn is_any_scroll_enabled(&self) -> bool { - self.scroll_enabled[0] || self.scroll_enabled[1] + pub(crate) const fn is_any_scroll_enabled(&self) -> bool { + self.scroll_enabled.any() } /// The scroll handle will stick to the rightmost position even while the content size @@ -444,8 +476,8 @@ impl ScrollArea { /// handle is dragged all the way to the right it will again become stuck and remain there /// until manually pulled from the end position. #[inline] - pub fn stick_to_right(mut self, stick: bool) -> Self { - self.stick_to_end[0] = stick; + pub const fn stick_to_right(mut self, stick: bool) -> Self { + self.stick_to_end.x = stick; self } @@ -456,8 +488,8 @@ impl ScrollArea { /// handle is dragged to the bottom it will again become stuck and remain there until manually /// pulled from the end position. #[inline] - pub fn stick_to_bottom(mut self, stick: bool) -> Self { - self.stick_to_end[1] = stick; + pub const fn stick_to_bottom(mut self, stick: bool) -> Self { + self.stick_to_end.y = stick; self } } diff --git a/crates/egui/src/containers/sides.rs b/crates/egui/src/containers/sides.rs index 3bc353380d0..79247073360 100644 --- a/crates/egui/src/containers/sides.rs +++ b/crates/egui/src/containers/sides.rs @@ -44,8 +44,11 @@ pub struct Sides { impl Sides { #[inline] - pub fn new() -> Self { - Default::default() + pub const fn new() -> Self { + Self { + height: None, + spacing: None, + } } /// The minimum height of the sides. @@ -53,7 +56,7 @@ impl Sides { /// The content will be centered vertically within this height. /// The default height is [`crate::Spacing::interact_size`]`.y`. #[inline] - pub fn height(mut self, height: f32) -> Self { + pub const fn height(mut self, height: f32) -> Self { self.height = Some(height); self } @@ -63,7 +66,7 @@ impl Sides { /// This is the minimum gap. /// The default is [`crate::Spacing::item_spacing`]`.x`. #[inline] - pub fn spacing(mut self, spacing: f32) -> Self { + pub const fn spacing(mut self, spacing: f32) -> Self { self.spacing = Some(spacing); self } diff --git a/crates/egui/src/containers/window.rs b/crates/egui/src/containers/window.rs index c183a4dc731..e4b6e1d5288 100644 --- a/crates/egui/src/containers/window.rs +++ b/crates/egui/src/containers/window.rs @@ -72,7 +72,7 @@ impl<'open> Window<'open> { /// Assign a unique id to the Window. Required if the title changes, or is shared with another window. #[inline] - pub fn id(mut self, id: Id) -> Self { + pub const fn id(mut self, id: Id) -> Self { self.area = self.area.id(id); self } @@ -90,7 +90,7 @@ impl<'open> Window<'open> { /// If `false` the window will be grayed out and non-interactive. #[inline] - pub fn enabled(mut self, enabled: bool) -> Self { + pub const fn enabled(mut self, enabled: bool) -> Self { self.area = self.area.enabled(enabled); self } @@ -101,21 +101,21 @@ impl<'open> Window<'open> { /// /// Default: `true`. #[inline] - pub fn interactable(mut self, interactable: bool) -> Self { + pub const fn interactable(mut self, interactable: bool) -> Self { self.area = self.area.interactable(interactable); self } /// If `false` the window will be immovable. #[inline] - pub fn movable(mut self, movable: bool) -> Self { + pub const fn movable(mut self, movable: bool) -> Self { self.area = self.area.movable(movable); self } /// `order(Order::Foreground)` for a Window that should always be on top #[inline] - pub fn order(mut self, order: Order) -> Self { + pub const fn order(mut self, order: Order) -> Self { self.area = self.area.order(order); self } @@ -124,7 +124,7 @@ impl<'open> Window<'open> { /// /// Default: `true`. #[inline] - pub fn fade_in(mut self, fade_in: bool) -> Self { + pub const fn fade_in(mut self, fade_in: bool) -> Self { self.area = self.area.fade_in(fade_in); self } @@ -135,7 +135,7 @@ impl<'open> Window<'open> { /// /// Default: `true`. #[inline] - pub fn fade_out(mut self, fade_out: bool) -> Self { + pub const fn fade_out(mut self, fade_out: bool) -> Self { self.fade_out = fade_out; self } @@ -158,82 +158,117 @@ impl<'open> Window<'open> { /// Change the background color, margins, etc. #[inline] - pub fn frame(mut self, frame: Frame) -> Self { + pub const fn frame(mut self, frame: Frame) -> Self { self.frame = Some(frame); self } /// Set minimum width of the window. #[inline] - pub fn min_width(mut self, min_width: f32) -> Self { + pub const fn min_width(mut self, min_width: f32) -> Self { self.resize = self.resize.min_width(min_width); self } /// Set minimum height of the window. #[inline] - pub fn min_height(mut self, min_height: f32) -> Self { + pub const fn min_height(mut self, min_height: f32) -> Self { self.resize = self.resize.min_height(min_height); self } /// Set minimum size of the window, equivalent to calling both `min_width` and `min_height`. #[inline] - pub fn min_size(mut self, min_size: impl Into) -> Self { - self.resize = self.resize.min_size(min_size); + pub const fn const_min_size(mut self, min_size: Vec2) -> Self { + self.resize = self.resize.const_min_size(min_size); self } + /// See [`Self::const_min_size`]. + #[inline] + pub fn min_size(self, min_size: impl Into) -> Self { + let min_size = min_size.into(); + self.const_min_size(min_size) + } + /// Set maximum width of the window. #[inline] - pub fn max_width(mut self, max_width: f32) -> Self { + pub const fn max_width(mut self, max_width: f32) -> Self { self.resize = self.resize.max_width(max_width); self } /// Set maximum height of the window. #[inline] - pub fn max_height(mut self, max_height: f32) -> Self { + pub const fn max_height(mut self, max_height: f32) -> Self { self.resize = self.resize.max_height(max_height); self } /// Set maximum size of the window, equivalent to calling both `max_width` and `max_height`. #[inline] - pub fn max_size(mut self, max_size: impl Into) -> Self { - self.resize = self.resize.max_size(max_size); + pub const fn const_max_size(mut self, max_size: Vec2) -> Self { + self.resize = self.resize.const_max_size(max_size); self } + /// See [`Self::const_max_size`]. + #[inline] + pub fn max_size(self, max_size: impl Into) -> Self { + let max_size = max_size.into(); + self.const_max_size(max_size) + } + /// Set current position of the window. /// If the window is movable it is up to you to keep track of where it moved to! #[inline] - pub fn current_pos(mut self, current_pos: impl Into) -> Self { - self.area = self.area.current_pos(current_pos); + pub const fn const_current_pos(mut self, current_pos: Pos2) -> Self { + self.area = self.area.const_current_pos(current_pos); self } + /// See [`Self::const_current_pos`]. + #[inline] + pub fn current_pos(self, current_pos: impl Into) -> Self { + let current_pos = current_pos.into(); + self.const_current_pos(current_pos) + } + /// Set initial position of the window. #[inline] - pub fn default_pos(mut self, default_pos: impl Into) -> Self { - self.area = self.area.default_pos(default_pos); + pub const fn const_default_pos(mut self, default_pos: Pos2) -> Self { + self.area = self.area.const_default_pos(default_pos); self } + /// See [`Self::const_default_pos`]. + #[inline] + pub fn default_pos(self, default_pos: impl Into) -> Self { + let default_pos = default_pos.into(); + self.const_default_pos(default_pos) + } + /// Sets the window position and prevents it from being dragged around. #[inline] - pub fn fixed_pos(mut self, pos: impl Into) -> Self { - self.area = self.area.fixed_pos(pos); + pub const fn const_fixed_pos(mut self, pos: Pos2) -> Self { + self.area = self.area.const_fixed_pos(pos); self } + /// See [`Self::const_fixed_pos`]. + #[inline] + pub fn fixed_pos(self, pos: impl Into) -> Self { + let pos = pos.into(); + self.const_fixed_pos(pos) + } + /// Constrains this window to [`Context::screen_rect`]. /// /// To change the area to constrain to, use [`Self::constrain_to`]. /// /// Default: `true`. #[inline] - pub fn constrain(mut self, constrain: bool) -> Self { + pub const fn constrain(mut self, constrain: bool) -> Self { self.area = self.area.constrain(constrain); self } @@ -242,7 +277,7 @@ impl<'open> Window<'open> { /// /// For instance: `.constrain_to(ctx.screen_rect())`. #[inline] - pub fn constrain_to(mut self, constrain_rect: Rect) -> Self { + pub const fn constrain_to(mut self, constrain_rect: Rect) -> Self { self.area = self.area.constrain_to(constrain_rect); self } @@ -255,7 +290,7 @@ impl<'open> Window<'open> { /// /// Default: [`Align2::LEFT_TOP`]. #[inline] - pub fn pivot(mut self, pivot: Align2) -> Self { + pub const fn pivot(mut self, pivot: Align2) -> Self { self.area = self.area.pivot(pivot); self } @@ -272,46 +307,67 @@ impl<'open> Window<'open> { /// /// It is an error to set both an anchor and a position. #[inline] - pub fn anchor(mut self, align: Align2, offset: impl Into) -> Self { - self.area = self.area.anchor(align, offset); + pub const fn const_anchor(mut self, align: Align2, offset: Vec2) -> Self { + self.area = self.area.const_anchor(align, offset); self } + /// See [`Self::const_anchor`]. + #[inline] + pub fn anchor(self, align: Align2, offset: impl Into) -> Self { + let offset = offset.into(); + self.const_anchor(align, offset) + } + /// Set initial collapsed state of the window #[inline] - pub fn default_open(mut self, default_open: bool) -> Self { + pub const fn default_open(mut self, default_open: bool) -> Self { self.default_open = default_open; self } /// Set initial size of the window. #[inline] - pub fn default_size(mut self, default_size: impl Into) -> Self { - self.resize = self.resize.default_size(default_size); + pub const fn const_default_size(mut self, default_size: Vec2) -> Self { + self.resize = self.resize.const_default_size(default_size); self } + /// See [`Self::const_default_size`]. + #[inline] + pub fn default_size(self, default_size: impl Into) -> Self { + let default_size = default_size.into(); + self.const_default_size(default_size) + } + /// Set initial width of the window. #[inline] - pub fn default_width(mut self, default_width: f32) -> Self { + pub const fn default_width(mut self, default_width: f32) -> Self { self.resize = self.resize.default_width(default_width); self } /// Set initial height of the window. #[inline] - pub fn default_height(mut self, default_height: f32) -> Self { + pub const fn default_height(mut self, default_height: f32) -> Self { self.resize = self.resize.default_height(default_height); self } /// Sets the window size and prevents it from being resized by dragging its edges. #[inline] - pub fn fixed_size(mut self, size: impl Into) -> Self { - self.resize = self.resize.fixed_size(size); + pub const fn const_fixed_size(mut self, size: Vec2) -> Self { + self.resize = self.resize.const_fixed_size(size); self } + /// See [`Self::const_fixed_size`]. + #[inline] + pub fn fixed_size(self, size: impl Into) -> Self { + let size = size.into(); + self.const_fixed_size(size) + } + /// Set initial position and size of the window. pub fn default_rect(self, rect: Rect) -> Self { self.default_pos(rect.min).default_size(rect.size()) @@ -332,15 +388,21 @@ impl<'open> Window<'open> { /// /// Default is `true`. #[inline] - pub fn resizable(mut self, resizable: impl Into) -> Self { - let resizable = resizable.into(); - self.resize = self.resize.resizable(resizable); + pub const fn const_resizable(mut self, resizable: Vec2b) -> Self { + self.resize = self.resize.const_resizable(resizable); self } + /// See [`Self::const_resizable`]. + #[inline] + pub fn resizable(self, resizable: impl Into) -> Self { + let resizable = resizable.into(); + self.const_resizable(resizable) + } + /// Can the window be collapsed by clicking on its title? #[inline] - pub fn collapsible(mut self, collapsible: bool) -> Self { + pub const fn collapsible(mut self, collapsible: bool) -> Self { self.collapsible = collapsible; self } @@ -348,7 +410,7 @@ impl<'open> Window<'open> { /// Show title bar on top of the window? /// If `false`, the window will not be collapsible nor have a close-button. #[inline] - pub fn title_bar(mut self, title_bar: bool) -> Self { + pub const fn title_bar(mut self, title_bar: bool) -> Self { self.with_title_bar = title_bar; self } @@ -357,39 +419,45 @@ impl<'open> Window<'open> { /// Also disabled scrolling. /// Text will not wrap, but will instead make your window width expand. #[inline] - pub fn auto_sized(mut self) -> Self { + pub const fn auto_sized(mut self) -> Self { self.resize = self.resize.auto_sized(); self.scroll = ScrollArea::neither(); self } /// Enable/disable horizontal/vertical scrolling. `false` by default. + #[inline] + pub const fn const_scroll(mut self, scroll: Vec2b) -> Self { + self.scroll = self.scroll.const_scroll(scroll); + self + } + + /// See [`Self::const_scroll`]. /// /// You can pass in `false`, `true`, `[false, true]` etc. #[inline] - pub fn scroll(mut self, scroll: impl Into) -> Self { - self.scroll = self.scroll.scroll(scroll); - self + pub fn scroll(self, scroll: impl Into) -> Self { + let scroll = scroll.into(); + self.const_scroll(scroll) } /// Enable/disable horizontal/vertical scrolling. `false` by default. #[deprecated = "Renamed to `scroll`"] #[inline] - pub fn scroll2(mut self, scroll: impl Into) -> Self { - self.scroll = self.scroll.scroll(scroll); - self + pub fn scroll2(self, scroll: impl Into) -> Self { + self.scroll(scroll) } /// Enable/disable horizontal scrolling. `false` by default. #[inline] - pub fn hscroll(mut self, hscroll: bool) -> Self { + pub const fn hscroll(mut self, hscroll: bool) -> Self { self.scroll = self.scroll.hscroll(hscroll); self } /// Enable/disable vertical scrolling. `false` by default. #[inline] - pub fn vscroll(mut self, vscroll: bool) -> Self { + pub const fn vscroll(mut self, vscroll: bool) -> Self { self.scroll = self.scroll.vscroll(vscroll); self } @@ -398,7 +466,7 @@ impl<'open> Window<'open> { /// /// See [`ScrollArea::drag_to_scroll`] for more. #[inline] - pub fn drag_to_scroll(mut self, drag_to_scroll: bool) -> Self { + pub const fn drag_to_scroll(mut self, drag_to_scroll: bool) -> Self { self.scroll = self.scroll.drag_to_scroll(drag_to_scroll); self } @@ -698,7 +766,7 @@ impl PossibleInteractions { } } - pub fn resizable(&self) -> bool { + pub const fn resizable(&self) -> bool { self.resize_left || self.resize_right || self.resize_top || self.resize_bottom } } @@ -721,7 +789,7 @@ struct SideResponse { } impl SideResponse { - pub fn any(&self) -> bool { + pub const fn any(&self) -> bool { self.hover || self.drag } } @@ -754,11 +822,11 @@ impl ResizeInteraction { } } - pub fn any_hovered(&self) -> bool { + pub const fn any_hovered(&self) -> bool { self.left.hover || self.right.hover || self.top.hover || self.bottom.hover } - pub fn any_dragged(&self) -> bool { + pub const fn any_dragged(&self) -> bool { self.left.drag || self.right.drag || self.top.drag || self.bottom.drag } } diff --git a/crates/egui/src/data/input.rs b/crates/egui/src/data/input.rs index c1b175dd843..5f3e107a4eb 100644 --- a/crates/egui/src/data/input.rs +++ b/crates/egui/src/data/input.rs @@ -1194,17 +1194,20 @@ pub struct EventFilter { #[allow(clippy::derivable_impls)] // let's be explicit impl Default for EventFilter { fn default() -> Self { - Self { - tab: false, - horizontal_arrows: false, - vertical_arrows: false, - escape: false, - } + Self::DEFAULT } } impl EventFilter { - pub fn matches(&self, event: &Event) -> bool { + /// Same as [`Self::default`]. + pub const DEFAULT: Self = Self { + tab: false, + horizontal_arrows: false, + vertical_arrows: false, + escape: false, + }; + + pub const fn matches(&self, event: &Event) -> bool { if let Event::Key { key, .. } = event { match key { crate::Key::Tab => self.tab, diff --git a/crates/egui/src/frame_state.rs b/crates/egui/src/frame_state.rs index ebfd0e47be1..d044764d609 100644 --- a/crates/egui/src/frame_state.rs +++ b/crates/egui/src/frame_state.rs @@ -58,7 +58,11 @@ pub struct ScrollTarget { } impl ScrollTarget { - pub fn new(range: Rangef, align: Option, animation: style::ScrollAnimation) -> Self { + pub const fn new( + range: Rangef, + align: Option, + animation: style::ScrollAnimation, + ) -> Self { Self { range, align, diff --git a/crates/egui/src/grid.rs b/crates/egui/src/grid.rs index 415cfd87177..a4869b25749 100644 --- a/crates/egui/src/grid.rs +++ b/crates/egui/src/grid.rs @@ -468,7 +468,7 @@ impl Grid { } } -fn striped_row_color(row: usize, style: &Style) -> Option { +const fn striped_row_color(row: usize, style: &Style) -> Option { if row % 2 == 1 { return Some(style.visuals.faint_bg_color); } diff --git a/crates/egui/src/id.rs b/crates/egui/src/id.rs index c5047c26613..33aa2027adc 100644 --- a/crates/egui/src/id.rs +++ b/crates/egui/src/id.rs @@ -73,7 +73,7 @@ impl Id { /// /// This is a high-entropy hash, or [`Self::NULL`]. #[inline(always)] - pub fn value(&self) -> u64 { + pub const fn value(&self) -> u64 { self.0.get() } diff --git a/crates/egui/src/input_state/mod.rs b/crates/egui/src/input_state/mod.rs index 8c2c5e79254..22b7f6e47a6 100644 --- a/crates/egui/src/input_state/mod.rs +++ b/crates/egui/src/input_state/mod.rs @@ -440,7 +440,7 @@ impl InputState { } #[inline(always)] - pub fn screen_rect(&self) -> Rect { + pub const fn screen_rect(&self) -> Rect { self.screen_rect } @@ -623,14 +623,14 @@ impl InputState { /// Also known as device pixel ratio, > 1 for high resolution screens. #[inline(always)] - pub fn pixels_per_point(&self) -> f32 { + pub const fn pixels_per_point(&self) -> f32 { self.pixels_per_point } /// Size of a physical pixel in logical gui coordinates (points). #[inline(always)] pub fn physical_pixel_size(&self) -> f32 { - 1.0 / self.pixels_per_point() + self.pixels_per_point().recip() } /// How imprecise do we expect the mouse/touch input to be? @@ -756,11 +756,11 @@ pub(crate) struct Click { } impl Click { - pub fn is_double(&self) -> bool { + pub const fn is_double(&self) -> bool { self.count == 2 } - pub fn is_triple(&self) -> bool { + pub const fn is_triple(&self) -> bool { self.count == 3 } } @@ -780,15 +780,15 @@ pub(crate) enum PointerEvent { } impl PointerEvent { - pub fn is_press(&self) -> bool { + pub const fn is_press(&self) -> bool { matches!(self, Self::Pressed { .. }) } - pub fn is_release(&self) -> bool { + pub const fn is_release(&self) -> bool { matches!(self, Self::Released { .. }) } - pub fn is_click(&self) -> bool { + pub const fn is_click(&self) -> bool { matches!(self, Self::Released { click: Some(_), .. }) } } @@ -1050,7 +1050,7 @@ impl PointerState { /// How much the pointer moved compared to last frame, in points. #[inline(always)] - pub fn delta(&self) -> Vec2 { + pub const fn delta(&self) -> Vec2 { self.delta } @@ -1058,7 +1058,7 @@ impl PointerState { /// Represents the actual movement of the mouse, without acceleration or clamped by screen edges. /// May be unavailable on some integrations. #[inline(always)] - pub fn motion(&self) -> Option { + pub const fn motion(&self) -> Option { self.motion } @@ -1067,7 +1067,7 @@ impl PointerState { /// This is smoothed over a few frames, /// but can be ZERO when frame-rate is bad. #[inline(always)] - pub fn velocity(&self) -> Vec2 { + pub const fn velocity(&self) -> Vec2 { self.velocity } @@ -1075,34 +1075,34 @@ impl PointerState { /// /// This is less sensitive to bad framerate than [`Self::velocity`]. #[inline(always)] - pub fn direction(&self) -> Vec2 { + pub const fn direction(&self) -> Vec2 { self.direction } /// Where did the current click/drag originate? /// `None` if no mouse button is down. #[inline(always)] - pub fn press_origin(&self) -> Option { + pub const fn press_origin(&self) -> Option { self.press_origin } /// When did the current click/drag originate? /// `None` if no mouse button is down. #[inline(always)] - pub fn press_start_time(&self) -> Option { + pub const fn press_start_time(&self) -> Option { self.press_start_time } /// Latest reported pointer position. /// When tapping a touch screen, this will be `None`. #[inline(always)] - pub fn latest_pos(&self) -> Option { + pub const fn latest_pos(&self) -> Option { self.latest_pos } /// If it is a good idea to show a tooltip, where is pointer? #[inline(always)] - pub fn hover_pos(&self) -> Option { + pub const fn hover_pos(&self) -> Option { self.latest_pos } @@ -1112,7 +1112,7 @@ impl PointerState { /// if there were interactions this frame. /// When tapping a touch screen, this will be the location of the touch. #[inline(always)] - pub fn interact_pos(&self) -> Option { + pub const fn interact_pos(&self) -> Option { self.interact_pos } @@ -1120,7 +1120,7 @@ impl PointerState { /// /// `false` if the mouse is not over the egui area, or if no touches are down on touch screens. #[inline(always)] - pub fn has_pointer(&self) -> bool { + pub const fn has_pointer(&self) -> bool { self.latest_pos.is_some() } @@ -1254,7 +1254,7 @@ impl PointerState { /// Is this button currently down? #[inline(always)] - pub fn button_down(&self, button: PointerButton) -> bool { + pub const fn button_down(&self, button: PointerButton) -> bool { self.down[button as usize] } diff --git a/crates/egui/src/input_state/touch_state.rs b/crates/egui/src/input_state/touch_state.rs index e9425dba24c..99751db1c97 100644 --- a/crates/egui/src/input_state/touch_state.rs +++ b/crates/egui/src/input_state/touch_state.rs @@ -126,10 +126,10 @@ struct ActiveTouch { } impl TouchState { - pub fn new(device_id: TouchDeviceId) -> Self { + pub const fn new(device_id: TouchDeviceId) -> Self { Self { device_id, - active_touches: Default::default(), + active_touches: BTreeMap::new(), gesture_state: None, } } diff --git a/crates/egui/src/layers.rs b/crates/egui/src/layers.rs index 3a657ba013f..19bb1c45d4c 100644 --- a/crates/egui/src/layers.rs +++ b/crates/egui/src/layers.rs @@ -42,7 +42,7 @@ impl Order { pub const TOP: Self = Self::Debug; #[inline(always)] - pub fn allow_interaction(&self) -> bool { + pub const fn allow_interaction(&self) -> bool { match self { Self::Background | Self::PanelResizeLine @@ -54,7 +54,7 @@ impl Order { } /// Short and readable summary - pub fn short_debug_format(&self) -> &'static str { + pub const fn short_debug_format(&self) -> &'static str { match self { Self::Background => "backg", Self::PanelResizeLine => "panel", @@ -76,7 +76,7 @@ pub struct LayerId { } impl LayerId { - pub fn new(order: Order, id: Id) -> Self { + pub const fn new(order: Order, id: Id) -> Self { Self { order, id } } @@ -95,7 +95,7 @@ impl LayerId { } #[inline(always)] - pub fn allow_interaction(&self) -> bool { + pub const fn allow_interaction(&self) -> bool { self.order.allow_interaction() } diff --git a/crates/egui/src/layout.rs b/crates/egui/src/layout.rs index 03b3bbd5287..321951a4559 100644 --- a/crates/egui/src/layout.rs +++ b/crates/egui/src/layout.rs @@ -2,7 +2,6 @@ use crate::{ emath::{pos2, vec2, Align2, NumExt, Pos2, Rect, Vec2}, Align, }; -use std::f32::INFINITY; // ---------------------------------------------------------------------------- @@ -89,7 +88,7 @@ pub enum Direction { impl Direction { #[inline(always)] - pub fn is_horizontal(self) -> bool { + pub const fn is_horizontal(self) -> bool { match self { Self::LeftToRight | Self::RightToLeft => true, Self::TopDown | Self::BottomUp => false, @@ -97,7 +96,7 @@ impl Direction { } #[inline(always)] - pub fn is_vertical(self) -> bool { + pub const fn is_vertical(self) -> bool { match self { Self::LeftToRight | Self::RightToLeft => false, Self::TopDown | Self::BottomUp => true, @@ -158,7 +157,7 @@ impl Layout { /// /// The `valign` parameter controls how to align elements vertically. #[inline(always)] - pub fn left_to_right(valign: Align) -> Self { + pub const fn left_to_right(valign: Align) -> Self { Self { main_dir: Direction::LeftToRight, main_wrap: false, @@ -173,7 +172,7 @@ impl Layout { /// /// The `valign` parameter controls how to align elements vertically. #[inline(always)] - pub fn right_to_left(valign: Align) -> Self { + pub const fn right_to_left(valign: Align) -> Self { Self { main_dir: Direction::RightToLeft, main_wrap: false, @@ -188,7 +187,7 @@ impl Layout { /// /// Use the provided horizontal alignment. #[inline(always)] - pub fn top_down(halign: Align) -> Self { + pub const fn top_down(halign: Align) -> Self { Self { main_dir: Direction::TopDown, main_wrap: false, @@ -201,7 +200,7 @@ impl Layout { /// Top-down layout justified so that buttons etc fill the full available width. #[inline(always)] - pub fn top_down_justified(halign: Align) -> Self { + pub const fn top_down_justified(halign: Align) -> Self { Self::top_down(halign).with_cross_justify(true) } @@ -209,7 +208,7 @@ impl Layout { /// /// Use the provided horizontal alignment. #[inline(always)] - pub fn bottom_up(halign: Align) -> Self { + pub const fn bottom_up(halign: Align) -> Self { Self { main_dir: Direction::BottomUp, main_wrap: false, @@ -221,7 +220,7 @@ impl Layout { } #[inline(always)] - pub fn from_main_dir_and_cross_align(main_dir: Direction, cross_align: Align) -> Self { + pub const fn from_main_dir_and_cross_align(main_dir: Direction, cross_align: Align) -> Self { Self { main_dir, main_wrap: false, @@ -237,7 +236,7 @@ impl Layout { /// /// Only one widget may be added to the inner `Ui`! #[inline(always)] - pub fn centered_and_justified(main_dir: Direction) -> Self { + pub const fn centered_and_justified(main_dir: Direction) -> Self { Self { main_dir, main_wrap: false, @@ -253,13 +252,13 @@ impl Layout { /// For instance, for left-to-right layouts, setting this to `true` will /// put widgets on a new row if we would overflow the right side of [`crate::Ui::max_rect`]. #[inline(always)] - pub fn with_main_wrap(self, main_wrap: bool) -> Self { + pub const fn with_main_wrap(self, main_wrap: bool) -> Self { Self { main_wrap, ..self } } /// The alignment to use on the main axis. #[inline(always)] - pub fn with_main_align(self, main_align: Align) -> Self { + pub const fn with_main_align(self, main_align: Align) -> Self { Self { main_align, ..self } } @@ -268,7 +267,7 @@ impl Layout { /// The "cross" axis is the one orthogonal to the main axis. /// For instance: in left-to-right layout, the main axis is horizontal and the cross axis is vertical. #[inline(always)] - pub fn with_cross_align(self, cross_align: Align) -> Self { + pub const fn with_cross_align(self, cross_align: Align) -> Self { Self { cross_align, ..self @@ -279,7 +278,7 @@ impl Layout { /// /// Justify here means "take up all available space". #[inline(always)] - pub fn with_main_justify(self, main_justify: bool) -> Self { + pub const fn with_main_justify(self, main_justify: bool) -> Self { Self { main_justify, ..self @@ -293,7 +292,7 @@ impl Layout { /// The "cross" axis is the one orthogonal to the main axis. /// For instance: in left-to-right layout, the main axis is horizontal and the cross axis is vertical. #[inline(always)] - pub fn with_cross_justify(self, cross_justify: bool) -> Self { + pub const fn with_cross_justify(self, cross_justify: bool) -> Self { Self { cross_justify, ..self @@ -304,44 +303,44 @@ impl Layout { /// ## Inspectors impl Layout { #[inline(always)] - pub fn main_dir(&self) -> Direction { + pub const fn main_dir(&self) -> Direction { self.main_dir } #[inline(always)] - pub fn main_wrap(&self) -> bool { + pub const fn main_wrap(&self) -> bool { self.main_wrap } #[inline(always)] - pub fn cross_align(&self) -> Align { + pub const fn cross_align(&self) -> Align { self.cross_align } #[inline(always)] - pub fn cross_justify(&self) -> bool { + pub const fn cross_justify(&self) -> bool { self.cross_justify } #[inline(always)] - pub fn is_horizontal(&self) -> bool { + pub const fn is_horizontal(&self) -> bool { self.main_dir().is_horizontal() } #[inline(always)] - pub fn is_vertical(&self) -> bool { + pub const fn is_vertical(&self) -> bool { self.main_dir().is_vertical() } - pub fn prefer_right_to_left(&self) -> bool { - self.main_dir == Direction::RightToLeft - || self.main_dir.is_vertical() && self.cross_align == Align::Max + pub const fn prefer_right_to_left(&self) -> bool { + matches!(self.main_dir, Direction::RightToLeft) + || self.main_dir.is_vertical() && matches!(self.cross_align, Align::Max) } /// e.g. for adjusting the placement of something. /// * in horizontal layout: left or right? /// * in vertical layout: same as [`Self::horizontal_align`]. - pub fn horizontal_placement(&self) -> Align { + pub const fn horizontal_placement(&self) -> Align { match self.main_dir { Direction::LeftToRight => Align::LEFT, Direction::RightToLeft => Align::RIGHT, @@ -350,7 +349,7 @@ impl Layout { } /// e.g. for when aligning text within a button. - pub fn horizontal_align(&self) -> Align { + pub const fn horizontal_align(&self) -> Align { if self.is_horizontal() { self.main_align } else { @@ -359,7 +358,7 @@ impl Layout { } /// e.g. for when aligning text within a button. - pub fn vertical_align(&self) -> Align { + pub const fn vertical_align(&self) -> Align { if self.is_vertical() { self.main_align } else { @@ -368,11 +367,11 @@ impl Layout { } /// e.g. for when aligning text within a button. - fn align2(&self) -> Align2 { + const fn align2(&self) -> Align2 { Align2([self.horizontal_align(), self.vertical_align()]) } - pub fn horizontal_justify(&self) -> bool { + pub const fn horizontal_justify(&self) -> bool { if self.is_horizontal() { self.main_justify } else { @@ -380,7 +379,7 @@ impl Layout { } } - pub fn vertical_justify(&self) -> bool { + pub const fn vertical_justify(&self) -> bool { if self.is_vertical() { self.main_justify } else { @@ -397,21 +396,21 @@ impl Layout { self.align2().align_size_within_rect(size, outer) } - fn initial_cursor(&self, max_rect: Rect) -> Rect { + const fn initial_cursor(&self, max_rect: Rect) -> Rect { let mut cursor = max_rect; match self.main_dir { Direction::LeftToRight => { - cursor.max.x = INFINITY; + cursor.max.x = f32::INFINITY; } Direction::RightToLeft => { - cursor.min.x = -INFINITY; + cursor.min.x = f32::NEG_INFINITY; } Direction::TopDown => { - cursor.max.y = INFINITY; + cursor.max.y = f32::INFINITY; } Direction::BottomUp => { - cursor.min.y = -INFINITY; + cursor.min.y = f32::NEG_INFINITY; } } @@ -538,7 +537,7 @@ impl Layout { let new_top = min_rect.bottom() + spacing.y; // tighter packing cursor = Rect::from_min_max( pos2(max_rect.left(), new_top), - pos2(INFINITY, new_top + new_row_height), + pos2(f32::INFINITY, new_top + new_row_height), ); max_rect.max.y = max_rect.max.y.max(cursor.max.y); } @@ -550,7 +549,7 @@ impl Layout { // let new_top = cursor.bottom() + spacing.y; let new_top = min_rect.bottom() + spacing.y; // tighter packing cursor = Rect::from_min_max( - pos2(-INFINITY, new_top), + pos2(f32::NEG_INFINITY, new_top), pos2(max_rect.right(), new_top + new_row_height), ); max_rect.max.y = max_rect.max.y.max(cursor.max.y); @@ -562,7 +561,7 @@ impl Layout { let new_col_width = cursor.width().max(child_size.x); cursor = Rect::from_min_max( pos2(cursor.right() + spacing.x, max_rect.top()), - pos2(cursor.right() + spacing.x + new_col_width, INFINITY), + pos2(cursor.right() + spacing.x + new_col_width, f32::INFINITY), ); max_rect.max.x = max_rect.max.x.max(cursor.max.x); } @@ -572,7 +571,7 @@ impl Layout { // New column let new_col_width = cursor.width().max(child_size.x); cursor = Rect::from_min_max( - pos2(cursor.right() + spacing.x, -INFINITY), + pos2(cursor.right() + spacing.x, f32::NEG_INFINITY), pos2( cursor.right() + spacing.x + new_col_width, max_rect.bottom(), @@ -715,24 +714,24 @@ impl Layout { Direction::LeftToRight => { *cursor = Rect::from_min_max( pos2(f32::NAN, frame_rect.min.y), - pos2(INFINITY, frame_rect.max.y), + pos2(f32::INFINITY, frame_rect.max.y), ); } Direction::RightToLeft => { *cursor = Rect::from_min_max( - pos2(-INFINITY, frame_rect.min.y), + pos2(f32::NEG_INFINITY, frame_rect.min.y), pos2(f32::NAN, frame_rect.max.y), ); } Direction::TopDown => { *cursor = Rect::from_min_max( pos2(frame_rect.min.x, f32::NAN), - pos2(frame_rect.max.x, INFINITY), + pos2(frame_rect.max.x, f32::INFINITY), ); } Direction::BottomUp => { *cursor = Rect::from_min_max( - pos2(frame_rect.min.x, -INFINITY), + pos2(frame_rect.min.x, f32::NEG_INFINITY), pos2(frame_rect.max.x, f32::NAN), ); } @@ -774,13 +773,13 @@ impl Layout { let new_top = region.cursor.bottom() + spacing.y; region.cursor = Rect::from_min_max( pos2(region.max_rect.left(), new_top), - pos2(INFINITY, new_top + region.cursor.height()), + pos2(f32::INFINITY, new_top + region.cursor.height()), ); } Direction::RightToLeft => { let new_top = region.cursor.bottom() + spacing.y; region.cursor = Rect::from_min_max( - pos2(-INFINITY, new_top), + pos2(f32::NEG_INFINITY, new_top), pos2(region.max_rect.right(), new_top + region.cursor.height()), ); } diff --git a/crates/egui/src/load.rs b/crates/egui/src/load.rs index ee12d8de845..49484da2d7a 100644 --- a/crates/egui/src/load.rs +++ b/crates/egui/src/load.rs @@ -386,19 +386,23 @@ pub struct SizedTexture { impl SizedTexture { /// Create a [`SizedTexture`] from a texture `id` with a specific `size`. + pub const fn const_new(id: TextureId, size: Vec2) -> Self { + Self { id, size } + } + + /// See [`Self::const_new`]. pub fn new(id: impl Into, size: impl Into) -> Self { - Self { - id: id.into(), - size: size.into(), - } + let id = id.into(); + let size = size.into(); + Self::const_new(id, size) } /// Fetch the [id][`SizedTexture::id`] and [size][`SizedTexture::size`] from a [`TextureHandle`]. pub fn from_handle(handle: &TextureHandle) -> Self { - let size = handle.size(); + let [width, height] = handle.size(); Self { id: handle.id(), - size: Vec2::new(size[0] as f32, size[1] as f32), + size: Vec2::new(width as f32, height as f32), } } } @@ -436,7 +440,7 @@ pub enum TexturePoll { impl TexturePoll { #[inline] - pub fn size(&self) -> Option { + pub const fn size(&self) -> Option { match self { Self::Pending { size } => *size, Self::Ready { texture } => Some(texture.size), @@ -444,7 +448,7 @@ impl TexturePoll { } #[inline] - pub fn texture_id(&self) -> Option { + pub const fn texture_id(&self) -> Option { match self { Self::Pending { .. } => None, Self::Ready { texture } => Some(texture.id), diff --git a/crates/egui/src/memory/mod.rs b/crates/egui/src/memory/mod.rs index f9fb6c9bae5..5f556d7868e 100644 --- a/crates/egui/src/memory/mod.rs +++ b/crates/egui/src/memory/mod.rs @@ -150,10 +150,9 @@ enum FocusDirection { } impl FocusDirection { - fn is_cardinal(&self) -> bool { + const fn is_cardinal(&self) -> bool { match self { Self::Up | Self::Right | Self::Down | Self::Left => true, - Self::Previous | Self::Next | Self::None => false, } } @@ -471,17 +470,18 @@ struct FocusWidget { } impl FocusWidget { - pub fn new(id: Id) -> Self { + pub const fn new(id: Id) -> Self { Self { id, - filter: Default::default(), + // TODO(BastiDood): Use `Default::default` when `const` traits stabilize. + filter: EventFilter::DEFAULT, } } } impl InteractionState { /// Are we currently clicking or dragging an egui widget? - pub fn is_using_pointer(&self) -> bool { + pub const fn is_using_pointer(&self) -> bool { self.potential_click_id.is_some() || self.potential_drag_id.is_some() } } diff --git a/crates/egui/src/memory/theme.rs b/crates/egui/src/memory/theme.rs index 71f86b1b614..a6bde921be4 100644 --- a/crates/egui/src/memory/theme.rs +++ b/crates/egui/src/memory/theme.rs @@ -11,7 +11,7 @@ pub enum Theme { impl Theme { /// Default visuals for this theme. - pub fn default_visuals(self) -> crate::Visuals { + pub const fn default_visuals(self) -> crate::Visuals { match self { Self::Dark => crate::Visuals::dark(), Self::Light => crate::Visuals::light(), @@ -19,7 +19,7 @@ impl Theme { } /// Chooses between [`Self::Dark`] or [`Self::Light`] based on a boolean value. - pub fn from_dark_mode(dark_mode: bool) -> Self { + pub const fn from_dark_mode(dark_mode: bool) -> Self { if dark_mode { Self::Dark } else { diff --git a/crates/egui/src/menu.rs b/crates/egui/src/menu.rs index 1683125d4e9..56f89f2dd13 100644 --- a/crates/egui/src/menu.rs +++ b/crates/egui/src/menu.rs @@ -55,7 +55,7 @@ impl BarState { self.open_menu.show(button, add_contents) } - pub(crate) fn has_root(&self) -> bool { + pub(crate) const fn has_root(&self) -> bool { self.open_menu.inner.is_some() } } @@ -491,8 +491,8 @@ pub enum MenuResponse { } impl MenuResponse { - pub fn is_close(&self) -> bool { - *self == Self::Close + pub const fn is_close(&self) -> bool { + matches!(self, Self::Close) } } @@ -504,12 +504,15 @@ pub struct SubMenuButton { impl SubMenuButton { /// The `icon` can be an emoji (e.g. `⏵` right arrow), shown right of the label + const fn const_new(text: WidgetText, icon: WidgetText, index: usize) -> Self { + Self { text, icon, index } + } + + /// See [`Self::const_new`]. fn new(text: impl Into, icon: impl Into, index: usize) -> Self { - Self { - text: text.into(), - icon: icon.into(), - index, - } + let text = text.into(); + let icon = icon.into(); + Self::const_new(text, icon, index) } fn visuals<'a>( diff --git a/crates/egui/src/painter.rs b/crates/egui/src/painter.rs index ff7d9879c7f..24f1d70c182 100644 --- a/crates/egui/src/painter.rs +++ b/crates/egui/src/painter.rs @@ -37,7 +37,7 @@ pub struct Painter { impl Painter { /// Create a painter to a specific layer within a certain clip rectangle. - pub fn new(ctx: Context, layer_id: LayerId, clip_rect: Rect) -> Self { + pub const fn new(ctx: Context, layer_id: LayerId, clip_rect: Rect) -> Self { Self { ctx, layer_id, @@ -108,12 +108,12 @@ impl Painter { /// /// See also: [`Self::set_opacity`] and [`Self::multiply_opacity`]. #[inline] - pub fn opacity(&self) -> f32 { + pub const fn opacity(&self) -> f32 { self.opacity_factor } - pub(crate) fn is_visible(&self) -> bool { - self.fade_to_color != Some(Color32::TRANSPARENT) + pub(crate) const fn is_visible(&self) -> bool { + !matches!(self.fade_to_color, Some(Color32::TRANSPARENT)) } /// If `false`, nothing added to the painter will be visible @@ -126,7 +126,7 @@ impl Painter { impl Painter { /// Get a reference to the parent [`Context`]. #[inline] - pub fn ctx(&self) -> &Context { + pub const fn ctx(&self) -> &Context { &self.ctx } @@ -140,14 +140,14 @@ impl Painter { /// Where we paint #[inline] - pub fn layer_id(&self) -> LayerId { + pub const 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] - pub fn clip_rect(&self) -> Rect { + pub const fn clip_rect(&self) -> Rect { self.clip_rect } diff --git a/crates/egui/src/placer.rs b/crates/egui/src/placer.rs index 3490eef1064..49aafd1b0b9 100644 --- a/crates/egui/src/placer.rs +++ b/crates/egui/src/placer.rs @@ -32,32 +32,32 @@ impl Placer { } #[inline(always)] - pub(crate) fn grid(&self) -> Option<&grid::GridLayout> { + pub(crate) const fn grid(&self) -> Option<&grid::GridLayout> { self.grid.as_ref() } #[inline(always)] - pub(crate) fn is_grid(&self) -> bool { + pub(crate) const fn is_grid(&self) -> bool { self.grid.is_some() } #[inline(always)] - pub(crate) fn layout(&self) -> &Layout { + pub(crate) const fn layout(&self) -> &Layout { &self.layout } #[inline(always)] - pub(crate) fn prefer_right_to_left(&self) -> bool { + pub(crate) const fn prefer_right_to_left(&self) -> bool { self.layout.prefer_right_to_left() } #[inline(always)] - pub(crate) fn min_rect(&self) -> Rect { + pub(crate) const fn min_rect(&self) -> Rect { self.region.min_rect } #[inline(always)] - pub(crate) fn max_rect(&self) -> Rect { + pub(crate) const fn max_rect(&self) -> Rect { self.region.max_rect } @@ -67,7 +67,7 @@ impl Placer { } #[inline(always)] - pub(crate) fn cursor(&self) -> Rect { + pub(crate) const fn cursor(&self) -> Rect { self.region.cursor } diff --git a/crates/egui/src/response.rs b/crates/egui/src/response.rs index d6a9a8a0c7f..dd582a280a8 100644 --- a/crates/egui/src/response.rs +++ b/crates/egui/src/response.rs @@ -163,7 +163,7 @@ impl Response { /// /// Usually you want to check [`Self::secondary_clicked`] instead. #[inline] - pub fn long_touched(&self) -> bool { + pub const fn long_touched(&self) -> bool { self.long_touched } @@ -226,7 +226,7 @@ impl Response { /// If false, there was no interaction attempted /// and the widget should be drawn in a gray disabled look. #[inline(always)] - pub fn enabled(&self) -> bool { + pub const fn enabled(&self) -> bool { self.enabled } @@ -235,7 +235,7 @@ impl Response { /// In contrast to [`Self::contains_pointer`], this will be `false` whenever some other widget is being dragged. /// `hovered` is always `false` for disabled widgets. #[inline(always)] - pub fn hovered(&self) -> bool { + pub const fn hovered(&self) -> bool { self.hovered } @@ -248,14 +248,14 @@ impl Response { /// This is slightly different from [`Ui::rect_contains_pointer`] and [`Context::rect_contains_pointer`], in that /// [`Self::contains_pointer`] also checks that no other widget is covering this response rectangle. #[inline(always)] - pub fn contains_pointer(&self) -> bool { + pub const fn contains_pointer(&self) -> bool { self.contains_pointer } /// The widget is highlighted via a call to [`Self::highlight`] or [`Context::highlight_widget`]. #[doc(hidden)] #[inline(always)] - pub fn highlighted(&self) -> bool { + pub const fn highlighted(&self) -> bool { self.highlighted } @@ -308,7 +308,7 @@ impl Response { /// /// This will only be true for a single frame. #[inline] - pub fn drag_started(&self) -> bool { + pub const fn drag_started(&self) -> bool { self.drag_started } @@ -338,7 +338,7 @@ impl Response { /// [`crate::DragValue`] senses drags; [`crate::Label`] does not (unless you call [`crate::Label::sense`]). /// You can use [`Self::interact`] to sense more things *after* adding a widget. #[inline(always)] - pub fn dragged(&self) -> bool { + pub const fn dragged(&self) -> bool { self.dragged } @@ -350,7 +350,7 @@ impl Response { /// The widget was being dragged, but now it has been released. #[inline] - pub fn drag_stopped(&self) -> bool { + pub const fn drag_stopped(&self) -> bool { self.drag_stopped } @@ -362,7 +362,7 @@ impl Response { /// The widget was being dragged, but now it has been released. #[inline] #[deprecated = "Renamed 'drag_stopped'"] - pub fn drag_released(&self) -> bool { + pub const fn drag_released(&self) -> bool { self.drag_stopped } @@ -452,7 +452,7 @@ impl Response { /// /// `None` if the widget is not being interacted with. #[inline] - pub fn interact_pointer_pos(&self) -> Option { + pub const fn interact_pointer_pos(&self) -> Option { self.interact_pointer_pos } @@ -482,7 +482,7 @@ impl Response { /// /// This could also be thought of as "is this widget being interacted with?". #[inline(always)] - pub fn is_pointer_button_down_on(&self) -> bool { + pub const fn is_pointer_button_down_on(&self) -> bool { self.is_pointer_button_down_on } @@ -497,7 +497,7 @@ impl Response { /// This is not set if the *view* of the data was changed. /// For instance, moving the cursor in a [`TextEdit`](crate::TextEdit) does not set this to `true`. #[inline(always)] - pub fn changed(&self) -> bool { + pub const fn changed(&self) -> bool { self.changed } @@ -1214,7 +1214,7 @@ pub struct InnerResponse { impl InnerResponse { #[inline] - pub fn new(inner: R, response: Response) -> Self { + pub const fn new(inner: R, response: Response) -> Self { Self { inner, response } } } diff --git a/crates/egui/src/sense.rs b/crates/egui/src/sense.rs index 1b6394b2cc3..a5f66f30b7d 100644 --- a/crates/egui/src/sense.rs +++ b/crates/egui/src/sense.rs @@ -41,7 +41,7 @@ impl Sense { /// Senses no clicks or drags. Only senses mouse hover. #[doc(alias = "none")] #[inline] - pub fn hover() -> Self { + pub const fn hover() -> Self { Self { click: false, drag: false, @@ -52,7 +52,7 @@ impl Sense { /// Senses no clicks or drags, but can be focused with the keyboard. /// Used for labels that can be focused for the benefit of screen readers. #[inline] - pub fn focusable_noninteractive() -> Self { + pub const fn focusable_noninteractive() -> Self { Self { click: false, drag: false, @@ -62,7 +62,7 @@ impl Sense { /// Sense clicks and hover, but not drags. #[inline] - pub fn click() -> Self { + pub const fn click() -> Self { Self { click: true, drag: false, @@ -72,7 +72,7 @@ impl Sense { /// Sense drags and hover, but not clicks. #[inline] - pub fn drag() -> Self { + pub const fn drag() -> Self { Self { click: false, drag: true, @@ -89,7 +89,7 @@ impl Sense { /// /// See [`crate::PointerState::is_decidedly_dragging`] for details. #[inline] - pub fn click_and_drag() -> Self { + pub const fn click_and_drag() -> Self { Self { click: true, drag: true, @@ -100,7 +100,7 @@ impl Sense { /// The logical "or" of two [`Sense`]s. #[must_use] #[inline] - pub fn union(self, other: Self) -> Self { + pub const fn union(self, other: Self) -> Self { Self { click: self.click | other.click, drag: self.drag | other.drag, @@ -110,7 +110,7 @@ impl Sense { /// Returns true if we sense either clicks or drags. #[inline] - pub fn interactive(&self) -> bool { + pub const fn interactive(&self) -> bool { self.click || self.drag } } diff --git a/crates/egui/src/style.rs b/crates/egui/src/style.rs index f1787fda212..09f97d2d431 100644 --- a/crates/egui/src/style.rs +++ b/crates/egui/src/style.rs @@ -314,7 +314,7 @@ impl Style { } /// Style to use for non-interactive widgets. - pub fn noninteractive(&self) -> &WidgetVisuals { + pub const fn noninteractive(&self) -> &WidgetVisuals { &self.visuals.widgets.noninteractive } @@ -525,7 +525,7 @@ impl Default for ScrollStyle { impl ScrollStyle { /// Solid scroll bars that always use up space - pub fn solid() -> Self { + pub const fn solid() -> Self { Self { floating: false, bar_width: 6.0, @@ -548,7 +548,7 @@ impl ScrollStyle { } /// Thin scroll bars that expand on hover - pub fn thin() -> Self { + pub const fn thin() -> Self { Self { floating: true, bar_width: 10.0, @@ -572,7 +572,7 @@ impl ScrollStyle { /// No scroll bars until you hover the scroll area, /// at which time they appear faintly, and then expand /// when you hover the scroll bars. - pub fn floating() -> Self { + pub const fn floating() -> Self { Self { floating: true, bar_width: 10.0, @@ -713,16 +713,13 @@ pub struct ScrollAnimation { impl Default for ScrollAnimation { fn default() -> Self { - Self { - points_per_second: 1000.0, - duration: Rangef::new(0.1, 0.3), - } + Self::new(1000.0, Rangef::new(0.1, 0.3)) } } impl ScrollAnimation { /// New scroll animation - pub fn new(points_per_second: f32, duration: Rangef) -> Self { + pub const fn new(points_per_second: f32, duration: Rangef) -> Self { Self { points_per_second, duration, @@ -730,7 +727,7 @@ impl ScrollAnimation { } /// No animation, scroll instantly. - pub fn none() -> Self { + pub const fn none() -> Self { Self { points_per_second: f32::INFINITY, duration: Rangef::new(0.0, 0.0), @@ -738,7 +735,7 @@ impl ScrollAnimation { } /// Scroll with a fixed duration, regardless of distance. - pub fn duration(t: f32) -> Self { + pub const fn duration(t: f32) -> Self { Self { points_per_second: f32::INFINITY, duration: Rangef::new(t, t), @@ -842,13 +839,7 @@ pub struct TextCursorStyle { impl Default for TextCursorStyle { fn default() -> Self { - Self { - stroke: Stroke::new(2.0, Color32::from_rgb(192, 222, 255)), // Dark mode - preview: false, - blink: true, - on_duration: 0.5, - off_duration: 0.5, - } + Self::DEFAULT } } @@ -972,7 +963,7 @@ pub struct Visuals { impl Visuals { #[inline(always)] - pub fn noninteractive(&self) -> &WidgetVisuals { + pub const fn noninteractive(&self) -> &WidgetVisuals { &self.widgets.noninteractive } @@ -993,19 +984,19 @@ impl Visuals { /// Window background color. #[inline(always)] - pub fn window_fill(&self) -> Color32 { + pub const fn window_fill(&self) -> Color32 { self.window_fill } #[inline(always)] - pub fn window_stroke(&self) -> Stroke { + pub const fn window_stroke(&self) -> Stroke { self.window_stroke } /// When fading out things, we fade the colors towards this. // TODO(emilk): replace with an alpha #[inline(always)] - pub fn fade_out_to_color(&self) -> Color32 { + pub const fn fade_out_to_color(&self) -> Color32 { self.widgets.noninteractive.weak_bg_fill } @@ -1112,7 +1103,7 @@ pub struct WidgetVisuals { impl WidgetVisuals { #[inline(always)] - pub fn text_color(&self) -> Color32 { + pub const fn text_color(&self) -> Color32 { self.fg_stroke.color } } @@ -1265,12 +1256,12 @@ impl Default for Interaction { impl Visuals { /// Default dark theme. - pub fn dark() -> Self { + pub const fn dark() -> Self { Self { dark_mode: true, override_text_color: None, - widgets: Widgets::default(), - selection: Selection::default(), + widgets: Widgets::dark(), + selection: Selection::dark(), hyperlink_color: Color32::from_rgb(90, 170, 255), faint_bg_color: Color32::from_additive_luminance(5), // visible, but barely so extreme_bg_color: Color32::from_gray(10), // e.g. TextEdit background @@ -1286,7 +1277,7 @@ impl Visuals { color: Color32::from_black_alpha(96), }, window_fill: Color32::from_gray(27), - window_stroke: Stroke::new(1.0, Color32::from_gray(60)), + window_stroke: Stroke::const_new(1.0, Color32::from_gray(60)), window_highlight_topmost: true, menu_rounding: Rounding::same(6.0), @@ -1302,7 +1293,8 @@ impl Visuals { resize_corner_size: 12.0, - text_cursor: Default::default(), + // TODO(BastiDood): Use `Default::default` when `const` traits stabilize. + text_cursor: TextCursorStyle::DEFAULT, clip_rect_margin: 3.0, // should be at least half the size of the widest frame stroke + max WidgetVisuals::expansion button_frame: true, @@ -1323,7 +1315,7 @@ impl Visuals { } /// Default light theme. - pub fn light() -> Self { + pub const fn light() -> Self { Self { dark_mode: false, widgets: Widgets::light(), @@ -1342,7 +1334,7 @@ impl Visuals { color: Color32::from_black_alpha(25), }, window_fill: Color32::from_gray(248), - window_stroke: Stroke::new(1.0, Color32::from_gray(190)), + window_stroke: Stroke::const_new(1.0, Color32::from_gray(190)), panel_fill: Color32::from_gray(248), @@ -1354,8 +1346,9 @@ impl Visuals { }, text_cursor: TextCursorStyle { - stroke: Stroke::new(2.0, Color32::from_rgb(0, 83, 125)), - ..Default::default() + stroke: Stroke::const_new(2.0, Color32::from_rgb(0, 83, 125)), + // TODO(BastiDood): Use `Default::default` when `const` traits stabilize. + ..TextCursorStyle::DEFAULT }, ..Self::dark() @@ -1370,17 +1363,17 @@ impl Default for Visuals { } impl Selection { - fn dark() -> Self { + const fn dark() -> Self { Self { bg_fill: Color32::from_rgb(0, 92, 128), - stroke: Stroke::new(1.0, Color32::from_rgb(192, 222, 255)), + stroke: Stroke::const_new(1.0, Color32::from_rgb(192, 222, 255)), } } - fn light() -> Self { + const fn light() -> Self { Self { bg_fill: Color32::from_rgb(144, 209, 255), - stroke: Stroke::new(1.0, Color32::from_rgb(0, 83, 125)), + stroke: Stroke::const_new(1.0, Color32::from_rgb(0, 83, 125)), } } } @@ -1392,90 +1385,92 @@ impl Default for Selection { } impl Widgets { - pub fn dark() -> Self { + pub const fn dark() -> Self { Self { noninteractive: WidgetVisuals { weak_bg_fill: Color32::from_gray(27), bg_fill: Color32::from_gray(27), - bg_stroke: Stroke::new(1.0, Color32::from_gray(60)), // separators, indentation lines - fg_stroke: Stroke::new(1.0, Color32::from_gray(140)), // normal text color + bg_stroke: Stroke::const_new(1.0, Color32::from_gray(60)), // separators, indentation lines + fg_stroke: Stroke::const_new(1.0, Color32::from_gray(140)), // normal text color rounding: Rounding::same(2.0), expansion: 0.0, }, inactive: WidgetVisuals { weak_bg_fill: Color32::from_gray(60), // button background bg_fill: Color32::from_gray(60), // checkbox background - bg_stroke: Default::default(), - fg_stroke: Stroke::new(1.0, Color32::from_gray(180)), // button text + // TODO(BastiDood): Use `Default::default` when `const` traits stabilize. + bg_stroke: Stroke::NONE, + fg_stroke: Stroke::const_new(1.0, Color32::from_gray(180)), // button text rounding: Rounding::same(2.0), expansion: 0.0, }, hovered: WidgetVisuals { weak_bg_fill: Color32::from_gray(70), bg_fill: Color32::from_gray(70), - bg_stroke: Stroke::new(1.0, Color32::from_gray(150)), // e.g. hover over window edge or button - fg_stroke: Stroke::new(1.5, Color32::from_gray(240)), + bg_stroke: Stroke::const_new(1.0, Color32::from_gray(150)), // e.g. hover over window edge or button + fg_stroke: Stroke::const_new(1.5, Color32::from_gray(240)), rounding: Rounding::same(3.0), expansion: 1.0, }, active: WidgetVisuals { weak_bg_fill: Color32::from_gray(55), bg_fill: Color32::from_gray(55), - bg_stroke: Stroke::new(1.0, Color32::WHITE), - fg_stroke: Stroke::new(2.0, Color32::WHITE), + bg_stroke: Stroke::const_new(1.0, Color32::WHITE), + fg_stroke: Stroke::const_new(2.0, Color32::WHITE), rounding: Rounding::same(2.0), expansion: 1.0, }, open: WidgetVisuals { weak_bg_fill: Color32::from_gray(45), bg_fill: Color32::from_gray(27), - bg_stroke: Stroke::new(1.0, Color32::from_gray(60)), - fg_stroke: Stroke::new(1.0, Color32::from_gray(210)), + bg_stroke: Stroke::const_new(1.0, Color32::from_gray(60)), + fg_stroke: Stroke::const_new(1.0, Color32::from_gray(210)), rounding: Rounding::same(2.0), expansion: 0.0, }, } } - pub fn light() -> Self { + pub const fn light() -> Self { Self { noninteractive: WidgetVisuals { weak_bg_fill: Color32::from_gray(248), bg_fill: Color32::from_gray(248), - bg_stroke: Stroke::new(1.0, Color32::from_gray(190)), // separators, indentation lines - fg_stroke: Stroke::new(1.0, Color32::from_gray(80)), // normal text color + bg_stroke: Stroke::const_new(1.0, Color32::from_gray(190)), // separators, indentation lines + fg_stroke: Stroke::const_new(1.0, Color32::from_gray(80)), // normal text color rounding: Rounding::same(2.0), expansion: 0.0, }, inactive: WidgetVisuals { weak_bg_fill: Color32::from_gray(230), // button background bg_fill: Color32::from_gray(230), // checkbox background - bg_stroke: Default::default(), - fg_stroke: Stroke::new(1.0, Color32::from_gray(60)), // button text + // TODO(BastiDood): Use `Default::default` when `const` traits stabilize. + bg_stroke: Stroke::NONE, + fg_stroke: Stroke::const_new(1.0, Color32::from_gray(60)), // button text rounding: Rounding::same(2.0), expansion: 0.0, }, hovered: WidgetVisuals { weak_bg_fill: Color32::from_gray(220), bg_fill: Color32::from_gray(220), - bg_stroke: Stroke::new(1.0, Color32::from_gray(105)), // e.g. hover over window edge or button - fg_stroke: Stroke::new(1.5, Color32::BLACK), + bg_stroke: Stroke::const_new(1.0, Color32::from_gray(105)), // e.g. hover over window edge or button + fg_stroke: Stroke::const_new(1.5, Color32::BLACK), rounding: Rounding::same(3.0), expansion: 1.0, }, active: WidgetVisuals { weak_bg_fill: Color32::from_gray(165), bg_fill: Color32::from_gray(165), - bg_stroke: Stroke::new(1.0, Color32::BLACK), - fg_stroke: Stroke::new(2.0, Color32::BLACK), + bg_stroke: Stroke::const_new(1.0, Color32::BLACK), + fg_stroke: Stroke::const_new(2.0, Color32::BLACK), rounding: Rounding::same(2.0), expansion: 1.0, }, open: WidgetVisuals { weak_bg_fill: Color32::from_gray(220), bg_fill: Color32::from_gray(220), - bg_stroke: Stroke::new(1.0, Color32::from_gray(160)), - fg_stroke: Stroke::new(1.0, Color32::BLACK), + bg_stroke: Stroke::const_new(1.0, Color32::from_gray(160)), + fg_stroke: Stroke::const_new(1.0, Color32::BLACK), rounding: Rounding::same(2.0), expansion: 0.0, }, @@ -2141,6 +2136,14 @@ impl Visuals { } impl TextCursorStyle { + pub const DEFAULT: Self = Self { + stroke: Stroke::const_new(2.0, Color32::from_rgb(192, 222, 255)), // Dark mode + preview: false, + blink: true, + on_duration: 0.5, + off_duration: 0.5, + }; + fn ui(&mut self, ui: &mut Ui) { let Self { stroke, diff --git a/crates/egui/src/text_selection/cursor_range.rs b/crates/egui/src/text_selection/cursor_range.rs index bd3f496fd8e..14e7e1cf4fc 100644 --- a/crates/egui/src/text_selection/cursor_range.rs +++ b/crates/egui/src/text_selection/cursor_range.rs @@ -24,7 +24,7 @@ pub struct CursorRange { impl CursorRange { /// The empty range. #[inline] - pub fn one(cursor: Cursor) -> Self { + pub const fn one(cursor: Cursor) -> Self { Self { primary: cursor, secondary: cursor, @@ -32,7 +32,7 @@ impl CursorRange { } #[inline] - pub fn two(min: Cursor, max: Cursor) -> Self { + pub const fn two(min: Cursor, max: Cursor) -> Self { Self { primary: max, secondary: min, @@ -44,7 +44,7 @@ impl CursorRange { Self::two(galley.begin(), galley.end()) } - pub fn as_ccursor_range(&self) -> CCursorRange { + pub const fn as_ccursor_range(&self) -> CCursorRange { CCursorRange { primary: self.primary.ccursor, secondary: self.secondary.ccursor, @@ -229,19 +229,24 @@ pub struct CCursorRange { impl CCursorRange { /// The empty range. #[inline] - pub fn one(ccursor: CCursor) -> Self { + pub const fn one(ccursor: CCursor) -> Self { Self { primary: ccursor, secondary: ccursor, } } + #[inline] + pub const fn const_two(primary: CCursor, secondary: CCursor) -> Self { + Self { primary, secondary } + } + + /// See [`Self::const_two`]. #[inline] pub fn two(min: impl Into, max: impl Into) -> Self { - Self { - primary: max.into(), - secondary: min.into(), - } + let min = min.into(); + let max = max.into(); + Self::const_two(min, max) } #[inline] diff --git a/crates/egui/src/text_selection/label_text_selection.rs b/crates/egui/src/text_selection/label_text_selection.rs index a2d78da5dea..672bb4ad025 100644 --- a/crates/egui/src/text_selection/label_text_selection.rs +++ b/crates/egui/src/text_selection/label_text_selection.rs @@ -223,7 +223,7 @@ impl LabelSelectionState { state.store(ctx); } - pub fn has_selection(&self) -> bool { + pub const fn has_selection(&self) -> bool { self.selection.is_some() } diff --git a/crates/egui/src/text_selection/text_cursor_state.rs b/crates/egui/src/text_selection/text_cursor_state.rs index dc75c7dd864..2d8a713c006 100644 --- a/crates/egui/src/text_selection/text_cursor_state.rs +++ b/crates/egui/src/text_selection/text_cursor_state.rs @@ -45,7 +45,7 @@ impl From for TextCursorState { } impl TextCursorState { - pub fn is_empty(&self) -> bool { + pub const fn is_empty(&self) -> bool { self.cursor_range.is_none() && self.ccursor_range.is_none() } @@ -290,11 +290,11 @@ fn next_line_boundary_char_index(it: impl Iterator, mut index: usiz index } -pub fn is_word_char(c: char) -> bool { +pub const fn is_word_char(c: char) -> bool { c.is_ascii_alphanumeric() || c == '_' } -fn is_linebreak(c: char) -> bool { +const fn is_linebreak(c: char) -> bool { c == '\r' || c == '\n' } diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index 627c119b139..e75ddf02058 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -301,7 +301,7 @@ impl Ui { /// Set to true in special cases where we do one frame /// where we size up the contents of the Ui, without actually showing it. #[inline] - pub fn is_sizing_pass(&self) -> bool { + pub const fn is_sizing_pass(&self) -> bool { self.sizing_pass } @@ -309,7 +309,7 @@ impl Ui { /// A unique identity of this [`Ui`]. #[inline] - pub fn id(&self) -> Id { + pub const fn id(&self) -> Id { self.id } @@ -317,7 +317,7 @@ impl Ui { /// /// Note that this may be a different [`Style`] than that of [`Context::style`]. #[inline] - pub fn style(&self) -> &Arc