1// Composable layout elements that can be combined together to create renderable 2// UI layouts. 3syntax = "proto3"; 4 5package androidx.wear.tiles.testing.proto; 6 7import "color.proto"; 8import "dimension.proto"; 9import "modifiers.proto"; 10import "types.proto"; 11 12option java_package = "androidx.wear.tiles.testing.proto"; 13option java_outer_classname = "LayoutElementProto"; 14 15// The horizontal alignment of an element within its container. 16enum HorizontalAlignment { 17 // Horizontal alignment is undefined. 18 HORIZONTAL_ALIGN_UNDEFINED = 0; 19 20 // Horizontally align to the left. 21 HORIZONTAL_ALIGN_LEFT = 1; 22 23 // Horizontally align to center. 24 HORIZONTAL_ALIGN_CENTER = 2; 25 26 // Horizontally align to the right. 27 HORIZONTAL_ALIGN_RIGHT = 3; 28 29 // Horizontally align to the content start (left in LTR layouts, right in RTL 30 // layouts). 31 HORIZONTAL_ALIGN_START = 4; 32 33 // Horizontally align to the content end (right in LTR layouts, left in RTL 34 // layouts). 35 HORIZONTAL_ALIGN_END = 5; 36} 37 38// An extensible HorizontalAlignment property. 39message HorizontalAlignmentProp { 40 // The value 41 HorizontalAlignment value = 1; 42} 43 44// The vertical alignment of an element within its container. 45enum VerticalAlignment { 46 // Vertical alignment is undefined. 47 VERTICAL_ALIGN_UNDEFINED = 0; 48 49 // Vertically align to the top. 50 VERTICAL_ALIGN_TOP = 1; 51 52 // Vertically align to center. 53 VERTICAL_ALIGN_CENTER = 2; 54 55 // Vertically align to the bottom. 56 VERTICAL_ALIGN_BOTTOM = 3; 57} 58 59// An extensible VerticalAlignment property. 60message VerticalAlignmentProp { 61 // The value. 62 VerticalAlignment value = 1; 63} 64 65// The weight to be applied to the font. 66enum FontWeight { 67 // Font weight is undefined. 68 FONT_WEIGHT_UNDEFINED = 0; 69 70 // Normal font weight. 71 FONT_WEIGHT_NORMAL = 400; 72 73 // Bold font weight. 74 FONT_WEIGHT_BOLD = 700; 75} 76 77// An extensible FontWeight property. 78message FontWeightProp { 79 // The value. 80 FontWeight value = 1; 81} 82 83// The styling of a font (e.g. font size, and metrics). 84message FontStyle { 85 // The size of the font, in scaled pixels (sp). If not specified, defaults to 86 // the size of the system's "body" font. 87 SpProp size = 1; 88 89 // Whether the text should be rendered in a italic typeface. If not specified, 90 // defaults to "false". 91 BoolProp italic = 2; 92 93 // Whether the text should be rendered with an underline. If not specified, 94 // defaults to "false". 95 BoolProp underline = 3; 96 97 // The text color. If not defined, defaults to white. 98 ColorProp color = 4; 99 100 // The weight of the font. If the provided value is not supported on a 101 // platform, the nearest supported value will be used. If not defined, or 102 // when set to an invalid value, defaults to "normal". 103 FontWeightProp weight = 5; 104 105 // The text letter-spacing. Positive numbers increase the space between 106 // letters while negative numbers tighten the space. If not specified, 107 // defaults to 0. 108 EmProp letter_spacing = 6; 109} 110 111// Alignment of a text element. 112enum TextAlignment { 113 // Alignment is undefined. 114 TEXT_ALIGN_UNDEFINED = 0; 115 116 // Align to the "start" of the Text element (left in LTR layouts, right in 117 // RTL layouts). 118 TEXT_ALIGN_START = 1; 119 120 // Align to the center of the Text element. 121 TEXT_ALIGN_CENTER = 2; 122 123 // Align to the "end" of the Text element (right in LTR layouts, left in RTL 124 // layouts). 125 TEXT_ALIGN_END = 3; 126} 127 128// An extensible TextAlignment property. 129message TextAlignmentProp { 130 // The value. 131 TextAlignment value = 1; 132} 133 134// How text that will not fit inside the bounds of a Text element will be 135// handled. 136// 137// TODO(b/175536688): Rename this to align with Spannable 138enum TextOverflow { 139 // Overflow behavior is undefined. 140 TEXT_OVERFLOW_UNDEFINED = 0; 141 142 // Truncate the text to fit inside of the Text element's bounds. If text is 143 // truncated, it will be truncated on a word boundary. 144 TEXT_OVERFLOW_TRUNCATE = 1; 145 146 // Truncate the text to fit in the Text element's bounds, but add an ellipsis 147 // (i.e. ...) to the end of the text if it has been truncated. 148 TEXT_OVERFLOW_ELLIPSIZE_END = 2; 149} 150 151// An extensible TextOverflow property. 152message TextOverflowProp { 153 // The value. 154 TextOverflow value = 1; 155} 156 157// The anchor position of an Arc's elements. This is used to specify how 158// elements added to an Arc should be laid out with respect to anchor_angle. 159// 160// As an example, assume that the following diagrams are wrapped to an arc, and 161// each represents an Arc element containing a single Text element. The Text 162// element's anchor_angle is "0" for all cases. 163// 164// ``` 165// ARC_ANCHOR_START: 166// -180 0 180 167// Hello World! 168// 169// 170// ARC_ANCHOR_CENTER: 171// -180 0 180 172// Hello World! 173// 174// ARC_ANCHOR_END: 175// -180 0 180 176// Hello World! 177// ``` 178enum ArcAnchorType { 179 // Anchor position is undefined. 180 ARC_ANCHOR_UNDEFINED = 0; 181 182 // Anchor at the start of the elements. This will cause elements added to an 183 // arc to begin at the given anchor_angle, and sweep around to the right. 184 ARC_ANCHOR_START = 1; 185 186 // Anchor at the center of the elements. This will cause the center of the 187 // whole set of elements added to an arc to be pinned at the given 188 // anchor_angle. 189 ARC_ANCHOR_CENTER = 2; 190 191 // Anchor at the end of the elements. This will cause the set of elements 192 // inside the arc to end at the specified anchor_angle, i.e. all elements 193 // should be to the left of anchor_angle. 194 ARC_ANCHOR_END = 3; 195} 196 197// An extensible ArcAnchorType property. 198message ArcAnchorTypeProp { 199 // The value. 200 ArcAnchorType value = 1; 201} 202 203// A text string. 204message Text { 205 // The text to render. 206 StringProp text = 1; 207 208 // The style of font to use (size, bold etc). If not specified, defaults to 209 // the platform's default body font. 210 FontStyle font_style = 2; 211 212 // Modifiers for this element. 213 Modifiers modifiers = 3; 214 215 // The maximum number of lines that can be represented by the Text element. 216 // If not defined, the Text element will be treated as a single-line element. 217 Int32Prop max_lines = 4; 218 219 // Alignment of the text within its bounds. Note that a Text element will size 220 // itself to wrap its contents, so this option is meaningless for single-line 221 // text (for that, use alignment of the outer container). For multi-line text, 222 // however, this will set the alignment of lines relative to the Text element 223 // bounds. If not defined, defaults to TEXT_ALIGN_CENTER. 224 TextAlignmentProp multiline_alignment = 5; 225 226 // How to handle text which overflows the bound of the Text element. 227 // A Text element will grow as large as possible inside its parent container 228 // (while still respecting max_lines); if it cannot grow large enough to 229 // render all of its text, the text which cannot fit inside its container will 230 // be truncated. If not defined, defaults to TEXT_OVERFLOW_TRUNCATE. 231 TextOverflowProp overflow = 6; 232 233 // The explicit height between lines of text. This is equivalent to the 234 // vertical distance between subsequent baselines. If not specified, defaults 235 // the font's recommended interline spacing. 236 SpProp line_height = 7; 237} 238 239// How content which does not match the dimensions of its bounds (e.g. an image 240// resource being drawn inside an Image) will be resized to fit its bounds. 241enum ContentScaleMode { 242 // Content scaling is undefined. 243 CONTENT_SCALE_MODE_UNDEFINED = 0; 244 245 // Content will be scaled to fit inside its bounds, proportionally. As an 246 // example, If a 10x5 image was going to be drawn inside a 50x50 Image 247 // element, the actual image resource would be drawn as a 50x25 image, 248 // centered within the 50x50 bounds. 249 CONTENT_SCALE_MODE_FIT = 1; 250 251 // Content will be resized proportionally so it completely fills its bounds, 252 // and anything outside of the bounds will be cropped. As an example, if a 253 // 10x5 image was going to be drawn inside a 50x50 Image element, the image 254 // resource would be drawn as a 100x50 image, centered within its bounds (and 255 // with 25px cropped from both the left and right sides). 256 CONTENT_SCALE_MODE_CROP = 2; 257 258 // Content will be resized to fill its bounds, without taking into account the 259 // aspect ratio. If a 10x5 image was going to be drawn inside a 50x50 Image 260 // element, the image would be drawn as a 50x50 image, stretched vertically. 261 CONTENT_SCALE_MODE_FILL_BOUNDS = 3; 262} 263 264// An extensible ContentScaleMode property. 265message ContentScaleModeProp { 266 ContentScaleMode value = 1; 267} 268 269// An image. 270// 271// Images used in this element must exist in the resource bundle that 272// corresponds to this layout. Images must have their dimension specified, and 273// will be rendered at this width and height, regardless of their native 274// dimension. 275message Image { 276 // The resource_id of the image to render. This must exist in the supplied 277 // resource bundle. 278 StringProp resource_id = 1; 279 280 // The width of this image. If not defined, the image will not be rendered. 281 ImageDimension width = 2; 282 283 // The height of this image. If not defined, the image will not be rendered. 284 ImageDimension height = 3; 285 286 // How to scale the image resource inside the bounds specified by width/height 287 // if its size does not match those bounds. Defaults to 288 // CONTENT_SCALE_MODE_FIT. 289 ContentScaleModeProp content_scale_mode = 4; 290 291 // Modifiers for this element. 292 Modifiers modifiers = 5; 293} 294 295// A simple spacer, typically used to provide padding between adjacent elements. 296message Spacer { 297 // The width of this Spacer. When this is added as the direct child of an Arc, 298 // this must be specified as an angular dimension, otherwise a linear 299 // dimension must be used. If not defined, defaults to 0. 300 SpacerDimension width = 1; 301 302 // The height of this spacer. If not defined, defaults to 0. 303 SpacerDimension height = 2; 304 305 // Modifiers for this element. 306 Modifiers modifiers = 3; 307} 308 309// A container which stacks all of its children on top of one another. This also 310// allows to add a background color, or to have a border around them with some 311// padding. 312message Box { 313 // The child element(s) to wrap. 314 repeated LayoutElement contents = 1; 315 316 // The height of this Box. If not defined, this will size itself to fit all of 317 // its children (i.e. a WrappedDimension). 318 ContainerDimension height = 2; 319 320 // The width of this Box. If not defined, this will size itself to fit all of 321 // its children (i.e. a WrappedDimension). 322 ContainerDimension width = 3; 323 324 // The horizontal alignment of the element inside this Box. If not defined, 325 // defaults to HORIZONTAL_ALIGN_CENTER. 326 HorizontalAlignmentProp horizontal_alignment = 4; 327 328 // The vertical alignment of the element inside this Box. If not defined, 329 // defaults to VERTICAL_ALIGN_CENTER. 330 VerticalAlignmentProp vertical_alignment = 5; 331 332 // Modifiers for this element. 333 Modifiers modifiers = 6; 334} 335 336// A portion of text which can be added to a Span. Two different SpanText 337// elements on the same line will be aligned to the same baseline, regardless of 338// the size of each SpanText. 339message SpanText { 340 // The text to render. 341 StringProp text = 1; 342 343 // The style of font to use (size, bold etc). If not specified, defaults to 344 // the platform's default body font. 345 FontStyle font_style = 2; 346 347 // Modifiers for this element. 348 SpanModifiers modifiers = 3; 349} 350 351// An image which can be added to a Span. 352message SpanImage { 353 // The resource_id of the image to render. This must exist in the supplied 354 // resource bundle. 355 StringProp resource_id = 1; 356 357 // The width of this image. If not defined, the image will not be rendered. 358 DpProp width = 2; 359 360 // The height of this image. If not defined, the image will not be rendered. 361 DpProp height = 3; 362 363 // Modifiers for this element. 364 SpanModifiers modifiers = 4; 365} 366 367// A single Span. Each Span forms part of a larger Spannable widget. At the 368// moment, the only widgets which can be added to Spannable containers are 369// SpanText and SpanImage elements. 370message Span { 371 oneof inner { 372 SpanText text = 1; 373 SpanImage image = 2; 374 } 375} 376 377// A container of Span elements. Currently, this only supports Text elements, 378// where each individual Span can have different styling applied to it but the 379// resulting text will flow naturally. This allows sections of a paragraph of 380// text to have different styling applied to it, for example, making one or two 381// words bold or italic. 382message Spannable { 383 // The Span elements that form this Spannable. 384 repeated Span spans = 1; 385 386 // Modifiers for this element. 387 Modifiers modifiers = 2; 388 389 // The maximum number of lines that can be represented by the Spannable 390 // element. If not defined, the Spannable element will be treated as a 391 // single-line element. 392 Int32Prop max_lines = 3; 393 394 // Alignment of the Spannable content within its bounds. Note that a Spannable 395 // element will size itself to wrap its contents, so this option is 396 // meaningless for single-line content (for that, use alignment of the outer 397 // container). For multi-line content, however, this will set the alignment of 398 // lines relative to the Spannable element bounds. If not defined, defaults to 399 // TEXT_ALIGN_CENTER. 400 HorizontalAlignmentProp multiline_alignment = 4; 401 402 // How to handle content which overflows the bound of the Spannable element. 403 // A Spannable element will grow as large as possible inside its parent 404 // container (while still respecting max_lines); if it cannot grow large 405 // enough to render all of its content, the content which cannot fit inside 406 // its container will be truncated. If not defined, defaults to 407 // TEXT_OVERFLOW_TRUNCATE. 408 TextOverflowProp overflow = 5; 409 410 // Extra spacing to add between each line. This will apply to all 411 // spans regardless of their font size. This is in addition to original 412 // line heights. Note that this won't add any additional space before the 413 // first line or after the last line. The default value is zero and negative 414 // values will decrease the interline spacing. 415 SpProp line_spacing = 6; 416} 417 418// A column of elements. Each child element will be laid out vertically, one 419// after another (i.e. stacking down). This element will size itself to the 420// smallest size required to hold all of its children (e.g. if it contains three 421// elements sized 10x10, 20x20 and 30x30, the resulting column will be 30x60). 422// 423// If specified, horizontal_alignment can be used to control the gravity inside 424// the container, affecting the horizontal placement of children whose width are 425// smaller than the resulting column width. 426message Column { 427 // The list of child elements to place inside this Column. 428 repeated LayoutElement contents = 1; 429 430 // The horizontal alignment of elements inside this column, if they are 431 // narrower than the resulting width of the column. If not defined, defaults 432 // to HORIZONTAL_ALIGN_CENTER. 433 HorizontalAlignmentProp horizontal_alignment = 2; 434 435 // The width of this column. If not defined, this will size itself to fit 436 // all of its children (i.e. a WrappedDimension). 437 ContainerDimension width = 3; 438 439 // The height of this column. If not defined, this will size itself to fit 440 // all of its children (i.e. a WrappedDimension). 441 ContainerDimension height = 4; 442 443 // Modifiers for this element. 444 Modifiers modifiers = 5; 445} 446 447// A row of elements. Each child will be laid out horizontally, one after 448// another (i.e. stacking to the right). This element will size itself to the 449// smallest size required to hold all of its children (e.g. if it contains three 450// elements sized 10x10, 20x20 and 30x30, the resulting row will be 60x30). 451// 452// If specified, vertical_alignment can be used to control the gravity inside 453// the container, affecting the vertical placement of children whose width are 454// smaller than the resulting row height. 455message Row { 456 // The list of child elements to place inside this Row. 457 repeated LayoutElement contents = 1; 458 459 // The vertical alignment of elements inside this row, if they are narrower 460 // than the resulting height of the row. If not defined, defaults to 461 // VERTICAL_ALIGN_CENTER. 462 VerticalAlignmentProp vertical_alignment = 2; 463 464 // The width of this row. If not defined, this will size itself to fit 465 // all of its children (i.e. a WrappedDimension). 466 ContainerDimension width = 3; 467 468 // The height of this row. If not defined, this will size itself to fit 469 // all of its children (i.e. a WrappedDimension). 470 ContainerDimension height = 4; 471 472 // Modifiers for this element. 473 Modifiers modifiers = 5; 474} 475 476// An arc container. This container will fill itself to a circle, which fits 477// inside its parent container, and all of its children will be placed on that 478// circle. The fields anchor_angle and anchor_type can be used to specify where 479// to draw children within this circle. 480message Arc { 481 // Contents of this container. 482 repeated ArcLayoutElement contents = 1; 483 484 // The angle for the anchor, used with anchor_type to determine where to draw 485 // children. Note that 0 degrees is the 12 o clock position on a device, and 486 // the angle sweeps clockwise. If not defined, defaults to 0 degrees. 487 // 488 // Values do not have to be clamped to the range 0-360; values less than 0 489 // degrees will sweep anti-clockwise (i.e. -90 degrees is equivalent to 270 490 // degrees), and values >360 will be be placed at X mod 360 degrees. 491 DegreesProp anchor_angle = 2; 492 493 // How to align the contents of this container relative to anchor_angle. See 494 // the descriptions of options in ArcAnchorType for more information. If not 495 // defined, defaults to ARC_ANCHOR_CENTER. 496 ArcAnchorTypeProp anchor_type = 3; 497 498 // Vertical alignment of elements within the arc. If the Arc's thickness is 499 // larger than the thickness of the element being drawn, this controls whether 500 // the element should be drawn towards the inner or outer edge of the arc, or 501 // drawn in the center. 502 // If not defined, defaults to VERTICAL_ALIGN_CENTER 503 VerticalAlignmentProp vertical_align = 4; 504 505 // Modifiers for this element. 506 Modifiers modifiers = 5; 507} 508 509// A text element that can be used in an Arc. 510message ArcText { 511 // The text to render. 512 StringProp text = 1; 513 514 // The style of font to use (size, bold etc). If not specified, defaults to 515 // the platform's default body font. 516 FontStyle font_style = 2; 517 518 // Modifiers for this element. 519 ArcModifiers modifiers = 3; 520} 521 522// A line that can be used in an Arc and renders as a round progress bar. 523message ArcLine { 524 // The length of this line, in degrees. If not defined, defaults to 0. 525 DegreesProp length = 1; 526 527 // The thickness of this line. If not defined, defaults to 0. 528 DpProp thickness = 2; 529 530 // The color of this line. 531 ColorProp color = 3; 532 533 // Modifiers for this element. 534 ArcModifiers modifiers = 4; 535} 536 537// A simple spacer used to provide padding between adjacent elements in an Arc. 538message ArcSpacer { 539 // The length of this spacer, in degrees. If not defined, defaults to 0. 540 DegreesProp length = 1; 541 542 // The thickness of this spacer, in DP. If not defined, defaults to 0. 543 DpProp thickness = 2; 544 545 // Modifiers for this element. 546 ArcModifiers modifiers = 3; 547} 548 549// A container that allows a standard LayoutElement to be added to an Arc. 550message ArcAdapter { 551 // The element to adapt to an Arc. 552 LayoutElement content = 1; 553 554 // Whether this adapter's contents should be rotated, according to its 555 // position in the arc or not. As an example, assume that an Image has been 556 // added to the arc, and ends up at the 3 o clock position. If rotate_contents 557 // = true, the image will be placed at the 3 o clock position, and will be 558 // rotated clockwise through 90 degrees. If rotate_contents = false, the image 559 // will be placed at the 3 o clock position, but itself will not be rotated. 560 // If not defined, defaults to false. 561 BoolProp rotate_contents = 2; 562} 563 564// The root of all layout elements. This exists to act as a holder for all of 565// the actual layout elements above. 566message LayoutElement { 567 oneof inner { 568 Column column = 1; 569 Row row = 2; 570 Box box = 3; 571 Spacer spacer = 4; 572 Text text = 5; 573 Image image = 6; 574 Arc arc = 7; 575 Spannable spannable = 8; 576 } 577} 578 579// The root of all elements that can be used in an Arc. This exists to act as a 580// holder for all of the actual arc layout elements above. 581message ArcLayoutElement { 582 oneof inner { 583 ArcText text = 1; 584 ArcLine line = 2; 585 ArcSpacer spacer = 3; 586 ArcAdapter adapter = 4; 587 } 588} 589 590// A complete layout. 591message Layout { 592 // The root element in the layout. 593 LayoutElement root = 1; 594} 595