Add UI for assigned/shared tasks
This will display an icon in view state, indicating task's origin; and icon + "Others can see changes that you make to this task" notice in edit state. Bug: b/308454705 Change-Id: I38eca4f9c1d73dc2fe9858bc7feda92b9164507d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5559523 Reviewed-by: Toni Barzic <tbarzic@chromium.org> Reviewed-by: James Cook <jamescook@chromium.org> Commit-Queue: Artsiom Mitrokhin <amitrokhin@chromium.org> Cr-Commit-Position: refs/heads/main@{#1305229}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
3723167af9
commit
2ee5beed6b
ash
@ -7579,6 +7579,10 @@ New install
|
||||
<message name="IDS_GLANCEABLES_TASKS_ERROR_EDIT_TASK_FAILED_WHILE_OFFLINE" desc="The error message used in the task glanceable to notify users that the glanceables failed to commit the task that they edited because the device is offline. Also guide the user to try again when the device is connected to the network.">
|
||||
Couldn't edit task. Try again when online.
|
||||
</message>
|
||||
<message name="IDS_GLANCEABLES_TASKS_ASSIGNED_TASK_NOTICE" desc="The glanceable displays tasks fetched from Google Tasks API. Some of them can be created and assigned by other users (e.g. via Google Docs). This is a privacy notice warning that any changes will be visible to others (e.g. everyone having access to the same origin document).">
|
||||
Others can see changes that you make to this task
|
||||
</message>
|
||||
|
||||
<!-- Do Not Disturb notification -->
|
||||
<message name="IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_TITLE" desc="Label used for the notification that shows up when the 'Do Not Disturb' feature is enabled.">
|
||||
Do Not Disturb is on
|
||||
|
@ -0,0 +1 @@
|
||||
d9e7cd0e6ef61ae983828f19a8881f65e55d4a99
|
@ -33,7 +33,7 @@ enum class GlanceablesViewId {
|
||||
kClassroomItemDueDateLabel,
|
||||
kClassroomItemDueTimeLabel,
|
||||
|
||||
// `GlanceablesTasksView` or `TasksBubbleView`.
|
||||
// `GlanceablesTasksView`.
|
||||
kTasksBubbleComboBox,
|
||||
kTasksBubbleListScrollView,
|
||||
kTasksBubbleExpandButton,
|
||||
@ -48,6 +48,8 @@ enum class GlanceablesViewId {
|
||||
kTaskItemTitleTextField,
|
||||
kTaskItemDueLabel,
|
||||
kTaskItemEditInBrowserLabel,
|
||||
kOriginSurfaceTypeIcon,
|
||||
kAssignedTaskNotice,
|
||||
|
||||
// `GlanceablesErrorMessageView`
|
||||
kGlanceablesErrorMessageLabel,
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "ui/views/controls/label.h"
|
||||
#include "ui/views/controls/textfield/textfield.h"
|
||||
#include "ui/views/controls/textfield/textfield_controller.h"
|
||||
#include "ui/views/layout/box_layout_view.h"
|
||||
#include "ui/views/layout/flex_layout_view.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
|
||||
@ -300,6 +301,8 @@ GlanceablesTaskView::GlanceablesTaskView(
|
||||
ShowErrorMessageCallback show_error_message_callback)
|
||||
: task_id_(task ? task->id : ""),
|
||||
task_title_(task ? base::UTF8ToUTF16(task->title) : u""),
|
||||
origin_surface_type_(task ? task->origin_surface_type
|
||||
: api::Task::OriginSurfaceType::kRegular),
|
||||
mark_as_completed_callback_(std::move(mark_as_completed_callback)),
|
||||
save_callback_(std::move(save_callback)),
|
||||
edit_in_browser_callback_(std::move(edit_in_browser_callback)),
|
||||
@ -375,12 +378,30 @@ GlanceablesTaskView::GlanceablesTaskView(
|
||||
CreateSecondRowIcon(kGlanceablesTasksNotesIcon));
|
||||
}
|
||||
|
||||
if (origin_surface_type_ != api::Task::OriginSurfaceType::kRegular) {
|
||||
details.push_back(
|
||||
l10n_util::GetStringUTF16(IDS_GLANCEABLES_TASKS_ASSIGNED_TASK_NOTICE));
|
||||
|
||||
const gfx::VectorIcon* icon = nullptr;
|
||||
if (origin_surface_type_ == api::Task::OriginSurfaceType::kDocument) {
|
||||
icon = &kGlanceablesTasksTaskAssignedFromDocumentIcon;
|
||||
} else if (origin_surface_type_ == api::Task::OriginSurfaceType::kSpace) {
|
||||
icon = &kGlanceablesTasksTaskAssignedFromSpaceIcon;
|
||||
}
|
||||
|
||||
if (icon) {
|
||||
origin_surface_type_icon_ =
|
||||
tasks_details_view_->AddChildView(CreateSecondRowIcon(*icon));
|
||||
origin_surface_type_icon_->SetID(
|
||||
base::to_underlying(GlanceablesViewId::kOriginSurfaceTypeIcon));
|
||||
}
|
||||
}
|
||||
|
||||
// If the task view is not associated with a task - e.g. for the view to add
|
||||
// a new task, the edit in browser button will remain visible, and thus does
|
||||
// not require a layer (used to animate the button visibility).
|
||||
if (!task) {
|
||||
edit_in_browser_button_ = contents_view_->AddChildView(
|
||||
std::make_unique<EditInBrowserButton>(edit_in_browser_callback_));
|
||||
AddExtraContentForEditState();
|
||||
}
|
||||
|
||||
UpdateTaskTitleViewForState(TaskTitleViewState::kView);
|
||||
@ -460,8 +481,12 @@ void GlanceablesTaskView::UpdateTaskTitleViewForState(
|
||||
task_title_button_->UpdateLabelForState(
|
||||
/*completed=*/check_button_->checked());
|
||||
|
||||
if (origin_surface_type_icon_) {
|
||||
origin_surface_type_icon_->SetVisible(true);
|
||||
}
|
||||
|
||||
if (!task_id_.empty()) {
|
||||
AnimateEditInBrowserButtonVisibility(false);
|
||||
AnimateExtraContentForEditStateVisibility(false);
|
||||
}
|
||||
break;
|
||||
case TaskTitleViewState::kEdit:
|
||||
@ -474,8 +499,12 @@ void GlanceablesTaskView::UpdateTaskTitleViewForState(
|
||||
GetWidget()->widget_delegate()->SetCanActivate(true);
|
||||
task_title_textfield_->RequestFocus();
|
||||
|
||||
if (origin_surface_type_icon_) {
|
||||
origin_surface_type_icon_->SetVisible(false);
|
||||
}
|
||||
|
||||
if (!task_id_.empty()) {
|
||||
AnimateEditInBrowserButtonVisibility(true);
|
||||
AnimateExtraContentForEditStateVisibility(true);
|
||||
}
|
||||
|
||||
edit_exit_observer_.AddObservation(task_title_textfield_);
|
||||
@ -491,6 +520,45 @@ void GlanceablesTaskView::UpdateTaskTitleViewForState(
|
||||
}
|
||||
}
|
||||
|
||||
void GlanceablesTaskView::AddExtraContentForEditState() {
|
||||
auto extra_content = std::make_unique<views::BoxLayoutView>();
|
||||
extra_content->SetOrientation(views::BoxLayout::Orientation::kVertical);
|
||||
extra_content->SetMainAxisAlignment(
|
||||
views::BoxLayout::MainAxisAlignment::kCenter);
|
||||
extra_content->SetCrossAxisAlignment(
|
||||
views::BoxLayout::CrossAxisAlignment::kStart);
|
||||
|
||||
if (origin_surface_type_ != api::Task::OriginSurfaceType::kRegular) {
|
||||
auto assigned_task_notice = std::make_unique<views::BoxLayoutView>();
|
||||
assigned_task_notice->SetOrientation(
|
||||
views::BoxLayout::Orientation::kHorizontal);
|
||||
assigned_task_notice->SetMainAxisAlignment(
|
||||
views::BoxLayout::MainAxisAlignment::kStart);
|
||||
assigned_task_notice->SetCrossAxisAlignment(
|
||||
views::BoxLayout::CrossAxisAlignment::kCenter);
|
||||
assigned_task_notice->SetProperty(views::kMarginsKey,
|
||||
kDetailMarginsInEditState);
|
||||
assigned_task_notice->SetID(
|
||||
base::to_underlying(GlanceablesViewId::kAssignedTaskNotice));
|
||||
|
||||
if (origin_surface_type_icon_) {
|
||||
assigned_task_notice->AddChildView(std::make_unique<views::ImageView>(
|
||||
origin_surface_type_icon_->GetImageModel()));
|
||||
}
|
||||
|
||||
assigned_task_notice->AddChildView(std::make_unique<views::Label>(
|
||||
l10n_util::GetStringUTF16(IDS_GLANCEABLES_TASKS_ASSIGNED_TASK_NOTICE)));
|
||||
|
||||
extra_content->AddChildView(std::move(assigned_task_notice));
|
||||
}
|
||||
|
||||
edit_in_browser_button_ = extra_content->AddChildView(
|
||||
std::make_unique<EditInBrowserButton>(edit_in_browser_callback_));
|
||||
|
||||
extra_content_for_edit_state_ =
|
||||
contents_view_->AddChildView(std::move(extra_content));
|
||||
}
|
||||
|
||||
void GlanceablesTaskView::UpdateContentsMargins(TaskTitleViewState state) {
|
||||
switch (state) {
|
||||
case TaskTitleViewState::kNotInitialized:
|
||||
@ -513,45 +581,49 @@ void GlanceablesTaskView::UpdateContentsMargins(TaskTitleViewState state) {
|
||||
}
|
||||
}
|
||||
|
||||
void GlanceablesTaskView::AnimateEditInBrowserButtonVisibility(bool visible) {
|
||||
if (visible == !!edit_in_browser_button_) {
|
||||
void GlanceablesTaskView::AnimateExtraContentForEditStateVisibility(
|
||||
bool visible) {
|
||||
if (visible == !!extra_content_for_edit_state_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!visible) {
|
||||
animating_edit_in_browser_layer_ = edit_in_browser_button_->RecreateLayer();
|
||||
animating_extra_content_for_edit_state_layer_ =
|
||||
extra_content_for_edit_state_->RecreateLayer();
|
||||
edit_in_browser_button_ = nullptr;
|
||||
contents_view_->RemoveChildViewT(
|
||||
std::exchange(edit_in_browser_button_, nullptr));
|
||||
std::exchange(extra_content_for_edit_state_, nullptr));
|
||||
} else {
|
||||
edit_in_browser_button_ = contents_view_->AddChildView(
|
||||
std::make_unique<EditInBrowserButton>(edit_in_browser_callback_));
|
||||
|
||||
edit_in_browser_button_->SetPaintToLayer();
|
||||
edit_in_browser_button_->layer()->SetFillsBoundsOpaquely(false);
|
||||
edit_in_browser_button_->layer()->SetOpacity(
|
||||
animating_edit_in_browser_layer_
|
||||
? animating_edit_in_browser_layer_->opacity()
|
||||
AddExtraContentForEditState();
|
||||
extra_content_for_edit_state_->SetPaintToLayer();
|
||||
extra_content_for_edit_state_->layer()->SetFillsBoundsOpaquely(false);
|
||||
extra_content_for_edit_state_->layer()->SetOpacity(
|
||||
animating_extra_content_for_edit_state_layer_
|
||||
? animating_extra_content_for_edit_state_layer_->opacity()
|
||||
: 0.0f);
|
||||
animating_edit_in_browser_layer_.reset();
|
||||
animating_extra_content_for_edit_state_layer_.reset();
|
||||
}
|
||||
|
||||
// Animate the transform back to the identity transform.
|
||||
views::AnimationBuilder()
|
||||
.OnEnded(base::BindOnce(
|
||||
&GlanceablesTaskView::OnEditInBrowserVisibilityAnimationCompleted,
|
||||
&GlanceablesTaskView::
|
||||
OnExtraContentForEditStateVisibilityAnimationCompleted,
|
||||
weak_ptr_factory_.GetWeakPtr()))
|
||||
.OnAborted(base::BindOnce(
|
||||
&GlanceablesTaskView::OnEditInBrowserVisibilityAnimationCompleted,
|
||||
&GlanceablesTaskView::
|
||||
OnExtraContentForEditStateVisibilityAnimationCompleted,
|
||||
weak_ptr_factory_.GetWeakPtr()))
|
||||
.Once()
|
||||
.SetOpacity(visible ? edit_in_browser_button_->layer()
|
||||
: animating_edit_in_browser_layer_.get(),
|
||||
.SetOpacity(visible ? extra_content_for_edit_state_->layer()
|
||||
: animating_extra_content_for_edit_state_layer_.get(),
|
||||
visible ? 1.0f : 0.5f, gfx::Tween::LINEAR)
|
||||
.SetDuration(base::Milliseconds(visible ? 100 : 50));
|
||||
}
|
||||
|
||||
void GlanceablesTaskView::OnEditInBrowserVisibilityAnimationCompleted() {
|
||||
animating_edit_in_browser_layer_.reset();
|
||||
void GlanceablesTaskView::
|
||||
OnExtraContentForEditStateVisibilityAnimationCompleted() {
|
||||
animating_extra_content_for_edit_state_layer_.reset();
|
||||
}
|
||||
|
||||
void GlanceablesTaskView::CheckButtonPressed() {
|
||||
@ -605,13 +677,14 @@ void GlanceablesTaskView::OnFinishedEditing(const std::u16string& title) {
|
||||
if (task_title_textfield_) {
|
||||
task_title_textfield_->SetEnabled(false);
|
||||
}
|
||||
if (edit_in_browser_button_ && !edit_in_browser_button_->layer()) {
|
||||
edit_in_browser_button_->SetPaintToLayer();
|
||||
edit_in_browser_button_->layer()->SetFillsBoundsOpaquely(false);
|
||||
if (extra_content_for_edit_state_ &&
|
||||
!extra_content_for_edit_state_->layer()) {
|
||||
extra_content_for_edit_state_->SetPaintToLayer();
|
||||
extra_content_for_edit_state_->layer()->SetFillsBoundsOpaquely(false);
|
||||
}
|
||||
if (task_id_.empty() && edit_in_browser_button_ &&
|
||||
!edit_in_browser_button_->HasFocus()) {
|
||||
AnimateEditInBrowserButtonVisibility(false);
|
||||
AnimateExtraContentForEditStateVisibility(false);
|
||||
}
|
||||
|
||||
// Note: result for task addition flow will be recorded in the parent view,
|
||||
@ -623,9 +696,6 @@ void GlanceablesTaskView::OnFinishedEditing(const std::u16string& title) {
|
||||
base::UTF16ToUTF8(task_title_),
|
||||
base::BindOnce(&GlanceablesTaskView::OnSaved,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
// TODO(b/301253574): introduce "disabled" state for this view to prevent
|
||||
// editing / marking as complete while the task is not fully created yet and
|
||||
// race conditions while editing the same task.
|
||||
} else {
|
||||
// Note: result for task addition flow will be recorded in the parent view,
|
||||
// which initialized add task flow.
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "ash/api/tasks/tasks_client.h"
|
||||
#include "ash/api/tasks/tasks_types.h"
|
||||
#include "ash/ash_export.h"
|
||||
#include "ash/glanceables/common/glanceables_error_message_view.h"
|
||||
#include "ash/glanceables/tasks/glanceables_tasks_error_type.h"
|
||||
@ -21,6 +22,7 @@
|
||||
|
||||
namespace views {
|
||||
class ImageButton;
|
||||
class ImageView;
|
||||
class LabelButton;
|
||||
} // namespace views
|
||||
|
||||
@ -28,10 +30,6 @@ namespace ash {
|
||||
|
||||
class SystemTextfield;
|
||||
|
||||
namespace api {
|
||||
struct Task;
|
||||
} // namespace api
|
||||
|
||||
// `GlanceablesTaskView` uses `views::FlexLayout` to show tasks metadata within
|
||||
// the `GlanceablesTasksView`.
|
||||
// +---------------------------------------------------------------+
|
||||
@ -97,14 +95,18 @@ class ASH_EXPORT GlanceablesTaskView : public views::FlexLayoutView,
|
||||
class CheckButton;
|
||||
class TaskTitleButton;
|
||||
|
||||
// Adds additional content (assigned task privacy notice if available + edit
|
||||
// in browser button) when the view is in edit mode.
|
||||
void AddExtraContentForEditState();
|
||||
|
||||
// Updates the margins of views in `contents_view_`.
|
||||
void UpdateContentsMargins(TaskTitleViewState state);
|
||||
|
||||
// Updates the edit in browser button visibility, animating the button
|
||||
// opacity. When hiding the button, the button is hidden immediately, but copy
|
||||
// of its layer is created, and animated in its place.
|
||||
void AnimateEditInBrowserButtonVisibility(bool visible);
|
||||
void OnEditInBrowserVisibilityAnimationCompleted();
|
||||
// Updates the `extra_content_for_edit_state_` visibility animating its
|
||||
// opacity. When hiding the container, the container is hidden immediately,
|
||||
// but copy of its layer is created, and animated in its place.
|
||||
void AnimateExtraContentForEditStateVisibility(bool visible);
|
||||
void OnExtraContentForEditStateVisibilityAnimationCompleted();
|
||||
|
||||
// Handles press events on `check_button_`.
|
||||
void CheckButtonPressed();
|
||||
@ -127,6 +129,8 @@ class ASH_EXPORT GlanceablesTaskView : public views::FlexLayoutView,
|
||||
raw_ptr<TaskTitleButton> task_title_button_ = nullptr;
|
||||
raw_ptr<SystemTextfield> task_title_textfield_ = nullptr;
|
||||
raw_ptr<views::FlexLayoutView> tasks_details_view_ = nullptr;
|
||||
raw_ptr<views::ImageView> origin_surface_type_icon_ = nullptr;
|
||||
raw_ptr<views::View> extra_content_for_edit_state_ = nullptr;
|
||||
raw_ptr<views::LabelButton> edit_in_browser_button_ = nullptr;
|
||||
|
||||
// ID for the task represented by this view.
|
||||
@ -135,6 +139,9 @@ class ASH_EXPORT GlanceablesTaskView : public views::FlexLayoutView,
|
||||
// Title of the task.
|
||||
std::u16string task_title_;
|
||||
|
||||
// The type of surface a task originates from.
|
||||
api::Task::OriginSurfaceType origin_surface_type_;
|
||||
|
||||
// Cached to reset the value of `task_title_` when the new title failed to
|
||||
// commit after editing.
|
||||
std::u16string task_title_before_edit_ = u"";
|
||||
@ -157,11 +164,12 @@ class ASH_EXPORT GlanceablesTaskView : public views::FlexLayoutView,
|
||||
// between editing and viewing state.
|
||||
StateChangeObserverCallback state_change_observer_;
|
||||
|
||||
// Copy of edit in browser button layer used for the button visibility
|
||||
// animation when hiding the button. The button view gets hidden immediately,
|
||||
// and the layer is faded out in its place. Deleted when the fade out
|
||||
// animation completes.
|
||||
std::unique_ptr<ui::Layer> animating_edit_in_browser_layer_;
|
||||
// Copy of `extra_content_for_edit_state_` (assigned task privacy notice if
|
||||
// available + edit in browser button) layer used for the visibility animation
|
||||
// when hiding the container. The container gets hidden immediately, and the
|
||||
// layer is faded out in its place. Deleted when the fade out animation
|
||||
// completes.
|
||||
std::unique_ptr<ui::Layer> animating_extra_content_for_edit_state_layer_;
|
||||
|
||||
base::ScopedMultiSourceObservation<views::View, GlanceablesTaskView>
|
||||
edit_exit_observer_{this};
|
||||
|
@ -28,8 +28,10 @@
|
||||
#include "ui/events/keycodes/keyboard_codes_posix.h"
|
||||
#include "ui/views/controls/button/image_button.h"
|
||||
#include "ui/views/controls/button/label_button.h"
|
||||
#include "ui/views/controls/image_view.h"
|
||||
#include "ui/views/controls/label.h"
|
||||
#include "ui/views/controls/textfield/textfield.h"
|
||||
#include "ui/views/view.h"
|
||||
#include "ui/views/view_utils.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "url/gurl.h"
|
||||
@ -593,4 +595,67 @@ TEST_F(GlanceablesTaskViewTest, HandlesPressingCheckButtonWhileAdding) {
|
||||
EXPECT_TRUE(title_button->GetEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GlanceablesTaskViewTest, DisplaysOriginSurfaceType) {
|
||||
for (auto origin_surface_type : {api::Task::OriginSurfaceType::kRegular,
|
||||
api::Task::OriginSurfaceType::kDocument,
|
||||
api::Task::OriginSurfaceType::kSpace,
|
||||
api::Task::OriginSurfaceType::kUnknown}) {
|
||||
SCOPED_TRACE(::testing::Message()
|
||||
<< "origin_surface_type="
|
||||
<< base::to_underlying(origin_surface_type));
|
||||
|
||||
const auto task = api::Task("task-id", "Task title",
|
||||
/*due=*/std::nullopt, /*completed=*/false,
|
||||
/*has_subtasks=*/false,
|
||||
/*has_email_link=*/false,
|
||||
/*has_notes=*/false,
|
||||
/*updated=*/base::Time::Now(),
|
||||
/*web_view_link=*/GURL(), origin_surface_type);
|
||||
const auto widget = CreateFramelessTestWidget();
|
||||
widget->SetFullscreen(true);
|
||||
const auto* const view =
|
||||
widget->SetContentsView(std::make_unique<GlanceablesTaskView>(
|
||||
&task, /*mark_as_completed_callback=*/base::DoNothing(),
|
||||
/*save_callback=*/base::DoNothing(),
|
||||
/*edit_in_browser_callback=*/base::DoNothing(),
|
||||
/*show_error_message_callback=*/base::DoNothing()));
|
||||
|
||||
const auto* const origin_surface_type_icon =
|
||||
views::AsViewClass<views::ImageView>(view->GetViewByID(
|
||||
base::to_underlying(GlanceablesViewId::kOriginSurfaceTypeIcon)));
|
||||
|
||||
// Check presence of the origin surface type icon. It's only added to
|
||||
// assigned/shared tasks except `kUnknown` and visible by default.
|
||||
if (origin_surface_type == api::Task::OriginSurfaceType::kDocument ||
|
||||
origin_surface_type == api::Task::OriginSurfaceType::kSpace) {
|
||||
ASSERT_TRUE(origin_surface_type_icon);
|
||||
EXPECT_TRUE(origin_surface_type_icon->GetVisible());
|
||||
EXPECT_FALSE(views::AsViewClass<views::View>(view->GetViewByID(
|
||||
base::to_underlying(GlanceablesViewId::kAssignedTaskNotice))));
|
||||
} else {
|
||||
EXPECT_FALSE(origin_surface_type_icon);
|
||||
}
|
||||
|
||||
{
|
||||
const auto* const title_label =
|
||||
views::AsViewClass<views::Label>(view->GetViewByID(
|
||||
base::to_underlying(GlanceablesViewId::kTaskItemTitleLabel)));
|
||||
ASSERT_TRUE(title_label);
|
||||
LeftClickOn(title_label);
|
||||
}
|
||||
|
||||
// The icon should disappear after switching to edit mode...
|
||||
if (origin_surface_type == api::Task::OriginSurfaceType::kDocument ||
|
||||
origin_surface_type == api::Task::OriginSurfaceType::kSpace) {
|
||||
EXPECT_FALSE(origin_surface_type_icon->GetVisible());
|
||||
}
|
||||
|
||||
// ...and the notice should appear for all tasks except `kRegular`.
|
||||
if (origin_surface_type != api::Task::OriginSurfaceType::kRegular) {
|
||||
EXPECT_TRUE(views::AsViewClass<views::View>(view->GetViewByID(
|
||||
base::to_underlying(GlanceablesViewId::kAssignedTaskNotice))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ash
|
||||
|
@ -156,6 +156,8 @@ aggregate_vector_icons("ash_vector_icons") {
|
||||
"glanceables_tasks_add_new_task.icon",
|
||||
"glanceables_tasks_due_date.icon",
|
||||
"glanceables_tasks_notes.icon",
|
||||
"glanceables_tasks_task_assigned_from_document.icon",
|
||||
"glanceables_tasks_task_assigned_from_space.icon",
|
||||
"global_media_controls.icon",
|
||||
"hide_closed_caption.icon",
|
||||
"holding_space.icon",
|
||||
|
@ -0,0 +1,37 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
CANVAS_DIMENSIONS, 16,
|
||||
FILL_RULE_NONZERO,
|
||||
MOVE_TO, 5.6f, 5.6f,
|
||||
H_LINE_TO, 10.4f,
|
||||
V_LINE_TO, 7.2f,
|
||||
H_LINE_TO, 5.6f,
|
||||
V_LINE_TO, 5.6f,
|
||||
CLOSE,
|
||||
NEW_PATH,
|
||||
FILL_RULE_NONZERO,
|
||||
MOVE_TO, 8.8f, 8,
|
||||
H_LINE_TO, 5.6f,
|
||||
V_LINE_TO, 9.6f,
|
||||
H_LINE_TO, 8.8f,
|
||||
V_LINE_TO, 8,
|
||||
CLOSE,
|
||||
NEW_PATH,
|
||||
MOVE_TO, 4, 2.4f,
|
||||
H_LINE_TO, 12,
|
||||
CUBIC_TO, 12.88f, 2.4f, 13.6f, 3.12f, 13.6f, 4,
|
||||
V_LINE_TO, 12,
|
||||
CUBIC_TO, 13.6f, 12.88f, 12.88f, 13.6f, 12, 13.6f,
|
||||
H_LINE_TO, 4,
|
||||
CUBIC_TO, 3.12f, 13.6f, 2.4f, 12.88f, 2.4f, 12,
|
||||
V_LINE_TO, 4,
|
||||
CUBIC_TO, 2.4f, 3.12f, 3.12f, 2.4f, 4, 2.4f,
|
||||
CLOSE,
|
||||
MOVE_TO, 4, 12,
|
||||
H_LINE_TO, 12,
|
||||
V_LINE_TO, 4,
|
||||
H_LINE_TO, 4,
|
||||
V_LINE_TO, 12,
|
||||
CLOSE
|
@ -0,0 +1,88 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
CANVAS_DIMENSIONS, 16,
|
||||
FILL_RULE_NONZERO,
|
||||
MOVE_TO, 0, 12,
|
||||
V_LINE_TO, 11.02f,
|
||||
CUBIC_TO, 0, 10.45f, 0.25f, 10.01f, 0.75f, 9.68f,
|
||||
CUBIC_TO, 1.25f, 9.36f, 1.93f, 9.2f, 2.8f, 9.2f,
|
||||
CUBIC_TO, 2.97f, 9.2f, 3.13f, 9.21f, 3.3f, 9.23f,
|
||||
CUBIC_TO, 3.47f, 9.24f, 3.63f, 9.27f, 3.8f, 9.3f,
|
||||
CUBIC_TO, 3.61f, 9.52f, 3.46f, 9.77f, 3.35f, 10.05f,
|
||||
CUBIC_TO, 3.25f, 10.33f, 3.2f, 10.61f, 3.2f, 10.9f,
|
||||
V_LINE_TO, 12,
|
||||
H_LINE_TO, 0,
|
||||
CLOSE,
|
||||
MOVE_TO, 4, 12,
|
||||
V_LINE_TO, 10.98f,
|
||||
CUBIC_TO, 4, 10.67f, 4.08f, 10.39f, 4.23f, 10.13f,
|
||||
CUBIC_TO, 4.4f, 9.88f, 4.62f, 9.68f, 4.88f, 9.55f,
|
||||
CUBIC_TO, 5.37f, 9.31f, 5.88f, 9.12f, 6.4f, 9,
|
||||
CUBIC_TO, 6.92f, 8.87f, 7.46f, 8.8f, 8, 8.8f,
|
||||
CUBIC_TO, 8.54f, 8.8f, 9.08f, 8.87f, 9.6f, 9,
|
||||
CUBIC_TO, 10.12f, 9.12f, 10.63f, 9.31f, 11.12f, 9.55f,
|
||||
CUBIC_TO, 11.38f, 9.68f, 11.59f, 9.88f, 11.75f, 10.13f,
|
||||
CUBIC_TO, 11.92f, 10.39f, 12, 10.67f, 12, 10.98f,
|
||||
V_LINE_TO, 12,
|
||||
H_LINE_TO, 4,
|
||||
CLOSE,
|
||||
MOVE_TO, 12.8f, 12,
|
||||
V_LINE_TO, 10.88f,
|
||||
CUBIC_TO, 12.8f, 10.58f, 12.74f, 10.3f, 12.63f, 10.03f,
|
||||
CUBIC_TO, 12.53f, 9.77f, 12.39f, 9.52f, 12.2f, 9.3f,
|
||||
CUBIC_TO, 12.39f, 9.27f, 12.56f, 9.24f, 12.72f, 9.23f,
|
||||
CUBIC_TO, 12.88f, 9.21f, 13.04f, 9.2f, 13.2f, 9.2f,
|
||||
CUBIC_TO, 14.07f, 9.2f, 14.75f, 9.36f, 15.25f, 9.68f,
|
||||
CUBIC_TO, 15.75f, 10.01f, 16, 10.45f, 16, 11.02f,
|
||||
V_LINE_TO, 12,
|
||||
H_LINE_TO, 12.8f,
|
||||
CLOSE,
|
||||
MOVE_TO, 5.23f, 10.8f,
|
||||
H_LINE_TO, 10.77f,
|
||||
CUBIC_TO, 10.69f, 10.61f, 10.36f, 10.43f, 9.77f, 10.27f,
|
||||
CUBIC_TO, 9.19f, 10.09f, 8.6f, 10, 8, 10,
|
||||
CUBIC_TO, 7.4f, 10, 6.81f, 10.09f, 6.22f, 10.27f,
|
||||
CUBIC_TO, 5.64f, 10.43f, 5.31f, 10.61f, 5.23f, 10.8f,
|
||||
CLOSE,
|
||||
MOVE_TO, 2.8f, 8.4f,
|
||||
CUBIC_TO, 2.47f, 8.4f, 2.18f, 8.28f, 1.95f, 8.05f,
|
||||
CUBIC_TO, 1.72f, 7.82f, 1.6f, 7.53f, 1.6f, 7.2f,
|
||||
CUBIC_TO, 1.6f, 6.87f, 1.72f, 6.58f, 1.95f, 6.35f,
|
||||
CUBIC_TO, 2.18f, 6.12f, 2.47f, 6, 2.8f, 6,
|
||||
CUBIC_TO, 3.13f, 6, 3.42f, 6.12f, 3.65f, 6.35f,
|
||||
CUBIC_TO, 3.88f, 6.58f, 4, 6.87f, 4, 7.2f,
|
||||
CUBIC_TO, 4, 7.53f, 3.88f, 7.82f, 3.65f, 8.05f,
|
||||
CUBIC_TO, 3.42f, 8.28f, 3.13f, 8.4f, 2.8f, 8.4f,
|
||||
CLOSE,
|
||||
MOVE_TO, 13.2f, 8.4f,
|
||||
CUBIC_TO, 12.87f, 8.4f, 12.58f, 8.28f, 12.35f, 8.05f,
|
||||
CUBIC_TO, 12.12f, 7.82f, 12, 7.53f, 12, 7.2f,
|
||||
CUBIC_TO, 12, 6.87f, 12.12f, 6.58f, 12.35f, 6.35f,
|
||||
CUBIC_TO, 12.58f, 6.12f, 12.87f, 6, 13.2f, 6,
|
||||
CUBIC_TO, 13.53f, 6, 13.82f, 6.12f, 14.05f, 6.35f,
|
||||
CUBIC_TO, 14.28f, 6.58f, 14.4f, 6.87f, 14.4f, 7.2f,
|
||||
CUBIC_TO, 14.4f, 7.53f, 14.28f, 7.82f, 14.05f, 8.05f,
|
||||
CUBIC_TO, 13.82f, 8.28f, 13.53f, 8.4f, 13.2f, 8.4f,
|
||||
CLOSE,
|
||||
MOVE_TO, 8, 8,
|
||||
CUBIC_TO, 7.44f, 8, 6.97f, 7.81f, 6.58f, 7.42f,
|
||||
CUBIC_TO, 6.19f, 7.03f, 6, 6.56f, 6, 6,
|
||||
CUBIC_TO, 6, 5.44f, 6.19f, 4.97f, 6.58f, 4.58f,
|
||||
CUBIC_TO, 6.97f, 4.19f, 7.44f, 4, 8, 4,
|
||||
CUBIC_TO, 8.56f, 4, 9.03f, 4.19f, 9.42f, 4.58f,
|
||||
CUBIC_TO, 9.81f, 4.97f, 10, 5.44f, 10, 6,
|
||||
CUBIC_TO, 10, 6.56f, 9.81f, 7.03f, 9.42f, 7.42f,
|
||||
CUBIC_TO, 9.03f, 7.81f, 8.56f, 8, 8, 8,
|
||||
CLOSE,
|
||||
MOVE_TO, 8, 6.8f,
|
||||
CUBIC_TO, 8.22f, 6.8f, 8.41f, 6.72f, 8.57f, 6.57f,
|
||||
CUBIC_TO, 8.72f, 6.41f, 8.8f, 6.22f, 8.8f, 6,
|
||||
CUBIC_TO, 8.8f, 5.78f, 8.72f, 5.59f, 8.57f, 5.43f,
|
||||
CUBIC_TO, 8.41f, 5.28f, 8.22f, 5.2f, 8, 5.2f,
|
||||
CUBIC_TO, 7.78f, 5.2f, 7.59f, 5.28f, 7.43f, 5.43f,
|
||||
CUBIC_TO, 7.28f, 5.59f, 7.2f, 5.78f, 7.2f, 6,
|
||||
CUBIC_TO, 7.2f, 6.22f, 7.28f, 6.41f, 7.43f, 6.57f,
|
||||
CUBIC_TO, 7.59f, 6.72f, 7.78f, 6.8f, 8, 6.8f,
|
||||
CLOSE
|
Reference in New Issue
Block a user