max / makeover-immediate
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+58 insertions,
-0 deletions
| @@ -107,6 +107,22 @@ | |||
| 107 | 107 | pub bevel_light: Color32, | |
| 108 | 108 | /// `bevel-dark`. | |
| 109 | 109 | pub bevel_dark: Color32, | |
| 110 | + | /// `elevation`. | |
| 111 | + | /// | |
| 112 | + | /// What a surface that floats OVER the page is cast onto it with. The one | |
| 113 | + | /// intent here that is about a surface's relationship to the page rather | |
| 114 | + | /// than about the surface, which is why it is a translucent near-black on | |
| 115 | + | /// every theme rather than something read off the palette's own ramp. | |
| 116 | + | /// | |
| 117 | + | /// **Only for a surface that overlays.** A menu, a tooltip, a modal. A | |
| 118 | + | /// surface *in* the layout takes a bevel, and reaching for this on a panel | |
| 119 | + | /// or a card is how a pre-Platinum look survives a conversion under a new | |
| 120 | + | /// name. | |
| 121 | + | /// | |
| 122 | + | /// egui has a real answer for this where a terminal does not: see | |
| 123 | + | /// [`Palette::cast`], which is the shadow to hand an | |
| 124 | + | /// [`egui::Frame`](egui::Frame). | |
| 125 | + | pub elevation: Color32, | |
| 110 | 126 | /// `content`. | |
| 111 | 127 | /// | |
| 112 | 128 | /// Ordinary text. Added 0.5.0 with the field renderer, which is the first | |
| @@ -154,6 +170,35 @@ | |||
| 154 | 170 | } | |
| 155 | 171 | } | |
| 156 | 172 | ||
| 173 | + | /// The cast shadow for a surface that overlays the page. | |
| 174 | + | /// | |
| 175 | + | /// What "overlaying" means in immediate mode, answered rather than skipped. | |
| 176 | + | /// egui already paints shadows for its menus and windows through | |
| 177 | + | /// [`egui::Frame::shadow`], so the honest port is to hand that machinery the | |
| 178 | + | /// theme's tone instead of egui's own default, not to invent a painter here | |
| 179 | + | /// the way [`paint_bevel`] had to. | |
| 180 | + | /// | |
| 181 | + | /// The geometry matches what `makeover-webview` composes, in points rather | |
| 182 | + | /// than pixels: a small downward offset and a wide soft blur. A Platinum-era | |
| 183 | + | /// menu sits just off the page rather than hovering above it. | |
| 184 | + | /// | |
| 185 | + | /// ```no_run | |
| 186 | + | /// # let palette: makeover_immediate::Palette = unimplemented!(); | |
| 187 | + | /// # let ui: &mut egui::Ui = unimplemented!(); | |
| 188 | + | /// egui::Frame::popup(ui.style()) | |
| 189 | + | /// .shadow(palette.cast()) | |
| 190 | + | /// .show(ui, |ui| { ui.label("over the page"); }); | |
| 191 | + | /// ``` | |
| 192 | + | #[must_use] | |
| 193 | + | pub const fn cast(&self) -> egui::Shadow { | |
| 194 | + | egui::Shadow { | |
| 195 | + | offset: [0, 2], | |
| 196 | + | blur: 24, | |
| 197 | + | spread: 0, | |
| 198 | + | color: self.elevation, | |
| 199 | + | } | |
| 200 | + | } | |
| 201 | + | ||
| 157 | 202 | /// Resolve a bevel edge intent. | |
| 158 | 203 | #[must_use] | |
| 159 | 204 | pub const fn edge(&self, edge: Edge) -> Color32 { | |
| @@ -602,12 +647,25 @@ | |||
| 602 | 647 | sunken: Color32::from_rgb(4, 4, 4), | |
| 603 | 648 | bevel_light: Color32::WHITE, | |
| 604 | 649 | bevel_dark: Color32::BLACK, | |
| 650 | + | elevation: Color32::from_black_alpha(46), | |
| 605 | 651 | content: Color32::from_rgb(5, 5, 5), | |
| 606 | 652 | content_muted: Color32::from_rgb(6, 6, 6), | |
| 607 | 653 | danger: Color32::from_rgb(7, 7, 7), | |
| 608 | 654 | } | |
| 609 | 655 | } | |
| 610 | 656 | ||
| 657 | + | /// The cast is egui's own shadow type carrying the theme's tone, which is | |
| 658 | + | /// the whole of what this crate had to decide for it: unlike a bevel, egui | |
| 659 | + | /// already knows how to paint one. | |
| 660 | + | #[test] | |
| 661 | + | fn the_cast_hands_egui_the_themes_tone() { | |
| 662 | + | let p = palette(Color32::from_rgb(9, 9, 9)); | |
| 663 | + | let cast = p.cast(); | |
| 664 | + | assert_eq!(cast.color, p.elevation); | |
| 665 | + | assert!(cast.blur > 0, "a cast shadow is soft"); | |
| 666 | + | assert_eq!(cast.offset, [0, 2], "it falls downward and only a little"); | |
| 667 | + | } | |
| 668 | + | ||
| 611 | 669 | #[test] | |
| 612 | 670 | fn a_well_resolves_to_its_own_token() { | |
| 613 | 671 | // No substitution left. The page-filled well was a stand-in for a |