Skip to content

Commit 00ebab3

Browse files
committed
Implement mouse enter and mouse leave events
1 parent 4c0ae23 commit 00ebab3

File tree

5 files changed

+92
-4
lines changed

5 files changed

+92
-4
lines changed

src/nigui.nim

+28
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ type
279279
fOnMouseButtonUp: MouseButtonProc
280280
fOnClick: ClickProc
281281
fOnMouseMove: MouseMoveProc
282+
fOnMouseEnter: MouseMoveProc
283+
fOnMouseLeave: MouseMoveProc
282284
fOnKeyDown: KeyboardProc
283285
tag*: string
284286

@@ -344,6 +346,8 @@ type
344346
y*: int
345347
MouseButtonProc* = proc(event: MouseEvent)
346348
MouseMoveProc* = proc(event: MouseEvent)
349+
MouseEnterProc* = proc(event: MouseEvent)
350+
MouseLeaveProc* = proc(event: MouseEvent)
347351

348352
ClickEvent* = ref object
349353
control*: Control
@@ -899,6 +903,12 @@ method `onMouseButtonUp=`*(control: Control, callback: MouseButtonProc) {.base.}
899903
method onMouseMove*(control: Control): MouseMoveProc {.base.}
900904
method `onMouseMove=`*(control: Control, callback: MouseMoveProc) {.base.}
901905

906+
method onMouseEnter*(control: Control): MouseEnterProc {.base.}
907+
method `onMouseEnter=`*(control: Control, callback: MouseEnterProc) {.base.}
908+
909+
method onMouseLeave*(control: Control): MouseLeaveProc {.base.}
910+
method `onMouseLeave=`*(control: Control, callback: MouseLeaveProc) {.base.}
911+
902912
method onClick*(control: Control): ClickProc {.base.}
903913
method `onClick=`*(control: Control, callback: ClickProc) {.base.}
904914

@@ -2014,6 +2024,18 @@ method handleMouseMoveEvent(control: Control, event: MouseEvent) =
20142024
if callback != nil:
20152025
callback(event)
20162026

2027+
method handleMouseEnterEvent(control: Control, event: MouseEvent) =
2028+
# can be overridden by custom control
2029+
let callback = control.onMouseEnter
2030+
if callback != nil:
2031+
callback(event)
2032+
2033+
method handleMouseLeaveEvent(control: Control, event: MouseEvent) =
2034+
# can be overridden by custom control
2035+
let callback = control.onMouseLeave
2036+
if callback != nil:
2037+
callback(event)
2038+
20172039
method handleClickEvent(control: Control, event: ClickEvent) =
20182040
# can be overridden by custom button
20192041
let callback = control.onClick
@@ -2041,6 +2063,12 @@ method `onMouseButtonUp=`(control: Control, callback: MouseButtonProc) = control
20412063
method onMouseMove(control: Control): MouseMoveProc = control.fOnMouseMove
20422064
method `onMouseMove=`(control: Control, callback: MouseMoveProc) = control.fOnMouseMove = callback
20432065

2066+
method onMouseEnter(control: Control): MouseEnterProc = control.fOnMouseEnter
2067+
method `onMouseEnter=`(control: Control, callback: MouseEnterProc) = control.fOnMouseEnter = callback
2068+
2069+
method onMouseLeave(control: Control): MouseLeaveProc = control.fOnMouseLeave
2070+
method `onMouseLeave=`(control: Control, callback: MouseLeaveProc) = control.fOnMouseLeave = callback
2071+
20442072
method onClick(control: Control): ClickProc = control.fOnClick
20452073
method `onClick=`(control: Control, callback: ClickProc) = control.fOnClick = callback
20462074

src/nigui/private/gtk3/gtk3.nim

+20-4
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,20 @@ type
7373
device*: pointer
7474
x_root*, y_root*: cdouble
7575

76+
GdkEventCrossing* {.bycopy.} = object
77+
event_type*: cint
78+
window*: pointer
79+
send_event*: int8
80+
subwindow*: pointer
81+
time*: cint
82+
x*, y*: cdouble
83+
x_root*, y_root*: cdouble
84+
mode*: cint
85+
detail*: cint
86+
focus*: bool
87+
device*: pointer
88+
state*: cint
89+
7690
GdkEventKey* {.bycopy.} = object
7791
event_type*: cint
7892
window*: pointer
@@ -196,10 +210,12 @@ const
196210
# [..]
197211

198212
# GdkEventMask:
199-
GDK_POINTER_MOTION_MASK* = 4
200-
GDK_BUTTON_PRESS_MASK* = 256
201-
GDK_BUTTON_RELEASE_MASK* = 512
202-
GDK_KEY_PRESS_MASK* = 1024
213+
GDK_POINTER_MOTION_MASK* = 1 shl 4
214+
GDK_BUTTON_PRESS_MASK* = 1 shl 8
215+
GDK_BUTTON_RELEASE_MASK* = 1 shl 9
216+
GDK_KEY_PRESS_MASK* = 1 shl 10
217+
GDK_ENTER_NOTIFY_MASK* = 1 shl 12
218+
GDK_LEAVE_NOTIFY_MASK* = 1 shl 13
203219
# [..]
204220

205221
# cairo_format_t:

src/nigui/private/gtk3/platform_impl.nim

+18
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,18 @@ proc pControlMotionNotifySignal(widget: pointer, event: var GdkEventMotion, data
314314
evt.y = event.y.int
315315
control.handleMouseMoveEvent(evt)
316316

317+
proc pControlEnterNotifySignal(widget: pointer, event: var GdkEventCrossing, data: pointer): Gboolean {.cdecl.} =
318+
let control = cast[ControlImpl](data)
319+
var evt = new MouseEvent
320+
evt.control = control
321+
control.handleMouseEnterEvent(evt)
322+
323+
proc pControlLeaveNotifySignal(widget: pointer, event: var GdkEventCrossing, data: pointer): Gboolean {.cdecl.} =
324+
let control = cast[ControlImpl](data)
325+
var evt = new MouseEvent
326+
evt.control = control
327+
control.handleMouseLeaveEvent(evt)
328+
317329
proc pControlChangedSignal(widget: pointer, data: pointer): Gboolean {.cdecl.} =
318330
let control = cast[TextBox](data)
319331
var evt = new TextChangeEvent
@@ -1040,6 +1052,12 @@ proc init(control: ControlImpl) =
10401052
gtk_widget_add_events(control.fHandle, GDK_POINTER_MOTION_MASK)
10411053
discard g_signal_connect_data(control.fHandle, "motion-notify-event", cast[pointer](pControlMotionNotifySignal), cast[pointer](control))
10421054

1055+
gtk_widget_add_events(control.fHandle, GDK_ENTER_NOTIFY_MASK)
1056+
discard g_signal_connect_data(control.fHandle, "enter-notify-event", cast[pointer](pControlEnterNotifySignal), cast[pointer](control))
1057+
1058+
gtk_widget_add_events(control.fHandle, GDK_LEAVE_NOTIFY_MASK)
1059+
discard g_signal_connect_data(control.fHandle, "leave-notify-event", cast[pointer](pControlLeaveNotifySignal), cast[pointer](control))
1060+
10431061
control.fIMContext = gtk_im_multicontext_new()
10441062
discard g_signal_connect_data(control.fIMContext, "commit", cast[pointer](pControlIMContextCommitSignal), cast[pointer](control))
10451063

src/nigui/private/windows/platform_impl.nim

+18
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ var pLastMouseButtonDownControlX: int
3939
var pLastMouseButtonDownControlY: int
4040
var pLastMouseMoveX: int
4141
var pLastMouseMoveY: int
42+
var pLastMouseEnterControl: Control
4243

4344
var appRunning: bool
4445

@@ -1293,11 +1294,28 @@ proc pCommonControlWndProc(hWnd: pointer, uMsg: int32, wParam, lParam: pointer):
12931294
pLastMouseMoveY = y
12941295
let control = cast[Control](pGetWindowLongPtr(hWnd, GWLP_USERDATA))
12951296
if control != nil:
1297+
if control != pLastMouseEnterControl:
1298+
pLastMouseEnterControl = control
1299+
var event = new MouseEvent
1300+
event.control = control
1301+
control.handleMouseEnterEvent(event)
1302+
var tme: TTrackMouseEvent
1303+
tme.cbSize = TTrackMouseEvent.sizeof.int32
1304+
tme.dwFlags = TME_LEAVE
1305+
tme.hwndTrack = hWnd
1306+
discard TrackMouseEvent(tme)
12961307
var event = new MouseEvent
12971308
event.control = control
12981309
event.x = x
12991310
event.y = y
13001311
control.handleMouseMoveEvent(event)
1312+
of WM_MOUSELEAVE:
1313+
let control = cast[Control](pGetWindowLongPtr(hWnd, GWLP_USERDATA))
1314+
if control != nil:
1315+
pLastMouseEnterControl = nil
1316+
var event = new MouseEvent
1317+
event.control = control
1318+
control.handleMouseLeaveEvent(event)
13011319
of WM_HSCROLL, WM_VSCROLL:
13021320
pCommonControlWndProc_Scroll(hWnd, uMsg, wParam, lParam)
13031321

src/nigui/private/windows/windows.nim

+8
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ const
169169
# WM_NCLBUTTONDOWN* = 161
170170
# WM_NCLBUTTONUP* = 162
171171
WM_MOUSEWHEEL* = 0x020A
172+
WM_MOUSELEAVE* = 0x02A3
172173
WM_MOVE* = 3
173174
WM_NEXTDLGCTL* = 0x0028
174175
WM_PAINT* = 15
@@ -243,6 +244,7 @@ const
243244
FontStyleRegular* = 0
244245
FontStyleBold* = 1
245246
TextRenderingHint_AntiAlias* = 4
247+
TME_LEAVE* = 0x00000002
246248

247249

248250
# ----------------------------------------------------------------------------------------
@@ -396,6 +398,11 @@ type
396398
ptMinTrackSize*: Point
397399
ptMaxTrackSize*: Point
398400

401+
TTrackMouseEvent* {.pure.} = object
402+
cbSize*: int32
403+
dwFlags*: int32
404+
hwndTrack*: pointer
405+
dwHoverTime*: int32
399406

400407

401408
# ----------------------------------------------------------------------------------------
@@ -498,6 +505,7 @@ proc ScreenToClient*(hWnd: pointer, lpPoint: var Point): bool {.importc, libUser
498505
proc MonitorFromPoint*(pt: Point, dwFlags: int32): pointer {.importc, libUser32.}
499506
proc GetScrollPos*(hWnd: pointer, nBar: int32): int32 {.importc, libUser32.}
500507
proc LockWindowUpdate*(hWndLock: pointer): bool {.importc, libUser32.}
508+
proc TrackMouseEvent*(lpEventTrack: var TTrackMouseEvent): bool {.importc, libUser32.}
501509

502510
type GetDpiForWindowType* = proc(hWnd: pointer): int32 {.gcsafe, stdcall.} # not available on Windows 7
503511

0 commit comments

Comments
 (0)