blob: 74065b01b278d120d4eba4ef500ee993ee09a9fc [file] [log] [blame]
// Copyright 2018 The Feed Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto2";
package search.now.ui.piet;
option optimize_for=LITE_RUNTIME;
import "src/main/proto/search/now/ui/piet/accessibility.proto";
import "src/main/proto/search/now/ui/piet/actions.proto";
import "src/main/proto/search/now/ui/piet/binding_refs.proto";
import "src/main/proto/search/now/ui/piet/images.proto";
import "src/main/proto/search/now/ui/piet/log_data.proto";
import "src/main/proto/search/now/ui/piet/styles.proto";
import "src/main/proto/search/now/ui/piet/text.proto";
option java_package = "com.google.search.now.ui.piet";
option java_outer_classname = "ElementsProto";
option cc_enable_arenas = true;
// Content is a placeholder which contains a layout Element, or something which
// resolves to a layout Element.
message Content {
// The payload of this content.
oneof content_type {
// Element, specified inline.
Element element = 1;
// A binding to look up an element.
// May have a performance penalty on some platforms.
ElementBindingRef bound_element = 2;
// An instance of a Template, represented by a TemplateInvocation.
//
// If the referenced template has several binding contexts, an Element
// instance will be created for each one.
//
// This may happen in one of two cases:
//
// The Content appears inside an ElementList, or repeated Element
// --------------------------------------------------------------
//
// For example:
// In case there's an ElementList with the following Contents:
//
// +----------------------------+
// | Template_1 |
// +----------------------------+
// | Template_2 with binding |
// | values [ a , b , c ] |
// +----------------------------+
// | Template_3 |
// +----------------------------+
//
// After the bindings are resolved, it will become:
// +----------------------------+
// | Template_1 |
// +----------------------------+
// | Template_2 {with data "a"} |
// +----------------------------+
// | Template_2 {with data "b"} |
// +----------------------------+
// | Template_2 {with data "c"} |
// +----------------------------+
// | Template_3 |
// +----------------------------+
//
// The Content appears in a GridCell
// ---------------------------------
// A GridCell is created for each invocation of the template. The created
// GridCells will be added to the GridRow containing this GridCell. The
// width of the created GridCells is duplicated from the GridCell containing
// this Content.
//
// For example:
// In case there's a GridRow with the following GridCells:
// +----------+------------------------+----------+
// | Cell | Cell with Content with | Cell |
// | | Template 2 with data | |
// | 1 | bindings {a,b,c } | 3 |
// +----------+------------------------+----------+
//
// After the bindings are resolved, it will become:
// +----------+------------+------------+------------+---------+
// | Cell | Template 2 | Template 2 | Template 2 | Cell |
// | 1 | {data "a"} | {data "b"} | {data "c"} | 3 |
// +----------+------------+------------+------------+---------+
//
//
// IMPORTANT:
// This feature may not be supported on all platforms; see [INTERNAL LINK].
TemplateInvocation template_invocation = 3;
// See comment on template field; this looks up the template based on the
// ID in the bindings.
TemplateBindingRef template_binding = 4;
}
}
// Indicates element's visibility, and the option to bind visibility state that
// overrides the default value.
// This message should be used to bind external values for controlling display
// of parts of the UI.
message VisibilityState {
// Binding of values.
optional VisibilityBindingRef overriding_bound_visibility = 1;
// The default visibility.
optional Visibility default_visibility = 2 [default = VISIBLE];
}
// Element is the "superclass" of all container and content types, holding all
// shared parameters (styles, actions, etc).
//
// Element size expands to fill its container, unless the content is taller than
// the container, and the container height is not specified explicitly. In that
// case, the Element and the container both get the height of the content.
// Next Id: 27
message Element {
// The specific content represented by this Element.
oneof elements {
/*** CONTENT ELEMENTS ***/
// An image container
ImageElement image_element = 3;
// A simple text line
TextElement text_element = 2;
/*** END CONTENT ELEMENTS ***/
/*** CONTAINER ELEMENTS ***/
// A horizontal layout of multiple items.
GridRow grid_row = 5;
// A vertical layout of multiple items.
ElementList element_list = 6;
// Multiple items stacked on top of each other (overlay).
ElementStack element_stack = 24;
/*** END CONTAINER ELEMENTS ***/
/*** NON-NATIVE ELEMENTS ***/
// A custom view that Piet knows nothing about. Servers can use this message
// to populate a custom proto extension, which Piet passes along to the Host
// for rendering. The Host is expected to be able to interpret and render
// this view and return to Piet, which then simply places it within the
// current view hierarchy at the proper position.
// If a renderer cannot be found for a particular CustomElement in a client
// implementation, Piet raises a ERR_CUSTOM_ELEMENT_RENDERER_MISSING & warns
// the user at runtime. A black/grey box is displayed in place of the
// CustomElement, but the rest of the Frame is still rendered. It is
// possible for CustomElements to invoke Piet for rendering sub-views, but
// only top-level Piet Frame protos can be embedded this way. (In other
// words, do not try to embed Piet Elements directly inside a
// CustomElement).
CustomElement custom_element = 1;
// A view that is implemented by a secondary (non-Core) Piet Module. Not all
// Piet Elements are useful to all clients/servers, so only the basic ones
// are included in Piet Core. Common shareable elements can be implemented
// in secondary Piet Modules, which are optional modules that can be
// included in or excluded from Piet-based apps on an as-needed basis.
// ModuleElements work similar to CustomElements, with the only difference
// being that CustomElements are rendered by non-Piet code, while
// ModuleElements are rendered by secondary Piet Modules.
ModuleElement module_element = 21;
/*** END NON-NATIVE ELEMENTS ***/
}
// Every UI element can have accessibility-related fields.
optional Accessibility accessibility = 11;
// Defines Actions that may be associated with the content of the Element.
// The server is responsible for ensuring that the size of this content is
// large enough to present a clear click target for the user.
oneof actions_data {
// Inlined actions.
Actions actions = 14;
// Actions coming from a template.
ActionsBindingRef actions_binding = 15;
}
// A list of Contents to be overlaid on top of this Element.
// This field is repeated to allow multiple overlay layers with different
// gravity settings. The index of the item inside the repeated field
// determines the order in which views will be laid out. Later items will
// appear above the earlier ones.
// Deprecated: To make an overlay on an Element, wrap the Element in an
// ElementStack.
repeated Content overlays = 22 [deprecated = true];
// Horizontal gravity of this element's content within the parent container
// Deprecated: use gravity_horizontal on Style instead
optional GravityHorizontal gravity_horizontal = 12 [deprecated = true];
// Vertical gravity of this element's content within the parent container
// Deprecated: use gravity_vertical on Style instead
optional GravityVertical gravity_vertical = 18 [deprecated = true];
// Defines the overflow behavior for contents that are wider than this
// Element.
// Contents can be wider than the container Element in two scenarios:
// 1. An element has defined width in its style, and the width is larger
// than the size of the Element.
// 2. The element is a GridRow, where the width sum of cells with defined dp
// width is larger than the containing Element.
//
// In all other cases, contents cannot be wider than the container
// Element.
//
// IMPORTANT: This might not be supported in all implementations of Piet, due
// to implementation/product decisions (for example, horizontal scrolling in
// a swipable card might be disabled).
optional OverflowBehavior horizontal_overflow = 16
[default = OVERFLOW_HIDDEN];
// Styles to apply to this Element. If any style_ids cannot be found,
// ERR_MISSING_STYLES is raised.
optional StyleIdsStack style_references = 17;
// Visibility state that can be controlled with binding.
optional VisibilityState visibility_state = 23;
oneof log_data_value {
LogData log_data = 25;
LogDataBindingRef log_data_ref = 26;
}
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
// Deprecated field IDs.
reserved 4, 7, 8, 13, 19, 20, 9, 10;
}
/*
*** CONTENT ELEMENTS ***
*/
// An Image which is displayed as a horizontal slice within a parent container.
message ImageElement {
// Content for this ImageElement.
oneof content {
// The image to be displayed.
Image image = 3;
// The binding to the BindingValue for an Image. It is an error if the
// BindingValue doesn't define an Image.
ImageBindingRef image_binding = 2;
}
// Styles applied to this ImageElement. If any style_ids cannot be found,
// ERR_MISSING_STYLES is raised.
// Deprecated: use the StyleIdsStack on Element instead.
optional StyleIdsStack style_references = 1 [deprecated = true];
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
}
// A simple text line (Android TextView, iOS UILabel, or HTML <div>).
message TextElement {
// Content for this TextElement.
oneof content {
// ChunkedText to be displayed. Styles referenced inside the text chunks
// should override the style references in this TextElement.
ChunkedText chunked_text = 5;
// The binding to the BindingValue for a ChunkedText. It is an error if the
// BindingValue doesn't define a ChunkedText. Styles referenced inside the
// ChunkedText should override the style references in this TextElement.
ChunkedTextBindingRef chunked_text_binding = 4;
// The text to display.
ParameterizedText parameterized_text = 3;
// The binding to the BindingValue for a ParameterizedText. It is an error
// if the BindingValue doesn't define a ParameterizedText.
ParameterizedTextBindingRef parameterized_text_binding = 2;
}
// Styles applied to this TextElement. If any style_ids cannot be found,
// ERR_MISSING_STYLES is raised.
// Deprecated: use the StyleIdsStack on Element instead.
optional StyleIdsStack style_references = 1 [deprecated = true];
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
}
/*
*** END CONTENT ELEMENTS ***
*/
/*
*** CONTAINER ELEMENTS ***
*/
// A horizontally-oriented left-to-right list of Contents with specified widths.
// Without explicit dimensions or constraints by the parent, this container is
// as tall as its tallest child, and as wide as the sum of its cells.
message GridRow {
// A list of cells defining the content of the grid.
repeated GridCell cells = 2;
// Styles applied to this GridRow.
// Deprecated: use the StyleIdsStack on Element instead.
optional StyleIdsStack style_references = 1 [deprecated = true];
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
}
// The Grid Cell represents the contents within a GridRow.
// The content within each cell is always the same width as the cell (minus
// margins) - width on the content's style is ignored. If the cell has extra
// vertical space (the GridRow is taller than the content), the content can
// float vertically with gravity.
// If the child's style does not specify a height, it defaults to matching the
// height of the GridRow.
// Next Id: 8
message GridCell {
// The content of the GridCell.
optional Content content = 7;
// The width of this cell, either fixed width or relative width.
// If width is not specified, behaves as if weight = 1 by default.
oneof cell_width {
// Specified inline.
GridCellWidth width = 4;
// Width specified in bindings.
GridCellWidthBindingRef width_binding = 5;
}
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
// Deprecated field IDs.
reserved 1, 2, 3, 6;
}
// The width of a GridCell.
message GridCellWidth {
// An enum that indicates the width of the GridCell, in reference to its
// content. The width of the GridCell will be the width of the contained
// element.
enum ContentWidth {
// Do not use. If used, this will raise
// ERR_CONTENT_WIDTH_GRID_CELL_WITH_INVALID_CONTENT at runtime.
INVALID_CONTENT_WIDTH = 0;
// This cell will expand just enough to fit its content.
CONTENT_WIDTH = 1;
}
// The width specification. One of these fields must be populated, otherwise
// ERR_GRID_CELL_WIDTH_WITHOUT_CONTENTS warning will be raised.
oneof width_spec {
// The width of the cell expressed as DP.
int32 dp = 1;
// The width of the cell expressed as a weight. This weight is relative to
// the remaining width, after DP and Content were allocated.
// For more information, see [INTERNAL LINK].
int32 weight = 2;
// The width of the content, limited to Content of TextElement or
// ImageElement. In case a different content is given to the cell,
// ERR_CONTENT_WIDTH_GRID_CELL_WITH_INVALID_CONTENT is raised.
ContentWidth content_width = 3;
}
// Whether this cell will shrink if the GridRow is too small for its contents.
// This cell will always be less than or equal to the defined width.
// If there are multiple collapsible cells in a row, they will shrink in order
// from last to first (ex. the last cell will be width 0 before the cell
// before it begins to shrink).
// This is ignored if weight is set.
optional bool is_collapsible = 4;
}
// A vertically-oriented top-to-bottom list of Contents.
// Without explicit dimensions or constraints by the parent, this container is
// as wide as its largest child, and as tall as the sum of its children.
// Cell height is always the size of the child Element, and vertical gravity is
// ignored. Cell width defaults to the width of the ElementList.
message ElementList {
// The list items to be laid out vertically.
repeated Content contents = 6;
// Styles applied to this ElementList.
// Deprecated: use the StyleIdsStack on Element instead.
optional StyleIdsStack style_references = 3 [deprecated = true];
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
// Deprecated field IDs.
reserved 1, 2, 4, 5;
}
// A stacked (overlaid) bottom-to-top list of Contents.
// Children can be smaller than the ElementStack and float around within it
// subject to their horizontal and vertical gravity.
// Without explicit dimensions or constraints by the parent, this container is
// as large as its largest child.
// By default, children are the size of their content.
message ElementStack {
// The items to be stacked from bottom to top.
repeated Content contents = 1;
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
}
/*
*** END CONTAINER ELEMENTS ***
*/
/*
*** NON-NATIVE ELEMENTS
*/
// A custom view that Piet knows nothing about. Servers can use this message to
// populate a custom proto extension, which Piet passes along to the Host for
// rendering. The Host is expected to be able to interpret and render this view
// and return to Piet, which then simply places it within the current view
// hierarchy at the proper position. If no renderer for this CustomElement can
// be found at runtime, ERR_CUSTOM_ELEMENT_RENDERER_MISSING is raised.
message CustomElement {
// Content for this CustomElement.
oneof content {
// The data to be displayed.
CustomElementData custom_element_data = 3;
// The binding to the BindingValue for a CustomElement.
CustomBindingRef custom_binding = 2;
}
// Styles applied to this CustomElement. If any style_ids cannot be found,
// ERR_MISSING_STYLES is raised.
// Deprecated: use the StyleIdsStack on Element instead.
optional StyleIdsStack style_references = 1 [deprecated = true];
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
}
// Data to be displayed in a CustomElement. Clients using Piet should add
// extensions to this proto to pass their custom data to CustomElements.
message CustomElementData {
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
}
// A view that is implemented by a secondary (non-Core) Piet Module. Not all
// Piet Elements are useful to all clients/servers, so only the basic ones are
// included in Piet Core. Common shareable elements can be implemented in
// secondary Piet Modules, which are optional modules that can be included in or
// excluded from Piet-based apps on an as-needed basis.
// ModuleElements work similar to CustomElements, with the only difference being
// that CustomElements are rendered by non-Piet code, while ModuleElements are
// rendered by secondary Piet Modules.
message ModuleElement {
// Content for this ModuleElement.
oneof content {
// The data to be displayed.
ModuleElementData module_element_data = 3;
// The binding to the BindingValue for a ModuleElement.
ModuleBindingRef module_binding = 2;
}
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
}
// Data to be displayed in a ModuleElement. Piet Modules should add extensions
// to this proto to pass their custom data to ModuleElements.
message ModuleElementData {
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
}
/*
*** END NON-NATIVE ELEMENTS ***
*/
/*
*** TEMPLATES AND BINDINGS ***
*/
// A template can be used to instantiate a single instance, or a list of
// instances at once: each of these is termed a TemplateInvocation. One instance
// is created for each `binding_context` provided.
//
// The types of objects instantiated by the template are determined by the
// element that holds the invocation. For example, an invocation from an
// ElementList will create one or more cells in that list. Invocation from a
// GridCell will create one or more GridCells.
message TemplateInvocation {
// The Template to be used.
optional string template_id = 1;
// To isolate Templates, we define the BindingContext used by the template
// within the invocation. When a TemplateInvocation is processed, we will
// create a template instance for each BindingContext defined (if none is
// defined, none will be created).
repeated BindingContext binding_contexts = 2;
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
}
// A single binding context, such as a whole Frame, or a single row in a grid.
// Binding IDs must be unique; if two or more BindingValues with the same
// `binding_id` are found within the same binding context,
// ERR_DUPLICATE_BINDING_VALUE is raised.
message BindingContext {
// The set of all bindings for a Template.
repeated BindingValue binding_values = 1;
}
// A BindingValue is a name/value pair which provides a value to be substituted
// wherever the specified `binding_id` is defined in the Template.
// Next Id: 18
message BindingValue {
// The name of the binding within the Template where this BindingValue should
// be substituted. Must be unique within a binding context.
optional string binding_id = 1;
// The possible values for the BindingValue.
oneof values {
// Actions that may be bound at runtime.
Actions actions = 10;
// Binding value for visibility, which changes the VisibilityState of an
// Element. This value can override the default visibility value set on an
// Element.
Visibility visibility = 13 [default = VISIBLE];
// Use an already existing bound value in a transcluded template.
// This should be used to pass parameters between templates.
//
// For example:
// Let's assume we have a template that shows a text with styling:
//
// template {
// id: "StyledText"
// ...
// element {
// text_element {
// parameterized_text_binding { binding_id: "StyledTextContent" }
// }
// }
// ...
// }
//
// And we want to create a template that shows the styled text overlayed
// over an image:
//
// template {
// id: "ImageWithText"
// ...
// element {
// image_element {
// image_binding {
// binding_id: "TopLevelImage"
// }
// }
// overlays {
// template_invocation {
// id: 'StyledText'
// binding_contexts {
// binding_values {
// binding_id: "StyledTextContent"
// binding_id_from_transcluding_template: "TopLevelText"
// }
// }
// }
// }
// }
// ...
// }
//
// The invocation of the template will then be:
//
// frame {
// template_invocation {
// id: "ImageWithText"
// binding_contexts {
// binding_values {
// binding_id: "TopLevelText"
// ...
// }
// binding_values {
// binding_id: "TopLevelImage"
// ...
// }
// }
// }
// }
string binding_id_from_transcluding_template = 16;
// Style that is bound to an element, and overrides the styles defined by
// the element. The Style attributes that can be bound are only a subset
// of all possible Styles.
BoundStyle bound_style = 11;
// Width of a cell.
GridCellWidth cell_width = 9;
// ChunkedText to be used in a TextElement.
ChunkedText chunked_text = 4;
// Data to be displayed in a CustomElement. Clients using Piet should add
// extensions to this proto to pass their custom data.
CustomElementData custom_element_data = 2;
// An Element, to allow binding of generic chunks of layout.
// May have a performance penalty on some platforms.
Element element = 15;
// Image to be used in an ImageElement.
Image image = 5;
// ParameterizedText to be used in a TextElement.
ParameterizedText parameterized_text = 3;
// Binding value for a TemplateInvocation.
TemplateInvocation template_invocation = 8;
// A Base64-encoded serialized ClickTrackingCGI proto that identifies the
// logged Visual Element corresponding to a bound Piet Template.
string ved = 7;
LogData log_data = 17;
}
// Data to provide a host in order for host to fulfill a binding for Piet.
// When Piet binds a value it will first look to see if there is a
// HostBindingData set. If there is one, then Piet asks the host for a new
// BindingValue to use. The host will be given this BindingValue from which it
// can use HostBindingData to determine how to create a new BindingValue. This
// allows the host to selectively alter the server specified BindingValue. If
// the BindingValue returned by the host has HostBindingData set it will be
// ignored. If there is no binding provided in the oneof then an error will be
// raised. See [INTERNAL LINK] for a list of possible errors that could be
// raised.
//
// Piet will use the binding reference and ask the host for a specific
// binding based on that reference type. As an example, Piet will request the
// host for an Image when ImageBindingRef is specified.
//
// An example usage of a host binding would be to check if something has
// been stored on the device and signaling with icons whether content is
// there or not. The server can specify where this element will appear and
// the host can determine what to show or even if the element should be
// shown.
optional HostBindingData host_binding_data = 14;
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
// Deprecated field IDs.
reserved 6;
}
// Data which is accompanied with BindingValue in order for a host to determine
// the information it needs to provide the correct BindingValue to fulfill a
// binding reference. Client using Piet should add extensions to this proto to
// pass their host specific data needed to fulfill the binding reference.
message HostBindingData {
// Please use CL numbers you own for extension numbers.
extensions 10000 to max;
}
/*
*** END TEMPLATES AND BINDINGS ***
*/
/*
*** ENUMS ***
*/
// Controls the visibility of a UI element.
enum Visibility {
VISIBILITY_UNSPECIFIED = 0;
// By default, every element is visible. If set to VISIBLE, at least one of
// the elements in the `values` oneof MUST be present, otherwise an error is
// raised.
VISIBLE = 1;
// The UI element corresponding to this binding is included in
// layout computation, but its visible UI is hidden.
INVISIBLE = 2;
// The UI element corresponding to this binding is completely
// removed from the view hierarchy. It is not used to compute layout. This
// is the equivalent of Android’s visibility:GONE.
GONE = 3;
}
// Defines the behavior for elements that don't fit in the view
enum OverflowBehavior {
// Unspecified value, will default to OVERFLOW_HIDDEN.
OVERFLOW_UNSPECIFIED = 0;
// All elements outside the boundaries of the view are hidden.
OVERFLOW_HIDDEN = 1;
// A scroll behavior is added to show elements that are outside of the view.
OVERFLOW_SCROLL = 2;
}
/*
*** END ENUMS ***
*/