153 lines
5.2 KiB
C++
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
|