-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
cursor.go
110 lines (93 loc) · 3.24 KB
/
cursor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright (c) 2021-2024 by Richard A. Wilkes. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, version 2.0. If a copy of the MPL was not distributed with
// this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// This Source Code Form is "Incompatible With Secondary Licenses", as
// defined by the Mozilla Public License, version 2.0.
package unison
import (
"image"
"github.com/go-gl/glfw/v3.3/glfw"
"github.com/richardwilkes/toolbox/errs"
"golang.org/x/image/draw"
)
var (
arrowCursor *Cursor
pointingCursor *Cursor
moveCursor *Cursor
resizeHorizontalCursor *Cursor
resizeLeftDiagonalCursor *Cursor
resizeRightDiagonalCursor *Cursor
resizeVerticalCursor *Cursor
textCursor *Cursor
)
// Cursor provides a graphical cursor for the mouse location.
type Cursor = glfw.Cursor
// ArrowCursor returns the standard arrow cursor.
func ArrowCursor() *Cursor {
if arrowCursor == nil {
arrowCursor = glfw.CreateStandardCursor(glfw.ArrowCursor)
}
return arrowCursor
}
// PointingCursor returns the standard pointing cursor.
func PointingCursor() *Cursor {
if pointingCursor == nil {
pointingCursor = glfw.CreateStandardCursor(glfw.HandCursor)
}
return pointingCursor
}
// MoveCursor returns the standard move cursor.
func MoveCursor() *Cursor {
return retrieveCursor(MoveCursorImage(), &moveCursor)
}
// ResizeHorizontalCursor returns the standard horizontal resize cursor.
func ResizeHorizontalCursor() *Cursor {
return retrieveCursor(ResizeHorizontalCursorImage(), &resizeHorizontalCursor)
}
// ResizeLeftDiagonalCursor returns the standard left diagonal resize cursor.
func ResizeLeftDiagonalCursor() *Cursor {
return retrieveCursor(ResizeLeftDiagonalCursorImage(), &resizeLeftDiagonalCursor)
}
// ResizeRightDiagonalCursor returns the standard right diagonal resize cursor.
func ResizeRightDiagonalCursor() *Cursor {
return retrieveCursor(ResizeRightDiagonalCursorImage(), &resizeRightDiagonalCursor)
}
// ResizeVerticalCursor returns the standard vertical resize cursor.
func ResizeVerticalCursor() *Cursor {
return retrieveCursor(ResizeVerticalCursorImage(), &resizeVerticalCursor)
}
// TextCursor returns the standard text cursor.
func TextCursor() *Cursor {
if textCursor == nil {
textCursor = glfw.CreateStandardCursor(glfw.IBeamCursor)
}
return textCursor
}
func retrieveCursor(img *Image, cursor **Cursor) *Cursor {
if *cursor == nil {
size := img.LogicalSize()
*cursor = NewCursor(img, Point{X: size.Width / 2, Y: size.Height / 2})
}
return *cursor
}
// NewCursor creates a new custom cursor from an image.
func NewCursor(img *Image, hotSpot Point) *Cursor {
nrgba, err := img.ToNRGBA()
if err != nil {
errs.Log(err)
return ArrowCursor()
}
// glfw doesn't take the high resolution cursors properly, so scale them down, if needed
logicalSize := img.LogicalSize()
size := img.Size()
if logicalSize != size {
dstRect := image.Rect(0, 0, int(logicalSize.Width), int(logicalSize.Height))
dst := image.NewNRGBA(dstRect)
draw.CatmullRom.Scale(dst, dstRect, nrgba, image.Rect(0, 0, int(size.Width), int(size.Height)), draw.Over, nil)
nrgba = dst
}
return glfw.CreateCursor(nrgba, int(hotSpot.X), int(hotSpot.Y))
}