Say it in front
- New to rust, I can’t find any tutorials on egui. I’ll record the learning process here.
- Environment: windows11 22H2
- rust version: rustc 1.71.1
- egui version: 0.22.0
- eframe version: 0.22.0
- Previous article: here
What is panel
-
panel
is an area on the UI. For example, if we open CSDN’s markdown editor, it can be roughly divided into four (five) blocks(of course, in actual implementation, these four areas may not be parallel ), then we can use four panels to implement it:- top-level article title
- sub-top menu bar
- Editing area on the left
- Preview area on the right
-
panel
is somewhat similar to thediv
element inhtml
, but its function is not as powerful asdiv
(preliminary Feeling haha)
How to use
-
In the previous sections, we have had a preliminary understanding of the basic use of
panel
. Here we look at a comprehensive use case. -
Suppose we want to implement the layout of
vscode
, how should we implement it? Let’s first take a look at the functional area ofvscode
. Of course, there is also a menu bar at the top.
-
Now let’s try to implement it (you can do it directly on the
template
in the previous sections)fn update( & amp;mut self, ctx: & amp;egui::Context, _frame: & amp;mut eframe::Frame) {<!-- --> egui::TopBottomPanel::top("Menu Bar").show(ctx, |ui| {<!-- --> ui.vertical_centered(|ui|{<!-- --> ui.heading("Menu Bar"); }); }); egui::TopBottomPanel::bottom("Status Bar").show(ctx, |ui| {<!-- --> ui.vertical_centered(|ui|{<!-- --> ui.heading("Status Bar"); }); }); egui::SidePanel::left("Activity Bar").show(ctx, |ui| {<!-- --> ui.horizontal_centered(|ui|{<!-- --> ui.label("Activity Bar"); }); }); egui::SidePanel::left("Side Bar").show(ctx, |ui| {<!-- --> ui.horizontal_centered(|ui|{<!-- --> ui.label("Side Bar"); }); }); egui::TopBottomPanel::bottom("Panel").show(ctx, |ui| {<!-- --> ui.vertical_centered(|ui|{<!-- --> ui.heading("Panel"); }); }); egui::CentralPanel::default().show(ctx, |ui|{<!-- --> ui.vertical_centered(|ui|{<!-- --> ui.heading("Editor"); }); }); }
The result is:
-
The general division of areas is almost the same, but the size of each area is not quite right. We can adjust it slightly.
fn update( & amp;mut self, ctx: & amp;egui::Context, _frame: & amp;mut eframe::Frame) {<!-- --> egui::TopBottomPanel::top("Menu Bar").show(ctx, |ui| {<!-- --> ui.vertical_centered(|ui| {<!-- --> ui.heading("Menu Bar"); }); }); egui::TopBottomPanel::bottom("Status Bar").show(ctx, |ui| {<!-- --> ui.vertical_centered(|ui| {<!-- --> ui.heading("Status Bar"); }); }); egui::SidePanel::left("Activity Bar") .max_width(40.0) .resizable(false) .show(ctx, |ui| ui.add(egui::Label::new("Activity Bar"))); egui::SidePanel::left("Side Bar") .default_width(1000.0) .width_range(200.0..=2000.0) .resizable(true) .show(ctx, |ui| {<!-- --> ui.text_edit_singleline( & amp;mut "hi"); }); egui::TopBottomPanel::bottom("Panel") .default_height(200.0) .resizable(false) .show(ctx, |ui| {<!-- --> ui.add(egui::TextEdit::multiline( & amp;mut "Panel").desired_rows(10)); }); egui::CentralPanel::default().show(ctx, |ui| {<!-- --> ui.heading("Editor"); }); }
The result is:
In the code, in addition to defining the width and height of the panel, some
text_edit
is also added; this is because the actual width and height of the panel are related to its internal elements.
For example, if there is only onelabel
inside aSidePanel
, its width cannot change dynamically even if you set theresizable
attribute.pub fn resizable(self, resizable: bool) -> Self
- Can panel be resized by dragging the edge of it?
- Default is true.
- If you want your panel to be resizable you also need a widget in it that takes up more space as you resize it
window decorations
-
Comparing
vscode
we can see that there is a small difference:
-
The icons and menu bar in vscode are all together, but our
demo app
is divided into two parts -
If we want to be consistent with
vscode
, how should we achieve it? -
First remove the decorations of
eframe
let mut native_options = eframe::NativeOptions::default(); native_options.decorated = false; let ret = eframe::run_native( "demo app", native_options, Box::new(|cc| Box::new(demo_app::TemplateApp::new(cc))), );
-
Then you need to implement the entire
frame
yourself. You can refer to here for details. It is relatively troublesome. The effect is as shown below:
-
I feel that the effect is not very good, so I won’t expand on it here.
Dividing areas within the panel
- When using a panel, you may encounter a situation where the interior of the panel needs to be further divided. How should you deal with this situation?
egui::SidePanel::left("Side Bar") .default_width(1000.0) .width_range(200.0..=2000.0) .resizable(true) .show(ctx, |ui| {<!-- --> egui::TopBottomPanel::bottom("AB bottom").show_inside(ui, |ui| {<!-- --> ui.label("bottom"); }); ui.text_edit_singleline( & amp;mut "Side Bar"); });
Use the
show_inside
method
Reference
- panel