Рисование наложения в пользовательском компоненте flex - PullRequest
2 голосов
/ 29 января 2010

Как создать пользовательский компонент MXML во flex, который основан на существующем компоненте, но в определенных ситуациях наложит поверх этого существующего компонента.

В идеале, новый компонент должен основываться (выходить из) существующего компонента, чтобы вхождения существующего компонента можно было просто заменить новым.

Я попытался переопределить updateDisplayList () в новом компоненте и нарисовать наложение, используя this.graphics. Это привело к тому, что наложение было нарисовано под дочерними элементами существующего компонента. Я также попытался сделать рисунок после получения события рендеринга, которое привело к аналогичным результатам.

Когда внешнее условие, которое должно вызвать отображение наложения, изменяется, я вызываю invalidateDisplayList () в моем новом компоненте. Это работает, чтобы вызвать рисование для обоих случаев, описанных выше. Похоже, остающаяся проблема состоит в том, чтобы выяснить, как рисовать поверх всех других компонентов после их добавления.

Следующий пример должен иллюстрировать то, что я пытался сделать; когда overlayEnabled был установлен и был вызван метод invalidateDisplayList () компонента, красный прямоугольник окрашивался в фоновом режиме ....

// NewComponent.mxml
<ExistingComponent ...>
    <mx:Script>
    ...

        public var overlayEnabled:Boolean;

        override protected updateDisplayList(...) {
            super.updateDisplayList(...)
            if (overlayEnabled) {
                var g:Graphics = this.graphics;     
                g.beginFill(0xFF0000, 0.5);
                g.drawRect(0, 0, width, height);
                g.endFill();
            }
        }
    ...
    </mx:Script>
</ExistingComponent>

Кроме того, не стесняйтесь предлагать различные подходы.

1 Ответ

4 голосов
/ 29 января 2010

Вам нужно будет добавить DisplayObject для наложения и убедиться, когда вы звоните updateDisplayList, что это место поверх другого.

        public var overlayEnabled:Boolean;

        public overlayHolder:(whatever display object you want to use)

        override protected updateDisplayList(...) {
            super.updateDisplayList(...)
            if (overlayEnabled) {
                if (overlayHolder.parent != this){
                 addChild(overlayHolder);
                } else {
                  if (numChildren > 0)
                     setChildIndex(overlayHolder, numChildren-1);
                }
                var g:Graphics = overlayHolder.graphics;     
                g.beginFill(0xFF0000, 0.5);
                g.drawRect(0, 0, width, height);
                g.endFill();
            } else if (overlayHolder.parent == this) {
              removeChild(overlayHolder);
            }
        }

Edit: Одним из свойств, которое можно использовать для добавления наложения в список отображения, может быть rawchildren:

package {
    import flash.display.Graphics;
    import flash.display.Sprite;

    import mx.containers.VBox;

    public class MyVBox extends VBox {
        public var overlayEnabled : Boolean = true;
        public var overlay : Sprite = new Sprite();

        public function MyVBox() {
            super();
        }

        protected override function updateDisplayList(unscaledWidth : Number, unscaledHeight : Number) : void {
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            if (overlayEnabled) {
                if (overlay.parent != this) {
                    rawChildren.addChild(overlay);
                } else {
                    if (rawChildren.numChildren > 0)
                        rawChildren.setChildIndex(overlay, rawChildren.numChildren - 1);
                }
                var g : Graphics = overlay.graphics;
                g.beginFill(0xFF0000, 0.5);
                g.drawRect(0, 0, width, height);
                g.endFill();
            } else if (overlay.parent == this) {
                rawChildren.removeChild(overlay);
            }
        }
    }
}
...