package nodeshape
import (
"math"
"github.com/pancsta/d2/lib/geo"
)
type shapeTable struct {
*shapeSquare
numColumns int
}
func NumColumns (s Shape ) int {
table , ok := s .(*shapeTable )
if !ok {
return 0
}
return table .numColumns
}
func SetNumColumns (s Shape , numColumns int ) {
if table , ok := s .(*shapeTable ); ok {
table .numColumns = numColumns
}
}
func TablePortIndex (s Shape , orientation geo .Orientation , columnIndex int ) (index int , ok bool ) {
table , ok := s .(*shapeTable )
if !ok {
return 0 , false
}
numColumns := table .numColumns
if numColumns == 0 {
numColumns = 1
}
if columnIndex < 0 || columnIndex >= numColumns {
panic ("table column port index out of range" )
}
switch orientation {
case geo .Left :
return 3 + columnIndex , true
case geo .Right :
return 6 + numColumns + columnIndex , true
default :
return 0 , false
}
}
func TableColumnPortValue (s Shape , orientation geo .Orientation , columnIndex int ) (port geo .Point , ok bool ) {
table , ok := s .(*shapeTable )
if !ok || (orientation != geo .Left && orientation != geo .Right ) {
return geo .Point {}, false
}
numColumns := table .numColumns
if numColumns == 0 {
if columnIndex != 0 {
panic ("table column port index out of range" )
}
} else if columnIndex < 0 || columnIndex >= numColumns {
panic ("table column port index out of range" )
}
yPercentage := 0.5
if numColumns > 0 {
rowHeightPercentage := 1. / (float64 (numColumns ) + 1. )
percentage := rowHeightPercentage + rowHeightPercentage /2.
for range columnIndex {
percentage += rowHeightPercentage
}
percentage = math .Round (percentage *10_000 ) / 10_000
yPercentage = geo .TruncateDecimals (percentage )
}
xPercentage := 0.0
if orientation == geo .Right {
xPercentage = 1.0
}
box := table .GetBox ()
return geo .Point {
X : box .TopLeft .X + math .Round (box .Width *xPercentage ),
Y : box .TopLeft .Y + math .Round (box .Height *yPercentage ),
}, true
}
func (s shapeTable ) SnapPointPercentages () [][]*geo .RelativePoint {
var left , right []*geo .RelativePoint
if s .numColumns == 0 {
left = []*geo .RelativePoint {geo .NewRelativePoint (0. , 0.5 )}
right = []*geo .RelativePoint {geo .NewRelativePoint (1. , 0.5 )}
} else {
left = make ([]*geo .RelativePoint , 0 , s .numColumns +1 )
right = make ([]*geo .RelativePoint , 0 , s .numColumns +1 )
rowHeightPercentage := 1. / (float64 (s .numColumns ) + 1. )
midRowPercentage := rowHeightPercentage / 2.
for perc := rowHeightPercentage + midRowPercentage ; perc < 1. ; perc += rowHeightPercentage {
h := math .Round (perc *10_000 ) / 10_000
left = append (left , geo .NewRelativePoint (0. , h ))
right = append (right , geo .NewRelativePoint (1. , h ))
}
}
return [][]*geo .RelativePoint {
{
geo .NewRelativePoint (0.25 , 0 ),
geo .NewRelativePoint (0.5 , 0 ),
geo .NewRelativePoint (0.75 , 0 ),
},
left ,
{
geo .NewRelativePoint (0.25 , 1 ),
geo .NewRelativePoint (0.5 , 1 ),
geo .NewRelativePoint (0.75 , 1 ),
},
right ,
}
}
func (s shapeTable ) CenterPortIndices () []int {
if s .numColumns > 0 {
return nil
}
return []int {
1 ,
3 ,
5 ,
7 ,
}
}
func (s shapeTable ) CenterPortIndex (o geo .Orientation ) int {
if s .numColumns > 0 {
return -1
}
centerPorts := s .CenterPortIndices ()
var centerPortsIndex int
switch o {
case geo .Top :
centerPortsIndex = 0
case geo .Left :
centerPortsIndex = 1
case geo .Bottom :
centerPortsIndex = 2
case geo .Right :
centerPortsIndex = 3
default :
return -1
}
return centerPorts [centerPortsIndex ]
}
func (s shapeTable ) MirroredPortIndices () map [int ]int {
if s .numColumns > 0 {
return nil
}
centerPorts := s .CenterPortIndices ()
return map [int ]int {
centerPorts [0 ]: centerPorts [2 ],
centerPorts [2 ]: centerPorts [0 ],
centerPorts [1 ]: centerPorts [3 ],
centerPorts [3 ]: centerPorts [1 ],
}
}
func (s shapeTable ) PortIndices (orientation geo .Orientation ) []int {
numColumns := s .numColumns
if numColumns == 0 {
numColumns = 1
}
topIndices := []int {0 , 1 , 2 }
firstLeftIndex := topIndices [2 ] + 1
leftIndices := make ([]int , numColumns )
for i := 0 ; i < numColumns ; i ++ {
leftIndices [i ] = firstLeftIndex + i
}
firstBottomIndex := leftIndices [numColumns -1 ] + 1
bottomIndices := make ([]int , 3 )
for i := 0 ; i < 3 ; i ++ {
bottomIndices [i ] = firstBottomIndex + i
}
firstRightIndex := bottomIndices [2 ] + 1
rightIndices := make ([]int , numColumns )
for i := 0 ; i < numColumns ; i ++ {
rightIndices [i ] = firstRightIndex + i
}
switch orientation {
case geo .Top :
return topIndices
case geo .Left :
return leftIndices
case geo .Bottom :
return bottomIndices
case geo .Right :
return rightIndices
case geo .TopLeft :
return append (topIndices , leftIndices ...)
case geo .TopRight :
return append (topIndices , rightIndices ...)
case geo .BottomLeft :
return append (bottomIndices , leftIndices ...)
case geo .BottomRight :
return append (bottomIndices , rightIndices ...)
default :
return []int {}
}
}
The pages are generated with Golds v0.8.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .