mirror of
https://github.com/Alex313031/thorium.git
synced 2025-01-10 11:57:48 -03:00
Add files via upload
This commit is contained in:
parent
143dfd9821
commit
79797c3acb
1 changed files with 258 additions and 0 deletions
258
src/ui/views/examples/examples_window.cc
Normal file
258
src/ui/views/examples/examples_window.cc
Normal 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
|
Loading…
Reference in a new issue