Struct arcdps_imgui::drag_drop::DragDropSource

source ·
pub struct DragDropSource<T> { /* private fields */ }
Expand description

Creates a source for drag drop data out of the last ID created.

fn show_ui(ui: &Ui<'_>) {
    ui.button("Hello, I am a drag source!");
     
    // Creates an empty DragSource with no tooltip
    DragDropSource::new("BUTTON_DRAG").begin(ui);
}

Notice especially the "BUTTON_DRAG" name – this is the identifier of this DragDropSource; DragDropTarget’s will specify an identifier to receive, and these names must match up. A single item should only have one DragDropSource, though a target may have multiple different targets.

DropDropSources don’t do anything until you use one of the three begin_ methods on this struct. Each of these methods describes how you handle the Payload which ImGui will manage, and then give to a DragDropTarget, which will received the payload. The simplest and safest Payload is the empty payload, created with begin.

Implementations§

source§

impl<T: AsRef<str>> DragDropSource<T>

source

pub fn new(name: T) -> Self

Creates a new DragDropSource with no flags and the Condition::Always with the given name. ImGui refers to this name field as a type, but really it’s just an identifier to match up Source/Target for DragDrop.

source

pub fn flags(self, flags: DragDropFlags) -> Self

Sets the flags on the DragDropSource. Only the flags SOURCE_NO_PREVIEW_TOOLTIP, SOURCE_NO_DISABLE_HOVER, SOURCE_NO_HOLD_TO_OPEN_OTHERS, SOURCE_ALLOW_NULL_ID, SOURCE_EXTERN, SOURCE_AUTO_EXPIRE_PAYLOAD make semantic sense, but any other flags will be accepted without panic.

source

pub fn condition(self, cond: Condition) -> Self

Sets the condition on the DragDropSource. Defaults to Always.

source

pub fn begin<'ui>(self, ui: &Ui<'ui>) -> Option<DragDropSourceToolTip<'ui>>

Creates the source of a drag and returns a handle on the tooltip. This handle can be immediately dropped without binding it, in which case a default empty circle will be used for the “blank” tooltip as this item is being dragged around.

Otherwise, use this tooltip to add data which will display as this item is dragged. If SOURCE_NO_PREVIEW_TOOLTIP is enabled, however, no preview will be displayed and this returned token does nothing. Additionally, a given target may use the flag ACCEPT_NO_PREVIEW_TOOLTIP, which will also prevent this tooltip from being shown.

This drag has no payload, but is still probably the most useful way in imgui-rs to handle payloads. Using once_cell or some shared data, this pattern can be very powerful:

fn show_ui(ui: &Ui<'_>, drop_message: &mut Option<String>) {
    ui.button("Drag me!");

    let drag_drop_name = "Test Drag";
     
    // drag drop SOURCE
    if DragDropSource::new(drag_drop_name).begin(ui).is_some() {
        // warning -- this would allocate every frame if `DragDropSource` has
        // condition `Always`, which it does by default. We're okay with that for
        // this example, but real code probably wouldn't want to allocate so much.
        *drop_message = Some("Test Payload".to_string());
    }

    ui.button("Target me!");

    // drag drop TARGET
    if let Some(target) = arcdps_imgui::DragDropTarget::new(ui) {
        if target
            .accept_payload_empty(drag_drop_name, DragDropFlags::empty())
            .is_some()
        {
            let msg = drop_message.take().unwrap();
            assert_eq!(msg, "Test Payload");
        }

        target.pop();
    }
}

In the above, you’ll see how the payload is really just a message passing service. If you want to pass a simple integer or other “plain old data”, take a look at begin_payload.

source

pub fn begin_payload<'ui, P: Copy + 'static>( self, ui: &Ui<'ui>, payload: P, ) -> Option<DragDropSourceToolTip<'ui>>

Creates the source of a drag and returns a handle on the tooltip. This handle can be immediately dropped without binding it, in which case a default empty circle will be used for the “blank” tooltip as this item is being dragged around.

Otherwise, use this tooltip to add data which will display as this item is dragged. If SOURCE_NO_PREVIEW_TOOLTIP is enabled, however, no preview will be displayed and this returned token does nothing. Additionally, a given target may use the flag ACCEPT_NO_PREVIEW_TOOLTIP, which will also prevent this tooltip from being shown.

This function also takes a payload in the form of T: Copy + 'static. ImGui will memcpy this data immediately to an internally held buffer, and will return the data to DragDropTarget.

fn show_ui(ui: &Ui<'_>) {
    ui.button("Drag me!");

    let drag_drop_name = "Test Drag";
    let msg_to_send = "hello there sailor";
     
    // drag drop SOURCE
    if let Some(tooltip) = DragDropSource::new(drag_drop_name).begin_payload(ui, msg_to_send) {
        ui.text("Sending message!");
        tooltip.end();
    }

    ui.button("Target me!");

    // drag drop TARGET
    if let Some(target) = arcdps_imgui::DragDropTarget::new(ui) {
        if let Some(Ok(payload_data)) = target
            .accept_payload::<&'static str, _>(drag_drop_name, DragDropFlags::empty())
        {
            let msg = payload_data.data;
            assert_eq!(msg, msg_to_send);
        }

        target.pop();
    }
}
source

pub unsafe fn begin_payload_unchecked<'ui>( &self, ui: &Ui<'ui>, ptr: *const c_void, size: usize, ) -> Option<DragDropSourceToolTip<'ui>>

Creates the source of a drag and returns a handle on the tooltip. This handle can be immediately dropped without binding it, in which case a default empty circle will be used for the “blank” tooltip as this item is being dragged around.

Otherwise, use this tooltip to add data which will display as this item is dragged. If SOURCE_NO_PREVIEW_TOOLTIP is enabled, however, no preview will be displayed and this returned token does nothing. Additionally, a given target may use the flag ACCEPT_NO_PREVIEW_TOOLTIP, which will also prevent this tooltip from being shown.

This function also takes a payload of any *const T. ImGui will memcpy this data immediately to an internally held buffer, and will return the data to DragDropTarget.

§Safety

This function itself will not cause a panic, but using it directly opts you into managing the lifetime of the pointer provided yourself. Dear ImGui will execute a memcpy on the data passed in with the size (in bytes) given, but this is, of course, just a copy, so if you pass in an &String, for example, the underlying String data will not be cloned, and could easily dangle if the String is dropped.

Moreover, if Condition::Always is set (as it is by default), you will be copying in your data every time this function is ran in your update loop, which if it involves an allocating and then handing the allocation to ImGui, would result in a significant amount of data created.

Overall, users should be very sure that this function is needed before they reach for it, and instead should consider either begin or begin_payload.

Trait Implementations§

source§

impl<T: Debug> Debug for DragDropSource<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for DragDropSource<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for DragDropSource<T>
where T: RefUnwindSafe,

§

impl<T> Send for DragDropSource<T>
where T: Send,

§

impl<T> Sync for DragDropSource<T>
where T: Sync,

§

impl<T> Unpin for DragDropSource<T>
where T: Unpin,

§

impl<T> UnwindSafe for DragDropSource<T>
where T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.