glfw.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package window
  5. import (
  6. "runtime"
  7. "bytes"
  8. "github.com/g3n/engine/core"
  9. "github.com/g3n/engine/gui/assets"
  10. "github.com/go-gl/glfw/v3.2/glfw"
  11. "image"
  12. _ "image/png"
  13. "os"
  14. )
  15. // Keycodes
  16. const (
  17. KeyUnknown = Key(glfw.KeyUnknown)
  18. KeySpace = Key(glfw.KeySpace)
  19. KeyApostrophe = Key(glfw.KeyApostrophe)
  20. KeyComma = Key(glfw.KeyComma)
  21. KeyMinus = Key(glfw.KeyMinus)
  22. KeyPeriod = Key(glfw.KeyPeriod)
  23. KeySlash = Key(glfw.KeySlash)
  24. Key0 = Key(glfw.Key0)
  25. Key1 = Key(glfw.Key1)
  26. Key2 = Key(glfw.Key2)
  27. Key3 = Key(glfw.Key3)
  28. Key4 = Key(glfw.Key4)
  29. Key5 = Key(glfw.Key5)
  30. Key6 = Key(glfw.Key6)
  31. Key7 = Key(glfw.Key7)
  32. Key8 = Key(glfw.Key8)
  33. Key9 = Key(glfw.Key9)
  34. KeySemicolon = Key(glfw.KeySemicolon)
  35. KeyEqual = Key(glfw.KeyEqual)
  36. KeyA = Key(glfw.KeyA)
  37. KeyB = Key(glfw.KeyB)
  38. KeyC = Key(glfw.KeyC)
  39. KeyD = Key(glfw.KeyD)
  40. KeyE = Key(glfw.KeyE)
  41. KeyF = Key(glfw.KeyF)
  42. KeyG = Key(glfw.KeyG)
  43. KeyH = Key(glfw.KeyH)
  44. KeyI = Key(glfw.KeyI)
  45. KeyJ = Key(glfw.KeyJ)
  46. KeyK = Key(glfw.KeyK)
  47. KeyL = Key(glfw.KeyL)
  48. KeyM = Key(glfw.KeyM)
  49. KeyN = Key(glfw.KeyN)
  50. KeyO = Key(glfw.KeyO)
  51. KeyP = Key(glfw.KeyP)
  52. KeyQ = Key(glfw.KeyQ)
  53. KeyR = Key(glfw.KeyR)
  54. KeyS = Key(glfw.KeyS)
  55. KeyT = Key(glfw.KeyT)
  56. KeyU = Key(glfw.KeyU)
  57. KeyV = Key(glfw.KeyV)
  58. KeyW = Key(glfw.KeyW)
  59. KeyX = Key(glfw.KeyX)
  60. KeyY = Key(glfw.KeyY)
  61. KeyZ = Key(glfw.KeyZ)
  62. KeyLeftBracket = Key(glfw.KeyLeftBracket)
  63. KeyBackslash = Key(glfw.KeyBackslash)
  64. KeyRightBracket = Key(glfw.KeyRightBracket)
  65. KeyGraveAccent = Key(glfw.KeyGraveAccent)
  66. KeyWorld1 = Key(glfw.KeyWorld1)
  67. KeyWorld2 = Key(glfw.KeyWorld2)
  68. KeyEscape = Key(glfw.KeyEscape)
  69. KeyEnter = Key(glfw.KeyEnter)
  70. KeyTab = Key(glfw.KeyTab)
  71. KeyBackspace = Key(glfw.KeyBackspace)
  72. KeyInsert = Key(glfw.KeyInsert)
  73. KeyDelete = Key(glfw.KeyDelete)
  74. KeyRight = Key(glfw.KeyRight)
  75. KeyLeft = Key(glfw.KeyLeft)
  76. KeyDown = Key(glfw.KeyDown)
  77. KeyUp = Key(glfw.KeyUp)
  78. KeyPageUp = Key(glfw.KeyPageUp)
  79. KeyPageDown = Key(glfw.KeyPageDown)
  80. KeyHome = Key(glfw.KeyHome)
  81. KeyEnd = Key(glfw.KeyEnd)
  82. KeyCapsLock = Key(glfw.KeyCapsLock)
  83. KeyScrollLock = Key(glfw.KeyScrollLock)
  84. KeyNumLock = Key(glfw.KeyNumLock)
  85. KeyPrintScreen = Key(glfw.KeyPrintScreen)
  86. KeyPause = Key(glfw.KeyPause)
  87. KeyF1 = Key(glfw.KeyF1)
  88. KeyF2 = Key(glfw.KeyF2)
  89. KeyF3 = Key(glfw.KeyF3)
  90. KeyF4 = Key(glfw.KeyF4)
  91. KeyF5 = Key(glfw.KeyF5)
  92. KeyF6 = Key(glfw.KeyF6)
  93. KeyF7 = Key(glfw.KeyF7)
  94. KeyF8 = Key(glfw.KeyF8)
  95. KeyF9 = Key(glfw.KeyF9)
  96. KeyF10 = Key(glfw.KeyF10)
  97. KeyF11 = Key(glfw.KeyF11)
  98. KeyF12 = Key(glfw.KeyF12)
  99. KeyF13 = Key(glfw.KeyF13)
  100. KeyF14 = Key(glfw.KeyF14)
  101. KeyF15 = Key(glfw.KeyF15)
  102. KeyF16 = Key(glfw.KeyF16)
  103. KeyF17 = Key(glfw.KeyF17)
  104. KeyF18 = Key(glfw.KeyF18)
  105. KeyF19 = Key(glfw.KeyF19)
  106. KeyF20 = Key(glfw.KeyF20)
  107. KeyF21 = Key(glfw.KeyF21)
  108. KeyF22 = Key(glfw.KeyF22)
  109. KeyF23 = Key(glfw.KeyF23)
  110. KeyF24 = Key(glfw.KeyF24)
  111. KeyF25 = Key(glfw.KeyF25)
  112. KeyKP0 = Key(glfw.KeyKP0)
  113. KeyKP1 = Key(glfw.KeyKP1)
  114. KeyKP2 = Key(glfw.KeyKP2)
  115. KeyKP3 = Key(glfw.KeyKP3)
  116. KeyKP4 = Key(glfw.KeyKP4)
  117. KeyKP5 = Key(glfw.KeyKP5)
  118. KeyKP6 = Key(glfw.KeyKP6)
  119. KeyKP7 = Key(glfw.KeyKP7)
  120. KeyKP8 = Key(glfw.KeyKP8)
  121. KeyKP9 = Key(glfw.KeyKP9)
  122. KeyKPDecimal = Key(glfw.KeyKPDecimal)
  123. KeyKPDivide = Key(glfw.KeyKPDivide)
  124. KeyKPMultiply = Key(glfw.KeyKPMultiply)
  125. KeyKPSubtract = Key(glfw.KeyKPSubtract)
  126. KeyKPAdd = Key(glfw.KeyKPAdd)
  127. KeyKPEnter = Key(glfw.KeyKPEnter)
  128. KeyKPEqual = Key(glfw.KeyKPEqual)
  129. KeyLeftShift = Key(glfw.KeyLeftShift)
  130. KeyLeftControl = Key(glfw.KeyLeftControl)
  131. KeyLeftAlt = Key(glfw.KeyLeftAlt)
  132. KeyLeftSuper = Key(glfw.KeyLeftSuper)
  133. KeyRightShift = Key(glfw.KeyRightShift)
  134. KeyRightControl = Key(glfw.KeyRightControl)
  135. KeyRightAlt = Key(glfw.KeyRightAlt)
  136. KeyRightSuper = Key(glfw.KeyRightSuper)
  137. KeyMenu = Key(glfw.KeyMenu)
  138. KeyLast = Key(glfw.KeyLast)
  139. )
  140. // Modifier keys
  141. const (
  142. ModShift = ModifierKey(glfw.ModShift)
  143. ModControl = ModifierKey(glfw.ModControl)
  144. ModAlt = ModifierKey(glfw.ModAlt)
  145. ModSuper = ModifierKey(glfw.ModSuper)
  146. )
  147. // Mouse buttons
  148. const (
  149. MouseButton1 = MouseButton(glfw.MouseButton1)
  150. MouseButton2 = MouseButton(glfw.MouseButton2)
  151. MouseButton3 = MouseButton(glfw.MouseButton3)
  152. MouseButton4 = MouseButton(glfw.MouseButton4)
  153. MouseButton5 = MouseButton(glfw.MouseButton5)
  154. MouseButton6 = MouseButton(glfw.MouseButton6)
  155. MouseButton7 = MouseButton(glfw.MouseButton7)
  156. MouseButton8 = MouseButton(glfw.MouseButton8)
  157. MouseButtonLast = MouseButton(glfw.MouseButtonLast)
  158. MouseButtonLeft = MouseButton(glfw.MouseButtonLeft)
  159. MouseButtonRight = MouseButton(glfw.MouseButtonRight)
  160. MouseButtonMiddle = MouseButton(glfw.MouseButtonMiddle)
  161. )
  162. // Standard cursors for g3n. The diagonal cursors are not standard for GLFW.
  163. const (
  164. ArrowCursor = StandardCursor(glfw.ArrowCursor)
  165. IBeamCursor = StandardCursor(glfw.IBeamCursor)
  166. CrosshairCursor = StandardCursor(glfw.CrosshairCursor)
  167. HandCursor = StandardCursor(glfw.HandCursor)
  168. HResizeCursor = StandardCursor(glfw.HResizeCursor)
  169. VResizeCursor = StandardCursor(glfw.VResizeCursor)
  170. DiagResize1Cursor = StandardCursor(VResizeCursor + 1)
  171. DiagResize2Cursor = StandardCursor(VResizeCursor + 2)
  172. )
  173. // Actions
  174. const (
  175. // Release indicates that key or mouse button was released
  176. Release = Action(glfw.Release)
  177. // Press indicates that key or mouse button was pressed
  178. Press = Action(glfw.Press)
  179. // Repeat indicates that key was held down until it repeated
  180. Repeat = Action(glfw.Repeat)
  181. )
  182. // Input modes
  183. const (
  184. CursorInputMode = InputMode(glfw.CursorMode) // See Cursor mode values
  185. StickyKeysInputMode = InputMode(glfw.StickyKeysMode) // Value can be either 1 or 0
  186. StickyMouseButtonsInputMode = InputMode(glfw.StickyMouseButtonsMode) // Value can be either 1 or 0
  187. )
  188. // Cursor mode values
  189. const (
  190. CursorNormal = CursorMode(glfw.CursorNormal)
  191. CursorHidden = CursorMode(glfw.CursorHidden)
  192. CursorDisabled = CursorMode(glfw.CursorDisabled)
  193. )
  194. // glfwManager contains data shared by all windows
  195. type glfwManager struct {
  196. arrowCursor *glfw.Cursor // Preallocated standard arrow cursor
  197. ibeamCursor *glfw.Cursor // Preallocated standard ibeam cursor
  198. crosshairCursor *glfw.Cursor // Preallocated standard cross hair cursor
  199. handCursor *glfw.Cursor // Preallocated standard hand cursor
  200. hresizeCursor *glfw.Cursor // Preallocated standard horizontal resize cursor
  201. vresizeCursor *glfw.Cursor // Preallocated standard vertical resize cursor
  202. // Non GLFW standard cursors (but g3n standard)
  203. diag1Cursor *glfw.Cursor // Preallocated diagonal resize cursor (/)
  204. diag2Cursor *glfw.Cursor // Preallocated diagonal resize cursor (\)
  205. // User-created custom cursors
  206. customCursors map[int]*glfw.Cursor
  207. lastCursorKey int
  208. }
  209. // glfwWindow describes one glfw window
  210. type glfwWindow struct {
  211. core.Dispatcher // Embedded event dispatcher
  212. win *glfw.Window // Pointer to native glfw window
  213. mgr *glfwManager // Pointer to window manager
  214. fullScreen bool
  215. lastX int
  216. lastY int
  217. lastWidth int
  218. lastHeight int
  219. scaleX float64
  220. scaleY float64
  221. // Events
  222. keyEv KeyEvent
  223. charEv CharEvent
  224. mouseEv MouseEvent
  225. posEv PosEvent
  226. sizeEv SizeEvent
  227. cursorEv CursorEvent
  228. scrollEv ScrollEvent
  229. }
  230. // glfw manager singleton
  231. var manager *glfwManager
  232. // Manager returns the glfw window manager
  233. func Manager() (IWindowManager, error) {
  234. if manager != nil {
  235. return manager, nil
  236. }
  237. // Initialize glfw
  238. err := glfw.Init()
  239. if err != nil {
  240. return nil, err
  241. }
  242. // Sets window hints
  243. glfw.WindowHint(glfw.ContextVersionMajor, 3)
  244. glfw.WindowHint(glfw.ContextVersionMinor, 3)
  245. glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
  246. glfw.WindowHint(glfw.Samples, 8)
  247. // Sets OpenGL forward compatible context only for OSX because it is required for OSX.
  248. // When this is set, glLineWidth(width) only accepts width=1.0 and generates an error
  249. // for any other values although the spec says it should ignore unsupported widths
  250. // and generate an error only when width <= 0.
  251. if runtime.GOOS == "darwin" {
  252. glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
  253. }
  254. manager = new(glfwManager)
  255. // Preallocate GLFW standard cursors
  256. manager.arrowCursor = glfw.CreateStandardCursor(glfw.ArrowCursor)
  257. manager.ibeamCursor = glfw.CreateStandardCursor(glfw.IBeamCursor)
  258. manager.crosshairCursor = glfw.CreateStandardCursor(glfw.CrosshairCursor)
  259. manager.handCursor = glfw.CreateStandardCursor(glfw.HandCursor)
  260. manager.hresizeCursor = glfw.CreateStandardCursor(glfw.HResizeCursor)
  261. manager.vresizeCursor = glfw.CreateStandardCursor(glfw.VResizeCursor)
  262. // Preallocate g3n cursors (diagonal cursors)
  263. cursorDiag1Png := assets.MustAsset("cursors/diag1.png")
  264. cursorDiag2Png := assets.MustAsset("cursors/diag2.png")
  265. diag1Img, _, err := image.Decode(bytes.NewReader(cursorDiag1Png))
  266. diag2Img, _, err := image.Decode(bytes.NewReader(cursorDiag2Png))
  267. if err != nil {
  268. return nil, err
  269. }
  270. manager.diag1Cursor = glfw.CreateCursor(diag1Img, 8, 8)
  271. manager.diag2Cursor = glfw.CreateCursor(diag2Img, 8, 8)
  272. // Create map for custom cursors
  273. manager.customCursors = make(map[int]*glfw.Cursor)
  274. return manager, nil
  275. }
  276. // ScreenResolution returns the screen resolution
  277. func (m *glfwManager) ScreenResolution(p interface{}) (width, height int) {
  278. mon := glfw.GetPrimaryMonitor()
  279. vmode := mon.GetVideoMode()
  280. return vmode.Width, vmode.Height
  281. }
  282. // PollEvents process events in the event queue
  283. func (m *glfwManager) PollEvents() {
  284. glfw.PollEvents()
  285. }
  286. // SetSwapInterval sets the number of screen updates to wait from the time SwapBuffer()
  287. // is called before swapping the buffers and returning.
  288. func (m *glfwManager) SetSwapInterval(interval int) {
  289. glfw.SwapInterval(interval)
  290. }
  291. // Terminate destroys any remainding window, cursors and other related objects.
  292. func (m *glfwManager) Terminate() {
  293. glfw.Terminate()
  294. manager = nil
  295. }
  296. // CreateCursor creates a new custom cursor and returns an int handle.
  297. func (m *glfwManager) CreateCursor(imgFile string, xhot, yhot int) (int, error) {
  298. // Open image file
  299. file, err := os.Open(imgFile)
  300. if err != nil {
  301. return 0, err
  302. }
  303. defer file.Close()
  304. // Decodes image
  305. img, _, err := image.Decode(file)
  306. if err != nil {
  307. return 0, err
  308. }
  309. cursor := glfw.CreateCursor(img, xhot, yhot)
  310. if err != nil {
  311. return 0, err
  312. }
  313. m.lastCursorKey += 1
  314. m.customCursors[m.lastCursorKey] = cursor
  315. return m.lastCursorKey, nil
  316. }
  317. // DisposeCursor deletes the existing custom cursor with the provided int handle.
  318. func (m *glfwManager) DisposeCursor(key int) {
  319. delete(m.customCursors, key)
  320. }
  321. // DisposeAllCursors deletes all existing custom cursors.
  322. func (m *glfwManager) DisposeAllCursors() {
  323. m.customCursors = make(map[int]*glfw.Cursor)
  324. m.lastCursorKey = 0
  325. }
  326. // CreateWindow creates and returns a new window with the specified width and height in screen coordinates
  327. func (m *glfwManager) CreateWindow(width, height int, title string, fullscreen bool) (IWindow, error) {
  328. // Creates window and sets it as the current context.
  329. // The window is created always as not full screen because if it is
  330. // created as full screen it not possible to revert it to windowed mode.
  331. // At the end of this function, the window will be set to full screen if requested.
  332. win, err := glfw.CreateWindow(width, height, title, nil, nil)
  333. if err != nil {
  334. return nil, err
  335. }
  336. win.MakeContextCurrent()
  337. // Create wrapper window with dispacher
  338. w := new(glfwWindow)
  339. w.win = win
  340. w.mgr = m
  341. w.Dispatcher.Initialize()
  342. fbw, fbh := w.FramebufferSize()
  343. w.scaleX = float64(fbw) / float64(width)
  344. w.scaleY = float64(fbh) / float64(height)
  345. // Set key callback to dispatch event
  346. win.SetKeyCallback(func(x *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) {
  347. w.keyEv.W = w
  348. w.keyEv.Keycode = Key(key)
  349. w.keyEv.Scancode = scancode
  350. w.keyEv.Action = Action(action)
  351. w.keyEv.Mods = ModifierKey(mods)
  352. if action == glfw.Press {
  353. w.Dispatch(OnKeyDown, &w.keyEv)
  354. return
  355. }
  356. if action == glfw.Release {
  357. w.Dispatch(OnKeyUp, &w.keyEv)
  358. return
  359. }
  360. if action == glfw.Repeat {
  361. w.Dispatch(OnKeyRepeat, &w.keyEv)
  362. return
  363. }
  364. })
  365. // Set char callback
  366. win.SetCharModsCallback(func(x *glfw.Window, char rune, mods glfw.ModifierKey) {
  367. w.charEv.W = w
  368. w.charEv.Char = char
  369. w.charEv.Mods = ModifierKey(mods)
  370. w.Dispatch(OnChar, &w.charEv)
  371. })
  372. // Set mouse button callback to dispatch event
  373. win.SetMouseButtonCallback(func(x *glfw.Window, button glfw.MouseButton, action glfw.Action, mods glfw.ModifierKey) {
  374. xpos, ypos := x.GetCursorPos()
  375. w.mouseEv.W = w
  376. w.mouseEv.Button = MouseButton(button)
  377. w.mouseEv.Action = Action(action)
  378. w.mouseEv.Mods = ModifierKey(mods)
  379. w.mouseEv.Xpos = float32(xpos * w.scaleX)
  380. w.mouseEv.Ypos = float32(ypos * w.scaleY)
  381. if action == glfw.Press {
  382. w.Dispatch(OnMouseDown, &w.mouseEv)
  383. return
  384. }
  385. if action == glfw.Release {
  386. w.Dispatch(OnMouseUp, &w.mouseEv)
  387. return
  388. }
  389. })
  390. // Set window size callback to dispatch event
  391. win.SetSizeCallback(func(x *glfw.Window, width int, height int) {
  392. fbw, fbh := x.GetFramebufferSize()
  393. w.sizeEv.W = w
  394. w.sizeEv.Width = width
  395. w.sizeEv.Height = height
  396. w.scaleX = float64(fbw) / float64(width)
  397. w.scaleY = float64(fbh) / float64(height)
  398. w.Dispatch(OnWindowSize, &w.sizeEv)
  399. })
  400. // Set window position event callback to dispatch event
  401. win.SetPosCallback(func(x *glfw.Window, xpos int, ypos int) {
  402. w.posEv.W = w
  403. w.posEv.Xpos = xpos
  404. w.posEv.Ypos = ypos
  405. w.Dispatch(OnWindowPos, &w.posEv)
  406. })
  407. // Set window cursor position event callback to dispatch event
  408. win.SetCursorPosCallback(func(x *glfw.Window, xpos float64, ypos float64) {
  409. w.cursorEv.W = w
  410. w.cursorEv.Xpos = float32(xpos * w.scaleX)
  411. w.cursorEv.Ypos = float32(ypos * w.scaleY)
  412. w.Dispatch(OnCursor, &w.cursorEv)
  413. })
  414. // Set mouse wheel scroll event callback to dispatch event
  415. win.SetScrollCallback(func(x *glfw.Window, xoff float64, yoff float64) {
  416. w.scrollEv.W = w
  417. w.scrollEv.Xoffset = float32(xoff)
  418. w.scrollEv.Yoffset = float32(yoff)
  419. w.Dispatch(OnScroll, &w.scrollEv)
  420. })
  421. // Sets full screen if requested
  422. if fullscreen {
  423. w.SetFullScreen(true)
  424. }
  425. return w, nil
  426. }
  427. // Manager returns the window manager and satisfies the IWindow interface
  428. func (w *glfwWindow) Manager() IWindowManager {
  429. return w.mgr
  430. }
  431. // MakeContextCurrent makes the OpenGL context of this window current on the calling thread
  432. func (w *glfwWindow) MakeContextCurrent() {
  433. w.win.MakeContextCurrent()
  434. }
  435. // FullScreen returns this window full screen state for the primary monitor
  436. func (w *glfwWindow) FullScreen() bool {
  437. return w.fullScreen
  438. }
  439. // SetFullScreen sets this window full screen state for the primary monitor
  440. func (w *glfwWindow) SetFullScreen(full bool) {
  441. // If already in the desired state, nothing to do
  442. if w.fullScreen == full {
  443. return
  444. }
  445. // Sets this window full screen for the primary monitor
  446. if full {
  447. // Get primary monitor
  448. mon := glfw.GetPrimaryMonitor()
  449. vmode := mon.GetVideoMode()
  450. width := vmode.Width
  451. height := vmode.Height
  452. // Saves current position and size of the window
  453. w.lastX, w.lastY = w.win.GetPos()
  454. w.lastWidth, w.lastHeight = w.win.GetSize()
  455. // Sets monitor for full screen
  456. w.win.SetMonitor(mon, 0, 0, width, height, vmode.RefreshRate)
  457. w.fullScreen = true
  458. } else {
  459. // Restore window to previous position and size
  460. w.win.SetMonitor(nil, w.lastX, w.lastY, w.lastWidth, w.lastHeight, glfw.DontCare)
  461. w.fullScreen = false
  462. }
  463. }
  464. // Destroy destroys this window and its context
  465. func (w *glfwWindow) Destroy() {
  466. w.win.Destroy()
  467. w.win = nil
  468. }
  469. // SwapBuffers swaps the front and back buffers of this window.
  470. // If the swap interval is greater than zero,
  471. // the GPU driver waits the specified number of screen updates before swapping the buffers.
  472. func (w *glfwWindow) SwapBuffers() {
  473. w.win.SwapBuffers()
  474. }
  475. // FramebufferSize returns framebuffer size of this window
  476. func (w *glfwWindow) FramebufferSize() (width int, height int) {
  477. return w.win.GetFramebufferSize()
  478. }
  479. // Scale returns this window's DPI scale factor (FramebufferSize / Size)
  480. func (w *glfwWindow) Scale() (x float64, y float64) {
  481. return w.scaleX, w.scaleY
  482. }
  483. // Size returns this window's size in screen coordinates
  484. func (w *glfwWindow) Size() (width int, height int) {
  485. return w.win.GetSize()
  486. }
  487. // SetSize sets the size, in screen coordinates, of the client area of this window
  488. func (w *glfwWindow) SetSize(width int, height int) {
  489. w.win.SetSize(width, height)
  490. }
  491. // Pos returns the position, in screen coordinates, of the upper-left corner of the client area of this window
  492. func (w *glfwWindow) Pos() (xpos, ypos int) {
  493. return w.win.GetPos()
  494. }
  495. // SetPos sets the position, in screen coordinates, of the upper-left corner of the client area of this window.
  496. // If the window is a full screen window, this function does nothing.
  497. func (w *glfwWindow) SetPos(xpos, ypos int) {
  498. w.win.SetPos(xpos, ypos)
  499. }
  500. // SetTitle sets this window title, encoded as UTF-8
  501. func (w *glfwWindow) SetTitle(title string) {
  502. w.win.SetTitle(title)
  503. }
  504. // ShouldClose returns the current state of this window should close flag
  505. func (w *glfwWindow) ShouldClose() bool {
  506. return w.win.ShouldClose()
  507. }
  508. // SetShouldClose sets the state of this windows should close flag
  509. func (w *glfwWindow) SetShouldClose(v bool) {
  510. w.win.SetShouldClose(v)
  511. }
  512. // SetStandardCursor sets the window's cursor to a standard one
  513. func (w *glfwWindow) SetStandardCursor(cursor StandardCursor) {
  514. switch cursor {
  515. case ArrowCursor:
  516. w.win.SetCursor(w.mgr.arrowCursor)
  517. case IBeamCursor:
  518. w.win.SetCursor(w.mgr.ibeamCursor)
  519. case CrosshairCursor:
  520. w.win.SetCursor(w.mgr.crosshairCursor)
  521. case HandCursor:
  522. w.win.SetCursor(w.mgr.handCursor)
  523. case HResizeCursor:
  524. w.win.SetCursor(w.mgr.hresizeCursor)
  525. case VResizeCursor:
  526. w.win.SetCursor(w.mgr.vresizeCursor)
  527. // Non-GLFW cursors (but standard cursors for g3n)
  528. case DiagResize1Cursor:
  529. w.win.SetCursor(w.mgr.diag1Cursor)
  530. case DiagResize2Cursor:
  531. w.win.SetCursor(w.mgr.diag2Cursor)
  532. default:
  533. panic("Invalid cursor")
  534. }
  535. }
  536. // SetStandardCursor sets this window's cursor to a custom, user-created one
  537. func (w *glfwWindow) SetCustomCursor(key int) {
  538. w.win.SetCursor(w.mgr.customCursors[key])
  539. }
  540. // SetInputMode changes specified input to specified state
  541. // Reference: http://www.glfw.org/docs/latest/group__input.html#gaa92336e173da9c8834558b54ee80563b
  542. func (w *glfwWindow) SetInputMode(mode InputMode, state int) {
  543. w.win.SetInputMode(glfw.InputMode(mode), state)
  544. }
  545. // SetCursorPos sets cursor position in window coordinates
  546. // Reference: http://www.glfw.org/docs/latest/group__input.html#ga04b03af936d906ca123c8f4ee08b39e7
  547. func (w *glfwWindow) SetCursorPos(xpos, ypos float64) {
  548. w.win.SetCursorPos(xpos, ypos)
  549. }