From 5c6694717b144452f26bb6ceb967ad02cfee0f46 Mon Sep 17 00:00:00 2001 From: PhilippMDoerner Date: Sat, 21 Oct 2023 22:52:05 +0100 Subject: [PATCH] Refactor bindings into a bindings directory and move adw.nim bindings into their own module * Move gtk.nim into bindings dir * Refactor adwaita bindings into a binding module * Re export bound enums * Add SearchEntry widget * Add Search Entry Widget * Add text field to searchEntry widget * Add missing text hook * Improve search entry example * Further improve example * Refine which fields you shouldn't have access to * Add activity to when you stop a search * Add activity to when you stop a search * Fix search entry displaying weird spacing * Unify GtkMinor into a single constant * Debug change Attempt to cat out the gtk.nim file to see how the hell it is getting the impression that GtkMinor is defined twice. * Move GtkMInor before the passL flag is passed? Maybe this fixes the problem with the pipeline sudenly thinking that value was defined twice. * Unto test-pipeline debug change * Comment out unsupported search thingy * Minor tweaks - Removed searchstring parameter from callbacks - made sure only changed callback can modify search value - Updated example - Moved example to far nicer looking ListBox * Remove unnecessary Box * Update examples/widgets/search_entry.nim Co-authored-by: Can Lehmann <85876381+can-lehmann@users.noreply.github.com> --------- Co-authored-by: Can Lehmann <85876381+can-lehmann@users.noreply.github.com> * Add PasswordEntry widget * Add core of password entry widget * Add bindings for menu model I do not plan to act on them yet but I'd like to at least already add them so I don't have to make the effort later * Update password entry docs * Improve gitignore * Use unsafeAddr for nim version 1.0 * Fix GValue being let instead of var * Add text field to password entry * Ensure activateEventCallback also updates state * Add missing text hook * Add way to demonstrate 2 way binding * Remove unnecessary pragma ping pong * Removed password from activate callback parameters * Add ActionBar widget * Make Centerbox orientable * Add Action Bar Widget and docs * Minor refinement to the action bar example It now actually "deletes" the contents of the label. There's also a button to reset its value. * Improve example button styling * Add examples to .gitignore * Update docs * Add license to adw.nim bindings --------- Co-authored-by: Can Lehmann --- book/internals/hooks/after_build_hook.nim | 2 +- book/internals/hooks/before_build_hook.nim | 2 +- book/internals/hooks/build_hook.nim | 2 +- book/internals/hooks/event_hooks.nim | 4 +- book/internals/hooks/read_hook.nim | 3 +- owlkettle.nim | 3 +- owlkettle/adw.nim | 151 +------------------ owlkettle/bindings/adw.nim | 165 +++++++++++++++++++++ owlkettle/{ => bindings}/gtk.nim | 2 +- owlkettle/mainloop.nim | 3 +- owlkettle/widgetdef.nim | 3 +- owlkettle/widgets.nim | 3 +- owlkettle/widgetutils.nim | 3 +- 13 files changed, 192 insertions(+), 154 deletions(-) create mode 100644 owlkettle/bindings/adw.nim rename owlkettle/{ => bindings}/gtk.nim (99%) diff --git a/book/internals/hooks/after_build_hook.nim b/book/internals/hooks/after_build_hook.nim index bfb93441..5422e943 100644 --- a/book/internals/hooks/after_build_hook.nim +++ b/book/internals/hooks/after_build_hook.nim @@ -15,7 +15,7 @@ Let's return to our earlier renderable example and write it so that the parent-w nbCode: import owlkettle - import owlkettle/gtk + import owlkettle/bindings/gtk import std/json renderable MyRenderable: diff --git a/book/internals/hooks/before_build_hook.nim b/book/internals/hooks/before_build_hook.nim index fb5e227a..e484e2cc 100644 --- a/book/internals/hooks/before_build_hook.nim +++ b/book/internals/hooks/before_build_hook.nim @@ -14,7 +14,7 @@ Here a simple code-example for writing a `beforeBuild` hook: nbCode: import owlkettle - import owlkettle/gtk + import owlkettle/bindings/gtk import std/json renderable MyRenderable: diff --git a/book/internals/hooks/build_hook.nim b/book/internals/hooks/build_hook.nim index 27043151..1e830854 100644 --- a/book/internals/hooks/build_hook.nim +++ b/book/internals/hooks/build_hook.nim @@ -27,7 +27,7 @@ nbCode: # main.nim import std/json import owlkettle - import owlkettle/gtk + import owlkettle/bindings/gtk type Config = object name: string diff --git a/book/internals/hooks/event_hooks.nim b/book/internals/hooks/event_hooks.nim index b7dd2f69..b73adbf3 100644 --- a/book/internals/hooks/event_hooks.nim +++ b/book/internals/hooks/event_hooks.nim @@ -14,7 +14,9 @@ Here a minimal example of a custom button widget that provides a `clicked` event nbCode: import owlkettle import std/tables - import owlkettle/[widgetutils, gtk] + import owlkettle/widgetutils + import owlkettle/bindings/gtk + renderable MyButton of BaseWidget: proc clicked() diff --git a/book/internals/hooks/read_hook.nim b/book/internals/hooks/read_hook.nim index 2a674e5d..07b130b9 100644 --- a/book/internals/hooks/read_hook.nim +++ b/book/internals/hooks/read_hook.nim @@ -12,7 +12,8 @@ Let's look at a minimal example from the `ColorChooserDialog` widget: nbCode: import owlkettle - import owlkettle/[gtk, widgetdef] + import owlkettle/widgetdef + import owlkettle/bindings/gtk # The custom widget renderable MyColorChooserDialog of BuiltinDialog: diff --git a/owlkettle.nim b/owlkettle.nim index 27fd82d3..725f76b2 100644 --- a/owlkettle.nim +++ b/owlkettle.nim @@ -20,7 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import owlkettle/[gtk, widgetutils, widgetdef, widgets, guidsl, mainloop] +import owlkettle/[widgetutils, widgetdef, widgets, guidsl, mainloop] +import owlkettle/bindings/gtk export widgetdef except build_bin, update_bin export widgets, guidsl export Align diff --git a/owlkettle/adw.nim b/owlkettle/adw.nim index c951b5b2..3cd444a3 100644 --- a/owlkettle/adw.nim +++ b/owlkettle/adw.nim @@ -24,156 +24,21 @@ when defined(nimPreviewSlimSystem): import std/assertions -import gtk, widgetdef, widgets, mainloop, widgetutils +import widgetdef, widgets, mainloop, widgetutils +import ./bindings/[adw, gtk] + +export adw.StyleManager +export adw.ColorScheme +export adw.FlapFoldPolicy +export adw.FoldThresholdPolicy +export adw.FlapTransitionType when defined(owlkettleDocs) and isMainModule: echo "# Libadwaita Widgets\n\n" -const AdwMajor {.intdefine: "adwmajor".}: int = 1 ## Specifies the minimum Adwaita major version required to run an application. Overwriteable via `-d:adwmajor=X`. Defaults to 1. -const AdwMinor {.intdefine: "adwminor".}: int = 0 ## Specifies the minimum Adwaita minor version required to run an application. Overwriteable via `-d:adwinor=X`. Defaults to 0. -const AdwVersion = (AdwMajor, AdwMinor) - -{.passl: "-ladwaita-1".} - -type - StyleManager = distinct pointer - - ColorScheme* = enum - ColorSchemeDefault, - ColorSchemeForceLight, - ColorSchemeForceDark, - ColorSchemePreferDark, - ColorSchemePreferLight - - FlapFoldPolicy* = enum - FlapFoldNever, - FlapFoldAlways, - FlapFoldAuto - - FoldThresholdPolicy* = enum - FoldThresholdMinimum, - FoldThresholdNatural - - FlapTransitionType* = enum - FlapTransitionOver - FlapTransitionUnder - FlapTransitionSlide - -{.push importc, cdecl.} -# Adw -proc adw_init() - -# Adw.StyleManager -proc adw_style_manager_get_default(): StyleManager -proc adw_style_manager_set_color_scheme(manager: StyleManager, colorScheme: ColorScheme) - -# Adw.Window -proc adw_window_new(): GtkWidget -proc adw_window_set_content(window, content: GtkWidget) - -# Adw.WindowTitle -proc adw_window_title_new(title, subtitle: cstring): GtkWidget -proc adw_window_title_set_title(widget: GtkWidget, title: cstring) -proc adw_window_title_set_subtitle(widget: GtkWidget, subtitle: cstring) - -# Adw.Avatar -proc adw_avatar_new(size: cint, text: cstring, showInitials: cbool): GtkWidget -proc adw_avatar_set_show_initials(avatar: GtkWidget, value: cbool) -proc adw_avatar_set_size(avatar: GtkWidget, size: cint) -proc adw_avatar_set_text(avatar: GtkWidget, text: cstring) -proc adw_avatar_set_icon_name(avatar: GtkWidget, iconName: cstring) - -# Adw.Clamp -proc adw_clamp_new(): GtkWidget -proc adw_clamp_set_child(clamp, child: GtkWidget) -proc adw_clamp_set_maximum_size(clamp: GtkWidget, size: cint) - -# Adw.PreferencesGroup -proc adw_preferences_group_new(): GtkWidget -proc adw_preferences_group_add(group, child: GtkWidget) -proc adw_preferences_group_remove(group, child: GtkWidget) -proc adw_preferences_group_set_header_suffix(group, child: GtkWidget) -proc adw_preferences_group_set_description(group: GtkWidget, descr: cstring) -proc adw_preferences_group_set_title(group: GtkWidget, title: cstring) - -# Adw.PreferencesRow -proc adw_preferences_row_new(): GtkWidget -proc adw_preferences_row_set_title(row: GtkWidget, title: cstring) - -# Adw.ActionRow -proc adw_action_row_new(): GtkWidget -proc adw_action_row_set_subtitle(row: GtkWidget, subtitle: cstring) -proc adw_action_row_add_prefix(row, child: GtkWidget) -proc adw_action_row_add_suffix(row, child: GtkWidget) -proc adw_action_row_remove(row, child: GtkWidget) -proc adw_action_row_set_activatable_widget(row, child: GtkWidget) - -# Adw.ExpanderRow -proc adw_expander_row_new(): GtkWidget -proc adw_expander_row_set_subtitle(row: GtkWidget, subtitle: cstring) -proc adw_expander_row_add_action(row, child: GtkWidget) -proc adw_expander_row_add_prefix(row, child: GtkWidget) -proc adw_expander_row_add_row(expanderRow, row: GtkWidget) -proc adw_expander_row_remove(row, child: GtkWidget) - -# Adw.ComboRow -proc adw_combo_row_new(): GtkWidget -proc adw_combo_row_set_model*(comboRow: GtkWidget, model: GListModel) -proc adw_combo_row_set_selected*(comboRow: GtkWidget, selected: cuint) -proc adw_combo_row_get_selected*(comboRow: GtkWidget): cuint - -when AdwVersion >= (1, 2): - # Adw.EntryRow - proc adw_entry_row_new(): GtkWidget - proc adw_entry_row_add_suffix(row, child: GtkWidget) - proc adw_entry_row_remove(row, child: GtkWidget) - -# Adw.Flap -proc adw_flap_new(): GtkWidget -proc adw_flap_set_content(flap, content: GtkWidget) -proc adw_flap_set_flap(flap, child: GtkWidget) -proc adw_flap_set_separator(flap, child: GtkWidget) -proc adw_flap_set_fold_policy(flap: GtkWidget, foldPolicy: FlapFoldPolicy) -proc adw_flap_set_fold_threshold_policy(flap: GtkWidget, foldThresholdPolicy: FoldThresholdPolicy) -proc adw_flap_set_transition_type(flap: GtkWidget, transitionType: FlapTransitionType) -proc adw_flap_set_reveal_flap(flap: GtkWidget, revealed: cbool) -proc adw_flap_set_modal(flap: GtkWidget, modal: cbool) -proc adw_flap_set_locked(flap: GtkWidget, locked: cbool) -proc adw_flap_set_swipe_to_open(flap: GtkWidget, swipe: cbool) -proc adw_flap_set_swipe_to_close(flap: GtkWidget, swipe: cbool) -proc adw_flap_get_reveal_flap(flap: GtkWidget): cbool -proc adw_flap_get_folded(flap: GtkWidget): cbool - -# Adw.SplitButton -proc adw_split_button_new(): GtkWidget -proc adw_split_button_set_child(button, child: GtkWidget) -proc adw_split_button_set_popover(button, child: GtkWidget) - -# Adw.StatusPage -proc adw_status_page_new(): GtkWidget -proc adw_status_page_set_child(self: GtkWidget, child: GtkWidget) -proc adw_status_page_set_description(self: GtkWidget, description: cstring) -proc adw_status_page_set_icon_name(self: GtkWidget, icon_name: cstring) -proc adw_status_page_set_paintable(self: GtkWidget, paintable: GtkWidget) -proc adw_status_page_set_title(self: GtkWidget, title: cstring) - -when AdwVersion >= (1, 2): - # Adw.AboutWindow - proc adw_about_window_new(): GtkWidget - proc adw_about_window_set_application_name(window: GtkWidget, value: cstring) - proc adw_about_window_set_developer_name(window: GtkWidget, value: cstring) - proc adw_about_window_set_version(window: GtkWidget, value: cstring) - proc adw_about_window_set_support_url(window: GtkWidget, value: cstring) - proc adw_about_window_set_issue_url(window: GtkWidget, value: cstring) - proc adw_about_window_set_website(window: GtkWidget, value: cstring) - proc adw_about_window_set_copyright(window: GtkWidget, value: cstring) - proc adw_about_window_set_license(window: GtkWidget, value: cstring) -{.pop.} - renderable WindowSurface of BaseWindow: ## A Window that does not have a title bar. ## A WindowSurface is equivalent to an `Adw.Window`. - content: Widget hooks: diff --git a/owlkettle/bindings/adw.nim b/owlkettle/bindings/adw.nim new file mode 100644 index 00000000..59114f46 --- /dev/null +++ b/owlkettle/bindings/adw.nim @@ -0,0 +1,165 @@ +# MIT License +# +# Copyright (c) 2022 Can Joshua Lehmann +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Bindings for Adwaita + +import ./gtk + +const AdwMajor {.intdefine: "adwmajor".}: int = 1 ## Specifies the minimum Adwaita major version required to run an application. Overwriteable via `-d:adwmajor=X`. Defaults to 1. +const AdwMinor {.intdefine: "adwminor".}: int = 0 ## Specifies the minimum Adwaita minor version required to run an application. Overwriteable via `-d:adwinor=X`. Defaults to 0. +const AdwVersion* = (AdwMajor, AdwMinor) + +{.passl: "-ladwaita-1".} + +type + StyleManager* = distinct pointer + + ColorScheme* = enum + ColorSchemeDefault, + ColorSchemeForceLight, + ColorSchemeForceDark, + ColorSchemePreferDark, + ColorSchemePreferLight + + FlapFoldPolicy* = enum + FlapFoldNever, + FlapFoldAlways, + FlapFoldAuto + + FoldThresholdPolicy* = enum + FoldThresholdMinimum, + FoldThresholdNatural + + FlapTransitionType* = enum + FlapTransitionOver + FlapTransitionUnder + FlapTransitionSlide + +{.push importc, cdecl.} +# Adw +proc adw_init*() + +# Adw.StyleManager +proc adw_style_manager_get_default*(): StyleManager +proc adw_style_manager_set_color_scheme*(manager: StyleManager, colorScheme: ColorScheme) + +# Adw.Window +proc adw_window_new*(): GtkWidget +proc adw_window_set_content*(window, content: GtkWidget) + +# Adw.WindowTitle +proc adw_window_title_new*(title, subtitle: cstring): GtkWidget +proc adw_window_title_set_title*(widget: GtkWidget, title: cstring) +proc adw_window_title_set_subtitle*(widget: GtkWidget, subtitle: cstring) + +# Adw.Avatar +proc adw_avatar_new*(size: cint, text: cstring, showInitials: cbool): GtkWidget +proc adw_avatar_set_show_initials*(avatar: GtkWidget, value: cbool) +proc adw_avatar_set_size*(avatar: GtkWidget, size: cint) +proc adw_avatar_set_text*(avatar: GtkWidget, text: cstring) +proc adw_avatar_set_icon_name*(avatar: GtkWidget, iconName: cstring) + +# Adw.Clamp +proc adw_clamp_new*(): GtkWidget +proc adw_clamp_set_child*(clamp, child: GtkWidget) +proc adw_clamp_set_maximum_size*(clamp: GtkWidget, size: cint) + +# Adw.PreferencesGroup +proc adw_preferences_group_new*(): GtkWidget +proc adw_preferences_group_add*(group, child: GtkWidget) +proc adw_preferences_group_remove*(group, child: GtkWidget) +proc adw_preferences_group_set_header_suffix*(group, child: GtkWidget) +proc adw_preferences_group_set_description*(group: GtkWidget, descr: cstring) +proc adw_preferences_group_set_title*(group: GtkWidget, title: cstring) + +# Adw.PreferencesRow +proc adw_preferences_row_new*(): GtkWidget +proc adw_preferences_row_set_title*(row: GtkWidget, title: cstring) + +# Adw.ActionRow +proc adw_action_row_new*(): GtkWidget +proc adw_action_row_set_subtitle*(row: GtkWidget, subtitle: cstring) +proc adw_action_row_add_prefix*(row, child: GtkWidget) +proc adw_action_row_add_suffix*(row, child: GtkWidget) +proc adw_action_row_remove*(row, child: GtkWidget) +proc adw_action_row_set_activatable_widget*(row, child: GtkWidget) + +# Adw.ExpanderRow +proc adw_expander_row_new*(): GtkWidget +proc adw_expander_row_set_subtitle*(row: GtkWidget, subtitle: cstring) +proc adw_expander_row_add_action*(row, child: GtkWidget) +proc adw_expander_row_add_prefix*(row, child: GtkWidget) +proc adw_expander_row_add_row*(expanderRow, row: GtkWidget) +proc adw_expander_row_remove*(row, child: GtkWidget) + +# Adw.ComboRow +proc adw_combo_row_new*(): GtkWidget +proc adw_combo_row_set_model*(comboRow: GtkWidget, model: GListModel) +proc adw_combo_row_set_selected*(comboRow: GtkWidget, selected: cuint) +proc adw_combo_row_get_selected*(comboRow: GtkWidget): cuint + +when AdwVersion >= (1, 2): + # Adw.EntryRow + proc adw_entry_row_new*(): GtkWidget + proc adw_entry_row_add_suffix*(row, child: GtkWidget) + proc adw_entry_row_remove*(row, child: GtkWidget) + +# Adw.Flap +proc adw_flap_new*(): GtkWidget +proc adw_flap_set_content*(flap, content: GtkWidget) +proc adw_flap_set_flap*(flap, child: GtkWidget) +proc adw_flap_set_separator*(flap, child: GtkWidget) +proc adw_flap_set_fold_policy*(flap: GtkWidget, foldPolicy: FlapFoldPolicy) +proc adw_flap_set_fold_threshold_policy*(flap: GtkWidget, foldThresholdPolicy: FoldThresholdPolicy) +proc adw_flap_set_transition_type*(flap: GtkWidget, transitionType: FlapTransitionType) +proc adw_flap_set_reveal_flap*(flap: GtkWidget, revealed: cbool) +proc adw_flap_set_modal*(flap: GtkWidget, modal: cbool) +proc adw_flap_set_locked*(flap: GtkWidget, locked: cbool) +proc adw_flap_set_swipe_to_open*(flap: GtkWidget, swipe: cbool) +proc adw_flap_set_swipe_to_close*(flap: GtkWidget, swipe: cbool) +proc adw_flap_get_reveal_flap*(flap: GtkWidget): cbool +proc adw_flap_get_folded*(flap: GtkWidget): cbool + +# Adw.SplitButton +proc adw_split_button_new*(): GtkWidget +proc adw_split_button_set_child*(button, child: GtkWidget) +proc adw_split_button_set_popover*(button, child: GtkWidget) + +# Adw.StatusPage +proc adw_status_page_new*(): GtkWidget +proc adw_status_page_set_child*(self: GtkWidget, child: GtkWidget) +proc adw_status_page_set_description*(self: GtkWidget, description: cstring) +proc adw_status_page_set_icon_name*(self: GtkWidget, icon_name: cstring) +proc adw_status_page_set_paintable*(self: GtkWidget, paintable: GtkWidget) +proc adw_status_page_set_title*(self: GtkWidget, title: cstring) + +when AdwVersion >= (1, 2): + # Adw.AboutWindow + proc adw_about_window_new*(): GtkWidget + proc adw_about_window_set_application_name*(window: GtkWidget, value: cstring) + proc adw_about_window_set_developer_name*(window: GtkWidget, value: cstring) + proc adw_about_window_set_version*(window: GtkWidget, value: cstring) + proc adw_about_window_set_support_url*(window: GtkWidget, value: cstring) + proc adw_about_window_set_issue_url*(window: GtkWidget, value: cstring) + proc adw_about_window_set_website*(window: GtkWidget, value: cstring) + proc adw_about_window_set_copyright*(window: GtkWidget, value: cstring) + proc adw_about_window_set_license*(window: GtkWidget, value: cstring) diff --git a/owlkettle/gtk.nim b/owlkettle/bindings/gtk.nim similarity index 99% rename from owlkettle/gtk.nim rename to owlkettle/bindings/gtk.nim index 2a90290f..b6e596be 100644 --- a/owlkettle/gtk.nim +++ b/owlkettle/bindings/gtk.nim @@ -23,7 +23,7 @@ # Bindings for GTK 4 import std/[os] -import ./common +import ../common import std/strutils as strutils diff --git a/owlkettle/mainloop.nim b/owlkettle/mainloop.nim index 21947994..bb286650 100644 --- a/owlkettle/mainloop.nim +++ b/owlkettle/mainloop.nim @@ -20,7 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import gtk, widgetdef, common +import widgetdef, common +import bindings/gtk type StylesheetObj = object diff --git a/owlkettle/widgetdef.nim b/owlkettle/widgetdef.nim index 6c230f8e..e9245371 100644 --- a/owlkettle/widgetdef.nim +++ b/owlkettle/widgetdef.nim @@ -25,7 +25,8 @@ import std/[macros, strutils, tables] when defined(nimPreviewSlimSystem): import std/assertions -import gtk, common +import common +import bindings/gtk type Widget* = ref object of RootObj diff --git a/owlkettle/widgets.nim b/owlkettle/widgets.nim index daf3e162..ef429583 100644 --- a/owlkettle/widgets.nim +++ b/owlkettle/widgets.nim @@ -25,7 +25,8 @@ import std/[unicode, os, sets, tables, options, asyncfutures, hashes, times] when defined(nimPreviewSlimSystem): import std/assertions -import gtk, widgetdef, cairo, widgetutils, common +import widgetdef, cairo, widgetutils, common +import bindings/gtk customPragmas() when defined(owlkettleDocs) and isMainModule: diff --git a/owlkettle/widgetutils.nim b/owlkettle/widgetutils.nim index 48839e2b..68b2874c 100644 --- a/owlkettle/widgetutils.nim +++ b/owlkettle/widgetutils.nim @@ -23,7 +23,8 @@ # Utilities for wrapping widgets import std/[sets] -import gtk, widgetdef, common +import widgetdef, common +import bindings/gtk customPragmas()