2026-04-23 07:00:06 -03:00
|
|
|
pub fn install_css(window: >k::ApplicationWindow) {
|
|
|
|
|
let provider = gtk::CssProvider::new();
|
|
|
|
|
provider.load_from_data(
|
|
|
|
|
r"
|
|
|
|
|
window.lesavka {
|
|
|
|
|
background: #101319;
|
|
|
|
|
color: #eef2f7;
|
|
|
|
|
}
|
|
|
|
|
box.launcher-root {
|
|
|
|
|
background: linear-gradient(180deg, #11161f 0%, #161d28 100%);
|
|
|
|
|
}
|
|
|
|
|
box.panel {
|
|
|
|
|
background: rgba(255, 255, 255, 0.04);
|
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
|
|
|
border-radius: 18px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
}
|
|
|
|
|
box.subgroup {
|
|
|
|
|
background: rgba(255, 255, 255, 0.025);
|
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
|
|
|
border-radius: 14px;
|
|
|
|
|
padding: 8px;
|
|
|
|
|
}
|
|
|
|
|
label.panel-title {
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
font-size: 1.05rem;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
}
|
|
|
|
|
label.subgroup-title {
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
opacity: 0.92;
|
|
|
|
|
}
|
|
|
|
|
label.version-tag {
|
|
|
|
|
font-size: 0.76rem;
|
|
|
|
|
opacity: 0.72;
|
|
|
|
|
}
|
|
|
|
|
image.app-logo {
|
|
|
|
|
opacity: 0.96;
|
|
|
|
|
}
|
|
|
|
|
box.status-chip {
|
|
|
|
|
background: rgba(91, 179, 162, 0.12);
|
|
|
|
|
border: 1px solid rgba(91, 179, 162, 0.25);
|
|
|
|
|
border-radius: 999px;
|
2026-04-29 20:52:55 -03:00
|
|
|
padding: 4px 6px;
|
2026-04-23 07:00:06 -03:00
|
|
|
}
|
|
|
|
|
box.status-light {
|
2026-04-29 20:52:55 -03:00
|
|
|
min-width: 9px;
|
|
|
|
|
min-height: 9px;
|
2026-04-23 07:00:06 -03:00
|
|
|
border-radius: 999px;
|
|
|
|
|
background: rgba(214, 81, 81, 0.92);
|
|
|
|
|
}
|
|
|
|
|
box.status-light-live {
|
|
|
|
|
background: rgba(96, 214, 126, 0.95);
|
|
|
|
|
}
|
2026-04-23 11:14:58 -03:00
|
|
|
box.status-light-connected {
|
|
|
|
|
background: rgba(76, 154, 255, 0.95);
|
|
|
|
|
}
|
2026-04-23 07:00:06 -03:00
|
|
|
box.status-light-idle {
|
|
|
|
|
background: rgba(214, 81, 81, 0.92);
|
|
|
|
|
}
|
|
|
|
|
box.status-light-warning {
|
|
|
|
|
background: rgba(242, 143, 54, 0.95);
|
|
|
|
|
}
|
|
|
|
|
box.status-light-caution {
|
|
|
|
|
background: rgba(227, 201, 73, 0.95);
|
|
|
|
|
}
|
|
|
|
|
label.status-chip-label {
|
2026-04-29 20:52:55 -03:00
|
|
|
font-size: 0.74rem;
|
2026-04-23 07:00:06 -03:00
|
|
|
opacity: 0.72;
|
|
|
|
|
}
|
|
|
|
|
label.status-chip-value {
|
2026-04-29 20:52:55 -03:00
|
|
|
font-size: 0.88rem;
|
2026-04-23 07:00:06 -03:00
|
|
|
font-weight: 700;
|
|
|
|
|
}
|
|
|
|
|
box.display-card {
|
|
|
|
|
background: rgba(255, 255, 255, 0.045);
|
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
|
|
|
border-radius: 22px;
|
|
|
|
|
padding: 16px;
|
|
|
|
|
}
|
|
|
|
|
box.display-placeholder {
|
|
|
|
|
background: rgba(255, 255, 255, 0.03);
|
|
|
|
|
border: 1px dashed rgba(255, 255, 255, 0.18);
|
|
|
|
|
border-radius: 16px;
|
2026-04-23 15:18:30 -03:00
|
|
|
padding: 12px;
|
|
|
|
|
}
|
|
|
|
|
picture.display-placeholder-art {
|
2026-04-23 17:03:12 -03:00
|
|
|
background: transparent;
|
|
|
|
|
background-color: transparent;
|
2026-04-23 15:18:30 -03:00
|
|
|
opacity: 0.78;
|
2026-04-23 07:00:06 -03:00
|
|
|
}
|
2026-04-23 17:03:12 -03:00
|
|
|
overlay.eye-preview-surface,
|
|
|
|
|
aspectframe.eye-preview-surface,
|
|
|
|
|
picture.eye-preview-surface {
|
|
|
|
|
background: transparent;
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
}
|
2026-04-23 07:00:06 -03:00
|
|
|
picture.camera-preview-frame {
|
|
|
|
|
background: rgba(0, 0, 0, 0.28);
|
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.10);
|
|
|
|
|
border-radius: 14px;
|
|
|
|
|
}
|
2026-04-23 19:11:54 -03:00
|
|
|
button.camera-preview-mirror-toggle {
|
|
|
|
|
min-width: 36px;
|
|
|
|
|
min-height: 36px;
|
|
|
|
|
padding: 0;
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
background: rgba(16, 19, 25, 0.28);
|
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.14);
|
|
|
|
|
color: rgba(238, 242, 247, 0.92);
|
|
|
|
|
}
|
|
|
|
|
button.camera-preview-mirror-toggle:checked {
|
|
|
|
|
background: rgba(76, 154, 255, 0.26);
|
|
|
|
|
border-color: rgba(76, 154, 255, 0.58);
|
|
|
|
|
color: #eef6ff;
|
|
|
|
|
}
|
|
|
|
|
button.camera-preview-mirror-toggle image {
|
|
|
|
|
-gtk-icon-size: 18px;
|
|
|
|
|
}
|
2026-04-23 07:00:06 -03:00
|
|
|
label.status-line {
|
|
|
|
|
opacity: 0.9;
|
|
|
|
|
}
|
|
|
|
|
label.eye-inline-status {
|
|
|
|
|
font-size: 0.86rem;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
background: rgba(91, 179, 162, 0.10);
|
|
|
|
|
border: 1px solid rgba(91, 179, 162, 0.22);
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
padding: 5px 8px;
|
|
|
|
|
opacity: 0.9;
|
|
|
|
|
}
|
|
|
|
|
textview.status-log,
|
|
|
|
|
label.status-log {
|
|
|
|
|
font-family: monospace;
|
|
|
|
|
background: rgba(0, 0, 0, 0.22);
|
|
|
|
|
border-radius: 14px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
}
|
|
|
|
|
progressbar.audio-check-meter trough {
|
|
|
|
|
min-width: 14px;
|
|
|
|
|
min-height: 10px;
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
background: rgba(255, 255, 255, 0.08);
|
|
|
|
|
}
|
|
|
|
|
progressbar.audio-check-meter.vertical trough {
|
2026-04-23 11:49:19 -03:00
|
|
|
min-height: 96px;
|
2026-04-23 07:00:06 -03:00
|
|
|
}
|
|
|
|
|
progressbar.audio-check-meter progress {
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
background: rgba(91, 179, 162, 0.88);
|
|
|
|
|
}
|
2026-05-10 23:14:15 -03:00
|
|
|
scale slider {
|
|
|
|
|
min-width: 14px;
|
|
|
|
|
min-height: 14px;
|
|
|
|
|
}
|
2026-04-23 07:00:06 -03:00
|
|
|
entry.server-entry {
|
|
|
|
|
min-height: 38px;
|
|
|
|
|
}
|
2026-04-23 11:14:58 -03:00
|
|
|
combobox.compact-combo {
|
|
|
|
|
min-width: 0;
|
|
|
|
|
}
|
|
|
|
|
combobox.compact-combo button {
|
|
|
|
|
min-width: 0;
|
|
|
|
|
padding-left: 8px;
|
|
|
|
|
padding-right: 8px;
|
|
|
|
|
}
|
2026-04-23 07:00:06 -03:00
|
|
|
button.pill-toggle {
|
|
|
|
|
min-height: 36px;
|
|
|
|
|
padding: 0 14px;
|
|
|
|
|
}
|
2026-04-23 18:05:21 -03:00
|
|
|
button.media-toggle {
|
|
|
|
|
background: rgba(214, 81, 81, 0.18);
|
|
|
|
|
border-color: rgba(214, 81, 81, 0.42);
|
|
|
|
|
color: #f7d6d6;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
}
|
|
|
|
|
button.media-toggle:checked {
|
|
|
|
|
background: rgba(96, 214, 126, 0.20);
|
|
|
|
|
border-color: rgba(96, 214, 126, 0.46);
|
|
|
|
|
color: #dff7e4;
|
|
|
|
|
}
|
|
|
|
|
button.media-toggle:disabled {
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
}
|
2026-04-23 07:00:06 -03:00
|
|
|
button.pill-toggle-active {
|
|
|
|
|
background: rgba(91, 179, 162, 0.2);
|
|
|
|
|
border-color: rgba(91, 179, 162, 0.45);
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
}
|
|
|
|
|
",
|
|
|
|
|
);
|
|
|
|
|
if let Some(display) = gtk::gdk::Display::default() {
|
|
|
|
|
gtk::style_context_add_provider_for_display(
|
|
|
|
|
&display,
|
|
|
|
|
&provider,
|
|
|
|
|
gtk::STYLE_PROVIDER_PRIORITY_APPLICATION,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
window.add_css_class("lesavka");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn install_window_icon(window: &impl IsA<gtk::Window>) {
|
|
|
|
|
if let Some(display) = gtk::gdk::Display::default() {
|
|
|
|
|
let theme = gtk::IconTheme::for_display(&display);
|
|
|
|
|
theme.add_search_path(LESAVKA_ICON_SEARCH_PATH);
|
|
|
|
|
}
|
|
|
|
|
gtk::Window::set_default_icon_name(LESAVKA_ICON_NAME);
|
|
|
|
|
window.as_ref().set_icon_name(Some(LESAVKA_ICON_NAME));
|
|
|
|
|
}
|
2026-04-25 06:56:17 -03:00
|
|
|
|
|
|
|
|
pub fn install_window_chrome(window: >k::ApplicationWindow, title: &str) {
|
|
|
|
|
window.set_decorated(true);
|
|
|
|
|
|
|
|
|
|
let header = gtk::HeaderBar::builder().show_title_buttons(true).build();
|
|
|
|
|
let title_label = gtk::Label::new(Some(title));
|
|
|
|
|
title_label.set_ellipsize(pango::EllipsizeMode::End);
|
|
|
|
|
header.set_title_widget(Some(&title_label));
|
|
|
|
|
|
|
|
|
|
window.set_titlebar(Some(&header));
|
|
|
|
|
}
|