Hi Andy,

one more question, do you load in a clip with all the assets and actually
construct an interface within that library, OR do you use runtime shared
libraries to accomplish this, if and not, why not;).
We are running into problems (as described in the previous post) which
forces us to move to a single library as well, and I'm still pondering which
option to take.

greetz
JC


On 5/31/07, Andy Herrman <[EMAIL PROTECTED]> wrote:

The application I'm working on gets all of its UI resources from a
separate SWF.  This will allow us to internationalize/brand the UI by
simply providing different resource SWFs.

Because the UI resources are all in the child movie I have to
construct the UI within the movie clips owned by that movie.  My
testing shows that if the ComboBox (or any other component) is in the
main movie's library I can't instantiate it any of these movie clips,
so I need to have it contained in the resources clip (I prefer this
anyway as it keeps everything in one place).  Unfortunately I've been
running into some weird issues with ComboBox when doing this.

I've found workarounds for all these issues, which I thought others
may find useful.  I'm also interested to know if other people have run
into them and how they solved them.

The first bug I ran into was that the combo box would never open.
Originally I set _lockroot to true on the movie clip that contained
the combo box.  However, in this case the dropdown would always open
down, even if there wasn't enough room in the movie to do so (which
normally would cause it to open up).  I found that doing _lockroot on
the UI resources movie fixed this.

The second bug I ran into was that a focus rectangle would display
around the combo box and the dropdown.  This doesn't display when the
combo box is simply created in the main movie (which I can't do
unfortunately).  Also, the focus rectangle for the dropdown does not
go away when the dropdown is closed, messing up the UI.  The fix I
found for this was to do the following, where cbx is the ComboBox:

   cbx.drawFocus = null;
   cbx.dropdown.drawFocus = null;

The last issue was a fun one.  If there were enough entries in the
combo box to require scrolling, clicking on the arrows in the
scrollbar or dragging the scroll thingy would cause the dropdown to
close (it closed on the release of the mouse).  This only seems to
happen when the combo box is in a child movie.

By digging through the ComboBox code and doing a bunch of tests I
determined that the combo box's onKillFocus() function was being
called after the mouse was released (this never happened when in the
main movie, only when in the child movie).  onKillFocus takes a single
argument, which I think is a reference to the object that was taking
focus.  In this case the argument was always the dropdown itself
(stored in the combo box as __dropdown).

The fix for this is a total hack, but seems to work in Flash 7+ (at
least in windows).  At the very beginning of the code for the movie I
put the following:

   ComboBox.prototype.onKillFocus = function(n) {
     if(n == this.__dropdown) {
       /* Skip */
     } else {
       if(this._showingDropdown && n != null) {
         this.displayDropdown(false);
       }
       super.onKillFocus();
     }
   }

This overrides the ComboBox function to do what it normally does in
all cases except for when the focus is being given to the dropdown.
The only thing I've found that this breaks is changing focus using the
TAB key.  If the combo box is open and you hit the TAB key to change
focus to something else then it won't close.  This was easily fixed by
adding a key listener that closes the combo box when it sees TAB is
pressed.

Has anyone else run into these things?  Any better solutions?  Any
idea why ComboBox is so broken when used in a child movie (Some of it
seems to be related to referencing _root, but not all of it).

For reference, here's the code for my test case.  This goes into one
SWF with an empty library, and it requires a UIResources.swf file that
has the ComboBox in its library:

////////////////////////////////////////////////////////////////
import mx.utils.Delegate;
import mx.controls.ComboBox;
//import net.hiddenresource.util.debug.Debug;

class MainImpl {
public static function main(root:MovieClip) {
   ComboBox.prototype.onKillFocus = function(n) {
     if(n == this.__dropdown) {
       MainImpl.log("Got onKillFocus for dropdown");
     } else {
       if(this._showingDropdown && n != null) {
         this.displayDropdown(false);
       }
       super.onKillFocus();
     }
   }

   if(root == undefined) { root = _root; }
   var test:MainImpl = new MainImpl(root);
}

private var uir:MovieClip;
private var cbx:ComboBox;

public function MainImpl(rootMC:MovieClip) {
   Stage.scaleMode = "noScale";
   Stage.align = "LT";
   uir = rootMC.createEmptyMovieClip('uir', rootMC.getNextHighestDepth());

   var l:Object = new Object();
   l.onLoadInit = Delegate.create(this, doTest);
   l.onLoadError = function(target, ec) { MainImpl.log('Error: ' + ec); };
   var mcl:MovieClipLoader = new MovieClipLoader();
   var b:Boolean = mcl.addListener(l);
   mcl.loadClip("UIResources.swf", uir);
   //doTest();
}

private function doTest():Void {
   log('doTest');
   uir._lockroot = true;
   createUI(uir);
}

private function createUI(root:MovieClip):Void {
   root.createClassObject(ComboBox, "cbxTest", root.getNextHighestDepth
());
   cbx = root["cbxTest"];

   cbx.drawFocus = null;
   cbx.dropdown.drawFocus = null;
   cbx.setSize(250, cbx.height);

   cbx.rowCount = 3;

   cbx.addEventListener("change", {
     change : Delegate.create(this, itemSelected)
   });

   for(var i:Number = 0; i < 10; i++) {
     cbx.addItem("Item " + i, {val:i});
   }

   cbx.move(10, 100);
}

private function itemSelected(eventObj:Object):Void {
   log("selected: " + eventObj.target.selectedItem.data.val);
}

public static function log(msg:String):Void {
   //Debug.trace(msg);
   trace(msg);
}
}
////////////////////////////////////////////////////////////////

Either call 'MainImpl.main(this)' from the first frame, or use MTASC
to build a movie with the 'use main' option.

-Andy
_______________________________________________
[email protected]
To change your subscription options or search the archive:
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Brought to you by Fig Leaf Software
Premier Authorized Adobe Consulting and Training
http://www.figleaf.com
http://training.figleaf.com

_______________________________________________
[email protected]
To change your subscription options or search the archive:
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Brought to you by Fig Leaf Software
Premier Authorized Adobe Consulting and Training
http://www.figleaf.com
http://training.figleaf.com

Reply via email to