diff --git a/component/geometry.go b/component/geometry.go new file mode 100644 index 0000000..39b8a10 --- /dev/null +++ b/component/geometry.go @@ -0,0 +1,40 @@ +package component + +import ( + "image" + "math" +) + +func getRectLeftAgeCenter(rect image.Rectangle) image.Point { + return image.Point{ + X: rect.Min.X, + Y: rect.Min.Y + rect.Dy()/2, + } +} + +func getRectRightAgeCenter(rect image.Rectangle) image.Point { + return image.Point{ + X: rect.Max.X, + Y: rect.Min.Y + rect.Dy()/2, + } +} + +func getRectTopAgeCenter(rect image.Rectangle) image.Point { + return image.Point{ + X: rect.Min.X + rect.Dx()/2, + Y: rect.Min.Y, + } +} + +func getRectBottomAgeCenter(rect image.Rectangle) image.Point { + return image.Point{ + X: rect.Min.X + rect.Dx()/2, + Y: rect.Max.Y, + } +} + +func getDistance(p1 image.Point, p2 image.Point) float64 { + x := math.Abs(float64(p1.X - p2.X)) + y := math.Abs(float64(p1.Y - p2.Y)) + return math.Sqrt(x*x + y*y) +} diff --git a/component/layout.go b/component/layout.go index 26e1d9c..d22b94c 100644 --- a/component/layout.go +++ b/component/layout.go @@ -5,6 +5,7 @@ import ( "github.com/sqshq/sampler/config" "github.com/sqshq/sampler/console" ui "github.com/sqshq/termui" + "image" "math" ) @@ -126,9 +127,7 @@ func (l *Layout) HandleConsoleEvent(e string) { chart := l.getSelectedComponent().Drawable.(*runchart.RunChart) chart.MoveSelection(-1) case ModeComponentSelect: - if l.selection > 0 { - l.selection-- - } + l.moveSelection(e) l.menu.highlight(l.getComponent(l.selection)) case ModeComponentMove: l.getSelectedComponent().Move(-1, 0) @@ -144,9 +143,7 @@ func (l *Layout) HandleConsoleEvent(e string) { chart := l.getSelectedComponent().Drawable.(*runchart.RunChart) chart.MoveSelection(1) case ModeComponentSelect: - if l.selection < len(l.Components)-1 { - l.selection++ - } + l.moveSelection(e) l.menu.highlight(l.getComponent(l.selection)) case ModeComponentMove: l.getSelectedComponent().Move(1, 0) @@ -159,9 +156,7 @@ func (l *Layout) HandleConsoleEvent(e string) { l.changeMode(ModeComponentSelect) l.menu.highlight(l.getComponent(l.selection)) case ModeComponentSelect: - if l.selection > 0 { - l.selection-- - } + l.moveSelection(e) l.menu.highlight(l.getComponent(l.selection)) case ModeMenuOptionSelect: l.menu.up() @@ -176,9 +171,7 @@ func (l *Layout) HandleConsoleEvent(e string) { l.changeMode(ModeComponentSelect) l.menu.highlight(l.getComponent(l.selection)) case ModeComponentSelect: - if l.selection < len(l.Components)-1 { - l.selection++ - } + l.moveSelection(e) l.menu.highlight(l.getComponent(l.selection)) case ModeMenuOptionSelect: l.menu.down() @@ -194,7 +187,6 @@ func (l *Layout) ChangeDimensions(width, height int) { l.SetRect(0, 0, width, height) } -// TODO func to get prev/next component navigating left/right/top/bottom func (l *Layout) getComponent(i int) Component { return l.Components[i] } @@ -203,6 +195,52 @@ func (l *Layout) getSelectedComponent() *Component { return &l.Components[l.selection] } +func (l *Layout) moveSelection(direction string) { + + previouslySelected := *l.getSelectedComponent() + newlySelectedIndex := l.selection + + for i, current := range l.Components { + + if current == previouslySelected { + continue + } + + if newlySelectedIndex < 0 { + newlySelectedIndex = i + } + + var previouslySelectedCornerPoint image.Point + var newlySelectedCornerPoint image.Point + var currentCornerPoint image.Point + + switch direction { + case console.KeyLeft: + previouslySelectedCornerPoint = getRectLeftAgeCenter(previouslySelected.Drawable.GetRect()) + newlySelectedCornerPoint = getRectRightAgeCenter(l.getComponent(newlySelectedIndex).Drawable.GetRect()) + currentCornerPoint = getRectRightAgeCenter(current.Drawable.GetRect()) + case console.KeyRight: + previouslySelectedCornerPoint = getRectRightAgeCenter(previouslySelected.Drawable.GetRect()) + newlySelectedCornerPoint = getRectLeftAgeCenter(l.getComponent(newlySelectedIndex).Drawable.GetRect()) + currentCornerPoint = getRectLeftAgeCenter(current.Drawable.GetRect()) + case console.KeyUp: + previouslySelectedCornerPoint = getRectTopAgeCenter(previouslySelected.Drawable.GetRect()) + newlySelectedCornerPoint = getRectBottomAgeCenter(l.getComponent(newlySelectedIndex).Drawable.GetRect()) + currentCornerPoint = getRectBottomAgeCenter(current.Drawable.GetRect()) + case console.KeyDown: + previouslySelectedCornerPoint = getRectBottomAgeCenter(previouslySelected.Drawable.GetRect()) + newlySelectedCornerPoint = getRectTopAgeCenter(l.getComponent(newlySelectedIndex).Drawable.GetRect()) + currentCornerPoint = getRectTopAgeCenter(current.Drawable.GetRect()) + } + + if getDistance(previouslySelectedCornerPoint, currentCornerPoint) < getDistance(previouslySelectedCornerPoint, newlySelectedCornerPoint) { + newlySelectedIndex = i + } + } + + l.selection = newlySelectedIndex +} + func (l *Layout) Draw(buffer *ui.Buffer) { columnWidth := float64(l.GetRect().Dx()) / float64(columnsCount)