mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
add flexlayout
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "ui/views/layout/flex_layout.h"
|
||||
#include "ui/views/layout/layout_manager_base.h"
|
||||
|
||||
#include <limits>
|
||||
@@ -55,6 +56,63 @@ struct Converter<views::ProposedLayout> {
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<views::LayoutOrientation> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
views::LayoutOrientation* out) {
|
||||
std::string orientation = base::ToLowerASCII(gin::V8ToString(isolate, val));
|
||||
if (orientation == "horizontal") {
|
||||
*out = views::LayoutOrientation::kHorizontal;
|
||||
} else if (orientation == "vertical") {
|
||||
*out = views::LayoutOrientation::kVertical;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<views::LayoutAlignment> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
views::LayoutAlignment* out) {
|
||||
std::string orientation = base::ToLowerASCII(gin::V8ToString(isolate, val));
|
||||
if (orientation == "start") {
|
||||
*out = views::LayoutAlignment::kStart;
|
||||
} else if (orientation == "center") {
|
||||
*out = views::LayoutAlignment::kCenter;
|
||||
} else if (orientation == "end") {
|
||||
*out = views::LayoutAlignment::kEnd;
|
||||
} else if (orientation == "stretch") {
|
||||
*out = views::LayoutAlignment::kStretch;
|
||||
} else if (orientation == "baseline") {
|
||||
*out = views::LayoutAlignment::kBaseline;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<views::FlexAllocationOrder> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
views::FlexAllocationOrder* out) {
|
||||
std::string orientation = base::ToLowerASCII(gin::V8ToString(isolate, val));
|
||||
if (orientation == "normal") {
|
||||
*out = views::FlexAllocationOrder::kNormal;
|
||||
} else if (orientation == "reverse") {
|
||||
*out = views::FlexAllocationOrder::kReverse;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<views::SizeBound> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
@@ -79,29 +137,24 @@ struct Converter<views::SizeBounds> {
|
||||
|
||||
namespace electron::api {
|
||||
|
||||
using LayoutCallback = base::RepeatingCallback<views::ProposedLayout(
|
||||
const views::SizeBounds& size_bounds)>;
|
||||
|
||||
class JSLayoutManager : public views::LayoutManagerBase {
|
||||
public:
|
||||
JSLayoutManager(v8::Isolate* isolate, v8::Local<v8::Object> js_side)
|
||||
: js_side_(isolate, js_side) {}
|
||||
JSLayoutManager(LayoutCallback layout_callback)
|
||||
: layout_callback_(std::move(layout_callback)) {}
|
||||
~JSLayoutManager() override {}
|
||||
|
||||
views::ProposedLayout CalculateProposedLayout(
|
||||
const views::SizeBounds& size_bounds) const override {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
gin_helper::Dictionary dict(isolate, js_side_.Get(isolate));
|
||||
base::RepeatingCallback<views::ProposedLayout(
|
||||
const views::SizeBounds& size_bounds)>
|
||||
calculate_proposed_layout;
|
||||
if (dict.Get("calculateProposedLayout", &calculate_proposed_layout)) {
|
||||
views::ProposedLayout pl = calculate_proposed_layout.Run(size_bounds);
|
||||
return pl;
|
||||
}
|
||||
return views::ProposedLayout();
|
||||
return layout_callback_.Run(size_bounds);
|
||||
}
|
||||
|
||||
private:
|
||||
v8::Global<v8::Object> js_side_;
|
||||
LayoutCallback layout_callback_;
|
||||
};
|
||||
|
||||
View::View(views::View* view) : view_(view) {
|
||||
@@ -132,8 +185,51 @@ void View::SetBounds(const gfx::Rect& bounds) {
|
||||
view()->SetBoundsRect(bounds);
|
||||
}
|
||||
|
||||
void View::SetLayoutManager(v8::Isolate* isolate, v8::Local<v8::Object> value) {
|
||||
view_->SetLayoutManager(std::make_unique<JSLayoutManager>(isolate, value));
|
||||
gfx::Rect View::GetBounds() {
|
||||
return view()->bounds();
|
||||
}
|
||||
|
||||
void View::SetLayout(v8::Isolate* isolate, v8::Local<v8::Object> value) {
|
||||
gin_helper::Dictionary dict(isolate, value);
|
||||
LayoutCallback calculate_proposed_layout;
|
||||
if (dict.Get("calculateProposedLayout", &calculate_proposed_layout)) {
|
||||
view_->SetLayoutManager(std::make_unique<JSLayoutManager>(
|
||||
std::move(calculate_proposed_layout)));
|
||||
} else {
|
||||
auto* layout =
|
||||
view_->SetLayoutManager(std::make_unique<views::FlexLayout>());
|
||||
views::LayoutOrientation orientation;
|
||||
if (dict.Get("orientation", &orientation))
|
||||
layout->SetOrientation(orientation);
|
||||
views::LayoutAlignment main_axis_alignment;
|
||||
if (dict.Get("mainAxisAlignment", &main_axis_alignment))
|
||||
layout->SetMainAxisAlignment(main_axis_alignment);
|
||||
views::LayoutAlignment cross_axis_alignment;
|
||||
if (dict.Get("crossAxisAlignment", &cross_axis_alignment))
|
||||
layout->SetCrossAxisAlignment(cross_axis_alignment);
|
||||
gfx::Insets interior_margin;
|
||||
if (dict.Get("interiorMargin", &interior_margin))
|
||||
layout->SetInteriorMargin(interior_margin);
|
||||
int minimum_cross_axis_size;
|
||||
if (dict.Get("minimumCrossAxisSize", &minimum_cross_axis_size))
|
||||
layout->SetMinimumCrossAxisSize(minimum_cross_axis_size);
|
||||
bool collapse_margins;
|
||||
if (dict.Has("collapseMargins") &&
|
||||
dict.Get("collapseMargins", &collapse_margins))
|
||||
layout->SetCollapseMargins(collapse_margins);
|
||||
bool include_host_insets_in_layout;
|
||||
if (dict.Has("includeHostInsetsInLayout") &&
|
||||
dict.Get("includeHostInsetsInLayout", &include_host_insets_in_layout))
|
||||
layout->SetIncludeHostInsetsInLayout(include_host_insets_in_layout);
|
||||
bool ignore_default_main_axis_margins;
|
||||
if (dict.Has("ignoreDefaultMainAxisMargins") &&
|
||||
dict.Get("ignoreDefaultMainAxisMargins",
|
||||
&ignore_default_main_axis_margins))
|
||||
layout->SetIgnoreDefaultMainAxisMargins(ignore_default_main_axis_margins);
|
||||
views::FlexAllocationOrder flex_allocation_order;
|
||||
if (dict.Get("flexAllocationOrder", &flex_allocation_order))
|
||||
layout->SetFlexAllocationOrder(flex_allocation_order);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<v8::Local<v8::Value>> View::GetChildren() {
|
||||
@@ -188,7 +284,8 @@ void View::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("addChildViewAt", &View::AddChildViewAt)
|
||||
.SetProperty("children", &View::GetChildren)
|
||||
.SetMethod("setBounds", &View::SetBounds)
|
||||
.SetMethod("setLayoutManager", &View::SetLayoutManager);
|
||||
.SetMethod("getBounds", &View::GetBounds)
|
||||
.SetMethod("setLayout", &View::SetLayout);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,8 @@ class View : public gin_helper::Wrappable<View> {
|
||||
void AddChildViewAt(gin::Handle<View> child, size_t index);
|
||||
|
||||
void SetBounds(const gfx::Rect& bounds);
|
||||
void SetLayoutManager(v8::Isolate* isolate, v8::Local<v8::Object> value);
|
||||
gfx::Rect GetBounds();
|
||||
void SetLayout(v8::Isolate* isolate, v8::Local<v8::Object> value);
|
||||
std::vector<v8::Local<v8::Value>> GetChildren();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "ui/views/layout/flex_layout_types.h"
|
||||
#include "ui/views/view_class_properties.h"
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#include "shell/browser/ui/cocoa/delayed_native_view_host.h"
|
||||
@@ -38,6 +40,10 @@ WebContentsView::WebContentsView(v8::Isolate* isolate,
|
||||
// managed by InspectableWebContents.
|
||||
set_delete_view(false);
|
||||
#endif
|
||||
view()->SetProperty(
|
||||
views::kFlexBehaviorKey,
|
||||
views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum,
|
||||
views::MaximumFlexSizeRule::kUnbounded));
|
||||
Observe(web_contents->web_contents());
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ class RootViewMac : public views::View {
|
||||
RootViewMac& operator=(const RootViewMac&) = delete;
|
||||
|
||||
// views::View:
|
||||
void Layout() override;
|
||||
gfx::Size GetMinimumSize() const override;
|
||||
gfx::Size GetMaximumSize() const override;
|
||||
|
||||
|
||||
@@ -5,22 +5,17 @@
|
||||
#include "shell/browser/ui/cocoa/root_view_mac.h"
|
||||
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "ui/views/layout/fill_layout.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
RootViewMac::RootViewMac(NativeWindow* window) : window_(window) {
|
||||
set_owned_by_client();
|
||||
SetLayoutManager(std::make_unique<views::FillLayout>());
|
||||
}
|
||||
|
||||
RootViewMac::~RootViewMac() = default;
|
||||
|
||||
void RootViewMac::Layout() {
|
||||
if (!window_->content_view()) // Not ready yet.
|
||||
return;
|
||||
|
||||
window_->content_view()->SetBoundsRect(gfx::Rect(gfx::Point(), size()));
|
||||
}
|
||||
|
||||
gfx::Size RootViewMac::GetMinimumSize() const {
|
||||
return window_->GetMinimumSize();
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
|
||||
#include "shell/common/gin_converters/gfx_converter.h"
|
||||
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/gfx/geometry/point_f.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
@@ -107,6 +109,35 @@ bool Converter<gfx::Rect>::FromV8(v8::Isolate* isolate,
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<gfx::Insets>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::Insets& val) {
|
||||
return gin::DataObjectBuilder(isolate)
|
||||
.Set("top", val.top())
|
||||
.Set("left", val.left())
|
||||
.Set("bottom", val.bottom())
|
||||
.Set("right", val.right())
|
||||
.Build();
|
||||
}
|
||||
|
||||
bool Converter<gfx::Insets>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::Insets* out) {
|
||||
gin::Dictionary dict(isolate);
|
||||
if (!gin::ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
double top, left, right, bottom;
|
||||
if (!dict.Get("top", &top))
|
||||
return false;
|
||||
if (!dict.Get("left", &left))
|
||||
return false;
|
||||
if (!dict.Get("bottom", &bottom))
|
||||
return false;
|
||||
if (!dict.Get("right", &right))
|
||||
return false;
|
||||
*out = gfx::Insets::TLBR(top, left, bottom, right);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
struct Converter<display::Display::AccelerometerSupport> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
|
||||
@@ -16,6 +16,7 @@ class Point;
|
||||
class PointF;
|
||||
class Size;
|
||||
class Rect;
|
||||
class Insets;
|
||||
enum class ResizeEdge;
|
||||
} // namespace gfx
|
||||
|
||||
@@ -54,6 +55,15 @@ struct Converter<gfx::Rect> {
|
||||
gfx::Rect* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<gfx::Insets> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const gfx::Insets& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::Insets* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<display::Display> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
|
||||
Reference in New Issue
Block a user