main f2d166b

placement.go RawHistoryFolder

1package core
2
3import (
4	"image"
5
6	"github.com/bnema/neferwl/internal/ports"
7)
8
9// placeItem is one output to place: its connector name, logical size, the
10// explicit origin when one is set (pos: explicit origin set at runtime by
11// wlr-output-management, not a config key) and the output.<name> relation to
12// another output.
13type placeItem struct {
14	name   string
15	w, h   int
16	pos    *image.Point
17	anchor ports.OutputAnchor
18}
19
20// placeOutputs returns the logical origin of every item, in item order.
21// Precedence: an explicit position, then the relation to another placed
22// output, then automatic placement: from the rightmost edge placed so far
23// (never left of 0), at y=0. Automatic placement runs only when no relation
24// can be resolved, so an anchored output never lands on an automatic one.
25// A relation to an absent output, or in a cycle, falls back to automatic.
26func placeOutputs(items []placeItem) []image.Point {
27	out := make([]image.Point, len(items))
28	done := make([]bool, len(items))
29	left := len(items)
30	for i, it := range items {
31		if it.pos != nil {
32			out[i], done[i] = *it.pos, true
33			left--
34		}
35	}
36	anchored := func(i int) bool { return !done[i] && items[i].anchor.Relation != ports.RelationNone }
37	for left > 0 {
38		for progress := true; progress; {
39			progress = false
40			for i, it := range items {
41				if !anchored(i) {
42					continue
43				}
44				for j, ref := range items {
45					if !done[j] || ref.name == "" || ref.name != it.anchor.To {
46						continue
47					}
48					out[i], done[i] = relativeTo(it, ref, out[j]), true
49					left--
50					progress = true
51					break
52				}
53			}
54		}
55		if left == 0 {
56			break
57		}
58		next := -1
59		for i := range items {
60			if !done[i] && (next < 0 || (anchored(next) && !anchored(i))) {
61				next = i
62			}
63		}
64		x := 0
65		for i, it := range items {
66			if done[i] {
67				x = max(x, out[i].X+it.w)
68			}
69		}
70		out[next], done[next] = image.Point{X: x}, true
71		left--
72	}
73	return out
74}
75
76// relativeTo is the origin of it placed against ref, whose origin is at.
77func relativeTo(it, ref placeItem, at image.Point) image.Point {
78	off := it.anchor.Offset
79	switch it.anchor.Relation {
80	case ports.RelationRightOf:
81		return image.Point{X: at.X + ref.w, Y: at.Y + off}
82	case ports.RelationLeftOf:
83		return image.Point{X: at.X - it.w, Y: at.Y + off}
84	case ports.RelationAbove:
85		return image.Point{X: at.X + off, Y: at.Y - it.h}
86	default: // RelationBelow
87		return image.Point{X: at.X + off, Y: at.Y + ref.h}
88	}
89}

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 25

Tags 10

↑↓ moveenter openesc close