use crate::components::layer::types;
use crate::core::SugarloafStyle;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Delta<T: Default> {
pub x: T,
pub top_y: T,
pub bottom_y: T,
}
#[derive(Default)]
pub struct SugarloafLayout {
pub scale_factor: f32,
pub line_height: f32,
pub width: f32,
pub height: f32,
pub width_u32: u32,
pub height_u32: u32,
pub font_size: f32,
pub original_font_size: f32,
pub columns: usize,
pub lines: usize,
pub margin: Delta<f32>,
pub style: SugarloafStyle,
pub background_color: wgpu::Color,
pub background_image: Option<types::Image>,
pub min_cols_lines: (usize, usize),
pub sugarwidth: f32,
pub sugarheight: f32,
pub scaled_sugarwidth: f32,
pub scaled_sugarheight: f32,
}
#[inline]
fn update_styles(layout: &mut SugarloafLayout) {
let text_scale = layout.font_size * layout.scale_factor;
let new_styles = SugarloafStyle {
line_height: layout.line_height,
screen_position: (
layout.margin.x * layout.scale_factor,
layout.margin.top_y * layout.scale_factor,
),
text_scale,
};
layout.style = new_styles;
}
#[inline]
fn compute(
dimensions: (f32, f32),
scale_factor: f32,
line_height: f32,
sugarwidth: f32,
sugarheight: f32,
margin: Delta<f32>,
min_cols_lines: (usize, usize),
) -> (usize, usize) {
let margin_x = ((margin.x) * scale_factor).floor();
let margin_spaces = (margin.top_y * 2.) + margin.bottom_y;
let mut lines = (dimensions.1 / scale_factor) - margin_spaces;
lines /= sugarheight * line_height;
let visible_lines = std::cmp::max(lines.floor() as usize, min_cols_lines.1);
let mut visible_columns = (dimensions.0 / scale_factor) - margin_x;
visible_columns /= sugarwidth;
let visible_columns = std::cmp::max(visible_columns as usize, min_cols_lines.0);
(visible_columns, visible_lines)
}
impl SugarloafLayout {
pub fn new(
width: f32,
height: f32,
padding: (f32, f32, f32),
scale_factor: f32,
font_size: f32,
line_height: f32,
min_cols_lines: (usize, usize),
) -> SugarloafLayout {
let style = SugarloafStyle::default();
let mut layout = SugarloafLayout {
width,
width_u32: width as u32,
height,
height_u32: height as u32,
columns: 80,
lines: 25,
scale_factor,
original_font_size: font_size,
font_size,
sugarwidth: font_size,
sugarheight: font_size,
scaled_sugarwidth: font_size,
scaled_sugarheight: font_size,
background_image: None,
line_height,
style,
margin: Delta {
x: padding.0,
top_y: padding.1,
bottom_y: padding.2,
},
background_color: wgpu::Color::BLACK,
min_cols_lines,
};
update_styles(&mut layout);
layout
}
#[inline]
pub fn rescale(&mut self, scale_factor: f32) -> &mut Self {
self.scale_factor = scale_factor;
self
}
#[inline]
pub fn resize(&mut self, width: u32, height: u32) -> &mut Self {
self.width_u32 = width;
self.height_u32 = height;
self.width = width as f32;
self.height = height as f32;
self
}
pub fn increase_font_size(&mut self) -> bool {
if self.font_size < 40.0 {
self.font_size += 1.0;
return true;
}
false
}
pub fn decrease_font_size(&mut self) -> bool {
if self.font_size > 6.0 {
self.font_size -= 1.0;
return true;
}
false
}
pub fn reset_font_size(&mut self) -> bool {
if self.font_size != self.original_font_size {
self.font_size = self.original_font_size;
return true;
}
false
}
#[inline]
pub fn update(&mut self) -> &mut Self {
update_styles(self);
let (columns, lines) = compute(
(self.width, self.height),
self.scale_factor,
self.line_height,
self.sugarwidth,
self.sugarheight,
self.margin,
self.min_cols_lines,
);
self.columns = columns;
self.lines = lines;
self
}
#[inline]
pub fn update_columns_per_font_width(&mut self) {
let current_stack_bound = self.sugarwidth * self.columns as f32;
let expected_stack_bound = (self.width / self.scale_factor) - self.sugarwidth;
log::info!("expected columns {}", self.columns);
if current_stack_bound < expected_stack_bound {
let stack_difference =
((expected_stack_bound - current_stack_bound) / self.sugarwidth) as usize;
log::info!("recalculating columns due to font width, adding more {stack_difference:?} columns");
self.columns += stack_difference;
}
if current_stack_bound > expected_stack_bound {
let stack_difference =
((current_stack_bound - expected_stack_bound) / self.sugarwidth) as usize;
log::info!("recalculating columns due to font width, removing {stack_difference:?} columns");
self.columns -= stack_difference;
}
}
#[inline]
pub fn set_margin_top_y(&mut self, top_y: f32) {
self.margin.top_y = top_y;
}
#[inline]
pub fn recalculate(
&mut self,
font_size: f32,
line_height: f32,
margin_x: f32,
margin_y_bottom: f32,
) -> &mut Self {
let mut should_apply_changes = false;
if self.font_size != font_size {
self.font_size = font_size;
self.original_font_size = font_size;
should_apply_changes = true;
}
if self.line_height != line_height {
self.line_height = line_height;
should_apply_changes = true;
}
if self.margin.x != margin_x {
self.margin.x = margin_x;
should_apply_changes = true;
}
if self.margin.bottom_y != margin_y_bottom {
self.margin.bottom_y = margin_y_bottom;
should_apply_changes = true;
}
if should_apply_changes {
update_styles(self);
}
self
}
}