VIP inspection tooling #4
|
@ -1,8 +1,9 @@
|
|||
use std::ops::{Bound, RangeBounds};
|
||||
|
||||
use egui::{
|
||||
ecolor::HexColor, Align, Color32, CursorIcon, Frame, Layout, Margin, Rect, Response, RichText,
|
||||
Rounding, Sense, Shape, Stroke, TextEdit, Ui, UiBuilder, Vec2, Widget, WidgetText,
|
||||
ecolor::HexColor, Align, Color32, CursorIcon, Event, Frame, Key, Layout, Margin, Rect,
|
||||
Response, RichText, Rounding, Sense, Shape, Stroke, TextEdit, Ui, UiBuilder, Vec2, Widget,
|
||||
WidgetText,
|
||||
};
|
||||
|
||||
pub trait UiExt {
|
||||
|
@ -117,10 +118,13 @@ impl<'a> NumberEdit<'a> {
|
|||
|
||||
impl Widget for NumberEdit<'_> {
|
||||
fn ui(self, ui: &mut Ui) -> Response {
|
||||
let (last_value, mut str) = ui.memory(|m| {
|
||||
m.data
|
||||
let (last_value, mut str, focus) = ui.memory(|m| {
|
||||
let (lv, s) = m
|
||||
.data
|
||||
.get_temp(ui.id())
|
||||
.unwrap_or((*self.value, self.value.to_string()))
|
||||
.unwrap_or((*self.value, self.value.to_string()));
|
||||
let focus = m.has_focus(ui.id());
|
||||
(lv, s, focus)
|
||||
});
|
||||
let mut stale = false;
|
||||
if *self.value != last_value {
|
||||
|
@ -128,8 +132,34 @@ impl Widget for NumberEdit<'_> {
|
|||
stale = true;
|
||||
}
|
||||
let valid = str.parse().is_ok_and(|v: usize| v == *self.value);
|
||||
let mut up_pressed = false;
|
||||
let mut down_pressed = false;
|
||||
if focus {
|
||||
ui.input_mut(|i| {
|
||||
i.events.retain(|e| match e {
|
||||
Event::Key {
|
||||
key: Key::ArrowUp,
|
||||
pressed: true,
|
||||
..
|
||||
} => {
|
||||
up_pressed = true;
|
||||
false
|
||||
}
|
||||
Event::Key {
|
||||
key: Key::ArrowDown,
|
||||
pressed: true,
|
||||
..
|
||||
} => {
|
||||
down_pressed = true;
|
||||
false
|
||||
}
|
||||
_ => true,
|
||||
})
|
||||
});
|
||||
}
|
||||
let text = TextEdit::singleline(&mut str)
|
||||
.horizontal_align(Align::Max)
|
||||
.id(ui.id())
|
||||
.margin(Margin {
|
||||
left: 4.0,
|
||||
right: 20.0,
|
||||
|
@ -167,14 +197,14 @@ impl Widget for NumberEdit<'_> {
|
|||
min: (arrow_left, arrow_top).into(),
|
||||
max: (arrow_right, arrow_middle).into(),
|
||||
};
|
||||
if draw_arrow(ui, top_arrow_rect, true).clicked_or_dragged() {
|
||||
if draw_arrow(ui, top_arrow_rect, true).clicked_or_dragged() || up_pressed {
|
||||
delta = 1;
|
||||
}
|
||||
let bottom_arrow_rect = Rect {
|
||||
min: (arrow_left, arrow_middle).into(),
|
||||
max: (arrow_right, arrow_bottom).into(),
|
||||
};
|
||||
if draw_arrow(ui, bottom_arrow_rect, false).clicked_or_dragged() {
|
||||
if draw_arrow(ui, bottom_arrow_rect, false).clicked_or_dragged() || down_pressed {
|
||||
delta = -1;
|
||||
}
|
||||
|
||||
|
@ -201,7 +231,14 @@ impl Widget for NumberEdit<'_> {
|
|||
|
||||
fn draw_arrow(ui: &mut Ui, rect: Rect, up: bool) -> Response {
|
||||
let arrow_res = ui
|
||||
.allocate_rect(rect, Sense::click_and_drag())
|
||||
.allocate_rect(
|
||||
rect,
|
||||
Sense {
|
||||
click: true,
|
||||
drag: true,
|
||||
focusable: false,
|
||||
},
|
||||
)
|
||||
.on_hover_cursor(CursorIcon::Default);
|
||||
let visuals = ui.style().visuals.widgets.style(&arrow_res);
|
||||
let painter = ui.painter_at(arrow_res.rect);
|
||||
|
|
Loading…
Reference in New Issue