main 5041353

widgets.go RawHistoryFolder

1// Package layout provides GTK widget abstractions and layout management for the pane system.
2// It defines interfaces that wrap GTK types, enabling unit testing without GTK runtime.
3package layout
4
5import (
6	"github.com/bnema/puregotk/v4/gtk"
7)
8
9// Orientation represents the orientation for layout widgets.
10type Orientation = gtk.Orientation
11
12// Orientation constants matching GTK values.
13const (
14	OrientationHorizontal = gtk.OrientationHorizontalValue
15	OrientationVertical   = gtk.OrientationVerticalValue
16)
17
18// Widget is the base interface that all GTK widgets implement.
19// It provides common widget operations needed for layout management.
20type Widget interface {
21	// Visibility
22	Show()
23	Hide()
24	SetVisible(visible bool)
25	IsVisible() bool
26	SetOpacity(opacity float64)
27
28	// Focus
29	GrabFocus() bool
30	HasFocus() bool
31	SetCanFocus(canFocus bool)
32	SetFocusable(focusable bool) // GTK4: makes widget able to receive keyboard focus
33	SetFocusOnClick(focusOnClick bool)
34
35	// Pointer events
36	SetCanTarget(canTarget bool) // If false, widget won't receive pointer events
37
38	// Layout
39	SetHexpand(expand bool)
40	SetVexpand(expand bool)
41	GetHexpand() bool
42	GetVexpand() bool
43	SetHalign(align gtk.Align)
44	SetValign(align gtk.Align)
45	SetSizeRequest(width, height int)
46
47	// Geometry - for focus navigation
48	GetAllocatedWidth() int
49	GetAllocatedHeight() int
50	// ComputePoint returns the position of this widget's origin (0,0) relative to
51	// the target widget's coordinate space. If target is nil, returns position
52	// relative to the native window. Returns ok=false if computation fails.
53	ComputePoint(target Widget) (x, y float64, ok bool)
54
55	// CSS styling
56	AddCssClass(cssClass string)
57	RemoveCssClass(cssClass string)
58	HasCssClass(cssClass string) bool
59
60	// Parent management
61	Unparent()
62	GetParent() Widget
63
64	// GTK interop - returns the underlying GTK widget for embedding
65	GtkWidget() *gtk.Widget
66
67	// AddController adds an event controller to the widget
68	AddController(controller *gtk.EventController)
69}
70
71// PanedWidget wraps gtk.Paned for creating split views.
72// It manages two child widgets separated by a draggable divider.
73type PanedWidget interface {
74	Widget
75
76	// Child management
77	SetStartChild(child Widget)
78	SetEndChild(child Widget)
79	GetStartChild() Widget
80	GetEndChild() Widget
81
82	// Divider position
83	SetPosition(position int)
84	GetPosition() int
85
86	// Resize behavior
87	SetResizeStartChild(resize bool)
88	SetResizeEndChild(resize bool)
89	GetResizeStartChild() bool
90	GetResizeEndChild() bool
91
92	// Shrink behavior (whether child can be smaller than its minimum size)
93	SetShrinkStartChild(shrink bool)
94	SetShrinkEndChild(shrink bool)
95	GetShrinkStartChild() bool
96	GetShrinkEndChild() bool
97
98	// Signals
99	ConnectMap(callback func()) uint
100	ConnectNotifyPosition(callback func()) uint
101
102	// Tick callback for frame-based updates (returns signal ID).
103	// Callback returns true to continue, false to stop.
104	AddTickCallback(callback func() bool) uint
105	// RemoveTickCallback releases an active callback slot. It is safe to call
106	// once after the callback has stopped itself.
107	RemoveTickCallback(id uint)
108
109	// Handle appearance
110	SetWideHandle(wide bool)
111	GetWideHandle() bool
112}
113
114// BoxWidget wraps gtk.Box for linear layouts.
115// It arranges children in a single row or column.
116type BoxWidget interface {
117	Widget
118
119	// Child management
120	Append(child Widget)
121	Prepend(child Widget)
122	Remove(child Widget)
123	InsertChildAfter(child Widget, sibling Widget)
124	ReorderChildAfter(child Widget, sibling Widget)
125
126	// Configuration
127	SetHomogeneous(homogeneous bool)
128	GetHomogeneous() bool
129	SetSpacing(spacing int)
130	GetSpacing() int
131	SetOrientation(orientation Orientation)
132	GetOrientation() Orientation
133}
134
135// OverlayWidget wraps gtk.Overlay for layered content.
136// It displays overlay widgets on top of a main child widget.
137type OverlayWidget interface {
138	Widget
139
140	// Main child
141	SetChild(child Widget)
142	GetChild() Widget
143
144	// Overlay management
145	AddOverlay(overlay Widget)
146	RemoveOverlay(overlay Widget)
147
148	// Overlay configuration
149	SetClipOverlay(overlay Widget, clip bool)
150	GetClipOverlay(overlay Widget) bool
151	SetMeasureOverlay(overlay Widget, measure bool)
152	GetMeasureOverlay(overlay Widget) bool
153}
154
155// EllipsizeMode represents pango ellipsize modes.
156type EllipsizeMode = int
157
158// Ellipsize mode constants.
159const (
160	EllipsizeNone   EllipsizeMode = 0
161	EllipsizeStart  EllipsizeMode = 1
162	EllipsizeMiddle EllipsizeMode = 2
163	EllipsizeEnd    EllipsizeMode = 3
164)
165
166// LabelWidget wraps gtk.Label for text display.
167type LabelWidget interface {
168	Widget
169
170	SetText(text string)
171	GetText() string
172	SetMarkup(markup string)
173	SetEllipsize(mode EllipsizeMode)
174	SetMaxWidthChars(nChars int)
175	SetXalign(xalign float32)
176}
177
178// ButtonWidget wraps gtk.Button for clickable elements.
179type ButtonWidget interface {
180	Widget
181
182	SetLabel(label string)
183	GetLabel() string
184	SetChild(child Widget)
185	GetChild() Widget
186	SetIconName(iconName string)
187
188	// Connect click handler, returns signal ID for disconnection
189	ConnectClicked(callback func()) uint
190}
191
192// Paintable represents a graphics texture that can be displayed in an image.
193// This interface abstracts over gdk.Paintable/gdk.Texture.
194type Paintable interface {
195	GoPointer() uintptr
196}
197
198// ImageWidget wraps gtk.Image for displaying images.
199type ImageWidget interface {
200	Widget
201
202	SetFromIconName(iconName string)
203	SetFromFile(filename string)
204	SetFromPaintable(paintable Paintable)
205	SetPixelSize(pixelSize int)
206	Clear()
207}
208
209// ProgressBarWidget wraps gtk.ProgressBar for displaying loading progress.
210// Implementations may include smooth animation behavior.
211type ProgressBarWidget interface {
212	Widget
213
214	// SetFraction sets the progress value (0.0 to 1.0).
215	SetFraction(fraction float64)
216	// GetFraction returns the current progress value.
217	GetFraction() float64
218}
219
220// SpinnerWidget wraps gtk.Spinner for displaying indefinite loading.
221type SpinnerWidget interface {
222	Widget
223
224	Start()
225	Stop()
226	SetSpinning(spinning bool)
227	GetSpinning() bool
228}
229
230// WidgetFactory creates widget instances.
231// This abstraction allows tests to inject mock factories.
232type WidgetFactory interface {
233	// Container widgets
234	NewPaned(orientation Orientation) PanedWidget
235	NewBox(orientation Orientation, spacing int) BoxWidget
236	NewOverlay() OverlayWidget
237
238	// Display widgets
239	NewLabel(text string) LabelWidget
240	NewButton() ButtonWidget
241	NewImage() ImageWidget
242	NewProgressBar() ProgressBarWidget
243	NewSpinner() SpinnerWidget
244
245	// Wrap existing GTK widget
246	WrapWidget(w *gtk.Widget) Widget
247	WrapNativeWidget(ptr uintptr) Widget
248}
249
250// PaneRenderer creates pane view widgets from domain entities.
251// This decouples the tree renderer from concrete PaneView implementation.
252type PaneRenderer interface {
253	// RenderPane creates a widget for a pane node.
254	// The webViewWidget is the GTK widget from the WebView.
255	RenderPane(paneID string, webViewWidget Widget) Widget
256}

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