blob: 14ef4a993436786e11b4680bd882ebfda23bfa99 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.ui.views;
/// A View is an interface that a component implements to offer Scenic view(s)
/// to its clients.
/// A Scenic view contains a tree of Scenic graph nodes which is used to render
/// a graphical user interface, such as a module, shell, or on-screen keyboard.
/// Other Scenic views can be embedded within this tree of nodes. This creates
/// a scene graph describing the UI of the entire system, rooted at the
/// top-most view. Different processes can contribute branches to the scene
/// graph, and their content will be rendered together in a shared space.
/// # Offering a View
/// A component that wishes to offer a `View` can do so in one of two ways:
/// 1. Expose a `View` interface as a service. This is usually done by components
/// that provide a single view, or have a clearly defined "main" view.
/// In this case, the component may obtain relevant properties for configuring
/// the view using services that may be available in its namespace, such as:
/// - `fuchsia.intl.PropertyProvider`
/// - `fuchsia.accessibility.PropertyProvider`
/// 2. Offer a domain-specific interface that provides `View`s using a
/// `request<View>` parameter. In this case, the component may obtain relevant
/// properties for configuring the view using services that may be provided by its
/// client as part of the request.
/// For example, an encyclopedia component might offer a method to expose article views:
/// GetArticleView(string article_id,
/// fuchsia.intl.PropertyProvider intl_properties,
/// fuchsia.accessibility.PropertyProvider accessibility_properties,
/// request<View> view_request);
/// This latter case is probably less common, as controlling domain-specific
/// views tends to be the job of the component that creates them.
/// # Presenting a View
/// A client of the `View` interface will:
/// 1. Launch (or bind to) the component that provides the interface.
/// 2. Connect to the component's `View` interface.
/// 3. Call `Present()` to give the `View` an attachment point into the scene graph
/// via the `view_token`. Subsequent calls to `Present()` will generate an error
/// and cause the connection to be closed.
/// When the client no longer needs the View, it should disconnect from the
/// interface.
/// NOTE: The client owns the `View` instance and must retain it for the
/// lifetime of the UI that it displays. If the `View` instance is destroyed,
/// the connection will be dropped and all UI content will be destroyed.
/// # Implementing a View
/// On the implementation side, a component that exposes the `View` interface
/// has the following responsibilities:
/// * When `Present()` is called, create a root for the `View`'s content in the
/// Scenic scene graph by passing the provided `view_token`.
/// * Provide graphical content for the view and attach it to the root.
/// * Adjust the appearance and/or contents of the view's content based on
/// relevant internationalization and/or accessibility properties as described
/// above.
/// * Handle user interface events such as touches, key presses, and
/// `fuchsia.ui.gfx.ViewProperty` changes using other Scenic interfaces such
/// as `fuchsia.ui.Scenic` and `fuchsia.ui.SessionListener`.
/// See also: `fuchsia.intl.PropertyProvider`, `fuchsia.accessibility.PropertyProvider`.
/// TODO(SCN-1198): Migrate all implementations of `ViewProvider` to use `View`.
protocol View {
/// Provides the View with an attachment point to Scenic's scene graph.
/// When `Present()` is called the View's implementation should create a
/// View resource within Scenic by providing it with the `view_token` (using
/// a `fuchsia.ui.gfx.CreateResourceCmd` and `fuchsia.ui.gfx.ViewArgs`).
/// Then the implementation should attach its graphical content to the
/// newly-created View resource using a `fuchsia.ui.gfx.AddChildCmd`.
/// If the implementation already owns a View resource (because `Present()`
/// had already been called before), then it should terminate the connection
/// with an error.
/// TODO(SCN-1271): Allow re-parenting `View`s with a new `Present()` call.
Present(ViewToken view_token);