main 5041353

main_window_sidebar.go RawHistoryFolder

1package window
2
3import (
4	"github.com/bnema/puregotk/v4/gtk"
5)
6
7// SidebarWidthConfig defines the initial/recommended width range for the sidebar.
8type SidebarWidthConfig struct {
9	// WidthPx is the preferred sidebar width.
10	WidthPx int
11	// MinPx is the minimum clamped width (default 280).
12	MinPx int
13	// MaxPx is the maximum clamping bound (default 380).
14	MaxPx int
15}
16
17// SidebarDefaultWidth returns a sensible default width configuration:
18// preferred 320px, clamped to [280, 380].
19func SidebarDefaultWidth() SidebarWidthConfig {
20	return SidebarWidthConfig{
21		WidthPx: 320,
22		MinPx:   280,
23		MaxPx:   380,
24	}
25}
26
27// SetSidebarWidth sets the sidebar box width to widthPx, clamped to the
28// config's [MinPx, MaxPx] bounds. Using the zero-value SidebarWidthConfig{}
29// sets sensible defaults (320px clamped to [280, 380]).
30func (mw *MainWindow) SetSidebarWidth(cfg SidebarWidthConfig) {
31	if mw.sidebarBox == nil {
32		return
33	}
34	defaults := SidebarDefaultWidth()
35	if cfg.MinPx == 0 {
36		cfg.MinPx = defaults.MinPx
37	}
38	if cfg.MaxPx == 0 {
39		cfg.MaxPx = defaults.MaxPx
40	}
41	if cfg.WidthPx == 0 {
42		cfg.WidthPx = defaults.WidthPx
43	}
44	if cfg.MinPx > cfg.MaxPx {
45		mw.logger.Warn().Int("min_px", cfg.MinPx).Int("max_px", cfg.MaxPx).Msg("invalid sidebar width bounds; swapping")
46		cfg.MinPx, cfg.MaxPx = cfg.MaxPx, cfg.MinPx
47	}
48	clamped := min(max(cfg.WidthPx, cfg.MinPx), cfg.MaxPx)
49	mw.sidebarBox.SetSizeRequest(clamped, -1)
50	mw.logger.Debug().Int("sidebar_width", clamped).Msg("sidebar width set")
51}
52
53// SetSidebarVisible shows or hides the sidebar pane.
54func (mw *MainWindow) SetSidebarVisible(visible bool) {
55	if mw.sidebarBox == nil {
56		return
57	}
58	mw.sidebarBox.SetVisible(visible)
59	mw.logger.Debug().Bool("sidebar_visible", visible).Msg("sidebar visibility changed")
60}
61
62// IsSidebarVisible returns whether the sidebar pane is currently visible.
63func (mw *MainWindow) IsSidebarVisible() bool {
64	if mw.sidebarBox == nil {
65		return false
66	}
67	return mw.sidebarBox.GetVisible()
68}
69
70// SetSidebarWidget replaces the current sidebar content widget.
71func (mw *MainWindow) SetSidebarWidget(widget *gtk.Widget) {
72	if mw.sidebarBox == nil {
73		return
74	}
75	// Remove existing children
76	for {
77		child := mw.sidebarBox.GetFirstChild()
78		if child == nil {
79			break
80		}
81		mw.sidebarBox.Remove(child)
82	}
83	if widget != nil {
84		widget.SetVisible(true)
85		mw.sidebarBox.Append(widget)
86	}
87}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close