use egui::KeyboardShortcut;
use egui::os::OperatingSystem;
use smallvec::{SmallVec, smallvec};
use super::CommandEnvironment;
use crate::context_ext::ContextExt as _;
pub trait RedapServerCommandSender {
fn send_redap_server_command(&self, command: RedapServerCommand);
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct RedapServerCommand {
pub origin: re_uri::Origin,
pub kind: RedapServerCommandKind,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, strum_macros::EnumIter)]
pub enum RedapServerCommandKind {
Refresh,
Edit,
CopyUrl,
Remove,
}
impl RedapServerCommand {
pub fn all_for_server(origin: &re_uri::Origin) -> impl Iterator<Item = Self> {
use strum::IntoEnumIterator as _;
let origin = origin.clone();
RedapServerCommandKind::iter().map(move |kind| Self {
origin: origin.clone(),
kind,
})
}
pub fn requires_editable_server(&self) -> bool {
self.kind.requires_editable_server()
}
pub fn text(&self) -> &'static str {
self.kind.text()
}
pub fn tooltip(&self) -> &'static str {
self.kind.tooltip()
}
pub fn icon(&self) -> &'static crate::Icon {
self.kind.icon()
}
pub fn menu_button_ui(
self,
ui: &mut egui::Ui,
command_sender: &impl RedapServerCommandSender,
) -> egui::Response {
let mut button = self
.icon()
.as_button_with_label(ui.ctx().tokens(), self.text());
if let Some(shortcut_text) = self.kind.formatted_kb_shortcut(ui.ctx()) {
button = button.shortcut_text(shortcut_text);
}
let response = ui.add(button).on_hover_text(self.tooltip());
if response.clicked() {
command_sender.send_redap_server_command(self);
ui.close();
}
response
}
}
impl RedapServerCommandKind {
pub fn requires_editable_server(self) -> bool {
match self {
Self::Refresh | Self::CopyUrl => false,
Self::Edit | Self::Remove => true,
}
}
pub fn text(self) -> &'static str {
self.text_and_tooltip().0
}
pub fn tooltip(self) -> &'static str {
self.text_and_tooltip().1
}
pub fn text_and_tooltip(self) -> (&'static str, &'static str) {
match self {
Self::Refresh => (
"Refresh server",
"Refresh the contents (datasets & tables) of the server",
),
Self::Edit => ("Edit server…", "Edit the URL and credentials of the server"),
Self::CopyUrl => ("Copy server URL", "Copy the URL of the server"),
Self::Remove => ("Remove server", "Remove the server"),
}
}
pub fn for_environment(self, env: &CommandEnvironment) -> Option<RedapServerCommand> {
let origin = env.redap_server.clone()?;
if self.requires_editable_server() && !env.has_editable_redap_server {
return None;
}
Some(RedapServerCommand { origin, kind: self })
}
pub fn kb_shortcuts(self, os: OperatingSystem) -> SmallVec<[KeyboardShortcut; 2]> {
match self {
Self::Refresh => super::refresh_shortcuts(os),
Self::Edit | Self::CopyUrl | Self::Remove => smallvec![],
}
}
pub fn primary_kb_shortcut(self, os: OperatingSystem) -> Option<KeyboardShortcut> {
self.kb_shortcuts(os).first().copied()
}
pub fn formatted_kb_shortcut(self, egui_ctx: &egui::Context) -> Option<String> {
self.primary_kb_shortcut(egui_ctx.os())
.map(|shortcut| egui_ctx.format_shortcut(&shortcut))
}
pub fn icon(self) -> &'static crate::Icon {
match self {
Self::Refresh => &crate::icons::RESET,
Self::Edit => &crate::icons::SETTINGS,
Self::CopyUrl => &crate::icons::COPY,
Self::Remove => &crate::icons::TRASH,
}
}
}