GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
Implement slider corner radius configuration
src/layout.rs | 38 ++++++++++++++++++++++++++++++++++++++
src/widget/input/button.rs | 25 +++++++++++++++----------
src/widget/input/slider.rs | 26 ++++++++++++++++++++++++++
src/widget/json_layout.rs | 24 ++++++++++++++++++++++--
src/widget/mod.rs | 2 +-
5 files changed, 102 insertions(+), 13 deletions(-)
diff --git a/src/layout.rs b/src/layout.rs
index a41baf0..7171c7b 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -102,6 +102,7 @@ static TEXTBOX_CORNER_RADIUS: RwLock<f32> = RwLock::new(4.0);
static FONT_SELECTOR_CORNER_RADIUS: RwLock<f32> = RwLock::new(4.0);
static DROPDOWN_CORNER_RADIUS: RwLock<f32> = RwLock::new(4.0);
static TOGGLE_CORNER_RADIUS: RwLock<f32> = RwLock::new(4.0);
+static SLIDER_CORNER_RADIUS: RwLock<f32> = RwLock::new(4.0);
static PLATE_CORNER_RADIUS: RwLock<f32> = RwLock::new(12.0);
static PLATE_OPACITY: RwLock<f32> = RwLock::new(1.0);
static PAGE_OPACITY: RwLock<f32> = RwLock::new(1.0);
@@ -481,6 +482,15 @@ pub fn reload_config() {
}
}
}
+ if let Some(rest) = trimmed.strip_prefix("slider_corner_radius") {
+ let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let val_str = rest.trim_end_matches('"').trim();
+ if let Ok(val) = val_str.parse::<f32>() {
+ if let Ok(mut lock) = SLIDER_CORNER_RADIUS.write() {
+ *lock = val;
+ }
+ }
+ }
}
if menubar_font_changed {
if let Ok(mut lock) = MENUBAR_FONT_CACHED.write() {
@@ -817,6 +827,34 @@ pub fn set_toggle_corner_radius(radius: f32) {
}
}
+pub fn slider_corner_radius() -> f32 {
+ use std::sync::Once;
+ static INIT: Once = Once::new();
+ INIT.call_once(|| {
+ if let Some(content) = read_config() {
+ for line in content.lines() {
+ let trimmed = line.trim();
+ if let Some(rest) = trimmed.strip_prefix("slider_corner_radius") {
+ let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let val_str = rest.trim_end_matches('"').trim();
+ if let Ok(val) = val_str.parse::<f32>() {
+ if let Ok(mut lock) = SLIDER_CORNER_RADIUS.write() {
+ *lock = val;
+ }
+ }
+ }
+ }
+ }
+ });
+ *SLIDER_CORNER_RADIUS.read().unwrap()
+}
+
+pub fn set_slider_corner_radius(radius: f32) {
+ if let Ok(mut lock) = SLIDER_CORNER_RADIUS.write() {
+ *lock = radius;
+ }
+}
+
pub fn plate_corner_radius() -> f32 {
use std::sync::Once;
static INIT: Once = Once::new();
diff --git a/src/widget/input/button.rs b/src/widget/input/button.rs
index 2099632..16e32ed 100644
--- a/src/widget/input/button.rs
+++ b/src/widget/input/button.rs
@@ -20,7 +20,7 @@ pub struct Button {
pub bg: Option<[f32; 4]>,
pub hover_bg: Option<[f32; 4]>,
pub label_color: Option<[f32; 4]>,
- pub left_align: bool,
+ pub justify: Justification,
}
impl std::fmt::Debug for Button {
@@ -48,7 +48,7 @@ impl Button {
bg: None,
hover_bg: None,
label_color: None,
- left_align: false,
+ justify: Justification::Center,
}
}
@@ -63,7 +63,7 @@ impl Button {
bg: None,
hover_bg: None,
label_color: None,
- left_align: false,
+ justify: Justification::Center,
}
}
@@ -78,7 +78,7 @@ impl Button {
bg: None,
hover_bg: None,
label_color: None,
- left_align: false,
+ justify: Justification::Center,
}
}
@@ -93,7 +93,7 @@ impl Button {
bg: None,
hover_bg: None,
label_color: None,
- left_align: false,
+ justify: Justification::Center,
}
}
@@ -128,7 +128,12 @@ impl Button {
}
pub fn with_left_align(mut self, left_align: bool) -> Self {
- self.left_align = left_align;
+ self.justify = if left_align { Justification::Left } else { Justification::Center };
+ self
+ }
+
+ pub fn with_justify(mut self, justify: Justification) -> Self {
+ self.justify = justify;
self
}
}
@@ -235,10 +240,10 @@ impl Element for Button {
_ => [0xcc, 0xcc, 0xd4]
}
};
- let x = if self.left_align {
- self.base.x + 8.0
- } else {
- self.base.x + (self.base.w - est_w) / 2.0
+ let x = match self.justify {
+ Justification::Left => self.base.x + 8.0,
+ Justification::Right => self.base.x + self.base.w - est_w - 8.0,
+ Justification::Center => self.base.x + (self.base.w - est_w) / 2.0,
};
labels.push(TextLabel {
text: label.clone(),
diff --git a/src/widget/input/slider.rs b/src/widget/input/slider.rs
index c5a5fcc..e7b06dc 100644
--- a/src/widget/input/slider.rs
+++ b/src/widget/input/slider.rs
@@ -153,6 +153,19 @@ impl Element for Slider {
Some(crate::layout::slider_height())
}
+ fn rounded_corners(&self) -> (bool, bool, bool, bool) {
+ let r = crate::layout::slider_corner_radius();
+ if r > 0.0 {
+ (true, true, true, true)
+ } else {
+ (false, false, false, false)
+ }
+ }
+
+ fn corner_radius(&self) -> f32 {
+ crate::layout::slider_corner_radius()
+ }
+
fn draggable(&self) -> bool { true }
fn is_dragging(&self) -> bool { self.dragging }
@@ -513,6 +526,19 @@ impl Element for RangeSlider {
Some(crate::layout::slider_height())
}
+ fn rounded_corners(&self) -> (bool, bool, bool, bool) {
+ let r = crate::layout::slider_corner_radius();
+ if r > 0.0 {
+ (true, true, true, true)
+ } else {
+ (false, false, false, false)
+ }
+ }
+
+ fn corner_radius(&self) -> f32 {
+ crate::layout::slider_corner_radius()
+ }
+
fn draggable(&self) -> bool { true }
fn is_dragging(&self) -> bool { self.active_thumb.is_some() }
diff --git a/src/widget/json_layout.rs b/src/widget/json_layout.rs
index d2b08e2..6c3ef5d 100644
--- a/src/widget/json_layout.rs
+++ b/src/widget/json_layout.rs
@@ -23,10 +23,19 @@ pub struct JsonWidgetConfig {
pub target_page: Option<usize>,
}
+#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[serde(rename_all = "lowercase")]
+pub enum Justification {
+ Left,
+ Center,
+ Right,
+}
+
#[derive(Deserialize, Debug, Clone)]
pub struct JsonPageConfig {
pub title: String,
pub widgets: Vec<JsonWidgetConfig>,
+ pub justify: Option<Justification>,
}
#[derive(Deserialize, Debug, Clone)]
@@ -35,6 +44,7 @@ pub struct JsonLayoutConfig {
pub height: Option<u32>,
pub widgets: Option<Vec<JsonWidgetConfig>>,
pub pages: Option<Vec<JsonPageConfig>>,
+ pub justify: Option<Justification>,
}
pub struct JsonWidget {
@@ -68,6 +78,7 @@ impl JsonLayoutWidget {
if let Some(ref pages_conf) = config.pages {
for (page_idx, page) in pages_conf.iter().enumerate() {
page_titles.push(page.title.clone());
+ let page_justify = page.justify.unwrap_or(Justification::Center);
for (idx, w_conf) in page.widgets.iter().enumerate() {
let id = w_conf.id.clone().unwrap_or_else(|| format!("widget_{}_{}", page_idx, idx));
let widget_type = w_conf.widget_type.clone();
@@ -82,7 +93,11 @@ impl JsonLayoutWidget {
Box::new(cb)
}
"button" => {
- Box::new(Button::new(0.0, 0.0, 0.0, 0.0).with_label(&text))
+ Box::new(Button::new(0.0, 0.0, 0.0, 0.0)
+ .with_label(&text)
+ .with_justify(page_justify)
+ .with_bg([0.0, 0.0, 0.0, 0.0])
+ .with_hover_bg([0.20, 0.35, 0.65, 0.9]))
}
"label" => {
Box::new(Label::new(&text).with_font_size(13.0).with_color([0xcc, 0xcc, 0xd4]))
@@ -135,6 +150,7 @@ impl JsonLayoutWidget {
}
}
} else if let Some(ref widgets_conf) = config.widgets {
+ let global_justify = config.justify.unwrap_or(Justification::Center);
for (idx, w_conf) in widgets_conf.iter().enumerate() {
let id = w_conf.id.clone().unwrap_or_else(|| format!("widget_{}", idx));
let widget_type = w_conf.widget_type.clone();
@@ -149,7 +165,11 @@ impl JsonLayoutWidget {
Box::new(cb)
}
"button" => {
- Box::new(Button::new(0.0, 0.0, 0.0, 0.0).with_label(&text))
+ Box::new(Button::new(0.0, 0.0, 0.0, 0.0)
+ .with_label(&text)
+ .with_justify(global_justify)
+ .with_bg([0.0, 0.0, 0.0, 0.0])
+ .with_hover_bg([0.20, 0.35, 0.65, 0.9]))
}
"label" => {
Box::new(Label::new(&text).with_font_size(13.0).with_color([0xcc, 0xcc, 0xd4]))
diff --git a/src/widget/mod.rs b/src/widget/mod.rs
index 1886f9f..cf6d21f 100644
--- a/src/widget/mod.rs
+++ b/src/widget/mod.rs
@@ -61,7 +61,7 @@ pub struct KeyEvent {
}
pub mod json_layout;
-pub use json_layout::{JsonLayoutWidget, JsonLayoutConfig, JsonWidgetConfig, JsonPageConfig, JsonWidget};
+pub use json_layout::{JsonLayoutWidget, JsonLayoutConfig, JsonWidgetConfig, JsonPageConfig, JsonWidget, Justification};
use crate::colors;
use std::sync::atomic::AtomicUsize;