1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-26 22:53:14 -04:00

checkbox & cleanup

This commit is contained in:
Adrien Zianne
2025-10-21 10:42:42 +02:00
parent 1e346da874
commit b18070caef
7 changed files with 50 additions and 153 deletions

View File

@@ -1,4 +1,3 @@
use emath::Vec2;
use epaint::{Color32, FontId, Shadow, Stroke, text::TextWrapMode};
use crate::{
@@ -36,9 +35,9 @@ pub struct CheckboxStyle {
pub frame: Frame,
/// Text next to it
pub text: TextVisuals,
/// Box size
/// Checkbox size
pub size: f32,
/// Check size
/// Checkmark size
pub check_size: f32,
/// Frame of the checkbox itself
pub checkbox_frame: Frame,
@@ -46,30 +45,6 @@ pub struct CheckboxStyle {
pub stroke: Stroke,
}
pub struct DragValueStyle {
/// Frame around
pub frame: Frame,
/// Text of the value
pub text: TextVisuals,
pub min_size: Vec2,
}
pub struct HyperlinkStyle {
pub frame: Frame,
pub text: TextVisuals,
pub size: Vec2,
pub checkbox_frame: Frame,
pub stroke: Stroke,
}
pub struct ImageStyle {
pub frame: Frame,
pub text: TextVisuals,
pub size: Vec2,
pub checkbox_frame: Frame,
pub stroke: Stroke,
}
pub struct LabelStyle {
/// Frame around
pub frame: Frame,
@@ -79,32 +54,10 @@ pub struct LabelStyle {
pub wrap_mode: TextWrapMode,
}
pub struct RadioButtonStyle {
pub frame: Frame,
pub text: TextVisuals,
pub size: Vec2,
pub checkbox_frame: Frame,
pub stroke: Stroke,
}
pub struct SeparatorStyle {
pub size: f32,
pub stroke: Stroke,
}
pub struct SliderStyle {
pub frame: Frame,
pub text: TextVisuals,
pub size: Vec2,
pub checkbox_frame: Frame,
pub stroke: Stroke,
}
pub struct SpinnerStyle {
pub frame: Frame,
pub text: TextVisuals,
pub size: Vec2,
pub checkbox_frame: Frame,
/// How much space is allocated in the layout direction
pub spacing: f32,
/// How to paint it
pub stroke: Stroke,
}
@@ -206,22 +159,11 @@ impl Style {
}
}
pub fn drag_value_style(&self, state: WidgetState) -> DragValueStyle {
let ws = self.widget_style(state);
DragValueStyle {
frame: ws.frame.inner_margin(self.spacing.button_padding),
min_size: self.spacing.interact_size,
text: ws.text,
pub fn separator_style(&self, state: WidgetState) -> SeparatorStyle {
let visuals = self.visuals.widgets.state(state);
SeparatorStyle {
spacing: 0.0,
stroke: visuals.fg_stroke,
}
}
// pub fn hyperlink_style(&self, state: WidgetState) -> HyperlinkStyle {}
// pub fn image_style(&self, state: WidgetState) -> ImageStyle {}
// pub fn slider_style(&self, state: WidgetState) -> SliderStyle {}
// pub fn separator_style(&self, state: WidgetState) -> SeparatorStyle {}
// pub fn spinner_style(&self, state: WidgetState) -> SpinnerStyle {}
}

View File

@@ -284,7 +284,7 @@ impl<'a> Button<'a> {
let text = layout.text().map(String::from);
// Get the widget style by reading the rect from the previous pass
// Get the widget style by reading the response from the previous pass
let id = ui.next_auto_id();
let response: Option<Response> = ui.ctx().read_response(id);
let state = response.map(|r| r.widget_state()).unwrap_or_default();

View File

@@ -1,3 +1,5 @@
use emath::Rect;
use crate::{
Atom, AtomLayout, Atoms, Id, IntoAtoms, NumExt as _, Response, Sense, Shape, Ui, Vec2, Widget,
WidgetInfo, WidgetType, epaint, pos2,
@@ -55,7 +57,7 @@ impl Widget for Checkbox<'_> {
indeterminate,
} = self;
// Get the widget style by reading the rect from the previous pass
// Get the widget style by reading the response from the previous pass
let id = ui.next_auto_id();
let response: Option<Response> = ui.ctx().read_response(id);
let state = response.map(|r| r.widget_state()).unwrap_or_default();
@@ -109,7 +111,13 @@ impl Widget for Checkbox<'_> {
let response = prepared.paint(ui);
if let Some(rect) = response.rect(rect_id) {
let (small_icon_rect, big_icon_rect) = ui.spacing().icon_rectangles(rect);
let big_icon_rect = Rect::from_center_size(
pos2(rect.left() + icon_width / 2.0, rect.center().y),
Vec2::splat(style.size),
);
let small_icon_rect =
Rect::from_center_size(big_icon_rect.center(), Vec2::splat(style.check_size));
ui.painter().add(epaint::RectShape::new(
big_icon_rect,
style.checkbox_frame.corner_radius,

View File

@@ -4,7 +4,7 @@ use std::{cmp::Ordering, ops::RangeInclusive};
use crate::{
Button, CursorIcon, Id, Key, MINUS_CHAR_STR, Modifiers, NumExt as _, Response, RichText, Sense,
TextEdit, TextWrapMode, Ui, Widget, WidgetInfo, emath, grid::State, text,
TextEdit, TextWrapMode, Ui, Widget, WidgetInfo, emath, text,
};
// ----------------------------------------------------------------------------
@@ -447,10 +447,6 @@ impl Widget for DragValue<'_> {
let id = ui.next_auto_id();
let is_slow_speed = shift && ui.ctx().is_being_dragged(id);
let response = ui.ctx().read_response(id);
let state = response.map(|r| r.widget_state()).unwrap_or_default();
let style = ui.style().drag_value_style(state);
// The following ensures that when a `DragValue` receives focus,
// it is immediately rendered in edit mode, rather than being rendered
// in button mode for just one frame. This is important for
@@ -564,14 +560,13 @@ impl Widget for DragValue<'_> {
.clip_text(false)
.horizontal_align(ui.layout().horizontal_align())
.vertical_align(ui.layout().vertical_align())
.margin(style.frame.inner_margin)
.min_size(style.min_size)
.margin(ui.spacing().button_padding)
.min_size(ui.spacing().interact_size)
.id(id)
.desired_width(
ui.spacing().interact_size.x - 2.0 * ui.spacing().button_padding.x,
)
.text_color(style.text.color)
.font(style.text.font_id),
.font(text_style),
);
// Select all text when the edit gains focus.

View File

@@ -179,7 +179,7 @@ impl Label {
return (pos, galley, response);
}
// Get the widget style by reading the rect from the previous pass
// Get the widget style by reading the response from the previous pass
let id = ui.next_auto_id();
let response: Option<Response> = ui.ctx().read_response(id);
let state = response.map(|r| r.widget_state()).unwrap_or_default();
@@ -280,10 +280,6 @@ impl Widget for Label {
let selectable = self.selectable;
let show_tooltip_when_elided = self.show_tooltip_when_elided;
// Get the widget style by reading the rect from the previous pass
// let id = ui.next_auto_id();
// let response: Option<Response> = ui.ctx().read_response(id);
let (galley_pos, galley, mut response) = self.layout_in_ui(ui);
response
.widget_info(|| WidgetInfo::labeled(WidgetType::Label, ui.is_enabled(), galley.text()));
@@ -309,11 +305,6 @@ impl Widget for Label {
ui.style().visuals.text_color()
};
// let underline = if response.has_focus() || response.highlighted() {
// Stroke::new(1.0, response_color)
// } else {
// Stroke::NONE
// };
let underline = style.text.underline;
let selectable = selectable.unwrap_or_else(|| ui.style().interaction.selectable_labels);

View File

@@ -88,11 +88,22 @@ impl Separator {
impl Widget for Separator {
fn ui(self, ui: &mut Ui) -> Response {
let Self {
spacing,
mut spacing,
grow,
is_horizontal_line,
} = self;
// Get the widget style by reading the response from the previous pass
let id = ui.next_auto_id();
let response: Option<Response> = ui.ctx().read_response(id);
let state = response.map(|r| r.widget_state()).unwrap_or_default();
let style = ui.style().separator_style(state);
// override the spacing if not set
if spacing == 0.0 && style.spacing != 0.0 {
spacing = style.spacing;
}
let is_horizontal_line = is_horizontal_line
.unwrap_or_else(|| ui.is_grid() || !ui.layout().main_dir().is_horizontal());
@@ -111,7 +122,7 @@ impl Widget for Separator {
let (rect, response) = ui.allocate_at_least(size, Sense::hover());
if ui.is_rect_visible(response.rect) {
let stroke = ui.visuals().widgets.noninteractive.bg_stroke;
let stroke = style.stroke;
let painter = ui.painter();
if is_horizontal_line {
painter.hline(

View File

@@ -1,10 +1,7 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
#![allow(rustdoc::missing_crate_level_docs)] // it's an example
use eframe::egui::{
self, Atom, Checkbox, Color32, FontId, Label, RichText, Sense, Stroke, style::WidgetVisuals,
vec2,
};
use eframe::egui;
fn main() -> eframe::Result {
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
@@ -17,67 +14,20 @@ fn main() -> eframe::Result {
// Our application state:
let mut name = "Arthur".to_owned();
let mut age = 42;
let mut is_adult = age >= 18;
eframe::run_simple_native("My egui App", options, move |ctx, _frame| {
egui::CentralPanel::default().show(ctx, |ui| {
ui.ctx().style_mut(|s| {
s.spacing.icon_width_inner = 8.0;
s.spacing.icon_width = 15.0;
s.spacing.button_padding = vec2(5.0, 5.0);
// s.spacing.interact_size.y = 30.0;
s.visuals.widgets.inactive = WidgetVisuals {
fg_stroke: Stroke::new(1.0, Color32::LIGHT_GRAY),
bg_stroke: Stroke::new(1.0, Color32::LIGHT_GRAY),
..s.visuals.widgets.inactive
};
s.visuals.widgets.active = WidgetVisuals {
fg_stroke: Stroke::new(1.0, Color32::LIGHT_BLUE),
..s.visuals.widgets.inactive
};
s.visuals.widgets.hovered = WidgetVisuals {
fg_stroke: Stroke::new(3.0, Color32::LIGHT_YELLOW),
..s.visuals.widgets.inactive
};
s.visuals.widgets.noninteractive = WidgetVisuals {
fg_stroke: Stroke::new(1.0, Color32::RED),
..s.visuals.widgets.inactive
};
ui.heading("My egui Application");
ui.horizontal(|ui| {
let name_label = ui.label("Your name: ");
ui.text_edit_singleline(&mut name)
.labelled_by(name_label.id);
});
// ui.heading("My egui Application");
// ui.horizontal(|ui| {
// let name_label = ui.label("Your name: ");
// ui.text_edit_singleline(&mut name)
// .labelled_by(name_label.id);
// });
// ui.add(egui::Slider::new(&mut age, 0..=120).text("age"));
// if ui.button("Increment").clicked() {
// age += 1;
// }
// Button test
// ui.add(Button::new("no frame").frame(false));
// ui.add(Button::new("small").small());
// ui.add_enabled(false, Button::new("disabled"));
// ui.add(Button::new("no frame inactive").frame_when_inactive(false));
// ui.label("Normal text");
// // Should not be affected by WidgetStyle
// ui.label(
// RichText::new("Unaffected by style")
// .font(FontId::monospace(15.0))
// .color(Color32::KHAKI),
// );
// ui.add(Label::new("interaction click").sense(Sense::click()));
// ui.add(Label::new("focusable").sense(Sense::focusable_noninteractive()))
// .request_focus();
ui.add(Checkbox::new(&mut is_adult, "test"));
ui.add(Checkbox::new(&mut is_adult, "test"));
ui.add(Checkbox::new(&mut is_adult, Atom::default()));
ui.add(Checkbox::new(&mut is_adult, Atom::default()).indeterminate(true));
ui.add(egui::Slider::new(&mut age, 0..=120).text("age"));
if ui.button("Increment").clicked() {
age += 1;
}
ui.label(format!("Hello '{name}', age {age}"));
});
})
}