// Window manipulation // Copyright (C) 2021 Nguyễn Gia Phong // // This file is part of gfz. // // gfz is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // gfz is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with gfz. If not, see . usingnamespace @import("cimport.zig"); const Error = gfz.Error; const Monitor = @import("Monitor.zig"); const checkError = gfz.checkError; const getError = gfz.getError; const gfz = @import("gfz.zig"); const Window = @This(); pub const Impl = GLFWwindow; pimpl: *Impl, const Options = struct { fullscreen: ?Monitor = null, share: ?Window = null, }; /// Set the specified window hint to the desired value. fn setHint(hint: c_int, value: anytype) Error!void { switch (@TypeOf(value)) { c_int, comptime_int => glfwWindowHint(hint, value), bool => glfwWindowHint(hint, if (value) GLFW_TRUE else GLFW_FALSE), else => unreachable, } try checkError(); } /// Create a window and its associated context. pub fn create(width: c_int, height: c_int, title: [:0]const u8, options: Options, hints: anytype) Error!Window { const Hints = @TypeOf(hints); // TODO: Add all supported GLFW window hints: // https://www.glfw.org/docs/latest/window_guide.html#window_hints_values if (@hasField(Hints, "depth_bits")) try setHint(GLFW_DEPTH_BITS, hints.depth_bits); if (@hasField(Hints, "double_buffer")) try setHint(GLFW_DOUBLEBUFFER, hints.double_buffer); const monitor = if (options.fullscreen) |box| box.pimpl else null; const share = if (options.share) |box| box.pimpl else null; const ptr = glfwCreateWindow(width, height, title.ptr, monitor, share); return if (ptr) |pimpl| Window{ .pimpl = pimpl } else getError(); } /// Make the context current for the calling thread. pub fn makeCurrent(self: Window) Error!void { glfwMakeContextCurrent(self.pimpl); try checkError(); } /// Check the close flag. pub fn shouldClose(self: Window) Error!bool { const flag = glfwWindowShouldClose(self.pimpl); try checkError(); return flag == GLFW_TRUE; } /// Set the close flag. pub fn setShouldClose(self: Window, value: bool) Error!void { glfwSetWindowShouldClose(self.pimpl, if (value) GLFW_TRUE else GLFW_FALSE); try checkError(); } pub fn swapBuffers(self: Window) Error!void { glfwSwapBuffers(self.pimpl); try checkError(); } pub const InputMode = enum(c_int) { sticky_keys = GLFW_STICKY_KEYS, sticky_mouse_buttons = GLFW_STICKY_MOUSE_BUTTONS, lock_key_mods = GLFW_LOCK_KEY_MODS, raw_mouse_motion = GLFW_RAW_MOUSE_MOTION, }; /// Return the value of an input option. pub fn getInputMode(self: Window, mode: InputMode) Error!bool { const value = glfwGetInputMode(self.pimpl, @enumToInt(mode)); try checkError(); return value == GLFW_TRUE; } /// Set an input option. pub fn setInputMode(self: Window, mode: InputMode, flag: bool) Error!void { const value = if (flag) GLFW_TRUE else GLFW_FALSE; glfwSetInputMode(self.pimpl, @enumToInt(mode), value); try checkError(); } pub const CursorMode = enum(c_int) { normal = GLFW_CURSOR_NORMAL, hidden = GLFW_CURSOR_HIDDEN, disabled = GLFW_CURSOR_DISABLED, }; /// Return the cursor mode. pub fn getCursorMode(self: Window) Error!CursorMode { const value = glfwGetInputMode(self.pimpl, GLFW_CURSOR); try checkError(); return @intToEnum(CursorMode, value); } /// Set the cursor mode. pub fn setCursorMode(self: Window, value: CursorMode) Error!void { glfwSetInputMode(self.pimpl, GLFW_CURSOR, @enumToInt(value)); try checkError(); } /// Set the size callback. pub fn setSizeCallback(self: Window, callback: GLFWwindowsizefun) Error!void { _ = glfwSetWindowSizeCallback(self.pimpl, callback); try checkError(); } /// Set the key callback. pub fn setKeyCallback(self: Window, callback: GLFWkeyfun) Error!void { _ = glfwSetKeyCallback(self.pimpl, callback); try checkError(); }