From 0ffacf8a0cf75052b1a50f96b00a6e15240138c3 Mon Sep 17 00:00:00 2001 From: PhilippMDoerner Date: Tue, 17 Oct 2023 19:03:53 +0100 Subject: [PATCH] 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> --- docs/assets/examples/search_entry.png | Bin 0 -> 32560 bytes docs/widgets.md | 23 +++++++ examples/README.md | 4 ++ examples/widgets/search_entry.nim | 90 ++++++++++++++++++++++++++ owlkettle/gtk.nim | 10 ++- owlkettle/widgets.nim | 64 +++++++++++++++++- 6 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 docs/assets/examples/search_entry.png create mode 100644 examples/widgets/search_entry.nim diff --git a/docs/assets/examples/search_entry.png b/docs/assets/examples/search_entry.png new file mode 100644 index 0000000000000000000000000000000000000000..7f54b47a7c0c31e24c67997f6967b1499fb6d400 GIT binary patch literal 32560 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 Scale Widget + + Search Entry + Search Entry Widget + Text View Text View diff --git a/examples/widgets/search_entry.nim b/examples/widgets/search_entry.nim new file mode 100644 index 00000000..6d3d1a98 --- /dev/null +++ b/examples/widgets/search_entry.nim @@ -0,0 +1,90 @@ +# MIT License +# +# Copyright (c) 2023 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 + +import owlkettle, owlkettle/[playground, adw, dataentries] +import std/[strutils, sets, sequtils] + +viewable App: + searchDelay: uint = 100 + text: string = "" + placeholderText: string = "Search List" + sensitive: bool = true + tooltip: string = "" + sizeRequest: tuple[x, y: int] = (-1, -1) + + items: seq[string] = mapIt(0..<100, "Item " & $it) + filteredItems: seq[string] = mapIt(0..<100, "Item " & $it) + selected: int = 0 + +method view(app: AppState): Widget = + let isInActiveSearch = app.text != "" + result = gui: + Window(): + defaultSize = (600, 400) + HeaderBar() {.addTitlebar.}: + insert(app.toAutoFormMenu(ignoreFields = @["filteredItems"])) {.addRight.} + + SearchEntry() {.addTitle, expand: true.}: + margin = Margin(top:0, left: 48, bottom:0, right: 48) + text = app.text + searchDelay = app.searchDelay + placeholderText = app.placeholderText + sensitive = app.sensitive + tooltip = app.tooltip + sizeRequest = app.sizeRequest + + proc nextMatch() = + if app.selected < app.filteredItems.high: + app.selected += 1 + + proc previousMatch() = + if app.selected > 0: + app.selected -= 1 + + proc activate() = + echo "activated search for entry: ": $app.filteredItems[app.selected] + + proc changed(searchString: string) = + app.text = searchString + app.selected = 0 + app.filteredItems = app.items.filterIt(searchString in it) + + proc stopSearch() = + echo "Search Stopped" + app.text = "" + app.filteredItems = app.items + + ScrolledWindow: + ListBox: + selected = [app.selected].toHashSet() + selectionMode = SelectionSingle + + proc select(rows: Hashset[int]) = + for num in rows: + app.selected = num + + for index, item in app.filteredItems: + Box(): + Label(text = item, margin = 6) {.hAlign: AlignStart, expand: false.} + + +adw.brew(gui(App())) \ No newline at end of file diff --git a/owlkettle/gtk.nim b/owlkettle/gtk.nim index fcee4458..8bc6c200 100644 --- a/owlkettle/gtk.nim +++ b/owlkettle/gtk.nim @@ -27,7 +27,7 @@ import ./common import std/strutils as strutils -const GtkMinor {.intdefine: "gtkminor".}: int = 0 ## Specifies the minimum GTK4 minor version required to run an application. Overwriteable via `-d:gtkminor=X`. Defaults to 0. +const GtkMinor* {.intdefine: "gtkminor".}: int = 0 ## Specifies the minimum GTK4 minor version required to run an application. Overwriteable via `-d:gtkminor=X`. Defaults to 0. {.passl: strutils.strip(gorge("pkg-config --libs gtk4")).} @@ -881,6 +881,14 @@ proc gtk_progress_bar_set_pulse_step*(widget: GtkWidget, fraction: cdouble) proc gtk_progress_bar_set_show_text*(widget: GtkWidget, show_text: cbool) proc gtk_progress_bar_set_text*(widget: GtkWidget, text: cstring) +# Gtk.SearchEntry +proc gtk_search_entry_new*(): GtkWidget +proc gtk_search_entry_set_key_capture_widget*(widget: GtkWidget, captureWidget: GtkWidget) +when GtkMinor >= 8: + proc gtk_search_entry_set_search_delay*(widget: GtkWidget, delay: cuint) +when GtkMinor >= 10: + proc gtk_search_entry_set_placeholder_text*(widget: GtkWidget, text: cstring) + # Gtk.Stack proc gtk_stack_add_named*(stack, child: GtkWidget, name: cstring) proc gtk_stack_remove*(stack, child: GtkWidget) diff --git a/owlkettle/widgets.nim b/owlkettle/widgets.nim index ae3b668b..a436304f 100644 --- a/owlkettle/widgets.nim +++ b/owlkettle/widgets.nim @@ -31,8 +31,6 @@ customPragmas() when defined(owlkettleDocs) and isMainModule: echo "# Widgets" -const GtkMinor {.intdefine: "gtkminor".}: int = 0 ## Specifies the minimum GTK4 minor version required to run an application. Overwriteable via `-d:gtkminor=X`. Defaults to 0. - type Margin* = object top*, bottom*, left*, right*: int @@ -2067,6 +2065,67 @@ renderable ModelButton of BaseWidget: proc clicked() = echo "Clicked " & $it +renderable SearchEntry of BaseWidget: + text: string + # child: GtkWidget # This is currently not supported + searchDelay: uint = 100 ## Determines the minimum time after a `searchChanged` event occurred before the next can be emitted. Only available when compiling for gtk 4.8 + placeholderText: string = "Search" ## Only available when compiling for gtk 4.10 + + proc activate() ## Triggered when the user "activated" the search e.g. by hitting "enter" key while SearchEntry is in focus. + proc nextMatch() ## Triggered when the user hits the "next entry" keybinding while the search entry is in focus, which is Ctrl-g by default. + proc previousMatch() ## Triggered when the user hits the "previous entry" keybinding while the search entry is in focus, which is Ctrl-Shift-g by default. + proc changed(searchString: string) ## Triggered when the user types in the SearchEntry. + # proc searchStarted() # Currently not supported + proc stopSearch() ## Triggered when the user "stops" a search, e.g. by hitting the "Esc" key while SearchEntry is in focus. + + hooks: + beforeBuild: + state.internalWidget = gtk_search_entry_new() + connectEvents: + proc changedCallback(widget: GtkWidget, data: ptr EventObj[proc(searchString: string)]) = + let searchString = $gtk_editable_get_text(widget) + SearchEntryState(data[].widget).text = searchString + data[].callback(searchString) + data[].redraw() + + state.connect(state.activate, "activate", eventCallback) + state.connect(state.nextMatch, "next-match", eventCallback) + state.connect(state.previousMatch, "previous-match", eventCallback) + state.connect(state.changed, "search-changed", changedCallback) + # state.connect(state.searchStarted, "search-changed", eventCallback) # Currently not supported + state.connect(state.stopSearch, "stop-search", eventCallback) + disconnectEvents: + state.internalWidget.disconnect(state.activate) + state.internalWidget.disconnect(state.nextMatch) + state.internalWidget.disconnect(state.previousMatch) + state.internalWidget.disconnect(state.changed) + # state.internalWidget.disconnect(state.searchStarted) # Currently not supported + state.internalWidget.disconnect(state.stopSearch) + + # hooks child: + # property: + # gtk_search_entry_set_key_capture_widget(state.internalWidget, state.child.pointer) + + hooks text: + property: + gtk_editable_set_text(state.internalWidget, state.text.cstring) + read: + state.text = $gtk_editable_get_text(state.internalWidget) + + hooks searchDelay: + property: + when GtkMinor >= 8: + gtk_search_entry_set_search_delay(state.internalWidget, state.searchDelay.cuint) + else: + discard + + hooks placeholderText: + property: + when GtkMinor >= 10: + gtk_search_entry_set_placeholder_text(state.internalWidget, state.placeholderText.cstring) + else: + discard + renderable Separator of BaseWidget: ## A separator line. @@ -4048,6 +4107,7 @@ export AboutDialog, AboutDialogState export buildState, updateState, assignAppEvents export Scale export Expander +export SearchEntry export Video export ProgressBar export EmojiChooser