Clean up various small TODOs

This commit is contained in:
Emil Ernerfeldt 2020-10-01 22:40:49 +02:00
parent 6fcfb52aa0
commit 5cba44eaa8
9 changed files with 56 additions and 26 deletions

48
TODO.md
View file

@ -3,6 +3,10 @@
TODO-list for the Egui project. If you looking for something to do, look here.
* Widgets
* [ ] Tooltips:
* [ ] Tooltip widget: Something that looks like this: (?) :that shows text on hover.
* [ ] ui.info_button().tooltip_text("More info here");
* [ ] Allow adding multiple tooltips to the same widget, showing them all one after the other.
* [ ] Text input
* [x] Input
* [x] Text focus
@ -37,16 +41,17 @@ TODO-list for the Egui project. If you looking for something to do, look here.
* [ ] Get modifier keys
* [ ] Keyboard shortcuts
* [ ] Copy, paste, undo, ...
* [ ] Text
* Text
* [/] Unicode
* [x] Shared mutable expanding texture map
* [ ] Text editing of unicode
* [ ] Change text style/color and continue in same layout
* [ ] Menu bar (File, Edit, etc)
* Menu bar (File, Edit, etc)
* [ ] Sub-menus
* [ ] Keyboard shortcuts
* [ ] Layout
* Layout
* [x] Generalize Layout (separate from Ui)
* [ ] Break out `Region` with min_size + max_size + cursor + layout
* [ ] Table with resizable columns
* [ ] Grid layout
* [ ] Point list
@ -54,9 +59,6 @@ TODO-list for the Egui project. If you looking for something to do, look here.
* [ ] Positioning preference: `window.preference(Top, Right)`
* [ ] Keeping right/bottom on expand. Maybe cover jitteryness with quick animation?
* [ ] Make auto-positioning of windows respect permanent side-bars.
* [x] Image support
* [x] Show user textures
* [x] API for creating a texture managed by `egui::app::Backend`
* Visuals
* [x] Pixel-perfect painting (round positions to nearest pixel).
* [x] Fix `aa_size`: should be 1, currently fudged at 1.5
@ -66,9 +68,7 @@ TODO-list for the Egui project. If you looking for something to do, look here.
* [x] sRGBA decode in fragment shader
* [ ] Fix alpha blending / sRGB weirdness in WebGL (EXT_sRGB)
* [ ] Thin circles look bad
* [ ] Allow adding multiple tooltips to the same widget, showing them all one after the other.
* Math
* [x] Change `width.min(max_width)` to `width.at_most(max_width)`
* [ ] Optimize small filled circles with the global texture.
* Id
* struct TempId(u64); struct StateId(u64);
* `TempId` is count-based. Only good for interaction. Can't be used for storing state.
@ -79,14 +79,32 @@ TODO-list for the Egui project. If you looking for something to do, look here.
* Manual layout example:
* ui.child_ui_pos(pos).label("Label at specific position");
* ui.child_ui_rect(rect).label("Label in a rectangle");
* Reactive mode
* [ ] Ask Egui if an event requires repainting
* [ ] Only repaint when mouse is over a Egui window (or is pressed and there is an active widget)
## egui_web
## Backends
* [ ] Extract egui_app as egui_backend
* egui_glium
* egui_web
* [ ] async HTTP requests
* [ ] egui_bitmap: slow reference rasterizer for tests
* Port https://github.com/emilk/imgui_software_renderer
* Less important: fast rasterizer for embedded 🤷‍♀️
* [ ] egui_terminal (think ncurses)
* [ ] replace `round_to_pixel` with `round_to_X` where user can select X to be e.g. width of a letter
* [ ] egui_svg: No idea what this would be for :)
### egui_web
* [x] Scroll input
* [x] Change to resize cursor on hover
* [x] Port most code to Rust
* [x] Read url fragment and redirect to a subpage (e.g. different examples apps)]
* [ ] Fix WebGL colors/beldning (try EXT_sRGB)
* [ ] Async HTTP requests
* [ ] Fix WebGL colors/blending (try EXT_sRGB)
* [ ] Embeddability
* [ ] Support canvas that does NOT cover entire screen.
* [ ] Support multiple eguis in one web page.
@ -101,7 +119,7 @@ TODO-list for the Egui project. If you looking for something to do, look here.
* [ ] `trait Container` (`Frame`, `Resize`, `ScrollArea`, ...)
* [ ] `widget::TextButton` implemented as a `container::Button` which contains a `widget::Label`.
* [ ] Easily chain `Container`s without nested closures.
* e.g. `ui.containers((Frame::new(), Resize::new(), ScrollArea::new()), |ui| ...)`
* e.g. `ui.wrap(Frame::new()).wrap(Resize::new()).wrap(ScrollArea::new()).show(|ui| ...)`
* [ ] Attach labels to checkboxes, radio buttons and sliders with a separate wrapper-widget ?
### Refactor space allocation
@ -112,6 +130,8 @@ When painting a widget, you want to allocate space. On that space you sometimes
* `ui.canvas(size) -> Paint`
* `ui.child_ui(size) -> Ui`
This is a good place to support whole-widget culling. If a swidget is not visible, the above functions should maybe return `None` so that the widget code can early-out.
## Other
* [x] Persist UI state in external storage
@ -120,6 +140,7 @@ When painting a widget, you want to allocate space. On that space you sometimes
* [ ] Build in a profiler which tracks which `Ui` in which window takes up CPU.
* [ ] Draw as flame graph
* [ ] Draw as hotmap
* [ ] Integrate puffin?
* [ ] Windows should open from `UI`s and be boxed by parent ui.
* Then we could open the example app inside a window in the example app, recursively.
* [ ] Implement a minimal markdown viewer
@ -157,3 +178,6 @@ Ability to do a search for any widget. The search works even for collapsed regio
* [x] Use clip rectangles when interacting
* [x] Adjust clip rects so edges of child widgets aren't clipped
* [x] Use HW clip rects
* [x] Image support
* [x] Show user textures
* [x] API for creating a texture managed by `egui::app::Backend`

