2024-07-28 19:18:11 +02:00
|
|
|
use iced::highlighter::{self, Highlighter};
|
2024-07-18 14:34:00 +02:00
|
|
|
use iced::widget::{self, markdown, row, scrollable, text_editor};
|
2024-07-17 22:04:11 +02:00
|
|
|
use iced::{Element, Fill, Font, Task, Theme};
|
|
|
|
|
|
|
|
|
|
pub fn main() -> iced::Result {
|
|
|
|
|
iced::application("Markdown - Iced", Markdown::update, Markdown::view)
|
|
|
|
|
.theme(Markdown::theme)
|
|
|
|
|
.run_with(Markdown::new)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct Markdown {
|
|
|
|
|
content: text_editor::Content,
|
2024-07-18 14:34:00 +02:00
|
|
|
items: Vec<markdown::Item>,
|
2024-07-18 13:14:56 +02:00
|
|
|
theme: Theme,
|
2024-07-17 22:04:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
enum Message {
|
|
|
|
|
Edit(text_editor::Action),
|
2024-07-21 18:16:32 +02:00
|
|
|
LinkClicked(markdown::Url),
|
2024-07-17 22:04:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Markdown {
|
|
|
|
|
fn new() -> (Self, Task<Message>) {
|
2024-07-18 13:14:56 +02:00
|
|
|
const INITIAL_CONTENT: &str = include_str!("../overview.md");
|
|
|
|
|
|
|
|
|
|
let theme = Theme::TokyoNight;
|
|
|
|
|
|
2024-07-17 22:04:11 +02:00
|
|
|
(
|
|
|
|
|
Self {
|
2024-07-18 13:14:56 +02:00
|
|
|
content: text_editor::Content::with_text(INITIAL_CONTENT),
|
2024-07-18 14:34:00 +02:00
|
|
|
items: markdown::parse(INITIAL_CONTENT, theme.palette())
|
|
|
|
|
.collect(),
|
2024-07-18 13:14:56 +02:00
|
|
|
theme,
|
2024-07-17 22:04:11 +02:00
|
|
|
},
|
|
|
|
|
widget::focus_next(),
|
|
|
|
|
)
|
|
|
|
|
}
|
2024-07-18 22:55:40 +02:00
|
|
|
|
2024-07-17 22:04:11 +02:00
|
|
|
fn update(&mut self, message: Message) {
|
|
|
|
|
match message {
|
|
|
|
|
Message::Edit(action) => {
|
2024-07-18 13:14:56 +02:00
|
|
|
let is_edit = action.is_edit();
|
|
|
|
|
|
2024-07-17 22:04:11 +02:00
|
|
|
self.content.perform(action);
|
2024-07-18 13:14:56 +02:00
|
|
|
|
|
|
|
|
if is_edit {
|
2024-07-18 14:34:00 +02:00
|
|
|
self.items = markdown::parse(
|
|
|
|
|
&self.content.text(),
|
|
|
|
|
self.theme.palette(),
|
|
|
|
|
)
|
|
|
|
|
.collect();
|
2024-07-18 13:14:56 +02:00
|
|
|
}
|
2024-07-17 22:04:11 +02:00
|
|
|
}
|
2024-07-21 12:45:05 +02:00
|
|
|
Message::LinkClicked(link) => {
|
2024-07-21 18:16:32 +02:00
|
|
|
let _ = open::that_in_background(link.to_string());
|
2024-07-21 12:45:05 +02:00
|
|
|
}
|
2024-07-17 22:04:11 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn view(&self) -> Element<Message> {
|
|
|
|
|
let editor = text_editor(&self.content)
|
2024-07-24 14:52:01 +02:00
|
|
|
.placeholder("Type your Markdown here...")
|
2024-07-17 22:04:11 +02:00
|
|
|
.on_action(Message::Edit)
|
|
|
|
|
.height(Fill)
|
|
|
|
|
.padding(10)
|
2024-07-28 19:18:11 +02:00
|
|
|
.font(Font::MONOSPACE)
|
|
|
|
|
.highlight::<Highlighter>(
|
|
|
|
|
highlighter::Settings {
|
|
|
|
|
theme: highlighter::Theme::Base16Ocean,
|
|
|
|
|
token: "markdown".to_owned(),
|
|
|
|
|
},
|
|
|
|
|
|highlight, _theme| highlight.to_format(),
|
|
|
|
|
);
|
2024-07-17 22:04:11 +02:00
|
|
|
|
2024-07-24 10:12:33 +02:00
|
|
|
let preview = markdown(&self.items, markdown::Settings::default())
|
|
|
|
|
.map(Message::LinkClicked);
|
2024-07-17 22:04:11 +02:00
|
|
|
|
2024-07-18 13:22:53 +02:00
|
|
|
row![editor, scrollable(preview).spacing(10).height(Fill)]
|
|
|
|
|
.spacing(10)
|
|
|
|
|
.padding(10)
|
|
|
|
|
.into()
|
2024-07-17 22:04:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn theme(&self) -> Theme {
|
2024-07-18 15:14:54 +02:00
|
|
|
self.theme.clone()
|
2024-07-17 22:04:11 +02:00
|
|
|
}
|
|
|
|
|
}
|