use capi::sctypes::*;
pub trait BaseWindow {
fn create(&mut self, rc: RECT, flags: UINT, parent: HWINDOW) -> HWINDOW;
fn get_hwnd(&self) -> HWINDOW;
fn collapse(&self, hide: bool);
fn expand(&self, maximize: bool);
fn dismiss(&self);
fn set_title(&mut self, title: &str);
fn get_title(&self) -> String;
fn run_app(&self);
fn quit_app(&self);
}
#[cfg(windows)]
mod windows {
use ::{_API};
use capi::sctypes::*;
use capi::scdef::*;
#[link(name="user32")]
extern "system"
{
fn ShowWindow(hwnd: HWINDOW, show: INT) -> BOOL;
fn PostMessageW(hwnd: HWINDOW, msg: UINT, w: WPARAM, l: LPARAM) -> BOOL;
fn SetWindowTextW(hwnd: HWINDOW, s: LPCWSTR) -> BOOL;
fn GetWindowTextLengthW(hwnd: HWINDOW) -> INT;
fn GetWindowTextW(hwnd: HWINDOW, s: LPWSTR, l: INT) -> INT;
fn GetMessageW(msg: LPMSG, hwnd: HWINDOW, min: UINT, max: UINT) -> BOOL;
fn DispatchMessageW(msg: LPMSG) -> LRESULT;
fn TranslateMessage(msg: LPMSG) -> BOOL;
fn PostQuitMessage(code: INT);
}
#[link(name="ole32")]
extern "system"
{
fn OleInitialize(pv: LPCVOID) -> i32; }
pub struct OsWindow
{
hwnd: HWINDOW,
flags: UINT,
}
impl OsWindow {
pub fn new() -> OsWindow {
OsWindow { hwnd: 0 as HWINDOW, flags: 0 }
}
pub fn from(hwnd: HWINDOW) -> OsWindow {
OsWindow { hwnd: hwnd, flags: 0 }
}
fn init_app() {
unsafe { OleInitialize(::std::ptr::null()) };
}
}
impl super::BaseWindow for OsWindow {
fn get_hwnd(&self) -> HWINDOW {
return self.hwnd;
}
fn create(&mut self, rc: RECT, flags: UINT, parent: HWINDOW) -> HWINDOW {
if (flags & SCITER_CREATE_WINDOW_FLAGS::SW_MAIN as u32) != 0 {
OsWindow::init_app();
}
self.flags = flags;
#[cfg(not(feature = "windowless"))]
{
let cb = ::std::ptr::null();
self.hwnd = (_API.SciterCreateWindow)(flags, &rc, cb, 0 as LPVOID, parent);
if self.hwnd.is_null() {
panic!("Failed to create window!");
}
}
#[cfg(feature = "windowless")]
{
let _ = rc;
let _ = parent;
let _ = &(_API.SciterVersion);
}
return self.hwnd;
}
fn collapse(&self, hide: bool) {
let n: INT = if hide { 0 } else { 6 };
unsafe { ShowWindow(self.hwnd, n) };
}
fn expand(&self, maximize: bool) {
let n: INT = if maximize { 3 } else { 1 };
unsafe { ShowWindow(self.hwnd, n) };
}
fn dismiss(&self) {
unsafe { PostMessageW(self.hwnd, 0x0010, 0, 0) };
}
fn set_title(&mut self, title: &str) {
let s = s2w!(title);
unsafe { SetWindowTextW(self.hwnd, s.as_ptr()) };
}
fn get_title(&self) -> String {
let n = unsafe { GetWindowTextLengthW(self.hwnd) + 1 };
let mut title: Vec<u16> = Vec::new();
title.resize(n as usize, 0);
unsafe { GetWindowTextW(self.hwnd, title.as_mut_ptr(), n) };
return ::utf::w2s(title.as_ptr());
}
fn run_app(&self) {
let mut msg = MSG { hwnd: 0 as HWINDOW, message: 0, wParam: 0, lParam: 0, time: 0, pt: POINT { x: 0, y: 0 } };
let pmsg: LPMSG = &mut msg;
let null: HWINDOW = ::std::ptr::null_mut();
unsafe {
while GetMessageW(pmsg, null, 0, 0) != 0 {
TranslateMessage(pmsg);
DispatchMessageW(pmsg);
}
};
}
fn quit_app(&self) {
unsafe { PostQuitMessage(0) };
}
}
}
#[cfg(target_os="linux")]
mod linux {
use ::{_API};
use capi::sctypes::*;
use capi::scdef::*;
use super::BaseWindow;
use ::std::ptr;
#[link(name="gtk-3")]
extern "C"
{
fn gtk_init(argc: *const i32, argv: *const *const LPCSTR);
fn gtk_main();
fn gtk_main_quit();
fn gtk_widget_get_toplevel(view: HWINDOW) -> HWINDOW;
fn gtk_window_present(hwnd: HWINDOW);
fn gtk_widget_hide(hwnd: HWINDOW);
fn gtk_window_maximize(hwnd: HWINDOW);
fn gtk_window_iconify(hwnd: HWINDOW);
fn gtk_window_close(hwnd: HWINDOW);
fn gtk_window_set_title(hwnd: HWINDOW, title: LPCSTR);
fn gtk_window_get_title(hwnd: HWINDOW) -> LPCSTR;
}
pub struct OsWindow
{
hwnd: HWINDOW,
flags: UINT,
}
impl OsWindow {
pub fn new() -> OsWindow {
OsWindow { hwnd: 0 as HWINDOW, flags: 0 }
}
pub fn from(hwnd: HWINDOW) -> OsWindow {
OsWindow { hwnd: hwnd, flags: 0 }
}
fn init_app() {
unsafe { gtk_init(ptr::null(), ptr::null()) };
}
fn window(&self) -> HWINDOW {
let hwnd = self.get_hwnd();
if hwnd.is_null() {
hwnd
} else {
unsafe { gtk_widget_get_toplevel(hwnd) }
}
}
}
impl super::BaseWindow for OsWindow {
fn get_hwnd(&self) -> HWINDOW {
return self.hwnd;
}
fn create(&mut self, rc: RECT, flags: UINT, parent: HWINDOW) -> HWINDOW {
if (flags & SCITER_CREATE_WINDOW_FLAGS::SW_MAIN as u32) != 0 {
OsWindow::init_app();
}
self.flags = flags;
#[cfg(not(feature = "windowless"))]
{
let cb = ptr::null();
self.hwnd = (_API.SciterCreateWindow)(flags, &rc, cb, 0 as LPVOID, parent);
if self.hwnd.is_null() {
panic!("Failed to create window!");
}
}
#[cfg(feature = "windowless")]
{
let _ = rc;
let _ = parent;
let _ = &(_API.SciterVersion);
}
return self.hwnd;
}
fn collapse(&self, hide: bool) {
unsafe {
if hide {
gtk_widget_hide(self.get_hwnd())
} else {
gtk_window_iconify(self.window())
}
};
}
fn expand(&self, maximize: bool) {
let wnd = self.window();
unsafe {
if maximize {
gtk_window_maximize(wnd)
} else {
gtk_window_present(wnd)
}
};
}
fn dismiss(&self) {
unsafe { gtk_window_close(self.window()) };
}
fn set_title(&mut self, title: &str) {
let s = s2u!(title);
unsafe { gtk_window_set_title(self.window(), s.as_ptr()) };
}
fn get_title(&self) -> String {
let s = unsafe { gtk_window_get_title(self.window()) };
return u2s!(s);
}
fn run_app(&self) {
unsafe { gtk_main() };
}
fn quit_app(&self) {
unsafe { gtk_main_quit() };
}
}
}
#[cfg(target_os="macos")]
mod macos {
extern crate objc_foundation;
use objc::runtime::{Class, Object};
use self::objc_foundation::{NSString, INSString};
#[repr(C)]
#[allow(dead_code)]
enum NSApplicationActivationPolicy {
Regular = 0,
Accessory,
Prohibited,
}
#[link(name="CoreFoundation", kind="framework")]
extern {}
#[link(name="AppKit", kind="framework")]
extern {}
use ::{_API};
use capi::sctypes::*;
use capi::scdef::*;
use super::BaseWindow;
pub struct OsWindow
{
hwnd: HWINDOW,
flags: UINT,
}
impl OsWindow {
pub fn new() -> OsWindow {
OsWindow { hwnd: 0 as HWINDOW, flags: 0, }
}
pub fn from(hwnd: HWINDOW) -> OsWindow {
OsWindow { hwnd: hwnd, flags: 0 }
}
fn get_app() -> *mut Object {
let cls = Class::get("NSApplication").expect("`NSApplication` is not registered.");
let obj = unsafe { msg_send!(cls, sharedApplication) };
return obj;
}
fn init_app() {
let app = OsWindow::get_app();
let _: () = unsafe { msg_send!(app, setActivationPolicy:NSApplicationActivationPolicy::Regular) };
}
fn view(&self) -> *mut Object {
let hwnd = self.get_hwnd();
let hwnd = hwnd as *mut Object;
return hwnd;
}
fn window(&self) -> *mut Object {
let hwnd = self.view();
let obj: *mut Object = unsafe { msg_send!(hwnd, window) };
assert!(!obj.is_null());
return obj;
}
}
impl super::BaseWindow for OsWindow {
fn get_hwnd(&self) -> HWINDOW {
return self.hwnd;
}
fn create(&mut self, rc: RECT, flags: UINT, parent: HWINDOW) -> HWINDOW {
if (flags & SCITER_CREATE_WINDOW_FLAGS::SW_MAIN as u32) != 0 {
OsWindow::init_app();
}
self.flags = flags;
#[cfg(not(feature = "windowless"))]
{
let w = rc.right - rc.left;
let h = rc.bottom - rc.top;
let prc: *const RECT = if w > 0 && h > 0 {
&rc
} else {
std::ptr::null()
};
let cb = std::ptr::null();
self.hwnd = (_API.SciterCreateWindow)(flags, prc, cb, 0 as LPVOID, parent);
if self.hwnd.is_null() {
panic!("Failed to create window!");
}
}
#[cfg(feature = "windowless")]
{
let _ = rc;
let _ = parent;
let _ = &(_API.SciterVersion);
}
return self.hwnd;
}
fn collapse(&self, hide: bool) {
let wnd = self.window();
if hide {
let _: () = unsafe { msg_send!(wnd, orderOut:0) };
} else {
let hwnd = self.view();
let _: () = unsafe { msg_send!(wnd, performMiniaturize:hwnd) };
}
}
fn expand(&self, maximize: bool) {
let wnd = self.window();
if (self.flags & SCITER_CREATE_WINDOW_FLAGS::SW_TITLEBAR as UINT) != 0 {
let app = OsWindow::get_app();
let _: () = unsafe { msg_send!(app, activateIgnoringOtherApps:true) };
}
unsafe {
let _: () = msg_send!(wnd, makeKeyAndOrderFront:0);
}
if maximize {
let _: () = unsafe { msg_send!(wnd, performZoom:0) };
}
}
fn dismiss(&self) {
let wnd = self.window();
let _: () = unsafe { msg_send!(wnd, close) };
}
fn set_title(&mut self, title: &str) {
let s = NSString::from_str(title);
let wnd = self.window();
let _: () = unsafe { msg_send!(wnd, setTitle:s) };
}
fn get_title(&self) -> String {
String::new()
}
fn run_app(&self) {
let app = OsWindow::get_app();
let _: () = unsafe { msg_send!(app, finishLaunching) };
let _: () = unsafe { msg_send!(app, run) };
}
fn quit_app(&self) {
let app = OsWindow::get_app();
let _: () = unsafe { msg_send!(app, terminate:app) };
}
}
}
#[cfg(windows)]
pub type OsWindow = windows::OsWindow;
#[cfg(target_os="linux")]
pub type OsWindow = linux::OsWindow;
#[cfg(target_os="macos")]
pub type OsWindow = macos::OsWindow;