Browse Source

Added filter focus attempts, mixed in open file

filter-focus
Macoy Madson 1 month ago
parent
commit
84ff2b3c4b
  1. 105
      src/FileHelper.cake

105
src/FileHelper.cake

@ -18,7 +18,7 @@
&comptime-only
"CHelpers.cake")
(c-import "SDL.h" "SDL_syswm.h" "SDL_timer.h" "<stdio.h>")
(c-import "SDL.h" "SDL_syswm.h" "SDL_timer.h" "<stdio.h>" "imgui_internal.h")
;; TODO: Somehow inherit this from SDL.cake?
(module-use-sdl-build-options)
@ -163,6 +163,21 @@
color ([] 3 float)
is-inherited bool)
(defstruct-local custom-imgui-text-filter
filter ([] 128 char))
(defun-local imgui-draw-imgui-text-filter (filter (* custom-imgui-text-filter))
;; This is a hack to get the desired focus behavior: Don't allow imgui to use regular Enter
;; behavior because it makes it difficult to get the field focused again
(var flags ImGuiInputTextFlags ImGuiInputTextFlags_CtrlEnterForNewLine)
(imgui-call InputText "Filter" (path filter > filter) (sizeof (path filter > filter))))
;; (ImVec2 (- FLT_MIN) (* (imgui-call GetTextLineHeight) 2))
;; flags))
(defun-local imgui-passes-text-filter (filter (* custom-imgui-text-filter)
item (* (const char))
&return bool)
(return true))
(defstruct-local imgui-directory-listing-state
current-dir dynstring
needs-update bool
@ -176,8 +191,9 @@
filtered-entries (* int) ;; Indices into directory-entries and other arrays
on-activate-index int
directory-filter ImGuiTextFilter
directory-filter custom-imgui-text-filter
focus-filter bool
try-focus-frames-remaining int
was-window-focused bool
is-deleting-filter-text bool
@ -192,6 +208,12 @@
mouse-last-frame Uint32
keys-last-frame (* (unsigned char)))
(defun-local focus-directory-listing-filter (state (* imgui-directory-listing-state))
(var num-focus-retries (const float) 2)
(set (path state > focus-filter) true)
(unless (path state > try-focus-frames-remaining)
(set (path state > try-focus-frames-remaining) num-focus-retries)))
;; TODO Auto-generate this
(defun-local destroy-directory-state (state (* imgui-directory-listing-state))
(dynarray-free (path state > keys-last-frame))
@ -318,13 +340,20 @@
state (* imgui-directory-listing-state))
(if (path activated-entry > is-directory)
(scope
(set (path state > focus-filter) true)
(focus-directory-listing-filter state)
(path-append-divider-if-necessary (addr (path state > current-dir)))
(dynstring-append (addr (path state > current-dir)) (path activated-entry > name))
(set (path state > needs-update) true)
(set (path state > should-scroll-to-entry) true)
(set (path state > on-activate-index) 0))
(scope (set (path state > focus-filter) true))))
(scope
(focus-directory-listing-filter state)
(var open-file-str dynstring null)
(dynstring-append (addr open-file-str) (path state > current-dir))
(path-append-divider-if-necessary (addr open-file-str))
(dynstring-append (addr open-file-str) (path activated-entry > name))
(open-system-file-explorer open-file-str)
(dynarray-free open-file-str))))
(defun-local set-auto-focus-child-entry (state (* imgui-directory-listing-state)
auto-select-entry-start (* (const char)))
@ -335,7 +364,7 @@
auto-select-entry-start))
(defun-local goto-parent-directory (state (* imgui-directory-listing-state))
(set (path state > focus-filter) true)
(focus-directory-listing-filter state)
(set (path state > on-activate-index) 0)
(var next-path dynstring null)
@ -360,8 +389,8 @@
(tokenize-push output
(each-item-addr-in-dynarray (token-splice entries-dynarray)
(token-splice index) (token-splice entry-it) (* directory-entry)
(unless (call-on PassFilter (token-splice filter)
(path (token-splice entry-it) > name))
(unless (imgui-passes-text-filter (addr (token-splice filter))
(path (token-splice entry-it) > name))
(continue))
(token-splice-rest body tokens)))
(return true))
@ -471,10 +500,10 @@
(path-append-divider-if-necessary path)
(dynstring-append path file-or-dir-name))
(defun open-system-file-explorer (in-directory (* (const char)))
(defun open-system-file-explorer (in-path (* (const char)))
(var url-current-directory ([] 1024 char) (array 0))
(snprintf url-current-directory (sizeof url-current-directory) "file://%s"
in-directory)
in-path)
(SDL_OpenURL url-current-directory))
(defstruct-local imgui-approximate-wrap-state
@ -556,7 +585,7 @@
;; Latch filter focus based on whether the window was just re-focused
(unless (path state > was-window-focused)
(when is-window-focused
(set (path state > focus-filter) true)))
(focus-directory-listing-filter state)))
(set (path state > was-window-focused) is-window-focused)
(scope ;; History buttons
@ -597,10 +626,9 @@
(when (and (imgui-call Selectable drive-label)
;; Prevent unnecessary updating if they pick the same dir
(!= drive current-dir-drive))
;; TODO: Select drive
(dynstring-printf (addr (path state > current-dir)) "%c:" drive)
(set (path state > needs-update) true)
(set (path state > focus-filter) true))
(focus-directory-listing-filter state))
(when (= drive current-dir-drive)
(imgui-call SetItemDefaultFocus)))
(imgui-call EndCombo)))))
@ -621,7 +649,7 @@
(dynarray-clear (path state > current-dir))
(dynstring-append (addr (path state > current-dir)) (path subpath > full-path))
(set (path state > needs-update) true)
(set (path state > focus-filter) true))
(focus-directory-listing-filter state))
(imgui-call PopID)
(imgui-approximate-wrap-after-element (addr wrap-state)))
(dynarray-free divided-path))
@ -678,7 +706,7 @@
(when (and backspace-pressed
(not (path state > is-deleting-filter-text)))
(set (path state > is-deleting-filter-text)
(call-on IsActive (path state > directory-filter)))
(at 0 (path state > directory-filter . filter)))
(when (not (path state > is-deleting-filter-text))
(goto-parent-directory state)))
@ -745,14 +773,28 @@
(when (and (field imgui-io KeyCtrl)
(is-key-tapped-this-frame SDL_SCANCODE_F current-key-states
(path state > keys-last-frame)))
(set (path state > focus-filter) true))
(focus-directory-listing-filter state))
(when (path state > focus-filter)
;; (fprintf stderr "Focus filter is set. g-is-first-time-run %s (imgui-call IsAnyItemActive) %s\n"
;; (? g-is-first-time-run "true" "false")
;; (? (imgui-call IsAnyItemActive) "true" "false"))
(unless (or g-is-first-time-run (imgui-call IsAnyItemActive))
(imgui-call SetKeyboardFocusHere))
(set (path state > focus-filter) false))
(call-on Draw (path state > directory-filter))
;; (fprintf stderr "Setting focus. Will retry until it is focused\n")
(imgui-call SetKeyboardFocusHere)))
(imgui-draw-imgui-text-filter (addr (path state > directory-filter)))
;; (scope
;; (var g-imgui (* ImGuiContext) GImGui)
;; (fprintf stderr "ActiveIdWindow: '%s'\n"
;; (? (path g-imgui > ActiveIdWindow) (path g-imgui > ActiveIdWindow > Name) "NULL")))
(when (path state > focus-filter)
(when (or (imgui-call IsItemFocused) (imgui-call IsItemActive))
(decr (path state > try-focus-frames-remaining))
(when (= 0 (path state > try-focus-frames-remaining))
(fprintf stderr "Focused %d\n" (path state > try-focus-frames-remaining))
(set (path state > focus-filter) false))
;; (fprintf stderr "Focused %d\n" (path state > try-focus-frames-remaining))
))
(when (imgui-call IsItemHovered)
(imgui-call BeginTooltip)
(imgui-call Text "Filter items in the current directory. This is a fast way to navigate.")
@ -767,7 +809,7 @@
(when (and (imgui-call IsItemDeactivated)
(imgui-call IsKeyPressed
(at ImGuiKey_Enter (field imgui-io KeyMap))))
(scope (set (path state > focus-filter) true))
(scope (focus-directory-listing-filter state))
(imgui-directory-listing-activated
(filtered-entry-index-to-entry (path state > on-activate-index) state)
state)))
@ -882,16 +924,16 @@
(when (imgui-call Selectable entry-name (= entry-index (path state > on-activate-index))
;;(bit-or ImGuiSelectableFlags_SpanAllColumns
ImGuiSelectableFlags_AllowDoubleClick) ;;)
(set (path state > focus-filter) true)
(focus-directory-listing-filter state)
(set (path state > on-activate-index) entry-index)
(when (imgui-call IsMouseDoubleClicked 0)
(set (path state > focus-filter) true)
(focus-directory-listing-filter state)
(append-file-entry-to-path (addr (path state > current-dir)) (path current-entry > name))
(set (path state > needs-update) true)))
;; File
(when (imgui-call Selectable entry-name (= entry-index (path state > on-activate-index)))
;;ImGuiSelectableFlags_SpanAllColumns)
(set (path state > focus-filter) true)
(focus-directory-listing-filter state)
(set (path state > on-activate-index) entry-index)))
(var selected-row-color ImU32 (imgui-call GetColorU32 (at ImGuiCol_FrameBg colors)))
@ -911,7 +953,7 @@
(imgui-call TableNextColumn)
(if (path current-entry > is-directory)
(when (imgui-call Button "dir")
(set (path state > focus-filter) true)
(focus-directory-listing-filter state)
(append-file-entry-to-path (addr (path state > current-dir)) (path current-entry > name))
(set (path state > needs-update) true))
(imgui-call TextDisabled "file"))
@ -996,7 +1038,8 @@
(imgui-call End)
(when (path state > needs-update)
(call-on Clear (path state > directory-filter))
(memset (addr (path state > directory-filter . filter)) 0
(sizeof (path state > directory-filter . filter)))
(update-directory-entries state)))
(var delete-without-prompt bool false)
@ -1277,7 +1320,7 @@
(dynstring-append (addr (field listing-state current-dir)) current-dir)
(free (type-cast current-dir (* void)))
(set (field listing-state focus-filter) true)
(focus-directory-listing-filter (addr listing-state))
(set (field listing-state was-window-focused) true)
;; (strdict-use-key-arena g-userdata-dict)
@ -1336,8 +1379,14 @@
(scope ;; ImGui style customizations
(var imgui-style (& ImGuiStyle) (imgui-call GetStyle))
(set (field imgui-style WindowMenuButtonPosition) ImGuiDir_Right)
(set (field imgui-style FrameRounding) 6.f))
;; This doesn't appear to solve double-click being flaky
;; (scope ;; ImGui input customizations
;; (var imgui-io (& ImGuiIO) (imgui-call GetIO))
;; (set (field imgui-io MouseDoubleClickMaxDist) 12.f))
(var directory-history (* dynstring) null)
(dynarray-set-capacity directory-history 64)
(var directory-history-index int 0)
@ -1535,7 +1584,7 @@ Depending on the error, open the UserData.cakedata file in a text editor and see
(when history-used
(set (field listing-state on-activate-index) 0)
(set (field listing-state should-scroll-to-entry) true)
(set (field listing-state focus-filter) true)
(focus-directory-listing-filter (addr listing-state))
(set (field listing-state needs-update) true))))
(when (is-key-tapped-this-frame SDL_SCANCODE_F5 key-states
@ -1606,7 +1655,7 @@ Depending on the error, open the UserData.cakedata file in a text editor and see
(+ hover-path (strlen (field listing-state current-dir))))
(set-auto-focus-child-entry (addr listing-state) auto-select-entry-start)
(set (field listing-state should-scroll-to-entry) true)
(set (field listing-state focus-filter) true)
(focus-directory-listing-filter (addr listing-state))
(set (field listing-state needs-update) true)))
(var application-window-width int 0)

Loading…
Cancel
Save