pub mod console;
pub mod data_grid;
pub mod engine;
pub mod filter_bar;
pub mod import_dialog;
pub mod plan_view;
pub mod process_list;
pub mod query_digest;
pub mod query_editor;
pub mod quick_switcher;
pub mod schema_search;
pub mod schema_view;
pub mod server_variables;
pub mod session;
pub mod settings_window;
pub mod shortcuts_dialog;
pub mod sql_file;
pub mod sqlite_maintenance;
pub mod table_view;
mod text_filter;
pub mod value_dialog;
pub mod welcome;
#[cfg(test)]
mod tests;
use gpui_kit::component::button::ButtonCustomVariant;
use gpui_kit::component::notification::Notification;
use gpui_kit::component::{ActiveTheme, Root, Theme, WindowExt};
use gpui_kit::prelude::*;
use gpui_kit::{App, Hsla, SharedString, Window, div, rgb};
use crate::db::TagColor;
pub use engine::{EngineLogos, engine_color, engine_icon};
pub fn notify_error(window: &mut Window, cx: &mut App, message: impl Into<SharedString>) {
if window.root::<Root>().flatten().is_some() {
window.push_notification(Notification::error(message.into()), cx);
}
}
pub fn notify_info(window: &mut Window, cx: &mut App, message: impl Into<SharedString>) {
if window.root::<Root>().flatten().is_some() {
window.push_notification(Notification::info(message.into()), cx);
}
}
pub fn subtle_button(cx: &App) -> ButtonCustomVariant {
let theme = cx.theme();
ButtonCustomVariant::new(cx)
.foreground(theme.muted_foreground)
.hover(theme.accent)
.active(theme.secondary_active)
}
pub fn color_dot(color: TagColor, cx: &App) -> impl IntoElement + use<> {
div().flex_none().size_2().rounded_full().bg(color.hsla(cx))
}
impl TagColor {
pub fn hsla(&self, cx: &App) -> Hsla {
self.hsla_on(cx.theme())
}
pub fn tint(&self, cx: &App) -> Hsla {
self.hsla(cx).opacity(0.1)
}
pub fn on_color(&self, cx: &App) -> Hsla {
on_color_for(self.hsla_on(cx.theme()))
}
pub(crate) fn hsla_on(&self, theme: &Theme) -> Hsla {
let dark = theme.mode.is_dark();
match self {
TagColor::Red => theme.danger,
TagColor::Orange => theme.warning,
TagColor::Green => theme.success,
TagColor::Blue => theme.info,
TagColor::Yellow => if dark { rgb(0xFACC15) } else { rgb(0xCA8A04) }.into(),
TagColor::Teal => if dark { rgb(0x14B8A6) } else { rgb(0x0D9488) }.into(),
TagColor::Purple => if dark { rgb(0xA78BFA) } else { rgb(0x7C3AED) }.into(),
TagColor::Pink => if dark { rgb(0xF472B6) } else { rgb(0xBE185D) }.into(),
TagColor::Gray => if dark { rgb(0x9CA3AF) } else { rgb(0x4B5563) }.into(),
}
}
#[cfg(test)]
pub(crate) fn on_color_for(&self, theme: &Theme) -> Hsla {
on_color_for(self.hsla_on(theme))
}
}
fn on_color_for(background: Hsla) -> Hsla {
let white = Hsla::white();
let black = Hsla::black();
if contrast(white, background) >= contrast(black, background) {
white
} else {
black
}
}
pub(crate) fn relative_luminance(color: Hsla) -> f64 {
let rgba = color.to_rgb();
let channel = |component: f32| {
let component = component as f64;
if component <= 0.04045 {
component / 12.92
} else {
((component + 0.055) / 1.055).powf(2.4)
}
};
0.2126 * channel(rgba.r) + 0.7152 * channel(rgba.g) + 0.0722 * channel(rgba.b)
}
pub(crate) fn contrast(a: Hsla, b: Hsla) -> f64 {
let (lighter, darker) = if relative_luminance(a) >= relative_luminance(b) {
(a, b)
} else {
(b, a)
};
(relative_luminance(lighter) + 0.05) / (relative_luminance(darker) + 0.05)
}