use super::adapt::MapAny;
use kas::prelude::*;
use kas::text::format::{EditableText, FormattableText};
use kas::text::Text;
use kas::theme::TextClass;
#[inline]
pub fn label_any<A, T: FormattableText + 'static>(label: T) -> MapAny<A, Label<T>> {
MapAny::new(Label::new(label))
}
impl_scope! {
#[impl_default(where T: Default)]
#[derive(Clone, Debug)]
#[widget {
Data = ();
}]
pub struct Label<T: FormattableText + 'static> {
core: widget_core!(),
class: TextClass = TextClass::Label(true),
label: Text<T>,
}
impl Self {
#[inline]
pub fn new(label: T) -> Self {
Label {
core: Default::default(),
class: TextClass::Label(true),
label: Text::new(label),
}
}
#[inline]
pub fn class(&self) -> TextClass {
self.class
}
#[inline]
pub fn set_class(&mut self, class: TextClass) {
self.class = class;
}
#[inline]
pub fn with_class(mut self, class: TextClass) -> Self {
self.class = class;
self
}
#[inline]
pub fn wrap(&self) -> bool {
self.class.multi_line()
}
#[inline]
pub fn set_wrap(&mut self, wrap: bool) {
self.class = TextClass::Label(wrap);
}
#[inline]
pub fn with_wrap(mut self, wrap: bool) -> Self {
self.class = TextClass::Label(wrap);
self
}
#[inline]
pub fn text(&self) -> &Text<T> {
&self.label
}
pub fn set_text(&mut self, text: T) -> Action {
match self.label.set_and_try_prepare(text) {
Ok(true) => Action::RESIZE,
_ => Action::REDRAW,
}
}
}
impl Layout for Self {
#[inline]
fn size_rules(&mut self, sizer: SizeCx, mut axis: AxisInfo) -> SizeRules {
axis.set_default_align_hv(Align::Default, Align::Center);
sizer.text_rules(&mut self.label, self.class, axis)
}
fn set_rect(&mut self, cx: &mut ConfigCx, rect: Rect) {
self.core.rect = rect;
cx.text_set_size(&mut self.label, self.class, rect.size, None);
}
#[cfg(feature = "min_spec")]
default fn draw(&mut self, mut draw: DrawCx) {
draw.text_effects(self.rect(), &self.label, self.class);
}
#[cfg(not(feature = "min_spec"))]
fn draw(&mut self, mut draw: DrawCx) {
draw.text_effects(self.rect(), &self.label, self.class);
}
}
impl HasStr for Self {
fn get_str(&self) -> &str {
self.label.as_str()
}
}
impl HasString for Self
where
T: EditableText,
{
fn set_string(&mut self, string: String) -> Action {
self.label.set_string(string);
match self.label.try_prepare() {
Ok(true) => Action::RESIZE,
_ => Action::REDRAW,
}
}
}
}
#[cfg(feature = "min_spec")]
impl<'a> Layout for Label<&'a str> {
fn draw(&mut self, mut draw: DrawCx) {
draw.text(self.rect(), &self.label, self.class);
}
}
#[cfg(feature = "min_spec")]
impl Layout for StringLabel {
fn draw(&mut self, mut draw: DrawCx) {
draw.text(self.rect(), &self.label, self.class);
}
}
impl<T: FormattableText + 'static> From<T> for Label<T> {
fn from(label: T) -> Self {
Label::new(label)
}
}
impl<'a> From<&'a str> for Label<String> {
fn from(label: &'a str) -> Self {
Label::new(label.to_string())
}
}
pub type StrLabel = Label<&'static str>;
pub type StringLabel = Label<String>;
impl_scope! {
#[impl_default]
#[derive(Clone, Debug)]
#[widget]
pub struct AccessLabel {
core: widget_core!(),
class: TextClass = TextClass::Label(true),
label: Text<AccessString>,
}
impl Self {
#[inline]
pub fn new(label: impl Into<AccessString>) -> Self {
AccessLabel {
core: Default::default(),
class: TextClass::AccessLabel(true),
label: Text::new(label.into()),
}
}
#[inline]
pub fn class(&self) -> TextClass {
self.class
}
#[inline]
pub fn set_class(&mut self, class: TextClass) {
self.class = class;
}
#[inline]
pub fn with_class(mut self, class: TextClass) -> Self {
self.class = class;
self
}
#[inline]
pub fn wrap(&self) -> bool {
self.class.multi_line()
}
#[inline]
pub fn set_wrap(&mut self, wrap: bool) {
self.class = TextClass::AccessLabel(wrap);
}
#[inline]
pub fn with_wrap(mut self, wrap: bool) -> Self {
self.class = TextClass::Label(wrap);
self
}
#[inline]
pub fn text(&self) -> &Text<AccessString> {
&self.label
}
pub fn set_text(&mut self, text: AccessString) -> Action {
match self.label.set_and_try_prepare(text) {
Ok(true) => Action::RESIZE,
_ => Action::REDRAW,
}
}
}
impl Layout for Self {
#[inline]
fn size_rules(&mut self, sizer: SizeCx, mut axis: AxisInfo) -> SizeRules {
axis.set_default_align_hv(Align::Default, Align::Center);
sizer.text_rules(&mut self.label, self.class, axis)
}
fn set_rect(&mut self, cx: &mut ConfigCx, rect: Rect) {
self.core.rect = rect;
cx.text_set_size(&mut self.label, self.class, rect.size, None);
}
fn draw(&mut self, mut draw: DrawCx) {
draw.text_effects(self.rect(), &self.label, self.class);
}
}
impl Events for Self {
type Data = ();
fn configure(&mut self, cx: &mut ConfigCx) {
if let Some(key) = self.label.text().key() {
cx.add_access_key(self.id_ref(), key.clone());
}
}
fn handle_event(&mut self, cx: &mut EventCx, _: &Self::Data, event: Event) -> IsUsed {
match event {
Event::Command(cmd, code) if cmd.is_activate() => {
cx.push(kas::message::Activate(code));
Used
}
_ => Unused
}
}
}
impl HasStr for Self {
fn get_str(&self) -> &str {
self.label.as_str()
}
}
}