-
Notifications
You must be signed in to change notification settings - Fork 0
/
dnd.go
213 lines (163 loc) · 6.21 KB
/
dnd.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
// Copyright (c) 2018, The GoKi Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package dnd defines the system drag-and-drop events for the GoGi GUI
// system. These are generated internally for dnd's within a given window,
// and are automatically converted into external dnd events when the mouse
// leaves the window
package dnd
import (
"image"
"time"
"github.com/goki/gi/oswin"
"github.com/goki/gi/oswin/key"
"github.com/goki/gi/oswin/mimedata"
"github.com/goki/ki/ki"
"github.com/goki/ki/kit"
)
// dnd.Event represents the drag-and-drop event, specifically the drop
type Event struct {
oswin.EventBase
// Where is the mouse location, in raw display dots (raw, actual pixels)
Where image.Point
// Action associated with the specific drag event: Start, Drop*, Move, Enter, Exit
Action Actions
// Modifiers is a bitmask representing a set of modifier keys:
// key.ModShift, key.ModAlt, etc. -- bit positions are key.Modifiers
Modifiers int32
// When event is received by target, Mod indicates the suggested modifier
// action associated with the drop (affected by holding down modifier
// keys), suggesting what to do with the dropped item, where appropriate
// -- receivers can ignore or process in their own relevant way as needed,
// BUT it is essential to update the event with the actual type of Mod
// action taken, because the event will be sent back to the source with
// this Mod as set by the receiver. The main consequence is that a
// DropMove requires the drop source to delete itself once the event has
// been received -- otherwise it (typically) doesn't do anything, so just
// be careful about that particular case.
Mod DropMods
// Data contains the MIME-typed data -- multiple different types are
// possible (and encouraged)
Data mimedata.Mimes
// Source of the drop -- only available for internal DND actions
Source ki.Ki
// Target of the drop -- receiver of an accepted drop should set this to
// itself, so Source (if internal) can see who got it
Target ki.Ki
}
// HasAnyModifier tests whether any of given modifier(s) were set
func (e *Event) HasAnyModifier(mods ...key.Modifiers) bool {
return key.HasAnyModifierBits(e.Modifiers, mods...)
}
// HasAllModifiers tests whether all of given modifier(s) were set
func (e *Event) HasAllModifiers(mods ...key.Modifiers) bool {
return key.HasAllModifierBits(e.Modifiers, mods...)
}
// DefaultModBits returns the default DropMod modifier action based on modifier keys
func DefaultModBits(modBits int32) DropMods {
switch {
case key.HasAnyModifierBits(modBits, key.Control):
return DropCopy
case key.HasAnyModifierBits(modBits, key.Shift, key.Meta):
return DropMove
case key.HasAnyModifierBits(modBits, key.Alt):
return DropLink
default:
return DropCopy
}
}
// DefaultMod sets the default DropMod modifier action based on modifier keys
func (e *Event) DefaultMod() {
e.Mod = DefaultModBits(e.Modifiers)
}
/////////////////////////////////////////////////////////////////
// dnd.MoveEvent is emitted when dnd is moved
type MoveEvent struct {
Event
// From is the previous location of the mouse
From image.Point
// LastTime is the time of the previous event
LastTime time.Time
}
/////////////////////////////////////////////////////////////////
// dnd.FocusEvent records actions of Enter and Exit of DND into a given widget
// bounding box -- generated in gi.Window, which knows about widget bounding
// boxes
type FocusEvent struct {
Event
}
// Actions associated with the DND event -- this is the nature of the event.
type Actions int32
const (
NoAction Actions = iota
// Start is triggered when criteria for DND starting have been met -- it
// is the chance for potential sources to start a DND event.
Start
// DropOnTarget is set when event is sent to the target where the item is dropped.
DropOnTarget
// DropFmSource is set when event is sent back to the source after the
// target has been dropped on a valid target that did not ignore the event
// -- the source should check if Mod = DropMove, and typically delete
// itself in this case.
DropFmSource
// External is triggered from an external drop event
External
// Move is sent whenever mouse is moving while dragging -- usually not needed.
Move
// Enter is sent when drag enters a given widget, in a FocusEvent.
Enter
// Exit is sent when drag exits a given widget, in a FocusEvent. Exit
// from one widget always happens before entering another (so you can
// reset cursor to Not).
Exit
// Hover is sent when drag is hovering over a widget without moving -- can
// use this for spring-loaded opening of items to drag into, for example.
Hover
ActionsN
)
//go:generate stringer -type=Actions
var KiT_Actions = kit.Enums.AddEnum(ActionsN, kit.NotBitFlag, nil)
// DropMods indicates the modifier associated with the drop action (affected by
// holding down modifier keys), suggesting what to do with the dropped item,
// where appropriate
type DropMods int32
const (
NoDropMod DropMods = iota
// Copy is the default and implies data is just copied -- receiver can do
// with it as they please and source does not need to take any further
// action
DropCopy
// Move is signaled with a Shift or Meta key (by default) and implies that
// the source should delete itself when it receives the DropFmSource event
// action with this Mod value set -- receiver must update the Mod to
// reflect actual action taken, and be particularly careful with this one
DropMove
// Link can be any other kind of alternative action -- link is applicable
// to files (symbolic link)
DropLink
// Ignore means that the receiver chose to not process this drop
DropIgnore
DropModsN
)
//go:generate stringer -type=DropMods
var KiT_DropMods = kit.Enums.AddEnum(DropModsN, kit.NotBitFlag, nil)
/////////////////////////////
// oswin.Event interface
func (ev *Event) Type() oswin.EventType {
return oswin.DNDEvent
}
func (ev *Event) HasPos() bool {
return true
}
func (ev *Event) Pos() image.Point {
return ev.Where
}
func (ev *Event) OnFocus() bool {
return false
}
func (ev *MoveEvent) Type() oswin.EventType {
return oswin.DNDMoveEvent
}
func (ev *FocusEvent) Type() oswin.EventType {
return oswin.DNDFocusEvent
}