-
Hi, I have a problem with the styling of my buttons. I successfully styled the text color, background color and borders using Now, I want the text of my buttons to be a little bit more elaborated, including an icon in the form of a specific font character. The text of the button should therefore have 2 different parts: one with the font icon and one with the text itself. let mut job = LayoutJob::default();
job.append(
my_icon,
0.0,
TextFormat {
font_id: FontId::new(ICON_SIZE, FontFamily::Name("icon".into())),
..Default::default()
},
);
job.append(
my_text,
0.0,
TextFormat {
font_id: FontId::new(TEXT_SIZE, FontFamily::Proportional),
..Default::default()
},
);
let button = Button::new(job); The icon and the text are displayed with the correct font and size, however all the colors set using Is there a way to have both custom styling and a text that uses different fonts and sizes please? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
The problem is that the button does the interaction first, and then draws itself depending on the response, and you don't have access to that until you have already rendered it. I think one workaround is to do the impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.style_mut().visuals.widgets.hovered.fg_stroke.color = egui::Color32::BLUE;
let ICON_SIZE = 30.0;
let TEXT_SIZE = 12.0;
let get_job = |visuals: Option<&WidgetVisuals>| {
let mut job = LayoutJob::default();
let color = visuals.map_or(egui::Color32::TRANSPARENT, |v| v.text_color());
job.append(
"&",
0.0,
TextFormat {
font_id: FontId::new(ICON_SIZE, FontFamily::Proportional),
color,
..Default::default()
},
);
job.append(
"Text",
0.0,
TextFormat {
font_id: FontId::new(TEXT_SIZE, FontFamily::Proportional),
color,
..Default::default()
},
);
job
};
let response = ui.button(get_job(None));
let visuals = ui.style().interact(&response);
let job = get_job(Some(visuals));
let galley = WidgetText::LayoutJob(job).into_galley(
ui,
None,
response.rect.width(),
TextStyle::Button,
);
ui.painter().galley(
response
.rect
.shrink2(ui.spacing().button_padding)
.left_top(),
galley,
egui::Color32::TRANSPARENT,
);
ui.button("Another button");
});
}
} Screencast.from.2024-05-21.22-49-58.mp4I don't know if there is an easier way. |
Beta Was this translation helpful? Give feedback.
The problem is that the button does the interaction first, and then draws itself depending on the response, and you don't have access to that until you have already rendered it. I think one workaround is to do the
LayoutJob
twice, first with invisible text just to get the size of the button right, and then again with the correct color according to the button response: