mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-13 22:48:34 +00:00
final
This commit is contained in:
parent
2a1ced631a
commit
1983f47941
@ -22,6 +22,12 @@
|
||||
- `Ui::get_background_draw_list()` has been fixed when used outside of a window context, and now has an example.
|
||||
- `Ui::get_foreground_draw_list()` has been added, analogous to `Ui::get_background_draw_list()`.
|
||||
|
||||
- Added drag drop support, with a safe and an unsafe variant: https://github.com/imgui-rs/imgui-rs/pull/428
|
||||
- `DragDropSource` allows users to create a dragdrop payload which is either empty, of `'static + Copy` data,
|
||||
or `unsafe`, allowing for theoretically arbitrary payloads.
|
||||
- `DragDropTarget` allows users to accept any of the above payloads.
|
||||
- Extensive documentation has been made on all of these features, hopefully as a target for future features.
|
||||
|
||||
## [0.6.1] - 2020-12-16
|
||||
|
||||
- Support for winit 0.24.x
|
||||
|
||||
@ -1,3 +1,31 @@
|
||||
//! Structs to create a Drag and Drop sequence. Almost all structs are re-exported
|
||||
//! and can be accessed from the crate root; some additional utilities can be found in here.
|
||||
//!
|
||||
//! A DragDrop is a UI mechanism where users can appear to "drag"
|
||||
//! some data from one [source](DragDropSource) to one [target](DragDropTarget).
|
||||
//! A source and a target must both have some `name` identifier, which is declared when they
|
||||
//! are created. If these names are equal, then a `payload` of some kind
|
||||
//! will be given to the target caller whne the user releases their mouse button over
|
||||
//! the target (additionally, the UI will reflect that the payload *can* be deposited
|
||||
//! in the target).
|
||||
//!
|
||||
//! The complexity of this implementation is primarily in managing this payload. Users
|
||||
//! can provide three different kinds of payloads:
|
||||
//!
|
||||
//! 1. Users can give an [empty payload](DragDropPayloadEmpty) with [begin](DragDropSource::begin).
|
||||
//! This payload type is essentially just a notification system, but using some shared state,
|
||||
//! this can be reasonably powerful, and is the safest way to transfer non-Copy data offered
|
||||
//! right now.
|
||||
//! 2. Users can give a [simple Copy payload](DragDropPayloadPod) with [begin](DragDropSource::begin_payload).
|
||||
//! This allows users to copy data to Dear ImGui, which will take ownership over it, and then be given
|
||||
//! it back to the Target. Please note: users are of course free to not drop any drag (cancel a drag),
|
||||
//! so this data could easily be lost forever. Our `'static + Copy` bound is intended to keep users
|
||||
//! to simplistic types.
|
||||
//! 3. An unsafe implementation is provided which allows for any data to be unsafely copied. Note that once
|
||||
//! you use this method, the safe implementations in #1 and #2 can create memory unsafety problems; notably,
|
||||
//! they both assume that a payload has certain header information within it.
|
||||
//!
|
||||
//! For examples of each payload type, see [DragDropSource].
|
||||
use std::{any, ffi, marker::PhantomData};
|
||||
|
||||
use crate::{sys, Condition, ImStr, Ui};
|
||||
@ -164,6 +192,36 @@ impl<'a> DragDropSource<'a> {
|
||||
/// 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].
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use imgui::*;
|
||||
/// fn show_ui(ui: &Ui<'_>) {
|
||||
/// ui.button(im_str!("Drag me!"), [0.0, 0.0]);
|
||||
///
|
||||
/// let drag_drop_name = im_str!("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(im_str!("Target me!"), [0.0, 0.0]);
|
||||
///
|
||||
/// // drag drop TARGET
|
||||
/// if let Some(target) = 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();
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn begin_payload<'ui, T: Copy + 'static>(
|
||||
self,
|
||||
@ -238,7 +296,7 @@ impl DragDropSourceToolTip<'_> {
|
||||
/// Ends the tooltip directly. You could choose to simply allow this to drop
|
||||
/// by not calling this, which will also be fine.
|
||||
#[inline]
|
||||
pub fn pop(self) {
|
||||
pub fn end(self) {
|
||||
// left empty to invoke drop...
|
||||
}
|
||||
}
|
||||
@ -415,11 +473,11 @@ impl Drop for DragDropTarget<'_> {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[non_exhaustive]
|
||||
pub struct DragDropPayloadEmpty {
|
||||
/// Set when [`accept_payload_empty`](Self::accept_payload_empty) was called
|
||||
/// Set when [`accept_payload_empty`](DragDropTarget::accept_payload_empty) was called
|
||||
/// and mouse has been hovering the target item.
|
||||
pub preview: bool,
|
||||
|
||||
/// Set when [`accept_payload_empty`](Self::accept_payload_empty) was
|
||||
/// Set when [`accept_payload_empty`](DragDropTarget::accept_payload_empty) was
|
||||
/// called and mouse button is released over the target item.
|
||||
pub delivery: bool,
|
||||
}
|
||||
@ -432,11 +490,11 @@ pub struct DragDropPayloadPod<T: 'static + Copy> {
|
||||
/// The kind data which was requested.
|
||||
pub data: T,
|
||||
|
||||
/// Set when [`accept_payload`](Self::accept_payload) was called
|
||||
/// Set when [`accept_payload`](DragDropTarget::accept_payload) was called
|
||||
/// and mouse has been hovering the target item.
|
||||
pub preview: bool,
|
||||
|
||||
/// Set when [`accept_payload`](Self::accept_payload) was
|
||||
/// Set when [`accept_payload`](DragDropTarget::accept_payload) was
|
||||
/// called and mouse button is released over the target item.
|
||||
pub delivery: bool,
|
||||
}
|
||||
@ -452,16 +510,17 @@ pub struct DragDropPayload {
|
||||
/// The size of the data in bytes.
|
||||
pub size: usize,
|
||||
|
||||
/// Set when [`accept_payload_unchecked`](Self::accept_payload_unchecked) was called
|
||||
/// Set when [`accept_payload_unchecked`](DragDropTarget::accept_payload_unchecked) was called
|
||||
/// and mouse has been hovering the target item.
|
||||
pub preview: bool,
|
||||
|
||||
/// Set when [`accept_payload_unchecked`](Self::accept_payload_unchecked) was
|
||||
/// Set when [`accept_payload_unchecked`](DragDropTarget::accept_payload_unchecked) was
|
||||
/// called and mouse button is released over the target item. If this is set to false, then you
|
||||
/// set DragDropFlags::ACCEPT_BEFORE_DELIVERY and shouldn't mutate `data`.
|
||||
pub delivery: bool,
|
||||
}
|
||||
|
||||
/// A typed payload.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
struct TypedPayload<T> {
|
||||
@ -469,7 +528,17 @@ struct TypedPayload<T> {
|
||||
data: T,
|
||||
}
|
||||
|
||||
/// We have this struct separately to easily read it off in unsafe code.
|
||||
impl<T: Copy + 'static> TypedPayload<T> {
|
||||
/// Creates a new typed payload which contains this data.
|
||||
fn new(data: T) -> Self {
|
||||
Self {
|
||||
header: TypedPayloadHeader::new::<T>(),
|
||||
data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A header for a typed payload.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
||||
#[repr(C)]
|
||||
struct TypedPayloadHeader {
|
||||
@ -495,18 +564,9 @@ impl TypedPayloadHeader {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + 'static> TypedPayload<T> {
|
||||
/// Creates a new typed payload which contains this data.
|
||||
pub fn new(data: T) -> Self {
|
||||
Self {
|
||||
header: TypedPayloadHeader::new::<T>(),
|
||||
data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates that an incorrect payload type was received. It is opaque,
|
||||
/// but you can view questionably useful debug information with Debug formatting.
|
||||
/// but you can view useful information with Debug formatting when
|
||||
/// `debug_assertions` are enabled.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
||||
pub struct PayloadIsWrongType {
|
||||
expected: TypedPayloadHeader,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user