2022-03-21 21:20:58 +00:00
|
|
|
//! Show a custom window frame instead of the default OS window chrome decorations.
|
|
|
|
|
|
|
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
|
|
|
|
|
|
|
|
use eframe::egui;
|
|
|
|
|
2022-12-14 16:29:54 +00:00
|
|
|
fn main() -> Result<(), eframe::Error> {
|
2022-03-21 21:20:58 +00:00
|
|
|
let options = eframe::NativeOptions {
|
|
|
|
// Hide the OS-specific "chrome" around the window:
|
|
|
|
decorated: false,
|
|
|
|
// To have rounded corners we need transparency:
|
|
|
|
transparent: true,
|
2023-02-04 13:42:42 +00:00
|
|
|
min_window_size: Some(egui::vec2(400.0, 100.0)),
|
|
|
|
initial_window_size: Some(egui::vec2(400.0, 240.0)),
|
2022-03-21 21:20:58 +00:00
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
eframe::run_native(
|
|
|
|
"Custom window frame", // unused title
|
|
|
|
options,
|
|
|
|
Box::new(|_cc| Box::new(MyApp::default())),
|
2022-12-12 14:16:32 +00:00
|
|
|
)
|
2022-03-21 21:20:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Default)]
|
2023-02-04 15:05:23 +00:00
|
|
|
struct MyApp {}
|
2022-03-21 21:20:58 +00:00
|
|
|
|
|
|
|
impl eframe::App for MyApp {
|
2023-02-04 10:02:15 +00:00
|
|
|
fn clear_color(&self, _visuals: &egui::Visuals) -> [f32; 4] {
|
|
|
|
egui::Rgba::TRANSPARENT.to_array() // Make sure we don't paint anything behind the rounded corners
|
2022-03-21 21:20:58 +00:00
|
|
|
}
|
|
|
|
|
2022-03-25 20:19:31 +00:00
|
|
|
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
2023-02-04 15:05:23 +00:00
|
|
|
custom_window_frame(ctx, frame, "egui with custom frame", |ui| {
|
2022-03-21 21:20:58 +00:00
|
|
|
ui.label("This is just the contents of the window");
|
|
|
|
ui.horizontal(|ui| {
|
|
|
|
ui.label("egui theme:");
|
|
|
|
egui::widgets::global_dark_light_mode_buttons(ui);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-30 08:12:52 +00:00
|
|
|
fn custom_window_frame(
|
2022-03-21 21:20:58 +00:00
|
|
|
ctx: &egui::Context,
|
2022-03-25 20:19:31 +00:00
|
|
|
frame: &mut eframe::Frame,
|
2022-03-21 21:20:58 +00:00
|
|
|
title: &str,
|
|
|
|
add_contents: impl FnOnce(&mut egui::Ui),
|
|
|
|
) {
|
|
|
|
use egui::*;
|
|
|
|
let text_color = ctx.style().visuals.text_color();
|
|
|
|
|
|
|
|
// Height of the title bar
|
|
|
|
let height = 28.0;
|
|
|
|
|
2023-02-04 15:05:23 +00:00
|
|
|
let button_height = 16.0;
|
|
|
|
|
2022-03-21 21:20:58 +00:00
|
|
|
CentralPanel::default()
|
|
|
|
.frame(Frame::none())
|
|
|
|
.show(ctx, |ui| {
|
|
|
|
let rect = ui.max_rect();
|
|
|
|
let painter = ui.painter();
|
|
|
|
|
|
|
|
// Paint the frame:
|
|
|
|
painter.rect(
|
|
|
|
rect.shrink(1.0),
|
|
|
|
10.0,
|
|
|
|
ctx.style().visuals.window_fill(),
|
|
|
|
Stroke::new(1.0, text_color),
|
|
|
|
);
|
|
|
|
|
|
|
|
// Paint the title:
|
|
|
|
painter.text(
|
|
|
|
rect.center_top() + vec2(0.0, height / 2.0),
|
|
|
|
Align2::CENTER_CENTER,
|
|
|
|
title,
|
Fix text sizes being too small (#2069)
Closes https://github.com/emilk/egui/issues/2068
Before this PR, the default font, Ubuntu-Light, was ~11% smaller
than it should have been, and the default monospace font, Hack,
was ~14% smaller. This means that setting the font size `12` in egui
would yield smaller text than using that font size in any other app.
Ooops!
The change is that this PR now takes into account the ttf properties
`units_per_em` and `height_unscaled`.
If your egui application has specified you own font sizes or text styles
you will see the text in your application grow
larger, unless you go in and compensate by dividing all font sizes by
~1.21 for Ubuntu-Light/Proportional and ~1.16 for Hack/Monospace,
and with something else if you are using a custom font!
This effects any use of `FontId`, `RichText::size`, etc.
This PR changes the default `Style::text_styles` to compensate,
so the default egui style should look the same before and after this PR.
2022-09-21 19:31:08 +00:00
|
|
|
FontId::proportional(height * 0.8),
|
2022-03-21 21:20:58 +00:00
|
|
|
text_color,
|
|
|
|
);
|
|
|
|
|
|
|
|
// Paint the line under the title:
|
|
|
|
painter.line_segment(
|
|
|
|
[
|
|
|
|
rect.left_top() + vec2(2.0, height),
|
|
|
|
rect.right_top() + vec2(-2.0, height),
|
|
|
|
],
|
|
|
|
Stroke::new(1.0, text_color),
|
|
|
|
);
|
|
|
|
|
|
|
|
// Interact with the title bar (drag to move window):
|
|
|
|
let title_bar_rect = {
|
|
|
|
let mut rect = rect;
|
|
|
|
rect.max.y = rect.min.y + height;
|
|
|
|
rect
|
|
|
|
};
|
|
|
|
let title_bar_response =
|
2022-08-04 10:32:27 +00:00
|
|
|
ui.interact(title_bar_rect, Id::new("title_bar"), Sense::click());
|
2023-02-04 13:42:42 +00:00
|
|
|
|
|
|
|
if title_bar_response.double_clicked() {
|
2023-02-04 15:05:23 +00:00
|
|
|
frame.set_maximized(!frame.info().window_info.maximized);
|
2023-02-04 13:42:42 +00:00
|
|
|
} else if title_bar_response.is_pointer_button_down_on() {
|
2022-03-21 21:20:58 +00:00
|
|
|
frame.drag_window();
|
|
|
|
}
|
|
|
|
|
2023-02-04 15:05:23 +00:00
|
|
|
ui.allocate_ui_at_rect(title_bar_rect, |ui| {
|
|
|
|
ui.horizontal_centered(|ui| {
|
|
|
|
ui.spacing_mut().item_spacing.x = 0.0;
|
|
|
|
ui.visuals_mut().button_frame = false;
|
|
|
|
|
|
|
|
let close_response = ui
|
|
|
|
.add(Button::new(RichText::new("❌").size(button_height)))
|
|
|
|
.on_hover_text("Close the window");
|
|
|
|
if close_response.clicked() {
|
|
|
|
frame.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
let minimized_response = ui
|
|
|
|
.add(Button::new(RichText::new("🗕").size(button_height)))
|
|
|
|
.on_hover_text("Minimize the window");
|
|
|
|
if minimized_response.clicked() {
|
|
|
|
frame.set_minimized(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if frame.info().window_info.maximized {
|
|
|
|
let maximized_response = ui
|
|
|
|
.add(Button::new(RichText::new("🗖").size(button_height)))
|
|
|
|
.on_hover_text("Restore window");
|
|
|
|
if maximized_response.clicked() {
|
|
|
|
frame.set_maximized(false);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let maximized_response = ui
|
|
|
|
.add(Button::new(RichText::new("🗗").size(button_height)))
|
|
|
|
.on_hover_text("Maximize window");
|
|
|
|
if maximized_response.clicked() {
|
|
|
|
frame.set_maximized(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2023-02-04 13:42:42 +00:00
|
|
|
|
2022-03-21 21:20:58 +00:00
|
|
|
// Add the contents:
|
|
|
|
let content_rect = {
|
|
|
|
let mut rect = rect;
|
|
|
|
rect.min.y = title_bar_rect.max.y;
|
|
|
|
rect
|
|
|
|
}
|
|
|
|
.shrink(4.0);
|
|
|
|
let mut content_ui = ui.child_ui(content_rect, *ui.layout());
|
|
|
|
add_contents(&mut content_ui);
|
|
|
|
});
|
|
|
|
}
|