You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: event.rs
    path of file: ./repos/amethyst/amethyst_ui/src
    
    the code of the file until where you have to start completion: use std::collections::HashSet;

use amethyst_core::{
    ecs::{component, Entity, IntoQuery, ParallelRunnable, System, SystemBuilder},
    math::Vector2,
    shrev::EventChannel,
    Hidden, HiddenPropagate,
};
use amethyst_input::InputHandler;
use amethyst_window::ScreenDimensions;
use serde::{Deserialize, Serialize};
use winit::event::MouseButton;

use crate::transform::UiTransform;

/// An event that pertains to a specific `Entity`, for example a `UiEvent` for clicking on a widget
/// entity.
pub trait TargetedEvent {
    /// The `Entity` targeted by the event.
    fn get_target(&self) -> Entity;
}

/// The type of ui event.
/// Click happens if you start and stop clicking on the same ui element.
#[derive(Debug, Clone, PartialEq)]
pub enum UiEventType {
    /// When an element is clicked normally.
    /// Includes touch events.
    Click,
    /// When the element starts being clicked (On left mouse down).
    /// Includes touch events.
    ClickStart,
    /// When the element stops being clicked (On left mouse up).
    /// Includes touch events.
    ClickStop,
    /// When the cursor gets over an element.
    HoverStart,
    /// When the cursor stops being over an element.
    HoverStop,
    /// When dragging a `Draggable` Ui element.
    Dragging {
        /// The position of the mouse relative to the center of the transform when the drag started.
        offset_from_mouse: Vector2<f32>,
        /// Position a
    
    fn build(mut self) -> Box<dyn ParallelRunnable> {
        Box::new(
            SystemBuilder::new("UiMouseSystem")
                .write_resource::<EventChannel<UiEvent>>()
                .read_resource::<InputHandler>()
                .read_resource::<ScreenDimensions>()
                // Interactable entities with an UiTransform, without Hidden or HiddenPropagate
                .with_query(
                    <(Entity, &UiTransform, Option<&Interactable>)>::query()
                        .filter(!component::<Hidden>() & !component::<HiddenPropagate>()),
                )
                .build(
                    move |_commands,
                          world,
                          (events, input, screen_dimensions),
                          interactables_entities| {
                        let down = input.mouse_button_is_down(MouseButton::Left);
                        // FIXME: To replace on InputHandler generate OnMouseDown and OnMouseUp events See #2496
                        let click_started = down && !self.was_down;
                        let click_stopped = !down && self.was_down;
                        if let Some((pos_x, pos_y)) = input.mouse_position() {
                            let x = pos_x as f32;
                            let y = screen_dimensions.height() - pos_y as f32;

                            let targets = targeted((x, y), interactables_entities.iter(world));

                            for target in targets.difference(&self.last_targets) {
                                events.single_write(UiEvent::new(UiEventType::HoverStart, *target));
                            }

                            for last_target in self.last_targets.difference(&targets) {
                                events.single_write(UiEvent::new(
                                    UiEventType::HoverStop,
                                    *last_target,
                                ));
                            }

                            if click_started {
                                self.click_started_on = targets.clone();
                                for target in &targets {
                                    events.single_write(UiEvent::new(
                                        UiEventType::ClickStart,
                                        *target,
                                    ));
                                }
                            } else if click_stopped {
                                for click_start_target in
                                    self.click_started_on.intersection(&targets)
                                {
                                    events.single_write(UiEvent::new(
                                        UiEventType::Click,
                                        *click_start_target,
                                    ));
                                }
                            }

                            self.last_targets = targets;
                        }

                        // Could be used for drag and drop
                        if click_stopped {
                            for click_start_target in self.click_started_on.drain() {
                                events.single_write(UiEvent::new(
                                    UiEventType::ClickStop,
                                    click_start_target,
                                ));
                            }
                        }
                        self.was_down = down;
                    },
                ),
        )
    }