Tweak and organize devtools crate
This commit is contained in:
parent
267583c2a9
commit
ef16ea3b2a
8 changed files with 239 additions and 132 deletions
|
|
@ -31,6 +31,7 @@ impl text::Renderer for () {
|
||||||
type Paragraph = ();
|
type Paragraph = ();
|
||||||
type Editor = ();
|
type Editor = ();
|
||||||
|
|
||||||
|
const MONOSPACE_FONT: Font = Font::MONOSPACE;
|
||||||
const ICON_FONT: Font = Font::DEFAULT;
|
const ICON_FONT: Font = Font::DEFAULT;
|
||||||
const CHECKMARK_ICON: char = '0';
|
const CHECKMARK_ICON: char = '0';
|
||||||
const ARROW_DOWN_ICON: char = '0';
|
const ARROW_DOWN_ICON: char = '0';
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,11 @@ pub trait Renderer: crate::Renderer {
|
||||||
/// The [`Editor`] of this [`Renderer`].
|
/// The [`Editor`] of this [`Renderer`].
|
||||||
type Editor: Editor<Font = Self::Font> + 'static;
|
type Editor: Editor<Font = Self::Font> + 'static;
|
||||||
|
|
||||||
|
/// A monospace font.
|
||||||
|
///
|
||||||
|
/// It may be used by devtools.
|
||||||
|
const MONOSPACE_FONT: Self::Font;
|
||||||
|
|
||||||
/// The icon font of the backend.
|
/// The icon font of the backend.
|
||||||
const ICON_FONT: Self::Font;
|
const ICON_FONT: Self::Font;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ pub use palette::Palette;
|
||||||
|
|
||||||
use crate::Color;
|
use crate::Color;
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
|
@ -87,14 +88,17 @@ impl Theme {
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Creates a new custom [`Theme`] from the given [`Palette`].
|
/// Creates a new custom [`Theme`] from the given [`Palette`].
|
||||||
pub fn custom(name: String, palette: Palette) -> Self {
|
pub fn custom(
|
||||||
|
name: impl Into<Cow<'static, str>>,
|
||||||
|
palette: Palette,
|
||||||
|
) -> Self {
|
||||||
Self::custom_with_fn(name, palette, palette::Extended::generate)
|
Self::custom_with_fn(name, palette, palette::Extended::generate)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new custom [`Theme`] from the given [`Palette`], with
|
/// Creates a new custom [`Theme`] from the given [`Palette`], with
|
||||||
/// a custom generator of a [`palette::Extended`].
|
/// a custom generator of a [`palette::Extended`].
|
||||||
pub fn custom_with_fn(
|
pub fn custom_with_fn(
|
||||||
name: String,
|
name: impl Into<Cow<'static, str>>,
|
||||||
palette: Palette,
|
palette: Palette,
|
||||||
generate: impl FnOnce(Palette) -> palette::Extended,
|
generate: impl FnOnce(Palette) -> palette::Extended,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -220,7 +224,7 @@ impl fmt::Display for Theme {
|
||||||
/// A [`Theme`] with a customized [`Palette`].
|
/// A [`Theme`] with a customized [`Palette`].
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Custom {
|
pub struct Custom {
|
||||||
name: String,
|
name: Cow<'static, str>,
|
||||||
palette: Palette,
|
palette: Palette,
|
||||||
extended: palette::Extended,
|
extended: palette::Extended,
|
||||||
}
|
}
|
||||||
|
|
@ -234,12 +238,12 @@ impl Custom {
|
||||||
/// Creates a [`Custom`] theme from the given [`Palette`] with
|
/// Creates a [`Custom`] theme from the given [`Palette`] with
|
||||||
/// a custom generator of a [`palette::Extended`].
|
/// a custom generator of a [`palette::Extended`].
|
||||||
pub fn with_fn(
|
pub fn with_fn(
|
||||||
name: String,
|
name: impl Into<Cow<'static, str>>,
|
||||||
palette: Palette,
|
palette: Palette,
|
||||||
generate: impl FnOnce(Palette) -> palette::Extended,
|
generate: impl FnOnce(Palette) -> palette::Extended,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name: name.into(),
|
||||||
palette,
|
palette,
|
||||||
extended: generate(palette),
|
extended: generate(palette),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
use crate::executor;
|
use crate::executor;
|
||||||
use crate::runtime::Task;
|
use crate::runtime::Task;
|
||||||
|
|
||||||
use std::io;
|
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub const COMPATIBLE_REVISION: &str =
|
pub const COMPATIBLE_REVISION: &str =
|
||||||
"69dd2283886dccdaa1ee6e1c274af62f7250bc38";
|
"69dd2283886dccdaa1ee6e1c274af62f7250bc38";
|
||||||
|
|
||||||
pub fn launch() -> Task<Result<(), Error>> {
|
pub fn launch() -> Task<launch::Result> {
|
||||||
executor::try_spawn_blocking(|mut sender| {
|
executor::try_spawn_blocking(|mut sender| {
|
||||||
let cargo_install = process::Command::new("cargo")
|
let cargo_install = process::Command::new("cargo")
|
||||||
.args(["install", "--list"])
|
.args(["install", "--list"])
|
||||||
|
|
@ -22,15 +20,15 @@ pub fn launch() -> Task<Result<(), Error>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some((_, revision)) = line.rsplit_once("?rev=") else {
|
let Some((_, revision)) = line.rsplit_once("?rev=") else {
|
||||||
return Err(Error::Outdated { revision: None });
|
return Err(launch::Error::Outdated { revision: None });
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some((revision, _)) = revision.rsplit_once("#") else {
|
let Some((revision, _)) = revision.rsplit_once("#") else {
|
||||||
return Err(Error::Outdated { revision: None });
|
return Err(launch::Error::Outdated { revision: None });
|
||||||
};
|
};
|
||||||
|
|
||||||
if revision != COMPATIBLE_REVISION {
|
if revision != COMPATIBLE_REVISION {
|
||||||
return Err(Error::Outdated {
|
return Err(launch::Error::Outdated {
|
||||||
revision: Some(revision.to_owned()),
|
revision: Some(revision.to_owned()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -45,16 +43,16 @@ pub fn launch() -> Task<Result<(), Error>> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(Error::NotFound)
|
Err(launch::Error::NotFound)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn install() -> Task<Result<Installation, Error>> {
|
pub fn install() -> Task<install::Result> {
|
||||||
executor::try_spawn_blocking(|mut sender| {
|
executor::try_spawn_blocking(|mut sender| {
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
let install = Command::new("cargo")
|
let mut install = Command::new("cargo")
|
||||||
.args([
|
.args([
|
||||||
"install",
|
"install",
|
||||||
"--locked",
|
"--locked",
|
||||||
|
|
@ -68,41 +66,75 @@ pub fn install() -> Task<Result<Installation, Error>> {
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()?;
|
.spawn()?;
|
||||||
|
|
||||||
let mut stderr =
|
let mut stderr = BufReader::new(
|
||||||
BufReader::new(install.stderr.expect("stderr must be piped"));
|
install.stderr.take().expect("stderr must be piped"),
|
||||||
|
);
|
||||||
|
|
||||||
let mut log = String::new();
|
let mut log = String::new();
|
||||||
|
|
||||||
while let Ok(n) = stderr.read_line(&mut log) {
|
while let Ok(n) = stderr.read_line(&mut log) {
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
break;
|
let status = install.wait()?;
|
||||||
|
|
||||||
|
if status.success() {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
return Err(install::Error::ProcessFailed(status));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = sender.try_send(Installation::Logged(log.clone()));
|
let _ = sender.try_send(install::Event::Logged(log.clone()));
|
||||||
log.clear();
|
log.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = sender.try_send(Installation::Finished);
|
let _ = sender.try_send(install::Event::Finished);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
pub mod launch {
|
||||||
pub enum Installation {
|
use std::io;
|
||||||
Logged(String),
|
use std::sync::Arc;
|
||||||
Finished,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
pub type Result = std::result::Result<(), Error>;
|
||||||
pub enum Error {
|
|
||||||
NotFound,
|
|
||||||
Outdated { revision: Option<String> },
|
|
||||||
IoFailed(Arc<io::Error>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<io::Error> for Error {
|
#[derive(Debug, Clone)]
|
||||||
fn from(error: io::Error) -> Self {
|
pub enum Error {
|
||||||
Self::IoFailed(Arc::new(error))
|
NotFound,
|
||||||
|
Outdated { revision: Option<String> },
|
||||||
|
IoFailed(Arc<io::Error>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for Error {
|
||||||
|
fn from(error: io::Error) -> Self {
|
||||||
|
Self::IoFailed(Arc::new(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod install {
|
||||||
|
use std::io;
|
||||||
|
use std::process;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub type Result = std::result::Result<Event, Error>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Event {
|
||||||
|
Logged(String),
|
||||||
|
Finished,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Error {
|
||||||
|
ProcessFailed(process::ExitStatus),
|
||||||
|
IoFailed(Arc<io::Error>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for Error {
|
||||||
|
fn from(error: io::Error) -> Self {
|
||||||
|
Self::IoFailed(Arc::new(error))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,12 @@ mod comet;
|
||||||
mod executor;
|
mod executor;
|
||||||
mod time_machine;
|
mod time_machine;
|
||||||
|
|
||||||
|
use crate::core::border;
|
||||||
use crate::core::keyboard;
|
use crate::core::keyboard;
|
||||||
use crate::core::theme::{self, Base, Theme};
|
use crate::core::theme::{self, Base, Theme};
|
||||||
use crate::core::time::seconds;
|
use crate::core::time::seconds;
|
||||||
use crate::core::window;
|
use crate::core::window;
|
||||||
use crate::core::{Color, Element, Length::Fill};
|
use crate::core::{Alignment::Center, Color, Element, Length::Fill};
|
||||||
use crate::futures::Subscription;
|
use crate::futures::Subscription;
|
||||||
use crate::program::Program;
|
use crate::program::Program;
|
||||||
use crate::runtime::Task;
|
use crate::runtime::Task;
|
||||||
|
|
@ -124,9 +125,9 @@ where
|
||||||
enum Message {
|
enum Message {
|
||||||
HideNotification,
|
HideNotification,
|
||||||
ToggleComet,
|
ToggleComet,
|
||||||
CometLaunched(Result<(), comet::Error>),
|
CometLaunched(comet::launch::Result),
|
||||||
InstallComet,
|
InstallComet,
|
||||||
InstallationProgressed(Result<comet::Installation, comet::Error>),
|
Installing(comet::install::Result),
|
||||||
CancelSetup,
|
CancelSetup,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -195,17 +196,17 @@ where
|
||||||
Message::CometLaunched(Ok(())) => Task::none(),
|
Message::CometLaunched(Ok(())) => Task::none(),
|
||||||
Message::CometLaunched(Err(error)) => {
|
Message::CometLaunched(Err(error)) => {
|
||||||
match error {
|
match error {
|
||||||
comet::Error::NotFound => {
|
comet::launch::Error::NotFound => {
|
||||||
self.mode = Mode::Setup(Setup::Idle {
|
self.mode = Mode::Setup(Setup::Idle {
|
||||||
goal: Goal::Installation,
|
goal: Goal::Installation,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
comet::Error::Outdated { revision } => {
|
comet::launch::Error::Outdated { revision } => {
|
||||||
self.mode = Mode::Setup(Setup::Idle {
|
self.mode = Mode::Setup(Setup::Idle {
|
||||||
goal: Goal::Update { revision },
|
goal: Goal::Update { revision },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
comet::Error::IoFailed(error) => {
|
comet::launch::Error::IoFailed(error) => {
|
||||||
log::error!("comet failed to run: {error}");
|
log::error!("comet failed to run: {error}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -217,29 +218,42 @@ where
|
||||||
Mode::Setup(Setup::Running { logs: Vec::new() });
|
Mode::Setup(Setup::Running { logs: Vec::new() });
|
||||||
|
|
||||||
comet::install()
|
comet::install()
|
||||||
.map(Message::InstallationProgressed)
|
.map(Message::Installing)
|
||||||
.map(Event::Message)
|
.map(Event::Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::InstallationProgressed(Ok(installation)) => {
|
Message::Installing(Ok(installation)) => {
|
||||||
let Mode::Setup(Setup::Running { logs }) = &mut self.mode
|
let Mode::Setup(Setup::Running { logs }) = &mut self.mode
|
||||||
else {
|
else {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
};
|
};
|
||||||
|
|
||||||
match installation {
|
match installation {
|
||||||
comet::Installation::Logged(log) => {
|
comet::install::Event::Logged(log) => {
|
||||||
logs.push(log);
|
logs.push(log);
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
comet::Installation::Finished => {
|
comet::install::Event::Finished => {
|
||||||
self.mode = Mode::None;
|
self.mode = Mode::None;
|
||||||
comet::launch().discard()
|
comet::launch().discard()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::InstallationProgressed(_error) => {
|
Message::Installing(Err(error)) => {
|
||||||
// TODO
|
let Mode::Setup(Setup::Running { logs }) = &mut self.mode
|
||||||
|
else {
|
||||||
|
return Task::none();
|
||||||
|
};
|
||||||
|
|
||||||
|
match error {
|
||||||
|
comet::install::Error::ProcessFailed(status) => {
|
||||||
|
logs.push(format!("process failed with {status}"));
|
||||||
|
}
|
||||||
|
comet::install::Error::IoFailed(error) => {
|
||||||
|
logs.push(error.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::CancelSetup => {
|
Message::CancelSetup => {
|
||||||
|
|
@ -304,7 +318,7 @@ where
|
||||||
let derive_theme = move || {
|
let derive_theme = move || {
|
||||||
theme
|
theme
|
||||||
.palette()
|
.palette()
|
||||||
.map(|palette| Theme::custom("DevTools".to_owned(), palette))
|
.map(|palette| Theme::custom("iced devtools", palette))
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -312,97 +326,14 @@ where
|
||||||
Mode::None => None,
|
Mode::None => None,
|
||||||
Mode::Setup(setup) => {
|
Mode::Setup(setup) => {
|
||||||
let stage: Element<'_, _, Theme, P::Renderer> = match setup {
|
let stage: Element<'_, _, Theme, P::Renderer> = match setup {
|
||||||
Setup::Idle { goal } => {
|
Setup::Idle { goal } => self::setup(goal),
|
||||||
let controls = row![
|
Setup::Running { logs } => installation(logs),
|
||||||
button(text("Cancel").center().width(Fill))
|
|
||||||
.width(100)
|
|
||||||
.on_press(Message::CancelSetup)
|
|
||||||
.style(button::danger),
|
|
||||||
horizontal_space(),
|
|
||||||
button(
|
|
||||||
text(match goal {
|
|
||||||
Goal::Installation => "Install",
|
|
||||||
Goal::Update { .. } => "Update",
|
|
||||||
})
|
|
||||||
.center()
|
|
||||||
.width(Fill)
|
|
||||||
)
|
|
||||||
.width(100)
|
|
||||||
.on_press(Message::InstallComet)
|
|
||||||
.style(button::success),
|
|
||||||
];
|
|
||||||
|
|
||||||
let command = container(
|
|
||||||
text(
|
|
||||||
"cargo install --locked \
|
|
||||||
--git https://github.com/iced-rs/comet.git",
|
|
||||||
)
|
|
||||||
.size(14),
|
|
||||||
)
|
|
||||||
.width(Fill)
|
|
||||||
.padding(5)
|
|
||||||
.style(container::dark);
|
|
||||||
|
|
||||||
match goal {
|
|
||||||
Goal::Installation => column![
|
|
||||||
text("comet is not installed!").size(20),
|
|
||||||
"In order to display performance \
|
|
||||||
metrics, the comet debugger must \
|
|
||||||
be installed in your system.",
|
|
||||||
"The comet debugger is an official \
|
|
||||||
companion tool that helps you debug \
|
|
||||||
your iced applications.",
|
|
||||||
"Do you wish to install it with the \
|
|
||||||
following command?",
|
|
||||||
command,
|
|
||||||
controls,
|
|
||||||
]
|
|
||||||
.spacing(20),
|
|
||||||
Goal::Update { revision } => column![
|
|
||||||
text("comet is out of date!").size(20),
|
|
||||||
text!(
|
|
||||||
"The installed revision is \"{current}\", \
|
|
||||||
but the latest compatible is \"{compatible}\".",
|
|
||||||
current = revision
|
|
||||||
.as_deref()
|
|
||||||
.unwrap_or("Unknown"),
|
|
||||||
compatible = comet::COMPATIBLE_REVISION,
|
|
||||||
),
|
|
||||||
"Do you wish to update it with the following \
|
|
||||||
command?",
|
|
||||||
command,
|
|
||||||
controls,
|
|
||||||
]
|
|
||||||
.spacing(20),
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
Setup::Running { logs } => column![
|
|
||||||
text("Installing comet...").size(20),
|
|
||||||
container(
|
|
||||||
scrollable(
|
|
||||||
column(
|
|
||||||
logs.iter()
|
|
||||||
.map(|log| text(log).size(12).into()),
|
|
||||||
)
|
|
||||||
.spacing(3),
|
|
||||||
)
|
|
||||||
.spacing(10)
|
|
||||||
.width(Fill)
|
|
||||||
.height(300)
|
|
||||||
.anchor_bottom(),
|
|
||||||
)
|
|
||||||
.padding(10)
|
|
||||||
.style(container::dark)
|
|
||||||
]
|
|
||||||
.spacing(20)
|
|
||||||
.into(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let setup = center(
|
let setup = center(
|
||||||
container(stage)
|
container(stage)
|
||||||
.padding(20)
|
.padding(20)
|
||||||
.width(500)
|
.max_width(500)
|
||||||
.style(container::bordered_box),
|
.style(container::bordered_box),
|
||||||
)
|
)
|
||||||
.padding(10)
|
.padding(10)
|
||||||
|
|
@ -510,3 +441,134 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setup<Renderer>(goal: &Goal) -> Element<'_, Message, Theme, Renderer>
|
||||||
|
where
|
||||||
|
Renderer: core::text::Renderer + 'static,
|
||||||
|
{
|
||||||
|
let controls = row![
|
||||||
|
button(text("Cancel").center().width(Fill))
|
||||||
|
.width(100)
|
||||||
|
.on_press(Message::CancelSetup)
|
||||||
|
.style(button::danger),
|
||||||
|
horizontal_space(),
|
||||||
|
button(
|
||||||
|
text(match goal {
|
||||||
|
Goal::Installation => "Install",
|
||||||
|
Goal::Update { .. } => "Update",
|
||||||
|
})
|
||||||
|
.center()
|
||||||
|
.width(Fill)
|
||||||
|
)
|
||||||
|
.width(100)
|
||||||
|
.on_press(Message::InstallComet)
|
||||||
|
.style(button::success),
|
||||||
|
];
|
||||||
|
|
||||||
|
let command = container(
|
||||||
|
text!(
|
||||||
|
"cargo install --locked \\
|
||||||
|
--git https://github.com/iced-rs/comet.git \\
|
||||||
|
--rev {}",
|
||||||
|
comet::COMPATIBLE_REVISION
|
||||||
|
)
|
||||||
|
.size(14)
|
||||||
|
.font(Renderer::MONOSPACE_FONT),
|
||||||
|
)
|
||||||
|
.width(Fill)
|
||||||
|
.padding(5)
|
||||||
|
.style(container::dark);
|
||||||
|
|
||||||
|
Element::from(match goal {
|
||||||
|
Goal::Installation => column![
|
||||||
|
text("comet is not installed!").size(20),
|
||||||
|
"In order to display performance \
|
||||||
|
metrics, the comet debugger must \
|
||||||
|
be installed in your system.",
|
||||||
|
"The comet debugger is an official \
|
||||||
|
companion tool that helps you debug \
|
||||||
|
your iced applications.",
|
||||||
|
column![
|
||||||
|
"Do you wish to install it with the \
|
||||||
|
following command?",
|
||||||
|
command
|
||||||
|
]
|
||||||
|
.spacing(10),
|
||||||
|
controls,
|
||||||
|
]
|
||||||
|
.spacing(20),
|
||||||
|
Goal::Update { revision } => {
|
||||||
|
let comparison = column![
|
||||||
|
row![
|
||||||
|
"Installed revision:",
|
||||||
|
horizontal_space(),
|
||||||
|
inline_code(revision.as_deref().unwrap_or("Unknown"))
|
||||||
|
]
|
||||||
|
.align_y(Center),
|
||||||
|
row![
|
||||||
|
"Compatible revision:",
|
||||||
|
horizontal_space(),
|
||||||
|
inline_code(comet::COMPATIBLE_REVISION),
|
||||||
|
]
|
||||||
|
.align_y(Center)
|
||||||
|
]
|
||||||
|
.spacing(5);
|
||||||
|
|
||||||
|
column![
|
||||||
|
text("comet is out of date!").size(20),
|
||||||
|
comparison,
|
||||||
|
column![
|
||||||
|
"Do you wish to update it with the following \
|
||||||
|
command?",
|
||||||
|
command
|
||||||
|
]
|
||||||
|
.spacing(10),
|
||||||
|
controls,
|
||||||
|
]
|
||||||
|
.spacing(20)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn installation<'a, Renderer>(
|
||||||
|
logs: &'a [String],
|
||||||
|
) -> Element<'a, Message, Theme, Renderer>
|
||||||
|
where
|
||||||
|
Renderer: core::text::Renderer + 'a,
|
||||||
|
{
|
||||||
|
column![
|
||||||
|
text("Installing comet...").size(20),
|
||||||
|
container(
|
||||||
|
scrollable(
|
||||||
|
column(logs.iter().map(|log| {
|
||||||
|
text(log).size(12).font(Renderer::MONOSPACE_FONT).into()
|
||||||
|
}),)
|
||||||
|
.spacing(3),
|
||||||
|
)
|
||||||
|
.spacing(10)
|
||||||
|
.width(Fill)
|
||||||
|
.height(300)
|
||||||
|
.anchor_bottom(),
|
||||||
|
)
|
||||||
|
.padding(10)
|
||||||
|
.style(container::dark)
|
||||||
|
]
|
||||||
|
.spacing(20)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inline_code<'a, Renderer>(
|
||||||
|
code: impl text::IntoFragment<'a>,
|
||||||
|
) -> Element<'a, Message, Theme, Renderer>
|
||||||
|
where
|
||||||
|
Renderer: core::text::Renderer + 'a,
|
||||||
|
{
|
||||||
|
container(text(code).font(Renderer::MONOSPACE_FONT).size(12))
|
||||||
|
.style(|_theme| {
|
||||||
|
container::Style::default()
|
||||||
|
.background(Color::BLACK)
|
||||||
|
.border(border::rounded(2))
|
||||||
|
})
|
||||||
|
.padding([2, 4])
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ where
|
||||||
type Paragraph = A::Paragraph;
|
type Paragraph = A::Paragraph;
|
||||||
type Editor = A::Editor;
|
type Editor = A::Editor;
|
||||||
|
|
||||||
|
const MONOSPACE_FONT: Self::Font = A::MONOSPACE_FONT;
|
||||||
const ICON_FONT: Self::Font = A::ICON_FONT;
|
const ICON_FONT: Self::Font = A::ICON_FONT;
|
||||||
const CHECKMARK_ICON: char = A::CHECKMARK_ICON;
|
const CHECKMARK_ICON: char = A::CHECKMARK_ICON;
|
||||||
const ARROW_DOWN_ICON: char = A::ARROW_DOWN_ICON;
|
const ARROW_DOWN_ICON: char = A::ARROW_DOWN_ICON;
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,7 @@ impl core::text::Renderer for Renderer {
|
||||||
type Paragraph = Paragraph;
|
type Paragraph = Paragraph;
|
||||||
type Editor = Editor;
|
type Editor = Editor;
|
||||||
|
|
||||||
|
const MONOSPACE_FONT: Font = Font::MONOSPACE;
|
||||||
const ICON_FONT: Font = Font::with_name("Iced-Icons");
|
const ICON_FONT: Font = Font::with_name("Iced-Icons");
|
||||||
const CHECKMARK_ICON: char = '\u{f00c}';
|
const CHECKMARK_ICON: char = '\u{f00c}';
|
||||||
const ARROW_DOWN_ICON: char = '\u{e800}';
|
const ARROW_DOWN_ICON: char = '\u{e800}';
|
||||||
|
|
|
||||||
|
|
@ -643,6 +643,7 @@ impl core::text::Renderer for Renderer {
|
||||||
type Paragraph = Paragraph;
|
type Paragraph = Paragraph;
|
||||||
type Editor = Editor;
|
type Editor = Editor;
|
||||||
|
|
||||||
|
const MONOSPACE_FONT: Font = Font::MONOSPACE;
|
||||||
const ICON_FONT: Font = Font::with_name("Iced-Icons");
|
const ICON_FONT: Font = Font::with_name("Iced-Icons");
|
||||||
const CHECKMARK_ICON: char = '\u{f00c}';
|
const CHECKMARK_ICON: char = '\u{f00c}';
|
||||||
const ARROW_DOWN_ICON: char = '\u{e800}';
|
const ARROW_DOWN_ICON: char = '\u{e800}';
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue