summaryrefslogtreecommitdiff
path: root/src/nigui/private
diff options
context:
space:
mode:
authortrustable-code <krauter.simon@arcor.de>2019-09-23 23:07:18 +0200
committertrustable-code <krauter.simon@arcor.de>2019-09-23 23:07:18 +0200
commit9d9babe7491f791545ddb7730a573e9b21cd3fa6 (patch)
tree75d42e1e10eccb196127b48c43e455678f690578 /src/nigui/private
parent20b7e0cdcbcf571c4bed1dc0460feff73be110e0 (diff)
downloadNiGui-9d9babe7491f791545ddb7730a573e9b21cd3fa6.tar.gz
NiGui-9d9babe7491f791545ddb7730a573e9b21cd3fa6.zip
Extend Checkbox and add Gtk implementation
- Add `checked=` to set the status - Add `onToggle` event to react on toggle by the user - Toggling works also by Space and Enter
Diffstat (limited to 'src/nigui/private')
-rwxr-xr-xsrc/nigui/private/gtk3/gtk3.nim14
-rwxr-xr-xsrc/nigui/private/gtk3/platform_impl.nim46
-rwxr-xr-xsrc/nigui/private/gtk3/platform_types2.nim2
-rwxr-xr-xsrc/nigui/private/windows/platform_impl.nim21
-rwxr-xr-xsrc/nigui/private/windows/windows.nim10
5 files changed, 89 insertions, 4 deletions
diff --git a/src/nigui/private/gtk3/gtk3.nim b/src/nigui/private/gtk3/gtk3.nim
index d7d9a1c..bb41873 100755
--- a/src/nigui/private/gtk3/gtk3.nim
+++ b/src/nigui/private/gtk3/gtk3.nim
@@ -210,6 +210,14 @@ const
GDK_WINDOW_STATE_FOCUSED* = 128
GDK_WINDOW_STATE_TILED* = 256
+ # GSignalMatchType:
+ G_SIGNAL_MATCH_ID* = 1
+ G_SIGNAL_MATCH_DETAIL* = 2
+ G_SIGNAL_MATCH_CLOSURE* = 4
+ G_SIGNAL_MATCH_FUNC* = 8
+ G_SIGNAL_MATCH_DATA* = 16
+ G_SIGNAL_MATCH_UNBLOCKED* = 16
+
# ----------------------------------------------------------------------------------------
# General Gtk Procs
@@ -228,6 +236,8 @@ proc gtk_main_iteration*(): cint {.importc: "gtk_main_iteration", libgtk3.}
proc g_timeout_add*(interval: cint, function, data: pointer): cint {.importc: "g_timeout_add", libgtk3.}
proc g_source_remove*(tag: cint): bool {.importc: "g_source_remove", libgtk3.}
proc g_signal_connect_data*(instance: pointer, detailed_signal: cstring, c_handler: pointer, data, destroy_data, connect_flags: pointer = nil): pointer {.importc: "g_signal_connect_data", libgtk3.}
+proc g_signal_handlers_block_matched*(instance: pointer, mask, signal_id: cint, detail, closure, function, data: pointer = nil) {.importc: "g_signal_handlers_block_matched", libgtk3.}
+proc g_signal_handlers_unblock_matched*(instance: pointer, mask, signal_id: cint, detail, closure, function, data: pointer = nil) {.importc: "g_signal_handlers_unblock_matched", libgtk3.}
proc gtk_window_new*(`type`: cint): pointer {.importc: "gtk_window_new", libgtk3.}
proc gtk_window_set_title*(window: pointer, title: cstring) {.importc: "gtk_window_set_title", libgtk3.}
@@ -326,6 +336,10 @@ proc gtk_button_new*(): pointer {.importc: "gtk_button_new", libgtk3.}
# proc gtk_button_get_label*(button: pointer): cstring {.importc: "gtk_button_get_label", libgtk3.}
proc gtk_button_set_label*(button: pointer, label: cstring) {.importc: "gtk_button_set_label", libgtk3.}
+proc gtk_check_button_new*(): pointer {.importc: "gtk_check_button_new", libgtk3.}
+proc gtk_toggle_button_set_active*(toggle_button: pointer, is_active: bool) {.importc: "gtk_toggle_button_set_active", libgtk3.}
+proc gtk_toggle_button_get_active*(toggle_button: pointer): bool {.importc: "gtk_toggle_button_get_active", libgtk3.}
+
proc gtk_entry_new*(): pointer {.importc: "gtk_entry_new", libgtk3.}
proc gtk_entry_set_text*(entry: pointer, text: cstring) {.importc: "gtk_entry_set_text", libgtk3.}
proc gtk_entry_get_text*(entry: pointer): cstring {.importc: "gtk_entry_get_text", libgtk3.}
diff --git a/src/nigui/private/gtk3/platform_impl.nim b/src/nigui/private/gtk3/platform_impl.nim
index 4aeb4ea..80e7cd0 100755
--- a/src/nigui/private/gtk3/platform_impl.nim
+++ b/src/nigui/private/gtk3/platform_impl.nim
@@ -1282,6 +1282,52 @@ method `enabled=`(button: NativeButton, enabled: bool) =
# ----------------------------------------------------------------------------------------
+# Checkbox
+# ----------------------------------------------------------------------------------------
+
+proc pControlToggledSignal(widget: pointer, data: pointer): bool {.cdecl.} =
+ let control = cast[Checkbox](data)
+ var evt = new ToggleEvent
+ evt.control = control
+ try:
+ control.handleToggleEvent(evt)
+ except:
+ handleException()
+
+proc init(checkbox: NativeCheckbox) =
+ checkbox.fHandle = gtk_check_button_new()
+ discard g_signal_connect_data(checkbox.fHandle, "toggled", pControlToggledSignal, cast[pointer](checkbox))
+ checkbox.Checkbox.init()
+ gtk_widget_show(checkbox.fHandle)
+
+method `text=`(checkbox: NativeCheckbox, text: string) =
+ procCall checkbox.Checkbox.`text=`(text)
+ gtk_button_set_label(checkbox.fHandle, text)
+ app.processEvents()
+
+method naturalWidth(checkbox: NativeCheckbox): int =
+ # Override parent method, to make it big enough for the text to fit in.
+ var context = gtk_widget_get_style_context(checkbox.fHandle)
+ var padding: GtkBorder
+ gtk_style_context_get_padding(context, GTK_STATE_FLAG_NORMAL, padding)
+ result = checkbox.getTextLineWidth(checkbox.text) + padding.left + padding.right + 25.scaleToDpi
+
+method `enabled=`(checkbox: NativeCheckbox, enabled: bool) =
+ checkbox.fEnabled = enabled
+ gtk_widget_set_sensitive(checkbox.fHandle, enabled)
+
+method checked(checkbox: NativeCheckbox): bool =
+ result = gtk_toggle_button_get_active(checkbox.fHandle)
+
+method `checked=`(checkbox: NativeCheckbox, checked: bool) =
+ g_signal_handlers_block_matched(checkbox.fHandle, G_SIGNAL_MATCH_FUNC, 0, nil, nil, pControlToggledSignal)
+ gtk_toggle_button_set_active(checkbox.fHandle, checked)
+ g_signal_handlers_unblock_matched(checkbox.fHandle, G_SIGNAL_MATCH_FUNC, 0, nil, nil, pControlToggledSignal)
+
+method pAddButtonPressEvent(checkbox: NativeCheckbox) = discard # don't override default handler
+
+
+# ----------------------------------------------------------------------------------------
# Label
# ----------------------------------------------------------------------------------------
diff --git a/src/nigui/private/gtk3/platform_types2.nim b/src/nigui/private/gtk3/platform_types2.nim
index 5faa8b6..12cf897 100755
--- a/src/nigui/private/gtk3/platform_types2.nim
+++ b/src/nigui/private/gtk3/platform_types2.nim
@@ -11,6 +11,8 @@ type
NativeButton* = ref object of Button
+ NativeCheckbox* = ref object of Checkbox
+
NativeLabel* = ref object of Label
NativeTextBox* = ref object of TextBox
diff --git a/src/nigui/private/windows/platform_impl.nim b/src/nigui/private/windows/platform_impl.nim
index c94224e..d7372f4 100755
--- a/src/nigui/private/windows/platform_impl.nim
+++ b/src/nigui/private/windows/platform_impl.nim
@@ -1406,11 +1406,25 @@ method `enabled=`(button: NativeButton, enabled: bool) =
var pCheckboxOrigWndProc: pointer
proc pCheckboxWndProc(hWnd: pointer, uMsg: int32, wParam, lParam: pointer): pointer {.cdecl.} =
+ let checkbox = cast[Checkbox](pGetWindowLongPtr(hWnd, GWLP_USERDATA))
+
+ if uMsg == WM_LBUTTONDOWN:
+ checkbox.checked = not checkbox.checked # let the event see the new status
+ var evt = new ToggleEvent
+ evt.control = checkbox
+ checkbox.handleToggleEvent(evt)
+ checkbox.checked = not checkbox.checked
+
let comProcRes = pCommonControlWndProc(hWnd, uMsg, wParam, lParam)
if comProcRes == PWndProcResult_False:
return cast[pointer](false)
if comProcRes == PWndProcResult_True:
return cast[pointer](true)
+
+ # Avoid toggling the checkbox twice
+ if uMsg == WM_KEYDOWN and pWMParamsToKey(wParam, lParam) == Key_Space:
+ return
+
result = CallWindowProcW(pCheckboxOrigWndProc, hWnd, uMsg, wParam, lParam)
proc init(checkbox: NativeCheckbox) =
@@ -1429,6 +1443,13 @@ method `enabled=`(checkbox: NativeCheckbox, enabled: bool) =
method checked(checkbox: NativeCheckbox): bool =
result = cast[int](SendMessageA(checkbox.fHandle, BM_GETCHECK, nil, nil)) == BST_CHECKED
+method `checked=`(checkbox: NativeCheckbox, checked: bool) =
+ if checked:
+ discard SendMessageA(checkbox.fHandle, BM_SETCHECK, cast[pointer](BST_CHECKED), nil)
+ else:
+ discard SendMessageA(checkbox.fHandle, BM_SETCHECK, cast[pointer](BST_UNCHECKED), nil)
+ # app.processEvents
+
# ----------------------------------------------------------------------------------------
# Label
diff --git a/src/nigui/private/windows/windows.nim b/src/nigui/private/windows/windows.nim
index d271cac..df9e75a 100755
--- a/src/nigui/private/windows/windows.nim
+++ b/src/nigui/private/windows/windows.nim
@@ -37,12 +37,14 @@ const
BN_CLICKED* = 0
BM_SETSTYLE* = 244
BM_SETIMAGE* = 247
- BM_GETCHECK* = 0x00F0
+ BM_GETCHECK* = 240
+ BM_SETCHECK* = 241
+ BM_GETSTATE* = 242
BS_DEFPUSHBUTTON* = 0x00000001
BS_AUTOCHECKBOX* = 0x00000003
BS_GROUPBOX* = 0x00000007
- BST_UNCHECKED* = 0x0000
- BST_CHECKED* = 0x0001
+ BST_UNCHECKED* = 0
+ BST_CHECKED* = 1
CF_TEXT* = 1
COLOR_BTNFACE* = 15
COLOR_WINDOW* = 5
@@ -548,4 +550,4 @@ proc GetSaveFileNameW*(lpofn: var OpenFileName): bool {.importc: "GetSaveFileNam
# Shcore Procs
# ----------------------------------------------------------------------------------------
-type SetProcessDpiAwarenessType* = proc(value: int32): int32 {.gcsafe, stdcall.} # not available on Windows 7 \ No newline at end of file
+type SetProcessDpiAwarenessType* = proc(value: int32): int32 {.gcsafe, stdcall.} # not available on Windows 7