use crate::utils::Caption;
use super::CharAttribute;
use EnumBitFlags::EnumBitFlags;
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Default, Eq)]
pub enum TextAlignment {
#[default]
Left,
Center,
Right,
}
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Default)]
pub enum WrapType {
WordWrap(u16),
CharacterWrap(u16),
MultiLine,
#[default]
SingleLine,
SingleLineWrap(u16),
}
#[EnumBitFlags(bits = 8)]
enum TextFormatFlags {
Hotkey = 0x01,
CharsCount = 0x02,
}
pub struct TextFormat {
flags: TextFormatFlags,
pub(crate) x: i32,
pub(crate) y: i32,
pub(crate) char_attr: CharAttribute,
pub(super) hotkey_attr: CharAttribute,
pub(super) hotkey_pos: u32,
pub(super) chars_count: u16,
pub(crate) align: TextAlignment,
pub(crate) wrap_type: WrapType,
}
impl TextFormat {
#[inline(always)]
pub(super) fn has_hotkey(&self) -> bool {
self.flags.contains(TextFormatFlags::Hotkey)
}
#[inline(always)]
pub(super) fn has_chars_count(&self) -> bool {
self.flags.contains(TextFormatFlags::CharsCount)
}
#[inline(always)]
pub fn set_align(&mut self, align: TextAlignment) {
self.align = align;
}
#[inline(always)]
pub fn set_attribute(&mut self, attr: CharAttribute) {
self.char_attr = attr;
}
#[inline(always)]
pub fn set_position(&mut self, x: i32, y: i32) {
self.x = x;
self.y = y;
}
#[inline(always)]
pub fn set_hotkey(&mut self, attr: CharAttribute, pos: u32) {
self.hotkey_attr = attr;
self.hotkey_pos = pos;
self.flags.set(TextFormatFlags::Hotkey);
}
#[inline(always)]
pub fn clear_hotkey(&mut self) {
self.flags.remove(TextFormatFlags::Hotkey);
}
#[inline(always)]
pub fn set_wrap_type(&mut self, wrap_type: WrapType) {
self.wrap_type = wrap_type;
}
#[inline(always)]
pub fn set_chars_count(&mut self, value: u16) {
self.chars_count = value;
self.flags.set(TextFormatFlags::CharsCount);
}
#[inline(always)]
pub(crate) fn width(&self) -> u16 {
match self.wrap_type {
WrapType::WordWrap(width) | WrapType::CharacterWrap(width) | WrapType::SingleLineWrap(width) => width,
_ => 0,
}
}
#[inline(always)]
pub(crate) fn set_hotkey_from_caption(&mut self, attr: CharAttribute, caption: &Caption) {
if caption.has_hotkey() {
self.set_hotkey(attr, caption.hotkey_pos().unwrap() as u32);
} else {
self.clear_hotkey();
}
}
}
impl Default for TextFormat {
fn default() -> Self {
Self {
flags: TextFormatFlags::None,
x: 0,
y: 0,
char_attr: Default::default(),
hotkey_attr: Default::default(),
hotkey_pos: 0,
chars_count: 0,
align: TextAlignment::Left,
wrap_type: WrapType::SingleLine,
}
}
}
pub struct TextFormatBuilder {
format: TextFormat,
}
impl TextFormatBuilder {
#[inline(always)]
pub fn new() -> Self {
Self { format: Default::default() }
}
#[inline(always)]
pub fn position(mut self, x: i32, y: i32) -> Self {
self.format.x = x;
self.format.y = y;
self
}
#[inline(always)]
pub fn attribute(mut self, attr: CharAttribute) -> Self {
self.format.char_attr = attr;
self
}
#[inline(always)]
pub fn hotkey(mut self, attr: CharAttribute, pos: u32) -> Self {
self.format.set_hotkey(attr, pos);
self
}
#[inline(always)]
pub fn align(mut self, align: TextAlignment) -> Self {
self.format.align = align;
self
}
#[inline(always)]
pub fn chars_count(mut self, value: u16) -> Self {
self.format.set_chars_count(value);
self
}
#[inline(always)]
pub fn wrap_type(mut self, wrap_type: WrapType) -> Self {
self.format.set_wrap_type(wrap_type);
self
}
#[inline(always)]
pub fn build(self) -> TextFormat {
self.format
}
}