now there are items and a bit of style to the library

This commit is contained in:
Chris Cochrun 2025-01-15 14:31:48 -06:00
parent 929b0a33d1
commit 40580a6e7a
7 changed files with 131 additions and 9 deletions

6
src/core/content.rs Normal file
View file

@ -0,0 +1,6 @@
use super::kinds::ServiceItemKind;
pub trait Content {
fn title(&self) -> String;
fn kind(&self) -> ServiceItemKind;
}

View file

@ -1,6 +1,8 @@
use crate::{Background, Slide, SlideBuilder, TextAlignment}; use crate::{Background, Slide, SlideBuilder, TextAlignment};
use super::{ use super::{
content::Content,
kinds::ServiceItemKind,
model::{get_db, LibraryKind, Model}, model::{get_db, LibraryKind, Model},
service_items::ServiceTrait, service_items::ServiceTrait,
}; };
@ -20,6 +22,16 @@ pub struct Image {
pub path: PathBuf, pub path: PathBuf,
} }
impl Content for Image {
fn title(&self) -> String {
self.title.clone()
}
fn kind(&self) -> ServiceItemKind {
ServiceItemKind::Image(self.clone())
}
}
impl From<Value> for Image { impl From<Value> for Image {
fn from(value: Value) -> Self { fn from(value: Value) -> Self {
Self::from(&value) Self::from(&value)

View file

@ -1,3 +1,4 @@
pub mod content;
pub mod images; pub mod images;
pub mod kinds; pub mod kinds;
pub mod lisp; pub mod lisp;

View file

@ -10,6 +10,8 @@ use tracing::error;
use crate::{Background, Slide, SlideBuilder, TextAlignment}; use crate::{Background, Slide, SlideBuilder, TextAlignment};
use super::{ use super::{
content::Content,
kinds::ServiceItemKind,
model::{get_db, LibraryKind, Model}, model::{get_db, LibraryKind, Model},
service_items::ServiceTrait, service_items::ServiceTrait,
}; };
@ -34,6 +36,16 @@ pub struct Presentation {
pub kind: PresKind, pub kind: PresKind,
} }
impl Content for Presentation {
fn title(&self) -> String {
self.title.clone()
}
fn kind(&self) -> ServiceItemKind {
ServiceItemKind::Presentation(self.clone())
}
}
impl From<Value> for Presentation { impl From<Value> for Presentation {
fn from(value: Value) -> Self { fn from(value: Value) -> Self {
Self::from(&value) Self::from(&value)

View file

@ -12,6 +12,8 @@ use tracing::{debug, error};
use crate::{core::slide, Slide, SlideBuilder}; use crate::{core::slide, Slide, SlideBuilder};
use super::{ use super::{
content::Content,
kinds::ServiceItemKind,
model::{get_db, LibraryKind, Model}, model::{get_db, LibraryKind, Model},
service_items::ServiceTrait, service_items::ServiceTrait,
slide::{Background, TextAlignment}, slide::{Background, TextAlignment},
@ -34,6 +36,16 @@ pub struct Song {
pub font_size: Option<i32>, pub font_size: Option<i32>,
} }
impl Content for Song {
fn title(&self) -> String {
self.title.clone()
}
fn kind(&self) -> ServiceItemKind {
ServiceItemKind::Song(self.clone())
}
}
impl ServiceTrait for Song { impl ServiceTrait for Song {
fn title(&self) -> String { fn title(&self) -> String {
self.title.clone() self.title.clone()

View file

@ -1,6 +1,8 @@
use crate::{Background, SlideBuilder, TextAlignment}; use crate::{Background, SlideBuilder, TextAlignment};
use super::{ use super::{
content::Content,
kinds::ServiceItemKind,
model::{get_db, LibraryKind, Model}, model::{get_db, LibraryKind, Model},
service_items::ServiceTrait, service_items::ServiceTrait,
slide::Slide, slide::Slide,
@ -25,6 +27,16 @@ pub struct Video {
pub looping: bool, pub looping: bool,
} }
impl Content for Video {
fn title(&self) -> String {
self.title.clone()
}
fn kind(&self) -> ServiceItemKind {
ServiceItemKind::Video(self.clone())
}
}
impl From<Value> for Video { impl From<Value> for Video {
fn from(value: Value) -> Self { fn from(value: Value) -> Self {
Self::from(&value) Self::from(&value)

View file

@ -1,18 +1,20 @@
use cosmic::{ use cosmic::{
font::default,
iced::{ iced::{
alignment::{Horizontal, Vertical}, alignment::{Horizontal, Vertical},
Background, Border, Color, Length, Background, Border, Color, Length,
}, },
iced_widget::{column, text}, iced_widget::{column, row as rowm, text as textm},
theme, theme,
widget::{ widget::{
button, container, horizontal_space, icon, mouse_area, row, button, container, horizontal_space, icon, mouse_area, row,
Container, Space, text, Column, Container, Space,
}, },
Element, Task, Element, Task,
}; };
use crate::core::{ use crate::core::{
content::Content,
images::Image, images::Image,
model::{get_db, LibraryKind, Model}, model::{get_db, LibraryKind, Model},
presentations::Presentation, presentations::Presentation,
@ -86,31 +88,34 @@ impl Library {
pub fn library_item<'a, T>( pub fn library_item<'a, T>(
&'a self, &'a self,
model: &'a Model<T>, model: &'a Model<T>,
) -> Element<'a, Message> { ) -> Element<'a, Message>
where
T: Content,
{
let mut row = row::<Message>().spacing(5); let mut row = row::<Message>().spacing(5);
match &model.kind { match &model.kind {
LibraryKind::Song => { LibraryKind::Song => {
row = row row = row
.push(text!("Songs").align_y(Vertical::Center)); .push(textm!("Songs").align_y(Vertical::Center));
} }
LibraryKind::Video => { LibraryKind::Video => {
row = row row = row
.push(text!("Videos").align_y(Vertical::Center)); .push(textm!("Videos").align_y(Vertical::Center));
} }
LibraryKind::Image => { LibraryKind::Image => {
row = row row = row
.push(text!("Images").align_y(Vertical::Center)); .push(textm!("Images").align_y(Vertical::Center));
} }
LibraryKind::Presentation => { LibraryKind::Presentation => {
row = row.push( row = row.push(
text!("Presentations").align_y(Vertical::Center), textm!("Presentations").align_y(Vertical::Center),
); );
} }
}; };
let item_count = model.items.len(); let item_count = model.items.len();
row = row.push(horizontal_space()); row = row.push(horizontal_space());
row = row row = row
.push(text!("{}", item_count).align_y(Vertical::Center)); .push(textm!("{}", item_count).align_y(Vertical::Center));
row = row.push( row = row.push(
icon::from_name({ icon::from_name({
if self.library_open == Some(model.kind) { if self.library_open == Some(model.kind) {
@ -156,6 +161,68 @@ impl Library {
}) })
.on_enter(Message::HoverLibrary(Some(model.kind))) .on_enter(Message::HoverLibrary(Some(model.kind)))
.on_exit(Message::HoverLibrary(None)); .on_exit(Message::HoverLibrary(None));
button.into() let lib_container = if self.library_open == Some(model.kind) {
let items: Column<Message> = column({
model.items.iter().map(|item| {
let text =
text::heading(elide_text(item.title(), 18))
.center()
.wrapping(textm::Wrapping::None);
let icon = icon::from_name({
match model.kind {
LibraryKind::Song => {
"folder-music-symbolic"
}
LibraryKind::Video => {
"folder-videos-symbolic"
}
LibraryKind::Image => {
"folder-pictures-symbolic"
}
LibraryKind::Presentation => {
"x-office-presentation-symbolic"
}
}
});
Container::new(rowm![icon, text].spacing(10))
.padding(5)
.width(Length::Fill)
.style(|t| {
container::Style::default()
.background(Background::Color(
t.cosmic().button.base.into(),
))
.border(Border::default().rounded(
t.cosmic().corner_radii.radius_l,
))
})
.into()
})
})
.spacing(2)
.width(Length::Fill);
Container::new(items).padding(5).style(|t| {
container::Style::default()
.background(Background::Color(
t.cosmic().primary.base.into(),
))
.border(
Border::default().rounded(
t.cosmic().corner_radii.radius_m,
),
)
})
} else {
Container::new(Space::new(0, 0))
};
column![button, lib_container].into()
}
}
fn elide_text(text: String, amount: usize) -> String {
if text.len() > amount {
format!("{}...", text.split_at(amount).0)
} else {
text
} }
} }