1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 14:20:04 -04:00

Horizontal scrolling (#663)

* First pass (missing rendering the bar)

* Render horizontal bars, and change Window scroll API

* emath: add impl Index + IndexMut for Align2

* Scrolling: fix subtle sizing bugs

* Add horizontal scrolling to color test

* try to wrap content before showing scrollbars, + add auto-shrink option

* Add hscroll to the misc demo window

* Fix for putting wrapping labels in an infinitely wide layout

* Add a egui_asserts to protect against nans in the layout engine

* Add line about horizontal scrolling to changelog

* Add example to docs of ScrollArea

* code cleanup
This commit is contained in:
Emil Ernerfeldt
2021-08-28 13:18:21 +02:00
committed by GitHub
parent e98ae2ea7a
commit 105b999cb6
26 changed files with 464 additions and 194 deletions

View File

@@ -42,7 +42,7 @@ impl epi::App for ColorTest {
);
ui.separator();
}
ScrollArea::auto_sized().show(ui, |ui| {
ScrollArea::both().auto_shrink([false; 2]).show(ui, |ui| {
self.ui(ui, &mut Some(frame.tex_allocator()));
});
});
@@ -55,6 +55,8 @@ impl ColorTest {
ui: &mut Ui,
mut tex_allocator: &mut Option<&mut dyn epi::TextureAllocator>,
) {
ui.set_max_width(680.0);
ui.vertical_centered(|ui| {
ui.add(crate::__egui_github_link_file!());
});

View File

@@ -15,7 +15,7 @@ impl super::Demo for DancingStrings {
Window::new(self.name())
.open(open)
.default_size(vec2(512.0, 256.0))
.scroll(false)
.vscroll(false)
.show(ctx, |ui| self.ui(ui));
}
}

View File

