v/vlib/glfw/glfw.v

374 lines
7.6 KiB
V

// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module glfw
import gl
// note: we might need special case for this
// see TmpGlImportHack below (joe-c)
#flag -I @VROOT/thirdparty/glfw
#flag -L @VROOT/thirdparty/glfw
// Debugging a custom build
//-#flag darwin -L/var/tmp/glfw/src/
// MacPorts
#flag darwin -L/opt/local/lib
#flag darwin -lglfw
#flag freebsd -I/usr/local/include
#flag freebsd -Wl,-L/usr/local/lib,-lglfw
#flag solaris -I/opt/local/include
#flag solaris -L/opt/local/lib
#flag solaris -lglfw
#flag linux -lglfw
#flag windows -lgdi32 -lshell32 -lglfw3
#flag mingw -mwindows
#include <GLFW/glfw3.h>
// #flag darwin -framework Carbon
// #flag darwin -framework Cocoa
// #flag darwin -framework CoreVideo
// #flag darwin -framework IOKit
pub const (
resizable = 1
decorated = 2
)
pub const (
key_escape = 256
key_space = 32
key_left_super = 343
key_up = 265
key_left = 263
key_right = 262
key_down = 264
)
fn C.glfwGetWindowUserPointer() voidptr
fn C.glfwGetPrimaryMonitor() voidptr
fn C.glfwSetWindowUserPointer()
fn C.glfwSetCursor()
fn C.glfwGetCursorPos()
fn C.glfwSetClipboardString()
fn C.glfwGetWindowContentScale()
fn C.glfwGetClipboardString()
fn C.glfwGetKey()
fn C.glfwGetTime() f64
fn C.glfwSetCharModsCallback()
fn C.glfwSetKeyCallback()
fn C.glfwPostEmptyEvent()
fn C.glfwSetScrollCallback()
fn C.glfwSetWindowSizeCallback()
fn C.glfwSetMouseButtonCallback()
fn C.glfwSetCursorPosCallback()
fn C.glfwSwapBuffers()
fn C.glfwWindowShouldClose() bool
fn C.glfwSetWindowShouldClose()
fn C.glfwWaitEvents()
fn C.glfwPollEvents()
fn C.glfwSwapInterval()
fn C.glfwMakeContextCurrent()
fn C.glfwSetWindowTitle()
fn C.glfwTerminate()
fn C.glfwCreateWindow(w int, h int, title charptr, m voidptr, sh voidptr) voidptr
fn C.glfwWindowHint()
fn C.glfwDestroyWindow()
fn C.glfwInit()
fn C.glGetIntegerv()
// joe-c: fix & remove
struct TmpGlImportHack {
hack gl.TmpGlImportHack
}
pub struct WinCfg {
width int
height int
title string
ptr voidptr
borderless bool
is_modal int
is_browser bool
url string
always_on_top bool
scale_to_monitor bool = true
}
// data *C.GLFWwindow
// TODO change data to cobj
pub struct Window {
data voidptr
title string
mx int
my int
scale_ f32
}
pub struct Size {
pub:
width int
height int
}
pub struct Pos {
pub:
x int
y int
}
// type clickpub fn pub fn (window * GLFWwindow, button, action, mods int)
type ClickPubFn fn (window voidptr, button, action, mods int)
/*
* TODO broken
fn init() {
init_glfw()
}
*/
pub fn init_glfw() {
C.glfwInit()
C.glfwWindowHint(C.GLFW_CONTEXT_VERSION_MAJOR, 3)
C.glfwWindowHint(C.GLFW_CONTEXT_VERSION_MINOR, 3)
C.glfwWindowHint(C.GLFW_OPENGL_FORWARD_COMPAT, C.GL_TRUE)
C.glfwWindowHint(C.GLFW_OPENGL_PROFILE, C.GLFW_OPENGL_CORE_PROFILE)
}
pub fn (w &Window) destroy() {
C.glfwDestroyWindow(w.data)
}
pub fn terminate() {
C.glfwTerminate()
}
// pub fn mouse_move(w * GLFWwindow, x, y double) {
pub fn mouse_move(w voidptr, x, y f64) {
// #printf("%f : %f => %d \n", x,y);
}
pub fn window_hint(key, val int) {
C.glfwWindowHint(key, val)
}
pub fn create_window(c WinCfg) &Window {
if c.borderless {
window_hint(C.GLFW_RESIZABLE, 0)
window_hint(C.GLFW_DECORATED, 0)
}
if c.always_on_top {
window_hint(C.GLFW_FLOATING, 1)
}
if c.scale_to_monitor {
$if windows {
window_hint(C.GLFW_SCALE_TO_MONITOR, 1)
}
}
cwindow := C.glfwCreateWindow(c.width, c.height, c.title.str, 0, 0)
if isnil(cwindow) {
println('failed to create a glfw window, make sure you have a GPU driver installed')
C.glfwTerminate()
}
// println('create window wnd=$cwindow ptr==$c.ptr')
C.glfwSetWindowUserPointer(cwindow, c.ptr)
mut scale := f32(1.0)
$if windows {
C.glfwGetWindowContentScale(cwindow, &scale, &scale)
}
$else {
scale = 1.0
}
window := &Window {
data: cwindow,
title: c.title,
scale_: scale
}
return window
}
pub fn (w &Window) set_title(title string) {
C.glfwSetWindowTitle(w.data, title.str)
}
pub fn (w &Window) make_context_current() {
C.glfwMakeContextCurrent(w.data)
}
pub fn (w &Window) scale() f32 {
return w.scale_
}
pub fn swap_interval(interval int) {
C.glfwSwapInterval(interval)
}
pub fn wait_events() {
C.glfwWaitEvents()
}
pub fn poll_events() {
C.glfwPollEvents()
}
pub fn set_should_close(w voidptr, close bool) {
C.glfwSetWindowShouldClose(w, close)
}
pub fn (w &Window) set_should_close(close bool) {
C.glfwSetWindowShouldClose(w.data, close)
}
pub fn (w &Window) should_close() bool {
return C.glfwWindowShouldClose(w.data)
}
pub fn (w &Window) swap_buffers() {
C.glfwSwapBuffers(w.data)
}
pub fn (mut w Window) onmousemove(cb voidptr) {
C.glfwSetCursorPosCallback(w.data, cb)
}
pub fn (mut w Window) set_mouse_button_callback(cb voidptr) {
C.glfwSetMouseButtonCallback(w.data, cb)
}
pub fn (mut w Window) on_resize(cb voidptr) {
C.glfwSetWindowSizeCallback(w.data, cb)
}
pub fn (mut w Window) on_click(cb voidptr) {
C.glfwSetMouseButtonCallback(w.data, cb)
}
pub fn (w &Window) set_scroll_callback(cb voidptr) {
C.glfwSetScrollCallback(w.data, cb)
}
pub fn (w &Window) on_scroll(cb voidptr) {
C.glfwSetScrollCallback(w.data, cb)
}
pub fn post_empty_event() {
C.glfwPostEmptyEvent()
}
pub fn (mut w Window) onkeydown(cb voidptr) {
C.glfwSetKeyCallback(w.data, cb)
}
pub fn (mut w Window) onchar(cb voidptr) {
C.glfwSetCharModsCallback(w.data, cb)
}
pub fn get_time() f64 {
return C.glfwGetTime()
}
pub fn key_pressed(wnd voidptr, key int) bool {
return int(C.glfwGetKey(wnd, key)) == C.GLFW_PRESS
}
pub fn (w &Window) get_clipboard_text() string {
return string(byteptr(C.glfwGetClipboardString(w.data)))
}
pub fn (w &Window) set_clipboard_text(s string) {
C.glfwSetClipboardString(w.data, s.str)
}
pub fn get_cursor_pos(cwindow voidptr) (f64, f64) {
x := f64(0)
y := f64(0)
C.glfwGetCursorPos(cwindow, &x, &y)
mut scale := f32(1.0)
$if windows {
C.glfwGetWindowContentScale(cwindow, &scale, &scale)
}
$else {
scale = 1.0
}
return x/scale, y/scale
}
pub fn (w &Window) get_cursor_pos() Pos {
x := f64(0)
y := f64(0)
C.glfwGetCursorPos(w.data, &x, &y)
return Pos {
x: int(x/w.scale_)
y: int(y/w.scale_)
}
}
enum Cursor {
arrow
ibeam
hand
}
pub fn set_cursor(c Cursor) {
C.glfwSetCursor(0, C.GLFW_IBEAM_CURSOR)
}
pub fn (w &Window) set_cursor(c Cursor) {
C.glfwSetCursor(w.data, C.GLFW_IBEAM_CURSOR)
}
pub fn (w &Window) user_ptr() voidptr {
return C.glfwGetWindowUserPointer(w.data)
}
pub fn (w &Window) set_user_ptr(ptr voidptr) {
C.glfwSetWindowUserPointer(w.data, ptr)
}
struct C.GLFWvidmode {
width int
height int
}
pub fn C.glfwGetVideoMode() &C.GLFWvidmode
pub fn get_monitor_size() Size {
//# GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
mode := C.glfwGetVideoMode(C.glfwGetPrimaryMonitor())
return Size{mode.width, mode.height}
}
fn C.glfwGetWindowSize(window &Window, width &int, height &int) // screen coordinates
fn C.glfwGetFramebufferSize(window &Window, width &int, height &int) // pixels
// get_window_size in screen coordinates
pub fn (w &Window) get_window_size() Size {
res := Size {0, 0}
C.glfwGetWindowSize(w.data, &res.width, &res.height)
return res
}
// get_framebuffer_size in pixels
pub fn (w &Window) get_framebuffer_size() Size {
res := Size {0, 0}
C.glfwGetFramebufferSize(w.data, &res.width, &res.height)
return res
}
pub fn (size Size) str() string {
return '{$size.width, $size.height}'
}
pub fn get_window_user_pointer(gwnd voidptr) voidptr {
return C.glfwGetWindowUserPointer(gwnd)
}