mirror of
https://github.com/emilk/egui.git
synced 2026-06-26 22:53:14 -04:00
<!-- Please read the "Making a PR" section of [`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md) before opening a Pull Request! * Keep your PR:s small and focused. * The PR title is what ends up in the changelog, so make it descriptive! * If applicable, add a screenshot or gif. * If it is a non-trivial addition, consider adding a demo for it to `egui_demo_lib`, or a new example. * Do NOT open PR:s from your `master` branch, as that makes it hard for maintainers to test and add commits to your PR. * Remember to run `cargo fmt` and `cargo clippy`. * Open the PR as a draft until you have self-reviewed it and run `./scripts/check.sh`. * When you have addressed a PR comment, mark it as resolved. Please be patient! I will review your PR, but my time is limited! --> * Closes <https://github.com/emilk/egui/issues/7466> * [x] I have followed the instructions in the PR template * I have ran `./scripts/check.sh` and it has no fails * I have run `cargo fmt` and `cargo clippy` Added the deprecated tag to ImageButton struct Removed the `WidgetType::ImageButton` variant. ImageButton will use `WidgetType::Button` for its WidgetInfo *This is my first PR ever, please let me know if I did something wrong so I can change it* --------- Co-authored-by: Nicolas <bircni@icloud.com> Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> Co-authored-by: Lucas Meurer <hi@lucasmerlin.me>
165 lines
5.1 KiB
Rust
165 lines
5.1 KiB
Rust
use crate::{
|
|
Color32, CornerRadius, Image, Rect, Response, Sense, Ui, Vec2, Widget, WidgetInfo, WidgetType,
|
|
widgets,
|
|
};
|
|
|
|
/// A clickable image within a frame.
|
|
#[must_use = "You should put this widget in a ui with `ui.add(widget);`"]
|
|
#[derive(Clone, Debug)]
|
|
#[deprecated(since = "0.33.0", note = "Use egui::Button::image instead")]
|
|
pub struct ImageButton<'a> {
|
|
pub(crate) image: Image<'a>,
|
|
sense: Sense,
|
|
frame: bool,
|
|
selected: bool,
|
|
alt_text: Option<String>,
|
|
}
|
|
|
|
#[expect(deprecated, reason = "Deprecated in egui 0.33.0")]
|
|
impl<'a> ImageButton<'a> {
|
|
pub fn new(image: impl Into<Image<'a>>) -> Self {
|
|
Self {
|
|
image: image.into(),
|
|
sense: Sense::click(),
|
|
frame: true,
|
|
selected: false,
|
|
alt_text: None,
|
|
}
|
|
}
|
|
|
|
/// Select UV range. Default is (0,0) in top-left, (1,1) bottom right.
|
|
#[inline]
|
|
pub fn uv(mut self, uv: impl Into<Rect>) -> Self {
|
|
self.image = self.image.uv(uv);
|
|
self
|
|
}
|
|
|
|
/// Multiply image color with this. Default is WHITE (no tint).
|
|
#[inline]
|
|
pub fn tint(mut self, tint: impl Into<Color32>) -> Self {
|
|
self.image = self.image.tint(tint);
|
|
self
|
|
}
|
|
|
|
/// If `true`, mark this button as "selected".
|
|
#[inline]
|
|
pub fn selected(mut self, selected: bool) -> Self {
|
|
self.selected = selected;
|
|
self
|
|
}
|
|
|
|
/// Turn off the frame
|
|
#[inline]
|
|
pub fn frame(mut self, frame: bool) -> Self {
|
|
self.frame = frame;
|
|
self
|
|
}
|
|
|
|
/// By default, buttons senses clicks.
|
|
/// Change this to a drag-button with `Sense::drag()`.
|
|
#[inline]
|
|
pub fn sense(mut self, sense: Sense) -> Self {
|
|
self.sense = sense;
|
|
self
|
|
}
|
|
|
|
/// Set rounding for the `ImageButton`.
|
|
///
|
|
/// If the underlying image already has rounding, this
|
|
/// will override that value.
|
|
#[inline]
|
|
pub fn corner_radius(mut self, corner_radius: impl Into<CornerRadius>) -> Self {
|
|
self.image = self.image.corner_radius(corner_radius.into());
|
|
self
|
|
}
|
|
|
|
/// Set rounding for the `ImageButton`.
|
|
///
|
|
/// If the underlying image already has rounding, this
|
|
/// will override that value.
|
|
#[inline]
|
|
#[deprecated = "Renamed to `corner_radius`"]
|
|
pub fn rounding(self, corner_radius: impl Into<CornerRadius>) -> Self {
|
|
self.corner_radius(corner_radius)
|
|
}
|
|
}
|
|
|
|
#[expect(deprecated, reason = "Deprecated in egui 0.33.0")]
|
|
impl Widget for ImageButton<'_> {
|
|
fn ui(self, ui: &mut Ui) -> Response {
|
|
let padding = if self.frame {
|
|
// so we can see that it is a button:
|
|
Vec2::splat(ui.spacing().button_padding.x)
|
|
} else {
|
|
Vec2::ZERO
|
|
};
|
|
|
|
let available_size_for_image = ui.available_size() - 2.0 * padding;
|
|
let tlr = self.image.load_for_size(ui.ctx(), available_size_for_image);
|
|
let image_source_size = tlr.as_ref().ok().and_then(|t| t.size());
|
|
let image_size = self
|
|
.image
|
|
.calc_size(available_size_for_image, image_source_size);
|
|
|
|
let padded_size = image_size + 2.0 * padding;
|
|
let (rect, response) = ui.allocate_exact_size(padded_size, self.sense);
|
|
response.widget_info(|| {
|
|
let mut info = WidgetInfo::new(WidgetType::Button);
|
|
info.label = self.alt_text.clone();
|
|
info
|
|
});
|
|
|
|
if ui.is_rect_visible(rect) {
|
|
let (expansion, rounding, fill, stroke) = if self.selected {
|
|
let selection = ui.visuals().selection;
|
|
(
|
|
Vec2::ZERO,
|
|
self.image.image_options().corner_radius,
|
|
selection.bg_fill,
|
|
selection.stroke,
|
|
)
|
|
} else if self.frame {
|
|
let visuals = ui.style().interact(&response);
|
|
let expansion = Vec2::splat(visuals.expansion);
|
|
(
|
|
expansion,
|
|
self.image.image_options().corner_radius,
|
|
visuals.weak_bg_fill,
|
|
visuals.bg_stroke,
|
|
)
|
|
} else {
|
|
Default::default()
|
|
};
|
|
|
|
// Draw frame background (for transparent images):
|
|
ui.painter()
|
|
.rect_filled(rect.expand2(expansion), rounding, fill);
|
|
|
|
let image_rect = ui
|
|
.layout()
|
|
.align_size_within_rect(image_size, rect.shrink2(padding));
|
|
// let image_rect = image_rect.expand2(expansion); // can make it blurry, so let's not
|
|
let image_options = self.image.image_options().clone();
|
|
|
|
widgets::image::paint_texture_load_result(
|
|
ui,
|
|
&tlr,
|
|
image_rect,
|
|
None,
|
|
&image_options,
|
|
self.alt_text.as_deref(),
|
|
);
|
|
|
|
// Draw frame outline:
|
|
ui.painter().rect_stroke(
|
|
rect.expand2(expansion),
|
|
rounding,
|
|
stroke,
|
|
epaint::StrokeKind::Inside,
|
|
);
|
|
}
|
|
|
|
widgets::image::texture_load_result_response(&self.image.source(ui.ctx()), &tlr, response)
|
|
}
|
|
}
|