@@ -159,7 +159,7 @@ impl DemoWindows {
ui.separator();
ScrollArea::auto_sized().show(ui, |ui| {
ScrollArea::vertical().show(ui, |ui| {
use egui::special_emojis::{GITHUB, OS_APPLE, OS_LINUX, OS_WINDOWS};
ui.label("egui is an immediate mode GUI library written in Rust.");

View File

@@ -103,7 +103,7 @@ impl super::Demo for DragAndDropDemo {
Window::new(self.name())
.open(open)
.default_size(vec2(256.0, 256.0))
.scroll(false)
.vscroll(false)
.resizable(false)
.show(ctx, |ui| self.ui(ui));
}

View File

@@ -84,7 +84,7 @@ impl super::View for FontBook {
ui.separator();
egui::ScrollArea::auto_sized().show(ui, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
ui.horizontal_wrapped(|ui| {
ui.spacing_mut().item_spacing = egui::Vec2::splat(2.0);

View File

@@ -34,13 +34,16 @@ impl Demo for MiscDemoWindow {
fn show(&mut self, ctx: &CtxRef, open: &mut bool) {
Window::new(self.name())
.open(open)
.scroll(true)
.vscroll(true)
.hscroll(true)
.show(ctx, |ui| self.ui(ui));
}
}
impl View for MiscDemoWindow {
fn ui(&mut self, ui: &mut Ui) {
ui.set_min_width(250.0);
CollapsingHeader::new("Widgets")
.default_open(true)
.show(ui, |ui| {

View File

@@ -79,7 +79,7 @@ impl super::Demo for Painting {
Window::new(self.name())
.open(open)
.default_size(vec2(512.0, 512.0))
.scroll(false)
.vscroll(false)
.show(ctx, |ui| self.ui(ui));
}
}

View File

@@ -401,7 +401,7 @@ impl super::Demo for PlotDemo {
Window::new(self.name())
.open(open)
.default_size(vec2(400.0, 400.0))
.scroll(false)
.vscroll(false)
.show(ctx, |ui| self.ui(ui));
}
}

View File

@@ -77,7 +77,7 @@ fn huge_content_lines(ui: &mut egui::Ui) {
let text_style = TextStyle::Body;
let row_height = ui.fonts()[text_style].row_height();
let num_rows = 10_000;
ScrollArea::auto_sized().show_rows(ui, row_height, num_rows, |ui, row_range| {
ScrollArea::vertical().show_rows(ui, row_height, num_rows, |ui, row_range| {
for row in row_range {
let text = format!("This is row {}/{}", row + 1, num_rows);
ui.label(text);
@@ -94,7 +94,7 @@ fn huge_content_painter(ui: &mut egui::Ui) {
let row_height = ui.fonts()[text_style].row_height() + ui.spacing().item_spacing.y;
let num_rows = 10_000;
ScrollArea::auto_sized().show_viewport(ui, |ui, viewport| {
ScrollArea::vertical().show_viewport(ui, |ui, viewport| {
ui.set_height(row_height * num_rows as f32);
let first_item = (viewport.min.y / row_height).floor().at_least(0.0) as usize;
@@ -184,7 +184,7 @@ impl super::View for ScrollTo {
scroll_bottom |= ui.button("Scroll to bottom").clicked();
});
let mut scroll_area = ScrollArea::from_max_height(200.0);
let mut scroll_area = ScrollArea::vertical().max_height(200.0);
if go_to_scroll_offset {
scroll_area = scroll_area.scroll_offset(self.offset);
}

View File

@@ -400,7 +400,7 @@ impl super::Demo for WindowResizeTest {
Window::new("↔ resizable + scroll")
.open(open)
.scroll(true)
.vscroll(true)
.resizable(true)
.default_height(300.0)
.show(ctx, |ui| {
@@ -413,14 +413,14 @@ impl super::Demo for WindowResizeTest {
Window::new("↔ resizable + embedded scroll")
.open(open)
.scroll(false)
.vscroll(false)
.resizable(true)
.default_height(300.0)
.show(ctx, |ui| {
ui.label("This window is resizable but has no built-in scroll area.");
ui.label("However, we have a sub-region with a scroll bar:");
ui.separator();
ScrollArea::auto_sized().show(ui, |ui| {
ScrollArea::vertical().show(ui, |ui| {
ui.code(crate::LOREM_IPSUM_LONG);
ui.code(crate::LOREM_IPSUM_LONG);
});
@@ -429,7 +429,7 @@ impl super::Demo for WindowResizeTest {
Window::new("↔ resizable without scroll")
.open(open)
.scroll(false)
.vscroll(false)
.resizable(true)
.show(ctx, |ui| {
ui.label("This window is resizable but has no scroll area. This means it can only be resized to a size where all the contents is visible.");
@@ -440,7 +440,7 @@ impl super::Demo for WindowResizeTest {
Window::new("↔ resizable with TextEdit")
.open(open)
.scroll(false)
.vscroll(false)
.resizable(true)
.default_height(300.0)
.show(ctx, |ui| {
@@ -450,7 +450,7 @@ impl super::Demo for WindowResizeTest {
Window::new("↔ freely resized")
.open(open)
.scroll(false)
.vscroll(false)
.resizable(true)
.default_size([250.0, 150.0])
.show(ctx, |ui| {

View File

@@ -6,7 +6,7 @@ pub struct WindowOptions {
closable: bool,
collapsible: bool,
resizable: bool,
scroll: bool,
scroll2: [bool; 2],
disabled_time: f64,
anchored: bool,
@@ -21,8 +21,8 @@ impl Default for WindowOptions {
title_bar: true,
closable: true,
collapsible: true,
resizable: false,
scroll: false,
resizable: true,
scroll2: [true; 2],
disabled_time: f64::NEG_INFINITY,
anchored: false,
anchor: egui::Align2::RIGHT_TOP,
@@ -43,7 +43,7 @@ impl super::Demo for WindowOptions {
closable,
collapsible,
resizable,
scroll,
scroll2,
disabled_time,
anchored,
anchor,
@@ -61,7 +61,7 @@ impl super::Demo for WindowOptions {
.resizable(resizable)
.collapsible(collapsible)
.title_bar(title_bar)
.scroll(scroll)
.scroll2(scroll2)
.enabled(enabled);
if closable {
window = window.open(open);
@@ -81,7 +81,7 @@ impl super::View for WindowOptions {
closable,
collapsible,
resizable,
scroll,
scroll2,
disabled_time: _,
anchored,
anchor,
@@ -100,7 +100,8 @@ impl super::View for WindowOptions {
ui.checkbox(closable, "closable");
ui.checkbox(collapsible, "collapsible");
ui.checkbox(resizable, "resizable");
ui.checkbox(scroll, "scroll");
ui.checkbox(&mut scroll2[0], "hscroll");
ui.checkbox(&mut scroll2[1], "vscroll");
});
});
ui.group(|ui| {
@@ -109,15 +110,15 @@ impl super::View for WindowOptions {
ui.set_enabled(*anchored);
ui.horizontal(|ui| {
ui.label("x:");
ui.selectable_value(&mut anchor.0[0], egui::Align::LEFT, "Left");
ui.selectable_value(&mut anchor.0[0], egui::Align::Center, "Center");
ui.selectable_value(&mut anchor.0[0], egui::Align::RIGHT, "Right");
ui.selectable_value(&mut anchor[0], egui::Align::LEFT, "Left");
ui.selectable_value(&mut anchor[0], egui::Align::Center, "Center");
ui.selectable_value(&mut anchor[0], egui::Align::RIGHT, "Right");
});
ui.horizontal(|ui| {
ui.label("y:");
ui.selectable_value(&mut anchor.0[1], egui::Align::TOP, "Top");
ui.selectable_value(&mut anchor.0[1], egui::Align::Center, "Center");
ui.selectable_value(&mut anchor.0[1], egui::Align::BOTTOM, "Bottom");
ui.selectable_value(&mut anchor[1], egui::Align::TOP, "Top");
ui.selectable_value(&mut anchor[1], egui::Align::Center, "Center");
ui.selectable_value(&mut anchor[1], egui::Align::BOTTOM, "Bottom");
});
ui.horizontal(|ui| {
ui.label("Offset:");

View File

@@ -12,7 +12,7 @@ impl super::Demo for WindowWithPanels {
let window = egui::Window::new("Window with Panels")
.default_width(600.0)
.default_height(400.0)
.scroll(false)
.vscroll(false)
.open(open);
window.show(ctx, |ui| self.ui(ui));
}
@@ -26,7 +26,7 @@ impl super::View for WindowWithPanels {
.resizable(true)
.min_height(32.0)
.show_inside(ui, |ui| {
egui::ScrollArea::auto_sized().show(ui, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
ui.vertical_centered(|ui| {
ui.heading("Expandable Upper Panel");
});
@@ -42,7 +42,7 @@ impl super::View for WindowWithPanels {
ui.vertical_centered(|ui| {
ui.heading("Left Panel");
});
egui::ScrollArea::auto_sized().show(ui, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
ui.add(egui::Label::new(crate::LOREM_IPSUM_LONG).small().weak());
});
});
@@ -55,7 +55,7 @@ impl super::View for WindowWithPanels {
ui.vertical_centered(|ui| {
ui.heading("Right Panel");
});
egui::ScrollArea::auto_sized().show(ui, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
ui.add(egui::Label::new(crate::LOREM_IPSUM_LONG).small().weak());
});
});
@@ -73,7 +73,7 @@ impl super::View for WindowWithPanels {
ui.vertical_centered(|ui| {
ui.heading("Central Panel");
});
egui::ScrollArea::auto_sized().show(ui, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
ui.add(egui::Label::new(crate::LOREM_IPSUM_LONG).small().weak());
});
});

View File

@@ -264,7 +264,7 @@ fn ui_resource(
ui.separator();
egui::ScrollArea::auto_sized().show(ui, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
if let Some(image) = image {
if let Some(texture_id) = tex_mngr.texture(frame, &response.url, image) {
let size = egui::Vec2::new(image.size.0 as f32, image.size.1 as f32);

View File

@@ -323,14 +323,14 @@ impl EguiWindows {
egui::Window::new("🔧 Settings")
.open(settings)
.scroll(true)
.vscroll(true)
.show(ctx, |ui| {
ctx.settings_ui(ui);
});
egui::Window::new("🔍 Inspection")
.open(inspection)
.scroll(true)
.vscroll(true)
.show(ctx, |ui| {
ctx.inspection_ui(ui);
});

View File

@@ -34,14 +34,14 @@ impl EasyMarkEditor {
});
ui.separator();
ui.columns(2, |columns| {
ScrollArea::auto_sized()
ScrollArea::vertical()
.id_source("source")
.show(&mut columns[0], |ui| {
ui.add(TextEdit::multiline(&mut self.code).text_style(TextStyle::Monospace));
// let cursor = TextEdit::cursor(response.id);
// TODO: cmd-i, cmd-b, etc for italics, bold, ....
});
ScrollArea::auto_sized()
ScrollArea::vertical()
.id_source("rendered")
.show(&mut columns[1], |ui| {
crate::easy_mark::easy_mark(ui, &self.code);