1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/user_education/webui/tracked_element_webui.h"
#include "base/check.h"
#include "components/user_education/common/help_bubble/help_bubble.h"
#include "components/user_education/common/user_education_events.h"
#include "components/user_education/webui/help_bubble_handler.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "ui/base/interaction/element_tracker.h"
#include "ui/base/interaction/framework_specific_implementation.h"
#include "ui/gfx/geometry/rect_conversions.h"
namespace user_education {
TrackedElementWebUI::TrackedElementWebUI(HelpBubbleHandlerBase* handler,
ui::ElementIdentifier identifier,
ui::ElementContext context)
: TrackedElement(identifier, context), handler_(handler) {
DCHECK(handler);
}
TrackedElementWebUI::~TrackedElementWebUI() {
SetVisible(false);
}
gfx::Rect TrackedElementWebUI::GetScreenBounds() const {
gfx::Rect result;
content::WebContents* const contents =
handler_->GetController()->web_ui()->GetWebContents();
if (contents) {
// Use the last known bounds, but if the bounds are empty, make them 1x1 so
// there's something to anchor to.
result = gfx::ToRoundedRect(last_known_bounds_);
if (result.width() < 1) {
result.set_width(1);
}
if (result.height() < 1) {
result.set_height(1);
}
// To get the screen coordinates, have to offset by the coordinates of the
// viewport.
result.Offset(contents->GetContainerBounds().OffsetFromOrigin());
}
return result;
}
void TrackedElementWebUI::SetVisible(bool visible, gfx::RectF bounds) {
if (visible == visible_) {
if (visible && last_known_bounds_ != bounds) {
last_known_bounds_ = bounds;
// This event signals that the bounds of the element have been updated.
ui::ElementTracker::GetFrameworkDelegate()->NotifyCustomEvent(
this, kHelpBubbleAnchorBoundsChangedEvent);
}
return;
}
last_known_bounds_ = bounds;
visible_ = visible;
auto* const delegate = ui::ElementTracker::GetFrameworkDelegate();
if (visible) {
delegate->NotifyElementShown(this);
} else {
delegate->NotifyElementHidden(this);
}
}
void TrackedElementWebUI::Activate() {
DCHECK(visible_);
ui::ElementTracker::GetFrameworkDelegate()->NotifyElementActivated(this);
}
void TrackedElementWebUI::CustomEvent(ui::CustomElementEventType event_type) {
DCHECK(visible_);
ui::ElementTracker::GetFrameworkDelegate()->NotifyCustomEvent(this,
event_type);
}
DEFINE_FRAMEWORK_SPECIFIC_METADATA(TrackedElementWebUI)
} // namespace user_education
|