borders.go RawHistoryFolder
1package focus
2
3import (
4 "context"
5
6 "github.com/bnema/dumber/internal/logging"
7 "github.com/bnema/dumber/internal/ui/input"
8 "github.com/bnema/dumber/internal/ui/layout"
9)
10
11// CSS classes for mode borders.
12const (
13 paneModeClass = "pane-mode-active"
14 tabModeClass = "tab-mode-active"
15 sessionModeClass = "session-mode-active"
16)
17
18// BorderManager manages mode indicator borders on the workspace container.
19// It creates a transparent overlay box that displays colored borders when
20// the user enters tab mode or pane mode.
21type BorderManager struct {
22 borderOverlay layout.BoxWidget
23 currentMode input.Mode
24}
25
26// NewBorderManager creates a border manager.
27// It creates a border overlay widget that should be added to the workspace container.
28func NewBorderManager(factory layout.WidgetFactory) *BorderManager {
29 // Create overlay box for mode borders
30 borderBox := factory.NewBox(layout.OrientationVertical, 0)
31 borderBox.SetCanFocus(false)
32 borderBox.SetCanTarget(false) // Don't intercept pointer events
33 borderBox.SetHexpand(true)
34 borderBox.SetVexpand(true)
35 borderBox.SetVisible(false) // Hidden in normal mode
36
37 return &BorderManager{
38 borderOverlay: borderBox,
39 currentMode: input.ModeNormal,
40 }
41}
42
43// Widget returns the border overlay widget for adding to workspace overlay.
44func (bm *BorderManager) Widget() layout.Widget {
45 return bm.borderOverlay
46}
47
48// OnModeChange updates border visibility based on mode.
49func (bm *BorderManager) OnModeChange(ctx context.Context, from, to input.Mode) {
50 log := logging.FromContext(ctx)
51 log.Debug().
52 Str("from", from.String()).
53 Str("to", to.String()).
54 Msg("border manager: mode changed")
55
56 // Remove old mode class
57 switch from {
58 case input.ModePane:
59 bm.borderOverlay.RemoveCssClass(paneModeClass)
60 case input.ModeTab:
61 bm.borderOverlay.RemoveCssClass(tabModeClass)
62 case input.ModeSession:
63 bm.borderOverlay.RemoveCssClass(sessionModeClass)
64 }
65
66 // Add new mode class and set visibility
67 switch to {
68 case input.ModePane:
69 bm.borderOverlay.AddCssClass(paneModeClass)
70 bm.borderOverlay.SetVisible(true)
71 case input.ModeTab:
72 bm.borderOverlay.AddCssClass(tabModeClass)
73 bm.borderOverlay.SetVisible(true)
74 case input.ModeSession:
75 bm.borderOverlay.AddCssClass(sessionModeClass)
76 bm.borderOverlay.SetVisible(true)
77 case input.ModeNormal:
78 bm.borderOverlay.SetVisible(false)
79 default:
80 // Resize mode is handled by per-pane stack border, not global overlay.
81 bm.borderOverlay.SetVisible(false)
82 }
83
84 bm.currentMode = to
85}
86
87// CurrentMode returns the current input mode.
88func (bm *BorderManager) CurrentMode() input.Mode {
89 return bm.currentMode
90}