10 Replies Latest reply on Feb 28, 2010 10:35 AM by shrelp

    use the OSMF layout API to layout my controlers

    boliz Level 1

       

       

      Hi,

      i would like to use the OSMF layout mechanism to layout all my video controls, i am using the OSMF as my media player and now just wanted to layout the controls ( scrubber, volume bar, buttons,...).

       

      i have created all the controls needs and I want to be able to layout them wisely and extendable with OSMF layout API, let's say i have a Sprite, my question is can i do something like that and what I need to extend to make it happen if possible:

       

      var relative:RelativeLayoutFacet = new RelativeLayoutFacet();
      relative.width = 100;
      relative.height = 20;

      mysprite.metadata.addFacet( relative );

       

      because currently I see that only media elements support the Layout API...

      please advise,

      10x

      Boaz

        • 1. Re: use the OSMF layout API to layout my controlers
          Brian Betz

          I have the same question.

           

          Is there a reason the layout API was limited to only media elements?

           

          Brian

          • 2. Re: use the OSMF layout API to layout my controlers
            boliz Level 1

            After a bit of investigation it seems that it is intend to work with Media only and be a limited layout API,

            The most “less ugly” solution I have found is to inherent from RegionSprite and the layout will apply on you,

            But then I bump into the ugly fact that the Layout API is not mature enough and I can’t imitate VBox or HBox,

            Because the parent to manage the children, it the children that layout according to the parent.

            So I have used Astra to layout my controls at last…

            • 3. Re: use the OSMF layout API to layout my controlers
              Edwin van Rijkom Level 2

              Hi Boliz and Brian,

               

              The OSMF Layout API is based on three core interfaces:

               

              • ILayoutTarget, to be implemented by objects that want to participate in a layout, next:
              • ILayoutContext, extends ILayoutTarget, implemented by objects that can contain ILayoutTarget children, and last:
              • ILayoutRenderer, to be implemented by objects that can arrange a set of ILayoutTargets onto an ILayoutContext.

               

              To have your controls, or any other visual within Flash, participate in an OSMF layout, the controls will have to support ILayoutTarget. The easiest way to do this, is probably by creating a wrapper for DisplayObjects, like so:

               

              package org.osmf.samples.layout
              {
                  import flash.display.DisplayObject;
                  import flash.events.EventDispatcher;
                  
                  import org.osmf.events.DimensionChangeEvent;
                  import org.osmf.layout.ILayoutTarget;
                  import org.osmf.metadata.Metadata;
              
                  public class DisplayObjectLayoutTarget extends EventDispatcher implements ILayoutTarget
                  {
                      // ILayoutTarget
                      //
                      
                      public function DisplayObjectLayoutTarget(displayObject:DisplayObject, metadata:Metadata = null)
                      {
                          this.displayObject = displayObject;
                          _metadata = metadata || new Metadata();
                          
                          super(displayObject);
                      }
                      
                      public function get metadata():Metadata
                      {
                          return _metadata;
                      }
                      
                      public function get view():DisplayObject
                      {
                          return displayObject;
                      }
                      
                      public function get intrinsicWidth():Number
                      {
                          return _intrinsicWidth;
                      }
                      
                      public function get intrinsicHeight():Number
                      {
                          return _intrinsicHeight;
                      }
                      
                      // Public API
                      //
                      
                      public function setDimensions(width:Number, height:Number):void
                      {
                          if (_intrinsicWidth != width || _intrinsicHeight != height)
                          {
                              var event:DimensionChangeEvent
                                  = new DimensionChangeEvent
                                      ( _intrinsicWidth, _intrinsicHeight
                                      , width, height
                                      );
                                      
                              _intrinsicWidth = width;
                              _intrinsicHeight = height;
                              
                              dispatchEvent(event);
                          }
                      }
                      
                      private var displayObject:DisplayObject;
                      private var _metadata:Metadata;
                      private var _intrinsicWidth:Number;
                      private var _intrinsicHeight:Number;
                  }
              }

               

              Using the wrapper class, you can add objects to OSMF's DefaultLayoutRenderer (or any renderer, for that matter), like so:

               

              ...
              
              var layoutTarget:DisplayObjectLayoutTarget = new DisplayObjectLayoutTarget(constructRect());
              layoutTarget.setDimensions(100, 100);
              
              LayoutUtils.setRelativeLayout(layoutTarget.metadata, 25, 25, 10, 10);
              
              layoutRenderer.addTarget(layoutTarget);
              
              
              ...
              
              private function constructRect():Sprite
              {
                   var sprite:Sprite = new Sprite();
                   sprite.graphics.beginFill(0xff,1);
                   sprite.graphics.drawRect(0, 0, 100, 100);
                   sprite.graphics.endFill();
                   
                   return sprite;
              }
              
              

               

              Full sample code is attached to this post. Note that it is build against the framework sources as they're currently in the SVN trunk. Hope this explains a bit how the system can work for objects other than MediaElements. (Perhaps interesting to point out: MediaElements don't implement ILayoutTarget directly either: they too get wrapped before placed on a layout, using MediaElementLayoutTarget, so there's really not much MediaElement specific about the layout system).

               

              Another question I saw was on Boxing. Compositions create a DefaultLayoutRenderer for their children by default. If a composite has a metadata facet of type LayoutRendererFacet set though, then the renderer type from its rendererType property will be instantiated instead. This allows for plugging in custom renderers. We don't have any other renderers yet, but I believe we have a "Layout Phase II" feature on our backlog that mentions VBox and HBox renderers.

               

              Hope it's helpful!

               

              Cheers,

              Edwin

              • 4. Re: use the OSMF layout API to layout my controlers
                Brian Betz Level 1

                Thanks Edwin!

                 

                I will look at the structure you suggest.

                 

                Brian

                • 5. Re: use the OSMF layout API to layout my controlers
                  Mr Binitie Level 1

                  This is really cool I will most probably need this.

                  Thanks

                  • 6. Re: use the OSMF layout API to layout my controlers
                    niduma Level 1

                    thanks for your explonation. i don't know the osmf very good but i tried to implement your code. it all worked well but this part i didn't understand:  layoutRenderer.addTarget(layoutTarget);

                     

                    how and where do i access the layoutrenderer?! do i have to create a new defaultrenderer?

                     

                    besides that i would like to know if i can assign a different layout/control to a different mediaelement? for example: a linkbutton for an advertising video and a playpause button for the main video. it would be great if you could make real life example with some video controls.

                    • 7. Re: use the OSMF layout API to layout my controlers
                      Edwin van Rijkom Level 2

                      Re the first part of your question: yes, layoutRender could just be a DefaultLayoutRenderer instance.

                       

                      In the sample code from the archive, it referes to the renderer of the LayoutRendererStandAloneSample class's internal layout renderer, which is a property of the LayoutContextSprite that it derives from. It gets instantiated at line 37 of LayoutRendererStandAloneSample.as, like so:

                       

                      ...
                      
                      /**
                       * Sets up our container: we derive from LayoutContextSprite, so we
                       * need to setup our layoutRenderer manually:
                       */          
                      private function setupContainer():void
                      {
                           // Setup a layout-renderer:
                           
                           layoutRenderer = new DefaultLayoutRenderer();
                           LayoutUtils.setAbsoluteLayout(metadata, 500, 500);
                      }
                      
                      ...
                      

                       

                      Re the second part: to create UI elements that appear as part of the content in a player, there are multiple approaches:

                       

                      1) Create UI seperately, and monitor the media that is being played back for change, and update the UI accordingly.

                      2) Create custom media elements that hold the UI, and combine them with the media using ParallelElement.

                       

                      I agree it'd be great to have some more elaborate samples on this, so I've added it to our feature back-log.

                       

                      Cheers,

                      Edwin

                      • 8. Re: use the OSMF layout API to layout my controlers
                        shrelp

                        Looks like DimensionChangeEvent was removed from the trunk.  Anyone know what event DisplayObjectLayoutTarget should dispatch now?

                         

                        public function setDimensions(width:Number, height:Number):void

                        {

                        if (_intrinsicWidth != width || _intrinsicHeight != height)

                        {

                        var event:DimensionChangeEvent

                        = new DimensionChangeEvent

                        ( _intrinsicWidth, _intrinsicHeight

                        , width, height

                        );

                         

                        _intrinsicWidth = width;

                        _intrinsicHeight = height;

                         

                        dispatchEvent(event);

                        }

                        }

                        • 9. Re: use the OSMF layout API to layout my controlers
                          boliz Level 1

                          addEventListener( DisplayObjectEvent.MEDIA_SIZE_CHANGE , onMediaSizeChange );

                           

                          private function  onMediaSizeChange( event : DisplayObjectEvent ) :void

                          {

                          }

                          • 10. Re: use the OSMF layout API to layout my controlers
                            shrelp Level 1

                            Original set dimensions method.

                            public function setDimensions(width:Number, height:Number):void
                                    {
                                        if (_intrinsicWidth != width || _intrinsicHeight != height)
                                        {
                                            var event:DimensionChangeEvent
                                                = new DimensionChangeEvent
                                                    ( _intrinsicWidth, _intrinsicHeight
                                                    , width, height
                                                    );
                                                    
                                            _intrinsicWidth = width;
                                            _intrinsicHeight = height;
                                            
                                            dispatchEvent(event);
                                        }
                                    }

                             

                             

                            Updated set dimensions method that works with trunk.

                             

                             

                            public function setDimensions(width:Number, height:Number):void
                            {
                                 if (_intrinsicWidth != width || _intrinsicHeight != height)
                                 {
                                       var event:DisplayObjectEvent     = new DisplayObjectEvent(DisplayObjectEvent.MEDIA_SIZE_CHANGE, 
                                                     false,
                                                     false,
                                                     displayObject,
                                                     displayObject,
                                                     _intrinsicWidth, 
                                                     _intrinsicHeight, 
                                                     width, height);
                                                _intrinsicWidth = width;
                                                _intrinsicHeight = height;
                                                dispatchEvent(event);
                                 }
                            }