mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 06:10:06 -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:
@@ -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!());
|
||||
});
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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| {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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| {
|
||||
|
||||
@@ -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:");
|
||||
|
||||
@@ -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());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user