diff options
| author | Polesznyák Márk László <116908301+pml68@users.noreply.github.com> | 2025-02-21 21:13:18 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-21 21:13:18 +0100 |
| commit | 53819b29b843326117feac310a6f97e594022cc9 (patch) | |
| tree | c81a88bf256ea7205c02e7bc57843375eb2ed079 /iced_drop/src/widget/operation/drop.rs | |
| parent | feat!: add name to `Theme`, `is_dark` -> `dark` (diff) | |
| parent | feat: update to `iced` 0.14-dev (diff) | |
| download | iced-builder-53819b29b843326117feac310a6f97e594022cc9.tar.gz | |
Merge pull request #6 from pml68/feat/0.14
Diffstat (limited to '')
| -rw-r--r-- | iced_drop/src/widget/operation/drop.rs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/iced_drop/src/widget/operation/drop.rs b/iced_drop/src/widget/operation/drop.rs new file mode 100644 index 0000000..ead412c --- /dev/null +++ b/iced_drop/src/widget/operation/drop.rs @@ -0,0 +1,88 @@ +use iced::advanced::widget::operation::{Outcome, Scrollable}; +use iced::advanced::widget::{Id, Operation}; +use iced::{Rectangle, Vector}; + +/// Produces an [`Operation`] that will find the drop zones that pass a filter on the zone's bounds. +/// For any drop zone to be considered, the Element must have some Id. +/// If `options` is `None`, all drop zones will be considered. +/// Depth determines how how deep into nested drop zones to go. +/// If 'depth' is `None`, nested dropzones will be fully explored +pub fn find_zones<F>( + filter: F, + options: Option<Vec<Id>>, + depth: Option<usize>, +) -> impl Operation<Vec<(Id, Rectangle)>> +where + F: Fn(&Rectangle) -> bool + Send + 'static, +{ + struct FindDropZone<F> { + filter: F, + options: Option<Vec<Id>>, + zones: Vec<(Id, Rectangle)>, + max_depth: Option<usize>, + c_depth: usize, + offset: Vector, + } + + impl<F> Operation<Vec<(Id, Rectangle)>> for FindDropZone<F> + where + F: Fn(&Rectangle) -> bool + Send + 'static, + { + fn container( + &mut self, + id: Option<&Id>, + bounds: iced::Rectangle, + operate_on_children: &mut dyn FnMut( + &mut dyn Operation<Vec<(Id, Rectangle)>>, + ), + ) { + match id { + Some(id) => { + let is_option = match &self.options { + Some(options) => options.contains(id), + None => true, + }; + let bounds = bounds - self.offset; + if is_option && (self.filter)(&bounds) { + self.c_depth += 1; + self.zones.push((id.clone(), bounds)); + } + } + None => (), + } + let goto_next = match &self.max_depth { + Some(m_depth) => self.c_depth < *m_depth, + None => true, + }; + if goto_next { + operate_on_children(self); + } + } + + fn finish(&self) -> Outcome<Vec<(Id, Rectangle)>> { + Outcome::Some(self.zones.clone()) + } + + fn scrollable( + &mut self, + _id: Option<&Id>, + bounds: Rectangle, + _content_bounds: Rectangle, + translation: Vector, + _state: &mut dyn Scrollable, + ) { + if (self.filter)(&bounds) { + self.offset = self.offset + translation; + } + } + } + + FindDropZone { + filter, + options, + zones: vec![], + max_depth: depth, + c_depth: 0, + offset: Vector { x: 0.0, y: 0.0 }, + } +} |