View file

@ -286,7 +286,6 @@ impl<'open> Window<'open> {
let outer_rect = frame.end(&mut area_content_ui);
if possible.resizable {
// TODO: draw BEHIND contents ?
paint_resize_corner(&mut area_content_ui, outer_rect, frame_stroke);
}

View file

@ -142,7 +142,7 @@ impl FrameHistory {
for (time, cpu_usage) in history.iter() {
let age = (right_side_time - time) as f32;
let x = remap(age, history.max_age()..=0.0, rect.range_x());
let x = remap(age, history.max_age()..=0.0, rect.x_range());
let y = remap_clamp(cpu_usage, 0.0..=graph_top_cpu_usage, rect.bottom_up_range());
cmds.push(PaintCmd::line_segment(

View file

@ -269,7 +269,7 @@ fn vertex_gradient(ui: &mut Ui, bg_fill: Srgba, gradient: &Gradient) -> Response
let mut triangles = Triangles::default();
for (i, &color) in gradient.0.iter().enumerate() {
let t = i as f32 / (n as f32 - 1.0);
let x = lerp(rect.range_x(), t);
let x = lerp(rect.x_range(), t);
triangles.colored_vertex(pos2(x, rect.top()), color);
triangles.colored_vertex(pos2(x, rect.bottom()), color);
if i < n - 1 {

View file

@ -32,8 +32,8 @@ impl Texture {
show_tooltip(ui.ctx(), |ui| {
let pos = ui.input().mouse.pos.unwrap_or_else(|| ui.left_top());
let zoom_rect = ui.allocate_space(vec2(128.0, 128.0));
let u = remap_clamp(pos.x, rect.range_x(), 0.0..=tex_w);
let v = remap_clamp(pos.y, rect.range_y(), 0.0..=tex_h);
let u = remap_clamp(pos.x, rect.x_range(), 0.0..=tex_w);
let v = remap_clamp(pos.y, rect.y_range(), 0.0..=tex_h);
let texel_radius = 32.0;
let u = u.at_least(texel_radius).at_most(tex_w - texel_radius);

View file

@ -139,14 +139,12 @@ impl Rect {
self.width() * self.height()
}
pub fn range_x(&self) -> RangeInclusive<f32> {
pub fn x_range(&self) -> RangeInclusive<f32> {
self.min.x..=self.max.x
}
pub fn range_y(&self) -> RangeInclusive<f32> {
pub fn y_range(&self) -> RangeInclusive<f32> {
self.min.y..=self.max.y
}
pub fn bottom_up_range(&self) -> RangeInclusive<f32> {
self.max.y..=self.min.y
}

View file

@ -711,8 +711,13 @@ impl Ui {
}
/// Start a ui with horizontal layout.
/// Elements will be centered on the Y axis.
/// Initial height is `style.spacing.interact_size.y`.
/// After you have called this, the registers the contents as any other widget.
///
/// Elements will be centered on the Y axis, i.e.
/// adjusted up and down to lie in the center of the horizontal layout.
/// The initial height is `style.spacing.interact_size.y`.
/// Centering is almost always what you want if you are
/// planning to to mix widgets or just different types of text.
pub fn horizontal<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Rect) {
let initial_size = vec2(
self.available().width(),

View file

@ -367,6 +367,7 @@ impl<'a> Widget for Checkbox<'a> {
let mut desired_size =
button_padding + vec2(icon_width + icon_spacing, 0.0) + galley.size + button_padding;
desired_size = desired_size.at_least(spacing.interact_size);
desired_size.y = desired_size.y.max(icon_width);
let rect = ui.allocate_space(desired_size);
let response = ui.interact(rect, id, Sense::click());
@ -450,6 +451,7 @@ impl Widget for RadioButton {
let mut desired_size =
button_padding + vec2(icon_width + icon_spacing, 0.0) + galley.size + button_padding;
desired_size = desired_size.at_least(ui.style().spacing.interact_size);
desired_size.y = desired_size.y.max(icon_width);
let rect = ui.allocate_space(desired_size);
let response = ui.interact(rect, id, Sense::click());

View file

@ -63,8 +63,10 @@ pub fn input_to_egui(
}
KeyboardInput { input, .. } => {
if let Some(virtual_keycode) = input.virtual_keycode {
// TODO: If mac
if input.modifiers.logo() && virtual_keycode == VirtualKeyCode::Q {
if cfg!(target_os = "macos")
&& input.modifiers.logo()
&& virtual_keycode == VirtualKeyCode::Q
{
*control_flow = ControlFlow::Exit;
}
@ -174,7 +176,7 @@ pub fn handle_output(
) {
if let Some(url) = output.open_url {
if let Err(err) = webbrowser::open(&url) {
eprintln!("Failed to open url: {}", err); // TODO show error in imgui
eprintln!("Failed to open url: {}", err);
}
}