searching can now append items or edit items
Some checks are pending
/ test (push) Waiting to run

This commit is contained in:
Chris Cochrun 2025-09-10 12:07:21 -05:00
parent 7c18af29ef
commit 48b3852c95
2 changed files with 101 additions and 33 deletions

View file

@ -1,12 +1,13 @@
use clap::{Parser, command}; use clap::{command, Parser};
use core::service_items::ServiceItem; use core::service_items::ServiceItem;
use core::slide::*; use core::slide::*;
use core::songs::Song; use core::songs::Song;
use cosmic::app::context_drawer::ContextDrawer; use cosmic::app::context_drawer::ContextDrawer;
use cosmic::app::{Core, Settings, Task}; use cosmic::app::{Core, Settings, Task};
use cosmic::iced::alignment::Vertical;
use cosmic::iced::keyboard::{Key, Modifiers}; use cosmic::iced::keyboard::{Key, Modifiers};
use cosmic::iced::window::{Mode, Position}; use cosmic::iced::window::{Mode, Position};
use cosmic::iced::{self, Length, Point, event, window}; use cosmic::iced::{self, event, window, Length, Point};
use cosmic::iced_futures::Subscription; use cosmic::iced_futures::Subscription;
use cosmic::iced_widget::{column, row, stack}; use cosmic::iced_widget::{column, row, stack};
use cosmic::theme; use cosmic::theme;
@ -16,15 +17,15 @@ use cosmic::widget::segmented_button::Entity;
use cosmic::widget::text; use cosmic::widget::text;
use cosmic::widget::tooltip::Position as TPosition; use cosmic::widget::tooltip::Position as TPosition;
use cosmic::widget::{ use cosmic::widget::{
Space, button, horizontal_space, mouse_area, nav_bar, button, horizontal_space, mouse_area, nav_bar, search_input,
search_input, tooltip, vertical_space, tooltip, vertical_space, Space,
}; };
use cosmic::widget::{icon, slider}; use cosmic::widget::{icon, slider};
use cosmic::{Application, ApplicationExt, Element, executor}; use cosmic::{executor, Application, ApplicationExt, Element};
use cosmic::{Theme, widget::Container}; use cosmic::{widget::Container, Theme};
use crisp::types::Value; use crisp::types::Value;
use lisp::parse_lisp; use lisp::parse_lisp;
use miette::{Result, miette}; use miette::{miette, Result};
use rayon::prelude::*; use rayon::prelude::*;
use resvg::usvg::fontdb; use resvg::usvg::fontdb;
use std::fs::read_to_string; use std::fs::read_to_string;
@ -33,11 +34,12 @@ use std::sync::Arc;
use tracing::{debug, level_filters::LevelFilter}; use tracing::{debug, level_filters::LevelFilter};
use tracing::{error, warn}; use tracing::{error, warn};
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
use ui::EditorMode;
use ui::library::{self, Library}; use ui::library::{self, Library};
use ui::presenter::{self, Presenter}; use ui::presenter::{self, Presenter};
use ui::song_editor::{self, SongEditor}; use ui::song_editor::{self, SongEditor};
use ui::EditorMode;
use crate::core::kinds::ServiceItemKind;
use crate::ui::text_svg; use crate::ui::text_svg;
pub mod core; pub mod core;
@ -113,6 +115,7 @@ struct App {
searching: bool, searching: bool,
search_query: String, search_query: String,
search_results: Vec<ServiceItem>, search_results: Vec<ServiceItem>,
search_id: cosmic::widget::Id,
library_dragged_item: Option<ServiceItem>, library_dragged_item: Option<ServiceItem>,
fontdb: Arc<fontdb::Database>, fontdb: Arc<fontdb::Database>,
} }
@ -145,6 +148,7 @@ enum Message {
Search(String), Search(String),
CloseSearch, CloseSearch,
UpdateSearchResults(Vec<ServiceItem>), UpdateSearchResults(Vec<ServiceItem>),
OpenEditor(ServiceItem),
} }
const HEADER_SPACE: u16 = 6; const HEADER_SPACE: u16 = 6;
@ -245,6 +249,7 @@ impl cosmic::Application for App {
searching: false, searching: false,
search_results: vec![], search_results: vec![],
search_query: "".into(), search_query: "".into(),
search_id: cosmic::widget::Id::unique(),
current_item: (0, 0), current_item: (0, 0),
library_dragged_item: None, library_dragged_item: None,
fontdb: Arc::clone(&fontdb), fontdb: Arc::clone(&fontdb),
@ -472,25 +477,51 @@ impl cosmic::Application for App {
.map(|item| { .map(|item| {
let title = text::title4(item.title.clone()); let title = text::title4(item.title.clone());
let subtitle = text::body(item.kind.to_string()); let subtitle = text::body(item.kind.to_string());
Element::from(Container::new(row![ Element::from(Container::new(
column![title, subtitle].spacing( row![
cosmic::theme::active() column![title, subtitle].spacing(
.cosmic() cosmic::theme::active()
.space_xxs(), .cosmic()
), .space_xxs(),
button::icon( ),
icon::from_name("add") horizontal_space(),
.scale( tooltip(
button::icon(
icon::from_name("add")
.symbolic(true)
)
.icon_size(
cosmic::theme::active() cosmic::theme::active()
.cosmic() .cosmic()
.space_l() .space_l()
) )
.symbolic(true) .on_press(
) Message::AppendServiceItem(
.on_press( item.clone()
Message::AppendServiceItem(item.clone()) )
) ),
])) "Add to service",
TPosition::FollowCursor
),
tooltip(
button::icon(
icon::from_name("edit")
.symbolic(true)
)
.icon_size(
cosmic::theme::active()
.cosmic()
.space_l()
)
.on_press(Message::OpenEditor(
item.clone()
)),
"Edit Item",
TPosition::FollowCursor
),
]
.align_y(Vertical::Center),
))
}) })
.collect(); .collect();
let modal = Container::new( let modal = Container::new(
@ -499,6 +530,7 @@ impl cosmic::Application for App {
"Amazing Grace", "Amazing Grace",
self.search_query.clone() self.search_query.clone()
) )
.id(self.search_id.clone())
.select_on_focus(true) .select_on_focus(true)
.on_input(Message::Search) .on_input(Message::Search)
.on_submit(Message::Search), .on_submit(Message::Search),
@ -886,7 +918,9 @@ impl cosmic::Application for App {
} }
Message::SearchFocus => { Message::SearchFocus => {
self.searching = true; self.searching = true;
Task::none() cosmic::widget::text_input::focus(
self.search_id.clone(),
)
} }
Message::ChangeServiceItem(index) => { Message::ChangeServiceItem(index) => {
if let Some((index, item)) = self if let Some((index, item)) = self
@ -933,6 +967,23 @@ impl cosmic::Application for App {
self.searching = false; self.searching = false;
Task::none() Task::none()
} }
Message::OpenEditor(item) => {
let kind = item.kind;
match kind {
ServiceItemKind::Song(song) => {
self.editor_mode = Some(EditorMode::Song);
self.update(Message::SongEditor(
song_editor::Message::ChangeSong(song),
))
}
ServiceItemKind::Video(video) => todo!(),
ServiceItemKind::Image(image) => todo!(),
ServiceItemKind::Presentation(presentation) => {
todo!()
}
ServiceItemKind::Content(slide) => todo!(),
}
}
} }
} }
@ -1173,14 +1224,31 @@ where
key: Key, key: Key,
modifiers: Modifiers, modifiers: Modifiers,
) -> Task<Message> { ) -> Task<Message> {
debug!(?key, ?modifiers); // debug!(?key, ?modifiers);
if self.editor_mode.is_some() { if self.editor_mode.is_some() {
return Task::none(); return Task::none();
} }
if self.song_editor.editing() { if self.song_editor.editing() {
return Task::none(); return Task::none();
} }
if self.searching {
match (key, modifiers) {
(
Key::Named(iced::keyboard::key::Named::Escape),
_,
) => return self.update(Message::CloseSearch),
_ => return Task::none(),
}
}
match (key, modifiers) { match (key, modifiers) {
(Key::Character(k), Modifiers::CTRL)
if k == *"k" || k == *"f" =>
{
self.update(Message::SearchFocus)
}
(Key::Character(k), _) if k == *"/" => {
self.update(Message::SearchFocus)
}
( (
Key::Named(iced::keyboard::key::Named::ArrowRight), Key::Named(iced::keyboard::key::Named::ArrowRight),
_, _,

View file

@ -2,36 +2,36 @@ use miette::{IntoDiagnostic, Result};
use std::{fs::File, io::BufReader, path::PathBuf, sync::Arc}; use std::{fs::File, io::BufReader, path::PathBuf, sync::Arc};
use cosmic::{ use cosmic::{
Task,
iced::{ iced::{
Background, Border, Color, ContentFit, Font, Length, Shadow,
Vector,
alignment::Horizontal, alignment::Horizontal,
border, border,
font::{Family, Stretch, Style, Weight}, font::{Family, Stretch, Style, Weight},
Background, Border, Color, ContentFit, Font, Length, Shadow,
Vector,
}, },
iced_widget::{ iced_widget::{
rich_text, rich_text,
scrollable::{ scrollable::{
AbsoluteOffset, Direction, Scrollbar, scroll_to, scroll_to, AbsoluteOffset, Direction, Scrollbar,
}, },
span, stack, vertical_rule, span, stack, vertical_rule,
}, },
prelude::*, prelude::*,
widget::{ widget::{
Column, Container, Id, Image, Row, Space, container, image, container, image, mouse_area, responsive, scrollable, text,
mouse_area, responsive, scrollable, text, Column, Container, Id, Image, Row, Space,
}, },
Task,
}; };
use iced_video_player::{Position, Video, VideoPlayer, gst_pbutils}; use iced_video_player::{gst_pbutils, Position, Video, VideoPlayer};
use rodio::{Decoder, OutputStream, Sink}; use rodio::{Decoder, OutputStream, Sink};
use tracing::{debug, error, info, warn}; use tracing::{debug, error, info, warn};
use url::Url; use url::Url;
use crate::{ use crate::{
BackgroundKind,
core::{service_items::ServiceItem, slide::Slide}, core::{service_items::ServiceItem, slide::Slide},
ui::text_svg, ui::text_svg,
BackgroundKind,
}; };
const REFERENCE_WIDTH: f32 = 1920.0; const REFERENCE_WIDTH: f32 = 1920.0;