Hi ! In our wgpu application, we developped a number of custom widgets ( heavily borrowing code and ideas from iced_audio ) which are drawing geometry using the canvas API.
I’ve come up with a simple example in this repository which shows the problem. It is based on the official integration example and features a custom theme and a custom horizontal slider widget which renders geometry using the iced::advanced::graphics::geometry::Renderer draw method. A branch named with-application shows the same example this time implemented with the Application trait, and which compiles correctly.
We get that sort of error messages:
the trait bound `iced_core::Element<'_, Message, iced_widget::iced_graphics::Renderer<iced_wgpu::Backend, theme::Theme>>: From<HSlider<'_, Message, _>>` is not satisfied
I assume something is off in the widget type signature and traits implementations, but after many hours of trying I could not manage to make it work.
I’m not at my computer to test, but your Cargo.lock has some old iced deps in it that may be the root cause here. Maybe try deleting the lock / cargo clean?
I think your hex crate is depending on an older iced version than 0.10
actually the hex crate was not even used in that example, I removed it and did delete the Cargo.lock + cargo clean ( and pushed the changes to master ), but this does not solve the pb
Your HSlider implementation is using iced::Renderer, while Controls::view is expected to return an Element that has an iced_wgpu::Renderer.
These are completely different types. If you want your widget to work everywhere, you need to implement it in a completely generic way. For that, you can only rely on the iced_core traits, which should be available in the iced::advanced module.
I recommend you to look at the custom_widget example or the actual widget implementations in iced_widget.
In the controls module, we had to update the renderer so that it isn’t strictly tied to “graphics.” The generic use iced::Renderer should be used instead.
After that change, there’s a type mismatch issue in main.rs where the renderer type of the Program from controls becomes incompatible. To address this, you can use the following workaround in main.rs:
// This initializes the WGPU renderer
let renderer = iced_wgpu::Renderer::new(Backend::new(&device, &queue, Settings::default(), format));
// Then, we wrap the renderer in a type that implements the iced renderer trait
let mut rd = iced_renderer::Renderer::Wgpu(renderer);
let mut state = program::State::new(
controls,
viewport.logical_size(),
&mut rd, // This ensures the renderer is of the correct type
&mut debug,
);
With these changes, everything should work seamlessly.
It’s easy to get bogged down in all these different types of renderers. (traits, structs, enums, in different crates).