iced_rizzen 0.14.0

Extra widgets for official releases of iced GUI library.
Documentation
// This file is part of `iced_rizzen` project. For the terms of use, please see the file
// called `LICENSE-BSD-3-Clause` at the top level of the `iced_rizzen` project's Git repository.

//! Collection of various convenience items related to cells of the [`CellGrid`]
//! widget.

#[doc(inline)]
#[allow(unused_imports)]
use super::cellgrid::CellGrid;
#[doc(inline)]
#[allow(unused_imports)]
use iced_widget::TextEditor;
#[doc(inline)]
#[allow(unused_imports)]
use iced_widget::TextInput;

use super::types::PropertyMinimal;
use crate::core::{Border, Color, Theme, border::Radius};
use iced_widget::{text_editor, text_input};

//
//
// ----- Extends the [`TextInput`] catalog [`text_input::Catalog`]
//
//

/// This extends the [`TextInput`] theme with a no border style, as [`CellGrid`]
/// provides borders for the cells by using grid lines.
pub trait TextInputCatalog: text_input::Catalog {
    /// Adding a no border style to [`text_input::Catalog`]
    fn no_border<'a>() -> <Self as text_input::Catalog>::Class<'a>;
}

impl TextInputCatalog for Theme {
    fn no_border<'a>() -> <Self as text_input::Catalog>::Class<'a> {
        Box::new(text_input_no_border)
    }
}

pub fn text_input_no_border(theme: &Theme, status: text_input::Status) -> text_input::Style {
    let base = text_input::default(theme, status);
    text_input::Style {
        border: Border {
            color: Color::TRANSPARENT,
            width: 0.0,
            radius: Radius::new(0.0),
        },
        ..base
    }
}

//
//
// ----- Extends the [`TextEditor`] catalog [`text_editor::Catalog`]
//
//

/// This extends the [`TextInput`] theme with a no border style, as [`CellGrid`]
/// provides borders for the cells by using grid lines.
pub trait TextEditorCatalog: text_editor::Catalog {
    /// Adding a no border style to [`text_input::Catalog`]
    fn no_border<'a>() -> <Self as text_editor::Catalog>::Class<'a>;
}

impl TextEditorCatalog for Theme {
    fn no_border<'a>() -> <Self as text_editor::Catalog>::Class<'a> {
        Box::new(text_editor_no_border)
    }
}

pub fn text_editor_no_border(theme: &Theme, status: text_editor::Status) -> text_editor::Style {
    let base = text_editor::default(theme, status);
    text_editor::Style {
        border: Border {
            color: Color::TRANSPARENT,
            width: 0.0,
            radius: Radius::new(0.0),
        },
        ..base
    }
}

//
//
// ----- Page breaks functions
//
//

/// Create a vector of page breaks from the visible size using the page size.
///
/// Note: Assumes the hidden columns or rows are not included in the visible
/// size.
pub fn page_breaks_simple(page: f32, visible_size: f32) -> Vec<f32> {
    page_breaks_simple_with_header(page, visible_size, 0.0)
}

/// Create a vector of page breaks from the properties by moving the property to
/// the next page to avoid splitting the property if the property overflows the
/// page size. However the property may still be split across multiple pages if
/// the property size is larger than the page size.
///
/// Note: Hidden columns or rows are ignored.
pub fn page_breaks_shift(page: f32, properties: &Vec<PropertyMinimal>) -> Vec<f32> {
    page_breaks_shift_with_header(page, properties, 0.0)
}

/// Create a vector of page breaks from the visible size using the page size,
/// and supports header spacing allocation.
///
/// Note:
///  * Assumes the hidden columns or rows are not included in the visible
///    size.
///
///  * The same result is obtained using [`page_breaks_shift()`] by passing the
///    page size minus the header spacing, however
///    `page_breaks_shift_with_header()` is explicit with regards to the header
///    space.
pub fn page_breaks_simple_with_header(page: f32, visible_size: f32, header: f32) -> Vec<f32> {
    let actual = page - header.min(page);
    let mut breaks = Vec::new();
    let count = (visible_size / actual).floor();
    let mut i = 1.0;
    while i <= count {
        breaks.push(i * actual);
        i += 1.0;
    }
    breaks.shrink_to(breaks.len());
    breaks
}

/// Create a vector of page breaks from the properties by moving the property to
/// the next page to avoid splitting the property if the property overflows the
/// page size. However the property may still be split across multiple pages if
/// the property size is larger than the page size. The header spacing is
/// allocated on every page.
///
/// Note:
///  * Hidden columns or rows are ignored.
///
///  * The same result is obtained using [`page_breaks_shift()`] by passing the
///    page size minus the header spacing, however
///    `page_breaks_shift_with_header()` is explicit with regards to the header
///    space.
pub fn page_breaks_shift_with_header(
    page: f32,
    properties: &Vec<PropertyMinimal>,
    header: f32,
) -> Vec<f32> {
    let actual = page - header.min(page);
    let mut breaks = Vec::new();
    let mut current = 0.0;
    let mut last = 0.0;
    for property in properties {
        if !property.hidden {
            let old = current;
            current += property.size;
            if current > actual {
                last += old;
                breaks.push(last);
                current -= old;
                while current > actual {
                    last += actual;
                    breaks.push(last);
                    current -= actual;
                }
            }
        }
    }
    breaks.shrink_to(breaks.len());
    breaks
}