emilk / egui

egui: an easy-to-use immediate mode GUI in Rust that runs on both web and native
https://www.egui.rs/
Apache License 2.0
22.25k stars 1.6k forks source link

Number base specifiers for `DragValue` and `Slider` #1953

Closed Adanos020 closed 2 years ago

Adanos020 commented 2 years ago

Is your feature request related to a problem? Please describe.

The newly added custom_formatter allows for, among other things, displaying numbers in DragValue and Slider in number systems other than decimal. What I didn't consider while adding this feature is that if you type a number into those widgets on keyboard, the input is still always parsed as a decimal number.

Describe the solution you'd like

First of all, get rid of custom_formatter since having separate methods for the input and output allows to specify different number bases on both ends, which can be confusing and difficult to debug.

Add an enum called NumberBase.

#[derive(Copy, Clone, Debug)]
pub enum NumberBase {
    Binary,
    Octal,
    Decimal,
    Hexadecimal,
}

Add new fields and methods for the DragValue and Slider structs.

/// Sets the number base in which the numeric input is parsed from and displayed to the widget.
pub fn number_base(mut self, base: NumberBase) -> Self {
    self.number_base = base;
    self
}

/// Sets the minimum number of digits displayed. If the number is shorter than this, it is prefixed with a required number of zeroes.
pub fn number_width(mut self, zeroes: u32) -> Self {
    self.number_width = width;
    self
}

Describe alternatives you've considered

  1. Instead of an enum, the number base could be specified as a u8, allowing for more number systems. However, Rust's standard library doesn't provide formatting numbers with an arbitrary radix, so we would need either our own implementation for that or an additional dependency such as the radix_fmt crate.
  2. The deletion of custom_formatter comes with two drawbacks: the API breaks and the number of ways a number can be formatted becomes limited. Instead of completely replacing it with a whole new API, we could only have an additional method specifying the number base for the input. However, as I mentioned earlier, that would allow for having the inconsistency where the e.g. number would be displayed in binary but parsed in hexadecimal on input.

Additional context

--

emilk commented 2 years ago

I wouldn't like to get rid of custom_formatter since it supports many interesting scenarios such as displaying time in HH::MM::SS format, etc.

Instead it can be coupled with a custom_parser. A NumberBase API could then be built on top of those two features.

Adanos020 commented 2 years ago

I see. This sounds like a good solution 👍