save cloud innerbox aspect ratio

This commit is contained in:
Gavin Nishizawa 2023-11-16 18:08:33 -08:00
parent ade01c8c54
commit b9a5dad820
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD
8 changed files with 41 additions and 5 deletions

View file

@ -167,6 +167,10 @@ func toShape(obj *d2graph.Object, theme *d2themes.Theme) d2target.Shape {
case d2target.ShapeSQLTable: case d2target.ShapeSQLTable:
shape.SQLTable = *obj.SQLTable shape.SQLTable = *obj.SQLTable
shape.FontSize -= d2target.HeaderFontAdd shape.FontSize -= d2target.HeaderFontAdd
case d2target.ShapeCloud:
if obj.ContentAspectRatio != nil {
shape.ContentAspectRatio = go2.Pointer(*obj.ContentAspectRatio)
}
} }
shape.Label = text.Text shape.Label = text.Text
shape.LabelWidth = text.Dimensions.Width shape.LabelWidth = text.Dimensions.Width

View file

@ -107,6 +107,8 @@ type Object struct {
LabelPosition *string `json:"labelPosition,omitempty"` LabelPosition *string `json:"labelPosition,omitempty"`
IconPosition *string `json:"iconPosition,omitempty"` IconPosition *string `json:"iconPosition,omitempty"`
ContentAspectRatio *float64 `json:"contentAspectRatio,omitempty"`
Class *d2target.Class `json:"class,omitempty"` Class *d2target.Class `json:"class,omitempty"`
SQLTable *d2target.SQLTable `json:"sql_table,omitempty"` SQLTable *d2target.SQLTable `json:"sql_table,omitempty"`
@ -1068,13 +1070,17 @@ func (obj *Object) SizeToContent(contentWidth, contentHeight, paddingX, paddingY
obj.Width = sideLength obj.Width = sideLength
obj.Height = sideLength obj.Height = sideLength
} else if desiredHeight == 0 || desiredWidth == 0 { } else if desiredHeight == 0 || desiredWidth == 0 {
switch s.GetType() { switch shapeType {
case shape.PERSON_TYPE: case shape.PERSON_TYPE:
obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.PERSON_AR_LIMIT) obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.PERSON_AR_LIMIT)
case shape.OVAL_TYPE: case shape.OVAL_TYPE:
obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.OVAL_AR_LIMIT) obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.OVAL_AR_LIMIT)
} }
} }
if shapeType == shape.CLOUD_TYPE {
innerBox := s.GetInnerBoxForContent(contentWidth, contentHeight)
obj.ContentAspectRatio = go2.Pointer(innerBox.Width / innerBox.Height)
}
} }
func (obj *Object) OuterNearContainer() *Object { func (obj *Object) OuterNearContainer() *Object {

View file

@ -364,7 +364,11 @@ func (obj *Object) ToShape() shape.Shape {
dslShape := strings.ToLower(obj.Shape.Value) dslShape := strings.ToLower(obj.Shape.Value)
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape] shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape]
contentBox := geo.NewBox(tl, obj.Width, obj.Height) contentBox := geo.NewBox(tl, obj.Width, obj.Height)
return shape.NewShape(shapeType, contentBox) s := shape.NewShape(shapeType, contentBox)
if shapeType == shape.CLOUD_TYPE && obj.ContentAspectRatio != nil {
s.SetInnerBoxAspectRatio(*obj.ContentAspectRatio)
}
return s
} }
func (obj *Object) GetLabelTopLeft() *geo.Point { func (obj *Object) GetLabelTopLeft() *geo.Point {

View file

@ -124,7 +124,7 @@ func Layout(ctx context.Context, g *d2graph.Graph) error {
innerTL := s.GetInsidePlacement(totalWidth, totalHeight, 0, 0) innerTL := s.GetInsidePlacement(totalWidth, totalHeight, 0, 0)
// depending on the shape innerBox may be larger than totalWidth, totalHeight // depending on the shape innerBox may be larger than totalWidth, totalHeight
// if this is the case, we want to center the cells within the larger innerBox // if this is the case, we want to center the cells within the larger innerBox
innerBox := s.GetInnerBoxForContent(totalWidth, totalHeight) innerBox := s.GetInnerBox()
var resizeDx, resizeDy float64 var resizeDx, resizeDy float64
if innerBox.Width > totalWidth { if innerBox.Width > totalWidth {
resizeDx = (innerBox.Width - totalWidth) / 2 resizeDx = (innerBox.Width - totalWidth) / 2

View file

@ -932,6 +932,9 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[targetShape.Type] shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[targetShape.Type]
s := shape.NewShape(shapeType, geo.NewBox(tl, width, height)) s := shape.NewShape(shapeType, geo.NewBox(tl, width, height))
if shapeType == shape.CLOUD_TYPE && targetShape.ContentAspectRatio != nil {
s.SetInnerBoxAspectRatio(*targetShape.ContentAspectRatio)
}
var shadowAttr string var shadowAttr string
if targetShape.Shadow { if targetShape.Shadow {

View file

@ -469,6 +469,8 @@ type Shape struct {
Class Class
SQLTable SQLTable
ContentAspectRatio *float64 `json:"contentAspectRatio,omitempty"`
Text Text
LabelPosition string `json:"labelPosition,omitempty"` LabelPosition string `json:"labelPosition,omitempty"`

View file

@ -45,7 +45,9 @@ type Shape interface {
GetBox() *geo.Box GetBox() *geo.Box
GetInnerBox() *geo.Box GetInnerBox() *geo.Box
// cloud shape has different innerBoxes depending on content's aspect ratio
GetInnerBoxForContent(width, height float64) *geo.Box GetInnerBoxForContent(width, height float64) *geo.Box
SetInnerBoxAspectRatio(aspectRatio float64)
// placing a rectangle of the given size and padding inside the shape, return the position relative to the shape's TopLeft // placing a rectangle of the given size and padding inside the shape, return the position relative to the shape's TopLeft
GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point
@ -91,7 +93,11 @@ func (s baseShape) GetInnerBox() *geo.Box {
// only cloud shape needs this right now // only cloud shape needs this right now
func (s baseShape) GetInnerBoxForContent(width, height float64) *geo.Box { func (s baseShape) GetInnerBoxForContent(width, height float64) *geo.Box {
return (*s.FullShape).GetInnerBox() return nil
}
func (s baseShape) SetInnerBoxAspectRatio(aspectRatio float64) {
// only used for cloud
} }
func (s baseShape) GetInsidePlacement(_, _, paddingX, paddingY float64) geo.Point { func (s baseShape) GetInsidePlacement(_, _, paddingX, paddingY float64) geo.Point {

View file

@ -30,6 +30,7 @@ const CLOUD_SQUARE_INNER_HEIGHT = 0.663
type shapeCloud struct { type shapeCloud struct {
*baseShape *baseShape
innerBoxAspectRatio *float64
} }
func NewCloud(box *geo.Box) Shape { func NewCloud(box *geo.Box) Shape {
@ -38,14 +39,19 @@ func NewCloud(box *geo.Box) Shape {
Type: CLOUD_TYPE, Type: CLOUD_TYPE,
Box: box, Box: box,
}, },
innerBoxAspectRatio: go2.Pointer(0.),
} }
shape.FullShape = go2.Pointer(Shape(shape)) shape.FullShape = go2.Pointer(Shape(shape))
return shape return shape
} }
func (s shapeCloud) GetInnerBox() *geo.Box { func (s shapeCloud) GetInnerBox() *geo.Box {
if s.innerBoxAspectRatio != nil && *s.innerBoxAspectRatio != 0. {
return s.GetInnerBoxForContent(*s.innerBoxAspectRatio, 1)
} else {
return s.GetInnerBoxForContent(s.Box.Width, s.Box.Height) return s.GetInnerBoxForContent(s.Box.Width, s.Box.Height)
} }
}
// we need this since the content's aspect ratio determines which placement is used // we need this since the content's aspect ratio determines which placement is used
func (s shapeCloud) GetInnerBoxForContent(width, height float64) *geo.Box { func (s shapeCloud) GetInnerBoxForContent(width, height float64) *geo.Box {
@ -66,6 +72,11 @@ func (s shapeCloud) GetInnerBoxForContent(width, height float64) *geo.Box {
return geo.NewBox(&insideTL, width, height) return geo.NewBox(&insideTL, width, height)
} }
func (s shapeCloud) SetInnerBoxAspectRatio(aspectRatio float64) {
// only used for cloud
*s.innerBoxAspectRatio = aspectRatio
}
func (s shapeCloud) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { func (s shapeCloud) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) {
width += paddingX width += paddingX
height += paddingY height += paddingY