123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- import { Widget, _decorator } from "cc";
- import { EDITOR } from "cc/env";
- import { Adapter } from "./Adapter";
- const { ccclass, property, executeInEditMode, menu } = _decorator;
- enum Flags {
- None = 0,
- TOP = 1 << 0,
- BOTTOM = 1 << 1,
- LEFT = 1 << 2,
- RIGHT = 1 << 3,
- }
- /**
- * @classdesc 安全区域适配Widget , App.isFullScreenAdaption = true 时有效
- * @description
- *
- * 用法:
- *
- * 1. 将本组件挂载在节点上即可(注意:该节点上必须挂在 Widget 组件)
- *
- * 适配原理:
- *
- * 1. 根据安全区域范围,修改widget组件属性
- * 自动添加刘海宽度,以避免显示到安全区域之外
- */
- @ccclass("AdapterSafeArea")
- @executeInEditMode
- @menu("Quick适配组件/AdapterSafeArea")
- export default class AdapterSafeArea extends Adapter {
- @property
- protected _flags: number = Flags.None;
- protected setFlag(flag: Flags, value: boolean) {
- const current = (this._flags & flag) > 0;
- if (value == current) {
- return;
- }
- if (value) {
- this._flags |= flag;
- } else {
- this._flags &= ~flag;
- }
- this._isDirty = true;
- }
- @property({ tooltip: EDITOR ? "是否对齐上边" : "" })
- get isAlignTop() {
- return (this._flags & Flags.TOP) > 0;
- }
- set isAlignTop(v) {
- this.setFlag(Flags.TOP, v);
- }
- @property({ tooltip: EDITOR ? "是否对齐下边" : "" })
- get isAlignBottom() {
- return (this._flags & Flags.BOTTOM) > 0;
- }
- set isAlignBottom(v) {
- this.setFlag(Flags.BOTTOM, v);
- }
- @property({ tooltip: EDITOR ? "是否对齐左边" : "" })
- get isAlignLeft() {
- return (this._flags & Flags.LEFT) > 0;
- }
- set isAlignLeft(v) {
- this.setFlag(Flags.LEFT, v);
- }
- @property({ tooltip: EDITOR ? "是否对齐右边" : "" })
- get isAlignRight() {
- return (this._flags & Flags.RIGHT) > 0;
- }
- set isAlignRight(v) {
- this.setFlag(Flags.RIGHT, v);
- }
- @property
- _top = 0;
- @property({
- visible: function (this: AdapterSafeArea) {
- return this.isAlignTop;
- }, tooltip: EDITOR ? "本节点顶边和父节点顶边的距离,可填写负值,只有在 isAlignTop 开启时才有作用" : ""
- })
- get top() {
- return this._top;
- }
- set top(v) {
- if (this._top == v) {
- return;
- }
- this._top = v;
- this._isDirty = true;
- }
- @property
- _bottom = 0;
- @property({
- visible: function (this: AdapterSafeArea) {
- return this.isAlignBottom;
- }, tooltip: EDITOR ? "本节点顶边和父节点底边的距离,可填写负值,只有在 isAlignBottom 开启时才有作用" : ""
- })
- get bottom() {
- return this._bottom;
- }
- set bottom(v) {
- if (this._bottom == v) {
- return;
- }
- this._bottom = v;
- this._isDirty = true;
- }
- @property
- _left = 0;
- @property({
- visible: function (this: AdapterSafeArea) {
- return this.isAlignLeft;
- }, tooltip: EDITOR ? "本节点顶边和父节点左边的距离,可填写负值,只有在 isAlignLeft 开启时才有作用" : ""
- })
- get left() {
- return this._left;
- }
- set left(v) {
- if (this._left == v) {
- return;
- }
- this._left = v;
- this._isDirty = true;
- }
- @property
- _right = 0;
- @property({
- visible: function (this: AdapterSafeArea) {
- return this.isAlignRight;
- }, tooltip: EDITOR ? "本节点顶边和父节点右边的距离,可填写负值,只有在 isAlignRight 开启时才有作用" : ""
- })
- get right() {
- return this._right;
- }
- set right(v) {
- if (this._right == v) {
- return;
- }
- this._right = v;
- this._isDirty = true;
- }
- protected _isDirty = false;
- protected get widget() {
- let comp = this.getComponent(Widget);
- if (comp) {
- return comp;
- }
- return this.addComponent(Widget);
- }
- resetInEditor() {
- this.doLayout(true);
- }
- protected doLayout(isForce = false) {
- if (this._isDirty || isForce) {
- let widget = this.widget!;
- if (EDITOR) {
- widget.left = this.left;
- widget.right = this.right;
- widget.top = this.top;
- widget.bottom = this.bottom;
- return;
- }
- if (!this.isFullScreenAdaption) {
- return;
- }
- if (!widget || !widget.enabled) {
- return;
- }
- // 屏幕向上时,加上安全区域高度
- if (widget.isAlignTop && this.isAlignTop) {
- widget.isAbsoluteTop = true;
- if (this.direction == Adapter.direction.Portrait) {
- widget.top = this.top + Adapter.safeArea.outside.height;
- } else {
- widget.top = this.top;
- }
- }
- // 屏幕向下时,加上安全区域高度
- if (widget.isAlignBottom && this.isAlignBottom) {
- widget.isAbsoluteBottom = true;
- if (this.direction == Adapter.direction.UpsideDown) {
- widget.bottom = this.bottom + Adapter.safeArea.outside.height;
- } else {
- widget.bottom = this.bottom;
- }
- }
- // 屏幕向左时,加上安全区域宽度
- if (widget.isAlignLeft && this.isAlignLeft) {
- widget.isAbsoluteLeft = true;
- if (this.direction == Adapter.direction.LandscapeLeft) {
- widget.left = this.left + Adapter.safeArea.outside.width;
- } else {
- widget.left = this.left;
- }
- }
- // 屏幕向右时,加上安全区域宽度
- if (widget.isAlignRight && this.isAlignRight) {
- widget.isAbsoluteRight = true;
- if (this.direction == Adapter.direction.LandscapeRight) {
- widget.right = this.right + Adapter.safeArea.outside.width;
- } else {
- widget.right = this.right;
- }
- }
- widget.updateAlignment();
- this._isDirty = false;
- this.doOnAdapterComplete();
- }
- }
- protected onChangeSize() {
- this.doLayout(true);
- }
- protected update(dt: number) {
- super.update && super.update(dt);
- this.doLayout();
- }
- }
|