@@ -8,13 +8,30 @@ import (
88 "zfs-file-history/internal/ui/shortcut_helper"
99 "zfs-file-history/internal/ui/snapshot_browser"
1010 "zfs-file-history/internal/ui/status_message"
11+ "zfs-file-history/internal/ui/theme"
1112 uiutil "zfs-file-history/internal/ui/util"
1213 "zfs-file-history/internal/zfs"
1314
1415 "github.com/gdamore/tcell/v2"
1516 "github.com/rivo/tview"
1617)
1718
19+ type dragType int
20+
21+ const (
22+ dragNone dragType = iota
23+ dragVertical
24+ dragHorizontal
25+ )
26+
27+ type boundaryType int
28+
29+ const (
30+ boundaryNone boundaryType = iota
31+ boundaryVertical
32+ boundaryHorizontal
33+ )
34+
1835type MainPage struct {
1936 application * tview.Application
2037 header * ApplicationHeaderComponent
@@ -23,8 +40,14 @@ type MainPage struct {
2340 datasetInfo * dataset_info.DatasetInfoComponent
2441 snapshotBrowser * snapshot_browser.SnapshotBrowserComponent
2542 layout * tview.Flex
43+ windowLayout * tview.Flex
44+ infoLayout * tview.Flex
2645
2746 wasInitialized bool
47+
48+ isDragging bool
49+ dragType dragType
50+ hoveredBoundary boundaryType
2851}
2952
3053func NewMainPage (application * tview.Application , path string ) * MainPage {
@@ -143,6 +166,105 @@ func (mainPage *MainPage) createLayout() *tview.Flex {
143166
144167 mainPageLayout .AddItem (windowLayout , 0 , 1 , true )
145168
169+ mainPage .windowLayout = windowLayout
170+ mainPage .infoLayout = infoLayout
171+
172+ windowLayout .SetMouseCapture (func (action tview.MouseAction , event * tcell.EventMouse ) (tview.MouseAction , * tcell.EventMouse ) {
173+ mouseX , mouseY := event .Position ()
174+ buttons := event .Buttons ()
175+
176+ diX , diY , diW , diH := mainPage .datasetInfo .GetLayout ().GetRect ()
177+ _ , sbY , _ , sbH := mainPage .snapshotBrowser .GetLayout ().GetRect ()
178+ winX , _ , winW , _ := windowLayout .GetRect ()
179+
180+ // 1. If currently dragging
181+ if mainPage .isDragging {
182+ if buttons == tcell .ButtonNone || action == tview .MouseLeftUp {
183+ mainPage .isDragging = false
184+ mainPage .dragType = dragNone
185+ mainPage .hoveredBoundary = boundaryNone
186+ mainPage .updateBorderHighlights ()
187+ return tview .MouseConsumed , nil
188+ }
189+
190+ if mainPage .dragType == dragVertical {
191+ newLeftWidth := mouseX - winX
192+ minWidth := 10
193+ if newLeftWidth < minWidth {
194+ newLeftWidth = minWidth
195+ }
196+ if newLeftWidth > winW - minWidth {
197+ newLeftWidth = winW - minWidth
198+ }
199+ newRightWidth := winW - newLeftWidth
200+
201+ windowLayout .ResizeItem (mainPage .fileBrowser .GetLayout (), 0 , newLeftWidth )
202+ windowLayout .ResizeItem (infoLayout , 0 , newRightWidth )
203+ } else if mainPage .dragType == dragHorizontal {
204+ infoH := diH + sbH
205+ infoY := diY
206+ newTopHeight := mouseY - infoY
207+ minTopHeight := 4
208+ minBottomHeight := 5
209+ if newTopHeight < minTopHeight {
210+ newTopHeight = minTopHeight
211+ }
212+ if newTopHeight > infoH - minBottomHeight {
213+ newTopHeight = infoH - minBottomHeight
214+ }
215+ newBottomHeight := infoH - newTopHeight
216+
217+ infoLayout .ResizeItem (mainPage .datasetInfo .GetLayout (), 0 , newTopHeight )
218+ infoLayout .ResizeItem (mainPage .snapshotBrowser .GetLayout (), 0 , newBottomHeight )
219+ }
220+
221+ return tview .MouseConsumed , nil
222+ }
223+
224+ // 2. Not dragging: detect hover boundaries
225+ isOnVertical := false
226+ if mouseY >= diY && mouseY < sbY + sbH {
227+ if mouseX == diX || mouseX == diX - 1 {
228+ isOnVertical = true
229+ }
230+ }
231+
232+ isOnHorizontal := false
233+ if mouseX >= diX && mouseX < diX + diW {
234+ if mouseY == sbY || mouseY == sbY - 1 {
235+ isOnHorizontal = true
236+ }
237+ }
238+
239+ newHover := boundaryNone
240+ if isOnHorizontal {
241+ newHover = boundaryHorizontal
242+ } else if isOnVertical {
243+ newHover = boundaryVertical
244+ }
245+
246+ if newHover != mainPage .hoveredBoundary {
247+ mainPage .hoveredBoundary = newHover
248+ mainPage .updateBorderHighlights ()
249+ return tview .MouseConsumed , nil
250+ }
251+
252+ // 3. Initiate dragging
253+ if buttons & tcell .Button1 != 0 && action == tview .MouseLeftDown {
254+ if isOnHorizontal {
255+ mainPage .isDragging = true
256+ mainPage .dragType = dragHorizontal
257+ return tview .MouseConsumed , nil
258+ } else if isOnVertical {
259+ mainPage .isDragging = true
260+ mainPage .dragType = dragVertical
261+ return tview .MouseConsumed , nil
262+ }
263+ }
264+
265+ return action , event
266+ })
267+
146268 mainPage .header = header
147269
148270 shortcutMap := shortcut_helper .NewShortcutMap (mainPage .application )
@@ -218,3 +340,33 @@ func (mainPage *MainPage) updateShortcutMap(component FocusableUiComponent) {
218340 mainPage .clearShortcutMap ()
219341 }
220342}
343+
344+ func (mainPage * MainPage ) setPanelBorderColor (panel FocusableUiComponent , color tcell.Color ) {
345+ if fb , ok := panel .(* file_browser.FileBrowserComponent ); ok {
346+ fb .SetBorderColor (color )
347+ } else if di , ok := panel .(* dataset_info.DatasetInfoComponent ); ok {
348+ di .SetBorderColor (color )
349+ } else if sb , ok := panel .(* snapshot_browser.SnapshotBrowserComponent ); ok {
350+ sb .SetBorderColor (color )
351+ }
352+ }
353+
354+ func (mainPage * MainPage ) updateBorderHighlights () {
355+ defaultColor := theme .Colors .Layout .Border
356+ highlightColor := theme .Primary
357+
358+ switch mainPage .hoveredBoundary {
359+ case boundaryVertical :
360+ mainPage .setPanelBorderColor (mainPage .fileBrowser , highlightColor )
361+ mainPage .setPanelBorderColor (mainPage .datasetInfo , highlightColor )
362+ mainPage .setPanelBorderColor (mainPage .snapshotBrowser , highlightColor )
363+ case boundaryHorizontal :
364+ mainPage .setPanelBorderColor (mainPage .fileBrowser , defaultColor )
365+ mainPage .setPanelBorderColor (mainPage .datasetInfo , highlightColor )
366+ mainPage .setPanelBorderColor (mainPage .snapshotBrowser , highlightColor )
367+ case boundaryNone :
368+ mainPage .setPanelBorderColor (mainPage .fileBrowser , defaultColor )
369+ mainPage .setPanelBorderColor (mainPage .datasetInfo , defaultColor )
370+ mainPage .setPanelBorderColor (mainPage .snapshotBrowser , defaultColor )
371+ }
372+ }
0 commit comments