| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_H_ |
| #define CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_H_ |
| |
| #include <memory> |
| #include <sstream> |
| #include <string> |
| #include <vector> |
| |
| #include "base/callback.h" |
| #include "base/macros.h" |
| #include "cc/animation/animation_target.h" |
| #include "cc/animation/transform_operations.h" |
| #include "chrome/browser/vr/animation.h" |
| #include "chrome/browser/vr/audio_delegate.h" |
| #include "chrome/browser/vr/databinding/binding_base.h" |
| #include "chrome/browser/vr/elements/corner_radii.h" |
| #include "chrome/browser/vr/elements/draw_phase.h" |
| #include "chrome/browser/vr/elements/ui_element_name.h" |
| #include "chrome/browser/vr/elements/ui_element_type.h" |
| #include "chrome/browser/vr/frame_lifecycle.h" |
| #include "chrome/browser/vr/model/camera_model.h" |
| #include "chrome/browser/vr/model/reticle_model.h" |
| #include "chrome/browser/vr/model/sounds.h" |
| #include "chrome/browser/vr/target_property.h" |
| #include "chrome/browser/vr/vr_export.h" |
| #include "ui/gfx/geometry/point3_f.h" |
| #include "ui/gfx/geometry/quaternion.h" |
| #include "ui/gfx/geometry/rect_f.h" |
| #include "ui/gfx/geometry/size_f.h" |
| #include "ui/gfx/geometry/vector3d_f.h" |
| #include "ui/gfx/transform.h" |
| |
| namespace base { |
| class TimeTicks; |
| } |
| |
| namespace vr { |
| |
| class KeyframeModel; |
| class SkiaSurfaceProvider; |
| class UiElementRenderer; |
| class InputEvent; |
| struct CameraModel; |
| struct EditedText; |
| |
| enum LayoutAlignment { |
| NONE = 0, |
| LEFT, |
| RIGHT, |
| TOP, |
| BOTTOM, |
| }; |
| |
| struct VR_EXPORT EventHandlers { |
| EventHandlers(); |
| EventHandlers(const EventHandlers& other); |
| ~EventHandlers(); |
| base::RepeatingCallback<void()> hover_enter; |
| base::RepeatingCallback<void()> hover_leave; |
| base::RepeatingCallback<void(const gfx::PointF&)> hover_move; |
| base::RepeatingCallback<void()> button_down; |
| base::RepeatingCallback<void()> button_up; |
| base::RepeatingCallback<void(const gfx::PointF&)> touch_move; |
| base::RepeatingCallback<void(bool)> focus_change; |
| }; |
| |
| struct HitTestRequest { |
| gfx::Point3F ray_origin; |
| gfx::Point3F ray_target; |
| float max_distance_to_plane = 1000.f; |
| }; |
| |
| // The result of performing a hit test. |
| struct HitTestResult { |
| enum Type { |
| // The given ray does not pass through the element. |
| kNone = 0, |
| // The given ray does not pass through the element, but passes through the |
| // element's plane. |
| kHitsPlane, |
| // The given ray passes through the element. |
| kHits, |
| }; |
| |
| Type type; |
| // The fields below are not set if the result Type is kNone. |
| // The hit position in the element's local coordinate space. |
| gfx::PointF local_hit_point; |
| // The hit position relative to the world. |
| gfx::Point3F hit_point; |
| // The distance from the ray origin to the hit position. |
| float distance_to_plane; |
| }; |
| |
| class VR_EXPORT UiElement : public cc::AnimationTarget { |
| public: |
| UiElement(); |
| ~UiElement() override; |
| |
| enum OperationIndex { |
| kTranslateIndex = 0, |
| kRotateIndex = 1, |
| kScaleIndex = 2, |
| }; |
| |
| UiElementName name() const { return name_; } |
| void SetName(UiElementName name); |
| virtual void OnSetName(); |
| |
| UiElementName owner_name_for_test() const { return owner_name_for_test_; } |
| void set_owner_name_for_test(UiElementName name) { |
| owner_name_for_test_ = name; |
| } |
| |
| UiElementType type() const { return type_; } |
| void SetType(UiElementType type); |
| virtual void OnSetType(); |
| UiElement* GetDescendantByType(UiElementType type); |
| |
| DrawPhase draw_phase() const { return draw_phase_; } |
| void SetDrawPhase(DrawPhase draw_phase); |
| virtual void OnSetDrawPhase(); |
| |
| void UpdateBindings(); |
| |
| // Returns true if the element has been updated in any visible way. |
| bool DoBeginFrame(const gfx::Transform& head_pose, |
| bool force_animations_to_completion); |
| |
| // Returns true if the element has changed size or position, or otherwise |
| // warrants re-rendering the scene. |
| virtual bool PrepareToDraw(); |
| |
| // Returns true if the element updated its texture. |
| virtual bool HasDirtyTexture() const; |
| |
| virtual void UpdateTexture(); |
| |
| bool IsHitTestable() const; |
| |
| virtual void Render(UiElementRenderer* renderer, |
| const CameraModel& model) const; |
| |
| virtual void Initialize(SkiaSurfaceProvider* provider); |
| |
| // Controller interaction methods. |
| virtual void OnHoverEnter(const gfx::PointF& position, |
| base::TimeTicks timestamp); |
| virtual void OnHoverLeave(base::TimeTicks timestamp); |
| virtual void OnHoverMove(const gfx::PointF& position, |
| base::TimeTicks timestamp); |
| virtual void OnButtonDown(const gfx::PointF& position, |
| base::TimeTicks timestamp); |
| virtual void OnButtonUp(const gfx::PointF& position, |
| base::TimeTicks timestamp); |
| virtual void OnTouchMove(const gfx::PointF& position, |
| base::TimeTicks timestamp); |
| virtual void OnFlingCancel(std::unique_ptr<InputEvent> gesture, |
| const gfx::PointF& position); |
| virtual void OnScrollBegin(std::unique_ptr<InputEvent> gesture, |
| const gfx::PointF& position); |
| virtual void OnScrollUpdate(std::unique_ptr<InputEvent> gesture, |
| const gfx::PointF& position); |
| virtual void OnScrollEnd(std::unique_ptr<InputEvent> gesture, |
| const gfx::PointF& position); |
| |
| // Whether the point (relative to the origin of the element), should be |
| // considered on the element. All elements are considered rectangular by |
| // default though elements may override this function to handle arbitrary |
| // shapes. Points within the rectangular area are mapped from 0:1 as follows, |
| // though will extend outside this range when outside of the element: |
| // [(0.0, 0.0), (1.0, 0.0) |
| // (0.0, 1.0), (1.0, 1.0)] |
| virtual bool LocalHitTest(const gfx::PointF& point) const; |
| |
| // Performs a hit test for the ray supplied in the request and populates the |
| // result. The ray is in the world coordinate space. |
| virtual void HitTest(const HitTestRequest& request, |
| HitTestResult* result) const; |
| |
| int id() const { return id_; } |
| |
| // If true, the object has a non-zero opacity. |
| bool IsVisible() const; |
| |
| // If true, the object is both visible and opaque. |
| bool IsVisibleAndOpaque() const; |
| |
| // For convenience, sets opacity to |opacity_when_visible_|. |
| virtual void SetVisible(bool visible); |
| virtual void SetVisibleImmediately(bool visible); |
| |
| void set_opacity_when_visible(float opacity) { |
| opacity_when_visible_ = opacity; |
| } |
| float opacity_when_visible() const { return opacity_when_visible_; } |
| |
| bool requires_layout() const { return requires_layout_; } |
| void set_requires_layout(bool requires_layout) { |
| requires_layout_ = requires_layout; |
| } |
| |
| bool hit_testable() const { return hit_testable_; } |
| void set_hit_testable(bool hit_testable) { hit_testable_ = hit_testable; } |
| |
| bool focusable() const { return focusable_; } |
| void set_focusable(bool focusable); |
| virtual void OnSetFocusable(); |
| |
| bool scrollable() const { return scrollable_; } |
| void set_scrollable(bool scrollable) { scrollable_ = scrollable; } |
| |
| bool bubble_events() const { return bubble_events_; } |
| void set_bubble_events(bool bubble_events) { bubble_events_ = bubble_events; } |
| |
| void set_event_handlers(const EventHandlers& event_handlers) { |
| event_handlers_ = event_handlers; |
| } |
| |
| // Editable elements should override these functions. |
| virtual void OnFocusChanged(bool focused); |
| virtual void OnInputEdited(const EditedText& info); |
| virtual void OnInputCommitted(const EditedText& info); |
| virtual void RequestFocus(); |
| virtual void RequestUnfocus(); |
| virtual void UpdateInput(const EditedText& info); |
| |
| gfx::SizeF size() const; |
| void SetSize(float width, float hight); |
| virtual void OnSetSize(const gfx::SizeF& size); |
| |
| // Setter and getter for the clip rect in relative tex coordinates, the same |
| // system used for hit testing. |
| gfx::RectF GetClipRect() const; |
| void SetClipRect(const gfx::RectF& rect); |
| |
| gfx::PointF local_origin() const { return local_origin_; } |
| |
| // These are convenience functions for setting the transform operations. They |
| // will animate if you've set a transition. If you need to animate more than |
| // one operation simultaneously, please use |SetTransformOperations| below. |
| void SetLayoutOffset(float x, float y); |
| void SetTranslate(float x, float y, float z); |
| void SetRotate(float x, float y, float z, float radians); |
| void SetScale(float x, float y, float z); |
| |
| // Returns the target value of the animation if the corresponding property is |
| // being animated, or the current value otherwise. |
| gfx::SizeF GetTargetSize() const; |
| cc::TransformOperations GetTargetTransform() const; |
| float GetTargetOpacity() const; |
| |
| float opacity() const { return opacity_; } |
| virtual void SetOpacity(float opacity); |
| |
| CornerRadii corner_radii() const { return corner_radii_; } |
| void SetCornerRadii(const CornerRadii& radii); |
| virtual void OnSetCornerRadii(const CornerRadii& radii); |
| |
| float corner_radius() const { |
| DCHECK(corner_radii_.AllEqual()); |
| return corner_radii_.upper_left; |
| } |
| |
| // Syntax sugar for setting all corner radii to the same value. |
| void set_corner_radius(float corner_radius) { |
| SetCornerRadii( |
| {corner_radius, corner_radius, corner_radius, corner_radius}); |
| } |
| |
| float computed_opacity() const; |
| void set_computed_opacity(float computed_opacity) { |
| computed_opacity_ = computed_opacity; |
| } |
| |
| virtual float ComputedAndLocalOpacityForTest() const; |
| |
| LayoutAlignment x_anchoring() const { return x_anchoring_; } |
| void set_x_anchoring(LayoutAlignment x_anchoring) { |
| DCHECK(x_anchoring == LEFT || x_anchoring == RIGHT || x_anchoring == NONE); |
| x_anchoring_ = x_anchoring; |
| } |
| |
| LayoutAlignment y_anchoring() const { return y_anchoring_; } |
| void set_y_anchoring(LayoutAlignment y_anchoring) { |
| DCHECK(y_anchoring == TOP || y_anchoring == BOTTOM || y_anchoring == NONE); |
| y_anchoring_ = y_anchoring; |
| } |
| |
| LayoutAlignment x_centering() const { return x_centering_; } |
| void set_x_centering(LayoutAlignment x_centering) { |
| DCHECK(x_centering == LEFT || x_centering == RIGHT || x_centering == NONE); |
| x_centering_ = x_centering; |
| } |
| |
| LayoutAlignment y_centering() const { return y_centering_; } |
| void set_y_centering(LayoutAlignment y_centering) { |
| DCHECK(y_centering == TOP || y_centering == BOTTOM || y_centering == NONE); |
| y_centering_ = y_centering; |
| } |
| |
| bool bounds_contain_children() const { return bounds_contain_children_; } |
| void set_bounds_contain_children(bool bounds_contain_children) { |
| bounds_contain_children_ = bounds_contain_children; |
| } |
| |
| bool bounds_contain_padding() const { return bounds_contain_padding_; } |
| void set_bounds_contain_padding(bool bounds_contain_padding) { |
| bounds_contain_padding_ = bounds_contain_padding; |
| } |
| |
| bool contributes_to_parent_bounds() const { |
| return contributes_to_parent_bounds_; |
| } |
| void set_contributes_to_parent_bounds(bool value) { |
| contributes_to_parent_bounds_ = value; |
| } |
| |
| float left_padding() const { return left_padding_; } |
| float right_padding() const { return right_padding_; } |
| float top_padding() const { return top_padding_; } |
| float bottom_padding() const { return bottom_padding_; } |
| |
| void set_padding(float x, float y) { |
| left_padding_ = x; |
| right_padding_ = x; |
| top_padding_ = y; |
| bottom_padding_ = y; |
| } |
| |
| void set_padding(float left, float top, float right, float bottom) { |
| left_padding_ = left; |
| right_padding_ = right; |
| top_padding_ = top; |
| bottom_padding_ = bottom; |
| } |
| |
| const gfx::Transform& inheritable_transform() const { |
| return inheritable_transform_; |
| } |
| void set_inheritable_transform(const gfx::Transform& transform) { |
| inheritable_transform_ = transform; |
| } |
| |
| const gfx::Transform& world_space_transform() const; |
| void set_world_space_transform(const gfx::Transform& transform) { |
| world_space_transform_ = transform; |
| world_space_transform_dirty_ = false; |
| } |
| |
| gfx::Transform ComputeTargetWorldSpaceTransform() const; |
| float ComputeTargetOpacity() const; |
| |
| // Transformations are applied relative to the parent element, rather than |
| // absolutely. |
| void AddChild(std::unique_ptr<UiElement> child); |
| |
| // These functions return the removed element. |
| std::unique_ptr<UiElement> RemoveChild(UiElement* to_remove); |
| std::unique_ptr<UiElement> ReplaceChild(UiElement* to_remove, |
| std::unique_ptr<UiElement> to_add); |
| |
| UiElement* parent() { return parent_; } |
| const UiElement* parent() const { return parent_; } |
| |
| void AddBinding(std::unique_ptr<BindingBase> binding); |
| const std::vector<std::unique_ptr<BindingBase>>& bindings() { |
| return bindings_; |
| } |
| |
| gfx::Point3F GetCenter() const; |
| gfx::Vector3dF GetNormal() const; |
| |
| // Computes the distance from |ray_origin| to this rectangles's plane, along |
| // |ray_vector|. Returns true and populates |distance| if the calculation is |
| // possible, and false if the ray is parallel to the plane. |
| bool GetRayDistance(const gfx::Point3F& ray_origin, |
| const gfx::Vector3dF& ray_vector, |
| float* distance) const; |
| |
| // Projects a 3D world point onto the X and Y axes of the transformed |
| // rectangle, returning 2D coordinates relative to the un-transformed unit |
| // rectangle. This allows beam intersection points to be mapped to sprite |
| // pixel coordinates. Points that fall onto the rectangle will generate X and |
| // Y values on the interval [-0.5, 0.5]. |
| gfx::PointF GetUnitRectangleCoordinates( |
| const gfx::Point3F& world_point) const; |
| |
| // cc::AnimationTarget |
| void NotifyClientFloatAnimated(float value, |
| int target_property_id, |
| cc::KeyframeModel* keyframe_model) override; |
| void NotifyClientTransformOperationsAnimated( |
| const cc::TransformOperations& operations, |
| int target_property_id, |
| cc::KeyframeModel* keyframe_model) override; |
| void NotifyClientSizeAnimated(const gfx::SizeF& size, |
| int target_property_id, |
| cc::KeyframeModel* keyframe_model) override; |
| |
| void SetTransitionedProperties(const std::set<TargetProperty>& properties); |
| void SetTransitionDuration(base::TimeDelta delta); |
| |
| void AddKeyframeModel(std::unique_ptr<cc::KeyframeModel> keyframe_model); |
| void RemoveKeyframeModel(int keyframe_model_id); |
| void RemoveKeyframeModels(int target_property); |
| bool IsAnimatingProperty(TargetProperty property) const; |
| |
| // Recursive method that sizes and lays out element subtrees. |
| bool SizeAndLayOut(); |
| |
| // Handles positioning adjustments for children. This will be overridden by |
| // UiElements providing custom layout modes. See the documentation of the |
| // override for their particular functionality. This method is specific to |
| // children that contribute to the parent's bounds. These elements may not |
| // use anchoring or centering attributes, as they themselves determine where |
| // the parent boundaries will be. |
| virtual void LayOutContributingChildren(); |
| |
| // Similar to LayOutContributingChildren, but runs after the parent's size has |
| // been determined. The default implementation applies anchoring. |
| virtual void LayOutNonContributingChildren(); |
| |
| // Recursive method that clips element subtrees, using the clip rect set. |
| void ClipChildren(); |
| |
| UiElement* FirstLaidOutChild() const; |
| UiElement* LastLaidOutChild() const; |
| |
| virtual gfx::Transform LocalTransform() const; |
| virtual gfx::Transform GetTargetLocalTransform() const; |
| |
| void UpdateComputedOpacity(); |
| bool UpdateWorldSpaceTransform(bool parent_changed); |
| |
| std::vector<std::unique_ptr<UiElement>>& children() { return children_; } |
| const std::vector<std::unique_ptr<UiElement>>& children() const { |
| return children_; |
| } |
| |
| void set_update_phase(UpdatePhase phase) { update_phase_ = phase; } |
| UpdatePhase update_phase() const { return update_phase_; } |
| |
| // This is true for all elements that respect the given view model matrix. If |
| // this is ignored (say for head-locked elements that draw in screen space), |
| // then this function should return false. |
| virtual bool IsWorldPositioned() const; |
| |
| bool updated_visiblity_this_frame() const { |
| return updated_visibility_this_frame_; |
| } |
| |
| void set_cursor_type(CursorType cursor_type) { cursor_type_ = cursor_type; } |
| CursorType cursor_type() const { return cursor_type_; } |
| |
| std::string DebugName() const; |
| |
| #ifndef NDEBUG |
| |
| // Writes a pretty-printed version of the UiElement subtree to |os|. The |
| // vector of counts represents where each ancestor on the ancestor chain is |
| // situated in its parent's list of children. This is used to determine |
| // whether each ancestor is the last child (which affects the lines we draw in |
| // the tree). |
| // TODO(vollick): generalize the configuration of the dump to selectively turn |
| // off or on a variety of features. |
| void DumpHierarchy(std::vector<size_t> counts, |
| std::ostringstream* os, |
| bool include_bindings) const; |
| virtual void DumpGeometry(std::ostringstream* os) const; |
| #endif |
| |
| // Set the sounds that play when an applicable handler is executed. Elements |
| // that override element hover and click methods must manage their own sounds. |
| void SetSounds(Sounds sounds, AudioDelegate* delegate); |
| |
| bool clips_descendants() const { return clips_descendants_; } |
| void set_clip_descendants(bool clips) { clips_descendants_ = clips; } |
| |
| bool resizable_by_layout() const { return resizable_by_layout_; } |
| void set_resizable_by_layout(bool resizable) { |
| resizable_by_layout_ = resizable; |
| } |
| |
| bool descendants_updated() const { return descendants_updated_; } |
| void set_descendants_updated(bool updated) { descendants_updated_ = updated; } |
| |
| base::TimeTicks last_frame_time() const { return last_frame_time_; } |
| void set_last_frame_time(const base::TimeTicks& time) { |
| last_frame_time_ = time; |
| } |
| |
| protected: |
| // This method may be overridden by elements that have custom layout |
| // requirements. |
| virtual bool SizeAndLayOutChildren(); |
| |
| gfx::RectF GetAbsoluteClipRect() const; |
| |
| Animation& animation() { return animation_; } |
| |
| virtual const Sounds& GetSounds() const; |
| |
| virtual bool ShouldUpdateWorldSpaceTransform( |
| bool parent_transform_changed) const; |
| |
| void set_world_space_transform_dirty() { |
| world_space_transform_dirty_ = true; |
| } |
| |
| EventHandlers event_handlers_; |
| |
| private: |
| virtual void OnUpdatedWorldSpaceTransform(); |
| |
| // Returns true if the element has been updated in any visible way. |
| virtual bool OnBeginFrame(const gfx::Transform& head_pose); |
| |
| // If true, the element is either locally visible (independent of its |
| // ancestors), or its animation will cause it to become locally visible. |
| bool IsOrWillBeLocallyVisible() const; |
| |
| // Recursive method that clips element subtrees, given that a parent is |
| // clipped. Receives a clipping rect in absolute scale. |
| void ClipChildren(const gfx::RectF& abs_clip); |
| |
| virtual gfx::RectF ComputeContributingChildrenBounds(); |
| |
| // Valid IDs are non-negative. |
| int id_ = -1; |
| |
| // If false, the reticle will not hit the element, even if visible. |
| bool hit_testable_ = false; |
| |
| // If false, clicking on the element doesn't give it focus. |
| bool focusable_ = true; |
| |
| // A signal to the input routing machinery that this element accepts scrolls. |
| bool scrollable_ = false; |
| |
| // If true, events such as OnButtonDown, OnHoverEnter, etc, get bubbled up the |
| // parent chain. |
| bool bubble_events_ = false; |
| |
| // The size of the object. This does not affect children. |
| gfx::SizeF size_; |
| |
| // The clip of the object. The rect dimensions are relative to the element's |
| // size, with the origin at its center. Use the getter and setter to |
| // manipulate the rect in relative tex coordinates. |
| gfx::RectF clip_rect_ = {-0.5f, 0.5f, 1.0f, 1.0f}; |
| |
| // Indicates that this element clips its descendants with its size. |
| bool clips_descendants_ = false; |
| |
| // The local orgin of the element. This can be updated, say, so that an |
| // element can contain its children, even if they are not centered about its |
| // true origin. |
| gfx::PointF local_origin_ = {0.0f, 0.0f}; |
| |
| // The opacity of the object (between 0.0 and 1.0). |
| float opacity_ = 1.0f; |
| |
| // SetVisible(true) is an alias for SetOpacity(opacity_when_visible_). |
| float opacity_when_visible_ = 1.0f; |
| |
| // A signal that this element is to be considered in |LayOutChildren|. |
| bool requires_layout_ = true; |
| |
| // The corner radius of the object. Analogous to the CSS property, |
| // border-radius. This is in meters (same units as |size|). |
| CornerRadii corner_radii_ = {0, 0, 0, 0}; |
| |
| // The computed opacity, incorporating opacity of parent objects. |
| float computed_opacity_ = 1.0f; |
| |
| // Returns true if the last call to UpdateBindings had any effect. NB: this |
| // value is *not* updated for all elements in the tree each frame. It is |
| // important to only query this value for elements whose visibility has |
| // changed this frame or will be visible. |
| bool updated_bindings_this_frame_ = false; |
| |
| // Return true if the last call to UpdateComputedOpacity had any effect on |
| // visibility. |
| bool updated_visibility_this_frame_ = false; |
| |
| // If anchoring is specified, the translation will be relative to the |
| // specified edge(s) of the parent, rather than the center. A parent object |
| // must be specified when using anchoring. |
| LayoutAlignment x_anchoring_ = LayoutAlignment::NONE; |
| LayoutAlignment y_anchoring_ = LayoutAlignment::NONE; |
| |
| // If centering is specified, the elements layout offset is adjusted such that |
| // it is positioned relative to its own edge or corner, rather than center. |
| LayoutAlignment x_centering_ = LayoutAlignment::NONE; |
| LayoutAlignment y_centering_ = LayoutAlignment::NONE; |
| |
| // If this is true, after laying out descendants, this element updates its |
| // size to accommodate all descendants, adding in the padding below along the |
| // x and y axes. |
| bool bounds_contain_children_ = false; |
| bool bounds_contain_padding_ = true; |
| bool contributes_to_parent_bounds_ = true; |
| float left_padding_ = 0.0f; |
| float right_padding_ = 0.0f; |
| float top_padding_ = 0.0f; |
| float bottom_padding_ = 0.0f; |
| |
| Animation animation_; |
| |
| DrawPhase draw_phase_ = kPhaseNone; |
| |
| // The time of the most recent frame. |
| base::TimeTicks last_frame_time_; |
| |
| // This transform can be used by children to derive position of its parent. |
| gfx::Transform inheritable_transform_; |
| |
| // An optional, but stable and semantic identifier for an element used in lieu |
| // of a string. |
| UiElementName name_ = UiElementName::kNone; |
| |
| // This name is used in tests and debugging output to associate a "component" |
| // element with its logical owner, such as a button icon within a specific, |
| // named button instance. |
| UiElementName owner_name_for_test_ = UiElementName::kNone; |
| |
| // An optional identifier to categorize a reusable element, such as a button |
| // background. It can also be used to identify categories of element for |
| // common styling. Eg, applying a corner-radius to all tab thumbnails. |
| UiElementType type_ = UiElementType::kTypeNone; |
| |
| // This local transform operations. They are inherited by descendants and are |
| // stored as a list of operations rather than a baked transform to make |
| // transitions easier to implement (you may, for example, want to animate just |
| // the translation, but leave the rotation and scale in tact). |
| cc::TransformOperations transform_operations_; |
| |
| // This is a cached version of the local transform. |
| gfx::Transform local_transform_; |
| |
| // This is set by the parent and is combined into LocalTransform() |
| cc::TransformOperations layout_offset_; |
| |
| // This is the combined, local to world transform. It includes |
| // |inheritable_transform_|, |transform_|, and anchoring adjustments. |
| gfx::Transform world_space_transform_; |
| bool world_space_transform_dirty_ = false; |
| |
| UiElement* parent_ = nullptr; |
| std::vector<std::unique_ptr<UiElement>> children_; |
| |
| // This is true if a descendant has been added and the total list has not yet |
| // been collected by the scene. |
| bool descendants_updated_ = false; |
| |
| std::vector<std::unique_ptr<BindingBase>> bindings_; |
| |
| UpdatePhase update_phase_ = kClean; |
| |
| AudioDelegate* audio_delegate_ = nullptr; |
| Sounds sounds_; |
| |
| // Indicates that this element may be resized by parent layout elements. |
| bool resizable_by_layout_ = false; |
| |
| CursorType cursor_type_ = kCursorDefault; |
| |
| DISALLOW_COPY_AND_ASSIGN(UiElement); |
| }; |
| |
| } // namespace vr |
| |
| #endif // CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_H_ |