all: remove traditional i3 titlebars, add corner rounding
This commit is contained in:
parent
e1928863d9
commit
a41dbae899
52 changed files with 1866 additions and 1047 deletions
126
src/theme.rs
126
src/theme.rs
|
|
@ -643,6 +643,95 @@ impl Into<ConfigBarPosition> for BarPosition {
|
|||
}
|
||||
}
|
||||
|
||||
/// Per-corner radius for rounded rectangles.
|
||||
///
|
||||
/// Each field specifies the radius (in logical pixels) for one corner.
|
||||
/// A radius of 0 means a square corner.
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||
pub struct CornerRadius {
|
||||
pub top_left: f32,
|
||||
pub top_right: f32,
|
||||
pub bottom_right: f32,
|
||||
pub bottom_left: f32,
|
||||
}
|
||||
|
||||
impl From<f32> for CornerRadius {
|
||||
fn from(value: f32) -> Self {
|
||||
Self {
|
||||
top_left: value,
|
||||
top_right: value,
|
||||
bottom_right: value,
|
||||
bottom_left: value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CornerRadius> for [f32; 4] {
|
||||
fn from(cr: CornerRadius) -> Self {
|
||||
[cr.top_left, cr.top_right, cr.bottom_right, cr.bottom_left]
|
||||
}
|
||||
}
|
||||
|
||||
impl CornerRadius {
|
||||
/// Shrink or grow all radii by `width`. Radii that are 0 stay 0 (square
|
||||
/// corners remain square). Negative `width` shrinks; the result is clamped
|
||||
/// to 0.
|
||||
pub fn expanded_by(mut self, width: f32) -> Self {
|
||||
if self.top_left > 0.0 {
|
||||
self.top_left = (self.top_left + width).max(0.0);
|
||||
}
|
||||
if self.top_right > 0.0 {
|
||||
self.top_right = (self.top_right + width).max(0.0);
|
||||
}
|
||||
if self.bottom_right > 0.0 {
|
||||
self.bottom_right = (self.bottom_right + width).max(0.0);
|
||||
}
|
||||
if self.bottom_left > 0.0 {
|
||||
self.bottom_left = (self.bottom_left + width).max(0.0);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Scale all radii by a factor (e.g. for HiDPI).
|
||||
pub fn scaled_by(self, scale: f32) -> Self {
|
||||
Self {
|
||||
top_left: self.top_left * scale,
|
||||
top_right: self.top_right * scale,
|
||||
bottom_right: self.bottom_right * scale,
|
||||
bottom_left: self.bottom_left * scale,
|
||||
}
|
||||
}
|
||||
|
||||
/// Reduce all radii proportionally so that adjacent corners don't overlap,
|
||||
/// following the CSS spec algorithm.
|
||||
pub fn fit_to(self, width: f32, height: f32) -> Self {
|
||||
let reduction = f32::min(
|
||||
f32::min(
|
||||
width / (self.top_left + self.top_right),
|
||||
width / (self.bottom_left + self.bottom_right),
|
||||
),
|
||||
f32::min(
|
||||
height / (self.top_left + self.bottom_left),
|
||||
height / (self.top_right + self.bottom_right),
|
||||
),
|
||||
);
|
||||
let reduction = f32::min(1.0, reduction);
|
||||
Self {
|
||||
top_left: self.top_left * reduction,
|
||||
top_right: self.top_right * reduction,
|
||||
bottom_right: self.bottom_right * reduction,
|
||||
bottom_left: self.bottom_left * reduction,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.top_left == 0.0
|
||||
&& self.top_right == 0.0
|
||||
&& self.bottom_right == 0.0
|
||||
&& self.bottom_left == 0.0
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Theme {
|
||||
pub colors: ThemeColors,
|
||||
pub sizes: ThemeSizes,
|
||||
|
|
@ -650,9 +739,12 @@ pub struct Theme {
|
|||
pub bar_font: CloneCell<Option<Arc<String>>>,
|
||||
pub title_font: CloneCell<Option<Arc<String>>>,
|
||||
pub default_font: Arc<String>,
|
||||
#[allow(dead_code)]
|
||||
pub show_titles: Cell<bool>,
|
||||
#[allow(dead_code)]
|
||||
pub floating_titles: Cell<bool>,
|
||||
pub bar_position: Cell<BarPosition>,
|
||||
pub corner_radius: Cell<CornerRadius>,
|
||||
}
|
||||
|
||||
impl Default for Theme {
|
||||
|
|
@ -668,50 +760,22 @@ impl Default for Theme {
|
|||
show_titles: Cell::new(true),
|
||||
floating_titles: Cell::new(false),
|
||||
bar_position: Default::default(),
|
||||
corner_radius: Cell::new(CornerRadius::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Theme {
|
||||
pub fn title_font(&self) -> Arc<String> {
|
||||
self.title_font.get().unwrap_or_else(|| self.font.get())
|
||||
}
|
||||
|
||||
pub fn bar_font(&self) -> Arc<String> {
|
||||
self.bar_font.get().unwrap_or_else(|| self.font.get())
|
||||
}
|
||||
|
||||
pub fn title_height(&self) -> i32 {
|
||||
if self.show_titles.get() {
|
||||
self.sizes.title_height.get()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn title_underline_height(&self) -> i32 {
|
||||
if self.show_titles.get() { 1 } else { 0 }
|
||||
}
|
||||
|
||||
pub fn floating_title_top_margin(&self) -> i32 {
|
||||
if self.floating_titles.get() && self.sizes.gap.get() != 0 {
|
||||
self.sizes.border_width.get()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
pub fn title_plus_underline_height(&self) -> i32 {
|
||||
if self.show_titles.get() {
|
||||
if self.floating_titles.get() && self.sizes.gap.get() != 0 {
|
||||
let bw = self.sizes.border_width.get();
|
||||
3 * bw + self.sizes.title_height.get() + self.sizes.title_gap.get()
|
||||
} else {
|
||||
self.sizes.title_height.get() + 1
|
||||
}
|
||||
} else {
|
||||
0
|
||||
}
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue