use serde::Deserialize;
use tauri::{Manager, Runtime, WebviewWindow};
use crate::error;
use crate::overlay;
#[derive(Clone, Default, Debug, Deserialize)]
#[serde(default, rename_all = "snake_case")]
pub struct DecorStyle {
pub controls_height: Option<f64>,
pub controls_inset_x: Option<f64>,
pub controls_spacing: Option<f64>,
pub controls_scale: Option<f64>,
pub controls_button_width: Option<u32>,
pub controls_close_hover_bg: Option<String>,
pub controls_button_hover_bg: Option<String>,
}
pub struct Decor<R: Runtime> {
app: tauri::AppHandle<R>,
}
impl<R: Runtime> Decor<R> {
pub fn new(app: tauri::AppHandle<R>) -> Self {
Self { app }
}
pub fn reconfigure(&self, style: DecorStyle) {
if let Some(v) = style.controls_scale {
self.set_controls_scale(v);
}
if let Some(v) = style.controls_height {
self.set_controls_height(v);
}
if let Some(v) = style.controls_inset_x {
self.set_controls_inset_x(v);
}
if let Some(v) = style.controls_spacing {
self.set_controls_spacing(v);
}
if let Some(v) = style.controls_button_width {
self.set_controls_button_width(v);
}
if let Some(v) = style.controls_close_hover_bg {
self.set_controls_close_hover_bg(v);
}
if let Some(v) = style.controls_button_hover_bg {
self.set_controls_button_hover_bg(v);
}
}
pub fn set_controls_height(&self, height: f64) {
#[cfg(any(target_os = "windows", target_os = "linux"))]
{
crate::config::set_titlebar_height(height.round().max(0.0) as u32);
self.refresh_html();
}
#[cfg(target_os = "macos")]
{
crate::config::set_traffic_inset_y(height);
crate::traffic::reposition_all(&self.app);
}
#[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
let _ = height;
}
pub fn set_controls_inset_x(&self, inset: f64) {
#[cfg(target_os = "macos")]
{
crate::config::set_traffic_inset_x(inset);
crate::traffic::reposition_all(&self.app);
}
#[cfg(not(target_os = "macos"))]
let _ = inset;
}
pub fn set_controls_spacing(&self, spacing: f64) {
#[cfg(target_os = "macos")]
{
crate::config::set_traffic_spacing(spacing);
crate::traffic::reposition_all(&self.app);
}
#[cfg(not(target_os = "macos"))]
let _ = spacing;
}
pub fn set_controls_scale(&self, scale: f64) {
#[cfg(target_os = "macos")]
{
crate::config::set_traffic_scale(scale);
crate::traffic::reposition_all(&self.app);
}
#[cfg(any(target_os = "windows", target_os = "linux"))]
{
crate::config::set_controls_scale(scale);
self.refresh_html();
}
#[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
let _ = scale;
}
pub fn set_controls_button_width(&self, width: u32) {
#[cfg(any(target_os = "windows", target_os = "linux"))]
{
crate::config::set_button_width(width);
self.refresh_html();
}
#[cfg(not(any(target_os = "windows", target_os = "linux")))]
let _ = width;
}
pub fn set_controls_close_hover_bg(&self, color: impl Into<String>) {
#[cfg(any(target_os = "windows", target_os = "linux"))]
{
crate::config::set_close_hover_bg(color);
self.refresh_html();
}
#[cfg(not(any(target_os = "windows", target_os = "linux")))]
let _ = color.into();
}
pub fn set_controls_button_hover_bg(&self, color: impl Into<String>) {
#[cfg(any(target_os = "windows", target_os = "linux"))]
{
crate::config::set_button_hover_bg(color);
self.refresh_html();
}
#[cfg(not(any(target_os = "windows", target_os = "linux")))]
let _ = color.into();
}
#[cfg(target_os = "windows")]
fn refresh_html(&self) {
crate::windows::apply_runtime_style(&self.app);
}
#[cfg(target_os = "linux")]
fn refresh_html(&self) {
crate::linux::apply_runtime_style(&self.app);
}
}
pub trait DecorExt<R: Runtime> {
fn decor(&self) -> &Decor<R>;
}
impl<R: Runtime, T: Manager<R>> DecorExt<R> for T {
fn decor(&self) -> &Decor<R> {
self.state::<Decor<R>>().inner()
}
}
pub trait WebviewWindowExt {
fn create_overlay_titlebar(&self) -> error::Result<&WebviewWindow>;
}
impl WebviewWindowExt for WebviewWindow {
fn create_overlay_titlebar(&self) -> error::Result<&WebviewWindow> {
#[cfg(target_os = "windows")]
self.set_decorations(false)?;
overlay::register(self.label());
#[cfg(target_os = "windows")]
{
let _ = self.eval(&crate::windows::build_scripts(
crate::config::titlebar_height(),
));
}
Ok(self)
}
}