From b1ad5ab08149694f1bb4b6a8607788408b07de38 Mon Sep 17 00:00:00 2001 From: Timon Ringwald Date: Wed, 4 May 2022 12:03:51 +0200 Subject: [PATCH] OnMouseClicked implemented for BorderLayout --- screen.go | 2 +- tests/screen_test.go | 19 +++++++++++++++++++ types.go | 32 +++++++++++++++++++++++++++++++- views/layout_border.go | 20 +++++++++++++++++++- views/layout_coord.go | 2 ++ views/layout_flow.go | 2 ++ views/layout_separator.go | 2 ++ 7 files changed, 76 insertions(+), 3 deletions(-) diff --git a/screen.go b/screen.go index faa91cc..7ee22ba 100644 --- a/screen.go +++ b/screen.go @@ -84,7 +84,7 @@ func (s *Screen) onMouseClicked(event *MouseEvent) { func convertMouseEvent(original *tcell.EventMouse) *MouseEvent { x, y := original.Position() return &MouseEvent{ - X: x, Y: y, + Position: P(x, y), Button: convertMouseButton(original.Buttons()), Modifiers: original.Modifiers(), } diff --git a/tests/screen_test.go b/tests/screen_test.go index 8bcb738..964d20e 100644 --- a/tests/screen_test.go +++ b/tests/screen_test.go @@ -114,6 +114,25 @@ func TestGrowView(t *testing.T) { } } +func TestMousePosition(t *testing.T) { + textView := views.NewTextView("hello world") + + screen, err := tui.NewScreen(textView) + if err != nil { + t.Error(err) + return + } + + screen.MouseClicked = func(event *tui.MouseEvent) (consumed bool) { + textView.Text = fmt.Sprintf("position: %s", event.Position.String()) + return true + } + + if err := screen.Start(); err != nil { + fmt.Println(err) + } +} + func TestFlowLayout(t *testing.T) { textView := views.NewTextView("hello world!") textView.SetStyle(tui.StyleDefault.Background(tcell.ColorRed).Foreground(tcell.ColorBlack)) diff --git a/types.go b/types.go index 9e7fa83..254af93 100644 --- a/types.go +++ b/types.go @@ -1,6 +1,8 @@ package tui import ( + "fmt" + "git.tordarus.net/Tordarus/buf2d" "github.com/gdamore/tcell" ) @@ -16,15 +18,43 @@ type Point struct { X, Y int } +func P(x, y int) Point { + return Point{x, y} +} + +func (p Point) In(d Dimension) bool { + return p.X >= d.X && p.X < d.X+d.Width && p.Y >= d.Y && p.Y < d.Y+d.Height +} + +func (p Point) String() string { + return fmt.Sprintf("P(%d, %d)", p.X, p.Y) +} + type Size struct { Width, Height int } +func S(w, h int) Size { + return Size{w, h} +} + +func (s Size) String() string { + return fmt.Sprintf("S(%d, %d)", s.Width, s.Height) +} + type Dimension struct { Point Size } +func D(x, y, w, h int) Dimension { + return Dimension{P(x, y), S(w, h)} +} + +func (d Dimension) String() string { + return fmt.Sprintf("D(%d, %d, %d, %d)", d.X, d.Y, d.Width, d.Height) +} + type Orientation uint8 const ( @@ -66,7 +96,7 @@ const ( ) type MouseEvent struct { - X, Y int + Position Point Button MouseButton Modifiers tcell.ModMask } diff --git a/views/layout_border.go b/views/layout_border.go index b99e85d..045697e 100644 --- a/views/layout_border.go +++ b/views/layout_border.go @@ -10,13 +10,16 @@ type BorderLayout struct { views map[Slot]tui.View horizontalLayout *LayoutResult verticalLayout *LayoutResult + + viewDimensions map[Slot]tui.Dimension } var _ tui.Layout = &BorderLayout{} func NewBorderLayout() *BorderLayout { return &BorderLayout{ - views: map[Slot]tui.View{}, + views: map[Slot]tui.View{}, + viewDimensions: map[Slot]tui.Dimension{}, } } @@ -76,6 +79,7 @@ func (g *BorderLayout) Draw(buf *tui.ViewBuffer) { topHeight = int(float64(buf.Height()) * float64(topHeight) / float64(verticalLayout.Sum.Height)) } + g.viewDimensions[Top] = tui.D(0, 0, buf.Width(), topHeight) view.Draw(buf.Sub(0, 0, buf.Width(), topHeight)) } @@ -88,6 +92,7 @@ func (g *BorderLayout) Draw(buf *tui.ViewBuffer) { bottomHeight = int(float64(buf.Height()) * float64(bottomHeight) / float64(verticalLayout.Sum.Height)) } + g.viewDimensions[Bottom] = tui.D(0, buf.Height()-bottomHeight, buf.Width(), bottomHeight) view.Draw(buf.Sub(0, buf.Height()-bottomHeight, buf.Width(), bottomHeight)) } @@ -100,6 +105,7 @@ func (g *BorderLayout) Draw(buf *tui.ViewBuffer) { leftWidth = int(float64(buf.Width()) * float64(leftWidth) / float64(horizontalLayout.Sum.Width)) } + g.viewDimensions[Left] = tui.D(0, topHeight, leftWidth, buf.Height()-topHeight-bottomHeight) view.Draw(buf.Sub(0, topHeight, leftWidth, buf.Height()-topHeight-bottomHeight)) } @@ -112,10 +118,12 @@ func (g *BorderLayout) Draw(buf *tui.ViewBuffer) { rightWidth = int(float64(buf.Width()) * float64(rightWidth) / float64(horizontalLayout.Sum.Width)) } + g.viewDimensions[Right] = tui.D(buf.Width()-rightWidth, topHeight, rightWidth, buf.Height()-topHeight-bottomHeight) view.Draw(buf.Sub(buf.Width()-rightWidth, topHeight, rightWidth, buf.Height()-topHeight-bottomHeight)) } if view, ok := g.views[Center]; ok { + g.viewDimensions[Center] = tui.D(leftWidth, topHeight, buf.Width()-leftWidth-rightWidth, buf.Height()-topHeight-bottomHeight) view.Draw(buf.Sub(leftWidth, topHeight, buf.Width()-leftWidth-rightWidth, buf.Height()-topHeight-bottomHeight)) } @@ -138,6 +146,16 @@ func (g *BorderLayout) OnKeyPressed(event *tui.KeyEvent) (consumed bool) { return false } +func (g *BorderLayout) OnMouseClicked(event *tui.MouseEvent) (consumed bool) { + for slot, dim := range g.viewDimensions { + if event.Position.In(dim) { + g.views[slot].OnMouseClicked(event) + return true + } + } + return false +} + type Slot uint8 const ( diff --git a/views/layout_coord.go b/views/layout_coord.go index e744f8f..0eb5b0e 100644 --- a/views/layout_coord.go +++ b/views/layout_coord.go @@ -48,3 +48,5 @@ func (g *CoordLayout) OnKeyPressed(event *tui.KeyEvent) (consumed bool) { } return false } + +// TODO OnMouseClicked diff --git a/views/layout_flow.go b/views/layout_flow.go index 6574f19..a1b6033 100644 --- a/views/layout_flow.go +++ b/views/layout_flow.go @@ -142,3 +142,5 @@ func (g *FlowLayout) OnKeyPressed(event *tui.KeyEvent) (consumed bool) { } return false } + +// TODO OnMouseClicked diff --git a/views/layout_separator.go b/views/layout_separator.go index 2110d25..77ba4f5 100644 --- a/views/layout_separator.go +++ b/views/layout_separator.go @@ -109,3 +109,5 @@ func (g *SeperatorLayout) OnKeyPressed(event *tui.KeyEvent) (consumed bool) { } return false } + +// TODO OnMouseClicked