aboutsummaryrefslogtreecommitdiffstats
path: root/src/i_events.go
diff options
context:
space:
mode:
authorJoe <rbo@gmx.us>2024-01-23 20:20:20 +0100
committerJoe <rbo@gmx.us>2024-01-23 20:20:20 +0100
commit730bbd15c64cf8324267176dc6ced128559ad4cd (patch)
tree8aac0527cf3616f04624ebf14e552d07396ae080 /src/i_events.go
parentgo (diff)
downloadhardflip-730bbd15c64cf8324267176dc6ced128559ad4cd.tar.gz
hardflip-730bbd15c64cf8324267176dc6ced128559ad4cd.tar.bz2
hardflip-730bbd15c64cf8324267176dc6ced128559ad4cd.tar.xz
hardflip-730bbd15c64cf8324267176dc6ced128559ad4cd.tar.zst
hardflip-730bbd15c64cf8324267176dc6ced128559ad4cd.zip
better org
Diffstat (limited to 'src/i_events.go')
-rw-r--r--src/i_events.go349
1 files changed, 349 insertions, 0 deletions
diff --git a/src/i_events.go b/src/i_events.go
new file mode 100644
index 0000000..526b4a4
--- /dev/null
+++ b/src/i_events.go
@@ -0,0 +1,349 @@
+/*
+ * ========================
+ * ===== ===============
+ * ====== ================
+ * ====== ================
+ * ====== ==== ==== ==
+ * ====== === == = =
+ * ====== === = == =
+ * = === === = == ====
+ * = === === = == = =
+ * == ===== ==== ==
+ * ========================
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2023-2024, Joe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the organization nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * hardflip: src/i_events.go
+ * Fri Jan 19 19:25:52 2024
+ * Joe
+ *
+ * events in the code
+ */
+
+package main
+
+import (
+ "os"
+
+ "github.com/gdamore/tcell/v2"
+ "golang.org/x/term"
+)
+
+func i_list_follow_cursor(litems *ItemsList, ui *HardUI) {
+ if litems.draw == nil || litems.curr == nil {
+ return
+ }
+ scrolloff := 4
+ if litems.last.ID - (ui.dim[H] - 4) <= litems.draw.ID {
+ scrolloff = 0
+ }
+ virt_id := litems.curr.ID - (ui.dim[H] - 4) + scrolloff
+ for litems.draw.ID < virt_id &&
+ litems.draw.next != nil {
+ litems.draw = litems.draw.next
+ }
+ scrolloff = 4
+ for litems.draw.ID > litems.curr.ID - scrolloff &&
+ litems.draw.prev != nil {
+ litems.draw = litems.draw.prev
+ }
+}
+
+func i_set_unfold(data *HardData, item *ItemsNode) {
+ delete(data.folds, item.Dirs)
+ data.litems.reset_id()
+}
+
+func i_unfold_dir(data *HardData, item *ItemsNode) {
+ if item == nil || item.Dirs == nil {
+ return
+ }
+ fold := data.folds[item.Dirs]
+ if fold == nil {
+ return
+ }
+ start, end := fold.head, fold.last
+ // last empty dir
+ if start == nil && end == nil {
+ i_set_unfold(data, item)
+ return
+ }
+ // single empty dir
+ if start == item && end == end {
+ i_set_unfold(data, item)
+ return
+ }
+ if data.litems.last == item {
+ data.litems.last = end
+ }
+ // non-emtpy dir
+ start.prev = item
+ end.next = item.next
+ if item.next != nil {
+ item.next.prev = end
+ }
+ item.next = start
+ i_set_unfold(data, item)
+}
+
+func i_set_fold(data *HardData, curr, start, end *ItemsNode) {
+ folds := data.folds
+ tmp := ItemsList{
+ start,
+ end,
+ nil,
+ nil,
+ }
+
+ folds[curr.Dirs] = &tmp
+ data.litems.reset_id()
+}
+
+func i_fold_dir(data *HardData, item *ItemsNode) {
+ if item == nil || item.Dirs == nil {
+ return
+ }
+ var start, end *ItemsNode
+ start = item.next
+ // last dir + empty
+ if start == nil {
+ i_set_fold(data, item, nil, nil)
+ return
+ }
+ // empty dir
+ if start.Dirs != nil && start.Dirs.Depth <= item.Dirs.Depth {
+ i_set_fold(data, item, item, item)
+ return
+ }
+ // non-empty dir
+ start.prev = nil
+ end = start
+ next_dir := item.get_next_level()
+ // this is the end
+ if next_dir == nil {
+ item.next = nil
+ end = data.litems.last
+ end.next = nil
+ data.litems.last = item
+ i_set_fold(data, item, start, end)
+ return
+ }
+ // this is not the end
+ end = next_dir.prev
+ end.next = nil
+ item.next = next_dir
+ next_dir.prev = item
+ i_set_fold(data, item, start, end)
+}
+
+func i_reload_data(data *HardData) {
+ data.data_dir = c_get_data_dir()
+ g_load_count = -1
+ data.ldirs, data.litems = i_load_ui(data.data_dir, data.opts, &data.ui)
+ // FIX: must input to start reloading for some reason
+ data.folds = make(map[*DirsNode]*ItemsList)
+}
+
+func i_delete_dir(data *HardData) error {
+ if data.litems.curr == nil || data.litems.curr.Dirs == nil {
+ return nil
+ }
+ curr := data.litems.curr
+ dir_path := data.data_dir + data.litems.curr.Dirs.path()
+ if err := os.RemoveAll(dir_path); err != nil {
+ c_error_mode("can't remove " + dir_path, err, &data.ui)
+ return err
+ }
+ if data.folds[curr.Dirs] == nil {
+ i_fold_dir(data, curr)
+ }
+ delete(data.folds, curr.Dirs)
+ if curr == data.litems.head {
+ data.litems.head = curr.next
+ if curr.next != nil {
+ curr.next.prev = nil
+ }
+ if data.litems.draw == curr {
+ data.litems.draw = curr.next
+ }
+ } else {
+ curr.prev.next = curr.next
+ }
+ if curr.next != nil {
+ curr.next.prev = curr.prev
+ data.litems.curr = curr.next
+ } else {
+ data.litems.last = curr.prev
+ data.litems.curr = curr.prev
+ }
+ data.litems.reset_id()
+ return nil
+}
+
+func i_delete_host(data *HardData) error {
+ if data.litems.curr == nil {
+ return nil
+ }
+ if data.litems.curr.is_dir() == true {
+ return i_delete_dir(data)
+ }
+ host := data.litems.curr.Host
+ if host == nil {
+ return nil
+ }
+ file_path := data.data_dir + host.Parent.path() + host.Filename
+
+ if err := os.Remove(file_path); err != nil {
+ c_error_mode("can't remove " + file_path, err, &data.ui)
+ return err
+ }
+ tmp := data.litems.curr.prev
+ host.Parent.lhost.del(host)
+ data.litems.del(data.litems.curr)
+ if tmp == nil {
+ tmp = data.litems.head
+ }
+ data.litems.curr = tmp
+ return nil
+}
+
+// screen events such as keypresses
+func i_events(data *HardData) {
+ var err error
+ ui := &data.ui
+ event := ui.s.PollEvent()
+ switch event := event.(type) {
+ case *tcell.EventResize:
+ ui.dim[W], ui.dim[H], _ = term.GetSize(0)
+ i_list_follow_cursor(data.litems, ui)
+ ui.s.Sync()
+ case *tcell.EventKey:
+ switch ui.mode {
+ case NORMAL_MODE:
+ if event.Key() == tcell.KeyCtrlC ||
+ event.Rune() == 'q' {
+ ui.s.Fini()
+ os.Exit(0)
+ } else if event.Rune() == 'j' ||
+ event.Key() == tcell.KeyDown {
+ data.litems.inc(+1)
+ } else if event.Rune() == 'k' ||
+ event.Key() == tcell.KeyUp {
+ data.litems.inc(-1)
+ } else if event.Key() == tcell.KeyCtrlD ||
+ event.Key() == tcell.KeyPgDn {
+ data.litems.inc(+(ui.dim[H] / 3))
+ } else if event.Key() == tcell.KeyCtrlU ||
+ event.Key() == tcell.KeyPgUp {
+ data.litems.inc(-(ui.dim[H] / 3))
+ } else if event.Key() == tcell.KeyCtrlF {
+ // TODO: maybe keymap these
+ } else if event.Key() == tcell.KeyCtrlB {
+ // TODO: maybe keymap these
+ } else if event.Rune() == '}' ||
+ event.Rune() == ']' {
+ if next := data.litems.curr.next_dir(); next != nil {
+ data.litems.curr = next
+ }
+ } else if event.Rune() == '{' ||
+ event.Rune() == '[' {
+ if prev := data.litems.curr.prev_dir(); prev != nil {
+ data.litems.curr = prev
+ }
+ } else if event.Rune() == 'g' ||
+ event.Key() == tcell.KeyHome {
+ data.litems.curr = data.litems.head
+ data.litems.draw = data.litems.head
+ } else if event.Rune() == 'G' ||
+ event.Key() == tcell.KeyEnd {
+ data.litems.curr = data.litems.last
+ } else if event.Rune() == 'D' &&
+ data.ldirs.head != nil {
+ ui.mode = DELETE_MODE
+ } else if event.Rune() == 'l' ||
+ event.Key() == tcell.KeyEnter {
+ if data.litems.curr == nil {
+ break
+ } else if data.litems.curr.is_dir() == false {
+ ui.s.Fini()
+ c_exec(data.litems.curr.Host, data.opts.Term)
+ if data.opts.Loop == false {
+ os.Exit(0)
+ } else {
+ if ui.s, err = tcell.NewScreen(); err != nil {
+ c_die("view", err)
+ }
+ if err := ui.s.Init(); err != nil {
+ c_die("view", err)
+ }
+ ui.s.SetStyle(ui.def_style)
+ }
+ } else if data.litems.curr.Dirs != nil &&
+ data.folds[data.litems.curr.Dirs] == nil {
+ i_fold_dir(data, data.litems.curr)
+ } else {
+ i_unfold_dir(data, data.litems.curr)
+ }
+ } else if event.Rune() == ' ' {
+ if data.litems.curr == nil ||
+ data.litems.curr.is_dir() == false {
+ break
+ }
+ if data.litems.curr.Dirs != nil &&
+ data.folds[data.litems.curr.Dirs] == nil {
+ i_fold_dir(data, data.litems.curr)
+ } else {
+ i_unfold_dir(data, data.litems.curr)
+ }
+ } else if event.Key() == tcell.KeyCtrlR {
+ i_reload_data(data)
+ }
+ i_list_follow_cursor(data.litems, ui)
+ case DELETE_MODE:
+ if event.Key() == tcell.KeyEscape ||
+ event.Key() == tcell.KeyCtrlC ||
+ event.Rune() == 'q' ||
+ event.Rune() == 'n' {
+ ui.mode = NORMAL_MODE
+ } else if event.Key() == tcell.KeyEnter ||
+ event.Rune() == 'y' {
+ if err := i_delete_host(data); err == nil {
+ ui.mode = NORMAL_MODE
+ }
+ }
+ case ERROR_MODE:
+ if event.Key() == tcell.KeyEnter {
+ ui.mode = NORMAL_MODE
+ }
+ }
+ }
+}