Files
brave-core/browser/ui/containers/containers_menu_model.cc
Aleksei Khoroshilov b225040fe1 Add temporary containers. (#36060)
* Add temporary containers.

* Add few more sync-related tests.
2026-05-08 13:33:35 +07:00

153 lines
5.2 KiB
C++

// Copyright (c) 2025 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
#include "brave/browser/ui/containers/containers_menu_model.h"
#include <utility>
#include <vector>
#include "base/strings/utf_string_conversions.h"
#include "brave/app/brave_command_ids.h"
#include "brave/browser/ui/containers/container_model.h"
#include "brave/grit/brave_generated_resources.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/grit/generated_resources.h"
#if BUILDFLAG(IS_MAC)
#include "ui/gfx/image/image_skia.h"
#endif
namespace containers {
ContainersMenuModel::ContainersMenuModel(Delegate& delegate,
const ContainersService& service)
: ui::SimpleMenuModel(this),
delegate_(delegate),
current_container_ids_(delegate_->GetCurrentContainerIds()),
items_(GetContainerModels(service,
current_container_ids_,
delegate_->GetScaleFactor())) {
BuildMenuItems();
}
ContainersMenuModel::ContainersMenuModel(Delegate& delegate,
std::vector<ContainerModel> items)
: ui::SimpleMenuModel(this),
delegate_(delegate),
current_container_ids_(delegate_->GetCurrentContainerIds()),
items_(std::move(items)) {
BuildMenuItems();
}
ContainersMenuModel::~ContainersMenuModel() = default;
void ContainersMenuModel::BuildMenuItems() {
// Trim the items to fit within the command ID range.
const auto max_items = static_cast<size_t>(IDC_OPEN_IN_CONTAINER_END -
IDC_OPEN_IN_CONTAINER_START);
if (items_.size() > max_items) {
items_.erase(items_.begin() + max_items, items_.end());
LOG(WARNING) << "Too many containers for the current menu model. "
<< "Trimming to fit within command ID range.";
}
// 1. Add an item to indicate "No container" state.
AddCheckItemWithStringId(IDC_OPEN_IN_CONTAINER_NO_CONTAINER,
IDS_CXMENU_NO_CONTAINER);
// 2. Add items for each container.
int index = 0;
for (const auto& item : items_) {
AddCheckItem(ItemIndexToCommandId(index), base::UTF8ToUTF16(item.name()));
SetIcon(index + 1,
#if BUILDFLAG(IS_MAC)
// On macOS, vector icon version of menu items are not supported.
// For the reference, we tried fix this with adhoc patch in
// https://github.com/brave/brave-core/pull/21835/files but was
// imperfect in some cases.
// So we just rasterize the icon right away and convert it to
// ImageSkia version model.
ui::ImageModel::FromImageSkia(
item.icon().Rasterize(/*color_provider=*/nullptr)));
#else
item.icon());
#endif
index++;
}
// 3. Add a separator.
AddSeparator(ui::NORMAL_SEPARATOR);
// 4. Add an item to create a new temporary container.
AddItemWithStringId(IDC_NEW_TEMPORARY_CONTAINER,
IDS_CXMENU_NEW_TEMPORARY_CONTAINER);
// 5. Add an item to open settings page.
AddItemWithStringId(IDC_OPEN_CONTAINERS_SETTING,
IDS_CXMENU_OPEN_CONTAINERS_SETTINGS);
}
void ContainersMenuModel::ExecuteCommand(int command_id, int event_flags) {
if (command_id == IDC_OPEN_IN_CONTAINER_START) {
// "No container" is selected.
delegate_->OnNoContainerSelected();
return;
}
if (command_id == IDC_NEW_TEMPORARY_CONTAINER) {
delegate_->OnNewTemporaryContainerSelected();
return;
}
if (command_id == IDC_OPEN_CONTAINERS_SETTING) {
// Open the containers settings page
OpenContainerSettingsPage();
return;
}
// Set the selected container ID.
ContainerSelected(command_id);
}
void ContainersMenuModel::OpenContainerSettingsPage() {
chrome::ShowSettingsSubPage(delegate_->GetBrowserToOpenSettings(),
"braveContent");
}
void ContainersMenuModel::ContainerSelected(int command_id) {
delegate_->OnContainerSelected(
items_[CommandIdToItemIndex(command_id)].container());
}
bool ContainersMenuModel::IsCommandIdChecked(int command_id) const {
if (command_id == IDC_OPEN_IN_CONTAINER_START) {
// IDC_OPEN_IN_CONTAINER_START is the command ID for the "No container"
return current_container_ids_.empty();
}
return current_container_ids_.contains(
items_[CommandIdToItemIndex(command_id)].container()->id);
}
bool ContainersMenuModel::IsCommandIdEnabled(int command_id) const {
return true;
}
int ContainersMenuModel::CommandIdToItemIndex(int command_id) const {
const auto item_index = command_id - IDC_OPEN_IN_CONTAINER_START - 1;
CHECK(item_index >= 0 && item_index < static_cast<int>(items_.size()))
<< "Command ID " << command_id
<< " is out of range for the current menu model.";
return item_index;
}
int ContainersMenuModel::ItemIndexToCommandId(int item_index) const {
CHECK(item_index >= 0 && item_index < static_cast<int>(items_.size()))
<< "Item index " << item_index
<< " is out of range for the current menu model.";
return item_index + IDC_OPEN_IN_CONTAINER_START + 1;
}
} // namespace containers