diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index f3add74ef111ea73ba50c1e5472db2cd7a0e7733..ce98dbd7795cb189b757d4db8ceb5c7e096682ed 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -30,7 +30,7 @@ jobs: target/ key: ${{ runner.os }}-cargo-build-stable-${{ hashFiles('**/Cargo.toml') }} - name: Install alsa and udev - run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev if: runner.os == 'linux' - name: Build run: cargo build --verbose --workspace --features "bevy/x11" @@ -38,3 +38,5 @@ jobs: # run: cargo test --verbose --workspace - name: Run fmt check run: cargo fmt --all -- --check + - name: Run clippy + run: cargo clippy --workspace --all-targets --all-features --features "bevy/x11" diff --git a/Cargo.toml b/Cargo.toml index a642ac828eed7b6f895e6e6c1d42ffdfe77d99f3..cb39aa36bdc0e70a9c030b4997b23617922b0556 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,3 +46,6 @@ path = "examples/tabs/tabs.rs" [[example]] name = "todo" path = "examples/todo/todo.rs" + +[package.metadata.docs.rs] +features = ["bevy/x11"] \ No newline at end of file diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000000000000000000000000000000000000..da8a02c4abe5478b51ee45d23819a0d6ccbd51ee --- /dev/null +++ b/clippy.toml @@ -0,0 +1,3 @@ +# BLOCKED: https://github.com/rust-lang/cargo/issues/5034 for properly disabling lints +type-complexity-threshold = 9000 +too-many-arguments-threshold = 30 \ No newline at end of file diff --git a/examples/avsb.rs b/examples/avsb.rs index 4aa2901519d9a29665143c972b46796d4bf75b89..30efc51361800da17f81e0897b5b09de26cb6043 100644 --- a/examples/avsb.rs +++ b/examples/avsb.rs @@ -55,21 +55,17 @@ fn current_count_render( <KButtonBundle button={KButton { text: "Click me!".into(), - ..Default::default() }} on_event={OnEvent::new( move |In(_entity): In<Entity>, mut event: ResMut<KEvent>, mut query: Query<&mut CurrentCountState>| { - match event.event_type { - EventType::Click(..) => { - event.prevent_default(); - event.stop_propagation(); - if let Ok(mut current_count) = query.get_mut(state_entity) { - current_count.foo += 1; - } + if let EventType::Click(..) = event.event_type { + event.prevent_default(); + event.stop_propagation(); + if let Ok(mut current_count) = query.get_mut(state_entity) { + current_count.foo += 1; } - _ => {} } }, )} diff --git a/examples/bevy_scene.rs b/examples/bevy_scene.rs index 942c6e4858e8c3ec85145a0f6d4fd1bc82607e2e..f6d4064fb2ce83d6ed65bc028be584f3fb1f0f35 100644 --- a/examples/bevy_scene.rs +++ b/examples/bevy_scene.rs @@ -186,11 +186,8 @@ fn startup( move |In(_entity): In<Entity>, event: Res<KEvent>, mut active_color: ResMut<ActiveColor>| { - match event.event_type { - EventType::Click(..) => { - active_color.index = (active_color.index + 1) % COLORS.len(); - } - _ => {} + if let EventType::Click(..) = event.event_type { + active_color.index = (active_color.index + 1) % COLORS.len(); } }, ); @@ -235,7 +232,6 @@ fn startup( <KButtonBundle button={KButton { text: "Change Tile Color".into(), - ..Default::default() }} on_event={handle_change_color} styles={button_styles} diff --git a/examples/conditional_widget.rs b/examples/conditional_widget.rs index fd35b3188e28017decc60dbd44d57d27bef01df7..fb010a418a6a24acca623cae3b7d4def10c81e4b 100644 --- a/examples/conditional_widget.rs +++ b/examples/conditional_widget.rs @@ -54,13 +54,10 @@ fn my_widget_render( mut query: Query<&mut MyWidgetState>| { event.prevent_default(); event.stop_propagation(); - match event.event_type { - EventType::Click(..) => { - if let Ok(mut state) = query.get_mut(state_entity) { - state.show_window = true; - } + if let EventType::Click(..) = event.event_type { + if let Ok(mut state) = query.get_mut(state_entity) { + state.show_window = true; } - _ => {} } }, )} @@ -77,20 +74,17 @@ fn my_widget_render( }} > <KButtonBundle - button={KButton { text: "Hide Window".into(), ..Default::default() }} + button={KButton { text: "Hide Window".into() }} on_event={OnEvent::new( move |In(_entity): In<Entity>, mut event: ResMut<KEvent>, mut query: Query<&mut MyWidgetState>| { - match event.event_type { - EventType::Click(..) => { - event.prevent_default(); - event.stop_propagation(); - if let Ok(mut state) = query.get_mut(state_entity) { - state.show_window = false; - } + if let EventType::Click(..) = event.event_type { + event.prevent_default(); + event.stop_propagation(); + if let Ok(mut state) = query.get_mut(state_entity) { + state.show_window = false; } - _ => {} } }, )} diff --git a/examples/context.rs b/examples/context.rs index de7cda837b3617a251d2b4976a80c90425598d46..db24c81d78cea0c2a01aae5737431085e7028a36 100644 --- a/examples/context.rs +++ b/examples/context.rs @@ -107,15 +107,12 @@ fn update_theme_button( query: Query<&ThemeButton>, mut context_query: Query<&mut Theme>, | { - match event.event_type { - EventType::Click(..) => { - if let Ok(button) = query.get(theme_button_entity) { - if let Ok(mut context_theme) = context_query.get_mut(theme_context_entity) { - *context_theme = button.theme.clone(); - } + if let EventType::Click(..) = event.event_type { + if let Ok(button) = query.get(theme_button_entity) { + if let Ok(mut context_theme) = context_query.get_mut(theme_context_entity) { + *context_theme = button.theme.clone(); } - }, - _ => {} + } } }, )} @@ -284,7 +281,7 @@ fn update_theme_demo( }} /> <KButtonBundle - button={KButton { text: "BUTTON".into(), ..Default::default() }} + button={KButton { text: "BUTTON".into() }} styles={btn_style} /> { diff --git a/examples/main_menu.rs b/examples/main_menu.rs index a0ab3f3579a95589c796eddb5eef613c90b46cb0..0111af0de38a09f9ab100d1bfb953bcc228a2a2e 100644 --- a/examples/main_menu.rs +++ b/examples/main_menu.rs @@ -143,17 +143,14 @@ fn startup( preload_resource.images.extend(vec![ panel1_image.clone(), logo_image.clone(), - button_image.clone(), - button_image_hover.clone(), + button_image, + button_image_hover, ]); let handle_click_close = OnEvent::new( move |In(_entity): In<Entity>, event: ResMut<KEvent>, mut exit: EventWriter<AppExit>| { - match event.event_type { - EventType::Click(..) => { - exit.send(AppExit); - } - _ => {} + if let EventType::Click(..) = event.event_type { + exit.send(AppExit); } }, ); diff --git a/examples/modal.rs b/examples/modal.rs index a0c603e5b8214aa1ddc35ea468b0003b8cbee5a7..877e2bfb94bb12779d32f7e916f9013d094af0c5 100644 --- a/examples/modal.rs +++ b/examples/modal.rs @@ -54,13 +54,10 @@ fn my_widget_render( mut query: Query<&mut MyWidgetState>| { event.prevent_default(); event.stop_propagation(); - match event.event_type { - EventType::Click(..) => { - if let Ok(mut state) = query.get_mut(state_entity) { - state.show_modal = true; - } + if let EventType::Click(..) = event.event_type { + if let Ok(mut state) = query.get_mut(state_entity) { + state.show_modal = true; } - _ => {} } }, )} @@ -80,20 +77,17 @@ fn my_widget_render( }} > <KButtonBundle - button={KButton { text: "Hide Window".into(), ..Default::default() }} + button={KButton { text: "Hide Window".into() }} on_event={OnEvent::new( move |In(_entity): In<Entity>, mut event: ResMut<KEvent>, mut query: Query<&mut MyWidgetState>| { - match event.event_type { - EventType::Click(..) => { - event.prevent_default(); - event.stop_propagation(); - if let Ok(mut state) = query.get_mut(state_entity) { - state.show_modal = false; - } + if let EventType::Click(..) = event.event_type { + event.prevent_default(); + event.stop_propagation(); + if let Ok(mut state) = query.get_mut(state_entity) { + state.show_modal = false; } - _ => {} } }, )} diff --git a/examples/simple_state.rs b/examples/simple_state.rs index dd8397e220586514a6efb4a0ddbe90f4ca8a711d..e04d165eb298fd1c71c3cfe4fcdbb5362a85ec26 100644 --- a/examples/simple_state.rs +++ b/examples/simple_state.rs @@ -55,7 +55,6 @@ fn current_count_render( <KButtonBundle button={KButton { text: "Click me!".into(), - ..Default::default() }} styles={KStyle { font_size: (48.).into(), @@ -66,15 +65,12 @@ fn current_count_render( move |In(_entity): In<Entity>, mut event: ResMut<KEvent>, mut query: Query<&mut CurrentCountState>| { - match event.event_type { - EventType::Click(..) => { - event.prevent_default(); - event.stop_propagation(); - if let Ok(mut current_count) = query.get_mut(state_entity) { - current_count.foo += 1; - } + if let EventType::Click(..) = event.event_type { + event.prevent_default(); + event.stop_propagation(); + if let Ok(mut current_count) = query.get_mut(state_entity) { + current_count.foo += 1; } - _ => {} } }, )} diff --git a/examples/tabs/tab_button.rs b/examples/tabs/tab_button.rs index 4fbd8b2973a0406c889174542cc4d80a84be6dad..154e83d166c6f321d09e9535999232168f176192 100644 --- a/examples/tabs/tab_button.rs +++ b/examples/tabs/tab_button.rs @@ -58,13 +58,10 @@ pub fn tab_button_render( move |In(_entity): In<Entity>, event: Res<KEvent>, mut query: Query<&mut TabContext>| { - match event.event_type { - EventType::Click(..) => { - if let Ok(mut tab_context) = query.get_mut(context_entity) { - tab_context.current_index = button_index; - } + if let EventType::Click(..) = event.event_type { + if let Ok(mut tab_context) = query.get_mut(context_entity) { + tab_context.current_index = button_index; } - _ => {} } }, ); diff --git a/examples/todo/input.rs b/examples/todo/input.rs index 9ddb6239daca89ee938c23654070f1a8877e6597..171b3d631d3e857f87cbfc792ef6e106f569bf2f 100644 --- a/examples/todo/input.rs +++ b/examples/todo/input.rs @@ -50,15 +50,12 @@ pub fn render_todo_input( let handle_click = OnEvent::new( move |In(_entity): In<Entity>, event: Res<KEvent>, mut todo_list: ResMut<TodoList>| { - match event.event_type { - EventType::Click(..) => { - if !todo_list.new_item.is_empty() { - let value = todo_list.new_item.clone(); - todo_list.items.push(value); - todo_list.new_item.clear(); - } + if let EventType::Click(..) = event.event_type { + if !todo_list.new_item.is_empty() { + let value = todo_list.new_item.clone(); + todo_list.items.push(value); + todo_list.new_item.clear(); } - _ => {} } }, ); diff --git a/examples/todo/items.rs b/examples/todo/items.rs index 4a09e1142275c641af781a042ce73e690acad00b..619e64ff53e4bdd0567ee596d670a942c070f1ea 100644 --- a/examples/todo/items.rs +++ b/examples/todo/items.rs @@ -51,11 +51,8 @@ pub fn render_todo_items( move |In(_entity): In<Entity>, event: Res<KEvent>, mut todo_list: ResMut<TodoList>,| { - match event.event_type { - EventType::Click(..) => { - todo_list.items.remove(index); - }, - _ => {} + if let EventType::Click(..) = event.event_type { + todo_list.items.remove(index); } }, ); diff --git a/examples/transitions.rs b/examples/transitions.rs index 2e55d3ae5c70764e3ec2ccefb8446c06c71da45c..1f5bd0b2be8f52315a1cd208ca311754fe08ff90 100644 --- a/examples/transitions.rs +++ b/examples/transitions.rs @@ -153,7 +153,7 @@ fn startup( }, style_b: KStyle { width: Units::Pixels(100.0).into(), - ..quad_styles.clone() + ..quad_styles }, ..Default::default() }} diff --git a/examples/vec.rs b/examples/vec.rs index 00aad5851065d8e24d0befca5218383d63497e21..066841f3228b48c705af1afb23714da9cbfc4d31 100644 --- a/examples/vec.rs +++ b/examples/vec.rs @@ -22,7 +22,7 @@ fn my_widget_1_update( constructor! { <TextWidgetBundle text={TextProps { - content: (*text).clone().into(), + content: (*text).into(), ..Default::default() }} /> diff --git a/kayak_font/Cargo.toml b/kayak_font/Cargo.toml index 8d5ea34bc430d91710a3f1eaa7714e4ae5c57df5..effd523d3d88d887293a38ac10078fbc315bdd4f 100644 --- a/kayak_font/Cargo.toml +++ b/kayak_font/Cargo.toml @@ -16,7 +16,7 @@ bevy_renderer = ["bevy"] [dependencies] anyhow = { version = "1.0" } -nanoserde = "0.1.30" +nanoserde = "0.1.32" unicode-segmentation = "1.10.0" num = "0.4" num-derive = "0.3" @@ -32,3 +32,6 @@ bevy = { version = "0.10", optional = true, default-features = false, features = [dev-dependencies] bevy = { version = "0.10" } bytemuck = "1.12.0" + +[package.metadata.docs.rs] +features = ["bevy/x11"] \ No newline at end of file diff --git a/kayak_font/examples/bevy.rs b/kayak_font/examples/bevy.rs deleted file mode 100644 index ac6413002da01dd77fef9096436c433bd93b8026..0000000000000000000000000000000000000000 --- a/kayak_font/examples/bevy.rs +++ /dev/null @@ -1,137 +0,0 @@ -use bevy::{ - math::Vec2, - prelude::{ - App as BevyApp, AssetServer, Camera2dBundle, Commands, Component, Handle, Input, KeyCode, - PluginGroup, Query, Res, ResMut, Sprite, SpriteBundle, Transform, With, Without, - }, - render::color::Color, - window::{WindowDescriptor, WindowPlugin}, - DefaultPlugins, -}; - -use kayak_font::{bevy::KayakFontPlugin, Alignment, KayakFont}; -use renderer::{FontRenderPlugin, Text}; - -mod renderer; - -const FONT_SIZE: f32 = 24.0; -const INITIAL_SIZE: Vec2 = Vec2::from_array([400.0, 300.0]); -const INITIAL_POS: Vec2 = Vec2::from_array([-200.0, 0.0]); -const INSTRUCTIONS: &str = - "Press 'A' and 'D' to shrink and grow the text box.\nPress \"Space\" to cycle text alignment."; - -#[derive(Component)] -struct Instructions; - -fn startup(mut commands: Commands, asset_server: Res<AssetServer>) { - commands.spawn(Camera2dBundle::default()); - - let font_handle: Handle<KayakFont> = asset_server.load("roboto.kttf"); - // let font_handle: Handle<KayakFont> = asset_server.load("roboto.kayak_font"); - - commands - .spawn(Text { - horz_alignment: Alignment::Start, - color: Color::WHITE, - content: "Hello World! This text should wrap because it's kinda-super-long. How cool is that?!\nHere's a new line.\n\tHere's a tab.".into(), - font_size: FONT_SIZE, - line_height: FONT_SIZE * 1.2, // Firefox method of calculating default line heights see: https://developer.mozilla.org/en-US/docs/Web/CSS/line-height - position: INITIAL_POS, - size: INITIAL_SIZE, - }) - .insert(font_handle.clone()); - - commands.spawn(SpriteBundle { - sprite: Sprite { - color: Color::DARK_GRAY, - custom_size: Some(INITIAL_SIZE), - ..Default::default() - }, - transform: Transform::from_xyz( - (INITIAL_SIZE.x / 2.0) + INITIAL_POS.x, - (-INITIAL_SIZE.y / 4.0) - 20.0, - -0.05, - ), - ..Default::default() - }); - - commands.spawn(( - Text { - horz_alignment: Alignment::Middle, - color: Color::WHITE, - content: INSTRUCTIONS.into(), - font_size: 32.0, - line_height: 32.0 * 1.2, // Firefox method of calculating default line heights see: https://developer.mozilla.org/en-US/docs/Web/CSS/line-height - position: Vec2::new(-360.0, 250.0), - size: Vec2::new(720.0, 200.0), - }, - Instructions, - font_handle.clone(), - )); -} - -fn control_text( - keyboard_input: ResMut<Input<KeyCode>>, - mut text_box: Query<&mut Text, Without<Instructions>>, - mut instructions: Query<&mut Text, With<Instructions>>, - mut bg: Query<&mut Sprite>, -) { - let speed = - if keyboard_input.pressed(KeyCode::LShift) || keyboard_input.pressed(KeyCode::RShift) { - 2.5 - } else { - 1.0 - }; - - if keyboard_input.just_pressed(KeyCode::Space) { - for mut text in text_box.iter_mut() { - let next = match text.horz_alignment { - Alignment::Start => Alignment::Middle, - Alignment::Middle => Alignment::End, - Alignment::End => Alignment::Start, - }; - text.horz_alignment = next; - } - } - - let speed = if keyboard_input.pressed(KeyCode::D) { - speed - } else if keyboard_input.pressed(KeyCode::A) { - -speed - } else { - return; - }; - - for mut text in text_box.iter_mut() { - text.size.x += speed; - text.position.x -= speed / 2.0; - - let mut instructions = instructions.single_mut(); - instructions.content = String::from(INSTRUCTIONS); - instructions - .content - .push_str(&format!("\nSize: {}", text.size.x)); - } - - for mut sprite in bg.iter_mut() { - sprite.custom_size.as_mut().unwrap().x += speed; - } -} - -fn main() { - BevyApp::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - window: WindowDescriptor { - width: 1270.0, - height: 720.0, - title: String::from("UI Example"), - ..Default::default() - }, - ..Default::default() - })) - .add_plugin(KayakFontPlugin) - .add_plugin(FontRenderPlugin) - .add_startup_system(startup) - .add_system(control_text) - .run(); -} diff --git a/kayak_font/examples/renderer/extract.rs b/kayak_font/examples/renderer/extract.rs deleted file mode 100644 index 8c1667c56215f3da416c231fe8775b053ea50595..0000000000000000000000000000000000000000 --- a/kayak_font/examples/renderer/extract.rs +++ /dev/null @@ -1,57 +0,0 @@ -use bevy::{ - math::Vec2, - prelude::{Assets, Commands, Handle, Query, Rect, Res}, - render::Extract, -}; -use kayak_font::{KayakFont, TextProperties}; - -use super::{ - pipeline::{ExtractCharBundle, ExtractedChar}, - Text, -}; - -pub fn extract( - mut commands: Commands, - fonts: Extract<Res<Assets<KayakFont>>>, - texts: Extract<Query<(&Text, &Handle<KayakFont>)>>, -) { - let mut extracted_texts = Vec::new(); - - for (text, font_handle) in texts.iter() { - if let Some(font) = fonts.get(font_handle) { - let properties = TextProperties { - font_size: text.font_size, - line_height: text.line_height, - max_size: (text.size.x, text.size.y), - alignment: text.horz_alignment, - ..Default::default() - }; - - let text_layout = font.measure(&text.content, properties); - - for glyph_rect in text_layout.glyphs() { - let mut position = Vec2::from(glyph_rect.position); - position.y *= -1.0; - position += text.position; - - let size = Vec2::from(glyph_rect.size); - - extracted_texts.push(ExtractCharBundle { - extracted_quad: ExtractedChar { - font_handle: Some(font_handle.clone()), - rect: Rect { - min: position, - max: position + size, - }, - color: text.color, - vertex_index: 0, - char_id: font.get_char_id(glyph_rect.content).unwrap(), - z_index: 0.0, - }, - }); - } - } - } - - commands.spawn_batch(extracted_texts); -} diff --git a/kayak_font/examples/renderer/mod.rs b/kayak_font/examples/renderer/mod.rs deleted file mode 100644 index 10ccaff55844b4b5635db7eb7c2703f4f40c676c..0000000000000000000000000000000000000000 --- a/kayak_font/examples/renderer/mod.rs +++ /dev/null @@ -1,63 +0,0 @@ -use bevy::{ - core_pipeline::core_2d::Transparent2d, - prelude::{Assets, HandleUntyped, Plugin, Res, ResMut}, - reflect::TypeUuid, - render::{ - render_asset::RenderAssets, - render_phase::DrawFunctions, - render_resource::Shader, - renderer::{RenderDevice, RenderQueue}, - texture::Image, - RenderApp, RenderStage, - }, -}; -use kayak_font::bevy::FontTextureCache; - -use self::pipeline::{DrawUI, FontPipeline, QuadMeta}; - -mod extract; -pub mod pipeline; -mod text; - -pub use text::*; - -pub const FONT_SHADER_HANDLE: HandleUntyped = - HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 7604018236855288450); - -pub struct FontRenderPlugin; - -impl Plugin for FontRenderPlugin { - fn build(&self, app: &mut bevy::prelude::App) { - let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap(); - let unified_shader = Shader::from_wgsl(include_str!("shader.wgsl")); - shaders.set_untracked(FONT_SHADER_HANDLE, unified_shader); - - let render_app = app.sub_app_mut(RenderApp); - render_app - .init_resource::<QuadMeta>() - .init_resource::<FontPipeline>() - .add_system_to_stage(RenderStage::Extract, extract::extract) - .add_system_to_stage(RenderStage::Prepare, pipeline::prepare_quads) - .add_system_to_stage(RenderStage::Queue, pipeline::queue_quads) - .add_system_to_stage(RenderStage::Queue, create_and_update_font_cache_texture); - - let draw_quad = DrawUI::new(&mut render_app.world); - - render_app - .world - .get_resource::<DrawFunctions<Transparent2d>>() - .unwrap() - .write() - .add(draw_quad); - } -} - -fn create_and_update_font_cache_texture( - device: Res<RenderDevice>, - queue: Res<RenderQueue>, - pipeline: Res<FontPipeline>, - mut font_texture_cache: ResMut<FontTextureCache>, - images: Res<RenderAssets<Image>>, -) { - font_texture_cache.process_new(&device, &queue, pipeline.into_inner(), &images); -} diff --git a/kayak_font/examples/renderer/pipeline.rs b/kayak_font/examples/renderer/pipeline.rs deleted file mode 100644 index f2738c4c436fe7a9a83a2c9edf15f1353693d548..0000000000000000000000000000000000000000 --- a/kayak_font/examples/renderer/pipeline.rs +++ /dev/null @@ -1,396 +0,0 @@ -use bevy::{ - core_pipeline::core_2d::Transparent2d, - ecs::system::{ - lifetimeless::{Read, SQuery, SRes}, - SystemState, - }, - math::{Mat4, Quat, Vec2, Vec3, Vec4}, - prelude::{ - Bundle, Component, Entity, FromWorld, Handle, Query, Rect, Res, ResMut, Resource, World, - }, - render::{ - color::Color, - render_phase::{Draw, DrawFunctions, RenderPhase, TrackedRenderPass}, - render_resource::{ - BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, - BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, BlendComponent, - BlendFactor, BlendOperation, BlendState, BufferBindingType, BufferSize, BufferUsages, - BufferVec, CachedRenderPipelineId, ColorTargetState, ColorWrites, FragmentState, - FrontFace, MultisampleState, PipelineCache, PolygonMode, PrimitiveState, - PrimitiveTopology, RenderPipelineDescriptor, SamplerBindingType, Shader, ShaderStages, - ShaderType, TextureFormat, TextureSampleType, TextureViewDimension, VertexAttribute, - VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, - }, - renderer::{RenderDevice, RenderQueue}, - texture::{BevyDefault, GpuImage}, - view::{ViewUniformOffset, ViewUniforms}, - }, - utils::FloatOrd, -}; -use bytemuck::{Pod, Zeroable}; -use kayak_font::{ - bevy::{FontRenderingPipeline, FontTextureCache}, - KayakFont, -}; - -use super::FONT_SHADER_HANDLE; - -#[derive(Resource)] -pub struct FontPipeline { - view_layout: BindGroupLayout, - pub(crate) font_image_layout: BindGroupLayout, - pipeline: CachedRenderPipelineId, - empty_font_texture: (GpuImage, BindGroup), -} - -const QUAD_VERTEX_POSITIONS: &[Vec3] = &[ - Vec3::from_array([0.0, 0.0, 0.0]), - Vec3::from_array([1.0, 1.0, 0.0]), - Vec3::from_array([0.0, 1.0, 0.0]), - Vec3::from_array([0.0, 0.0, 0.0]), - Vec3::from_array([1.0, 0.0, 0.0]), - Vec3::from_array([1.0, 1.0, 0.0]), -]; - -impl FontRenderingPipeline for FontPipeline { - fn get_font_image_layout(&self) -> &BindGroupLayout { - &self.font_image_layout - } -} - -impl FromWorld for FontPipeline { - fn from_world(world: &mut World) -> Self { - let world = world.cell(); - let render_device = world.get_resource::<RenderDevice>().unwrap(); - let mut pipeline_cache = world.get_resource_mut::<PipelineCache>().unwrap(); - - let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: true, - min_binding_size: BufferSize::new(144), - }, - count: None, - }], - label: Some("ui_view_layout"), - }); - - // Used by fonts - let font_image_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[ - BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Texture { - multisampled: false, - sample_type: TextureSampleType::Float { filterable: true }, - view_dimension: TextureViewDimension::D2Array, - }, - count: None, - }, - BindGroupLayoutEntry { - binding: 1, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Sampler(SamplerBindingType::Filtering), - count: None, - }, - ], - label: Some("text_image_layout"), - }); - - let vertex_buffer_layout = VertexBufferLayout { - array_stride: 60, - step_mode: VertexStepMode::Vertex, - attributes: vec![ - VertexAttribute { - format: VertexFormat::Float32x3, - offset: 0, - shader_location: 0, - }, - VertexAttribute { - format: VertexFormat::Float32x4, - offset: 12, - shader_location: 1, - }, - VertexAttribute { - format: VertexFormat::Float32x4, - offset: 28, - shader_location: 2, - }, - VertexAttribute { - format: VertexFormat::Float32x4, - offset: 44, - shader_location: 3, - }, - ], - }; - - let empty_font_texture = FontTextureCache::get_empty(&render_device, &font_image_layout); - - let pipeline_desc = RenderPipelineDescriptor { - vertex: VertexState { - shader: FONT_SHADER_HANDLE.typed::<Shader>(), - entry_point: "vertex".into(), - shader_defs: vec![], - buffers: vec![vertex_buffer_layout], - }, - fragment: Some(FragmentState { - shader: FONT_SHADER_HANDLE.typed::<Shader>(), - shader_defs: vec![], - entry_point: "fragment".into(), - targets: vec![Some(ColorTargetState { - format: TextureFormat::bevy_default(), - blend: Some(BlendState { - color: BlendComponent { - src_factor: BlendFactor::SrcAlpha, - dst_factor: BlendFactor::OneMinusSrcAlpha, - operation: BlendOperation::Add, - }, - alpha: BlendComponent { - src_factor: BlendFactor::One, - dst_factor: BlendFactor::One, - operation: BlendOperation::Add, - }, - }), - write_mask: ColorWrites::ALL, - })], - }), - layout: Some(vec![view_layout.clone(), font_image_layout.clone()]), - primitive: PrimitiveState { - front_face: FrontFace::Ccw, - cull_mode: None, - polygon_mode: PolygonMode::Fill, - conservative: false, - topology: PrimitiveTopology::TriangleList, - strip_index_format: None, - unclipped_depth: false, - }, - depth_stencil: None, - multisample: MultisampleState { - count: 4, - mask: !0, - alpha_to_coverage_enabled: false, - }, - label: Some("font_pipeline".into()), - }; - - FontPipeline { - pipeline: pipeline_cache.queue_render_pipeline(pipeline_desc), - view_layout, - font_image_layout, - empty_font_texture, - } - } -} - -#[derive(Debug, Bundle)] -pub struct ExtractCharBundle { - pub(crate) extracted_quad: ExtractedChar, -} - -#[derive(Debug, Component, Clone)] -pub struct ExtractedChar { - pub rect: Rect, - pub color: Color, - pub vertex_index: usize, - pub char_id: u32, - pub z_index: f32, - pub font_handle: Option<Handle<KayakFont>>, -} - -#[repr(C)] -#[derive(Copy, Clone, Pod, Zeroable)] -struct QuadVertex { - pub position: [f32; 3], - pub color: [f32; 4], - pub uv: [f32; 4], - pub pos_size: [f32; 4], -} - -#[repr(C)] -#[derive(Copy, Clone, ShaderType)] -struct QuadType { - pub t: i32, -} - -#[derive(Resource)] -pub struct QuadMeta { - vertices: BufferVec<QuadVertex>, - view_bind_group: Option<BindGroup>, -} - -impl Default for QuadMeta { - fn default() -> Self { - Self { - vertices: BufferVec::new(BufferUsages::VERTEX), - view_bind_group: None, - } - } -} - -pub fn prepare_quads( - render_device: Res<RenderDevice>, - render_queue: Res<RenderQueue>, - mut sprite_meta: ResMut<QuadMeta>, - mut extracted_quads: Query<&mut ExtractedChar>, -) { - let extracted_sprite_len = extracted_quads.iter_mut().len(); - // don't create buffers when there are no quads - if extracted_sprite_len == 0 { - return; - } - - sprite_meta.vertices.clear(); - sprite_meta.vertices.reserve( - extracted_sprite_len * QUAD_VERTEX_POSITIONS.len(), - &render_device, - ); - - for (i, mut extracted_sprite) in extracted_quads.iter_mut().enumerate() { - let sprite_rect = extracted_sprite.rect; - let color = extracted_sprite.color.as_linear_rgba_f32(); - - let uv_min = Vec2::ZERO; - let uv_max = Vec2::ONE; - - let bottom_left = Vec4::new(uv_min.x, uv_max.y, extracted_sprite.char_id as f32, 0.0); - let top_left = Vec4::new(uv_min.x, uv_min.y, extracted_sprite.char_id as f32, 0.0); - let top_right = Vec4::new(uv_max.x, uv_min.y, extracted_sprite.char_id as f32, 0.0); - let bottom_right = Vec4::new(uv_max.x, uv_max.y, extracted_sprite.char_id as f32, 0.0); - - let uvs: [[f32; 4]; 6] = [ - bottom_left.into(), - top_right.into(), - top_left.into(), - bottom_left.into(), - bottom_right.into(), - top_right.into(), - ]; - - extracted_sprite.vertex_index = i; - for (index, vertex_position) in QUAD_VERTEX_POSITIONS.iter().enumerate() { - let world = Mat4::from_scale_rotation_translation( - sprite_rect.size().extend(1.0), - Quat::default(), - sprite_rect.min.extend(0.0), - ); - let final_position = (world * Vec3::from(*vertex_position).extend(1.0)).truncate(); - sprite_meta.vertices.push(QuadVertex { - position: final_position.into(), - color, - uv: uvs[index], - pos_size: [ - sprite_rect.min.x, - sprite_rect.min.y, - sprite_rect.size().x, - sprite_rect.size().y, - ], - }); - } - } - sprite_meta - .vertices - .write_buffer(&render_device, &render_queue); -} - -pub fn queue_quads( - draw_functions: Res<DrawFunctions<Transparent2d>>, - render_device: Res<RenderDevice>, - mut sprite_meta: ResMut<QuadMeta>, - view_uniforms: Res<ViewUniforms>, - quad_pipeline: Res<FontPipeline>, - mut extracted_sprites: Query<(Entity, &ExtractedChar)>, - mut views: Query<&mut RenderPhase<Transparent2d>>, -) { - if let Some(view_binding) = view_uniforms.uniforms.binding() { - sprite_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor { - entries: &[BindGroupEntry { - binding: 0, - resource: view_binding, - }], - label: Some("quad_view_bind_group"), - layout: &quad_pipeline.view_layout, - })); - - let draw_quad = draw_functions.read().get_id::<DrawUI>().unwrap(); - for mut transparent_phase in views.iter_mut() { - for (entity, quad) in extracted_sprites.iter_mut() { - transparent_phase.add(Transparent2d { - draw_function: draw_quad, - pipeline: quad_pipeline.pipeline, - entity, - sort_key: FloatOrd(quad.z_index), - batch_range: None, - }); - } - } - } -} - -pub struct DrawUI { - params: SystemState<( - SRes<QuadMeta>, - SRes<FontPipeline>, - SRes<PipelineCache>, - SRes<FontTextureCache>, - SQuery<Read<ViewUniformOffset>>, - SQuery<Read<ExtractedChar>>, - )>, -} - -impl DrawUI { - pub fn new(world: &mut World) -> Self { - Self { - params: SystemState::new(world), - } - } -} - -impl Draw<Transparent2d> for DrawUI { - fn draw<'w>( - &mut self, - world: &'w World, - pass: &mut TrackedRenderPass<'w>, - view: Entity, - item: &Transparent2d, - ) { - let (quad_meta, unified_pipeline, pipelines, font_texture_cache, views, quads) = - self.params.get(world); - - let view_uniform = views.get(view).unwrap(); - let quad_meta = quad_meta.into_inner(); - let extracted_quad = quads.get(item.entity).unwrap(); - if let Some(pipeline) = pipelines.into_inner().get_render_pipeline(item.pipeline) { - pass.set_render_pipeline(pipeline); - pass.set_vertex_buffer(0, quad_meta.vertices.buffer().unwrap().slice(..)); - pass.set_bind_group( - 0, - quad_meta.view_bind_group.as_ref().unwrap(), - &[view_uniform.offset], - ); - - let unified_pipeline = unified_pipeline.into_inner(); - if let Some(font_handle) = extracted_quad.font_handle.as_ref() { - if let Some(image_bindings) = - font_texture_cache.into_inner().get_binding(font_handle) - { - pass.set_bind_group(1, image_bindings, &[]); - } else { - pass.set_bind_group(1, &unified_pipeline.empty_font_texture.1, &[]); - } - } else { - pass.set_bind_group(1, &unified_pipeline.empty_font_texture.1, &[]); - } - - pass.draw( - (extracted_quad.vertex_index * QUAD_VERTEX_POSITIONS.len()) as u32 - ..((extracted_quad.vertex_index + 1) * QUAD_VERTEX_POSITIONS.len()) as u32, - 0..1, - ); - } - } -} diff --git a/kayak_font/examples/renderer/shader.wgsl b/kayak_font/examples/renderer/shader.wgsl deleted file mode 100644 index 36af3a3045da9d17a6dfe361f221bdf6d84517c4..0000000000000000000000000000000000000000 --- a/kayak_font/examples/renderer/shader.wgsl +++ /dev/null @@ -1,52 +0,0 @@ -struct View { - view_proj: mat4x4<f32>, - world_position: vec3<f32>, -} - -@group(0) @binding(0) -var<uniform> view: View; - -struct VertexOutput { - @builtin(position) position: vec4<f32>, - @location(0) color: vec4<f32>, - @location(1) uv: vec3<f32>, - @location(2) pos: vec2<f32>, - @location(3) size: vec2<f32>, - @location(4) screen_position: vec2<f32>, - @location(5) border_radius: f32, -}; - -@vertex -fn vertex( - @location(0) vertex_position: vec3<f32>, - @location(1) vertex_color: vec4<f32>, - @location(2) vertex_uv: vec4<f32>, - @location(3) vertex_pos_size: vec4<f32>, -) -> VertexOutput { - var out: VertexOutput; - out.color = vertex_color; - out.pos = vertex_pos_size.xy; - out.position = view.view_proj * vec4<f32>(vertex_position, 1.0); - out.screen_position = (view.view_proj * vec4<f32>(vertex_position, 1.0)).xy; - out.uv = vertex_uv.xyz; - out.size = vertex_pos_size.zw; - out.border_radius = vertex_uv.w; - return out; -} - -@group(1) @binding(0) -var font_texture: texture_2d_array<f32>; -@group(1) @binding(1) -var font_sampler: sampler; - -@fragment -fn fragment(in: VertexOutput) -> @location(0) vec4<f32> { - var px_range = 4.5; - var tex_dimensions = textureDimensions(font_texture); - var msdf_unit = vec2<f32>(px_range, px_range) / vec2<f32>(f32(tex_dimensions.x), f32(tex_dimensions.y)); - var x = textureSample(font_texture, font_sampler, vec2<f32>(in.uv.x, in.uv.y), i32(in.uv.z)); - var v = max(min(x.r, x.g), min(max(x.r, x.g), x.b)); - var sig_dist = (v - 0.5) * dot(msdf_unit, 0.5 / fwidth(in.uv.xy)); - var a = clamp(sig_dist + 0.5, 0.0, 1.0); - return vec4<f32>(in.color.rgb, a); -} \ No newline at end of file diff --git a/kayak_font/examples/renderer/text.rs b/kayak_font/examples/renderer/text.rs deleted file mode 100644 index 21832d9bb7a4bfe4c2be2f4f9f85acd969a77674..0000000000000000000000000000000000000000 --- a/kayak_font/examples/renderer/text.rs +++ /dev/null @@ -1,13 +0,0 @@ -use bevy::{math::Vec2, prelude::Component, render::color::Color}; -use kayak_font::Alignment; - -#[derive(Component)] -pub struct Text { - pub horz_alignment: Alignment, - pub content: String, - pub position: Vec2, - pub size: Vec2, - pub font_size: f32, - pub line_height: f32, - pub color: Color, -} diff --git a/kayak_font/src/bevy/font_texture.rs b/kayak_font/src/bevy/font_texture.rs index 1b4b43a2f379355eff394aca8b1bd66367066c6c..c2b32ac3ef999183d06b5f291f0c8291a71c683c 100644 --- a/kayak_font/src/bevy/font_texture.rs +++ b/kayak_font/src/bevy/font_texture.rs @@ -11,11 +11,8 @@ pub fn init_font_texture( ) { // quick and dirty, run this for all textures anytime a texture is created. for event in font_events.iter() { - match event { - AssetEvent::Created { handle } => { - not_processed.push(handle.clone_weak()); - } - _ => (), + if let AssetEvent::Created { handle } = event { + not_processed.push(handle.clone_weak()); } } diff --git a/kayak_font/src/bevy/renderer/font_texture_cache.rs b/kayak_font/src/bevy/renderer/font_texture_cache.rs index ff8f85176c047c8f68cc823758d98dbaae0f5139..c61a329e24ef0148b4e9dc1ffbb5fac4268e0689 100644 --- a/kayak_font/src/bevy/renderer/font_texture_cache.rs +++ b/kayak_font/src/bevy/renderer/font_texture_cache.rs @@ -63,12 +63,10 @@ impl FontTextureCache { ) -> Option<&'s GpuImage> { if let Some(gpu_image) = self.images.get(handle) { Some(gpu_image) + } else if let Some(font) = self.fonts.get(handle) { + render_images.get(font.image.get()) } else { - if let Some(font) = self.fonts.get(handle) { - render_images.get(font.image.get()) - } else { - None - } + None } } @@ -86,20 +84,18 @@ impl FontTextureCache { if render_images.get(font.image.get()).is_none() { was_processed = false; } + } else if let Some(atlas_texture) = render_images.get(font.image.get()) { + Self::create_from_atlas( + &mut self.images, + &font.sdf, + kayak_font_handle.clone_weak(), + device, + queue, + atlas_texture, + font.sdf.max_glyph_size().into(), + ); } else { - if let Some(atlas_texture) = render_images.get(font.image.get()) { - Self::create_from_atlas( - &mut self.images, - &font.sdf, - kayak_font_handle.clone_weak(), - device, - queue, - atlas_texture, - font.sdf.max_glyph_size().into(), - ); - } else { - was_processed = false; - } + was_processed = false; } } if !was_processed { @@ -206,15 +202,14 @@ impl FontTextureCache { array_layer_count: std::num::NonZeroU32::new(MAX_CHARACTERS), }); - let image = GpuImage { + GpuImage { texture, sampler, texture_view, mip_level_count: 1, size: Vec2 { x: 1.0, y: 1.0 }, texture_format: TextureFormat::Rgba8Unorm, - }; - image + } } pub fn create_from_atlas( diff --git a/kayak_font/src/font.rs b/kayak_font/src/font.rs index 49b170fe97058c2c63df23f335bfd3abf2e18b85..b5c11872667df47565c8eedfad328af073d09fa9 100644 --- a/kayak_font/src/font.rs +++ b/kayak_font/src/font.rs @@ -85,7 +85,7 @@ impl KayakFont { } pub fn get_char_id(&self, c: char) -> Option<u32> { - self.char_ids.get(&c).and_then(|id| Some(*id)) + self.char_ids.get(&c).copied() } pub fn get_word_width(&self, word: &str, properties: TextProperties) -> f32 { @@ -271,6 +271,7 @@ impl KayakFont { let start = line.glyph_index(); let end = line.glyph_index() + line.total_glyphs(); + #[allow(clippy::needless_range_loop)] for index in start..end { let rect = &mut glyph_rects[index]; rect.position.0 += shift_x; diff --git a/kayak_font/src/glyph.rs b/kayak_font/src/glyph.rs index 0975e26be28c112d2838940fe7ebfa8ef096836b..b67f491496251dc75eddf496118ab2f154cd82db 100644 --- a/kayak_font/src/glyph.rs +++ b/kayak_font/src/glyph.rs @@ -1,3 +1,4 @@ +#![allow(clippy::needless_question_mark, clippy::question_mark)] use nanoserde::{DeJson, DeJsonErr, DeJsonState, SerJson, SerJsonState}; pub struct UnicodeChar(char); diff --git a/kayak_font/src/msdf/contour.rs b/kayak_font/src/msdf/contour.rs index dc3f55adbf13e115851d8abbfa8609b29028db95..5cba51fe7dd0b8bb7758d5690dbbcc24ede0bfa8 100644 --- a/kayak_font/src/msdf/contour.rs +++ b/kayak_font/src/msdf/contour.rs @@ -145,7 +145,7 @@ impl Contour { } } } - return Vector2::sign(total) as i32; + Vector2::sign(total) as i32 } pub fn bound_miters( diff --git a/kayak_font/src/msdf/edge_coloring.rs b/kayak_font/src/msdf/edge_coloring.rs index b74f326fc602802d9baa702e7965034010fdf7c4..4b559d13d882c5d75204249022ab8035975893c5 100644 --- a/kayak_font/src/msdf/edge_coloring.rs +++ b/kayak_font/src/msdf/edge_coloring.rs @@ -17,7 +17,7 @@ fn estimate_edge_length(edge: &EdgeSegment) -> f64 { len += (cur - prev).length(); prev = cur; } - return len; + len } fn switch_color(color: &mut EdgeColor, seed: &mut usize, banned: EdgeColor) { @@ -68,6 +68,7 @@ pub fn simple(shape: &mut Shape, angle_threshold: f64, mut seed: usize) { let edge_count = edges.len(); if edge_count != 0 { let mut prev_dir = edges.last().unwrap().direction(1.0); + #[allow(clippy::needless_range_loop)] for i in 0..edge_count { let edge = &edges[i]; if is_corner( @@ -81,7 +82,8 @@ pub fn simple(shape: &mut Shape, angle_threshold: f64, mut seed: usize) { } } - if corners.len() == 0 { + if corners.is_empty() { + #[allow(clippy::needless_range_loop)] for i in 0..edge_count { edges[i].set_color(EdgeColor::WHITE); } @@ -103,7 +105,7 @@ pub fn simple(shape: &mut Shape, angle_threshold: f64, mut seed: usize) { let mut parts = [EdgeSegment::default(); 7]; let (o1, o2, o3) = edges[0].split_in_thirds(); - parts[0 + 3 * corner] = o1; + parts[3 * corner] = o1; parts[1 + 3 * corner] = o2; parts[2 + 3 * corner] = o3; @@ -124,6 +126,7 @@ pub fn simple(shape: &mut Shape, angle_threshold: f64, mut seed: usize) { parts[2].set_color(colors[2]); } edges.clear(); + #[allow(clippy::needless_range_loop)] for i in 0..7 { edges.push(parts[i]); } @@ -171,6 +174,7 @@ pub fn ink_trap(shape: &mut Shape, angle_threshold: f64, mut seed: usize) { if !contour.edges.is_empty() { let mut prev_direction = contour.edges.last().unwrap().direction(1.0); let mut index = 0; + #[allow(clippy::explicit_counter_loop)] for edge in contour.edges.iter() { if is_corner( prev_direction.normalize(false), @@ -210,10 +214,10 @@ pub fn ink_trap(shape: &mut Shape, angle_threshold: f64, mut seed: usize) { ((3.0 + 2.875 * i as f64 / (m as f64 - 1.0) - 1.4375 + 0.5) as i32 - 3) + 1; contour.edges[(corner + i) % m].set_color(colors[lookup as usize]); } - } else if contour.edges.len() >= 1 { + } else if !contour.edges.is_empty() { let mut parts = vec![EdgeSegment::default(); 7]; let (o1, o2, o3) = contour.edges[0].split_in_thirds(); - parts[0 + 3 * corner] = o1; + parts[3 * corner] = o1; parts[1 + 3 * corner] = o2; parts[2 + 3 * corner] = o3; if contour.edges.len() >= 2 { @@ -258,6 +262,7 @@ pub fn ink_trap(shape: &mut Shape, angle_threshold: f64, mut seed: usize) { let mut color = EdgeColor::WHITE; let mut initial_color = EdgeColor::BLACK; + #[allow(clippy::needless_range_loop)] for i in 0..corner_count { if !corners[i].minor { major_corner_count -= 1; diff --git a/kayak_font/src/msdf/edge_segment/cubic.rs b/kayak_font/src/msdf/edge_segment/cubic.rs index 21444bfa057dc957a9b6cd2680826390bb9dd1d2..afaaae9de69749f5c6d9bd6f7778308e10b8b053 100644 --- a/kayak_font/src/msdf/edge_segment/cubic.rs +++ b/kayak_font/src/msdf/edge_segment/cubic.rs @@ -144,7 +144,7 @@ pub fn signed_distance( t -= Vector2::dot_product(qe, d1) / (Vector2::dot_product(d1, d1) + Vector2::dot_product(qe, d2)); - if t < 0.0 || t > 1.0 { + if !(0.0..=1.0).contains(&t) { break; } @@ -177,10 +177,10 @@ pub fn signed_distance( } } - if param >= 0.0 && param <= 1.0 { - return (SignedDistance::new(min_distance, 0.0), param); + if (0.0..=1.0).contains(¶m) { + (SignedDistance::new(min_distance, 0.0), param) } else if param < 0.5 { - return ( + ( SignedDistance::new( min_distance, fabs(Vector2::dot_product( @@ -189,9 +189,9 @@ pub fn signed_distance( )), ), param, - ); + ) } else { - return ( + ( SignedDistance::new( min_distance, fabs(Vector2::dot_product( @@ -200,6 +200,6 @@ pub fn signed_distance( )), ), param, - ); + ) } } diff --git a/kayak_font/src/msdf/edge_segment/equation_solver.rs b/kayak_font/src/msdf/edge_segment/equation_solver.rs index 6e71ee2bfe7a3b19a307819d59e9bc647fd85c09..b0313c3bc2cfff4b4ab85dfae4d8a6fac388ece7 100644 --- a/kayak_font/src/msdf/edge_segment/equation_solver.rs +++ b/kayak_font/src/msdf/edge_segment/equation_solver.rs @@ -22,12 +22,12 @@ pub fn solve_quadratic(a: f64, b: f64, c: f64) -> (i32, [f64; 3]) { dscr = dscr.sqrt(); result[0] = (-b + dscr) / (2.0 * a); result[1] = (-b - dscr) / (2.0 * a); - return (2, result); + (2, result) } else if dscr == 0.0 { result[0] = -b / (2.0 * a); - return (1, result); + (1, result) } else { - return (0, result); + (0, result) } } @@ -54,7 +54,7 @@ pub fn solve_cubic_norm(mut a: f64, b: f64, c: f64) -> (i32, [f64; 3]) { result[0] = q * (t / 3.0).cos() - a; result[1] = q * ((t + 2.0 * std::f64::consts::PI) / 3.0).cos() - a; result[2] = q * ((t - 2.0 * std::f64::consts::PI) / 3.0).cos() - a; - return (3, result); + (3, result) } else { result_a = -(fabs(r) + (r2 - q3).sqrt()).powf(1.0 / 3.0); if r < 0.0 { @@ -68,7 +68,7 @@ pub fn solve_cubic_norm(mut a: f64, b: f64, c: f64) -> (i32, [f64; 3]) { if fabs(result[2]) < EPSILON { return (2, result); } - return (1, result); + (1, result) } } diff --git a/kayak_font/src/msdf/edge_segment/line.rs b/kayak_font/src/msdf/edge_segment/line.rs index 639b262c8f5aa93934e331476ac0bc83dd896c03..bbf085742f83e15c2a869e983965ec539e1da009 100644 --- a/kayak_font/src/msdf/edge_segment/line.rs +++ b/kayak_font/src/msdf/edge_segment/line.rs @@ -40,11 +40,11 @@ pub fn signed_distance(p0: Vector2, p1: Vector2, origin: Vector2) -> (SignedDist return (SignedDistance::new(ortho_distance, 0.0), param); } } - return ( + ( SignedDistance::new( non_zero_sign(Vector2::cross_product(aq, ab)) as f64 * endpoint_distance, Vector2::dot_product(ab.normalize(false), eq.normalize(false)).abs(), ), param, - ); + ) } diff --git a/kayak_font/src/msdf/edge_segment/mod.rs b/kayak_font/src/msdf/edge_segment/mod.rs index 41411b487fe3213046cb41ee2268910f6117192f..07711eef4fdcb7bf509bfcf1c9439309d45a9d50 100644 --- a/kayak_font/src/msdf/edge_segment/mod.rs +++ b/kayak_font/src/msdf/edge_segment/mod.rs @@ -6,7 +6,7 @@ mod line; mod quadratic; pub fn non_zero_sign(n: f64) -> i32 { - return 2 * (if n > 0.0 { 1 } else { 0 }) - 1; + 2 * (if n > 0.0 { 1 } else { 0 }) - 1 } pub fn mix(a: Vector2, b: Vector2, weight: f64) -> Vector2 { Vector2::new( @@ -17,18 +17,18 @@ pub fn mix(a: Vector2, b: Vector2, weight: f64) -> Vector2 { #[derive(Debug, Clone, Copy)] pub enum EdgeSegment { - LineSegment { + Line { color: EdgeColor, p0: Vector2, p1: Vector2, }, - QuadraticSegment { + Quadratic { color: EdgeColor, p0: Vector2, p1: Vector2, p2: Vector2, }, - CubicSegment { + Cubic { color: EdgeColor, p0: Vector2, p1: Vector2, @@ -39,7 +39,7 @@ pub enum EdgeSegment { impl Default for EdgeSegment { fn default() -> Self { - EdgeSegment::LineSegment { + EdgeSegment::Line { color: EdgeColor::WHITE, p0: Vector2::default(), p1: Vector2::default(), @@ -49,14 +49,14 @@ impl Default for EdgeSegment { impl EdgeSegment { pub fn new_linear(p0: Vector2, p1: Vector2, color: EdgeColor) -> Self { - Self::LineSegment { p0, p1, color } + Self::Line { p0, p1, color } } pub fn new_quadratic(p0: Vector2, mut p1: Vector2, p2: Vector2, color: EdgeColor) -> Self { if p1 == p0 || p1 == p2 { p1 = 0.5 * (p0 + p2); } - Self::QuadraticSegment { p0, p1, p2, color } + Self::Quadratic { p0, p1, p2, color } } pub fn new_cubic( @@ -70,7 +70,7 @@ impl EdgeSegment { p1 = mix(p0, p3, 1.0 / 3.0); p2 = mix(p0, p3, 2.0 / 3.0); } - Self::CubicSegment { + Self::Cubic { p0, p1, p2, @@ -110,39 +110,33 @@ impl EdgeSegment { pub fn direction(&self, param: f64) -> Vector2 { match *self { - Self::LineSegment { p0, p1, .. } => line::direction(p0, p1, param), - Self::QuadraticSegment { p0, p1, p2, .. } => quadratic::direction(p0, p1, p2, param), - Self::CubicSegment { p0, p1, p2, p3, .. } => cubic::direction(p0, p1, p2, p3, param), + Self::Line { p0, p1, .. } => line::direction(p0, p1, param), + Self::Quadratic { p0, p1, p2, .. } => quadratic::direction(p0, p1, p2, param), + Self::Cubic { p0, p1, p2, p3, .. } => cubic::direction(p0, p1, p2, p3, param), } } pub fn point(&self, param: f64) -> Vector2 { match *self { - Self::LineSegment { p0, p1, .. } => line::point(p0, p1, param), - Self::QuadraticSegment { p0, p1, p2, .. } => quadratic::point(p0, p1, p2, param), - Self::CubicSegment { p0, p1, p2, p3, .. } => cubic::point(p0, p1, p2, p3, param), + Self::Line { p0, p1, .. } => line::point(p0, p1, param), + Self::Quadratic { p0, p1, p2, .. } => quadratic::point(p0, p1, p2, param), + Self::Cubic { p0, p1, p2, p3, .. } => cubic::point(p0, p1, p2, p3, param), } } pub fn find_bounds(&self, l: &mut f64, b: &mut f64, r: &mut f64, t: &mut f64) { match *self { - Self::LineSegment { p0, p1, .. } => line::find_bounds(p0, p1, l, b, r, t), - Self::QuadraticSegment { p0, p1, p2, .. } => { - quadratic::find_bounds(p0, p1, p2, l, b, r, t) - } - Self::CubicSegment { p0, p1, p2, p3, .. } => { - cubic::find_bounds(p0, p1, p2, p3, l, b, r, t) - } + Self::Line { p0, p1, .. } => line::find_bounds(p0, p1, l, b, r, t), + Self::Quadratic { p0, p1, p2, .. } => quadratic::find_bounds(p0, p1, p2, l, b, r, t), + Self::Cubic { p0, p1, p2, p3, .. } => cubic::find_bounds(p0, p1, p2, p3, l, b, r, t), } } pub fn split_in_thirds(&self) -> (EdgeSegment, EdgeSegment, EdgeSegment) { match *self { - Self::LineSegment { p0, p1, color } => line::split_in_thirds(p0, p1, color), - Self::QuadraticSegment { p0, p1, p2, color } => { - quadratic::split_in_thirds(p0, p1, p2, color) - } - Self::CubicSegment { + Self::Line { p0, p1, color } => line::split_in_thirds(p0, p1, color), + Self::Quadratic { p0, p1, p2, color } => quadratic::split_in_thirds(p0, p1, p2, color), + Self::Cubic { p0, p1, p2, @@ -154,37 +148,33 @@ impl EdgeSegment { pub fn signed_distance(&self, origin: Vector2) -> (SignedDistance, f64) { match *self { - Self::LineSegment { p0, p1, .. } => line::signed_distance(p0, p1, origin), - Self::QuadraticSegment { p0, p1, p2, .. } => { - quadratic::signed_distance(p0, p1, p2, origin) - } - Self::CubicSegment { p0, p1, p2, p3, .. } => { - cubic::signed_distance(p0, p1, p2, p3, origin) - } + Self::Line { p0, p1, .. } => line::signed_distance(p0, p1, origin), + Self::Quadratic { p0, p1, p2, .. } => quadratic::signed_distance(p0, p1, p2, origin), + Self::Cubic { p0, p1, p2, p3, .. } => cubic::signed_distance(p0, p1, p2, p3, origin), } } pub fn has_color(&self, c: EdgeColor) -> bool { match *self { - Self::LineSegment { color, .. } => color as usize & c as usize != 0, - Self::QuadraticSegment { color, .. } => color as usize & c as usize != 0, - Self::CubicSegment { color, .. } => color as usize & c as usize != 0, + Self::Line { color, .. } => color as usize & c as usize != 0, + Self::Quadratic { color, .. } => color as usize & c as usize != 0, + Self::Cubic { color, .. } => color as usize & c as usize != 0, } } pub fn get_color(&self) -> EdgeColor { match self { - Self::LineSegment { color, .. } => *color, - Self::QuadraticSegment { color, .. } => *color, - Self::CubicSegment { color, .. } => *color, + Self::Line { color, .. } => *color, + Self::Quadratic { color, .. } => *color, + Self::Cubic { color, .. } => *color, } } pub fn set_color(&mut self, c: EdgeColor) { match self { - Self::LineSegment { color, .. } => *color = c, - Self::QuadraticSegment { color, .. } => *color = c, - Self::CubicSegment { color, .. } => *color = c, + Self::Line { color, .. } => *color = c, + Self::Quadratic { color, .. } => *color = c, + Self::Cubic { color, .. } => *color = c, } } } diff --git a/kayak_font/src/msdf/edge_segment/quadratic.rs b/kayak_font/src/msdf/edge_segment/quadratic.rs index c0edbc6492a27197fbbad4f826ae617ab3fc1862..5771a08bb16da294569ad98db7875bb432f6e46b 100644 --- a/kayak_font/src/msdf/edge_segment/quadratic.rs +++ b/kayak_font/src/msdf/edge_segment/quadratic.rs @@ -107,24 +107,24 @@ pub fn signed_distance( } } - if param >= 0.0 && param <= 1.0 { - return (SignedDistance::new(min_distance, 0.0), param); + if (0.0..=1.0).contains(¶m) { + (SignedDistance::new(min_distance, 0.0), param) } else if param < 0.5 { - return ( + ( SignedDistance::new( min_distance, (Vector2::dot_product(ab.normalize(false), qa.normalize(false))).abs(), ), param, - ); + ) } else { - return ( + ( SignedDistance::new( min_distance, (Vector2::dot_product((p2 - p1).normalize(false), (p2 - origin).normalize(false))) .abs(), ), param, - ); + ) } } diff --git a/kayak_font/src/msdf/gen.rs b/kayak_font/src/msdf/gen.rs index 61cc4f9f581e9af5213fdd022df8267dea1d053a..8cb851674f61557b68e5d062ae872aa15753d4e3 100644 --- a/kayak_font/src/msdf/gen.rs +++ b/kayak_font/src/msdf/gen.rs @@ -166,9 +166,7 @@ pub fn msdf_error_correction(output: &mut FloatRGBBmp, threshold: Vector2) { } } } - let clash_count = clashes.len(); - for i in 0..clash_count { - let clash = clashes[i]; + for clash in clashes { let pixel = output.get_pixel(clash.0, clash.1); let med = median(pixel.r, pixel.g, pixel.b); output.set_pixel(clash.0, clash.1, FloatRGB::new(med, med, med)); diff --git a/kayak_font/src/msdf/mod.rs b/kayak_font/src/msdf/mod.rs index a687ffecfdbf52b72f4129ad4be27da7cbbff080..4788d60b87218b84bb812e2f34e31fe406deca23 100644 --- a/kayak_font/src/msdf/mod.rs +++ b/kayak_font/src/msdf/mod.rs @@ -12,6 +12,7 @@ pub mod signed_distance; pub mod ttf_parser; pub mod vector; +#[allow(clippy::upper_case_acronyms)] #[derive(Debug, Clone, Copy, PartialEq, FromPrimitive)] pub enum EdgeColor { BLACK = 0, diff --git a/kayak_font/src/msdf/shape.rs b/kayak_font/src/msdf/shape.rs index 5b4d34f3f636dd3bf207d820a3e892e3bacb83a9..d596bcd2a922c67d801ec93b55024b2d5778c752 100644 --- a/kayak_font/src/msdf/shape.rs +++ b/kayak_font/src/msdf/shape.rs @@ -54,6 +54,6 @@ impl Shape { let mut right = LARGE_VALUE; let mut top = -LARGE_VALUE; self.find_bounds(&mut left, &mut bottom, &mut right, &mut top); - return (left, bottom, right, top); + (left, bottom, right, top) } } diff --git a/kayak_font/src/msdf/vector.rs b/kayak_font/src/msdf/vector.rs index 34d7a29534dcbba343328e317b16dc29ac311b05..672deaf00a12cea356d3f70471a0c365e9972d4d 100644 --- a/kayak_font/src/msdf/vector.rs +++ b/kayak_font/src/msdf/vector.rs @@ -23,25 +23,25 @@ impl Vector2 { Vector2::new(0.0, -allow_zero) }; } - return if polarity { + if polarity { Vector2::new(-self.y / len, self.x / len) } else { Vector2::new(self.y / len, -self.x / len) - }; + } } pub fn get_orthogonal(&self, polarity: bool) -> Vector2 { - return if polarity { + if polarity { Vector2::new(-self.y, self.x) } else { Vector2::new(self.y, -self.x) - }; + } } pub fn dot_product(a: Vector2, b: Vector2) -> f64 { - return a.x * b.x + a.y * b.y; + a.x * b.x + a.y * b.y } pub fn cross_product(a: Vector2, b: Vector2) -> f64 { - return a.x * b.y - a.y * b.x; + a.x * b.y - a.y * b.x } pub fn normalize(&self, allow_zero: bool) -> Vector2 { @@ -50,32 +50,37 @@ impl Vector2 { let allow_zero = if !allow_zero { 1.0 } else { 0.0 }; return Vector2::new(0.0, allow_zero); } - return Vector2::new(self.x / len, self.y / len); + Vector2::new(self.x / len, self.y / len) } pub fn length(&self) -> f64 { - return (self.x * self.x + self.y * self.y).sqrt(); + (self.x * self.x + self.y * self.y).sqrt() } pub fn clamp(n: i32, b: i32) -> i32 { if n > 0 { - return if n <= b { n } else { b }; + if n <= b { + n + } else { + b + } + } else { + 0 } - return 0; } pub fn sign(n: f64) -> f64 { - return if n == 0.0 { + if n == 0.0 { 0.0 } else if n > 0.0 { 1.0 } else { -1.0 - }; + } } pub fn shoelace(a: Vector2, b: Vector2) -> f64 { - return (b.x - a.x) * (a.y + b.y); + (b.x - a.x) * (a.y + b.y) } pub fn point_bounds(p: Vector2, l: &mut f64, b: &mut f64, r: &mut f64, t: &mut f64) { diff --git a/kayak_font/src/ttf/loader.rs b/kayak_font/src/ttf/loader.rs index fb0dc19cb85f74386155c4c24453d8d61f0de7b1..27b423a162d58426f44895008df4fec3899e5db3 100644 --- a/kayak_font/src/ttf/loader.rs +++ b/kayak_font/src/ttf/loader.rs @@ -1,3 +1,4 @@ +#![allow(clippy::needless_question_mark, clippy::question_mark)] use bevy::{ asset::{AssetLoader, LoadContext, LoadedAsset}, render::render_resource::{Extent3d, TextureFormat}, @@ -17,7 +18,7 @@ use crate::{ pub struct TTFLoader; #[derive(DeJson, Default, Debug, Clone)] -pub struct KTTF { +pub struct Kttf { file: String, char_range_start: String, char_range_end: String, @@ -38,7 +39,7 @@ impl AssetLoader for TTFLoader { .downcast_ref::<FileAssetIo>() .unwrap(); - let kttf: KTTF = + let kttf: Kttf = nanoserde::DeJson::deserialize_json(std::str::from_utf8(bytes).unwrap()).unwrap(); let char_range_start = @@ -78,10 +79,8 @@ impl AssetLoader for TTFLoader { for subtable in subtable.subtables { subtable.codepoints(|codepoint| { if let Some(mapping) = subtable.glyph_index(codepoint) { - glyph_to_char - .insert(mapping, unsafe { std::mem::transmute(codepoint) }); - char_to_glyph - .insert(unsafe { std::mem::transmute(codepoint) }, mapping); + glyph_to_char.insert(mapping, std::char::from_u32(codepoint).unwrap()); + char_to_glyph.insert(std::char::from_u32(codepoint).unwrap(), mapping); } }) } @@ -134,7 +133,7 @@ impl AssetLoader for TTFLoader { advance: advance * pixel_scale as f32, atlas_bounds: Some(Rect { left: 0.0, - bottom: 0.0 as f32, + bottom: 0.0, right: size_x as f32, top: size_y as f32, }), @@ -163,7 +162,7 @@ impl AssetLoader for TTFLoader { range, scale, translation + Vector2::new(0.0, size_x as f64 * 1.25), - 1.11111111111111111, + 1.111_111_111_111_111_2, ); // let left = (translation.x - char_bounds.x_min as f64 * pixel_scale).max(0.0).floor() as u32; @@ -198,16 +197,19 @@ impl AssetLoader for TTFLoader { yy += size_y as u32; } - let image_bytes = if cache_image.is_err() { - #[cfg(not(target_family = "wasm"))] - image_builder - .save(asset_io.root_path().join(cache_path)) - .unwrap(); - image_builder.as_bytes().to_vec() - } else { - let cache_image = cache_image.unwrap(); - let image = image::load_from_memory(&cache_image).unwrap(); - image.as_bytes().to_vec() + let image_bytes = match cache_image { + Ok(cache_image) => { + let cache_image = cache_image; + let image = image::load_from_memory(&cache_image).unwrap(); + image.as_bytes().to_vec() + } + Err(_) => { + #[cfg(not(target_family = "wasm"))] + image_builder + .save(asset_io.root_path().join(cache_path)) + .unwrap(); + image_builder.as_bytes().to_vec() + } }; let mut sdf = Sdf::default(); @@ -241,7 +243,7 @@ impl AssetLoader for TTFLoader { } fn calculate_plane( - loaded_file: &KTTF, + loaded_file: &Kttf, shape: &mut Shape, geometry_scale: f32, scale: f32, diff --git a/kayak_ui_macros/src/children.rs b/kayak_ui_macros/src/children.rs index 627821bd48510f712622064a7d388e843a698869..36acf9ed0525ce6d19358cc9398f16a1d41526ce 100644 --- a/kayak_ui_macros/src/children.rs +++ b/kayak_ui_macros/src/children.rs @@ -13,10 +13,9 @@ impl Children { } pub fn is_block(&self) -> bool { - self.nodes.iter().any(|node| match node { - Child::RawBlock(_) => true, - _ => false, - }) + self.nodes + .iter() + .any(|node| matches!(node, Child::RawBlock(..))) } // pub fn get_clonable_attributes(&self, index: usize) -> Vec<proc_macro2::TokenStream> { @@ -64,10 +63,7 @@ impl Children { ( entity_id, quote! { #child }, - match child { - Child::Widget(_) => true, - _ => false, - }, + matches!(child, Child::Widget(_)), index, ) }) @@ -165,6 +161,7 @@ impl Children { let mut output = Vec::new(); // output.push(quote! { #base_clone }); + #[allow(clippy::needless_range_loop)] for i in 0..children_quotes.len() { // output.push(quote! { #base_clones_inner }); let name: proc_macro2::TokenStream = format!("child{}", i).parse().unwrap(); diff --git a/src/calculate_nodes.rs b/src/calculate_nodes.rs index 1a1548f8bf91880d99573d6d0600f49333331790..9d7b724da8217dfee3d41150b718613f3263ddc9 100644 --- a/src/calculate_nodes.rs +++ b/src/calculate_nodes.rs @@ -273,7 +273,7 @@ fn create_primitive( .font .resolve_or_else(|| String::from(crate::DEFAULT_FONT)); // --- Bind to Font Asset --- // - let font_handle = font_mapping.get_handle(font.clone()).unwrap(); + let font_handle = font_mapping.get_handle(font).unwrap(); if let Some(font) = fonts.get(&font_handle) { if let Ok(node_tree) = context.tree.try_read() { if let Some(parent_id) = @@ -300,7 +300,7 @@ fn create_primitive( font_size, line_height: styles.line_height.resolve_or(font_size * 1.2), alignment: *alignment, - ..properties.clone() + ..*properties }; properties.max_size = ( diff --git a/src/camera/mod.rs b/src/camera/mod.rs index f260d649c4ff1ded0f0a3befe5b44e5f7697b1b2..1e02a5305fe0ec7bc3a67965ec61dbeef937294b 100644 --- a/src/camera/mod.rs +++ b/src/camera/mod.rs @@ -12,7 +12,7 @@ impl ExtractComponent for CameraUIKayak { type Out = CameraUIKayak; fn extract_component(item: QueryItem<Self::Query>) -> Option<Self::Out> { - Some(item.clone()) + Some(*item) } } diff --git a/src/context.rs b/src/context.rs index 1e27f4131b0a94d62abe7e1f849553aff204e9bc..61612160a982173adb610a5642af223bead37aa9 100644 --- a/src/context.rs +++ b/src/context.rs @@ -143,7 +143,7 @@ impl KayakRootContext { /// Retreives the current entity that has focus or None if nothing is focused. pub fn get_current_focus(&self) -> Option<Entity> { if let Ok(tree) = self.focus_tree.try_read() { - return tree.current().and_then(|a| Some(a.0)); + return tree.current().map(|a| a.0); } None } @@ -335,7 +335,7 @@ impl KayakRootContext { tree.add(WrappedIndex(entity.unwrap()), parent_id.map(WrappedIndex)) } } - } else if let Ok(mut tree) = self.order_tree.try_write() { + } else if let Ok(_tree) = self.order_tree.try_write() { // let root_node = tree.root_node; // if entity.map(WrappedIndex) != root_node { // tree.add(entity.map(WrappedIndex).unwrap(), root_node); @@ -420,7 +420,6 @@ impl KayakRootContext { None, 0, 0, - 0, ); } } @@ -444,7 +443,6 @@ fn recurse_node_tree_to_build_primitives( _parent_global_z: f32, mut current_global_z: f32, mut prev_clip: Option<ExtractedQuad>, - depth: usize, mut current_opacity_layer: u32, mut total_opacity_layers: u32, ) -> (usize, f32, u32) { @@ -546,7 +544,6 @@ fn recurse_node_tree_to_build_primitives( current_parent_global_z, current_global_z, prev_clip.clone(), - depth + 1, current_opacity_layer, total_opacity_layers, ); @@ -890,7 +887,7 @@ fn update_widgets( (unique_ids.try_write(), unique_ids_parents.try_write()) { if let Some(parent) = unique_ids_parents.get(&entity) { - if let Some(keyed_hashmap) = unique_ids.get_mut(&parent) { + if let Some(keyed_hashmap) = unique_ids.get_mut(parent) { let possible_key = keyed_hashmap .iter() .find(|(_, keyed_entity)| **keyed_entity == entity) @@ -1075,9 +1072,9 @@ fn update_widget( cloned_widget_entities: &Arc<RwLock<HashMap<Entity, Entity>>>, widget_state: &WidgetState, new_ticks: &mut HashMap<String, u32>, - order_tree: &Arc<RwLock<Tree>>, - unique_ids: &Arc<RwLock<HashMap<Entity, HashMap<String, Entity>>>>, - unique_ids_parents: &Arc<RwLock<HashMap<Entity, Entity>>>, + _order_tree: &Arc<RwLock<Tree>>, + _unique_ids: &Arc<RwLock<HashMap<Entity, HashMap<String, Entity>>>>, + _unique_ids_parents: &Arc<RwLock<HashMap<Entity, Entity>>>, ) -> (Tree, bool) { // Check if we should update this widget let should_rerender = { @@ -1120,10 +1117,12 @@ fn update_widget( let widget_update_system = &mut systems .get_mut(&widget_type) - .expect(&format!( - "Wasn't able to find render/update systems for widget: {}!", - widget_type - )) + .unwrap_or_else(|| { + panic!( + "Wasn't able to find render/update systems for widget: {}!", + widget_type + ) + }) .0; let old_tick = widget_update_system.get_last_change_tick(); @@ -1398,8 +1397,8 @@ impl From<String> for WidgetName { } } -impl Into<String> for WidgetName { - fn into(self) -> String { - self.0 +impl From<WidgetName> for String { + fn from(val: WidgetName) -> Self { + val.0 } } diff --git a/src/event_dispatcher.rs b/src/event_dispatcher.rs index 61f7c877b473b39c11eff3b2c3d6e962d2a19d60..a7fcc9893869e87db18d8ab111e25f448fd7ed03 100644 --- a/src/event_dispatcher.rs +++ b/src/event_dispatcher.rs @@ -177,7 +177,7 @@ impl EventDispatcher { /// Process and dispatch a set of [InputEvents](crate::InputEvent) pub(crate) fn process_events( &mut self, - input_events: &Vec<InputEvent>, + input_events: &[InputEvent], context: &mut KayakRootContext, world: &mut World, ) { @@ -797,39 +797,35 @@ impl EventDispatcher { context: &mut KayakRootContext, world: &mut World, ) { - match event.event_type { - EventType::KeyDown(evt) => match evt.key() { - KeyCode::Tab => { - let (index, current_focus) = - if let Ok(mut focus_tree) = context.focus_tree.try_write() { - let current_focus = focus_tree.current(); - - let index = if evt.is_shift_pressed() { - focus_tree.prev() - } else { - focus_tree.next() - }; - (index, current_focus) + if let EventType::KeyDown(evt) = event.event_type { + if let KeyCode::Tab = evt.key() { + let (index, current_focus) = + if let Ok(mut focus_tree) = context.focus_tree.try_write() { + let current_focus = focus_tree.current(); + + let index = if evt.is_shift_pressed() { + focus_tree.prev() } else { - (None, None) + focus_tree.next() }; - - if let Some(index) = index { - let mut events = vec![KEvent::new(index.0, EventType::Focus)]; - if let Some(current_focus) = current_focus { - if current_focus != index { - events.push(KEvent::new(current_focus.0, EventType::Blur)); - } - } - if let Ok(mut focus_tree) = context.focus_tree.try_write() { - focus_tree.focus(index); + (index, current_focus) + } else { + (None, None) + }; + + if let Some(index) = index { + let mut events = vec![KEvent::new(index.0, EventType::Focus)]; + if let Some(current_focus) = current_focus { + if current_focus != index { + events.push(KEvent::new(current_focus.0, EventType::Blur)); } - self.dispatch_events(events, context, world); } + if let Ok(mut focus_tree) = context.focus_tree.try_write() { + focus_tree.focus(index); + } + self.dispatch_events(events, context, world); } - _ => {} - }, - _ => {} + } } } diff --git a/src/input.rs b/src/input.rs index a131a479833ac702ea593ad8bb8a050db1bd6547..cf51b47ab4b5093f05b7e63e17d674d4e3e37cd1 100644 --- a/src/input.rs +++ b/src/input.rs @@ -18,7 +18,7 @@ pub(crate) fn process_events(world: &mut World) { // TODO: Rewrite an process events per window. let window_size = if let Ok(window) = world .query_filtered::<&Window, With<PrimaryWindow>>() - .get_single(&world) + .get_single(world) { Vec2::new(window.width(), window.height()) } else { @@ -63,21 +63,18 @@ pub(crate) fn process_events(world: &mut World) { { // Currently, we can only handle a single MouseMoved event at a time so everything but the last needs to be skipped input_events.push(InputEvent::MouseMoved(( - event.position.x as f32, - window_size.y - event.position.y as f32, + event.position.x, + window_size.y - event.position.y, ))); } for event in custom_event_mouse_button.0.iter(&mouse_button_input_events) { - match event.button { - MouseButton::Left => { - if event.state == ButtonState::Pressed { - input_events.push(InputEvent::MouseLeftPress); - } else if event.state == ButtonState::Released { - input_events.push(InputEvent::MouseLeftRelease); - } + if let MouseButton::Left = event.button { + if event.state == ButtonState::Pressed { + input_events.push(InputEvent::MouseLeftPress); + } else if event.state == ButtonState::Released { + input_events.push(InputEvent::MouseLeftRelease); } - _ => {} } } diff --git a/src/render/extract.rs b/src/render/extract.rs index 8385e755f981d3c410e6841f5471c5eea7556189..f9942d8cc14f07030e8715c16c9fdd9d217bfb94 100644 --- a/src/render/extract.rs +++ b/src/render/extract.rs @@ -56,18 +56,14 @@ pub fn extract( for (_entity, context) in context_query.iter() { let dpi = if let Ok(camera) = cameras.get(context.camera_entity) { - match &camera.target { - bevy::render::camera::RenderTarget::Window(window_ref) => match window_ref { - WindowRef::Primary => { - if let Ok(window) = primary_window.get_single() { - window.scale_factor() as f32 - } else { - 1.0 - } - } - _ => 1.0, - }, - _ => 1.0, + if let bevy::render::camera::RenderTarget::Window(WindowRef::Primary) = &camera.target { + if let Ok(window) = primary_window.get_single() { + window.scale_factor() as f32 + } else { + 1.0 + } + } else { + 1.0 } } else { 1.0 diff --git a/src/render/font/extract.rs b/src/render/font/extract.rs index 3f16445651c16b75df82d989e2f4333b72b399e0..1681451cfcf358b27b49f4cad4f930b73105f833 100644 --- a/src/render/font/extract.rs +++ b/src/render/font/extract.rs @@ -26,7 +26,7 @@ pub fn extract_texts( ) -> Vec<ExtractedQuad> { let mut extracted_texts = Vec::new(); - let font_handle = font_mapping.get_handle(font.clone()).unwrap(); + let font_handle = font_mapping.get_handle(font).unwrap(); let font = match fonts.get(&font_handle) { Some(font) => font, None => { diff --git a/src/render/mod.rs b/src/render/mod.rs index 58def9567849af14e79e39233da9e7159d88ab07..f1da1813f7c1c44d65bec395dc8192ca69eb385d 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -185,17 +185,14 @@ pub fn update_opacity_layer_cameras( mut images: ResMut<Assets<Image>>, ) { for (camera_entity, camera) in cameras.iter() { - match &camera.target { - RenderTarget::Window(window_ref) => { - let window_entity = match window_ref { - WindowRef::Entity(entity) => *entity, - WindowRef::Primary => primary_window.get_single().unwrap(), - }; - if let Ok(camera_window) = windows.get(window_entity) { - opacity_layers.add_or_update(&camera_entity, camera_window, &mut images); - } + if let RenderTarget::Window(window_ref) = &camera.target { + let window_entity = match window_ref { + WindowRef::Entity(entity) => *entity, + WindowRef::Primary => primary_window.get_single().unwrap(), + }; + if let Ok(camera_window) = windows.get(window_entity) { + opacity_layers.add_or_update(&camera_entity, camera_window, &mut images); } - _ => {} } } } @@ -220,9 +217,9 @@ pub fn extract_core_pipeline_camera_phases( fn prepare_opacity_layers( mut opacity_layers: ResMut<OpacityLayerManager>, - mut gpu_images: ResMut<RenderAssets<Image>>, + gpu_images: Res<RenderAssets<Image>>, ) { for (_, layer) in opacity_layers.camera_layers.iter_mut() { - layer.set_texture_views(&mut gpu_images); + layer.set_texture_views(&gpu_images); } } diff --git a/src/render/unified/pipeline.rs b/src/render/unified/pipeline.rs index 2291065aa6cd85b3072953be104c40dc5299553d..1f929da115cee549ac98ac45421da4905f4232ee 100644 --- a/src/render/unified/pipeline.rs +++ b/src/render/unified/pipeline.rs @@ -578,7 +578,7 @@ pub struct QueueQuads<'w, 's> { quad_meta: ResMut<'w, QuadMeta>, quad_pipeline: Res<'w, UnifiedPipeline>, pipelines: ResMut<'w, SpecializedRenderPipelines<UnifiedPipeline>>, - pipeline_cache: ResMut<'w, PipelineCache>, + pipeline_cache: Res<'w, PipelineCache>, extracted_quads: ResMut<'w, ExtractedQuads>, views: Query< 'w, @@ -610,7 +610,7 @@ pub fn queue_quads(queue_quads: QueueQuads) { mut quad_meta, quad_pipeline, mut pipelines, - mut pipeline_cache, + pipeline_cache, mut extracted_quads, mut views, mut image_bind_groups, @@ -663,7 +663,7 @@ pub fn queue_quads(queue_quads: QueueQuads) { msaa: 1, hdr: view.hdr, }; - let spec_pipeline = pipelines.specialize(&mut pipeline_cache, &quad_pipeline, key); + let spec_pipeline = pipelines.specialize(&pipeline_cache, &quad_pipeline, key); for quad in extracted_quads.iter_mut() { if quad.quad_type == UIQuadType::Clip { @@ -1167,15 +1167,13 @@ impl<T: PhaseItem + TransparentUIGeneric + BatchedPhaseItem> RenderCommand<T> fo let image_bind_groups = image_bind_groups.into_inner(); if let Some(bind_group) = image_bind_groups.values.get(&Handle::weak(*image_handle)) { pass.set_bind_group(1, bind_group, &[]); + } else if let Some(bind_group) = image_bind_groups + .font_values + .get(&Handle::weak(*image_handle)) + { + pass.set_bind_group(1, bind_group, &[]); } else { - if let Some(bind_group) = image_bind_groups - .font_values - .get(&Handle::weak(*image_handle)) - { - pass.set_bind_group(1, bind_group, &[]); - } else { - pass.set_bind_group(1, &unified_pipeline.default_image.1, &[]); - } + pass.set_bind_group(1, &unified_pipeline.default_image.1, &[]); } } else { pass.set_bind_group(1, &unified_pipeline.default_image.1, &[]); diff --git a/src/styles/mod.rs b/src/styles/mod.rs index f4c569384d99667834057db071cfde083d04a72a..5a084d9a59b3105c9c53606678911e9fd19ee0ca 100644 --- a/src/styles/mod.rs +++ b/src/styles/mod.rs @@ -21,9 +21,9 @@ pub use units::*; #[derive(Component, Reflect, Debug, Default, Clone, PartialEq)] pub struct ComputedStyles(pub KStyle); -impl Into<ComputedStyles> for KStyle { - fn into(self) -> ComputedStyles { - ComputedStyles(self) +impl From<KStyle> for ComputedStyles { + fn from(val: KStyle) -> Self { + ComputedStyles(val) } } @@ -47,7 +47,7 @@ impl BoxShadow { let box_shadow_string: String = s.to_string(); let box_shadow_string = box_shadow_string .replace("box-shadow: ", "") - .replace(";", ""); + .replace(';', ""); let values_parsed = fancy_regex::Regex::new(r",(?![^\(]*\))").unwrap(); let split_regex = fancy_regex::Regex::new(r"\s(?![^(]*\))").unwrap(); @@ -60,7 +60,7 @@ impl BoxShadow { for value in values_split.map(|s| s.trim()) { // Split single shadow let parts = Split { - finder: split_regex.find_iter(&value), + finder: split_regex.find_iter(value), last: 0, } .collect::<Vec<_>>(); @@ -68,14 +68,14 @@ impl BoxShadow { let color = parts .last() .map(|last| { - if last.contains("rgb") || last.contains("#") { - Some(last.clone()) + if last.contains("rgb") || last.contains('#') { + Some(*last) } else { None } }) .and_then(|s| s) - .unwrap_or(parts.first().unwrap().clone()); + .unwrap_or(parts.first().cloned().unwrap()); let nums = parts .iter() @@ -84,7 +84,7 @@ impl BoxShadow { .map(|v| v.replace("px", "").parse::<f32>().unwrap_or(0.0)) .collect::<Vec<f32>>(); - let offset_x = nums.get(0).copied().unwrap_or(0.0); + let offset_x = nums.first().copied().unwrap_or(0.0); let offset_y = nums.get(1).copied().unwrap_or(0.0); let blur_radius = nums.get(2).copied().unwrap_or(0.0); let spread = nums.get(3).copied().unwrap_or(0.0); @@ -112,11 +112,11 @@ fn is_rgba(s: &str) -> bool { } fn parse_rgba(s: &str) -> Color { - let s = s.replace("rgba(", "").replace("rgb(", "").replace(")", ""); - let values = s.split(",").collect::<Vec<_>>(); + let s = s.replace("rgba(", "").replace("rgb(", "").replace(')', ""); + let values = s.split(',').collect::<Vec<_>>(); let r = values - .get(0) + .first() .map(|s| s.trim().parse::<f32>().map(|v| v / 255.0).unwrap_or(0.0)) .unwrap_or(0.0); let g = values diff --git a/src/styles/style.rs b/src/styles/style.rs index 7b5ae7b904a3b0983daf1e93f8c238df1384e9c7..60b697d5caa0e0bf3852adca62bc2f19afaf0e0c 100644 --- a/src/styles/style.rs +++ b/src/styles/style.rs @@ -678,7 +678,7 @@ fn lerp_ang(a: f32, b: f32, x: f32) -> f32 { let ang = ((((a - b) % std::f32::consts::TAU) + std::f32::consts::PI * 3.) % std::f32::consts::TAU) - std::f32::consts::PI; - return ang * x + b; + ang * x + b } /// Linear interpolation between two colors in Lch space @@ -693,13 +693,13 @@ fn lerp_lch(a: Color, b: Color, x: f32) -> Color { let alpha = lerp(a_a, b_a, x); - return Color::Lcha { + Color::Lcha { lightness: xy.x, chroma: xy.y, hue, alpha, } - .as_rgba(); + .as_rgba() } fn rgb_to_hsv(from: &Color) -> Vec3 { @@ -739,7 +739,7 @@ fn rgb_to_hsv(from: &Color) -> Vec3 { res.x = 4.0 + (r - g) / delta; } - res.x = res.x * 60.0; // Convert to degrees + res.x *= 60.0; // Convert to degrees if res.x < 0.0 { res.x += 360.0; // Unwrap angle in case of negative } @@ -759,23 +759,23 @@ fn hsv_to_rgb(from: &Vec3) -> Color { let mut res = Vec4::new(0.0, 0.0, 0.0, 1.0); - if h >= 0.0 && h < 60.0 { + if (0.0..60.0).contains(&h) { res.x = c; res.y = x; res.z = 0.0; - } else if h >= 60.0 && h < 120.0 { + } else if (60.0..120.0).contains(&h) { res.x = x; res.y = c; res.z = 0.0; - } else if h >= 120.0 && h < 180.0 { + } else if (120.0..180.0).contains(&h) { res.x = 0.0; res.y = c; res.z = x; - } else if h >= 180.0 && h < 240.0 { + } else if (180.0..240.0).contains(&h) { res.x = 0.0; res.y = x; res.z = c; - } else if h >= 240.0 && h < 300.0 { + } else if (240.0..300.0).contains(&h) { res.x = x; res.y = 0.0; res.z = c; @@ -785,7 +785,7 @@ fn hsv_to_rgb(from: &Vec3) -> Color { res.z = x; } - res = res + Vec4::new(m, m, m, 0.0); + res += Vec4::new(m, m, m, 0.0); Color::from(res) } diff --git a/src/styles/units.rs b/src/styles/units.rs index 01c563153c3db11b0b397b677c2a89f2ada5b967..eab69b5c06676b93eaf48c4db45d1a4c75b06da1 100644 --- a/src/styles/units.rs +++ b/src/styles/units.rs @@ -17,9 +17,9 @@ impl Default for LayoutType { } } -impl Into<morphorm::LayoutType> for LayoutType { - fn into(self) -> morphorm::LayoutType { - match self { +impl From<LayoutType> for morphorm::LayoutType { + fn from(val: LayoutType) -> Self { + match val { LayoutType::Column => morphorm::LayoutType::Column, LayoutType::Row => morphorm::LayoutType::Row, LayoutType::Grid => morphorm::LayoutType::Grid, @@ -42,11 +42,11 @@ impl Default for KPositionType { } } -impl Into<morphorm::PositionType> for KPositionType { - fn into(self) -> morphorm::PositionType { - match self { - Self::ParentDirected => morphorm::PositionType::ParentDirected, - Self::SelfDirected => morphorm::PositionType::SelfDirected, +impl From<KPositionType> for morphorm::PositionType { + fn from(val: KPositionType) -> Self { + match val { + KPositionType::ParentDirected => morphorm::PositionType::ParentDirected, + KPositionType::SelfDirected => morphorm::PositionType::SelfDirected, } } } @@ -70,13 +70,13 @@ impl Default for Units { } } -impl Into<morphorm::Units> for Units { - fn into(self) -> morphorm::Units { - match self { - Self::Pixels(value) => morphorm::Units::Pixels(value), - Self::Percentage(value) => morphorm::Units::Percentage(value), - Self::Stretch(value) => morphorm::Units::Stretch(value), - Self::Auto => morphorm::Units::Auto, +impl From<Units> for morphorm::Units { + fn from(val: Units) -> Self { + match val { + Units::Pixels(value) => morphorm::Units::Pixels(value), + Units::Percentage(value) => morphorm::Units::Percentage(value), + Units::Stretch(value) => morphorm::Units::Stretch(value), + Units::Auto => morphorm::Units::Auto, } } } @@ -85,42 +85,30 @@ impl Units { /// Converts the units to an f32 value pub fn value_or(&self, parent_value: f32, auto: f32) -> f32 { match self { - &Units::Pixels(pixels) => pixels, - &Units::Percentage(percentage) => (percentage / 100.0) * parent_value, - &Units::Stretch(_) => auto, - &Units::Auto => auto, + Units::Pixels(pixels) => *pixels, + Units::Percentage(percentage) => (percentage / 100.0) * parent_value, + Units::Stretch(_) => auto, + Units::Auto => auto, } } /// Returns true if the value is in pixels pub fn is_pixels(&self) -> bool { - match self { - Units::Pixels(_) => true, - _ => false, - } + matches!(self, Units::Pixels(_)) } /// Returns true if the value is a percentage pub fn is_percentage(&self) -> bool { - match self { - Units::Percentage(_) => true, - _ => false, - } + matches!(self, Units::Percentage(_)) } /// Returns true if the value is a stretch factor pub fn is_stretch(&self) -> bool { - match self { - Units::Stretch(_) => true, - _ => false, - } + matches!(self, Units::Stretch(_)) } /// Returns true if the value is auto pub fn is_auto(&self) -> bool { - match self { - Units::Auto => true, - _ => false, - } + matches!(self, Units::Auto) } } diff --git a/src/tree.rs b/src/tree.rs index 757c5312b7eeeb177b9519649b40d1d73624a615..e8f456c76f5046e56a9056a3ea2232fb6265d38f 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -258,9 +258,8 @@ impl Tree { let children_b = other_tree.children.get(&root_node); // Handle both easy cases first.. - if children_a.is_some() && children_b.is_none() { + if let (Some(children_a), None) = (children_a, children_b) { return children_a - .unwrap() .iter() .enumerate() .map(|(child_id, child_node)| { @@ -268,9 +267,8 @@ impl Tree { }) .collect::<Vec<_>>() .into(); - } else if children_a.is_none() && children_b.is_some() { + } else if let (None, Some(children_b)) = (children_a, children_b) { return children_b - .unwrap() .iter() .enumerate() .map(|(child_id, child_node)| { @@ -362,16 +360,15 @@ impl Tree { let parent_a = self.parent(children_a.get(*id).unwrap().1); let parent_b = self.parent(*node); - let definitely_moved = if parent_a.is_some() && parent_b.is_some() { - let parent_a = parent_a.unwrap(); - let parent_b = parent_b.unwrap(); - parent_a != parent_b - || (parent_a == parent_b - && *node != children_a.get(*id).unwrap().1 - && children_a.iter().any(|(_, node_b)| node == node_b)) - } else { - false - }; + let definitely_moved = + if let (Some(parent_a), Some(parent_b)) = (parent_a, parent_b) { + parent_a != parent_b + || (parent_a == parent_b + && *node != children_a.get(*id).unwrap().1 + && children_a.iter().any(|(_, node_b)| node == node_b)) + } else { + false + }; if definitely_moved { let change = if change[0] == Change::Unchanged { @@ -485,16 +482,15 @@ impl Tree { let parent_a = self.parent(tree1.get(*id).unwrap().1); let parent_b = self.parent(*node); - let definitely_moved = if parent_a.is_some() && parent_b.is_some() { - let parent_a = parent_a.unwrap(); - let parent_b = parent_b.unwrap(); - parent_a != parent_b - || (parent_a == parent_b - && *node != tree1.get(*id).unwrap().1 - && tree1.iter().any(|(_, node_b)| node == node_b)) - } else { - false - }; + let definitely_moved = + if let (Some(parent_a), Some(parent_b)) = (parent_a, parent_b) { + parent_a != parent_b + || (parent_a == parent_b + && *node != tree1.get(*id).unwrap().1 + && tree1.iter().any(|(_, node_b)| node == node_b)) + } else { + false + }; if definitely_moved { let change = if change[0] == Change::Unchanged { @@ -527,19 +523,18 @@ impl Tree { if children_a.is_none() && children_b.is_none() { // Nothing to do. return; - } else if children_a.is_none() && children_b.is_some() { + } else if let (None, Some(children_b)) = (children_a.as_ref(), children_b) { // Simple case of moving all children over to A. - self.children.insert(root_node, children_b.unwrap().clone()); + self.children.insert(root_node, children_b.clone()); for (parent, children) in self.children.iter() { for child in children.iter() { self.parents.insert(*child, *parent); } } return; - } else if children_a.is_some() && children_b.is_none() { + } else if let (Some(children_a), None) = (children_a.as_ref(), children_b) { // Case for erasing all if has_changes { - let children_a = children_a.unwrap(); for child in children_a.iter() { self.parents.remove(child); } @@ -644,7 +639,7 @@ impl Tree { for child in children.iter() { println!(" [{}]", child.0.index()); } - println!(""); + println!(); } } diff --git a/src/widget.rs b/src/widget.rs index 0b94249ff6d4e54aeb946be07a40c825b8b34ce0..f07986eb586a8f0157261a8cf78b2437cbf9190d 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -164,9 +164,9 @@ impl<'w, 's, Props: PartialEq + Component, State: PartialEq + Component> } // Check state - if current_state_entity.is_some() && previous_state_entity.is_some() { - let previous_state_entity = previous_state_entity.unwrap(); - let current_state_entity = current_state_entity.unwrap(); + if let (Some(current_state_entity), Some(previous_state_entity)) = + (current_state_entity, previous_state_entity) + { if let (Ok(state), Ok(previous_state)) = ( self.state_query.get(current_state_entity), self.state_query.get(previous_state_entity), diff --git a/src/widgets/accordion/context.rs b/src/widgets/accordion/context.rs index 9b9ef011c6267a39c91852c36484401381320938..b91150defc6b36259d33c3a1771674730c023e5f 100644 --- a/src/widgets/accordion/context.rs +++ b/src/widgets/accordion/context.rs @@ -16,7 +16,7 @@ pub struct AccordionContext { impl AccordionContext { pub fn is_open(&self, index: usize) -> bool { - self.accordions.get(&index).map(|v| *v).unwrap_or(false) + self.accordions.get(&index).copied().unwrap_or(false) } pub fn toggle_current(&mut self, index: usize) { @@ -80,8 +80,10 @@ pub fn render( { context_entity } else { - let mut accordion_context = AccordionContext::default(); - accordion_context.allow_one = accordion.allow_only_one; + let mut accordion_context = AccordionContext { + allow_one: accordion.allow_only_one, + ..AccordionContext::default() + }; if let Some(default_open) = accordion.default_open { accordion_context.toggle_current(default_open); } diff --git a/src/widgets/accordion/summary.rs b/src/widgets/accordion/summary.rs index 662f9c15b758d6fee7549d243c419e94893d2a30..1f40d6a77fb770c35b5d41760553c911ec329e85 100644 --- a/src/widgets/accordion/summary.rs +++ b/src/widgets/accordion/summary.rs @@ -81,11 +81,8 @@ pub fn render( if let Ok(mut context) = query.get_mut(context_entity) { event.stop_propagation(); event.prevent_default(); - match event.event_type { - EventType::Click(..) => { - context.toggle_current(current_index); - } - _ => {} + if let EventType::Click(..) = event.event_type { + context.toggle_current(current_index); } } }, diff --git a/src/widgets/button.rs b/src/widgets/button.rs index 75976883f6c9d078ff585742051284ce8e7d03fc..adf34cba2d20ceb559f9cdef1a2da7274d5856d4 100644 --- a/src/widgets/button.rs +++ b/src/widgets/button.rs @@ -80,7 +80,7 @@ pub fn button_render( }, border: Edge::all(2.0).into(), border_radius: StyleProp::Value(Corner::all(10.0)), - font_size: StyleProp::Value(font_size).into(), + font_size: StyleProp::Value(font_size), height: StyleProp::Value(height), width: Units::Stretch(1.0).into(), cursor: StyleProp::Value(KCursorIcon(CursorIcon::Hand)), diff --git a/src/widgets/icons/mod.rs b/src/widgets/icons/mod.rs index a1ae1881704f6d2a2a741664fa59780060fc69ed..6174ddd8f54b81097d0c6f12ca6c02e661e61ea2 100644 --- a/src/widgets/icons/mod.rs +++ b/src/widgets/icons/mod.rs @@ -17,8 +17,8 @@ impl Plugin for IconsPlugin { fn build(&self, app: &mut bevy::prelude::App) { let expand_less_bytes = include_bytes!("expand_less.svg"); let expand_more_bytes = include_bytes!("expand_more.svg"); - let mut expand_less = Svg::from_bytes(expand_less_bytes, &Path::new("")).unwrap(); - let mut expand_more = Svg::from_bytes(expand_more_bytes, &Path::new("")).unwrap(); + let mut expand_less = Svg::from_bytes(expand_less_bytes, Path::new("")).unwrap(); + let mut expand_more = Svg::from_bytes(expand_more_bytes, Path::new("")).unwrap(); let mut meshes = app.world.get_resource_mut::<Assets<Mesh>>().unwrap(); expand_less.mesh = meshes.add(expand_less.tessellate()); diff --git a/src/widgets/modal.rs b/src/widgets/modal.rs index b3ae1042cb0e2e49e8ae11a76a91ecde2ce17df6..73b900ce03b414d9490e44e1a68d7a27a5c68943 100644 --- a/src/widgets/modal.rs +++ b/src/widgets/modal.rs @@ -102,7 +102,7 @@ pub fn render( }, style_b: KStyle { opacity: 1.0.into(), - ..styles.clone() + ..styles }, autoplay: false, }; @@ -150,7 +150,7 @@ pub fn render( render_command: RenderCommand::Quad.into(), position_type: KPositionType::SelfDirected.into(), ..Default::default() - }.with_style(modal_styles).into()} + }.with_style(modal_styles)} > <BackgroundBundle styles={KStyle { diff --git a/src/widgets/scroll/scroll_bar.rs b/src/widgets/scroll/scroll_bar.rs index d3387f530710ff3389d8a85895b4a463216c7f59..99db8b47afab9fe28d1de233e59bb038c0557f51 100644 --- a/src/widgets/scroll/scroll_bar.rs +++ b/src/widgets/scroll/scroll_bar.rs @@ -144,19 +144,17 @@ pub fn scroll_bar_render( }); let mut border_color = thumb_color; - match &mut border_color { - Color::Rgba { - red, - green, - blue, - alpha, - } => { - *alpha = (*alpha - 0.2).max(0.0); - *red = (*red + 0.1).min(1.0); - *green = (*green + 0.1).min(1.0); - *blue = (*blue + 0.1).min(1.0); - } - _ => {} + if let Color::Rgba { + red, + green, + blue, + alpha, + } = &mut border_color + { + *alpha = (*alpha - 0.2).max(0.0); + *red = (*red + 0.1).min(1.0); + *green = (*green + 0.1).min(1.0); + *blue = (*blue + 0.1).min(1.0); } let mut thumb_style = KStyle::default() diff --git a/src/widgets/scroll/scroll_box.rs b/src/widgets/scroll/scroll_box.rs index b05c85a470572db1e8b264d28876eddc1c3ba3f7..258ea31682d2680ced8ec9059f91fca5466308cd 100644 --- a/src/widgets/scroll/scroll_box.rs +++ b/src/widgets/scroll/scroll_box.rs @@ -185,31 +185,26 @@ pub fn scroll_box_render( mut event: ResMut<KEvent>, mut query: Query<&mut ScrollContext>| { if let Ok(mut scroll_context) = query.get_mut(context_entity) { - match event.event_type { - EventType::Scroll(evt) => { - match evt.delta { - ScrollUnit::Line { x, y } => { - if !disable_horizontal { - scroll_context - .set_scroll_x(scroll_x - x * scroll_line); - } - if !disable_vertical { - scroll_context - .set_scroll_y(scroll_y + y * scroll_line); - } + if let EventType::Scroll(evt) = event.event_type { + match evt.delta { + ScrollUnit::Line { x, y } => { + if !disable_horizontal { + scroll_context.set_scroll_x(scroll_x - x * scroll_line); } - ScrollUnit::Pixel { x, y } => { - if !disable_horizontal { - scroll_context.set_scroll_x(scroll_x - x); - } - if !disable_vertical { - scroll_context.set_scroll_y(scroll_y + y); - } + if !disable_vertical { + scroll_context.set_scroll_y(scroll_y + y * scroll_line); + } + } + ScrollUnit::Pixel { x, y } => { + if !disable_horizontal { + scroll_context.set_scroll_x(scroll_x - x); + } + if !disable_vertical { + scroll_context.set_scroll_y(scroll_y + y); } } - event.stop_propagation(); } - _ => {} + event.stop_propagation(); } } }, diff --git a/src/widgets/text_box.rs b/src/widgets/text_box.rs index 667a7ce1efce241a9e541da6239229bc6260c88d..00ab963a2bc99bea1943597c5431c8a511955d1f 100644 --- a/src/widgets/text_box.rs +++ b/src/widgets/text_box.rs @@ -403,7 +403,7 @@ fn get_single_grapheme_length( font_assets: &Res<Assets<KayakFont>>, font_mapping: &FontMapping, style_font: &StyleProp<String>, - text: &String, + text: &str, ) -> usize { let font_handle = match style_font { StyleProp::Value(font) => font_mapping.get_handle(font.clone()).unwrap(), @@ -411,7 +411,7 @@ fn get_single_grapheme_length( }; if let Some(font) = font_assets.get(&font_handle) { - let graphemes = font.get_graphemes(&text); + let graphemes = font.get_graphemes(text); return graphemes[0].len(); }