Completely eliminate panel separation gap with unified horizontal container in v2.5.5
This commit is contained in:
+114
-97
@@ -16,7 +16,7 @@ use crate::updater::{
|
|||||||
};
|
};
|
||||||
use eframe::egui::{
|
use eframe::egui::{
|
||||||
self, Align, Button, CentralPanel, Color32, ColorImage, Frame, Layout, Margin, ProgressBar,
|
self, Align, Button, CentralPanel, Color32, ColorImage, Frame, Layout, Margin, ProgressBar,
|
||||||
RichText, Rounding, ScrollArea, SidePanel, Stroke, TextureHandle, TextureOptions, Ui, Vec2,
|
RichText, Rounding, ScrollArea, Stroke, TextureHandle, TextureOptions, Ui, Vec2,
|
||||||
};
|
};
|
||||||
use human_bytes::human_bytes;
|
use human_bytes::human_bytes;
|
||||||
use qrcode::{Color as QrColor, QrCode};
|
use qrcode::{Color as QrColor, QrCode};
|
||||||
@@ -5020,114 +5020,131 @@ impl eframe::App for ZeroSendApp {
|
|||||||
style.visuals.widgets.active.rounding = Rounding::same(6.0);
|
style.visuals.widgets.active.rounding = Rounding::same(6.0);
|
||||||
ctx.set_style(style);
|
ctx.set_style(style);
|
||||||
|
|
||||||
SidePanel::left("sidebar_panel")
|
|
||||||
.resizable(false)
|
|
||||||
.show_separator_line(false)
|
|
||||||
.exact_width(200.0)
|
|
||||||
.frame(
|
|
||||||
Frame::none()
|
|
||||||
.fill(theme.bg_sidebar)
|
|
||||||
.inner_margin(Margin::same(12.0)),
|
|
||||||
)
|
|
||||||
.show(ctx, |ui| {
|
|
||||||
self.render_sidebar(ctx, ui, theme);
|
|
||||||
});
|
|
||||||
|
|
||||||
CentralPanel::default()
|
CentralPanel::default()
|
||||||
.frame(
|
.frame(
|
||||||
Frame::none()
|
Frame::none()
|
||||||
.fill(theme.bg_app)
|
.fill(theme.bg_app)
|
||||||
.inner_margin(Margin::same(20.0)),
|
.inner_margin(Margin::ZERO),
|
||||||
)
|
)
|
||||||
.show(ctx, |ui| {
|
.show(ctx, |ui| {
|
||||||
// Top Update Banner if update available on Gitea
|
ui.spacing_mut().item_spacing = Vec2::ZERO;
|
||||||
if self.show_update_banner {
|
|
||||||
if let Some(info) = &self.update_info {
|
|
||||||
if info.has_update {
|
|
||||||
let mut dismiss = false;
|
|
||||||
let mut trigger_install = None;
|
|
||||||
let mut open_gitea = false;
|
|
||||||
let gitea_url = info.gitea_url.clone();
|
|
||||||
let latest_ver = info.latest_version.clone();
|
|
||||||
let download_url = info.download_url.clone();
|
|
||||||
|
|
||||||
Frame::none()
|
ui.horizontal(|ui| {
|
||||||
.fill(if theme.is_dark { Color32::from_rgb(17, 43, 31) } else { Color32::from_rgb(220, 252, 231) })
|
// ── Left Sidebar (200px) ──
|
||||||
.stroke(Stroke::new(1.0_f32, Color32::from_rgb(34, 197, 94)))
|
ui.allocate_ui(Vec2::new(200.0, ui.available_height()), |ui| {
|
||||||
.rounding(Rounding::same(8.0))
|
Frame::none()
|
||||||
.inner_margin(Margin::symmetric(14.0, 10.0))
|
.fill(theme.bg_sidebar)
|
||||||
.show(ui, |ui| {
|
.inner_margin(Margin::same(12.0))
|
||||||
ui.horizontal(|ui| {
|
.show(ui, |ui| {
|
||||||
ui.label(RichText::new("✨").size(16.0));
|
ui.set_min_width(176.0);
|
||||||
ui.label(
|
ui.set_min_height(ui.available_height());
|
||||||
RichText::new(format!("Update Available: ZeroSend v{} is out on Gitea!", latest_ver))
|
self.render_sidebar(ctx, ui, theme);
|
||||||
.strong()
|
});
|
||||||
.color(if theme.is_dark { Color32::WHITE } else { Color32::from_rgb(20, 83, 45) })
|
});
|
||||||
);
|
|
||||||
|
|
||||||
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
// ── Right Main Content Area ──
|
||||||
if ui.button(RichText::new("✕").size(12.0).color(theme.text_muted)).clicked() {
|
let content_width = ui.available_width();
|
||||||
dismiss = true;
|
let content_height = ui.available_height();
|
||||||
|
ui.allocate_ui(Vec2::new(content_width, content_height), |ui| {
|
||||||
|
Frame::none()
|
||||||
|
.fill(theme.bg_app)
|
||||||
|
.inner_margin(Margin::same(20.0))
|
||||||
|
.show(ui, |ui| {
|
||||||
|
ui.set_min_width(content_width - 40.0);
|
||||||
|
ui.set_min_height(content_height - 40.0);
|
||||||
|
ui.spacing_mut().item_spacing = Vec2::new(8.0, 8.0);
|
||||||
|
|
||||||
|
// Top Update Banner if update available on Gitea
|
||||||
|
if self.show_update_banner {
|
||||||
|
if let Some(info) = &self.update_info {
|
||||||
|
if info.has_update {
|
||||||
|
let mut dismiss = false;
|
||||||
|
let mut trigger_install = None;
|
||||||
|
let mut open_gitea = false;
|
||||||
|
let gitea_url = info.gitea_url.clone();
|
||||||
|
let latest_ver = info.latest_version.clone();
|
||||||
|
let download_url = info.download_url.clone();
|
||||||
|
|
||||||
|
Frame::none()
|
||||||
|
.fill(if theme.is_dark { Color32::from_rgb(17, 43, 31) } else { Color32::from_rgb(220, 252, 231) })
|
||||||
|
.stroke(Stroke::new(1.0_f32, Color32::from_rgb(34, 197, 94)))
|
||||||
|
.rounding(Rounding::same(8.0))
|
||||||
|
.inner_margin(Margin::symmetric(14.0, 10.0))
|
||||||
|
.show(ui, |ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label(RichText::new("✨").size(16.0));
|
||||||
|
ui.label(
|
||||||
|
RichText::new(format!("Update Available: ZeroSend v{} is out on Gitea!", latest_ver))
|
||||||
|
.strong()
|
||||||
|
.color(if theme.is_dark { Color32::WHITE } else { Color32::from_rgb(20, 83, 45) })
|
||||||
|
);
|
||||||
|
|
||||||
|
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
||||||
|
if ui.button(RichText::new("✕").size(12.0).color(theme.text_muted)).clicked() {
|
||||||
|
dismiss = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ui.button(RichText::new("🌐 View on Gitea").size(11.5)).clicked() {
|
||||||
|
open_gitea = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(dl) = download_url {
|
||||||
|
if !self.is_updating {
|
||||||
|
let update_btn = Button::new(
|
||||||
|
RichText::new("🚀 Update Now").strong().size(12.0).color(Color32::WHITE)
|
||||||
|
)
|
||||||
|
.fill(Color32::from_rgb(34, 197, 94))
|
||||||
|
.rounding(Rounding::same(6.0));
|
||||||
|
|
||||||
|
if ui.add(update_btn).clicked() {
|
||||||
|
trigger_install = Some(dl);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ui.label(RichText::new("⏳ Updating...").color(Color32::from_rgb(34, 197, 94)).strong());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if dismiss {
|
||||||
|
self.show_update_banner = false;
|
||||||
|
}
|
||||||
|
if open_gitea {
|
||||||
|
let _ = std::process::Command::new("explorer").arg(&gitea_url).spawn();
|
||||||
|
}
|
||||||
|
if let Some(dl) = trigger_install {
|
||||||
|
self.trigger_install_update(dl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ui.button(RichText::new("🌐 View on Gitea").size(11.5)).clicked() {
|
ui.add_space(10.0);
|
||||||
open_gitea = true;
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(dl) = download_url {
|
// Fluid Tab Transition Animation (Smooth Slide-in & Fade-in)
|
||||||
if !self.is_updating {
|
let elapsed = self.last_tab_change.elapsed().as_secs_f32();
|
||||||
let update_btn = Button::new(
|
let duration = 0.20; // 200 ms
|
||||||
RichText::new("🚀 Update Now").strong().size(12.0).color(Color32::WHITE)
|
let progress = (elapsed / duration).min(1.0);
|
||||||
)
|
if progress < 1.0 {
|
||||||
.fill(Color32::from_rgb(34, 197, 94))
|
ctx.request_repaint();
|
||||||
.rounding(Rounding::same(6.0));
|
}
|
||||||
|
// Cubic ease-out curve
|
||||||
|
let ease = 1.0 - (1.0 - progress).powi(3);
|
||||||
|
let slide_offset = (1.0 - ease) * 12.0;
|
||||||
|
ui.add_space(slide_offset);
|
||||||
|
|
||||||
if ui.add(update_btn).clicked() {
|
match self.current_tab {
|
||||||
trigger_install = Some(dl);
|
Tab::Nearby => self.render_nearby_tab(ui, theme),
|
||||||
}
|
Tab::Send => self.render_send_tab(ui, theme),
|
||||||
} else {
|
Tab::Receive => self.render_receive_tab(ui, theme),
|
||||||
ui.label(RichText::new("⏳ Updating...").color(Color32::from_rgb(34, 197, 94)).strong());
|
Tab::Shared => self.render_shared_tab(ui, theme),
|
||||||
}
|
Tab::Transfers => self.render_transfers_tab(ui, theme),
|
||||||
}
|
Tab::Settings => self.render_settings_tab(ui, theme),
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
if dismiss {
|
|
||||||
self.show_update_banner = false;
|
|
||||||
}
|
|
||||||
if open_gitea {
|
|
||||||
let _ = std::process::Command::new("explorer").arg(&gitea_url).spawn();
|
|
||||||
}
|
|
||||||
if let Some(dl) = trigger_install {
|
|
||||||
self.trigger_install_update(dl);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.add_space(10.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fluid Tab Transition Animation (Smooth Slide-in & Fade-in)
|
|
||||||
let elapsed = self.last_tab_change.elapsed().as_secs_f32();
|
|
||||||
let duration = 0.20; // 200 ms
|
|
||||||
let progress = (elapsed / duration).min(1.0);
|
|
||||||
if progress < 1.0 {
|
|
||||||
ctx.request_repaint();
|
|
||||||
}
|
|
||||||
// Cubic ease-out curve
|
|
||||||
let ease = 1.0 - (1.0 - progress).powi(3);
|
|
||||||
let slide_offset = (1.0 - ease) * 12.0;
|
|
||||||
ui.add_space(slide_offset);
|
|
||||||
|
|
||||||
match self.current_tab {
|
|
||||||
Tab::Nearby => self.render_nearby_tab(ui, theme),
|
|
||||||
Tab::Send => self.render_send_tab(ui, theme),
|
|
||||||
Tab::Receive => self.render_receive_tab(ui, theme),
|
|
||||||
Tab::Shared => self.render_shared_tab(ui, theme),
|
|
||||||
Tab::Transfers => self.render_transfers_tab(ui, theme),
|
|
||||||
Tab::Settings => self.render_settings_tab(ui, theme),
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
self.render_modals(ctx, theme);
|
self.render_modals(ctx, theme);
|
||||||
|
|||||||
Reference in New Issue
Block a user