mirror of
https://github.com/YaLTeR/niri.git
synced 2024-09-11 20:37:25 +03:00
Merge 89d6c622cd
into a283c34dbb
This commit is contained in:
commit
8e60b4f5ce
@ -422,6 +422,8 @@ pub struct Gradient {
|
|||||||
pub angle: i16,
|
pub angle: i16,
|
||||||
#[knuffel(property, default)]
|
#[knuffel(property, default)]
|
||||||
pub relative_to: GradientRelativeTo,
|
pub relative_to: GradientRelativeTo,
|
||||||
|
#[knuffel(property(name="in"), str, default)]
|
||||||
|
pub in_: GradientInterpolation,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)]
|
#[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||||
@ -431,6 +433,30 @@ pub enum GradientRelativeTo {
|
|||||||
WorkspaceView,
|
WorkspaceView,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, Copy, PartialEq)]
|
||||||
|
pub struct GradientInterpolation {
|
||||||
|
pub color_space: GradientColorSpace,
|
||||||
|
pub hue_interpol: HueInterpolation
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum GradientColorSpace {
|
||||||
|
#[default]
|
||||||
|
Srgb,
|
||||||
|
SrgbLinear,
|
||||||
|
Oklab,
|
||||||
|
Oklch,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum HueInterpolation {
|
||||||
|
#[default]
|
||||||
|
Shorter,
|
||||||
|
Longer,
|
||||||
|
Increasing,
|
||||||
|
Decreasing,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
|
#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct Border {
|
pub struct Border {
|
||||||
#[knuffel(child)]
|
#[knuffel(child)]
|
||||||
@ -1423,6 +1449,55 @@ impl CornerRadius {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for GradientInterpolation {
|
||||||
|
type Err = miette::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let mut iter = s.split_whitespace();
|
||||||
|
let in_part1 = iter.next();
|
||||||
|
let in_part2 = iter.next();
|
||||||
|
let in_part3 = iter.next();
|
||||||
|
|
||||||
|
let color = if in_part1 != None {
|
||||||
|
let in_str = in_part1.unwrap();
|
||||||
|
match in_str {
|
||||||
|
"srgb" => GradientColorSpace::Srgb,
|
||||||
|
"srgb-linear" => GradientColorSpace::SrgbLinear,
|
||||||
|
"oklab" => GradientColorSpace::Oklab,
|
||||||
|
"oklch" => GradientColorSpace::Oklch,
|
||||||
|
&_ => return Err(miette!("Invalid color-space: {in_str}"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GradientColorSpace::Srgb
|
||||||
|
};
|
||||||
|
|
||||||
|
let interpolation = if in_part2 != None {
|
||||||
|
let in_str = in_part2.unwrap();
|
||||||
|
if color != GradientColorSpace::Oklch {
|
||||||
|
return Err(miette!("There's a value: {in_str} after a non polar colorspace"))
|
||||||
|
}
|
||||||
|
if in_part3 == None || in_part3.unwrap() != "hue" {
|
||||||
|
return Err(miette!("Invalid hue-interpolation: {in_str} you may be missing 'hue' at the end."))
|
||||||
|
} else if iter.next() == None {
|
||||||
|
match in_str {
|
||||||
|
"shorter" => HueInterpolation::Shorter,
|
||||||
|
"longer" => HueInterpolation::Longer,
|
||||||
|
"increasing" => HueInterpolation::Increasing,
|
||||||
|
"decreasing" => HueInterpolation::Decreasing,
|
||||||
|
&_ => return Err(miette!("Invalid hue-interpolation: {in_str}"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this is a placeholder and should be changed if anything is added to in
|
||||||
|
return Err(miette!("Theres a missing indicator ’hue’ from ’in’ "))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HueInterpolation::Shorter
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok( Self { color_space: color, hue_interpol: interpolation } )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for Color {
|
impl FromStr for Color {
|
||||||
type Err = miette::Error;
|
type Err = miette::Error;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use niri::animation::ANIMATION_SLOWDOWN;
|
use niri::animation::ANIMATION_SLOWDOWN;
|
||||||
use niri::render_helpers::border::BorderRenderElement;
|
use niri::render_helpers::border::BorderRenderElement;
|
||||||
use niri_config::CornerRadius;
|
use niri_config::{CornerRadius, GradientInterpolation};
|
||||||
use smithay::backend::renderer::element::RenderElement;
|
use smithay::backend::renderer::element::RenderElement;
|
||||||
use smithay::backend::renderer::gles::GlesRenderer;
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
use smithay::utils::{Logical, Physical, Rectangle, Size};
|
use smithay::utils::{Logical, Physical, Rectangle, Size};
|
||||||
@ -64,6 +64,7 @@ impl TestCase for GradientAngle {
|
|||||||
[BorderRenderElement::new(
|
[BorderRenderElement::new(
|
||||||
area.size,
|
area.size,
|
||||||
Rectangle::from_loc_and_size((0., 0.), area.size),
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
GradientInterpolation::default(),
|
||||||
[1., 0., 0., 1.],
|
[1., 0., 0., 1.],
|
||||||
[0., 1., 0., 1.],
|
[0., 1., 0., 1.],
|
||||||
self.angle - FRAC_PI_2,
|
self.angle - FRAC_PI_2,
|
||||||
|
@ -5,7 +5,7 @@ use std::time::Duration;
|
|||||||
use niri::animation::ANIMATION_SLOWDOWN;
|
use niri::animation::ANIMATION_SLOWDOWN;
|
||||||
use niri::layout::focus_ring::FocusRing;
|
use niri::layout::focus_ring::FocusRing;
|
||||||
use niri::render_helpers::border::BorderRenderElement;
|
use niri::render_helpers::border::BorderRenderElement;
|
||||||
use niri_config::{Color, CornerRadius, FloatOrInt};
|
use niri_config::{Color, CornerRadius, FloatOrInt, GradientInterpolation};
|
||||||
use smithay::backend::renderer::element::RenderElement;
|
use smithay::backend::renderer::element::RenderElement;
|
||||||
use smithay::backend::renderer::gles::GlesRenderer;
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
use smithay::utils::{Logical, Physical, Point, Rectangle, Size};
|
use smithay::utils::{Logical, Physical, Point, Rectangle, Size};
|
||||||
@ -104,6 +104,7 @@ impl TestCase for GradientArea {
|
|||||||
[BorderRenderElement::new(
|
[BorderRenderElement::new(
|
||||||
area.size,
|
area.size,
|
||||||
g_area,
|
g_area,
|
||||||
|
GradientInterpolation::default(),
|
||||||
[1., 0., 0., 1.],
|
[1., 0., 0., 1.],
|
||||||
[0., 1., 0., 1.],
|
[0., 1., 0., 1.],
|
||||||
FRAC_PI_4,
|
FRAC_PI_4,
|
||||||
|
51
niri-visual-tests/src/cases/gradient_oklab.rs
Normal file
51
niri-visual-tests/src/cases/gradient_oklab.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
use niri::render_helpers::border::BorderRenderElement;
|
||||||
|
use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace};
|
||||||
|
use smithay::backend::renderer::element::RenderElement;
|
||||||
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
|
use smithay::utils::{Logical, Physical, Rectangle, Size};
|
||||||
|
|
||||||
|
use super::TestCase;
|
||||||
|
|
||||||
|
pub struct GradientOklab {
|
||||||
|
gradient_format: GradientInterpolation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GradientOklab {
|
||||||
|
pub fn new(_size: Size<i32, Logical>) -> Self {
|
||||||
|
Self {
|
||||||
|
gradient_format: GradientInterpolation{
|
||||||
|
color_space: GradientColorSpace::Oklab,
|
||||||
|
hue_interpol: HueInterpolation::Shorter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for GradientOklab {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_renderer: &mut GlesRenderer,
|
||||||
|
size: Size<i32, Physical>,
|
||||||
|
) -> Vec<Box<dyn RenderElement<GlesRenderer>>> {
|
||||||
|
let (a, b) = (size.w / 6, size.h / 3);
|
||||||
|
let size = (size.w - a * 2, size.h - b * 2);
|
||||||
|
let area = Rectangle::from_loc_and_size((a, b), size).to_f64();
|
||||||
|
|
||||||
|
[BorderRenderElement::new(
|
||||||
|
area.size,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
self.gradient_format,
|
||||||
|
[1., 0., 0., 1.],
|
||||||
|
[0., 1., 0., 1.],
|
||||||
|
0.,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
0.,
|
||||||
|
CornerRadius::default(),
|
||||||
|
1.,
|
||||||
|
)
|
||||||
|
.with_location(area.loc)]
|
||||||
|
.into_iter()
|
||||||
|
.map(|elem| Box::new(elem) as _)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
51
niri-visual-tests/src/cases/gradient_oklch_decreasing.rs
Normal file
51
niri-visual-tests/src/cases/gradient_oklch_decreasing.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
use niri::render_helpers::border::BorderRenderElement;
|
||||||
|
use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace};
|
||||||
|
use smithay::backend::renderer::element::RenderElement;
|
||||||
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
|
use smithay::utils::{Logical, Physical, Rectangle, Size};
|
||||||
|
|
||||||
|
use super::TestCase;
|
||||||
|
|
||||||
|
pub struct GradientOklchDecreasing {
|
||||||
|
gradient_format: GradientInterpolation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GradientOklchDecreasing {
|
||||||
|
pub fn new(_size: Size<i32, Logical>) -> Self {
|
||||||
|
Self {
|
||||||
|
gradient_format: GradientInterpolation{
|
||||||
|
color_space: GradientColorSpace::Oklch,
|
||||||
|
hue_interpol: HueInterpolation::Decreasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for GradientOklchDecreasing {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_renderer: &mut GlesRenderer,
|
||||||
|
size: Size<i32, Physical>,
|
||||||
|
) -> Vec<Box<dyn RenderElement<GlesRenderer>>> {
|
||||||
|
let (a, b) = (size.w / 6, size.h / 3);
|
||||||
|
let size = (size.w - a * 2, size.h - b * 2);
|
||||||
|
let area = Rectangle::from_loc_and_size((a, b), size).to_f64();
|
||||||
|
|
||||||
|
[BorderRenderElement::new(
|
||||||
|
area.size,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
self.gradient_format,
|
||||||
|
[1., 0., 0., 1.],
|
||||||
|
[0., 1., 0., 1.],
|
||||||
|
0.,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
0.,
|
||||||
|
CornerRadius::default(),
|
||||||
|
1.,
|
||||||
|
)
|
||||||
|
.with_location(area.loc)]
|
||||||
|
.into_iter()
|
||||||
|
.map(|elem| Box::new(elem) as _)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
51
niri-visual-tests/src/cases/gradient_oklch_increasing.rs
Normal file
51
niri-visual-tests/src/cases/gradient_oklch_increasing.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
use niri::render_helpers::border::BorderRenderElement;
|
||||||
|
use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace};
|
||||||
|
use smithay::backend::renderer::element::RenderElement;
|
||||||
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
|
use smithay::utils::{Logical, Physical, Rectangle, Size};
|
||||||
|
|
||||||
|
use super::TestCase;
|
||||||
|
|
||||||
|
pub struct GradientOklchIncreasing {
|
||||||
|
gradient_format: GradientInterpolation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GradientOklchIncreasing {
|
||||||
|
pub fn new(_size: Size<i32, Logical>) -> Self {
|
||||||
|
Self {
|
||||||
|
gradient_format: GradientInterpolation{
|
||||||
|
color_space: GradientColorSpace::Oklch,
|
||||||
|
hue_interpol: HueInterpolation::Increasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for GradientOklchIncreasing {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_renderer: &mut GlesRenderer,
|
||||||
|
size: Size<i32, Physical>,
|
||||||
|
) -> Vec<Box<dyn RenderElement<GlesRenderer>>> {
|
||||||
|
let (a, b) = (size.w / 6, size.h / 3);
|
||||||
|
let size = (size.w - a * 2, size.h - b * 2);
|
||||||
|
let area = Rectangle::from_loc_and_size((a, b), size).to_f64();
|
||||||
|
|
||||||
|
[BorderRenderElement::new(
|
||||||
|
area.size,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
self.gradient_format,
|
||||||
|
[1., 0., 0., 1.],
|
||||||
|
[0., 1., 0., 1.],
|
||||||
|
0.,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
0.,
|
||||||
|
CornerRadius::default(),
|
||||||
|
1.,
|
||||||
|
)
|
||||||
|
.with_location(area.loc)]
|
||||||
|
.into_iter()
|
||||||
|
.map(|elem| Box::new(elem) as _)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
51
niri-visual-tests/src/cases/gradient_oklch_longer.rs
Normal file
51
niri-visual-tests/src/cases/gradient_oklch_longer.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
use niri::render_helpers::border::BorderRenderElement;
|
||||||
|
use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace};
|
||||||
|
use smithay::backend::renderer::element::RenderElement;
|
||||||
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
|
use smithay::utils::{Logical, Physical, Rectangle, Size};
|
||||||
|
|
||||||
|
use super::TestCase;
|
||||||
|
|
||||||
|
pub struct GradientOklchLonger {
|
||||||
|
gradient_format: GradientInterpolation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GradientOklchLonger {
|
||||||
|
pub fn new(_size: Size<i32, Logical>) -> Self {
|
||||||
|
Self {
|
||||||
|
gradient_format: GradientInterpolation{
|
||||||
|
color_space: GradientColorSpace::Oklch,
|
||||||
|
hue_interpol: HueInterpolation::Longer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for GradientOklchLonger {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_renderer: &mut GlesRenderer,
|
||||||
|
size: Size<i32, Physical>,
|
||||||
|
) -> Vec<Box<dyn RenderElement<GlesRenderer>>> {
|
||||||
|
let (a, b) = (size.w / 6, size.h / 3);
|
||||||
|
let size = (size.w - a * 2, size.h - b * 2);
|
||||||
|
let area = Rectangle::from_loc_and_size((a, b), size).to_f64();
|
||||||
|
|
||||||
|
[BorderRenderElement::new(
|
||||||
|
area.size,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
self.gradient_format,
|
||||||
|
[1., 0., 0., 1.],
|
||||||
|
[0., 1., 0., 1.],
|
||||||
|
0.,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
0.,
|
||||||
|
CornerRadius::default(),
|
||||||
|
1.,
|
||||||
|
)
|
||||||
|
.with_location(area.loc)]
|
||||||
|
.into_iter()
|
||||||
|
.map(|elem| Box::new(elem) as _)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
51
niri-visual-tests/src/cases/gradient_oklch_shorter.rs
Normal file
51
niri-visual-tests/src/cases/gradient_oklch_shorter.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
use niri::render_helpers::border::BorderRenderElement;
|
||||||
|
use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace};
|
||||||
|
use smithay::backend::renderer::element::RenderElement;
|
||||||
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
|
use smithay::utils::{Logical, Physical, Rectangle, Size};
|
||||||
|
|
||||||
|
use super::TestCase;
|
||||||
|
|
||||||
|
pub struct GradientOklchShorter {
|
||||||
|
gradient_format: GradientInterpolation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GradientOklchShorter {
|
||||||
|
pub fn new(_size: Size<i32, Logical>) -> Self {
|
||||||
|
Self {
|
||||||
|
gradient_format: GradientInterpolation{
|
||||||
|
color_space: GradientColorSpace::Oklch,
|
||||||
|
hue_interpol: HueInterpolation::Shorter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for GradientOklchShorter {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_renderer: &mut GlesRenderer,
|
||||||
|
size: Size<i32, Physical>,
|
||||||
|
) -> Vec<Box<dyn RenderElement<GlesRenderer>>> {
|
||||||
|
let (a, b) = (size.w / 6, size.h / 3);
|
||||||
|
let size = (size.w - a * 2, size.h - b * 2);
|
||||||
|
let area = Rectangle::from_loc_and_size((a, b), size).to_f64();
|
||||||
|
|
||||||
|
[BorderRenderElement::new(
|
||||||
|
area.size,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
self.gradient_format,
|
||||||
|
[1., 0., 0., 1.],
|
||||||
|
[0., 1., 0., 1.],
|
||||||
|
0.,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
0.,
|
||||||
|
CornerRadius::default(),
|
||||||
|
1.,
|
||||||
|
)
|
||||||
|
.with_location(area.loc)]
|
||||||
|
.into_iter()
|
||||||
|
.map(|elem| Box::new(elem) as _)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
51
niri-visual-tests/src/cases/gradient_srgb.rs
Normal file
51
niri-visual-tests/src/cases/gradient_srgb.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
use niri::render_helpers::border::BorderRenderElement;
|
||||||
|
use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace};
|
||||||
|
use smithay::backend::renderer::element::RenderElement;
|
||||||
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
|
use smithay::utils::{Logical, Physical, Rectangle, Size};
|
||||||
|
|
||||||
|
use super::TestCase;
|
||||||
|
|
||||||
|
pub struct GradientSrgb {
|
||||||
|
gradient_format: GradientInterpolation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GradientSrgb {
|
||||||
|
pub fn new(_size: Size<i32, Logical>) -> Self {
|
||||||
|
Self {
|
||||||
|
gradient_format: GradientInterpolation{
|
||||||
|
color_space: GradientColorSpace::Srgb,
|
||||||
|
hue_interpol: HueInterpolation::Shorter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for GradientSrgb {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_renderer: &mut GlesRenderer,
|
||||||
|
size: Size<i32, Physical>,
|
||||||
|
) -> Vec<Box<dyn RenderElement<GlesRenderer>>> {
|
||||||
|
let (a, b) = (size.w / 6, size.h / 3);
|
||||||
|
let size = (size.w - a * 2, size.h - b * 2);
|
||||||
|
let area = Rectangle::from_loc_and_size((a, b), size).to_f64();
|
||||||
|
|
||||||
|
[BorderRenderElement::new(
|
||||||
|
area.size,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
self.gradient_format,
|
||||||
|
[1., 0., 0., 1.],
|
||||||
|
[0., 1., 0., 1.],
|
||||||
|
0.,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
0.,
|
||||||
|
CornerRadius::default(),
|
||||||
|
1.,
|
||||||
|
)
|
||||||
|
.with_location(area.loc)]
|
||||||
|
.into_iter()
|
||||||
|
.map(|elem| Box::new(elem) as _)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
51
niri-visual-tests/src/cases/gradient_srgblinear.rs
Normal file
51
niri-visual-tests/src/cases/gradient_srgblinear.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
use niri::render_helpers::border::BorderRenderElement;
|
||||||
|
use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace};
|
||||||
|
use smithay::backend::renderer::element::RenderElement;
|
||||||
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
|
use smithay::utils::{Logical, Physical, Rectangle, Size};
|
||||||
|
|
||||||
|
use super::TestCase;
|
||||||
|
|
||||||
|
pub struct GradientSrgbLinear {
|
||||||
|
gradient_format: GradientInterpolation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GradientSrgbLinear {
|
||||||
|
pub fn new(_size: Size<i32, Logical>) -> Self {
|
||||||
|
Self {
|
||||||
|
gradient_format: GradientInterpolation{
|
||||||
|
color_space: GradientColorSpace::SrgbLinear,
|
||||||
|
hue_interpol: HueInterpolation::Shorter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for GradientSrgbLinear {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_renderer: &mut GlesRenderer,
|
||||||
|
size: Size<i32, Physical>,
|
||||||
|
) -> Vec<Box<dyn RenderElement<GlesRenderer>>> {
|
||||||
|
let (a, b) = (size.w / 6, size.h / 3);
|
||||||
|
let size = (size.w - a * 2, size.h - b * 2);
|
||||||
|
let area = Rectangle::from_loc_and_size((a, b), size).to_f64();
|
||||||
|
|
||||||
|
[BorderRenderElement::new(
|
||||||
|
area.size,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
self.gradient_format,
|
||||||
|
[1., 0., 0., 1.],
|
||||||
|
[0., 1., 0., 1.],
|
||||||
|
0.,
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), area.size),
|
||||||
|
0.,
|
||||||
|
CornerRadius::default(),
|
||||||
|
1.,
|
||||||
|
)
|
||||||
|
.with_location(area.loc)]
|
||||||
|
.into_iter()
|
||||||
|
.map(|elem| Box::new(elem) as _)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,13 @@ use smithay::utils::{Physical, Size};
|
|||||||
|
|
||||||
pub mod gradient_angle;
|
pub mod gradient_angle;
|
||||||
pub mod gradient_area;
|
pub mod gradient_area;
|
||||||
|
pub mod gradient_srgb;
|
||||||
|
pub mod gradient_srgblinear;
|
||||||
|
pub mod gradient_oklab;
|
||||||
|
pub mod gradient_oklch_shorter;
|
||||||
|
pub mod gradient_oklch_longer;
|
||||||
|
pub mod gradient_oklch_increasing;
|
||||||
|
pub mod gradient_oklch_decreasing;
|
||||||
pub mod layout;
|
pub mod layout;
|
||||||
pub mod tile;
|
pub mod tile;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
|
@ -18,6 +18,13 @@ use tracing_subscriber::EnvFilter;
|
|||||||
|
|
||||||
use crate::cases::gradient_angle::GradientAngle;
|
use crate::cases::gradient_angle::GradientAngle;
|
||||||
use crate::cases::gradient_area::GradientArea;
|
use crate::cases::gradient_area::GradientArea;
|
||||||
|
use crate::cases::gradient_srgb::GradientSrgb;
|
||||||
|
use crate::cases::gradient_srgblinear::GradientSrgbLinear;
|
||||||
|
use crate::cases::gradient_oklab::GradientOklab;
|
||||||
|
use crate::cases::gradient_oklch_shorter::GradientOklchShorter;
|
||||||
|
use crate::cases::gradient_oklch_longer::GradientOklchLonger;
|
||||||
|
use crate::cases::gradient_oklch_increasing::GradientOklchIncreasing;
|
||||||
|
use crate::cases::gradient_oklch_decreasing::GradientOklchDecreasing;
|
||||||
use crate::cases::layout::Layout;
|
use crate::cases::layout::Layout;
|
||||||
use crate::cases::TestCase;
|
use crate::cases::TestCase;
|
||||||
|
|
||||||
@ -112,6 +119,13 @@ fn build_ui(app: &adw::Application) {
|
|||||||
|
|
||||||
s.add(GradientAngle::new, "Gradient - Angle");
|
s.add(GradientAngle::new, "Gradient - Angle");
|
||||||
s.add(GradientArea::new, "Gradient - Area");
|
s.add(GradientArea::new, "Gradient - Area");
|
||||||
|
s.add(GradientSrgb::new, "Gradient - Srgb");
|
||||||
|
s.add(GradientSrgbLinear::new, "Gradient - SrgbLinear");
|
||||||
|
s.add(GradientOklab::new, "Gradient - Oklab");
|
||||||
|
s.add(GradientOklchShorter::new, "Gradient - Oklch Shorter");
|
||||||
|
s.add(GradientOklchLonger::new, "Gradient - Oklch Longer");
|
||||||
|
s.add(GradientOklchIncreasing::new, "Gradient - Oklch Increasing");
|
||||||
|
s.add(GradientOklchDecreasing::new, "Gradient - Oklch Decreasing");
|
||||||
|
|
||||||
let content_headerbar = adw::HeaderBar::new();
|
let content_headerbar = adw::HeaderBar::new();
|
||||||
|
|
||||||
|
@ -153,6 +153,7 @@ layout {
|
|||||||
// The angle is the same as in linear-gradient, and is optional,
|
// The angle is the same as in linear-gradient, and is optional,
|
||||||
// defaulting to 180 (top-to-bottom gradient).
|
// defaulting to 180 (top-to-bottom gradient).
|
||||||
// You can use any CSS linear-gradient tool on the web to set these up.
|
// You can use any CSS linear-gradient tool on the web to set these up.
|
||||||
|
// Changing the color space is also supported, check the wiki for more info.
|
||||||
//
|
//
|
||||||
// active-gradient from="#80c8ff" to="#bbddff" angle=45
|
// active-gradient from="#80c8ff" to="#bbddff" angle=45
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::iter::zip;
|
use std::iter::zip;
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use niri_config::{CornerRadius, Gradient, GradientRelativeTo};
|
use niri_config::{CornerRadius, Gradient, GradientRelativeTo, GradientInterpolation};
|
||||||
use smithay::backend::renderer::element::Kind;
|
use smithay::backend::renderer::element::Kind;
|
||||||
use smithay::utils::{Logical, Point, Rectangle, Size};
|
use smithay::utils::{Logical, Point, Rectangle, Size};
|
||||||
|
|
||||||
@ -91,6 +91,7 @@ impl FocusRing {
|
|||||||
to: color,
|
to: color,
|
||||||
angle: 0,
|
angle: 0,
|
||||||
relative_to: GradientRelativeTo::Window,
|
relative_to: GradientRelativeTo::Window,
|
||||||
|
in_: GradientInterpolation::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
let full_rect = Rectangle::from_loc_and_size((-width, -width), self.full_size);
|
let full_rect = Rectangle::from_loc_and_size((-width, -width), self.full_size);
|
||||||
@ -178,6 +179,7 @@ impl FocusRing {
|
|||||||
border.update(
|
border.update(
|
||||||
size,
|
size,
|
||||||
Rectangle::from_loc_and_size(gradient_area.loc - loc, gradient_area.size),
|
Rectangle::from_loc_and_size(gradient_area.loc - loc, gradient_area.size),
|
||||||
|
gradient.in_,
|
||||||
gradient.from.into(),
|
gradient.from.into(),
|
||||||
gradient.to.into(),
|
gradient.to.into(),
|
||||||
((gradient.angle as f32) - 90.).to_radians(),
|
((gradient.angle as f32) - 90.).to_radians(),
|
||||||
@ -198,6 +200,7 @@ impl FocusRing {
|
|||||||
gradient_area.loc - self.locations[0],
|
gradient_area.loc - self.locations[0],
|
||||||
gradient_area.size,
|
gradient_area.size,
|
||||||
),
|
),
|
||||||
|
gradient.in_,
|
||||||
gradient.from.into(),
|
gradient.from.into(),
|
||||||
gradient.to.into(),
|
gradient.to.into(),
|
||||||
((gradient.angle as f32) - 90.).to_radians(),
|
((gradient.angle as f32) - 90.).to_radians(),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use niri_config::CornerRadius;
|
use niri_config::{CornerRadius, GradientInterpolation};
|
||||||
use smithay::backend::allocator::Fourcc;
|
use smithay::backend::allocator::Fourcc;
|
||||||
use smithay::backend::renderer::element::{Element, Kind};
|
use smithay::backend::renderer::element::{Element, Kind};
|
||||||
use smithay::backend::renderer::gles::GlesRenderer;
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
@ -757,6 +757,7 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
return BorderRenderElement::new(
|
return BorderRenderElement::new(
|
||||||
geo.size,
|
geo.size,
|
||||||
Rectangle::from_loc_and_size((0., 0.), geo.size),
|
Rectangle::from_loc_and_size((0., 0.), geo.size),
|
||||||
|
GradientInterpolation::default(),
|
||||||
elem.color(),
|
elem.color(),
|
||||||
elem.color(),
|
elem.color(),
|
||||||
0.,
|
0.,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use glam::{Mat3, Vec2};
|
use glam::{Mat3, Vec2};
|
||||||
use niri_config::CornerRadius;
|
use niri_config::{CornerRadius, GradientInterpolation, GradientColorSpace, HueInterpolation};
|
||||||
use smithay::backend::renderer::element::{Element, Id, Kind, RenderElement, UnderlyingStorage};
|
use smithay::backend::renderer::element::{Element, Id, Kind, RenderElement, UnderlyingStorage};
|
||||||
use smithay::backend::renderer::gles::{GlesError, GlesFrame, GlesRenderer, Uniform};
|
use smithay::backend::renderer::gles::{GlesError, GlesFrame, GlesRenderer, Uniform};
|
||||||
use smithay::backend::renderer::utils::{CommitCounter, DamageSet, OpaqueRegions};
|
use smithay::backend::renderer::utils::{CommitCounter, DamageSet, OpaqueRegions};
|
||||||
@ -28,6 +28,7 @@ pub struct BorderRenderElement {
|
|||||||
struct Parameters {
|
struct Parameters {
|
||||||
size: Size<f64, Logical>,
|
size: Size<f64, Logical>,
|
||||||
gradient_area: Rectangle<f64, Logical>,
|
gradient_area: Rectangle<f64, Logical>,
|
||||||
|
gradient_format: GradientInterpolation,
|
||||||
color_from: [f32; 4],
|
color_from: [f32; 4],
|
||||||
color_to: [f32; 4],
|
color_to: [f32; 4],
|
||||||
angle: f32,
|
angle: f32,
|
||||||
@ -43,6 +44,7 @@ impl BorderRenderElement {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
size: Size<f64, Logical>,
|
size: Size<f64, Logical>,
|
||||||
gradient_area: Rectangle<f64, Logical>,
|
gradient_area: Rectangle<f64, Logical>,
|
||||||
|
gradient_format: GradientInterpolation,
|
||||||
color_from: [f32; 4],
|
color_from: [f32; 4],
|
||||||
color_to: [f32; 4],
|
color_to: [f32; 4],
|
||||||
angle: f32,
|
angle: f32,
|
||||||
@ -57,6 +59,7 @@ impl BorderRenderElement {
|
|||||||
params: Parameters {
|
params: Parameters {
|
||||||
size,
|
size,
|
||||||
gradient_area,
|
gradient_area,
|
||||||
|
gradient_format,
|
||||||
color_from,
|
color_from,
|
||||||
color_to,
|
color_to,
|
||||||
angle,
|
angle,
|
||||||
@ -77,6 +80,7 @@ impl BorderRenderElement {
|
|||||||
params: Parameters {
|
params: Parameters {
|
||||||
size: Default::default(),
|
size: Default::default(),
|
||||||
gradient_area: Default::default(),
|
gradient_area: Default::default(),
|
||||||
|
gradient_format: GradientInterpolation::default(),
|
||||||
color_from: Default::default(),
|
color_from: Default::default(),
|
||||||
color_to: Default::default(),
|
color_to: Default::default(),
|
||||||
angle: 0.,
|
angle: 0.,
|
||||||
@ -97,6 +101,7 @@ impl BorderRenderElement {
|
|||||||
&mut self,
|
&mut self,
|
||||||
size: Size<f64, Logical>,
|
size: Size<f64, Logical>,
|
||||||
gradient_area: Rectangle<f64, Logical>,
|
gradient_area: Rectangle<f64, Logical>,
|
||||||
|
gradient_format: GradientInterpolation,
|
||||||
color_from: [f32; 4],
|
color_from: [f32; 4],
|
||||||
color_to: [f32; 4],
|
color_to: [f32; 4],
|
||||||
angle: f32,
|
angle: f32,
|
||||||
@ -108,6 +113,7 @@ impl BorderRenderElement {
|
|||||||
let params = Parameters {
|
let params = Parameters {
|
||||||
size,
|
size,
|
||||||
gradient_area,
|
gradient_area,
|
||||||
|
gradient_format,
|
||||||
color_from,
|
color_from,
|
||||||
color_to,
|
color_to,
|
||||||
angle,
|
angle,
|
||||||
@ -128,6 +134,7 @@ impl BorderRenderElement {
|
|||||||
let Parameters {
|
let Parameters {
|
||||||
size,
|
size,
|
||||||
gradient_area,
|
gradient_area,
|
||||||
|
gradient_format,
|
||||||
color_from,
|
color_from,
|
||||||
color_to,
|
color_to,
|
||||||
angle,
|
angle,
|
||||||
@ -162,11 +169,27 @@ impl BorderRenderElement {
|
|||||||
let input_to_geo =
|
let input_to_geo =
|
||||||
Mat3::from_scale(area_size) * Mat3::from_translation(-geo_loc / area_size);
|
Mat3::from_scale(area_size) * Mat3::from_translation(-geo_loc / area_size);
|
||||||
|
|
||||||
|
let colorspace = match gradient_format.color_space {
|
||||||
|
GradientColorSpace::Srgb => 0.,
|
||||||
|
GradientColorSpace::SrgbLinear => 1.,
|
||||||
|
GradientColorSpace::Oklab => 2.,
|
||||||
|
GradientColorSpace::Oklch => 3.,
|
||||||
|
};
|
||||||
|
|
||||||
|
let hue_interpolation = match gradient_format.hue_interpol {
|
||||||
|
HueInterpolation::Shorter => 0.,
|
||||||
|
HueInterpolation::Longer => 1.,
|
||||||
|
HueInterpolation::Increasing => 2.,
|
||||||
|
HueInterpolation::Decreasing => 3.,
|
||||||
|
};
|
||||||
|
|
||||||
self.inner.update(
|
self.inner.update(
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
scale,
|
scale,
|
||||||
vec![
|
vec![
|
||||||
|
Uniform::new("colorspace", colorspace),
|
||||||
|
Uniform::new("hue_interpolation", hue_interpolation),
|
||||||
Uniform::new("color_from", color_from),
|
Uniform::new("color_from", color_from),
|
||||||
Uniform::new("color_to", color_to),
|
Uniform::new("color_to", color_to),
|
||||||
Uniform::new("grad_offset", grad_offset.to_array()),
|
Uniform::new("grad_offset", grad_offset.to_array()),
|
||||||
|
@ -10,6 +10,8 @@ uniform float niri_scale;
|
|||||||
uniform vec2 niri_size;
|
uniform vec2 niri_size;
|
||||||
varying vec2 niri_v_coords;
|
varying vec2 niri_v_coords;
|
||||||
|
|
||||||
|
uniform float colorspace;
|
||||||
|
uniform float hue_interpolation;
|
||||||
uniform vec4 color_from;
|
uniform vec4 color_from;
|
||||||
uniform vec4 color_to;
|
uniform vec4 color_to;
|
||||||
uniform vec2 grad_offset;
|
uniform vec2 grad_offset;
|
||||||
@ -21,6 +23,174 @@ uniform vec2 geo_size;
|
|||||||
uniform vec4 outer_radius;
|
uniform vec4 outer_radius;
|
||||||
uniform float border_width;
|
uniform float border_width;
|
||||||
|
|
||||||
|
float srgb_to_linear(float color) {
|
||||||
|
return pow(color, 2.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float linear_to_srgb(float color) {
|
||||||
|
return pow(color, 1.0 / 2.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 lab_to_lch(vec3 color) {
|
||||||
|
float c = sqrt(pow(color.y, 2.0) + pow(color.z, 2.0));
|
||||||
|
float h = degrees(atan(color.z, color.y)) ;
|
||||||
|
h += h <= 0.0 ?
|
||||||
|
360.0 :
|
||||||
|
0.0 ;
|
||||||
|
return vec3(
|
||||||
|
color.x,
|
||||||
|
c,
|
||||||
|
h
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 lch_to_lab(vec3 color) {
|
||||||
|
float a = color.y * clamp(cos(radians(color.z)), -1.0, 1.0);
|
||||||
|
float b = color.y * clamp(sin(radians(color.z)), -1.0, 1.0);
|
||||||
|
return vec3(
|
||||||
|
color.x,
|
||||||
|
a,
|
||||||
|
b
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 linear_to_oklab(vec3 color){
|
||||||
|
mat3 rgb_to_lms = mat3(
|
||||||
|
vec3(0.4122214708, 0.5363325363, 0.0514459929),
|
||||||
|
vec3(0.2119034982, 0.6806995451, 0.1073969566),
|
||||||
|
vec3(0.0883024619, 0.2817188376, 0.6299787005)
|
||||||
|
);
|
||||||
|
mat3 lms_to_oklab = mat3(
|
||||||
|
vec3(0.2104542553, 0.7936177850, -0.0040720468),
|
||||||
|
vec3(1.9779984951, -2.4285922050, 0.4505937099),
|
||||||
|
vec3(0.0259040371, 0.7827717662, -0.8086757660)
|
||||||
|
);
|
||||||
|
vec3 lms = color * rgb_to_lms;
|
||||||
|
|
||||||
|
lms = vec3(
|
||||||
|
pow(lms.x, 1.0 / 3.0),
|
||||||
|
pow(lms.y, 1.0 / 3.0),
|
||||||
|
pow(lms.z, 1.0 / 3.0)
|
||||||
|
);
|
||||||
|
return lms * lms_to_oklab;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 oklab_to_linear(vec3 color){
|
||||||
|
mat3 oklab_to_lms = mat3(
|
||||||
|
vec3(1.0, 0.3963377774, 0.2158037573),
|
||||||
|
vec3(1.0, -0.1055613458, -0.0638541728),
|
||||||
|
vec3(1.0, -0.0894841775, -1.2914855480)
|
||||||
|
);
|
||||||
|
mat3 lms_to_rgb = mat3(
|
||||||
|
vec3(4.0767416621, -3.3077115913, 0.2309699292),
|
||||||
|
vec3(-1.2684380046, 2.6097574011, -0.3413193965),
|
||||||
|
vec3(-0.0041960863, -0.7034186147, 1.7076147010)
|
||||||
|
);
|
||||||
|
vec3 lms = color * oklab_to_lms;
|
||||||
|
|
||||||
|
lms = vec3(
|
||||||
|
pow(lms.x, 3.0),
|
||||||
|
pow(lms.y, 3.0),
|
||||||
|
pow(lms.z, 3.0)
|
||||||
|
);
|
||||||
|
return lms * lms_to_rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) {
|
||||||
|
// srgb
|
||||||
|
|
||||||
|
if (colorspace == 0.0) {
|
||||||
|
return mix(color1, color2, color_ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 color_out;
|
||||||
|
|
||||||
|
color1.rgb /= color1.a != 0.0 ? color1.a : 1.0;
|
||||||
|
color2.rgb /= color2.a != 0.0 ? color2.a : 1.0;
|
||||||
|
|
||||||
|
color1.rgb = vec3(
|
||||||
|
srgb_to_linear(color1.r),
|
||||||
|
srgb_to_linear(color1.g),
|
||||||
|
srgb_to_linear(color1.b)
|
||||||
|
);
|
||||||
|
color2.rgb = vec3(
|
||||||
|
srgb_to_linear(color2.r),
|
||||||
|
srgb_to_linear(color2.g),
|
||||||
|
srgb_to_linear(color2.b)
|
||||||
|
);
|
||||||
|
// srgb-linear
|
||||||
|
if (colorspace == 1.0) {
|
||||||
|
color_out = mix(
|
||||||
|
color1,
|
||||||
|
color2,
|
||||||
|
color_ratio
|
||||||
|
);
|
||||||
|
// oklab
|
||||||
|
} else if (colorspace == 2.0) {
|
||||||
|
color1.xyz = linear_to_oklab(color1.rgb);
|
||||||
|
color2.xyz = linear_to_oklab(color2.rgb);
|
||||||
|
color_out = mix(
|
||||||
|
color1,
|
||||||
|
color2,
|
||||||
|
color_ratio
|
||||||
|
);
|
||||||
|
color_out.rgb = oklab_to_linear(color_out.xyz);
|
||||||
|
// oklch
|
||||||
|
} else if (colorspace == 3.0) {
|
||||||
|
color1.xyz = lab_to_lch(linear_to_oklab(color1.rgb));
|
||||||
|
color2.xyz = lab_to_lch(linear_to_oklab(color2.rgb));
|
||||||
|
color_out = mix(color1, color2, color_ratio);
|
||||||
|
|
||||||
|
float min_hue = min(color1.z, color2.z);
|
||||||
|
float max_hue = max(color1.z, color2.z);
|
||||||
|
float path_direct_distance = (max_hue - min_hue) * color_ratio;
|
||||||
|
float path_mod_distance = (360.0 - max_hue + min_hue) * color_ratio;
|
||||||
|
|
||||||
|
float path_mod =
|
||||||
|
color1.z == min_hue ?
|
||||||
|
mod(color1.z - path_mod_distance, 360.0) :
|
||||||
|
mod(color1.z + path_mod_distance, 360.0) ;
|
||||||
|
float path_direct =
|
||||||
|
color1.z == min_hue ?
|
||||||
|
color1.z + path_direct_distance :
|
||||||
|
color1.z - path_direct_distance ;
|
||||||
|
|
||||||
|
// shorter
|
||||||
|
if (hue_interpolation == 0.0) {
|
||||||
|
color_out.z =
|
||||||
|
max_hue - min_hue > 360.0 - max_hue + min_hue ?
|
||||||
|
path_mod :
|
||||||
|
path_direct ;
|
||||||
|
// longer
|
||||||
|
} else if (hue_interpolation == 1.0) {
|
||||||
|
color_out.z =
|
||||||
|
max_hue - min_hue <= 360.0 - max_hue + min_hue ?
|
||||||
|
path_mod :
|
||||||
|
path_direct ;
|
||||||
|
// increasing
|
||||||
|
} else if (hue_interpolation == 2.0) {
|
||||||
|
color_out.z =
|
||||||
|
color1.z > color2.z ?
|
||||||
|
path_mod :
|
||||||
|
path_direct ;
|
||||||
|
// decreasing
|
||||||
|
} else if (hue_interpolation == 3.0) {
|
||||||
|
color_out.z =
|
||||||
|
color1.z <= color2.z ?
|
||||||
|
path_mod :
|
||||||
|
path_direct ;
|
||||||
|
}
|
||||||
|
color_out.rgb = clamp(oklab_to_linear(lch_to_lab(color_out.xyz)), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec4(
|
||||||
|
linear_to_srgb(color_out.r) * color_out.a,
|
||||||
|
linear_to_srgb(color_out.g) * color_out.a,
|
||||||
|
linear_to_srgb(color_out.b) * color_out.a,
|
||||||
|
color_out.a
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
vec4 gradient_color(vec2 coords) {
|
vec4 gradient_color(vec2 coords) {
|
||||||
coords = coords + grad_offset;
|
coords = coords + grad_offset;
|
||||||
|
|
||||||
@ -33,7 +203,7 @@ vec4 gradient_color(vec2 coords) {
|
|||||||
frac += 1.0;
|
frac += 1.0;
|
||||||
|
|
||||||
frac = clamp(frac, 0.0, 1.0);
|
frac = clamp(frac, 0.0, 1.0);
|
||||||
return mix(color_from, color_to, frac);
|
return color_mix(color_from, color_to, frac);
|
||||||
}
|
}
|
||||||
|
|
||||||
float rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius) {
|
float rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius) {
|
||||||
|
@ -34,6 +34,8 @@ impl Shaders {
|
|||||||
renderer,
|
renderer,
|
||||||
include_str!("border.frag"),
|
include_str!("border.frag"),
|
||||||
&[
|
&[
|
||||||
|
UniformName::new("colorspace", UniformType::_1f),
|
||||||
|
UniformName::new("hue_interpolation", UniformType::_1f),
|
||||||
UniformName::new("color_from", UniformType::_4f),
|
UniformName::new("color_from", UniformType::_4f),
|
||||||
UniformName::new("color_to", UniformType::_4f),
|
UniformName::new("color_to", UniformType::_4f),
|
||||||
UniformName::new("grad_offset", UniformType::_2f),
|
UniformName::new("grad_offset", UniformType::_2f),
|
||||||
|
@ -2,7 +2,7 @@ use std::cell::{Cell, RefCell};
|
|||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use niri_config::{CornerRadius, WindowRule};
|
use niri_config::{CornerRadius, GradientInterpolation, WindowRule};
|
||||||
use smithay::backend::renderer::element::surface::render_elements_from_surface_tree;
|
use smithay::backend::renderer::element::surface::render_elements_from_surface_tree;
|
||||||
use smithay::backend::renderer::element::{Id, Kind};
|
use smithay::backend::renderer::element::{Id, Kind};
|
||||||
use smithay::backend::renderer::gles::GlesRenderer;
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
@ -289,6 +289,7 @@ impl Mapped {
|
|||||||
return BorderRenderElement::new(
|
return BorderRenderElement::new(
|
||||||
geo.size,
|
geo.size,
|
||||||
Rectangle::from_loc_and_size((0., 0.), geo.size),
|
Rectangle::from_loc_and_size((0., 0.), geo.size),
|
||||||
|
GradientInterpolation::default(),
|
||||||
elem.color(),
|
elem.color(),
|
||||||
elem.color(),
|
elem.color(),
|
||||||
0.,
|
0.,
|
||||||
|
@ -32,7 +32,7 @@ layout {
|
|||||||
active-color "#ffc87f"
|
active-color "#ffc87f"
|
||||||
inactive-color "#505050"
|
inactive-color "#505050"
|
||||||
// active-gradient from="#ffbb66" to="#ffc880" angle=45 relative-to="workspace-view"
|
// active-gradient from="#ffbb66" to="#ffc880" angle=45 relative-to="workspace-view"
|
||||||
// inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view"
|
// inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" gradient-type="linear"
|
||||||
}
|
}
|
||||||
|
|
||||||
struts {
|
struts {
|
||||||
@ -169,7 +169,7 @@ layout {
|
|||||||
inactive-color "#505050"
|
inactive-color "#505050"
|
||||||
|
|
||||||
// active-gradient from="#ffbb66" to="#ffc880" angle=45 relative-to="workspace-view"
|
// active-gradient from="#ffbb66" to="#ffc880" angle=45 relative-to="workspace-view"
|
||||||
// inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view"
|
// inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" gradient-type="linear"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -221,6 +221,9 @@ layout {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Gradients can be rendered with different kinds of color interpolation, this doesen't mean that the arguments the gradient takes are any different.
|
||||||
|
Except for an optional `in` argument which can take both a colorspace and a hue interpolation method if the color space is polar.
|
||||||
|
|
||||||
Gradients can be colored relative to windows individually (the default), or to the whole view of the workspace.
|
Gradients can be colored relative to windows individually (the default), or to the whole view of the workspace.
|
||||||
To do that, set `relative-to="workspace-view"`.
|
To do that, set `relative-to="workspace-view"`.
|
||||||
Here's a visual example:
|
Here's a visual example:
|
||||||
|
Loading…
Reference in New Issue
Block a user