now there are items and a bit of style to the library
This commit is contained in:
parent
929b0a33d1
commit
40580a6e7a
6
src/core/content.rs
Normal file
6
src/core/content.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
use super::kinds::ServiceItemKind;
|
||||||
|
|
||||||
|
pub trait Content {
|
||||||
|
fn title(&self) -> String;
|
||||||
|
fn kind(&self) -> ServiceItemKind;
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue