Replace TODO: with TODO(emilk): and update code guidelines

This commit is contained in:
Emil Ernerfeldt 2022-05-21 16:53:25 +02:00
parent 3d5e203d86
commit f3e305a646
60 changed files with 140 additions and 112 deletions

View file

@ -59,15 +59,44 @@ Conventions unless otherwise specified:
While using an immediate mode gui is simple, implementing one is a lot more tricky. There are many subtle corner-case you need to think through. The `egui` source code is a bit messy, partially because it is still evolving.
* read some code before writing your own
* follow the `egui` code style
* add blank lines around all `fn`, `struct`, `enum`, etc.
* `// Comment like this`, not `//like this`
* write idiomatic rust
* avoid `unsafe`
* avoid code that can cause panics
* use good names for everything
* add docstrings to types, `struct` fields and all `pub fn`.
* add some example code (doc-tests)
* before making a function longer, consider adding a helper function
* break the above rules when it makes sense
* Read some code before writing your own.
* Follow the `egui` code style.
* Add blank lines around all `fn`, `struct`, `enum`, etc.
* `// Comment like this.` and not `//like this`.
* Use `TODO` instead of `FIXME`.
* Add your github handle to the `TODO`:s you write, e.g: `TODO(emilk): clean this up`.
* Write idiomatic rust.
* Avoid `unsafe`.
* Avoid code that can cause panics.
* Use good names for everything.
* Add docstrings to types, `struct` fields and all `pub fn`.
* Add some example code (doc-tests).
* Before making a function longer, consider adding a helper function.
* If you are only using it in one function, put the `use` statement in that function. This improves locality, making it easier to read and move the code.
* When importing a `trait` to use it's trait methods, do this: `use Trait as _;`. That lets the reader know why you imported it, even though it seems unused.
* Follow the [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/).
* Break the above rules when it makes sense.
### Good:
``` rust
/// The name of the thing.
fn name(&self) -> &str {
&self.name
}
fn foo(&self) {
// TODO(emilk): implement
}
```
### Bad:
``` rust
//some function
fn get_name(&self) -> &str {
&self.name
}
fn foo(&self) {
//FIXME: implement
}
```

View file

@ -180,7 +180,7 @@ pub fn run_glow(
if integration.should_quit() {
*control_flow = winit::event_loop::ControlFlow::Exit;
}
window.request_redraw(); // TODO: ask egui if the events warrants a repaint instead
window.request_redraw(); // TODO(emilk): ask egui if the events warrants a repaint instead
}
winit::event::Event::LoopDestroyed => {
integration.save(&mut *app, window);
@ -193,7 +193,7 @@ pub fn run_glow(
});
}
// TODO: merge with with the clone above
// TODO(emilk): merge with with the clone above
/// Run an egui app
#[cfg(feature = "wgpu")]
pub fn run_wgpu(
@ -329,7 +329,7 @@ pub fn run_wgpu(
if integration.should_quit() {
*control_flow = winit::event_loop::ControlFlow::Exit;
}
window.request_redraw(); // TODO: ask egui if the events warrants a repaint instead
window.request_redraw(); // TODO(emilk): ask egui if the events warrants a repaint instead
}
winit::event::Event::LoopDestroyed => {
integration.save(&mut *app, window);

View file

@ -270,7 +270,7 @@ impl AppRunner {
let epi::backend::AppOutput {
quit: _, // Can't quit a web page
window_size: _, // Can't resize a web page
window_title: _, // TODO: change title of window
window_title: _, // TODO(emilk): change title of window
decorated: _, // Can't toggle decorations
drag_window: _, // Can't be dragged
window_pos: _, // Can't set position of a web page
@ -406,7 +406,7 @@ fn start_runner(app_runner: AppRunner) -> Result<AppRunnerRef, JsValue> {
super::events::install_canvas_events(&runner_container)?;
super::events::install_document_events(&runner_container)?;
text_agent::install_text_agent(&runner_container)?;
super::events::repaint_every_ms(&runner_container, 1000)?; // just in case. TODO: make it a parameter
super::events::repaint_every_ms(&runner_container, 1000)?; // just in case. TODO(emilk): make it a parameter
super::events::paint_and_schedule(&runner_container.runner, runner_container.panicked.clone())?;

View file

@ -252,7 +252,7 @@ pub(crate) fn webgl1_requires_brightening(gl: &web_sys::WebGlRenderingContext) -
fn is_safari_and_webkit_gtk(gl: &web_sys::WebGlRenderingContext) -> bool {
// This call produces a warning in Firefox ("WEBGL_debug_renderer_info is deprecated in Firefox and will be removed.")
// but unless we call it we get errors in Chrome when we call `get_parameter` below.
// TODO: do something smart based on user agent?
// TODO(emilk): do something smart based on user agent?
if gl
.get_extension("WEBGL_debug_renderer_info")
.unwrap()

View file

@ -44,7 +44,7 @@ impl Painter {
format: surface_format,
width: size.width as u32,
height: size.height as u32,
present_mode: wgpu::PresentMode::Fifo, // TODO: make vsync configurable
present_mode: wgpu::PresentMode::Fifo, // TODO(emilk): make vsync configurable
};
surface.configure(&device, &surface_config);
@ -143,6 +143,6 @@ impl Painter {
#[allow(clippy::unused_self)]
pub fn destroy(&mut self) {
// TODO: something here?
// TODO(emilk): something here?
}
}

View file

@ -7,7 +7,7 @@ use std::{fmt::Debug, hash::Hash};
use crate::*;
/// State that is persisted between frames.
// TODO: this is not currently stored in `memory().data`, but maybe it should be?
// TODO(emilk): this is not currently stored in `memory().data`, but maybe it should be?
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub(crate) struct State {

View file

@ -485,7 +485,7 @@ impl CollapsingHeader {
show_background,
} = self;
// TODO: horizontal layout, with icon and text as labels. Insert background behind using Frame.
// TODO(emilk): horizontal layout, with icon and text as labels. Insert background behind using Frame.
let id = ui.make_persistent_id(id_source);
let button_padding = ui.spacing().button_padding;

View file

@ -52,7 +52,7 @@ impl Default for Resize {
resizable: true,
min_size: Vec2::splat(16.0),
max_size: Vec2::splat(f32::INFINITY),
default_size: vec2(320.0, 128.0), // TODO: preferred size of [`Resize`] area.
default_size: vec2(320.0, 128.0), // TODO(emilk): preferred size of [`Resize`] area.
with_stroke: true,
}
}

View file

@ -592,7 +592,7 @@ impl Prepared {
- current_bar_use[d]
- ui.spacing().item_spacing[d];
inner_rect.max[d] = inner_rect.max[d].at_most(max);
// TODO: maybe auto-enable horizontal/vertical scrolling if this limit is reached
// TODO(emilk): maybe auto-enable horizontal/vertical scrolling if this limit is reached
}
}

View file

@ -507,7 +507,7 @@ fn interact(
let new_rect = ctx.constrain_window_rect_to_area(new_rect, area.drag_bounds());
// TODO: add this to a Window state instead as a command "move here next frame"
// TODO(emilk): add this to a Window state instead as a command "move here next frame"
area.state_mut().pos = new_rect.min;
if window_interaction.is_resize() {

View file

@ -1227,7 +1227,7 @@ impl Context {
continue;
}
let text = format!("{} - {:?}", layer_id.short_debug_format(), area.rect(),);
// TODO: `Sense::hover_highlight()`
// TODO(emilk): `Sense::hover_highlight()`
if ui
.add(Label::new(RichText::new(text).monospace()).sense(Sense::click()))
.hovered

View file

@ -506,7 +506,7 @@ impl WidgetInfo {
text_selection: _,
} = self;
// TODO: localization
// TODO(emilk): localization
let widget_type = match typ {
WidgetType::Link => "link",
WidgetType::TextEdit => "text edit",

View file

@ -37,7 +37,7 @@ pub(crate) struct FrameState {
/// Set to [`InputState::scroll_delta`] on the start of each frame.
///
/// Cleared by the first [`ScrollArea`] that makes use of it.
pub(crate) scroll_delta: Vec2, // TODO: move to a Mutex inside of `InputState` ?
pub(crate) scroll_delta: Vec2, // TODO(emilk): move to `InputState` ?
/// horizontal, vertical
pub(crate) scroll_target: [Option<(RangeInclusive<f32>, Option<Align>)>; 2],

View file

@ -74,7 +74,7 @@ impl GridLayout {
pub(crate) fn new(ui: &Ui, id: Id) -> Self {
let prev_state = State::load(ui.ctx(), id).unwrap_or_default();
// TODO: respect current layout
// TODO(emilk): respect current layout
let initial_available = ui.placer().max_rect().intersect(ui.cursor());
crate::egui_assert!(
@ -126,7 +126,7 @@ impl GridLayout {
let width = if is_last_column {
(self.initial_available.right() - region.cursor.left()).at_most(self.max_cell_size.x)
} else if self.max_cell_size.x.is_finite() {
// TODO: should probably heed `prev_state` here too
// TODO(emilk): should probably heed `prev_state` here too
self.max_cell_size.x
} else {
// If we want to allow width-filling widgets like [`Separator`] in one of the first cells
@ -159,7 +159,7 @@ impl GridLayout {
#[allow(clippy::unused_self)]
pub(crate) fn align_size_within_rect(&self, size: Vec2, frame: Rect) -> Rect {
// TODO: allow this alignment to be customized
// TODO(emilk): allow this alignment to be customized
Align2::LEFT_CENTER.align_size_within_rect(size, frame)
}

View file

@ -1,4 +1,4 @@
// TODO: have separate types `PositionId` and `UniqueId`. ?
// TODO(emilk): have separate types `PositionId` and `UniqueId`. ?
/// egui tracks widgets frame-to-frame using [`Id`]s.
///

View file

@ -9,13 +9,13 @@ pub use touch_state::MultiTouchInfo;
use touch_state::TouchState;
/// If the pointer moves more than this, it won't become a click (but it is still a drag)
const MAX_CLICK_DIST: f32 = 6.0; // TODO: move to settings
const MAX_CLICK_DIST: f32 = 6.0; // TODO(emilk): move to settings
/// If the pointer is down for longer than this, it won't become a click (but it is still a drag)
const MAX_CLICK_DURATION: f64 = 0.6; // TODO: move to settings
const MAX_CLICK_DURATION: f64 = 0.6; // TODO(emilk): move to settings
/// The new pointer press must come within this many seconds from previous pointer release
const MAX_DOUBLE_CLICK_DELAY: f64 = 0.3; // TODO: move to settings
const MAX_DOUBLE_CLICK_DELAY: f64 = 0.3; // TODO(emilk): move to settings
/// Input state that egui updates each frame.
///
@ -192,7 +192,7 @@ impl InputState {
stable_dt,
modifiers: new.modifiers,
keys_down,
events: new.events.clone(), // TODO: remove clone() and use raw.events
events: new.events.clone(), // TODO(emilk): remove clone() and use raw.events
raw: new,
}
}
@ -324,7 +324,7 @@ impl InputState {
/// Returns imprecision in points.
#[inline(always)]
pub fn aim_radius(&self) -> f32 {
// TODO: multiply by ~3 for touch inputs because fingers are fat
// TODO(emilk): multiply by ~3 for touch inputs because fingers are fat
self.physical_pixel_size()
}

View file

@ -144,7 +144,7 @@ pub struct Layout {
impl Default for Layout {
fn default() -> Self {
// TODO: Get from `Style` instead.
// TODO(emilk): Get from `Style` instead.
Self::top_down(Align::LEFT) // This is a very euro-centric default.
}
}

View file

@ -497,7 +497,7 @@ pub mod special_emojis {
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum WidgetType {
Label, // TODO: emit Label events
Label, // TODO(emilk): emit Label events
/// e.g. a hyperlink
Link,
TextEdit,

View file

@ -142,7 +142,7 @@ pub(crate) fn menu_ui<'c, R>(
Frame::menu(style)
.show(ui, |ui| {
const DEFAULT_MENU_WIDTH: f32 = 150.0; // TODO: add to ui.spacing
const DEFAULT_MENU_WIDTH: f32 = 150.0; // TODO(emilk): add to ui.spacing
ui.set_max_width(DEFAULT_MENU_WIDTH);
ui.set_menu_state(Some(menu_state_arc.clone()));
ui.with_layout(Layout::top_down_justified(Align::LEFT), add_contents)

View file

@ -46,7 +46,7 @@ pub struct Response {
#[doc(hidden)]
pub clicked: [bool; NUM_POINTER_BUTTONS],
// TODO: `released` for sliders
// TODO(emilk): `released` for sliders
/// The thing was double-clicked.
#[doc(hidden)]
pub double_clicked: [bool; NUM_POINTER_BUTTONS],

View file

@ -204,7 +204,7 @@ pub struct Style {
}
impl Style {
// TODO: rename style.interact() to maybe... `style.interactive` ?
// TODO(emilk): rename style.interact() to maybe... `style.interactive` ?
/// Use this style for interactive things.
/// Note that you must already have a response,
/// i.e. you must allocate space and interact BEFORE painting the widget!
@ -258,10 +258,10 @@ pub struct Spacing {
/// Minimum size of a [`DragValue`], color picker button, and other small widgets.
/// `interact_size.y` is the default height of button, slider, etc.
/// Anything clickable should be (at least) this size.
pub interact_size: Vec2, // TODO: rename min_interact_size ?
pub interact_size: Vec2, // TODO(emilk): rename min_interact_size ?
/// Default width of a [`Slider`] and [`ComboBox`](crate::ComboBox).
pub slider_width: f32, // TODO: rename big_interact_size ?
pub slider_width: f32, // TODO(emilk): rename big_interact_size ?
/// Default width of a [`TextEdit`].
pub text_edit_width: f32,
@ -1226,7 +1226,7 @@ impl DebugOptions {
}
}
// TODO: improve and standardize `slider_vec2`
// TODO(emilk): improve and standardize `slider_vec2`
fn slider_vec2<'a>(
value: &'a mut Vec2,
range: std::ops::RangeInclusive<f32>,

View file

@ -1037,7 +1037,7 @@ impl Ui {
/// # });
/// ```
pub fn add_sized(&mut self, max_size: impl Into<Vec2>, widget: impl Widget) -> Response {
// TODO: configure to overflow to main_dir instead of centered overflow
// TODO(emilk): configure to overflow to main_dir instead of centered overflow
// to handle the bug mentioned at https://github.com/emilk/egui/discussions/318#discussioncomment-627578
// and fixed in https://github.com/emilk/egui/commit/035166276322b3f2324bd8b97ffcedc63fa8419f
//
@ -1721,7 +1721,7 @@ impl Ui {
/// Create a child ui which is indented to the right.
///
/// The `id_source` here be anything at all.
// TODO: remove `id_source` argument?
// TODO(emilk): remove `id_source` argument?
#[inline]
pub fn indent<R>(
&mut self,
@ -2037,7 +2037,7 @@ impl Ui {
num_columns: usize,
add_contents: Box<dyn FnOnce(&mut [Self]) -> R + 'c>,
) -> R {
// TODO: ensure there is space
// TODO(emilk): ensure there is space
let spacing = self.spacing().item_spacing.x;
let total_spacing = spacing * (num_columns as f32 - 1.0);
let column_width = (self.available_width() - total_spacing) / (num_columns as f32);

View file

@ -2,7 +2,7 @@ use epaint::util::hash;
const FIXED_CACHE_SIZE: usize = 1024; // must be small for web/WASM build (for unknown reason)
/// Very stupid/simple key-value cache. TODO: improve
/// Very stupid/simple key-value cache. TODO(emilk): improve
#[derive(Clone)]
pub(crate) struct FixedCache<K, V>([Option<(K, V)>; FIXED_CACHE_SIZE]);

View file

@ -108,7 +108,7 @@ where
/// `(time, value)` pairs
/// Time difference between values can be zero, but never negative.
// TODO: impl IntoIter
// TODO(emilk): impl IntoIter
pub fn iter(&'_ self) -> impl ExactSizeIterator<Item = (f64, T)> + '_ {
self.values.iter().map(|(time, value)| (*time, *value))
}

View file

@ -1,4 +1,4 @@
// TODO: it is possible we can simplify `Element` further by
// TODO(emilk): it is possible we can simplify `Element` further by
// assuming everything is possibly serializable, and by supplying serialize/deserialize functions for them.
// For non-serializable types, these simply return `None`.
// This will also allow users to pick their own serialization format per type.
@ -292,7 +292,7 @@ fn from_ron_str<T: serde::de::DeserializeOwned>(ron: &str) -> Option<T> {
use crate::Id;
// TODO: make IdTypeMap generic over the key (`Id`), and make a library of IdTypeMap.
// TODO(emilk): make IdTypeMap generic over the key (`Id`), and make a library of IdTypeMap.
/// Stores values identified by an [`Id`] AND a the [`std::any::TypeId`] of the value.
///
/// In other words, it maps `(Id, TypeId)` to any value you want.

View file

@ -203,7 +203,7 @@ impl Widget for Button {
// ----------------------------------------------------------------------------
// TODO: allow checkbox without a text label
// TODO(emilk): allow checkbox without a text label
/// Boolean on/off control with text label.
///
/// Usually you'd use [`Ui::checkbox`] instead.

View file

@ -350,7 +350,7 @@ pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Res
if button_response.clicked() {
ui.memory().toggle_popup(popup_id);
}
// TODO: make it easier to show a temporary popup that closes when you click outside it
// TODO(emilk): make it easier to show a temporary popup that closes when you click outside it
if ui.memory().is_popup_open(popup_id) {
let area_response = Area::new(popup_id)
.order(Order::Foreground)

View file

@ -112,7 +112,7 @@ impl<'a> DragValue<'a> {
self
}
// TODO: we should also have a "min precision".
// TODO(emilk): we should also have a "min precision".
/// Set a minimum number of decimals to display.
/// Normally you don't need to pick a precision, as the slider will intelligently pick a precision for you.
/// Regardless of precision the slider will use "smart aim" to help the user select nice, round values.
@ -121,7 +121,7 @@ impl<'a> DragValue<'a> {
self
}
// TODO: we should also have a "max precision".
// TODO(emilk): we should also have a "max precision".
/// Set a maximum number of decimals to display.
/// Values will also be rounded to this number of decimals.
/// Normally you don't need to pick a precision, as the slider will intelligently pick a precision for you.
@ -214,7 +214,7 @@ impl<'a> Widget for DragValue<'a> {
)
.wrap(false)
.sense(Sense::click_and_drag())
.min_size(ui.spacing().interact_size); // TODO: find some more generic solution to `min_size`
.min_size(ui.spacing().interact_size); // TODO(emilk): find some more generic solution to `min_size`
let response = ui.add(button);
let mut response = response.on_hover_cursor(CursorIcon::ResizeHorizontal);
@ -223,7 +223,7 @@ impl<'a> Widget for DragValue<'a> {
response = response .on_hover_text(format!(
"{}{}{}\nDrag to edit or click to enter a value.\nPress 'Shift' while dragging for better control.",
prefix,
value as f32, // Show full precision value on-hover. TODO: figure out f64 vs f32
value as f32, // Show full precision value on-hover. TODO(emilk): figure out f64 vs f32
suffix
));
}

View file

@ -116,7 +116,7 @@ impl Image {
}
{
// TODO: builder pattern for Mesh
// TODO(emilk): builder pattern for Mesh
let mut mesh = Mesh::with_texture(*texture_id);
mesh.add_rect_with_uv(rect, *uv, *tint);
if let Some((rot, origin)) = rotation {

View file

@ -135,7 +135,7 @@ impl Label {
};
if ui.is_grid() {
// TODO: remove special Grid hacks like these
// TODO(emilk): remove special Grid hacks like these
text_job.job.halign = Align::LEFT;
text_job.job.justify = false;
} else {

View file

@ -347,7 +347,7 @@ impl ExplicitGenerator {
let max_x = *self.x_range.end();
let min_y = (self.function)(min_x);
let max_y = (self.function)(max_x);
// TODO: sample some more points
// TODO(emilk): sample some more points
PlotBounds {
min: [min_x, min_y],
max: [max_x, max_y],

View file

@ -65,7 +65,7 @@ impl Default for CoordinatesFormatter {
// ----------------------------------------------------------------------------
const MIN_LINE_SPACING_IN_POINTS: f64 = 6.0; // TODO: large enough for a wide label
const MIN_LINE_SPACING_IN_POINTS: f64 = 6.0; // TODO(emilk): large enough for a wide label
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Clone)]
@ -867,7 +867,7 @@ impl PlotUi {
self.next_auto_color_idx += 1;
let golden_ratio = (5.0_f32.sqrt() - 1.0) / 2.0; // 0.61803398875
let h = i as f32 * golden_ratio;
Hsva::new(h, 0.85, 0.5, 1.0).into() // TODO: OkLab or some other perspective color space
Hsva::new(h, 0.85, 0.5, 1.0).into() // TODO(emilk): OkLab or some other perspective color space
}
pub fn ctx(&self) -> &Context {

View file

@ -212,7 +212,7 @@ impl<'a> Slider<'a> {
self
}
// TODO: we should also have a "min precision".
// TODO(emilk): we should also have a "min precision".
/// Set a minimum number of decimals to display.
/// Normally you don't need to pick a precision, as the slider will intelligently pick a precision for you.
/// Regardless of precision the slider will use "smart aim" to help the user select nice, round values.
@ -221,7 +221,7 @@ impl<'a> Slider<'a> {
self
}
// TODO: we should also have a "max precision".
// TODO(emilk): we should also have a "max precision".
/// Set a maximum number of decimals to display.
/// Values will also be rounded to this number of decimals.
/// Normally you don't need to pick a precision, as the slider will intelligently pick a precision for you.
@ -485,7 +485,7 @@ impl<'a> Slider<'a> {
/// delta(value) / delta(points)
fn current_gradient(&mut self, position_range: &RangeInclusive<f32>) -> f64 {
// TODO: handle clamping
// TODO(emilk): handle clamping
let value = self.get_value();
let value_from_pos =
|position: f32| self.value_from_position(position, position_range.clone());

View file

@ -312,7 +312,7 @@ impl<'t> TextEdit<'t> {
rect: frame_rect,
rounding: visuals.rounding,
fill: ui.visuals().extreme_bg_color,
stroke: visuals.bg_stroke, // TODO: we want to show something here, or a text-edit field doesn't "pop".
stroke: visuals.bg_stroke, // TODO(emilk): we want to show something here, or a text-edit field doesn't "pop".
}
}
} else {
@ -323,7 +323,7 @@ impl<'t> TextEdit<'t> {
// fill: ui.visuals().extreme_bg_color,
// fill: visuals.bg_fill,
fill: Color32::TRANSPARENT,
stroke: visuals.bg_stroke, // TODO: we want to show something here, or a text-edit field doesn't "pop".
stroke: visuals.bg_stroke, // TODO(emilk): we want to show something here, or a text-edit field doesn't "pop".
}
};
@ -388,7 +388,7 @@ impl<'t> TextEdit<'t> {
let desired_width = if multiline {
galley.size().x.max(wrap_width) // always show everything in multiline
} else {
wrap_width // visual clipping with scroll in singleline input. TODO: opt-in/out?
wrap_width // visual clipping with scroll in singleline input. TODO(emilk): opt-in/out?
};
let desired_height = (desired_height_rows.at_least(1) as f32) * row_height;
let desired_size = vec2(desired_width, galley.size().y.max(desired_height));
@ -430,7 +430,7 @@ impl<'t> TextEdit<'t> {
ui.output().mutable_text_under_cursor = true;
}
// TODO: drag selected text to either move or clone (ctrl on windows, alt on mac)
// TODO(emilk): drag selected text to either move or clone (ctrl on windows, alt on mac)
let singleline_offset = vec2(state.singleline_offset, 0.0);
let cursor_at_pointer =
galley.cursor_from_pos(pointer_pos - response.rect.min + singleline_offset);
@ -693,7 +693,7 @@ fn events(
let mut any_change = false;
let events = ui.input().events.clone(); // avoid dead-lock by cloning. TODO: optimize
let events = ui.input().events.clone(); // avoid dead-lock by cloning. TODO(emilk): optimize
for event in &events {
let did_mutate_text = match event {
Event::Copy => {
@ -740,7 +740,7 @@ fn events(
if multiline && ui.memory().has_lock_focus(id) {
let mut ccursor = delete_selected(text, &cursor_range);
if modifiers.shift {
// TODO: support removing indentation over a selection?
// TODO(emilk): support removing indentation over a selection?
decrease_identation(&mut ccursor, text);
} else {
insert_text(&mut ccursor, text, "\t");
@ -758,7 +758,7 @@ fn events(
if multiline {
let mut ccursor = delete_selected(text, &cursor_range);
insert_text(&mut ccursor, text, "\n");
// TODO: if code editor, auto-indent by same leading tabs, + one if the lines end on an opening bracket
// TODO(emilk): if code editor, auto-indent by same leading tabs, + one if the lines end on an opening bracket
Some(CCursorRange::one(ccursor))
} else {
ui.memory().surrender_focus(id); // End input with enter
@ -770,7 +770,7 @@ fn events(
pressed: true,
modifiers,
} if modifiers.command && !modifiers.shift => {
// TODO: redo
// TODO(emilk): redo
if let Some((undo_ccursor_range, undo_txt)) = state
.undoer
.lock()

View file

@ -21,4 +21,4 @@ pub struct TextEditOutput {
pub cursor_range: Option<super::CursorRange>,
}
// TODO: add `output.paint` and `output.store` and split out that code from `TextEdit::show`.
// TODO(emilk): add `output.paint` and `output.store` and split out that code from `TextEdit::show`.

View file

@ -65,7 +65,7 @@ impl FrameHistory {
let history = &self.frame_times;
// TODO: we should not use `slider_width` as default graph width.
// TODO(emilk): we should not use `slider_width` as default graph width.
let height = ui.spacing().slider_width;
let size = vec2(ui.available_size_before_wrap().x, height);
let (rect, response) = ui.allocate_at_least(size, Sense::hover());

View file

@ -300,7 +300,7 @@ impl WrapApp {
ui.with_layout(egui::Layout::right_to_left(), |ui| {
if false {
// TODO: fix the overlap on small screens
// TODO(emilk): fix the overlap on small screens
if let Some(seconds_since_midnight) = crate::seconds_since_midnight() {
if clock_button(ui, seconds_since_midnight).clicked() {
self.state.selected_anchor = "clock".to_owned();

View file

@ -90,7 +90,7 @@ impl ColorTest {
ui.separator();
// TODO: test color multiplication (image tint),
// TODO(emilk): test color multiplication (image tint),
// to make sure vertex and texture color multiplication is done in linear space.
self.show_gradients(ui, WHITE, (RED, GREEN));

View file

@ -64,7 +64,7 @@ impl EasyMarkEditor {
ScrollArea::vertical()
.id_source("rendered")
.show(&mut columns[1], |ui| {
// TODO: we can save some more CPU by caching the rendered output.
// TODO(emilk): we can save some more CPU by caching the rendered output.
crate::easy_mark::easy_mark(ui, &self.code);
});
});

View file

@ -10,7 +10,7 @@
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Item<'a> {
/// `\n`
// TODO: add Style here so empty heading still uses up the right amount of space.
// TODO(emilk): add Style here so empty heading still uses up the right amount of space.
Newline,
///
Text(Style, &'a str),

View file

@ -95,7 +95,7 @@ impl<'a> Widget for DatePickerButton<'a> {
if pos.x + width_with_padding > ui.clip_rect().right() {
pos.x = button_response.rect.right() - width_with_padding;
}
//TODO: Better positioning
//TODO(elwerene): Better positioning
let area_response = Area::new(ui.make_persistent_id(&self.id_source))
.order(Order::Foreground)

View file

@ -257,7 +257,7 @@ impl<'a> DatePickerPopup<'a> {
});
}
//TODO: Locale
//TODO(elwerene): Locale
for name in ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"] {
header.col(|ui| {
ui.with_layout(

View file

@ -296,7 +296,7 @@ impl<'a> Table<'a> {
let bottom = ui.min_rect().bottom();
// TODO: fix frame-delay by interacting before laying out (but painting later).
// TODO(emilk): fix frame-delay by interacting before laying out (but painting later).
if let Some(resize_id) = resize_id {
let spacing_x = ui.spacing().item_spacing.x;
let mut x = avail_rect.left() - spacing_x * 0.5;

View file

@ -83,7 +83,7 @@ fn main() {
egui_glium.on_event(&event);
display.gl_window().window().request_redraw(); // TODO: ask egui if the events warrants a repaint instead
display.gl_window().window().request_redraw(); // TODO(emilk): ask egui if the events warrants a repaint instead
}
_ => (),

View file

@ -64,7 +64,7 @@ fn main() {
egui_glium.on_event(&event);
display.gl_window().window().request_redraw(); // TODO: ask egui if the events warrants a repaint instead
display.gl_window().window().request_redraw(); // TODO(emilk): ask egui if the events warrants a repaint instead
}
_ => (),

View file

@ -133,11 +133,11 @@ impl Painter {
let vertices: &[Vertex] = bytemuck::cast_slice(&mesh.vertices);
// TODO: we should probably reuse the [`VertexBuffer`] instead of allocating a new one each frame.
// TODO(emilk): we should probably reuse the [`VertexBuffer`] instead of allocating a new one each frame.
glium::VertexBuffer::new(display, vertices).unwrap()
};
// TODO: we should probably reuse the [`IndexBuffer`] instead of allocating a new one each frame.
// TODO(emilk): we should probably reuse the [`IndexBuffer`] instead of allocating a new one each frame.
let index_buffer =
glium::IndexBuffer::new(display, PrimitiveType::TrianglesList, &mesh.indices).unwrap();

View file

@ -77,7 +77,7 @@ fn main() {
egui_glow.on_event(&event);
gl_window.window().request_redraw(); // TODO: ask egui if the events warrants a repaint instead
gl_window.window().request_redraw(); // TODO(emilk): ask egui if the events warrants a repaint instead
}
glutin::event::Event::LoopDestroyed => {
egui_glow.destroy();

View file

@ -68,7 +68,7 @@ pub struct Painter {
textures: HashMap<egui::TextureId, glow::Texture>,
next_native_tex_id: u64, // TODO: 128-bit texture space?
next_native_tex_id: u64,
/// Stores outdated OpenGL textures that are yet to be deleted
textures_to_destroy: Vec<glow::Texture>,

View file

@ -88,7 +88,7 @@ impl PostProcess {
// ---------------------------------------------------------
// Depth buffer - we only need this when embedding 3D within egui using `egui::PaintCallback`.
// TODO: add a setting to enable/disable the depth buffer.
// TODO(emilk): add a setting to enable/disable the depth buffer.
let with_depth_buffer = true;
let depth_renderbuffer = if with_depth_buffer {

View file

@ -145,7 +145,7 @@ pub fn format_with_decimals_in_range(value: f64, decimal_range: RangeInclusive<u
let min_decimals = min_decimals.min(max_decimals);
if min_decimals != max_decimals {
// Ugly/slow way of doing this. TODO: clean up precision.
// Ugly/slow way of doing this. TODO(emilk): clean up precision.
for decimals in min_decimals..max_decimals {
let text = format!("{:.*}", decimals, value);
let epsilon = 16.0 * f32::EPSILON; // margin large enough to handle most peoples round-tripping needs

View file

@ -127,7 +127,7 @@ fn test_aim() {
assert_eq!(best_in_range_f64(12.3, 65.9), 50.0, "Prefer leading 5");
assert_eq!(best_in_range_f64(493.0, 879.0), 500.0, "Prefer leading 5");
assert_eq!(best_in_range_f64(0.37, 0.48), 0.40);
// assert_eq!(best_in_range_f64(123.71, 123.76), 123.75); // TODO: we get 123.74999999999999 here
// assert_eq!(best_in_range_f64(123.71, 123.76), 123.75); // TODO(emilk): we get 123.74999999999999 here
// assert_eq!(best_in_range_f32(123.71, 123.76), 123.75);
assert_eq!(best_in_range_f64(7.5, 16.3), 10.0);
assert_eq!(best_in_range_f64(7.5, 76.3), 10.0);

View file

@ -38,7 +38,7 @@ pub struct Mesh {
/// The texture to use when drawing these triangles.
pub texture_id: TextureId,
// TODO: bounding rectangle
// TODO(emilk): bounding rectangle
}
impl Mesh {

View file

@ -47,7 +47,7 @@ impl Shadow {
}
pub fn tessellate(&self, rect: emath::Rect, rounding: impl Into<Rounding>) -> Mesh {
// tessellator.clip_rect = clip_rect; // TODO: culling
// tessellator.clip_rect = clip_rect; // TODO(emilk): culling
let Self { extrusion, color } = *self;

View file

@ -339,7 +339,7 @@ impl Path {
pub fn add_circle(&mut self, center: Pos2, radius: f32) {
use precomputed_vertices::*;
// These cutoffs are based on a high-dpi display. TODO: use pixels_per_point here?
// These cutoffs are based on a high-dpi display. TODO(emilk): use pixels_per_point here?
// same cutoffs as in add_circle_quadrant
if radius <= 2.0 {
@ -547,7 +547,7 @@ pub mod path {
pub fn add_circle_quadrant(path: &mut Vec<Pos2>, center: Pos2, radius: f32, quadrant: f32) {
use super::precomputed_vertices::*;
// These cutoffs are based on a high-dpi display. TODO: use pixels_per_point here?
// These cutoffs are based on a high-dpi display. TODO(emilk): use pixels_per_point here?
// same cutoffs as in add_circle
if radius <= 0.0 {
@ -1171,7 +1171,7 @@ impl Tessellator {
let cutoff_radius = radius_px * 2.0_f32.powf(0.25);
// Find the right disc radius for a crisp edge:
// TODO: perhaps we can do something faster than this linear search.
// TODO(emilk): perhaps we can do something faster than this linear search.
for disc in &self.prepared_discs {
if cutoff_radius <= disc.r {
let side = radius_px * disc.w / (self.pixels_per_point * disc.r);

View file

@ -66,7 +66,7 @@ pub struct FontImpl {
// move each character by this much (hack)
y_offset: f32,
pixels_per_point: f32,
glyph_info_cache: RwLock<AHashMap<char, GlyphInfo>>, // TODO: standard Mutex
glyph_info_cache: RwLock<AHashMap<char, GlyphInfo>>, // TODO(emilk): standard Mutex
atlas: Arc<Mutex<TextureAtlas>>,
}
@ -84,7 +84,7 @@ impl FontImpl {
let height_in_points = scale_in_pixels as f32 / pixels_per_point;
// TODO: use these font metrics?
// TODO(emilk): use these font metrics?
// use ab_glyph::ScaleFont as _;
// let scaled = ab_glyph_font.as_scaled(scale_in_pixels as f32);
// dbg!(scaled.ascent());
@ -212,7 +212,7 @@ impl FontImpl {
type FontIndex = usize;
// TODO: rename?
// TODO(emilk): rename?
/// Wrapper over multiple [`FontImpl`] (e.g. a primary + fallbacks for emojis)
pub struct Font {
fonts: Vec<Arc<FontImpl>>,
@ -349,7 +349,7 @@ fn invisible_char(c: char) -> bool {
// See https://github.com/emilk/egui/issues/336
// From https://www.fileformat.info/info/unicode/category/Cf/list.htm
('\u{200B}'..='\u{206F}').contains(&c) // TODO: heed bidi characters
('\u{200B}'..='\u{206F}').contains(&c) // TODO(emilk): heed bidi characters
}
fn allocate_glyph(

View file

@ -22,7 +22,7 @@ pub struct FontId {
/// What font family to use.
pub family: FontFamily,
// TODO: weight (bold), italics, …
// TODO(emilk): weight (bold), italics, …
}
impl Default for FontId {
@ -240,7 +240,6 @@ pub struct FontDefinitions {
/// When looking for a character glyph `epaint` will start with
/// the first font and then move to the second, and so on.
/// So the first font is the primary, and then comes a list of fallbacks in order of priority.
// TODO: per font size-modifier.
pub families: BTreeMap<FontFamily, Vec<String>>,
}
@ -618,7 +617,7 @@ struct GalleyCache {
impl GalleyCache {
fn layout(&mut self, fonts: &mut FontsImpl, job: LayoutJob) -> Arc<Galley> {
let hash = crate::util::hash(&job); // TODO: even faster hasher?
let hash = crate::util::hash(&job); // TODO(emilk): even faster hasher?
match self.cache.entry(hash) {
std::collections::hash_map::Entry::Occupied(entry) => {

View file

@ -98,7 +98,7 @@ fn layout_section(
let mut paragraph = out_paragraphs.last_mut().unwrap();
if paragraph.glyphs.is_empty() {
paragraph.empty_paragraph_height = font_height; // TODO: replace this hack with actually including `\n` in the glyphs?
paragraph.empty_paragraph_height = font_height; // TODO(emilk): replace this hack with actually including `\n` in the glyphs?
}
paragraph.cursor_x += leading_space;
@ -109,7 +109,7 @@ fn layout_section(
if job.break_on_newline && chr == '\n' {
out_paragraphs.push(Paragraph::default());
paragraph = out_paragraphs.last_mut().unwrap();
paragraph.empty_paragraph_height = font_height; // TODO: replace this hack with actually including `\n` in the glyphs?
paragraph.empty_paragraph_height = font_height; // TODO(emilk): replace this hack with actually including `\n` in the glyphs?
} else {
let (font_impl, glyph_info) = font.glyph_info_and_font_impl(chr);
if let Some(font_impl) = font_impl {
@ -207,7 +207,7 @@ fn line_break(
&& !row_break_candidates.has_good_candidate(job.wrap.break_anywhere)
{
// Allow the first row to be completely empty, because we know there will be more space on the next row:
// TODO: this records the height of this first row as zero, though that is probably fine since first_row_indentation usually comes with a first_row_min_height.
// TODO(emilk): this records the height of this first row as zero, though that is probably fine since first_row_indentation usually comes with a first_row_min_height.
out_rows.push(Row {
glyphs: vec![],
visuals: Default::default(),
@ -685,7 +685,7 @@ fn add_hline(point_scale: PointScale, [start, stop]: [Pos2; 2], stroke: Stroke,
let antialiased = true;
if antialiased {
let mut path = crate::tessellator::Path::default(); // TODO: reuse this to avoid re-allocations.
let mut path = crate::tessellator::Path::default(); // TODO(emilk): reuse this to avoid re-allocations.
path.add_line_segment([start, stop]);
let feathering = 1.0 / point_scale.pixels_per_point();
path.stroke_open(feathering, stroke, mesh);

View file

@ -227,7 +227,7 @@ pub struct TextFormat {
/// If you use a small font and [`Align::TOP`] you
/// can get the effect of raised text.
pub valign: Align,
// TODO: lowered
// TODO(emilk): lowered
}
impl Default for TextFormat {
@ -735,7 +735,7 @@ impl Galley {
}
}
// TODO: return identical cursor, or clamp?
// TODO(emilk): return identical cursor, or clamp?
pub fn from_pcursor(&self, pcursor: PCursor) -> Cursor {
let prefer_next_row = pcursor.prefer_next_row;
let mut ccursor_it = CCursor {

View file

@ -87,7 +87,7 @@ impl TextureAtlas {
image[pos] = 1.0;
// Allocate a series of anti-aliased discs used to render small filled circles:
// TODO: these circles can be packed A LOT better.
// TODO(emilk): these circles can be packed A LOT better.
// In fact, the whole texture atlas could be packed a lot better.
// for r in [1, 2, 4, 8, 16, 32, 64] {
// let w = 2 * r + 3;

View file

@ -49,7 +49,7 @@ cargo doc --document-private-items --no-deps --all-features
# cargo install cargo-deny
cargo deny check
# TODO: consider using https://github.com/taiki-e/cargo-hack or https://github.com/frewsxcv/cargo-all-features
# TODO(emilk): consider using https://github.com/taiki-e/cargo-hack or https://github.com/frewsxcv/cargo-all-features
# ------------------------------------------------------------
#