Add files via upload

This commit is contained in:
Alexander David Frick 2022-07-25 02:55:41 -05:00 committed by GitHub
parent 143dfd9821
commit 79797c3acb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -0,0 +1,258 @@
// Copyright (c) 2022 The Chromium Authors and Alex313031. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/examples/examples_window.h"
#include <algorithm>
#include <iostream>
#include <iterator>
#include <memory>
#include <string>
#include <utility>
#include "base/command_line.h"
#include "base/containers/cxx20_erase.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/combobox_model.h"
#include "ui/base/ui_base_paths.h"
#include "ui/color/color_id.h"
#include "ui/views/background.h"
#include "ui/views/controls/combobox/combobox.h"
#include "ui/views/controls/label.h"
#include "ui/views/examples/create_examples.h"
#include "ui/views/examples/grit/views_examples_resources.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
namespace views {
namespace examples {
const char kExamplesWidgetName[] = "ExamplesWidget";
static const char kEnableExamples[] = "enable-examples";
bool CheckCommandLineUsage() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch("help")) {
// Print the program usage.
std::cout << "Usage: " << command_line->GetProgram() << " [--"
<< kEnableExamples << "=<example1,[example2...]>]\n";
return true;
}
return false;
}
namespace {
ExampleVector GetExamplesToShow(ExampleVector examples) {
using StringVector = std::vector<std::string>;
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
std::sort(examples.begin(), examples.end(), [](const auto& a, const auto& b) {
return a->example_title() < b->example_title();
});
std::string enable_examples =
command_line->GetSwitchValueASCII(kEnableExamples);
if (!enable_examples.empty()) {
// Filter examples to show based on the command line switch.
StringVector enabled =
base::SplitString(enable_examples, ";,", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
// Transform list of examples to just the list of names.
StringVector example_names;
std::transform(
examples.begin(), examples.end(), std::back_inserter(example_names),
[](const auto& example) { return example->example_title(); });
std::sort(enabled.begin(), enabled.end());
// Get an intersection of list of titles between the full list and the list
// from the command-line.
StringVector valid_examples =
base::STLSetIntersection<StringVector>(enabled, example_names);
// If there are still example names in the list, only include the examples
// from the list.
if (!valid_examples.empty()) {
base::EraseIf(examples, [valid_examples](auto& example) {
return std::find(valid_examples.begin(), valid_examples.end(),
example->example_title()) == valid_examples.end();
});
}
} else if (command_line->HasSwitch(kEnableExamples)) {
std::string titles;
for (auto& example : examples) {
titles += "\n\t";
titles += example->example_title();
}
titles += "\n";
std::cout << "By default, all examples will be shown.";
std::cout << "You may want to specify the example(s) you want to run:"
<< titles;
}
for (auto& example : examples)
example->CreateExampleView(example->example_view());
return examples;
}
} // namespace
// Model for the examples that are being added via AddExample().
class ComboboxModelExampleList : public ui::ComboboxModel {
public:
ComboboxModelExampleList() = default;
ComboboxModelExampleList(const ComboboxModelExampleList&) = delete;
ComboboxModelExampleList& operator=(const ComboboxModelExampleList&) = delete;
~ComboboxModelExampleList() override = default;
void SetExamples(ExampleVector examples) {
example_list_ = std::move(examples);
}
// ui::ComboboxModel:
size_t GetItemCount() const override { return example_list_.size(); }
std::u16string GetItemAt(size_t index) const override {
return base::UTF8ToUTF16(example_list_[index]->example_title());
}
View* GetItemViewAt(size_t index) {
return example_list_[index]->example_view();
}
private:
ExampleVector example_list_;
};
class ExamplesWindowContents : public WidgetDelegateView {
public:
ExamplesWindowContents(base::OnceClosure on_close, ExampleVector examples)
: on_close_(std::move(on_close)) {
SetHasWindowSizeControls(true);
auto combobox_model = std::make_unique<ComboboxModelExampleList>();
combobox_model_ = combobox_model.get();
combobox_model_->SetExamples(std::move(examples));
auto combobox = std::make_unique<Combobox>(std::move(combobox_model));
instance_ = this;
combobox->SetCallback(base::BindRepeating(
&ExamplesWindowContents::ComboboxChanged, base::Unretained(this)));
combobox->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_EXAMPLES_COMBOBOX_AX_LABEL));
SetBackground(CreateThemedSolidBackground(ui::kColorDialogBackground));
auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
BoxLayout::Orientation::kVertical, gfx::Insets(5)));
combobox_ = AddChildView(std::move(combobox));
auto item_count = combobox_model_->GetItemCount();
if (item_count > 0) {
combobox_->SetVisible(item_count > 1);
example_shown_ = AddChildView(std::make_unique<View>());
example_shown_->SetLayoutManager(std::make_unique<FillLayout>());
example_shown_->AddChildView(combobox_model_->GetItemViewAt(0));
layout->SetFlexForView(example_shown_, 1);
}
status_label_ = AddChildView(std::make_unique<Label>());
}
ExamplesWindowContents(const ExamplesWindowContents&) = delete;
ExamplesWindowContents& operator=(const ExamplesWindowContents&) = delete;
~ExamplesWindowContents() override = default;
// Sets the status area (at the bottom of the window) to |status|.
void SetStatus(const std::string& status) {
status_label_->SetText(base::UTF8ToUTF16(status));
}
static ExamplesWindowContents* instance() { return instance_; }
private:
// WidgetDelegateView:
std::u16string GetWindowTitle() const override { return u"Thorium UI Debug Shell"; }
void WindowClosing() override {
instance_ = nullptr;
if (on_close_)
std::move(on_close_).Run();
}
gfx::Size CalculatePreferredSize() const override {
gfx::Size size(800, 300);
for (size_t i = 0; i < combobox_model_->GetItemCount(); i++) {
size.set_height(
std::max(size.height(),
combobox_model_->GetItemViewAt(i)->GetHeightForWidth(800)));
}
return size;
}
gfx::Size GetMinimumSize() const override { return gfx::Size(50, 50); }
void ComboboxChanged() {
size_t index = combobox_->GetSelectedIndex().value();
DCHECK_LT(index, combobox_model_->GetItemCount());
example_shown_->RemoveAllChildViewsWithoutDeleting();
example_shown_->AddChildView(combobox_model_->GetItemViewAt(index));
example_shown_->RequestFocus();
SetStatus(std::string());
InvalidateLayout();
}
static ExamplesWindowContents* instance_;
raw_ptr<View> example_shown_ = nullptr;
raw_ptr<Label> status_label_ = nullptr;
base::OnceClosure on_close_;
raw_ptr<Combobox> combobox_ = nullptr;
// Owned by |combobox_|.
raw_ptr<ComboboxModelExampleList> combobox_model_ = nullptr;
};
// static
ExamplesWindowContents* ExamplesWindowContents::instance_ = nullptr;
Widget* GetExamplesWidget() {
return ExamplesWindowContents::instance()
? ExamplesWindowContents::instance()->GetWidget()
: nullptr;
}
void ShowExamplesWindow(base::OnceClosure on_close,
ExampleVector examples,
gfx::NativeWindow window_context) {
if (ExamplesWindowContents::instance()) {
ExamplesWindowContents::instance()->GetWidget()->Activate();
} else {
examples = GetExamplesToShow(std::move(examples));
Widget* widget = new Widget;
Widget::InitParams params;
params.delegate =
new ExamplesWindowContents(std::move(on_close), std::move(examples));
params.context = window_context;
params.name = kExamplesWidgetName;
widget->Init(std::move(params));
widget->Show();
}
}
void LogStatus(const std::string& string) {
if (ExamplesWindowContents::instance())
ExamplesWindowContents::instance()->SetStatus(string);
}
} // namespace examples
} // namespace views