refactor interact style
This commit is contained in:
parent
2bd610cb5b
commit
3a1d677840
10 changed files with 135 additions and 87 deletions
|
@ -1,5 +1,7 @@
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// 0-255 `sRGBA`. TODO: rename `sRGBA` for clarity.
|
/// 0-255 `sRGBA`. TODO: rename `sRGBA` for clarity.
|
||||||
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd, serde_derive::Serialize)]
|
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
|
||||||
pub struct Color {
|
pub struct Color {
|
||||||
pub r: u8,
|
pub r: u8,
|
||||||
pub g: u8,
|
pub g: u8,
|
||||||
|
@ -31,6 +33,15 @@ pub const fn gray(l: u8, a: u8) -> Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn white(a: u8) -> Color {
|
||||||
|
Color {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
a,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const BLACK: Color = srgba(0, 0, 0, 255);
|
pub const BLACK: Color = srgba(0, 0, 0, 255);
|
||||||
pub const LIGHT_GRAY: Color = srgba(220, 220, 220, 255);
|
pub const LIGHT_GRAY: Color = srgba(220, 220, 220, 255);
|
||||||
pub const WHITE: Color = srgba(255, 255, 255, 255);
|
pub const WHITE: Color = srgba(255, 255, 255, 255);
|
||||||
|
|
|
@ -93,15 +93,15 @@ impl CollapsingHeader {
|
||||||
text_pos,
|
text_pos,
|
||||||
label.text_style,
|
label.text_style,
|
||||||
title,
|
title,
|
||||||
Some(ui.style().interact_stroke_color(&interact)),
|
Some(ui.style().interact(&interact).stroke_color),
|
||||||
);
|
);
|
||||||
|
|
||||||
ui.insert_paint_cmd(
|
ui.insert_paint_cmd(
|
||||||
where_to_put_background,
|
where_to_put_background,
|
||||||
PaintCmd::Rect {
|
PaintCmd::Rect {
|
||||||
corner_radius: ui.style().interact_corner_radius(&interact),
|
corner_radius: ui.style().interact(&interact).corner_radius,
|
||||||
fill_color: ui.style().interact_fill_color(&interact),
|
fill_color: ui.style().interact(&interact).fill_color,
|
||||||
outline: ui.style().interact_outline(&interact),
|
outline: ui.style().interact(&interact).outline,
|
||||||
rect: interact.rect,
|
rect: interact.rect,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -147,8 +147,8 @@ impl CollapsingHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_icon(ui: &mut Ui, state: &State, interact: &InteractInfo) {
|
fn paint_icon(ui: &mut Ui, state: &State, interact: &InteractInfo) {
|
||||||
let stroke_color = ui.style().interact_stroke_color(interact);
|
let stroke_color = ui.style().interact(interact).stroke_color;
|
||||||
let stroke_width = ui.style().interact_stroke_width(interact);
|
let stroke_width = ui.style().interact(interact).stroke_width;
|
||||||
|
|
||||||
let (mut small_icon_rect, _) = ui.style().icon_rectangles(interact.rect);
|
let (mut small_icon_rect, _) = ui.style().icon_rectangles(interact.rect);
|
||||||
small_icon_rect.set_center(pos2(
|
small_icon_rect.set_center(pos2(
|
||||||
|
|
|
@ -235,8 +235,8 @@ impl Resize {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_resize_corner(ui: &mut Ui, interact: &InteractInfo) {
|
fn paint_resize_corner(ui: &mut Ui, interact: &InteractInfo) {
|
||||||
let color = ui.style().interact_stroke_color(interact);
|
let color = ui.style().interact(interact).stroke_color;
|
||||||
let width = ui.style().interact_stroke_width(interact);
|
let width = ui.style().interact(interact).stroke_width;
|
||||||
|
|
||||||
let corner = interact.rect.right_bottom().round(); // TODO: round to pixels
|
let corner = interact.rect.right_bottom().round(); // TODO: round to pixels
|
||||||
let mut w = 2.0;
|
let mut w = 2.0;
|
||||||
|
|
|
@ -164,8 +164,8 @@ impl ScrollArea {
|
||||||
);
|
);
|
||||||
|
|
||||||
let style = outer_ui.style();
|
let style = outer_ui.style();
|
||||||
let handle_fill_color = style.interact_fill_color(&handle_interact);
|
let handle_fill_color = style.interact(&handle_interact).fill_color;
|
||||||
let handle_outline = style.interact_outline(&handle_interact);
|
let handle_outline = style.interact(&handle_interact).outline;
|
||||||
|
|
||||||
outer_ui.add_paint_cmd(PaintCmd::Rect {
|
outer_ui.add_paint_cmd(PaintCmd::Rect {
|
||||||
rect: outer_scroll_rect,
|
rect: outer_scroll_rect,
|
||||||
|
|
|
@ -25,6 +25,8 @@ pub struct Style {
|
||||||
/// The text starts after this many pixels.
|
/// The text starts after this many pixels.
|
||||||
pub start_icon_width: f32,
|
pub start_icon_width: f32,
|
||||||
|
|
||||||
|
pub interact: Interact,
|
||||||
|
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
// Purely visual:
|
// Purely visual:
|
||||||
/// For stuff like check marks in check boxes.
|
/// For stuff like check marks in check boxes.
|
||||||
|
@ -39,6 +41,8 @@ pub struct Style {
|
||||||
|
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
|
|
||||||
|
pub menu_bar: MenuBar,
|
||||||
|
|
||||||
/// Allow child widgets to be just on the border and still have an outline with some thickness
|
/// Allow child widgets to be just on the border and still have an outline with some thickness
|
||||||
pub clip_rect_margin: f32,
|
pub clip_rect_margin: f32,
|
||||||
|
|
||||||
|
@ -47,11 +51,6 @@ pub struct Style {
|
||||||
pub debug_widget_rects: bool,
|
pub debug_widget_rects: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
|
||||||
pub struct Window {
|
|
||||||
pub corner_radius: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Style {
|
impl Default for Style {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -61,17 +60,89 @@ impl Default for Style {
|
||||||
indent: 21.0,
|
indent: 21.0,
|
||||||
clickable_diameter: 22.0,
|
clickable_diameter: 22.0,
|
||||||
start_icon_width: 16.0,
|
start_icon_width: 16.0,
|
||||||
|
interact: Default::default(),
|
||||||
line_width: 1.0,
|
line_width: 1.0,
|
||||||
cursor_blink_hz: 1.0,
|
cursor_blink_hz: 1.0,
|
||||||
text_cursor_width: 2.0,
|
text_cursor_width: 2.0,
|
||||||
animation_time: 1.0 / 20.0,
|
animation_time: 1.0 / 20.0,
|
||||||
window: Window::default(),
|
window: Window::default(),
|
||||||
|
menu_bar: MenuBar::default(),
|
||||||
clip_rect_margin: 3.0,
|
clip_rect_margin: 3.0,
|
||||||
debug_widget_rects: false,
|
debug_widget_rects: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Interact {
|
||||||
|
pub active: WidgetStyle,
|
||||||
|
pub hovered: WidgetStyle,
|
||||||
|
pub inactive: WidgetStyle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Interact {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
active: WidgetStyle {
|
||||||
|
fill_color: Some(srgba(120, 120, 200, 255)),
|
||||||
|
stroke_color: WHITE,
|
||||||
|
stroke_width: 2.0,
|
||||||
|
outline: Some(Outline::new(2.0, WHITE)),
|
||||||
|
corner_radius: 5.0,
|
||||||
|
},
|
||||||
|
hovered: WidgetStyle {
|
||||||
|
fill_color: Some(srgba(100, 100, 150, 255)),
|
||||||
|
stroke_color: WHITE,
|
||||||
|
stroke_width: 1.5,
|
||||||
|
outline: None,
|
||||||
|
corner_radius: 5.0,
|
||||||
|
},
|
||||||
|
inactive: WidgetStyle {
|
||||||
|
fill_color: Some(srgba(60, 60, 80, 255)),
|
||||||
|
stroke_color: gray(220, 255), // Mustn't look grayed out!
|
||||||
|
stroke_width: 1.0,
|
||||||
|
outline: None,
|
||||||
|
corner_radius: 0.0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Interact {
|
||||||
|
pub fn style(&self, interact: &InteractInfo) -> &WidgetStyle {
|
||||||
|
if interact.active {
|
||||||
|
&self.active
|
||||||
|
} else if interact.hovered {
|
||||||
|
&self.hovered
|
||||||
|
} else {
|
||||||
|
&self.inactive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct WidgetStyle {
|
||||||
|
/// Fill color of the interactive part of a component (button, slider grab, checkbox, ...)
|
||||||
|
pub fill_color: Option<Color>,
|
||||||
|
|
||||||
|
/// Stroke and text color of the interactive part of a component (button, slider grab, checkbox, ...)
|
||||||
|
pub stroke_color: Color,
|
||||||
|
|
||||||
|
/// For lines etc
|
||||||
|
pub stroke_width: f32,
|
||||||
|
|
||||||
|
/// For rectangles
|
||||||
|
pub outline: Option<Outline>,
|
||||||
|
|
||||||
|
/// Button frames etdc
|
||||||
|
pub corner_radius: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Window {
|
||||||
|
pub corner_radius: f32,
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Window {
|
impl Default for Window {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -80,6 +151,17 @@ impl Default for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct MenuBar {
|
||||||
|
pub height: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MenuBar {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { height: 16.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Style {
|
impl Style {
|
||||||
/// e.g. the background of the slider
|
/// e.g. the background of the slider
|
||||||
pub fn background_fill_color(&self) -> Color {
|
pub fn background_fill_color(&self) -> Color {
|
||||||
|
@ -90,62 +172,9 @@ impl Style {
|
||||||
gray(255, 200)
|
gray(255, 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fill color of the interactive part of a component (button, slider grab, checkbox, ...)
|
/// Use this style for interactive things
|
||||||
pub fn interact_fill_color(&self, interact: &InteractInfo) -> Option<Color> {
|
pub fn interact(&self, interact: &InteractInfo) -> &WidgetStyle {
|
||||||
if interact.active {
|
self.interact.style(interact)
|
||||||
Some(srgba(120, 120, 200, 255))
|
|
||||||
} else if interact.hovered {
|
|
||||||
Some(srgba(100, 100, 150, 255))
|
|
||||||
} else {
|
|
||||||
Some(srgba(60, 60, 80, 255))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stroke and text color of the interactive part of a component (button, slider grab, checkbox, ...)
|
|
||||||
pub fn interact_stroke_color(&self, interact: &InteractInfo) -> Color {
|
|
||||||
if interact.active {
|
|
||||||
gray(255, 255)
|
|
||||||
} else if interact.hovered {
|
|
||||||
gray(255, 255)
|
|
||||||
} else {
|
|
||||||
gray(220, 255) // Mustn't look grayed out!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// For lines etc
|
|
||||||
pub fn interact_stroke_width(&self, interact: &InteractInfo) -> f32 {
|
|
||||||
if interact.active {
|
|
||||||
2.0
|
|
||||||
} else if interact.hovered {
|
|
||||||
1.5
|
|
||||||
} else {
|
|
||||||
1.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// For rectangles
|
|
||||||
pub fn interact_outline(&self, interact: &InteractInfo) -> Option<Outline> {
|
|
||||||
if interact.active {
|
|
||||||
Some(Outline::new(
|
|
||||||
self.interact_stroke_width(interact),
|
|
||||||
self.interact_stroke_color(interact),
|
|
||||||
))
|
|
||||||
} else if interact.hovered {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Buttons etc
|
|
||||||
pub fn interact_corner_radius(&self, interact: &InteractInfo) -> f32 {
|
|
||||||
if interact.active {
|
|
||||||
5.0
|
|
||||||
} else if interact.hovered {
|
|
||||||
5.0
|
|
||||||
} else {
|
|
||||||
0.0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns small icon rectangle and big icon rectangle
|
/// Returns small icon rectangle and big icon rectangle
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use serde_derive::Serialize;
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
color::Color,
|
color::Color,
|
||||||
|
@ -55,7 +55,7 @@ pub struct InteractInfo {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||||
pub struct Outline {
|
pub struct Outline {
|
||||||
pub width: f32,
|
pub width: f32,
|
||||||
pub color: Color,
|
pub color: Color,
|
||||||
|
@ -101,7 +101,7 @@ pub enum PaintCmd {
|
||||||
/// Top left corner of the first character.
|
/// Top left corner of the first character.
|
||||||
pos: Pos2,
|
pos: Pos2,
|
||||||
text: String,
|
text: String,
|
||||||
text_style: TextStyle,
|
text_style: TextStyle, // TODO: Font
|
||||||
/// Start each character in the text, as offset from pos.
|
/// Start each character in the text, as offset from pos.
|
||||||
x_offsets: Vec<f32>,
|
x_offsets: Vec<f32>,
|
||||||
// TODO: font info
|
// TODO: font info
|
||||||
|
|
|
@ -115,6 +115,10 @@ impl Ui {
|
||||||
&self.style
|
&self.style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_style(&mut self, style: Style) {
|
||||||
|
self.style = style
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ctx(&self) -> &Arc<Context> {
|
pub fn ctx(&self) -> &Arc<Context> {
|
||||||
&self.ctx
|
&self.ctx
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,10 @@ impl Label {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn text(&self) -> &str {
|
||||||
|
&self.text
|
||||||
|
}
|
||||||
|
|
||||||
pub fn multiline(mut self, multiline: bool) -> Self {
|
pub fn multiline(mut self, multiline: bool) -> Self {
|
||||||
self.multiline = multiline;
|
self.multiline = multiline;
|
||||||
self
|
self
|
||||||
|
@ -189,12 +193,12 @@ impl Widget for Button {
|
||||||
let mut text_cursor = interact.rect.left_center() + vec2(padding.x, -0.5 * text_size.y);
|
let mut text_cursor = interact.rect.left_center() + vec2(padding.x, -0.5 * text_size.y);
|
||||||
text_cursor.y += 2.0; // TODO: why is this needed?
|
text_cursor.y += 2.0; // TODO: why is this needed?
|
||||||
ui.add_paint_cmd(PaintCmd::Rect {
|
ui.add_paint_cmd(PaintCmd::Rect {
|
||||||
corner_radius: ui.style().interact_corner_radius(&interact),
|
corner_radius: ui.style().interact(&interact).corner_radius,
|
||||||
fill_color: ui.style().interact_fill_color(&interact),
|
fill_color: ui.style().interact(&interact).fill_color,
|
||||||
outline: ui.style().interact_outline(&interact),
|
outline: ui.style().interact(&interact).outline,
|
||||||
rect: interact.rect,
|
rect: interact.rect,
|
||||||
});
|
});
|
||||||
let stroke_color = ui.style().interact_stroke_color(&interact);
|
let stroke_color = ui.style().interact(&interact).stroke_color;
|
||||||
let text_color = self.text_color.unwrap_or(stroke_color);
|
let text_color = self.text_color.unwrap_or(stroke_color);
|
||||||
ui.add_text(text_cursor, text_style, text, Some(text_color));
|
ui.add_text(text_cursor, text_style, text, Some(text_color));
|
||||||
ui.response(interact)
|
ui.response(interact)
|
||||||
|
@ -246,12 +250,12 @@ impl<'a> Widget for Checkbox<'a> {
|
||||||
let (small_icon_rect, big_icon_rect) = ui.style().icon_rectangles(interact.rect);
|
let (small_icon_rect, big_icon_rect) = ui.style().icon_rectangles(interact.rect);
|
||||||
ui.add_paint_cmd(PaintCmd::Rect {
|
ui.add_paint_cmd(PaintCmd::Rect {
|
||||||
corner_radius: 3.0,
|
corner_radius: 3.0,
|
||||||
fill_color: ui.style().interact_fill_color(&interact),
|
fill_color: ui.style().interact(&interact).fill_color,
|
||||||
outline: None,
|
outline: None,
|
||||||
rect: big_icon_rect,
|
rect: big_icon_rect,
|
||||||
});
|
});
|
||||||
|
|
||||||
let stroke_color = ui.style().interact_stroke_color(&interact);
|
let stroke_color = ui.style().interact(&interact).stroke_color;
|
||||||
|
|
||||||
if *self.checked {
|
if *self.checked {
|
||||||
ui.add_paint_cmd(PaintCmd::Line {
|
ui.add_paint_cmd(PaintCmd::Line {
|
||||||
|
@ -315,8 +319,8 @@ impl Widget for RadioButton {
|
||||||
let text_cursor =
|
let text_cursor =
|
||||||
interact.rect.min + ui.style().button_padding + vec2(ui.style().start_icon_width, 0.0);
|
interact.rect.min + ui.style().button_padding + vec2(ui.style().start_icon_width, 0.0);
|
||||||
|
|
||||||
let fill_color = ui.style().interact_fill_color(&interact);
|
let fill_color = ui.style().interact(&interact).fill_color;
|
||||||
let stroke_color = ui.style().interact_stroke_color(&interact);
|
let stroke_color = ui.style().interact(&interact).stroke_color;
|
||||||
|
|
||||||
let (small_icon_rect, big_icon_rect) = ui.style().icon_rectangles(interact.rect);
|
let (small_icon_rect, big_icon_rect) = ui.style().icon_rectangles(interact.rect);
|
||||||
|
|
||||||
|
|
|
@ -184,10 +184,10 @@ impl<'a> Widget for Slider<'a> {
|
||||||
ui.add_paint_cmd(PaintCmd::Circle {
|
ui.add_paint_cmd(PaintCmd::Circle {
|
||||||
center: pos2(marker_center_x, rail_rect.center().y),
|
center: pos2(marker_center_x, rail_rect.center().y),
|
||||||
radius: handle_radius,
|
radius: handle_radius,
|
||||||
fill_color: ui.style().interact_fill_color(&interact),
|
fill_color: ui.style().interact(&interact).fill_color,
|
||||||
outline: Some(Outline::new(
|
outline: Some(Outline::new(
|
||||||
ui.style().interact_stroke_width(&interact),
|
ui.style().interact(&interact).stroke_width,
|
||||||
ui.style().interact_stroke_color(&interact),
|
ui.style().interact(&interact).stroke_color,
|
||||||
)),
|
)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ impl<'t> Widget for TextEdit<'t> {
|
||||||
rect: interact.rect,
|
rect: interact.rect,
|
||||||
corner_radius: 0.0,
|
corner_radius: 0.0,
|
||||||
// fill_color: Some(color::BLACK),
|
// fill_color: Some(color::BLACK),
|
||||||
fill_color: ui.style().interact_fill_color(&interact),
|
fill_color: ui.style().interact(&interact).fill_color,
|
||||||
// fill_color: Some(ui.style().background_fill_color()),
|
// fill_color: Some(ui.style().background_fill_color()),
|
||||||
outline: None, //Some(Outline::new(1.0, color::WHITE)),
|
outline: None, //Some(Outline::new(1.0, color::WHITE)),
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue