mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 13:38:35 +00:00
Pull clipboard support from 0.1-dev
This commit is contained in:
parent
35f7ed9737
commit
3f6bc12e0b
@ -12,6 +12,7 @@
|
||||
- Support for navigation input system
|
||||
- Support for backend/renderer name strings
|
||||
- Support for saving/loading INI settings manually
|
||||
- Pluggable clipboard support
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
62
imgui-examples/Cargo.lock
generated
62
imgui-examples/Cargo.lock
generated
@ -98,6 +98,26 @@ dependencies = [
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clipboard"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"clipboard-win 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"x11-clipboard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
@ -388,6 +408,7 @@ dependencies = [
|
||||
name = "imgui-examples"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"clipboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glium 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"imgui 0.1.0-pre",
|
||||
@ -599,6 +620,24 @@ dependencies = [
|
||||
"malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc-foundation"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc_id"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "1.0.2"
|
||||
@ -1090,6 +1129,14 @@ dependencies = [
|
||||
"x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11-clipboard"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11-dl"
|
||||
version = "2.18.3"
|
||||
@ -1100,6 +1147,15 @@ dependencies = [
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xcb"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xdg"
|
||||
version = "2.2.0"
|
||||
@ -1125,6 +1181,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d"
|
||||
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
|
||||
"checksum cgl 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "55e7ec0b74fe5897894cbc207092c577e87c52f8a59e8ca8d97ef37551f60a49"
|
||||
"checksum clipboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7"
|
||||
"checksum clipboard-win 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf79daa4e11e5def06e55306aa3601b87de6b5149671529318da048f67cdd77b"
|
||||
"checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
|
||||
@ -1178,6 +1236,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
||||
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
|
||||
"checksum objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "31d20fd2b37e07cf5125be68357b588672e8cefe9a96f8c17a9d46053b3e590d"
|
||||
"checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
|
||||
"checksum objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
|
||||
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
|
||||
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
|
||||
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
|
||||
@ -1234,6 +1294,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum winit 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d233301129ddd33260b47f76900b50e154b7254546e2edba0e5468a1a5fe4de3"
|
||||
"checksum x11-clipboard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea"
|
||||
"checksum x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "940586acb859ea05c53971ac231685799a7ec1dee66ac0bccc0e6ad96e06b4e3"
|
||||
"checksum xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de"
|
||||
"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
|
||||
"checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5"
|
||||
|
||||
@ -10,8 +10,9 @@ license = "MIT/Apache-2.0"
|
||||
publish = false
|
||||
|
||||
[dev-dependencies]
|
||||
clipboard = "0.5"
|
||||
glium = { version = "0.25", default-features = true }
|
||||
image = "0.21"
|
||||
imgui = { version = "0.1.0-pre", path = "../" }
|
||||
imgui-glium-renderer = { version = "0.1.0-pre", path = "../imgui-glium-renderer" }
|
||||
imgui-winit-support = { version = "0.1.0-pre", path = "../imgui-winit-support" }
|
||||
image = "0.21"
|
||||
|
||||
19
imgui-examples/examples/support/clipboard.rs
Normal file
19
imgui-examples/examples/support/clipboard.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use clipboard::{ClipboardContext, ClipboardProvider};
|
||||
use imgui::{ClipboardBackend, ImStr, ImString};
|
||||
|
||||
pub struct ClipboardSupport(ClipboardContext);
|
||||
|
||||
pub fn init() -> Option<ClipboardSupport> {
|
||||
ClipboardContext::new()
|
||||
.ok()
|
||||
.map(|ctx| ClipboardSupport(ctx))
|
||||
}
|
||||
|
||||
impl ClipboardBackend for ClipboardSupport {
|
||||
fn get(&mut self) -> Option<ImString> {
|
||||
self.0.get_contents().ok().map(|text| text.into())
|
||||
}
|
||||
fn set(&mut self, text: &ImStr) {
|
||||
let _ = self.0.set_contents(text.to_str().to_owned());
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,8 @@ use imgui_glium_renderer::GliumRenderer;
|
||||
use imgui_winit_support::{HiDpiMode, WinitPlatform};
|
||||
use std::time::Instant;
|
||||
|
||||
mod clipboard;
|
||||
|
||||
pub struct System {
|
||||
pub events_loop: glutin::EventsLoop,
|
||||
pub display: glium::Display,
|
||||
@ -30,6 +32,12 @@ pub fn init(title: &str) -> System {
|
||||
let mut imgui = Context::create();
|
||||
imgui.set_ini_filename(None);
|
||||
|
||||
if let Some(backend) = clipboard::init() {
|
||||
imgui.set_clipboard_backend(Box::new(backend));
|
||||
} else {
|
||||
eprintln!("Failed to initialize clipboard");
|
||||
}
|
||||
|
||||
let mut platform = WinitPlatform::init(&mut imgui);
|
||||
{
|
||||
let gl_window = display.gl_window();
|
||||
|
||||
109
src/clipboard.rs
Normal file
109
src/clipboard.rs
Normal file
@ -0,0 +1,109 @@
|
||||
use std::fmt;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::panic::catch_unwind;
|
||||
use std::process;
|
||||
use std::ptr;
|
||||
|
||||
use crate::string::{ImStr, ImString};
|
||||
use crate::Ui;
|
||||
|
||||
pub trait ClipboardBackend {
|
||||
fn get(&mut self) -> Option<ImString>;
|
||||
fn set(&mut self, value: &ImStr);
|
||||
}
|
||||
|
||||
pub(crate) struct ClipboardContext {
|
||||
backend: Box<dyn ClipboardBackend>,
|
||||
// this is needed to keep ownership of the value when the raw C callback is called
|
||||
last_value: ImString,
|
||||
}
|
||||
|
||||
impl ClipboardContext {
|
||||
pub fn new(backend: Box<dyn ClipboardBackend>) -> ClipboardContext {
|
||||
ClipboardContext {
|
||||
backend,
|
||||
last_value: ImString::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ClipboardContext {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"ClipboardContext({:?}, {:?})",
|
||||
&(*self.backend) as *const _,
|
||||
self.last_value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe extern "C" fn get_clipboard_text(user_data: *mut c_void) -> *const c_char {
|
||||
let result = catch_unwind(|| {
|
||||
let ctx = &mut *(user_data as *mut ClipboardContext);
|
||||
match ctx.backend.get() {
|
||||
Some(text) => {
|
||||
ctx.last_value = text;
|
||||
ctx.last_value.as_ptr()
|
||||
}
|
||||
None => ptr::null(),
|
||||
}
|
||||
});
|
||||
result.unwrap_or_else(|_| {
|
||||
eprintln!("Clipboard getter panicked");
|
||||
process::abort();
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) unsafe extern "C" fn set_clipboard_text(user_data: *mut c_void, text: *const c_char) {
|
||||
let result = catch_unwind(|| {
|
||||
let ctx = &mut *(user_data as *mut ClipboardContext);
|
||||
let text = ImStr::from_ptr_unchecked(text);
|
||||
ctx.backend.set(text);
|
||||
});
|
||||
result.unwrap_or_else(|_| {
|
||||
eprintln!("Clipboard setter panicked");
|
||||
process::abort();
|
||||
});
|
||||
}
|
||||
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// Returns the current clipboard contents as text or None if clipboard cannot be accessed or
|
||||
/// it is empty
|
||||
pub fn clipboard_text(&self) -> Option<ImString> {
|
||||
let io = self.io();
|
||||
io.get_clipboard_text_fn.and_then(|get_clipboard_text_fn| {
|
||||
// Bypass FFI if we end up calling our own function anyway
|
||||
if get_clipboard_text_fn == get_clipboard_text {
|
||||
let ctx = unsafe { &mut *(io.clipboard_user_data as *mut ClipboardContext) };
|
||||
ctx.backend.get()
|
||||
} else {
|
||||
unsafe {
|
||||
let text_ptr = get_clipboard_text_fn(io.clipboard_user_data);
|
||||
if text_ptr.is_null() || *text_ptr == b'\0' as c_char {
|
||||
None
|
||||
} else {
|
||||
Some(ImStr::from_ptr_unchecked(text_ptr).to_owned())
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
/// Sets the clipboard contents.
|
||||
///
|
||||
/// Does nothing if the clipboard cannot be accessed.
|
||||
pub fn set_clipboard_text(&self, text: &ImStr) {
|
||||
let io = self.io();
|
||||
if let Some(set_clipboard_text_fn) = io.set_clipboard_text_fn {
|
||||
// Bypass FFI if we end up calling our own function anyway
|
||||
if set_clipboard_text_fn == set_clipboard_text {
|
||||
let ctx = unsafe { &mut *(io.clipboard_user_data as *mut ClipboardContext) };
|
||||
ctx.backend.set(text);
|
||||
} else {
|
||||
unsafe {
|
||||
set_clipboard_text_fn(io.clipboard_user_data, text.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,7 @@ use std::ops::Drop;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::clipboard::{ClipboardBackend, ClipboardContext};
|
||||
use crate::fonts::atlas::{FontAtlas, FontAtlasRefMut, FontId, SharedFontAtlas};
|
||||
use crate::io::Io;
|
||||
use crate::string::{ImStr, ImString};
|
||||
@ -54,6 +55,7 @@ pub struct Context {
|
||||
log_filename: Option<ImString>,
|
||||
platform_name: Option<ImString>,
|
||||
renderer_name: Option<ImString>,
|
||||
clipboard_ctx: Option<Box<ClipboardContext>>,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
@ -170,6 +172,15 @@ impl Context {
|
||||
let data = unsafe { CStr::from_ptr(sys::igSaveIniSettingsToMemory(ptr::null_mut())) };
|
||||
buf.push_str(&data.to_string_lossy());
|
||||
}
|
||||
pub fn set_clipboard_backend(&mut self, backend: Box<dyn ClipboardBackend>) {
|
||||
use std::borrow::BorrowMut;
|
||||
let mut clipboard_ctx = Box::new(ClipboardContext::new(backend));
|
||||
let io = self.io_mut();
|
||||
io.set_clipboard_text_fn = Some(crate::clipboard::set_clipboard_text);
|
||||
io.get_clipboard_text_fn = Some(crate::clipboard::get_clipboard_text);
|
||||
io.clipboard_user_data = clipboard_ctx.borrow_mut() as *mut ClipboardContext as *mut _;
|
||||
self.clipboard_ctx.replace(clipboard_ctx);
|
||||
}
|
||||
fn create_internal(shared_font_atlas: Option<Rc<RefCell<SharedFontAtlas>>>) -> Self {
|
||||
let _guard = CTX_MUTEX.lock();
|
||||
assert!(
|
||||
@ -186,6 +197,7 @@ impl Context {
|
||||
log_filename: None,
|
||||
platform_name: None,
|
||||
renderer_name: None,
|
||||
clipboard_ctx: None,
|
||||
}
|
||||
}
|
||||
fn is_current_context(&self) -> bool {
|
||||
@ -263,6 +275,7 @@ impl SuspendedContext {
|
||||
log_filename: None,
|
||||
platform_name: None,
|
||||
renderer_name: None,
|
||||
clipboard_ctx: None,
|
||||
};
|
||||
if ctx.is_current_context() {
|
||||
// Oops, the context was activated -> deactivate
|
||||
|
||||
@ -10,6 +10,7 @@ use std::str;
|
||||
use std::thread;
|
||||
|
||||
pub use self::child_frame::ChildFrame;
|
||||
pub use self::clipboard::*;
|
||||
pub use self::color_editors::{
|
||||
ColorButton, ColorEdit, ColorEditMode, ColorFormat, ColorPicker, ColorPickerMode, ColorPreview,
|
||||
EditableColor,
|
||||
@ -52,6 +53,7 @@ pub use self::window_draw_list::{ChannelsSplit, ImColor, WindowDrawList};
|
||||
use internal::RawCast;
|
||||
|
||||
mod child_frame;
|
||||
mod clipboard;
|
||||
mod color_editors;
|
||||
mod context;
|
||||
mod drag;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user