mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-23 11:21:30 +11:00
Transparency (#164)
* Add transparency field to WindowOptions * Add transparency example * Implement transparency on Wayland * Improvements * [WIP] X11 transparency * Restructure * Redox implement transparency * Update src/lib.rs Co-Authored-By: Cole Helbling <cole.e.helbling@outlook.com> * Rust-2018 changes * Fixed issue * cargo fmt * [WIP] Implement alpha transparency for windows * Staging Windows code * Transparency is currently unimplemented on Windows * Add note * Dont use assertions * Correction Co-authored-by: Antonino Siena <a.siena@gmx.de> Co-authored-by: Cole Helbling <cole.e.helbling@outlook.com>
This commit is contained in:
parent
29a4c5d9df
commit
d2fe8c0469
|
@ -1,6 +1,3 @@
|
|||
extern crate minifb;
|
||||
extern crate png;
|
||||
|
||||
use minifb::{Key, ScaleMode, Window, WindowOptions};
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
extern crate minifb;
|
||||
|
||||
use minifb::{Key, Scale, ScaleMode, Window, WindowOptions};
|
||||
|
||||
const WIDTH: usize = 100;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
extern crate minifb;
|
||||
|
||||
use minifb::MENU_KEY_CTRL;
|
||||
use minifb::{InputCallback, Key, Menu, Scale, Window, WindowOptions};
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
extern crate minifb;
|
||||
|
||||
use minifb::{Key, MouseButton, MouseMode, Scale, Window, WindowOptions};
|
||||
|
||||
const WIDTH: usize = 640;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
extern crate minifb;
|
||||
|
||||
use minifb::{Key, Scale, Window, WindowOptions};
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
extern crate minifb;
|
||||
|
||||
use minifb::{Key, ScaleMode, Window, WindowOptions};
|
||||
|
||||
const WIDTH: usize = 640 / 2;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
extern crate minifb;
|
||||
|
||||
use minifb::{CursorStyle, Key, MouseMode, Scale, Window, WindowOptions};
|
||||
|
||||
const WIDTH: usize = 640;
|
||||
|
|
24
examples/transparent.rs
Normal file
24
examples/transparent.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
use minifb::{Key, ScaleMode, Window, WindowOptions};
|
||||
|
||||
fn main() {
|
||||
// Allocate the output buffer.
|
||||
let buf = vec![0x00AAFF33; 320 * 480];
|
||||
|
||||
let mut window = Window::new(
|
||||
"Press ESC to exit",
|
||||
320,
|
||||
480,
|
||||
WindowOptions {
|
||||
resize: true,
|
||||
scale_mode: ScaleMode::Center,
|
||||
borderless: true,
|
||||
transparency: true,
|
||||
..WindowOptions::default()
|
||||
},
|
||||
)
|
||||
.expect("Unable to open Window");
|
||||
|
||||
while window.is_open() && !window.is_key_down(Key::Escape) {
|
||||
window.update_with_buffer(&buf, 320, 480).unwrap();
|
||||
}
|
||||
}
|
10
src/lib.rs
10
src/lib.rs
|
@ -187,6 +187,10 @@ pub struct WindowOptions {
|
|||
pub scale_mode: ScaleMode,
|
||||
/// Should the window be the topmost window (default: false)
|
||||
pub topmost: bool,
|
||||
/// Specifies whether or not the window is allowed to draw transparent pixels (default: false)
|
||||
/// Requires borderless to be 'true'
|
||||
/// TODO: Currently not implemented on Windows and OSX
|
||||
pub transparency: bool,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
|
@ -220,6 +224,11 @@ impl Window {
|
|||
/// .expect("Unable to open Window");
|
||||
/// ```
|
||||
pub fn new(name: &str, width: usize, height: usize, opts: WindowOptions) -> Result<Window> {
|
||||
if opts.transparency && !opts.borderless {
|
||||
return Err(Error::WindowCreate(
|
||||
"Window transparency requires the borderless property".to_owned(),
|
||||
));
|
||||
}
|
||||
imp::Window::new(name, width, height, opts).map(Window)
|
||||
}
|
||||
|
||||
|
@ -993,6 +1002,7 @@ impl Default for WindowOptions {
|
|||
fn default() -> WindowOptions {
|
||||
WindowOptions {
|
||||
borderless: false,
|
||||
transparency: false,
|
||||
title: true,
|
||||
resize: false,
|
||||
scale: Scale::X1,
|
||||
|
|
|
@ -67,6 +67,9 @@ impl Window {
|
|||
if !opts.title {
|
||||
window_flags.push(orbclient::WindowFlag::Borderless);
|
||||
}
|
||||
if opts.transparency {
|
||||
window_flags.push(orbclient::WindowFlag::Transparent);
|
||||
}
|
||||
|
||||
let window_opt =
|
||||
orbclient::Window::new_flags(-1, -1, window_width, window_height, name, &window_flags);
|
||||
|
|
|
@ -520,7 +520,7 @@ impl Window {
|
|||
|
||||
let (display, input) = DisplayInfo::new(
|
||||
(width as i32 * scale, height as i32 * scale),
|
||||
false,
|
||||
opts.transparency,
|
||||
!opts.borderless,
|
||||
)?;
|
||||
|
||||
|
|
|
@ -99,8 +99,8 @@ struct DisplayInfo {
|
|||
}
|
||||
|
||||
impl DisplayInfo {
|
||||
fn new() -> Result<DisplayInfo> {
|
||||
let mut display = Self::setup()?;
|
||||
fn new(transparency: bool) -> Result<DisplayInfo> {
|
||||
let mut display = Self::setup(transparency)?;
|
||||
|
||||
display.check_formats()?;
|
||||
display.check_extensions()?;
|
||||
|
@ -110,7 +110,7 @@ impl DisplayInfo {
|
|||
Ok(display)
|
||||
}
|
||||
|
||||
fn setup() -> Result<DisplayInfo> {
|
||||
fn setup(transparency: bool) -> Result<DisplayInfo> {
|
||||
unsafe {
|
||||
let lib = xlib::Xlib::open()
|
||||
.map_err(|e| Error::WindowCreate(format!("failed to load Xlib: {:?}", e)))?;
|
||||
|
@ -124,10 +124,29 @@ impl DisplayInfo {
|
|||
return Err(Error::WindowCreate("XOpenDisplay failed".to_owned()));
|
||||
}
|
||||
|
||||
let screen = (lib.XDefaultScreen)(display);
|
||||
let visual = (lib.XDefaultVisual)(display, screen);
|
||||
let screen;
|
||||
let visual;
|
||||
let depth;
|
||||
|
||||
let mut vinfo: xlib::XVisualInfo = std::mem::zeroed();
|
||||
if transparency {
|
||||
(lib.XMatchVisualInfo)(
|
||||
display,
|
||||
(lib.XDefaultScreen)(display),
|
||||
32,
|
||||
xlib::TrueColor,
|
||||
&mut vinfo as *mut _,
|
||||
);
|
||||
screen = vinfo.screen;
|
||||
visual = vinfo.visual;
|
||||
depth = vinfo.depth;
|
||||
} else {
|
||||
screen = (lib.XDefaultScreen)(display);
|
||||
visual = (lib.XDefaultVisual)(display, screen);
|
||||
depth = (lib.XDefaultDepth)(display, screen);
|
||||
}
|
||||
|
||||
let gc = (lib.XDefaultGC)(display, screen);
|
||||
let depth = (lib.XDefaultDepth)(display, screen);
|
||||
|
||||
let screen_width = cast::usize((lib.XDisplayWidth)(display, screen))
|
||||
.map_err(|e| Error::WindowCreate(format!("illegal width: {}", e)))?;
|
||||
|
@ -316,7 +335,7 @@ impl Window {
|
|||
// FIXME: this DisplayInfo should be a singleton, hence this code
|
||||
// is probably no good when using multiple windows.
|
||||
|
||||
let mut d = DisplayInfo::new()?;
|
||||
let mut d = DisplayInfo::new(opts.transparency)?;
|
||||
|
||||
let scale =
|
||||
Self::get_scale_factor(width, height, d.screen_width, d.screen_height, opts.scale);
|
||||
|
@ -331,6 +350,10 @@ impl Window {
|
|||
|
||||
attributes.border_pixel = (d.lib.XBlackPixel)(d.display, d.screen);
|
||||
attributes.background_pixel = attributes.border_pixel;
|
||||
if opts.transparency {
|
||||
attributes.colormap =
|
||||
(d.lib.XCreateColormap)(d.display, root, d.visual, xlib::AllocNone);
|
||||
}
|
||||
|
||||
attributes.backing_store = xlib::NotUseful;
|
||||
|
||||
|
@ -356,10 +379,12 @@ impl Window {
|
|||
d.depth,
|
||||
xlib::InputOutput as u32, /* class */
|
||||
d.visual,
|
||||
xlib::CWBackingStore | xlib::CWBackPixel | xlib::CWBorderPixel,
|
||||
xlib::CWColormap | xlib::CWBackingStore | xlib::CWBackPixel | xlib::CWBorderPixel,
|
||||
&mut attributes,
|
||||
);
|
||||
|
||||
d.gc = (d.lib.XCreateGC)(d.display, handle, 0, ptr::null_mut());
|
||||
|
||||
if handle == 0 {
|
||||
return Err(Error::WindowCreate("Unable to open Window".to_owned()));
|
||||
}
|
||||
|
@ -464,7 +489,6 @@ impl Window {
|
|||
let bytes_per_line = (width as i32) * 4;
|
||||
|
||||
draw_buffer.resize(width * height, 0);
|
||||
|
||||
let image = (d.lib.XCreateImage)(
|
||||
d.display,
|
||||
d.visual, /* TODO: this was CopyFromParent in the C code */
|
||||
|
|
|
@ -535,6 +535,12 @@ impl Window {
|
|||
flags &= !winuser::WS_THICKFRAME;
|
||||
}
|
||||
|
||||
//TODO: UpdateLayeredWindow, etc.
|
||||
//https://gist.github.com/texus/31676aba4ca774b1298e1e15133b8141
|
||||
if opts.transparency {
|
||||
flags &= winuser::WS_EX_LAYERED;
|
||||
}
|
||||
|
||||
let handle = winuser::CreateWindowExW(
|
||||
0,
|
||||
class_name.as_ptr(),
|
||||
|
|
Loading…
Reference in a new issue