Skip to content

Commit

Permalink
fix: remove custom titlebar implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir committed May 25, 2024
1 parent 18cbc7b commit 7dce6ea
Show file tree
Hide file tree
Showing 9 changed files with 491 additions and 622 deletions.
923 changes: 437 additions & 486 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ egui_extras = { version = "0.27", features = ["all_loaders"] }
image = { version = "0.24", features = ["png"] }
qrcode-generator = "4.1"
raw-window-handle = "0.6"
window-shadows = "0.2"
window-vibrancy = "0.5"
windows-sys = { version = "0.52.0", features = [
"Win32_Foundation",
Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fn main() -> std::io::Result<()> {
winres::WindowsResource::new()
.set_icon("./.github/icon.ico")
.set_icon("./icons/icon.ico")
.compile()
}
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
185 changes: 51 additions & 134 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use std::sync::Arc;

use eframe::{
egui::{self, vec2, Id, Margin, Modifiers, Rounding, Sense, ViewportCommand},
emath::Align,
egui::{self, Layout, Margin, Modifiers, ViewportCommand},
epaint::{Color32, Stroke},
icon_data,
};
Expand All @@ -19,20 +20,18 @@ mod state;
mod widgets;
mod wifi;

const WINDOW_ICON: &[u8] = include_bytes!("../icons/icon.png");

fn main() -> Result<(), eframe::Error> {
let options = eframe::NativeOptions {
centered: true,
window_builder: Some(Box::new(|builder| {
//
builder
.with_inner_size([600.0, 600.0])
.with_min_inner_size([300.0, 350.0])
.with_transparent(true)
.with_decorations(false)
.with_resizable(true)
.with_icon(
icon_data::from_png_bytes(include_bytes!("../.github/icon.png")).unwrap(),
)
.with_icon(icon_data::from_png_bytes(WINDOW_ICON).unwrap())
})),
..Default::default()
};
Expand All @@ -57,26 +56,38 @@ impl App {
fn new(cc: &eframe::CreationContext<'_>) -> Self {
Self::apply_effects(cc, cc.egui_ctx.style().visuals.dark_mode);
let _ = Self::setup_fonts(&cc.egui_ctx);
Self {
..Default::default()
}

Self::default()
}

fn apply_effects(handle: &impl HasWindowHandle, dark: bool) {
let _ = window_vibrancy::apply_mica(handle, Some(dark));
Self::apply_shadow(handle)
}

// shadows
match handle.window_handle().unwrap().as_raw() {
raw_window_handle::RawWindowHandle::Win32(handle) => unsafe {
fn apply_shadow(handle: &impl HasWindowHandle) {
if let raw_window_handle::RawWindowHandle::Win32(handle) =
handle.window_handle().unwrap().as_raw()
{
unsafe {
let margins = MARGINS {
cyTopHeight: 1,
cxLeftWidth: 1,
cxRightWidth: 1,
cyBottomHeight: 1,
};
DwmExtendFrameIntoClientArea(handle.hwnd.get(), &margins);
},
_ => {}
}
}
}

// TODO: seems like eframe fails to change icon on startup, let's workaround it for now
fn change_icon(&mut self, ctx: &egui::Context) {
if self.state.changed_icon_counter < 5 {
let icon_data = Arc::new(icon_data::from_png_bytes(WINDOW_ICON).unwrap());
ctx.send_viewport_cmd(ViewportCommand::Icon(Some(icon_data)));

self.state.changed_icon_counter += 1;
}
}

Expand Down Expand Up @@ -114,6 +125,8 @@ impl eframe::App for App {
egui::CentralPanel::default()
.frame(egui::Frame::none().fill(Color32::TRANSPARENT))
.show(ctx, |ui| {
self.change_icon(ctx);

// window effects
let dark_mode = ui.visuals().dark_mode;
if dark_mode != self.state.dark_mode {
Expand Down Expand Up @@ -144,115 +157,34 @@ impl eframe::App for App {
});

egui::Frame::none().show(ui, |ui| {
// render titlebar
let tb_height = 32.0;
let tb_padding = 8.0;
let tb_rect = {
let mut rect = ui.max_rect();
rect.max.y = 32.0;
rect
};

let tb_response = ui.interact(tb_rect, Id::new("title_bar"), Sense::click());

if tb_response.double_clicked() {
let is_maximized = ui.input(|i| i.viewport().maximized.unwrap_or(false));
ui.ctx()
.send_viewport_cmd(ViewportCommand::Maximized(!is_maximized));
}
if tb_response.is_pointer_button_down_on() {
ui.ctx().send_viewport_cmd(ViewportCommand::StartDrag);
}

ui.allocate_ui_at_rect(tb_rect, |ui| {
ui.horizontal(|ui| {
ui.vertical(|ui| {
ui.add_space(tb_padding);
ui.horizontal_centered(|ui| {
ui.add_space(tb_padding);
if ui
.add_enabled(
self.state.previous_route.is_some(),
|ui: &mut egui::Ui| {
ui.add_sized(
[0.0, tb_height - tb_padding],
// back
widgets::Button::new("")
.flat(true)
.padding(vec2(12.0, 12.0)),
)
},
)
.clicked()
{
Route::back(&mut self.state)
}

ui.label("WiFi QR");
});
});

ui.with_layout(egui::Layout::right_to_left(Align::Min), |ui| {
ui.horizontal_centered(|ui| {
let style = ui.style_mut();
let default_item_spacing = style.spacing.item_spacing;
style.spacing.item_spacing = vec2(0.0, 0.0);

if ui
.add(
// close
widgets::Button::new("")
.rounding(Rounding::ZERO)
.flat(true),
)
.clicked()
{
ui.ctx().send_viewport_cmd(ViewportCommand::Close);
}
let is_maximized =
ui.input(|i| i.viewport().maximized.unwrap_or(false));
if ui
.add(
// maximize
widgets::Button::new(if is_maximized {
""
} else {
""
})
.rounding(Rounding::ZERO)
.flat(true),
)
.clicked()
{
ui.ctx().send_viewport_cmd(ViewportCommand::Maximized(
!is_maximized,
));
}
if ui
.add(
// minimize
widgets::Button::new("")
.rounding(Rounding::ZERO)
.flat(true),
)
.clicked()
{
ui.ctx()
.send_viewport_cmd(ViewportCommand::Minimized(true));
}

ui.add_space(default_item_spacing.x);
ui.style_mut().spacing.item_spacing = default_item_spacing;

// Render route
egui::Frame::none()
.inner_margin(Margin::same(8.0))
.show(ui, |ui| {
ui.horizontal(|ui| {
// back
if ui
.add_enabled(
self.state.previous_route.is_some(),
|ui: &mut egui::Ui| {
ui.add(widgets::Button::new("").flat(true))
},
)
.clicked()
{
Route::back(&mut self.state)
}

// refresh
ui.with_layout(Layout::right_to_left(egui::Align::Min), |ui| {
// dark mode toggle
if ui
.add(
// dark mode toggle
widgets::Button::new(if dark_mode {
""
} else {
""
})
.rounding(Rounding::ZERO)
.flat(true),
)
.clicked()
Expand All @@ -265,28 +197,13 @@ impl eframe::App for App {
}

if self.state.selected_route == Route::WifiList
&& ui
.add(
// refresh
widgets::Button::new("")
.rounding(Rounding::ZERO)
.flat(true),
)
.clicked()
&& ui.add(widgets::Button::new("").flat(true)).clicked()
{
self.state.requested_refresh = true;
}

ui.add_space(ui.available_width());
})
});
});
});
});

// Render route
egui::Frame::none()
.inner_margin(Margin::same(8.0))
.show(ui, |ui| {
self.state
.selected_route
.clone()
Expand Down
2 changes: 2 additions & 0 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub struct State {
pub requested_refresh: bool,
pub selected_wifi_qr_img_bytes: Option<Vec<u8>>,
pub dark_mode: bool,
pub changed_icon_counter: u8,
}

impl Default for State {
Expand All @@ -22,6 +23,7 @@ impl Default for State {
requested_refresh: true,
selected_wifi_qr_img_bytes: None,
dark_mode: true,
changed_icon_counter: 0,
}
}
}

0 comments on commit 7dce6ea

Please sign in to comment.