I keep forgetting to commit stuff
This commit is contained in:
parent
8d7d9882ba
commit
c0bfa76ba6
@ -16,7 +16,7 @@ type Button struct {
|
|||||||
// NewButton creates a new button with the specified text.
|
// NewButton creates a new button with the specified text.
|
||||||
func NewButton (text string) *Button {
|
func NewButton (text string) *Button {
|
||||||
box := &Button { TextBox: tomo.NewTextBox() }
|
box := &Button { TextBox: tomo.NewTextBox() }
|
||||||
theme.Apply(box, theme.R("objects", "Button"))
|
theme.Apply(box, theme.R("objects", "Button", ""))
|
||||||
box.SetText(text)
|
box.SetText(text)
|
||||||
box.SetAlign(tomo.AlignMiddle, tomo.AlignMiddle)
|
box.SetAlign(tomo.AlignMiddle, tomo.AlignMiddle)
|
||||||
box.OnMouseUp(box.handleMouseUp)
|
box.OnMouseUp(box.handleMouseUp)
|
||||||
|
39
container.go
Normal file
39
container.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package objects
|
||||||
|
|
||||||
|
import "git.tebibyte.media/tomo/tomo"
|
||||||
|
import "git.tebibyte.media/tomo/tomo/theme"
|
||||||
|
|
||||||
|
// Container is an object that can contain other objects. It can be used as a
|
||||||
|
// primitive for building more complex layouts. It has two variants: an outer
|
||||||
|
// container, and an inner container. The outer container has padding around
|
||||||
|
// its edges, whereas the inner container does not. The container will have a
|
||||||
|
// corresponding object role variation of either "outer" or "inner".
|
||||||
|
type Container struct {
|
||||||
|
tomo.ContainerBox
|
||||||
|
}
|
||||||
|
|
||||||
|
func newContainer (layout tomo.Layout, children ...tomo.Object) *Container {
|
||||||
|
this := &Container {
|
||||||
|
ContainerBox: tomo.NewContainerBox(),
|
||||||
|
}
|
||||||
|
this.SetLayout(layout)
|
||||||
|
for _, child := range children {
|
||||||
|
this.Add(child)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOuterContainer creates a new container that has padding around it.
|
||||||
|
func NewOuterContainer (layout tomo.Layout, children ...tomo.Object) *Container {
|
||||||
|
this := newContainer(layout, children...)
|
||||||
|
theme.Apply(this, theme.R("objects", "Container", "outer"))
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInnerContainer creates a new container that has no padding around it.
|
||||||
|
func NewInnerContainer (layout tomo.Layout, children ...tomo.Object) *Container {
|
||||||
|
this := newContainer(layout, children...)
|
||||||
|
theme.Apply(this, theme.R("objects", "Container", "inner"))
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
4
go.mod
4
go.mod
@ -2,6 +2,6 @@ module git.tebibyte.media/tomo/objects
|
|||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require git.tebibyte.media/tomo/tomo v0.20.0
|
require git.tebibyte.media/tomo/tomo v0.23.0
|
||||||
|
|
||||||
require golang.org/x/image v0.8.0 // indirect
|
require golang.org/x/image v0.11.0 // indirect
|
||||||
|
10
go.sum
10
go.sum
@ -1,10 +1,10 @@
|
|||||||
git.tebibyte.media/tomo/tomo v0.20.0 h1:dJJWmCAj/8XtbxjiCkgykP2vNCeP5zuvMEKGChbQ0AI=
|
git.tebibyte.media/tomo/tomo v0.23.0 h1:OZwI4oLKMP7JqFc98VxBoRxwjL+W9NyTQZLB/m1BvaA=
|
||||||
git.tebibyte.media/tomo/tomo v0.20.0/go.mod h1:lTwjpiHbP4UN/kFw+6FwhG600B+PMKVtMOr7wpd5IUY=
|
git.tebibyte.media/tomo/tomo v0.23.0/go.mod h1:C9EzepS9wjkTJjnZaPBh22YvVPyA4hbBAJVU20Rdmps=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/image v0.8.0 h1:agUcRXV/+w6L9ryntYYsF2x9fQTMd4T8fiiYXAVW6Jg=
|
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||||
golang.org/x/image v0.8.0/go.mod h1:PwLxp3opCYg4WR2WO9P0L6ESnsD6bLTWcw8zanLMVFM=
|
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@ -27,7 +27,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
23
heading.go
Normal file
23
heading.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package objects
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
import "git.tebibyte.media/tomo/tomo"
|
||||||
|
import "git.tebibyte.media/tomo/tomo/theme"
|
||||||
|
|
||||||
|
// Heading is a label that denotes the start of some section of content. It can
|
||||||
|
// have a level from 0 to 2, with 0 being the most prominent and 2 being the
|
||||||
|
// most subtle. The level is described in the role variation.
|
||||||
|
type Heading struct {
|
||||||
|
tomo.TextBox
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHeading creates a new section heading. The level can be from 0 to 2.
|
||||||
|
func NewHeading (level int, text string) *Label {
|
||||||
|
if level < 0 { level = 0 }
|
||||||
|
if level > 2 { level = 2 }
|
||||||
|
this := &Label { TextBox: tomo.NewTextBox() }
|
||||||
|
theme.Apply(this, theme.R("objects", "Heading", fmt.Sprint(level)))
|
||||||
|
this.SetText(text)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
2
input.go
2
input.go
@ -18,7 +18,7 @@ type TextInput struct {
|
|||||||
// NewTextInput creates a new text input containing the specified text.
|
// NewTextInput creates a new text input containing the specified text.
|
||||||
func NewTextInput (text string) *TextInput {
|
func NewTextInput (text string) *TextInput {
|
||||||
this := &TextInput { TextBox: tomo.NewTextBox() }
|
this := &TextInput { TextBox: tomo.NewTextBox() }
|
||||||
theme.Apply(this, theme.R("objects", "TextInput"))
|
theme.Apply(this, theme.R("objects", "TextInput", ""))
|
||||||
this.SetText(text)
|
this.SetText(text)
|
||||||
this.SetFocusable(true)
|
this.SetFocusable(true)
|
||||||
this.SetSelectable(true)
|
this.SetSelectable(true)
|
||||||
|
2
label.go
2
label.go
@ -11,7 +11,7 @@ type Label struct {
|
|||||||
// NewLabel creates a new text label.
|
// NewLabel creates a new text label.
|
||||||
func NewLabel (text string) *Label {
|
func NewLabel (text string) *Label {
|
||||||
this := &Label { TextBox: tomo.NewTextBox() }
|
this := &Label { TextBox: tomo.NewTextBox() }
|
||||||
theme.Apply(this, theme.R("objects", "Label"))
|
theme.Apply(this, theme.R("objects", "Label", ""))
|
||||||
this.SetText(text)
|
this.SetText(text)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
88
layouts/layouts.go
Normal file
88
layouts/layouts.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package layouts
|
||||||
|
|
||||||
|
import "image"
|
||||||
|
import "git.tebibyte.media/tomo/tomo"
|
||||||
|
|
||||||
|
type Row struct { }
|
||||||
|
|
||||||
|
func (Row) MinimumSize (hints tomo.LayoutHints, boxes []tomo.Box) image.Point {
|
||||||
|
dot := image.Point { }
|
||||||
|
for _, box := range boxes {
|
||||||
|
minimum := box.MinimumSize()
|
||||||
|
dot.X += minimum.X
|
||||||
|
if dot.Y < minimum.Y {
|
||||||
|
dot.Y = minimum.Y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dot.X += hints.Gap.X * (len(boxes) - 1)
|
||||||
|
return dot
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Row) Arrange (hints tomo.LayoutHints, boxes []tomo.Box) {
|
||||||
|
// TODO respect alignment value
|
||||||
|
dot := hints.Bounds.Min
|
||||||
|
for index, box := range boxes {
|
||||||
|
if index > 0 { dot.X += hints.Gap.X }
|
||||||
|
minimum := box.MinimumSize()
|
||||||
|
box.SetBounds(image.Rectangle {
|
||||||
|
Min: dot,
|
||||||
|
Max: dot.Add(image.Pt(minimum.X, hints.Bounds.Dy())),
|
||||||
|
})
|
||||||
|
dot.X += minimum.X
|
||||||
|
}
|
||||||
|
|
||||||
|
width := dot.X - hints.Bounds.Min.X
|
||||||
|
offset := 0
|
||||||
|
|
||||||
|
switch hints.AlignX {
|
||||||
|
case tomo.AlignMiddle:
|
||||||
|
offset = (hints.Bounds.Dx() - width) / 2
|
||||||
|
case tomo.AlignEnd:
|
||||||
|
offset = hints.Bounds.Dx() - width
|
||||||
|
}
|
||||||
|
for _, box := range boxes {
|
||||||
|
box.SetBounds(box.Bounds().Add(image.Pt(offset, 0)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Column struct { }
|
||||||
|
|
||||||
|
func (Column) MinimumSize (hints tomo.LayoutHints, boxes []tomo.Box) image.Point {
|
||||||
|
dot := image.Point { }
|
||||||
|
for _, box := range boxes {
|
||||||
|
minimum := box.MinimumSize()
|
||||||
|
dot.Y += minimum.Y
|
||||||
|
if dot.X < minimum.X {
|
||||||
|
dot.X = minimum.X
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dot.Y += hints.Gap.Y * (len(boxes) - 1)
|
||||||
|
return dot
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Column) Arrange (hints tomo.LayoutHints, boxes []tomo.Box) {
|
||||||
|
// TODO respect alignment value
|
||||||
|
dot := hints.Bounds.Min
|
||||||
|
for index, box := range boxes {
|
||||||
|
if index > 0 { dot.Y += hints.Gap.Y }
|
||||||
|
minimum := box.MinimumSize()
|
||||||
|
box.SetBounds(image.Rectangle {
|
||||||
|
Min: dot,
|
||||||
|
Max: dot.Add(image.Pt(hints.Bounds.Dx(), minimum.Y)),
|
||||||
|
})
|
||||||
|
dot.Y += minimum.Y
|
||||||
|
}
|
||||||
|
|
||||||
|
height := dot.Y - hints.Bounds.Min.Y
|
||||||
|
offset := 0
|
||||||
|
|
||||||
|
switch hints.AlignY {
|
||||||
|
case tomo.AlignMiddle:
|
||||||
|
offset = (hints.Bounds.Dy() - height) / 2
|
||||||
|
case tomo.AlignEnd:
|
||||||
|
offset = hints.Bounds.Dy() - height
|
||||||
|
}
|
||||||
|
for _, box := range boxes {
|
||||||
|
box.SetBounds(box.Bounds().Add(image.Pt(0, offset)))
|
||||||
|
}
|
||||||
|
}
|
15
separator.go
Normal file
15
separator.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package objects
|
||||||
|
|
||||||
|
import "git.tebibyte.media/tomo/tomo"
|
||||||
|
import "git.tebibyte.media/tomo/tomo/theme"
|
||||||
|
|
||||||
|
// Separator is a line for visually separating elements.
|
||||||
|
type Separator tomo.Box
|
||||||
|
|
||||||
|
// NewSeparator creates a new text label.
|
||||||
|
func NewSeparator () Separator {
|
||||||
|
this := Separator(tomo.NewBox())
|
||||||
|
theme.Apply(this, theme.R("objects", "Separator", ""))
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
38
slider.go
Normal file
38
slider.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package objects
|
||||||
|
|
||||||
|
import "git.tebibyte.media/tomo/tomo"
|
||||||
|
import "git.tebibyte.media/tomo/tomo/theme"
|
||||||
|
|
||||||
|
|
||||||
|
type Slider struct {
|
||||||
|
tomo.ContainerBox
|
||||||
|
handle *SliderHandle
|
||||||
|
vertical bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type SliderHandle struct {
|
||||||
|
tomo.Box
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSlider (orient string) *Slider {
|
||||||
|
this := &Slider {
|
||||||
|
ContainerBox: tomo.NewContainerBox(),
|
||||||
|
handle: &SliderHandle {
|
||||||
|
Box: tomo.NewBox(),
|
||||||
|
},
|
||||||
|
vertical: orient == "vertical",
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Add(this.handle)
|
||||||
|
theme.Apply(this.handle, theme.R("objects", "SliderHandle", orient))
|
||||||
|
theme.Apply(this, theme.R("objects", "Slider", orient))
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewVerticalSlider () *Slider {
|
||||||
|
return newSlider("vertical")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHorizontalSlider () *Slider {
|
||||||
|
return newSlider("horizontal")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user