Another project
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(ui): pre-work for composite widgets

Lewis: May this revision serve well! <lu5a@proton.me>

+102 -20
+2
crates/bone-ui/src/input/mod.rs
··· 17 17 pub buttons_released: PointerButtonMask, 18 18 pub keys_pressed: Vec<KeyEvent>, 19 19 pub text_committed: String, 20 + pub modifiers: ModifierMask, 20 21 pub double_click_window: DoubleClickWindow, 21 22 pub drag_threshold: DragThreshold, 22 23 } ··· 31 32 buttons_released: PointerButtonMask::EMPTY, 32 33 keys_pressed: Vec::new(), 33 34 text_committed: String::new(), 35 + modifiers: ModifierMask::NONE, 34 36 double_click_window: DoubleClickWindow::DEFAULT, 35 37 drag_threshold: DragThreshold::DEFAULT, 36 38 }
+10
crates/bone-ui/src/layout/geometry.rs
··· 41 41 pub const fn value(self) -> f32 { 42 42 self.0 43 43 } 44 + 45 + #[must_use] 46 + pub fn min(self, other: Self) -> Self { 47 + if self.0 <= other.0 { self } else { other } 48 + } 49 + 50 + #[must_use] 51 + pub fn max(self, other: Self) -> Self { 52 + if self.0 >= other.0 { self } else { other } 53 + } 44 54 } 45 55 46 56 impl Default for LayoutPx {
+6 -3
crates/bone-ui/src/widgets/checkbox.rs
··· 82 82 .active(checkbox.state.is_active()), 83 83 ); 84 84 let live_focused = ctx.is_focused(checkbox.id); 85 - let toggled = interactive 86 - && (interaction.click() || (live_focused && take_activation(ctx.input))); 85 + let toggled = 86 + interactive && (interaction.click() || (live_focused && take_activation(ctx.input))); 87 87 let next_state = if toggled { 88 88 checkbox.state.next() 89 89 } else { ··· 164 164 fn next_cycles_through_states() { 165 165 assert_eq!(CheckboxState::Unchecked.next(), CheckboxState::Checked); 166 166 assert_eq!(CheckboxState::Checked.next(), CheckboxState::Unchecked); 167 - assert_eq!(CheckboxState::Indeterminate.next(), CheckboxState::Unchecked); 167 + assert_eq!( 168 + CheckboxState::Indeterminate.next(), 169 + CheckboxState::Unchecked 170 + ); 168 171 } 169 172 170 173 #[test]
+5 -1
crates/bone-ui/src/widgets/dimensioned_input.rs
··· 49 49 50 50 const ANGLE_UNITS: UnitTable<Angle> = UnitTable { 51 51 default: ANGLE_DEG, 52 - suffixes: &[("deg", ANGLE_DEG), ("\u{00B0}", ANGLE_DEG), ("rad", ANGLE_RAD)], 52 + suffixes: &[ 53 + ("deg", ANGLE_DEG), 54 + ("\u{00B0}", ANGLE_DEG), 55 + ("rad", ANGLE_RAD), 56 + ], 53 57 }; 54 58 55 59 fn parse_dimensioned<Q>(text: &str, units: &UnitTable<Q>) -> Result<Q, DimensionedParseError> {
+6 -5
crates/bone-ui/src/widgets/dropdown.rs
··· 83 83 } 84 84 85 85 fn popup_rect_below(trigger: LayoutRect, item_height: LayoutPx, count: usize) -> LayoutRect { 86 - #[allow( 87 - clippy::cast_precision_loss, 88 - reason = "dropdown item counts are small" 89 - )] 86 + #[allow(clippy::cast_precision_loss, reason = "dropdown item counts are small")] 90 87 let count_f32 = count as f32; 91 88 LayoutRect::new( 92 89 LayoutPos::new( ··· 1068 1065 ModifierMask::NONE, 1069 1066 )); 1070 1067 let _ = render_with(&mut state, None, &mut focus, &mut snap, &prev); 1071 - assert_eq!(state.highlighted, Some(2), "PageDown jumps to last when within visible count"); 1068 + assert_eq!( 1069 + state.highlighted, 1070 + Some(2), 1071 + "PageDown jumps to last when within visible count" 1072 + ); 1072 1073 } 1073 1074 1074 1075 #[test]
+46
crates/bone-ui/src/widgets/mod.rs
··· 1 1 mod button; 2 2 mod checkbox; 3 + mod dialog; 3 4 mod dimensioned_input; 4 5 mod dropdown; 6 + mod file_picker; 5 7 mod hotkey_capture; 6 8 mod keys; 9 + mod menu; 7 10 mod numeric_input; 8 11 mod paint; 12 + mod panel; 9 13 mod parsed_input; 14 + mod property_grid; 10 15 mod radio_group; 16 + mod ribbon; 11 17 mod slider; 18 + mod status_bar; 19 + mod table; 20 + mod tabs; 12 21 mod text_input; 22 + mod toast; 13 23 mod toggle_button; 24 + mod toolbar; 14 25 mod tooltip; 26 + mod tree_view; 15 27 mod visuals; 16 28 17 29 pub use button::{ 18 30 Button, ButtonResponse, ButtonState, ButtonVariant, ButtonVisuals, button_visuals, show_button, 19 31 }; 20 32 pub use checkbox::{Checkbox, CheckboxResponse, CheckboxState, show_checkbox}; 33 + pub use dialog::{ 34 + BackdropStyle, ConfirmationDialog, ConfirmationOutcome, ConfirmationResponse, Dialog, 35 + DialogButton, DialogResponse, Modal, ModalResponse, show_confirmation, show_dialog, show_modal, 36 + }; 21 37 pub use dimensioned_input::{DimensionedInput, DimensionedInputResponse, DimensionedParseError}; 22 38 pub use dropdown::{Dropdown, DropdownItem, DropdownResponse, DropdownState, show_dropdown}; 39 + pub use file_picker::{ 40 + FilePickerDialog, FilePickerEntry, FilePickerMode, FilePickerOutcome, FilePickerResponse, 41 + FilePickerState, show_file_picker, 42 + }; 23 43 pub use hotkey_capture::{ 24 44 HotkeyCapture, HotkeyCaptureResponse, HotkeyCaptureState, show_hotkey_capture, 25 45 }; 26 46 pub use keys::{TakeKey, take_key}; 47 + pub use menu::{ 48 + ContextMenu, Menu, MenuBar, MenuBarEntry, MenuBarResponse, MenuBarState, MenuItem, MenuMetrics, 49 + MenuResponse, MenuState, show_context_menu, show_menu, show_menu_bar, 50 + }; 27 51 pub use numeric_input::{NumericFloatParseError, NumericInput, NumericInputResponse}; 28 52 pub use paint::{ButtonPaintKind, GlyphMark, LabelText, SelectionByteRange, WidgetPaint}; 53 + pub use panel::{Panel, PanelResponse, PanelState, PanelTitlebar, PanelVariant, show_panel}; 29 54 pub use parsed_input::{ParsedInput, ParsedInputResponse, ParsedValue, show_parsed_input}; 55 + pub use property_grid::{ 56 + AngleEditor, BoolEditor, LengthEditor, PropertyCell, PropertyEditor, PropertyGrid, 57 + PropertyGridResponse, PropertyOption, PropertyRow, SelectionEditor, TextEditor, 58 + show_property_grid, 59 + }; 30 60 pub use radio_group::{ 31 61 RadioGroup, RadioGroupResponse, RadioOption, RadioOrientation, show_radio_group, 32 62 }; 63 + pub use ribbon::{ 64 + Ribbon, RibbonGroup, RibbonIconSize, RibbonResponse, RibbonState, RibbonTab, show_ribbon, 65 + }; 33 66 pub use slider::{ 34 67 Slider, SliderCoarseStep, SliderRange, SliderRangeError, SliderResponse, SliderScalar, 35 68 SliderStep, SliderStepError, show_slider, 36 69 }; 70 + pub use status_bar::{StatusAlign, StatusBar, StatusBarResponse, StatusItem, show_status_bar}; 71 + pub use table::{ 72 + ListItem, ListSelectionMode, ListView, ListViewResponse, ListViewState, ResizeAnchor, 73 + SortDirection, Table, TableColumn, TableResponse, TableRow, TableSort, TableState, 74 + show_list_view, show_table, 75 + }; 76 + pub use tabs::{Tab, Tabs, TabsOrientation, TabsResponse, show_tabs}; 37 77 pub use text_input::{ 38 78 AlwaysValid, Clipboard, MemoryClipboard, TextInput, TextInputAction, TextInputEdit, 39 79 TextInputResponse, TextInputState, TextInputValidation, show_text_input, 40 80 }; 81 + pub use toast::{Toast, ToastKind, ToastResponse, ToastState, show_toast}; 41 82 pub use toggle_button::{ToggleButton, ToggleButtonResponse, show_toggle_button}; 83 + pub use toolbar::{Toolbar, ToolbarItem, ToolbarOrientation, ToolbarResponse, show_toolbar}; 42 84 pub use tooltip::{Tooltip, TooltipPlacement, TooltipState, show_tooltip}; 85 + pub use tree_view::{ 86 + DropPlacement, DropTarget, RenameCommit, TreeNode, TreeSelectionMode, TreeView, 87 + TreeViewResponse, TreeViewState, show_tree_view, 88 + }; 43 89 pub use visuals::{ 44 90 FieldVisuals, Indicator, SurfaceVisuals, TextVisuals, indicator_border, indicator_fill, 45 91 indicator_label_color, push_focus_ring, push_indicator,
+7
crates/bone-ui/src/widgets/paint.rs
··· 24 24 Chevron, 25 25 SliderThumb, 26 26 Spinner, 27 + Close, 28 + DisclosureClosed, 29 + DisclosureOpen, 30 + SubmenuArrow, 31 + SortAscending, 32 + SortDescending, 33 + Ellipsis, 27 34 } 28 35 29 36 #[derive(Clone, Debug, PartialEq, Eq, Serialize)]
+2 -3
crates/bone-ui/src/widgets/parsed_input.rs
··· 10 10 use super::keys::{TakeKey, take_key}; 11 11 use super::paint::WidgetPaint; 12 12 use super::text_input::{ 13 - Clipboard, TextInput, TextInputResponse, TextInputState, TextInputValidation, 14 - show_text_input, 13 + Clipboard, TextInput, TextInputResponse, TextInputState, TextInputValidation, show_text_input, 15 14 }; 16 15 17 16 pub trait ParsedValue: Sized + Clone + PartialEq { ··· 75 74 } 76 75 77 76 #[must_use] 78 - pub fn show_parsed_input<T: ParsedValue, C: Clipboard>( 77 + pub fn show_parsed_input<T: ParsedValue, C: Clipboard + ?Sized>( 79 78 ctx: &mut FrameCtx<'_>, 80 79 input: ParsedInput<'_, T>, 81 80 clipboard: &mut C,
+5 -1
crates/bone-ui/src/widgets/radio_group.rs
··· 403 403 first_id, 404 404 vec![arrow], 405 405 ); 406 - assert_eq!(focus.focused(), Some(first_id), "vertical orientation ignores ArrowRight"); 406 + assert_eq!( 407 + focus.focused(), 408 + Some(first_id), 409 + "vertical orientation ignores ArrowRight" 410 + ); 407 411 } 408 412 409 413 #[test]
+4 -1
crates/bone-ui/src/widgets/slider.rs
··· 665 665 SliderStep::try_new(-1.0_f64), 666 666 Err(SliderStepError::NotPositive), 667 667 ); 668 - assert_eq!(SliderStep::try_new(-1_i32), Err(SliderStepError::NotPositive)); 668 + assert_eq!( 669 + SliderStep::try_new(-1_i32), 670 + Err(SliderStepError::NotPositive) 671 + ); 669 672 } 670 673 671 674 #[test]
+7 -4
crates/bone-ui/src/widgets/text_input.rs
··· 113 113 } 114 114 115 115 #[must_use] 116 - pub fn show_text_input<V: TextInputValidation, C: Clipboard>( 116 + pub fn show_text_input<V: TextInputValidation, C: Clipboard + ?Sized>( 117 117 ctx: &mut FrameCtx<'_>, 118 118 input: TextInput<'_, V>, 119 119 clipboard: &mut C, ··· 160 160 } 161 161 } 162 162 163 - fn drain_edits<C: Clipboard>( 163 + fn drain_edits<C: Clipboard + ?Sized>( 164 164 ctx: &mut FrameCtx<'_>, 165 165 state: &mut TextInputState, 166 166 clipboard: &mut C, ··· 203 203 edits 204 204 } 205 205 206 - fn perform<C: Clipboard>( 206 + fn perform<C: Clipboard + ?Sized>( 207 207 classified: ClassifiedKey, 208 208 state: &mut TextInputState, 209 209 clipboard: &mut C, ··· 704 704 &mut clipboard, 705 705 AlwaysValid, 706 706 ); 707 - assert!(input.keys_pressed.is_empty(), "Paste with content drains chord"); 707 + assert!( 708 + input.keys_pressed.is_empty(), 709 + "Paste with content drains chord" 710 + ); 708 711 } 709 712 710 713 #[test]
+2 -2
crates/bone-ui/src/widgets/toggle_button.rs
··· 54 54 .active(toggle.on), 55 55 ); 56 56 let live_focused = ctx.is_focused(toggle.id); 57 - let toggled = interactive 58 - && (interaction.click() || (live_focused && take_activation(ctx.input))); 57 + let toggled = 58 + interactive && (interaction.click() || (live_focused && take_activation(ctx.input))); 59 59 let next_on = if toggled { !toggle.on } else { toggle.on }; 60 60 let disabled = matches!(toggle.state, ButtonState::Disabled); 61 61 let mut paint = Vec::new();