Style tweaks (#450)
* Tweak style More compact, less round, less noisy * Button text is now same size as body text * The rounder corners are now less rounded * Collapsing headers no longer have a frame around them * Combo-boxes looks better when opened * Slightly more muted colors * Remove extra line spacing after `\n` (i.e. between paragraphs) * Thinner scrollbars * Tweak light mode * Tweak shadows * Fix broken doc link * Add style tweak to CHANGELOG
This commit is contained in:
parent
a50ddc2703
commit
778bcc1ef7
18 changed files with 365 additions and 166 deletions
|
@ -24,6 +24,7 @@ NOTE: [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md) and [
|
||||||
* Add `ScrollArea::enable_scrolling` to allow freezing scrolling when editing TextEdit widgets within it
|
* Add `ScrollArea::enable_scrolling` to allow freezing scrolling when editing TextEdit widgets within it
|
||||||
|
|
||||||
### Changed 🔧
|
### Changed 🔧
|
||||||
|
* [Tweaked the default visuals style](https://github.com/emilk/egui/pull/450).
|
||||||
* Plot: Changed `Curve` to `Line`.
|
* Plot: Changed `Curve` to `Line`.
|
||||||
* `TopPanel::top` is now `TopBottomPanel::top`.
|
* `TopPanel::top` is now `TopBottomPanel::top`.
|
||||||
* `SidePanel::left` no longet takes the default width by argument, but by a builder call.
|
* `SidePanel::left` no longet takes the default width by argument, but by a builder call.
|
||||||
|
|
|
@ -246,13 +246,16 @@ impl CollapsingHeader {
|
||||||
|
|
||||||
let visuals = ui.style().interact(&header_response);
|
let visuals = ui.style().interact(&header_response);
|
||||||
let text_color = visuals.text_color();
|
let text_color = visuals.text_color();
|
||||||
ui.painter().add(Shape::Rect {
|
|
||||||
rect: header_response.rect.expand(visuals.expansion),
|
if ui.visuals().collapsing_header_frame {
|
||||||
corner_radius: visuals.corner_radius,
|
ui.painter().add(Shape::Rect {
|
||||||
fill: visuals.bg_fill,
|
rect: header_response.rect.expand(visuals.expansion),
|
||||||
stroke: visuals.bg_stroke,
|
corner_radius: visuals.corner_radius,
|
||||||
// stroke: Default::default(),
|
fill: visuals.bg_fill,
|
||||||
});
|
stroke: visuals.bg_stroke,
|
||||||
|
// stroke: Default::default(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let (mut icon_rect, _) = ui.spacing().icon_rectangles(header_response.rect);
|
let (mut icon_rect, _) = ui.spacing().icon_rectangles(header_response.rect);
|
||||||
|
|
|
@ -176,8 +176,8 @@ fn combo_box(
|
||||||
) -> Response {
|
) -> Response {
|
||||||
let popup_id = button_id.with("popup");
|
let popup_id = button_id.with("popup");
|
||||||
|
|
||||||
let button_active = ui.memory().is_popup_open(popup_id);
|
let is_popup_open = ui.memory().is_popup_open(popup_id);
|
||||||
let button_response = button_frame(ui, button_id, button_active, Sense::click(), |ui| {
|
let button_response = button_frame(ui, button_id, is_popup_open, Sense::click(), |ui| {
|
||||||
// We don't want to change width when user selects something new
|
// We don't want to change width when user selects something new
|
||||||
let full_minimum_width = ui.spacing().slider_width;
|
let full_minimum_width = ui.spacing().slider_width;
|
||||||
let icon_size = Vec2::splat(ui.spacing().icon_width);
|
let icon_size = Vec2::splat(ui.spacing().icon_width);
|
||||||
|
@ -193,10 +193,14 @@ fn combo_box(
|
||||||
let (_, rect) = ui.allocate_space(Vec2::new(width, height));
|
let (_, rect) = ui.allocate_space(Vec2::new(width, height));
|
||||||
let button_rect = ui.min_rect().expand2(ui.spacing().button_padding);
|
let button_rect = ui.min_rect().expand2(ui.spacing().button_padding);
|
||||||
let response = ui.interact(button_rect, button_id, Sense::click());
|
let response = ui.interact(button_rect, button_id, Sense::click());
|
||||||
// response.active |= button_active;
|
// response.active |= is_popup_open;
|
||||||
|
|
||||||
let icon_rect = Align2::RIGHT_CENTER.align_size_within_rect(icon_size, rect);
|
let icon_rect = Align2::RIGHT_CENTER.align_size_within_rect(icon_size, rect);
|
||||||
let visuals = ui.style().interact(&response);
|
let visuals = if is_popup_open {
|
||||||
|
&ui.visuals().widgets.open
|
||||||
|
} else {
|
||||||
|
ui.style().interact(&response)
|
||||||
|
};
|
||||||
paint_icon(ui.painter(), icon_rect.expand(visuals.expansion), visuals);
|
paint_icon(ui.painter(), icon_rect.expand(visuals.expansion), visuals);
|
||||||
|
|
||||||
let text_rect = Align2::LEFT_CENTER.align_size_within_rect(galley.size, rect);
|
let text_rect = Align2::LEFT_CENTER.align_size_within_rect(galley.size, rect);
|
||||||
|
@ -207,9 +211,8 @@ fn combo_box(
|
||||||
if button_response.clicked() {
|
if button_response.clicked() {
|
||||||
ui.memory().toggle_popup(popup_id);
|
ui.memory().toggle_popup(popup_id);
|
||||||
}
|
}
|
||||||
const MAX_COMBO_HEIGHT: f32 = 128.0;
|
|
||||||
crate::popup::popup_below_widget(ui, popup_id, &button_response, |ui| {
|
crate::popup::popup_below_widget(ui, popup_id, &button_response, |ui| {
|
||||||
ScrollArea::from_max_height(MAX_COMBO_HEIGHT).show(ui, menu_contents)
|
ScrollArea::from_max_height(ui.spacing().combo_height).show(ui, menu_contents)
|
||||||
});
|
});
|
||||||
|
|
||||||
button_response
|
button_response
|
||||||
|
@ -218,7 +221,7 @@ fn combo_box(
|
||||||
fn button_frame(
|
fn button_frame(
|
||||||
ui: &mut Ui,
|
ui: &mut Ui,
|
||||||
id: Id,
|
id: Id,
|
||||||
button_active: bool,
|
is_popup_open: bool,
|
||||||
sense: Sense,
|
sense: Sense,
|
||||||
add_contents: impl FnOnce(&mut Ui),
|
add_contents: impl FnOnce(&mut Ui),
|
||||||
) -> Response {
|
) -> Response {
|
||||||
|
@ -237,9 +240,12 @@ fn button_frame(
|
||||||
let mut outer_rect = content_ui.min_rect().expand2(margin);
|
let mut outer_rect = content_ui.min_rect().expand2(margin);
|
||||||
outer_rect.set_height(outer_rect.height().at_least(interact_size.y));
|
outer_rect.set_height(outer_rect.height().at_least(interact_size.y));
|
||||||
|
|
||||||
let mut response = ui.interact(outer_rect, id, sense);
|
let response = ui.interact(outer_rect, id, sense);
|
||||||
response.is_pointer_button_down_on |= button_active;
|
let visuals = if is_popup_open {
|
||||||
let visuals = ui.style().interact(&response);
|
&ui.visuals().widgets.open
|
||||||
|
} else {
|
||||||
|
ui.style().interact(&response)
|
||||||
|
};
|
||||||
|
|
||||||
ui.painter().set(
|
ui.painter().set(
|
||||||
where_to_put_background,
|
where_to_put_background,
|
||||||
|
|
|
@ -24,8 +24,8 @@ impl Frame {
|
||||||
pub fn group(style: &Style) -> Self {
|
pub fn group(style: &Style) -> Self {
|
||||||
Self {
|
Self {
|
||||||
margin: Vec2::new(8.0, 6.0),
|
margin: Vec2::new(8.0, 6.0),
|
||||||
corner_radius: 4.0,
|
corner_radius: style.visuals.widgets.noninteractive.corner_radius,
|
||||||
stroke: style.visuals.window_stroke(),
|
stroke: style.visuals.widgets.noninteractive.bg_stroke,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,8 @@ impl Frame {
|
||||||
pub fn menu(style: &Style) -> Self {
|
pub fn menu(style: &Style) -> Self {
|
||||||
Self {
|
Self {
|
||||||
margin: Vec2::splat(1.0),
|
margin: Vec2::splat(1.0),
|
||||||
corner_radius: 2.0,
|
corner_radius: style.visuals.widgets.noninteractive.corner_radius,
|
||||||
shadow: Shadow::small(),
|
shadow: style.visuals.popup_shadow,
|
||||||
fill: style.visuals.window_fill(),
|
fill: style.visuals.window_fill(),
|
||||||
stroke: style.visuals.window_stroke(),
|
stroke: style.visuals.window_stroke(),
|
||||||
}
|
}
|
||||||
|
@ -73,8 +73,8 @@ impl Frame {
|
||||||
pub fn popup(style: &Style) -> Self {
|
pub fn popup(style: &Style) -> Self {
|
||||||
Self {
|
Self {
|
||||||
margin: style.spacing.window_padding,
|
margin: style.spacing.window_padding,
|
||||||
corner_radius: 5.0,
|
corner_radius: style.visuals.widgets.noninteractive.corner_radius,
|
||||||
shadow: Shadow::small(),
|
shadow: style.visuals.popup_shadow,
|
||||||
fill: style.visuals.window_fill(),
|
fill: style.visuals.window_fill(),
|
||||||
stroke: style.visuals.window_stroke(),
|
stroke: style.visuals.window_stroke(),
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ impl Frame {
|
||||||
pub fn dark_canvas(style: &Style) -> Self {
|
pub fn dark_canvas(style: &Style) -> Self {
|
||||||
Self {
|
Self {
|
||||||
margin: Vec2::new(10.0, 10.0),
|
margin: Vec2::new(10.0, 10.0),
|
||||||
corner_radius: 5.0,
|
corner_radius: style.visuals.widgets.noninteractive.corner_radius,
|
||||||
fill: Color32::from_black_alpha(250),
|
fill: Color32::from_black_alpha(250),
|
||||||
stroke: style.visuals.window_stroke(),
|
stroke: style.visuals.window_stroke(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -357,7 +357,6 @@ impl Prepared {
|
||||||
let margin = animation_t * ui.spacing().item_spacing.x;
|
let margin = animation_t * ui.spacing().item_spacing.x;
|
||||||
let left = inner_rect.right() + margin;
|
let left = inner_rect.right() + margin;
|
||||||
let right = outer_rect.right();
|
let right = outer_rect.right();
|
||||||
let corner_radius = (right - left) / 2.0;
|
|
||||||
let top = inner_rect.top();
|
let top = inner_rect.top();
|
||||||
let bottom = inner_rect.bottom();
|
let bottom = inner_rect.bottom();
|
||||||
|
|
||||||
|
@ -415,7 +414,7 @@ impl Prepared {
|
||||||
pos2(left, from_content(state.offset.y)),
|
pos2(left, from_content(state.offset.y)),
|
||||||
pos2(right, from_content(state.offset.y + inner_rect.height())),
|
pos2(right, from_content(state.offset.y + inner_rect.height())),
|
||||||
);
|
);
|
||||||
let min_handle_height = (2.0 * corner_radius).max(8.0);
|
let min_handle_height = ui.spacing().scroll_bar_width;
|
||||||
if handle_rect.size().y < min_handle_height {
|
if handle_rect.size().y < min_handle_height {
|
||||||
handle_rect = Rect::from_center_size(
|
handle_rect = Rect::from_center_size(
|
||||||
handle_rect.center(),
|
handle_rect.center(),
|
||||||
|
@ -429,21 +428,17 @@ impl Prepared {
|
||||||
&ui.style().visuals.widgets.inactive
|
&ui.style().visuals.widgets.inactive
|
||||||
};
|
};
|
||||||
|
|
||||||
ui.painter().add(epaint::Shape::Rect {
|
ui.painter().add(epaint::Shape::rect_filled(
|
||||||
rect: outer_scroll_rect,
|
outer_scroll_rect,
|
||||||
corner_radius,
|
visuals.corner_radius,
|
||||||
fill: ui.visuals().extreme_bg_color,
|
ui.visuals().extreme_bg_color,
|
||||||
stroke: Default::default(),
|
));
|
||||||
// fill: visuals.bg_fill,
|
|
||||||
// stroke: visuals.bg_stroke,
|
|
||||||
});
|
|
||||||
|
|
||||||
ui.painter().add(epaint::Shape::Rect {
|
ui.painter().add(epaint::Shape::rect_filled(
|
||||||
rect: handle_rect.expand(-2.0),
|
handle_rect,
|
||||||
corner_radius,
|
visuals.corner_radius,
|
||||||
fill: visuals.bg_fill,
|
visuals.bg_fill,
|
||||||
stroke: visuals.bg_stroke,
|
));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let size = vec2(
|
let size = vec2(
|
||||||
|
@ -465,5 +460,5 @@ impl Prepared {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max_scroll_bar_width_with_margin(ui: &Ui) -> f32 {
|
fn max_scroll_bar_width_with_margin(ui: &Ui) -> f32 {
|
||||||
ui.spacing().item_spacing.x + 16.0
|
ui.spacing().item_spacing.x + ui.spacing().scroll_bar_width
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,12 +198,7 @@ impl GridLayout {
|
||||||
let rect = rect.expand2(0.5 * self.spacing.y * Vec2::Y);
|
let rect = rect.expand2(0.5 * self.spacing.y * Vec2::Y);
|
||||||
let rect = rect.expand2(2.0 * Vec2::X); // HACK: just looks better with some spacing on the sides
|
let rect = rect.expand2(2.0 * Vec2::X); // HACK: just looks better with some spacing on the sides
|
||||||
|
|
||||||
let color = if self.style.visuals.dark_mode {
|
painter.rect_filled(rect, 2.0, self.style.visuals.faint_bg_color);
|
||||||
Rgba::from_white_alpha(0.0075)
|
|
||||||
} else {
|
|
||||||
Rgba::from_black_alpha(0.075)
|
|
||||||
};
|
|
||||||
painter.rect_filled(rect, 2.0, color);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,14 +132,17 @@ impl Widget for &mut epaint::TessellationOptions {
|
||||||
debug_paint_text_rects,
|
debug_paint_text_rects,
|
||||||
debug_ignore_clip_rects,
|
debug_ignore_clip_rects,
|
||||||
} = self;
|
} = self;
|
||||||
ui.checkbox(anti_alias, "Antialias");
|
ui.checkbox(anti_alias, "Antialias")
|
||||||
ui.checkbox(
|
.on_hover_text("Turn off for small performance gain.");
|
||||||
coarse_tessellation_culling,
|
ui.collapsing("debug", |ui| {
|
||||||
"Do coarse culling in the tessellator",
|
ui.checkbox(
|
||||||
);
|
coarse_tessellation_culling,
|
||||||
ui.checkbox(debug_ignore_clip_rects, "Ignore clip rectangles (debug)");
|
"Do coarse culling in the tessellator)",
|
||||||
ui.checkbox(debug_paint_clip_rects, "Paint clip rectangles (debug)");
|
);
|
||||||
ui.checkbox(debug_paint_text_rects, "Paint text bounds (debug)");
|
ui.checkbox(debug_ignore_clip_rects, "Ignore clip rectangles");
|
||||||
|
ui.checkbox(debug_paint_clip_rects, "Paint clip rectangles");
|
||||||
|
ui.checkbox(debug_paint_text_rects, "Paint text bounds");
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.response
|
.response
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,8 @@ fn menu_impl<'c>(ui: &mut Ui, title: impl ToString, add_contents: Box<dyn FnOnce
|
||||||
let mut button = Button::new(title);
|
let mut button = Button::new(title);
|
||||||
|
|
||||||
if bar_state.open_menu == Some(menu_id) {
|
if bar_state.open_menu == Some(menu_id) {
|
||||||
button = button.fill(Some(ui.visuals().selection.bg_fill));
|
button = button.fill(ui.visuals().widgets.open.bg_fill);
|
||||||
|
button = button.stroke(ui.visuals().widgets.open.bg_stroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
let button_response = ui.add(button);
|
let button_response = ui.add(button);
|
||||||
|
|
|
@ -117,6 +117,14 @@ pub struct Spacing {
|
||||||
|
|
||||||
/// Width of a tooltip (`on_hover_ui`, `on_hover_text` etc).
|
/// Width of a tooltip (`on_hover_ui`, `on_hover_text` etc).
|
||||||
pub tooltip_width: f32,
|
pub tooltip_width: f32,
|
||||||
|
|
||||||
|
/// End indented regions with a horizontal line
|
||||||
|
pub indent_ends_with_horizontal_line: bool,
|
||||||
|
|
||||||
|
/// Height of a combo-box before showing scroll bars.
|
||||||
|
pub combo_height: f32,
|
||||||
|
|
||||||
|
pub scroll_bar_width: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Spacing {
|
impl Spacing {
|
||||||
|
@ -188,20 +196,26 @@ pub struct Visuals {
|
||||||
|
|
||||||
pub selection: Selection,
|
pub selection: Selection,
|
||||||
|
|
||||||
|
/// The color used for `Hyperlink`,
|
||||||
|
pub hyperlink_color: Color32,
|
||||||
|
|
||||||
|
/// Something just barely different from the background color.
|
||||||
|
/// Used for [`crate::Grid::striped`].
|
||||||
|
pub faint_bg_color: Color32,
|
||||||
|
|
||||||
/// Very dark or light color (for corresponding theme).
|
/// Very dark or light color (for corresponding theme).
|
||||||
/// Used as the background of text edits, scroll bars and others things
|
/// Used as the background of text edits, scroll bars and others things
|
||||||
/// that needs to look different from other interactive stuff.
|
/// that needs to look different from other interactive stuff.
|
||||||
pub extreme_bg_color: Color32,
|
pub extreme_bg_color: Color32,
|
||||||
|
|
||||||
/// The color used for `Hyperlink`,
|
|
||||||
pub hyperlink_color: Color32,
|
|
||||||
|
|
||||||
/// Background color behind code-styled monospaced labels.
|
/// Background color behind code-styled monospaced labels.
|
||||||
pub code_bg_color: Color32,
|
pub code_bg_color: Color32,
|
||||||
|
|
||||||
pub window_corner_radius: f32,
|
pub window_corner_radius: f32,
|
||||||
pub window_shadow: Shadow,
|
pub window_shadow: Shadow,
|
||||||
|
|
||||||
|
pub popup_shadow: Shadow,
|
||||||
|
|
||||||
pub resize_corner_size: f32,
|
pub resize_corner_size: f32,
|
||||||
|
|
||||||
pub text_cursor_width: f32,
|
pub text_cursor_width: f32,
|
||||||
|
@ -210,6 +224,12 @@ pub struct Visuals {
|
||||||
|
|
||||||
/// Allow child widgets to be just on the border and still have a stroke with some thickness
|
/// Allow child widgets to be just on the border and still have a stroke with some thickness
|
||||||
pub clip_rect_margin: f32,
|
pub clip_rect_margin: f32,
|
||||||
|
|
||||||
|
/// Show a background behind buttons.
|
||||||
|
pub button_frame: bool,
|
||||||
|
|
||||||
|
/// Show a background behind collapsing headers.
|
||||||
|
pub collapsing_header_frame: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visuals {
|
impl Visuals {
|
||||||
|
@ -264,6 +284,8 @@ pub struct Widgets {
|
||||||
pub hovered: WidgetVisuals,
|
pub hovered: WidgetVisuals,
|
||||||
/// The style of an interactive widget as you are clicking or dragging it.
|
/// The style of an interactive widget as you are clicking or dragging it.
|
||||||
pub active: WidgetVisuals,
|
pub active: WidgetVisuals,
|
||||||
|
/// The style of a button that has an open menu beneath it (e.g. a combo-box)
|
||||||
|
pub open: WidgetVisuals,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widgets {
|
impl Widgets {
|
||||||
|
@ -344,13 +366,16 @@ impl Default for Spacing {
|
||||||
item_spacing: vec2(8.0, 3.0),
|
item_spacing: vec2(8.0, 3.0),
|
||||||
window_padding: Vec2::splat(6.0),
|
window_padding: Vec2::splat(6.0),
|
||||||
button_padding: vec2(4.0, 1.0),
|
button_padding: vec2(4.0, 1.0),
|
||||||
indent: 25.0,
|
indent: 18.0, // match checkbox/radio-button with `button_padding.x + icon_width + icon_spacing`
|
||||||
interact_size: vec2(40.0, 20.0),
|
interact_size: vec2(40.0, 18.0),
|
||||||
slider_width: 100.0,
|
slider_width: 100.0,
|
||||||
text_edit_width: 280.0,
|
text_edit_width: 280.0,
|
||||||
icon_width: 16.0,
|
icon_width: 14.0,
|
||||||
icon_spacing: 0.0,
|
icon_spacing: 0.0,
|
||||||
tooltip_width: 600.0,
|
tooltip_width: 600.0,
|
||||||
|
combo_height: 200.0,
|
||||||
|
scroll_bar_width: 8.0,
|
||||||
|
indent_ends_with_horizontal_line: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,15 +398,19 @@ impl Visuals {
|
||||||
override_text_color: None,
|
override_text_color: None,
|
||||||
widgets: Widgets::default(),
|
widgets: Widgets::default(),
|
||||||
selection: Selection::default(),
|
selection: Selection::default(),
|
||||||
extreme_bg_color: Color32::from_gray(10),
|
|
||||||
hyperlink_color: Color32::from_rgb(90, 170, 255),
|
hyperlink_color: Color32::from_rgb(90, 170, 255),
|
||||||
|
faint_bg_color: Color32::from_gray(24),
|
||||||
|
extreme_bg_color: Color32::from_gray(10),
|
||||||
code_bg_color: Color32::from_gray(64),
|
code_bg_color: Color32::from_gray(64),
|
||||||
window_corner_radius: 10.0,
|
window_corner_radius: 6.0,
|
||||||
window_shadow: Shadow::big_dark(),
|
window_shadow: Shadow::big_dark(),
|
||||||
|
popup_shadow: Shadow::small_dark(),
|
||||||
resize_corner_size: 12.0,
|
resize_corner_size: 12.0,
|
||||||
text_cursor_width: 2.0,
|
text_cursor_width: 2.0,
|
||||||
text_cursor_preview: false,
|
text_cursor_preview: false,
|
||||||
clip_rect_margin: 3.0, // should be at least half the size of the widest frame stroke + max WidgetVisuals::expansion
|
clip_rect_margin: 3.0, // should be at least half the size of the widest frame stroke + max WidgetVisuals::expansion
|
||||||
|
button_frame: true,
|
||||||
|
collapsing_header_frame: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,10 +420,12 @@ impl Visuals {
|
||||||
dark_mode: false,
|
dark_mode: false,
|
||||||
widgets: Widgets::light(),
|
widgets: Widgets::light(),
|
||||||
selection: Selection::light(),
|
selection: Selection::light(),
|
||||||
extreme_bg_color: Color32::from_gray(235), // TODO: rename
|
hyperlink_color: Color32::from_rgb(0, 155, 255),
|
||||||
hyperlink_color: Color32::from_rgb(0, 133, 218),
|
faint_bg_color: Color32::from_gray(240),
|
||||||
|
extreme_bg_color: Color32::from_gray(250),
|
||||||
code_bg_color: Color32::from_gray(200),
|
code_bg_color: Color32::from_gray(200),
|
||||||
window_shadow: Shadow::big_light(),
|
window_shadow: Shadow::big_light(),
|
||||||
|
popup_shadow: Shadow::small_light(),
|
||||||
..Self::dark()
|
..Self::dark()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -431,32 +462,39 @@ impl Widgets {
|
||||||
pub fn dark() -> Self {
|
pub fn dark() -> Self {
|
||||||
Self {
|
Self {
|
||||||
noninteractive: WidgetVisuals {
|
noninteractive: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(30), // window background
|
bg_fill: Color32::from_gray(27), // window background
|
||||||
bg_stroke: Stroke::new(1.0, Color32::from_gray(65)), // window outline
|
bg_stroke: Stroke::new(1.0, Color32::from_gray(60)), // separators, indentation lines, windows outlines
|
||||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(160)), // normal text color
|
fg_stroke: Stroke::new(1.0, Color32::from_gray(140)), // normal text color
|
||||||
corner_radius: 4.0,
|
corner_radius: 2.0,
|
||||||
expansion: 0.0,
|
expansion: 0.0,
|
||||||
},
|
},
|
||||||
inactive: WidgetVisuals {
|
inactive: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(70),
|
bg_fill: Color32::from_gray(60), // button background
|
||||||
bg_stroke: Default::default(),
|
bg_stroke: Default::default(),
|
||||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(200)), // Should NOT look grayed out!
|
fg_stroke: Stroke::new(1.0, Color32::from_gray(180)), // button text
|
||||||
corner_radius: 4.0,
|
corner_radius: 2.0,
|
||||||
expansion: 0.0,
|
expansion: 0.0,
|
||||||
},
|
},
|
||||||
hovered: WidgetVisuals {
|
hovered: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(80),
|
bg_fill: Color32::from_gray(70),
|
||||||
bg_stroke: Stroke::new(1.0, Color32::from_gray(150)), // e.g. hover over window edge or button
|
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)),
|
fg_stroke: Stroke::new(1.5, Color32::from_gray(240)),
|
||||||
corner_radius: 4.0,
|
corner_radius: 3.0,
|
||||||
expansion: 1.0,
|
expansion: 1.0,
|
||||||
},
|
},
|
||||||
active: WidgetVisuals {
|
active: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(90),
|
bg_fill: Color32::from_gray(55),
|
||||||
bg_stroke: Stroke::new(1.0, Color32::WHITE),
|
bg_stroke: Stroke::new(1.0, Color32::WHITE),
|
||||||
fg_stroke: Stroke::new(2.0, Color32::WHITE),
|
fg_stroke: Stroke::new(2.0, Color32::WHITE),
|
||||||
corner_radius: 4.0,
|
corner_radius: 2.0,
|
||||||
expansion: 2.0,
|
expansion: 1.0,
|
||||||
|
},
|
||||||
|
open: WidgetVisuals {
|
||||||
|
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)),
|
||||||
|
corner_radius: 2.0,
|
||||||
|
expansion: 0.0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,32 +502,39 @@ impl Widgets {
|
||||||
pub fn light() -> Self {
|
pub fn light() -> Self {
|
||||||
Self {
|
Self {
|
||||||
noninteractive: WidgetVisuals {
|
noninteractive: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(220), // window background
|
bg_fill: Color32::from_gray(235), // window background
|
||||||
bg_stroke: Stroke::new(1.0, Color32::from_gray(180)), // window outline
|
bg_stroke: Stroke::new(1.0, Color32::from_gray(190)), // separators, indentation lines, windows outlines
|
||||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(70)), // normal text color
|
fg_stroke: Stroke::new(1.0, Color32::from_gray(100)), // normal text color
|
||||||
corner_radius: 4.0,
|
corner_radius: 2.0,
|
||||||
expansion: 0.0,
|
expansion: 0.0,
|
||||||
},
|
},
|
||||||
inactive: WidgetVisuals {
|
inactive: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(195),
|
bg_fill: Color32::from_gray(215), // button background
|
||||||
bg_stroke: Default::default(),
|
bg_stroke: Default::default(),
|
||||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(55)), // Should NOT look grayed out!
|
fg_stroke: Stroke::new(1.0, Color32::from_gray(80)), // button text
|
||||||
corner_radius: 4.0,
|
corner_radius: 2.0,
|
||||||
expansion: 0.0,
|
expansion: 0.0,
|
||||||
},
|
},
|
||||||
hovered: WidgetVisuals {
|
hovered: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(175),
|
bg_fill: Color32::from_gray(210),
|
||||||
bg_stroke: Stroke::new(1.0, Color32::from_gray(105)), // e.g. hover over window edge or button
|
bg_stroke: Stroke::new(1.0, Color32::from_gray(105)), // e.g. hover over window edge or button
|
||||||
fg_stroke: Stroke::new(2.0, Color32::BLACK),
|
fg_stroke: Stroke::new(1.5, Color32::BLACK),
|
||||||
corner_radius: 4.0,
|
corner_radius: 3.0,
|
||||||
expansion: 1.0,
|
expansion: 1.0,
|
||||||
},
|
},
|
||||||
active: WidgetVisuals {
|
active: WidgetVisuals {
|
||||||
bg_fill: Color32::from_gray(165),
|
bg_fill: Color32::from_gray(165),
|
||||||
bg_stroke: Stroke::new(1.0, Color32::BLACK),
|
bg_stroke: Stroke::new(1.0, Color32::BLACK),
|
||||||
fg_stroke: Stroke::new(2.0, Color32::BLACK),
|
fg_stroke: Stroke::new(2.0, Color32::BLACK),
|
||||||
corner_radius: 4.0,
|
corner_radius: 2.0,
|
||||||
expansion: 2.0,
|
expansion: 1.0,
|
||||||
|
},
|
||||||
|
open: WidgetVisuals {
|
||||||
|
bg_fill: Color32::from_gray(220),
|
||||||
|
bg_stroke: Stroke::new(1.0, Color32::from_gray(160)),
|
||||||
|
fg_stroke: Stroke::new(1.0, Color32::BLACK),
|
||||||
|
corner_radius: 2.0,
|
||||||
|
expansion: 0.0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,30 +565,55 @@ impl Style {
|
||||||
|
|
||||||
visuals.light_dark_radio_buttons(ui);
|
visuals.light_dark_radio_buttons(ui);
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
crate::Grid::new("_options").show(ui, |ui| {
|
||||||
ui.label("Default text style:");
|
ui.label("Default body text style:");
|
||||||
for &value in &[TextStyle::Body, TextStyle::Monospace] {
|
ui.horizontal(|ui| {
|
||||||
ui.radio_value(body_text_style, value, format!("{:?}", value));
|
for &style in &[TextStyle::Body, TextStyle::Monospace] {
|
||||||
}
|
if ui
|
||||||
});
|
.add(
|
||||||
|
RadioButton::new(*body_text_style == style, format!("{:?}", style))
|
||||||
crate::ComboBox::from_label("Global text style override")
|
.text_style(style),
|
||||||
.selected_text(match override_text_style {
|
)
|
||||||
None => "None".to_owned(),
|
.clicked()
|
||||||
Some(override_text_style) => format!("{:?}", override_text_style),
|
{
|
||||||
})
|
*body_text_style = style;
|
||||||
.show_ui(ui, |ui| {
|
};
|
||||||
ui.selectable_value(override_text_style, None, "None");
|
|
||||||
for style in TextStyle::all() {
|
|
||||||
ui.selectable_value(override_text_style, Some(style), format!("{:?}", style));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
ui.add(
|
ui.label("Override text style:");
|
||||||
Slider::new(animation_time, 0.0..=1.0)
|
crate::ComboBox::from_id_source("Override text style")
|
||||||
.text("animation durations")
|
.selected_text(match override_text_style {
|
||||||
.suffix(" s"),
|
None => "None".to_owned(),
|
||||||
);
|
Some(override_text_style) => format!("{:?}", override_text_style),
|
||||||
|
})
|
||||||
|
.show_ui(ui, |ui| {
|
||||||
|
ui.selectable_value(override_text_style, None, "None");
|
||||||
|
for style in TextStyle::all() {
|
||||||
|
// ui.selectable_value(override_text_style, Some(style), format!("{:?}", style));
|
||||||
|
let selected = *override_text_style == Some(style);
|
||||||
|
if ui
|
||||||
|
.add(
|
||||||
|
SelectableLabel::new(selected, format!("{:?}", style))
|
||||||
|
.text_style(style),
|
||||||
|
)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
*override_text_style = Some(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.label("Animation duration:");
|
||||||
|
ui.add(
|
||||||
|
Slider::new(animation_time, 0.0..=1.0)
|
||||||
|
.clamp_to_range(true)
|
||||||
|
.suffix(" s"),
|
||||||
|
);
|
||||||
|
ui.end_row();
|
||||||
|
});
|
||||||
|
|
||||||
ui.collapsing("📏 Spacing", |ui| spacing.ui(ui));
|
ui.collapsing("📏 Spacing", |ui| spacing.ui(ui));
|
||||||
ui.collapsing("☝ Interaction", |ui| interaction.ui(ui));
|
ui.collapsing("☝ Interaction", |ui| interaction.ui(ui));
|
||||||
|
@ -567,19 +637,61 @@ impl Spacing {
|
||||||
icon_width,
|
icon_width,
|
||||||
icon_spacing,
|
icon_spacing,
|
||||||
tooltip_width,
|
tooltip_width,
|
||||||
|
indent_ends_with_horizontal_line,
|
||||||
|
combo_height,
|
||||||
|
scroll_bar_width,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
ui.add(slider_vec2(item_spacing, 0.0..=10.0, "item_spacing"));
|
ui.add(slider_vec2(item_spacing, 0.0..=20.0, "Item spacing"));
|
||||||
ui.add(slider_vec2(window_padding, 0.0..=10.0, "window_padding"));
|
ui.add(slider_vec2(window_padding, 0.0..=20.0, "Window padding"));
|
||||||
ui.add(slider_vec2(button_padding, 0.0..=10.0, "button_padding"));
|
ui.add(slider_vec2(button_padding, 0.0..=20.0, "Button padding"));
|
||||||
ui.add(slider_vec2(interact_size, 0.0..=60.0, "interact_size"))
|
ui.add(slider_vec2(interact_size, 4.0..=60.0, "Interact size"))
|
||||||
.on_hover_text("Minimum size of an interactive widget");
|
.on_hover_text("Minimum size of an interactive widget");
|
||||||
ui.add(Slider::new(indent, 0.0..=100.0).text("indent"));
|
ui.horizontal(|ui| {
|
||||||
ui.add(Slider::new(slider_width, 0.0..=1000.0).text("slider_width"));
|
ui.add(DragValue::new(indent).clamp_range(0.0..=100.0));
|
||||||
ui.add(Slider::new(text_edit_width, 0.0..=1000.0).text("text_edit_width"));
|
ui.label("Indent");
|
||||||
ui.add(Slider::new(icon_width, 0.0..=60.0).text("icon_width"));
|
});
|
||||||
ui.add(Slider::new(icon_spacing, 0.0..=10.0).text("icon_spacing"));
|
ui.horizontal(|ui| {
|
||||||
ui.add(Slider::new(tooltip_width, 0.0..=1000.0).text("tooltip_width"));
|
ui.add(DragValue::new(slider_width).clamp_range(0.0..=1000.0));
|
||||||
|
ui.label("Slider width");
|
||||||
|
});
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.add(DragValue::new(text_edit_width).clamp_range(0.0..=1000.0));
|
||||||
|
ui.label("TextEdit width");
|
||||||
|
});
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.add(DragValue::new(scroll_bar_width).clamp_range(0.0..=32.0));
|
||||||
|
ui.label("Scroll-bar width width");
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Checkboxes etc:");
|
||||||
|
ui.add(
|
||||||
|
DragValue::new(icon_width)
|
||||||
|
.prefix("width:")
|
||||||
|
.clamp_range(0.0..=60.0),
|
||||||
|
);
|
||||||
|
ui.add(
|
||||||
|
DragValue::new(icon_spacing)
|
||||||
|
.prefix("spacing:")
|
||||||
|
.clamp_range(0.0..=10.0),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.add(DragValue::new(tooltip_width).clamp_range(0.0..=1000.0));
|
||||||
|
ui.label("Tooltip wrap width");
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.checkbox(
|
||||||
|
indent_ends_with_horizontal_line,
|
||||||
|
"End indented regions with a horizontal separator",
|
||||||
|
);
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Max height of a combo box");
|
||||||
|
ui.add(DragValue::new(combo_height).clamp_range(0.0..=1000.0));
|
||||||
|
});
|
||||||
|
|
||||||
ui.vertical_centered(|ui| reset_button(ui, self));
|
ui.vertical_centered(|ui| reset_button(ui, self));
|
||||||
}
|
}
|
||||||
|
@ -612,33 +724,40 @@ impl Widgets {
|
||||||
hovered,
|
hovered,
|
||||||
inactive,
|
inactive,
|
||||||
noninteractive,
|
noninteractive,
|
||||||
|
open,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
ui.collapsing("noninteractive", |ui| {
|
ui.collapsing("Noninteractive", |ui| {
|
||||||
ui.label("The style of a widget that you cannot interact with.");
|
ui.label(
|
||||||
|
"The style of a widget that you cannot interact with, e.g. labels and separators.",
|
||||||
|
);
|
||||||
noninteractive.ui(ui)
|
noninteractive.ui(ui)
|
||||||
});
|
});
|
||||||
ui.collapsing("interactive & inactive", |ui| {
|
ui.collapsing("Interactive but inactive", |ui| {
|
||||||
ui.label("The style of an interactive widget, such as a button, at rest.");
|
ui.label("The style of an interactive widget, such as a button, at rest.");
|
||||||
inactive.ui(ui)
|
inactive.ui(ui)
|
||||||
});
|
});
|
||||||
ui.collapsing("interactive & hovered", |ui| {
|
ui.collapsing("Interactive and hovered", |ui| {
|
||||||
ui.label("The style of an interactive widget while you hover it.");
|
ui.label("The style of an interactive widget while you hover it.");
|
||||||
hovered.ui(ui)
|
hovered.ui(ui)
|
||||||
});
|
});
|
||||||
ui.collapsing("interactive & active", |ui| {
|
ui.collapsing("Interactive and active", |ui| {
|
||||||
ui.label("The style of an interactive widget as you are clicking or dragging it.");
|
ui.label("The style of an interactive widget as you are clicking or dragging it.");
|
||||||
active.ui(ui)
|
active.ui(ui)
|
||||||
});
|
});
|
||||||
|
ui.collapsing("Open menu", |ui| {
|
||||||
|
ui.label("The style of an open combo-box or menu button");
|
||||||
|
open.ui(ui)
|
||||||
|
});
|
||||||
|
|
||||||
ui.vertical_centered(|ui| reset_button(ui, self));
|
// ui.vertical_centered(|ui| reset_button(ui, self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Selection {
|
impl Selection {
|
||||||
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
||||||
let Self { bg_fill, stroke } = self;
|
let Self { bg_fill, stroke } = self;
|
||||||
|
ui.label("Selectable labels");
|
||||||
ui_color(ui, bg_fill, "bg_fill");
|
ui_color(ui, bg_fill, "bg_fill");
|
||||||
stroke_ui(ui, stroke, "stroke");
|
stroke_ui(ui, stroke, "stroke");
|
||||||
}
|
}
|
||||||
|
@ -653,12 +772,12 @@ impl WidgetVisuals {
|
||||||
fg_stroke,
|
fg_stroke,
|
||||||
expansion,
|
expansion,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
ui_color(ui, bg_fill, "bg_fill");
|
ui_color(ui, bg_fill, "bg_fill");
|
||||||
stroke_ui(ui, bg_stroke, "bg_stroke");
|
stroke_ui(ui, bg_stroke, "bg_stroke");
|
||||||
ui.add(Slider::new(corner_radius, 0.0..=10.0).text("corner_radius"));
|
ui.add(Slider::new(corner_radius, 0.0..=10.0).text("corner_radius"));
|
||||||
stroke_ui(ui, fg_stroke, "fg_stroke (text)");
|
stroke_ui(ui, fg_stroke, "fg_stroke (text)");
|
||||||
ui.add(Slider::new(expansion, -5.0..=5.0).text("expansion"));
|
ui.add(Slider::new(expansion, -5.0..=5.0).text("expansion"))
|
||||||
|
.on_hover_text("make shapes this much larger");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,42 +822,66 @@ impl Visuals {
|
||||||
override_text_color: _,
|
override_text_color: _,
|
||||||
widgets,
|
widgets,
|
||||||
selection,
|
selection,
|
||||||
extreme_bg_color,
|
|
||||||
hyperlink_color,
|
hyperlink_color,
|
||||||
|
faint_bg_color,
|
||||||
|
extreme_bg_color,
|
||||||
code_bg_color,
|
code_bg_color,
|
||||||
window_corner_radius,
|
window_corner_radius,
|
||||||
window_shadow,
|
window_shadow,
|
||||||
|
popup_shadow,
|
||||||
resize_corner_size,
|
resize_corner_size,
|
||||||
text_cursor_width,
|
text_cursor_width,
|
||||||
text_cursor_preview,
|
text_cursor_preview,
|
||||||
clip_rect_margin,
|
clip_rect_margin,
|
||||||
|
button_frame,
|
||||||
|
collapsing_header_frame,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
ui.collapsing("widgets", |ui| widgets.ui(ui));
|
ui.collapsing("Background Colors", |ui| {
|
||||||
ui.collapsing("selection", |ui| selection.ui(ui));
|
ui_color(ui, &mut widgets.inactive.bg_fill, "Buttons");
|
||||||
|
ui_color(ui, &mut widgets.noninteractive.bg_fill, "Windows");
|
||||||
|
ui_color(ui, faint_bg_color, "Faint accent").on_hover_text(
|
||||||
|
"Used for faint accentuation of interactive things, like striped grids.",
|
||||||
|
);
|
||||||
|
ui_color(ui, extreme_bg_color, "Extreme")
|
||||||
|
.on_hover_text("Background of plots and paintings");
|
||||||
|
});
|
||||||
|
|
||||||
ui.group(|ui| {
|
ui.collapsing("Window", |ui| {
|
||||||
ui.label("Window");
|
|
||||||
// Common shortcuts
|
// Common shortcuts
|
||||||
ui_color(ui, &mut widgets.noninteractive.bg_fill, "Fill");
|
ui_color(ui, &mut widgets.noninteractive.bg_fill, "Fill");
|
||||||
stroke_ui(ui, &mut widgets.noninteractive.bg_stroke, "Outline");
|
stroke_ui(ui, &mut widgets.noninteractive.bg_stroke, "Outline");
|
||||||
ui.add(Slider::new(window_corner_radius, 0.0..=20.0).text("Corner Radius"));
|
ui.add(Slider::new(window_corner_radius, 0.0..=20.0).text("Rounding"));
|
||||||
shadow_ui(ui, window_shadow, "Shadow");
|
shadow_ui(ui, window_shadow, "Shadow");
|
||||||
|
shadow_ui(ui, popup_shadow, "Shadow (small menus and popups)");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ui.collapsing("Widgets", |ui| widgets.ui(ui));
|
||||||
|
ui.collapsing("Selection", |ui| selection.ui(ui));
|
||||||
|
|
||||||
ui_color(
|
ui_color(
|
||||||
ui,
|
ui,
|
||||||
&mut widgets.noninteractive.fg_stroke.color,
|
&mut widgets.noninteractive.fg_stroke.color,
|
||||||
"Text color",
|
"Text color",
|
||||||
);
|
);
|
||||||
|
ui_color(ui, code_bg_color, Label::new("Code background").code()).on_hover_ui(|ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.spacing_mut().item_spacing.x = 0.0;
|
||||||
|
ui.label("For monospaced inlined text ");
|
||||||
|
ui.code("like this");
|
||||||
|
ui.label(".");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
ui_color(ui, extreme_bg_color, "extreme_bg_color");
|
|
||||||
ui_color(ui, hyperlink_color, "hyperlink_color");
|
ui_color(ui, hyperlink_color, "hyperlink_color");
|
||||||
ui_color(ui, code_bg_color, "code_bg_color");
|
|
||||||
ui.add(Slider::new(resize_corner_size, 0.0..=20.0).text("resize_corner_size"));
|
ui.add(Slider::new(resize_corner_size, 0.0..=20.0).text("resize_corner_size"));
|
||||||
ui.add(Slider::new(text_cursor_width, 0.0..=2.0).text("text_cursor_width"));
|
ui.add(Slider::new(text_cursor_width, 0.0..=4.0).text("text_cursor_width"));
|
||||||
ui.checkbox(text_cursor_preview, "text_cursor_preview");
|
ui.checkbox(text_cursor_preview, "Preview text cursor on hover");
|
||||||
ui.add(Slider::new(clip_rect_margin, 0.0..=20.0).text("clip_rect_margin"));
|
ui.add(Slider::new(clip_rect_margin, 0.0..=20.0).text("clip_rect_margin"));
|
||||||
|
|
||||||
|
ui.checkbox(button_frame, "Button has a frame");
|
||||||
|
ui.checkbox(collapsing_header_frame, "Collapsing header has a frame");
|
||||||
|
|
||||||
ui.vertical_centered(|ui| reset_button(ui, self));
|
ui.vertical_centered(|ui| reset_button(ui, self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -775,17 +918,26 @@ fn slider_vec2<'a>(
|
||||||
) -> impl Widget + 'a {
|
) -> impl Widget + 'a {
|
||||||
move |ui: &mut crate::Ui| {
|
move |ui: &mut crate::Ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(Slider::new(&mut value.x, range.clone()).text("w"));
|
ui.add(
|
||||||
ui.add(Slider::new(&mut value.y, range.clone()).text("h"));
|
DragValue::new(&mut value.x)
|
||||||
|
.clamp_range(range.clone())
|
||||||
|
.prefix("x: "),
|
||||||
|
);
|
||||||
|
ui.add(
|
||||||
|
DragValue::new(&mut value.y)
|
||||||
|
.clamp_range(range.clone())
|
||||||
|
.prefix("y: "),
|
||||||
|
);
|
||||||
ui.label(text);
|
ui.label(text);
|
||||||
})
|
})
|
||||||
.response
|
.response
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui_color(ui: &mut Ui, srgba: &mut Color32, text: &str) {
|
fn ui_color(ui: &mut Ui, srgba: &mut Color32, text: impl Into<Label>) -> Response {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.color_edit_button_srgba(srgba);
|
ui.color_edit_button_srgba(srgba);
|
||||||
ui.label(text);
|
ui.label(text);
|
||||||
});
|
})
|
||||||
|
.response
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,6 +137,11 @@ impl Ui {
|
||||||
self.style = style.into();
|
self.style = style.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reset to the default style set in [`Context`].
|
||||||
|
pub fn reset_style(&mut self) {
|
||||||
|
self.style = self.ctx().style();
|
||||||
|
}
|
||||||
|
|
||||||
/// The current spacing options for this `Ui`.
|
/// The current spacing options for this `Ui`.
|
||||||
/// Short for `ui.style().spacing`.
|
/// Short for `ui.style().spacing`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -1317,6 +1322,9 @@ impl Ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a child ui which is indented to the right.
|
/// Create a child ui which is indented to the right.
|
||||||
|
///
|
||||||
|
/// The `id_source` here be anything at all.
|
||||||
|
// TODO: remove `id_source` argument?
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn indent<R>(
|
pub fn indent<R>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -1347,7 +1355,8 @@ impl Ui {
|
||||||
};
|
};
|
||||||
let ret = add_contents(&mut child_ui);
|
let ret = add_contents(&mut child_ui);
|
||||||
|
|
||||||
let end_with_horizontal_line = true;
|
let end_with_horizontal_line = self.spacing().indent_ends_with_horizontal_line;
|
||||||
|
|
||||||
if end_with_horizontal_line {
|
if end_with_horizontal_line {
|
||||||
child_ui.add_space(4.0);
|
child_ui.add_space(4.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,10 @@ pub struct Button {
|
||||||
text_style: Option<TextStyle>,
|
text_style: Option<TextStyle>,
|
||||||
/// None means default for interact
|
/// None means default for interact
|
||||||
fill: Option<Color32>,
|
fill: Option<Color32>,
|
||||||
|
stroke: Option<Stroke>,
|
||||||
sense: Sense,
|
sense: Sense,
|
||||||
small: bool,
|
small: bool,
|
||||||
frame: bool,
|
frame: Option<bool>,
|
||||||
wrap: Option<bool>,
|
wrap: Option<bool>,
|
||||||
min_size: Vec2,
|
min_size: Vec2,
|
||||||
}
|
}
|
||||||
|
@ -32,10 +33,11 @@ impl Button {
|
||||||
text: text.to_string(),
|
text: text.to_string(),
|
||||||
text_color: None,
|
text_color: None,
|
||||||
text_style: None,
|
text_style: None,
|
||||||
fill: Default::default(),
|
fill: None,
|
||||||
|
stroke: None,
|
||||||
sense: Sense::click(),
|
sense: Sense::click(),
|
||||||
small: false,
|
small: false,
|
||||||
frame: true,
|
frame: None,
|
||||||
wrap: None,
|
wrap: None,
|
||||||
min_size: Vec2::ZERO,
|
min_size: Vec2::ZERO,
|
||||||
}
|
}
|
||||||
|
@ -56,8 +58,19 @@ impl Button {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fill(mut self, fill: Option<Color32>) -> Self {
|
/// Override background fill color. Note that this will override any on-hover effects.
|
||||||
self.fill = fill;
|
/// Calling this will also turn on the frame.
|
||||||
|
pub fn fill(mut self, fill: impl Into<Color32>) -> Self {
|
||||||
|
self.fill = Some(fill.into());
|
||||||
|
self.frame = Some(true);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Override button stroke. Note that this will override any on-hover effects.
|
||||||
|
/// Calling this will also turn on the frame.
|
||||||
|
pub fn stroke(mut self, stroke: impl Into<Stroke>) -> Self {
|
||||||
|
self.stroke = Some(stroke.into());
|
||||||
|
self.frame = Some(true);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +83,7 @@ impl Button {
|
||||||
|
|
||||||
/// Turn off the frame
|
/// Turn off the frame
|
||||||
pub fn frame(mut self, frame: bool) -> Self {
|
pub fn frame(mut self, frame: bool) -> Self {
|
||||||
self.frame = frame;
|
self.frame = Some(frame);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +129,7 @@ impl Button {
|
||||||
text_color,
|
text_color,
|
||||||
text_style,
|
text_style,
|
||||||
fill,
|
fill,
|
||||||
|
stroke,
|
||||||
sense,
|
sense,
|
||||||
small,
|
small,
|
||||||
frame,
|
frame,
|
||||||
|
@ -123,6 +137,8 @@ impl Button {
|
||||||
min_size,
|
min_size,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
let frame = frame.unwrap_or_else(|| ui.visuals().button_frame);
|
||||||
|
|
||||||
let text_style = text_style
|
let text_style = text_style
|
||||||
.or(ui.style().override_text_style)
|
.or(ui.style().override_text_style)
|
||||||
.unwrap_or(TextStyle::Button);
|
.unwrap_or(TextStyle::Button);
|
||||||
|
@ -159,11 +175,12 @@ impl Button {
|
||||||
|
|
||||||
if frame {
|
if frame {
|
||||||
let fill = fill.unwrap_or(visuals.bg_fill);
|
let fill = fill.unwrap_or(visuals.bg_fill);
|
||||||
|
let stroke = stroke.unwrap_or(visuals.bg_stroke);
|
||||||
ui.painter().rect(
|
ui.painter().rect(
|
||||||
rect.expand(visuals.expansion),
|
rect.expand(visuals.expansion),
|
||||||
visuals.corner_radius,
|
visuals.corner_radius,
|
||||||
fill,
|
fill,
|
||||||
visuals.bg_stroke,
|
stroke,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,11 +67,15 @@ fn show_hsva(ui: &mut Ui, color: Hsva, desired_size: Vec2) -> Response {
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
fn color_button(ui: &mut Ui, color: Color32) -> Response {
|
fn color_button(ui: &mut Ui, color: Color32, open: bool) -> Response {
|
||||||
let size = ui.spacing().interact_size;
|
let size = ui.spacing().interact_size;
|
||||||
let (rect, response) = ui.allocate_exact_size(size, Sense::click());
|
let (rect, response) = ui.allocate_exact_size(size, Sense::click());
|
||||||
response.widget_info(|| WidgetInfo::new(WidgetType::ColorButton));
|
response.widget_info(|| WidgetInfo::new(WidgetType::ColorButton));
|
||||||
let visuals = ui.style().interact(&response);
|
let visuals = if open {
|
||||||
|
&ui.visuals().widgets.open
|
||||||
|
} else {
|
||||||
|
ui.style().interact(&response)
|
||||||
|
};
|
||||||
let rect = rect.expand(visuals.expansion);
|
let rect = rect.expand(visuals.expansion);
|
||||||
|
|
||||||
background_checkers(ui.painter(), rect);
|
background_checkers(ui.painter(), rect);
|
||||||
|
@ -83,7 +87,7 @@ fn color_button(ui: &mut Ui, color: Color32) -> Response {
|
||||||
|
|
||||||
let corner_radius = visuals.corner_radius.at_most(2.0);
|
let corner_radius = visuals.corner_radius.at_most(2.0);
|
||||||
ui.painter()
|
ui.painter()
|
||||||
.rect_stroke(rect, corner_radius, (2.0, visuals.bg_fill)); // fill is intentional!
|
.rect_stroke(rect, corner_radius, (2.0, visuals.bg_fill)); // fill is intentional, because default style has no border
|
||||||
|
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
@ -335,7 +339,9 @@ fn color_picker_hsva_2d(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> bool {
|
||||||
|
|
||||||
pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Response {
|
pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Response {
|
||||||
let pupup_id = ui.auto_id_with("popup");
|
let pupup_id = ui.auto_id_with("popup");
|
||||||
let mut button_response = color_button(ui, (*hsva).into()).on_hover_text("Click to edit color");
|
let open = ui.memory().is_popup_open(pupup_id);
|
||||||
|
let mut button_response =
|
||||||
|
color_button(ui, (*hsva).into(), open).on_hover_text("Click to edit color");
|
||||||
|
|
||||||
if button_response.clicked() {
|
if button_response.clicked() {
|
||||||
ui.memory().toggle_popup(pupup_id);
|
ui.memory().toggle_popup(pupup_id);
|
||||||
|
|
|
@ -353,7 +353,7 @@ impl Widget for Plot {
|
||||||
rect,
|
rect,
|
||||||
corner_radius: 2.0,
|
corner_radius: 2.0,
|
||||||
fill: ui.visuals().extreme_bg_color,
|
fill: ui.visuals().extreme_bg_color,
|
||||||
stroke: ui.visuals().window_stroke(),
|
stroke: ui.visuals().widgets.noninteractive.bg_stroke,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Legend
|
// Legend
|
||||||
|
|
|
@ -375,7 +375,10 @@ impl<'a> Slider<'a> {
|
||||||
{
|
{
|
||||||
let value = self.get_value();
|
let value = self.get_value();
|
||||||
|
|
||||||
let rail_radius = ui.painter().round_to_pixel((rect.height() / 8.0).max(2.0));
|
let rail_radius = ui
|
||||||
|
.painter()
|
||||||
|
.round_to_pixel((rect.height() / 4.0).at_least(2.0));
|
||||||
|
|
||||||
let rail_rect = Rect::from_min_max(
|
let rail_rect = Rect::from_min_max(
|
||||||
pos2(rect.left(), rect.center().y - rail_radius),
|
pos2(rect.left(), rect.center().y - rail_radius),
|
||||||
pos2(rect.right(), rect.center().y + rail_radius),
|
pos2(rect.right(), rect.center().y + rail_radius),
|
||||||
|
@ -385,8 +388,7 @@ impl<'a> Slider<'a> {
|
||||||
let visuals = ui.style().interact(response);
|
let visuals = ui.style().interact(response);
|
||||||
ui.painter().add(Shape::Rect {
|
ui.painter().add(Shape::Rect {
|
||||||
rect: rail_rect,
|
rect: rail_rect,
|
||||||
corner_radius: rail_radius,
|
corner_radius: ui.visuals().widgets.inactive.corner_radius,
|
||||||
|
|
||||||
fill: ui.visuals().widgets.inactive.bg_fill,
|
fill: ui.visuals().widgets.inactive.bg_fill,
|
||||||
// fill: visuals.bg_fill,
|
// fill: visuals.bg_fill,
|
||||||
// fill: ui.visuals().extreme_bg_color,
|
// fill: ui.visuals().extreme_bg_color,
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub fn easy_mark(ui: &mut Ui, easy_mark: &str) {
|
||||||
|
|
||||||
pub fn easy_mark_it<'em>(ui: &mut Ui, items: impl Iterator<Item = easy_mark::Item<'em>>) {
|
pub fn easy_mark_it<'em>(ui: &mut Ui, items: impl Iterator<Item = easy_mark::Item<'em>>) {
|
||||||
ui.horizontal_wrapped(|ui| {
|
ui.horizontal_wrapped(|ui| {
|
||||||
ui.spacing_mut().item_spacing = Vec2::new(0.0, 0.0);
|
ui.spacing_mut().item_spacing.x = 0.0;
|
||||||
ui.set_row_height(ui.fonts()[TextStyle::Body].row_height());
|
ui.set_row_height(ui.fonts()[TextStyle::Body].row_height());
|
||||||
|
|
||||||
for item in items {
|
for item in items {
|
||||||
|
|
|
@ -15,10 +15,18 @@ pub struct Shadow {
|
||||||
|
|
||||||
impl Shadow {
|
impl Shadow {
|
||||||
/// Tooltips, menus, ...
|
/// Tooltips, menus, ...
|
||||||
pub fn small() -> Self {
|
pub fn small_dark() -> Self {
|
||||||
Self {
|
Self {
|
||||||
extrusion: 8.0,
|
extrusion: 16.0,
|
||||||
color: Color32::from_black_alpha(64),
|
color: Color32::from_black_alpha(96),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tooltips, menus, ...
|
||||||
|
pub fn small_light() -> Self {
|
||||||
|
Self {
|
||||||
|
extrusion: 16.0,
|
||||||
|
color: Color32::from_black_alpha(32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -400,7 +400,8 @@ impl Font {
|
||||||
row.y_max += cursor_y;
|
row.y_max += cursor_y;
|
||||||
}
|
}
|
||||||
cursor_y = paragraph_rows.last().unwrap().y_max;
|
cursor_y = paragraph_rows.last().unwrap().y_max;
|
||||||
cursor_y += row_height * 0.2; // Extra spacing between paragraphs. TODO: less hacky
|
|
||||||
|
// cursor_y += row_height * 0.2; // Extra spacing between paragraphs.
|
||||||
|
|
||||||
rows.append(&mut paragraph_rows);
|
rows.append(&mut paragraph_rows);
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ impl Default for FontDefinitions {
|
||||||
let mut family_and_size = BTreeMap::new();
|
let mut family_and_size = BTreeMap::new();
|
||||||
family_and_size.insert(TextStyle::Small, (FontFamily::Proportional, 10.0));
|
family_and_size.insert(TextStyle::Small, (FontFamily::Proportional, 10.0));
|
||||||
family_and_size.insert(TextStyle::Body, (FontFamily::Proportional, 14.0));
|
family_and_size.insert(TextStyle::Body, (FontFamily::Proportional, 14.0));
|
||||||
family_and_size.insert(TextStyle::Button, (FontFamily::Proportional, 16.0));
|
family_and_size.insert(TextStyle::Button, (FontFamily::Proportional, 14.0));
|
||||||
family_and_size.insert(TextStyle::Heading, (FontFamily::Proportional, 20.0));
|
family_and_size.insert(TextStyle::Heading, (FontFamily::Proportional, 20.0));
|
||||||
family_and_size.insert(TextStyle::Monospace, (FontFamily::Monospace, 13.0)); // 13 for `ProggyClean`
|
family_and_size.insert(TextStyle::Monospace, (FontFamily::Monospace, 13.0)); // 13 for `ProggyClean`
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue