I have various components that are skinned through a programmatic skin. The skin class references a singleton class that holds various colors to be applied to different aspects of the component. The singleton class has default colors set to variations of black/grey etc. I'm loading in custom colors from an XML file that are then loaded into the singleton. I'm applying the custom skin through a css stylesheet that is included in the main Application mxml.
The problem is that when the swf initially loads, the components that are drawn on screen are black and don't reflect the changes in color loaded from the XML file. I have some dropdown windows that show on button clicks and those dropdowns do reflect the correct colors from the XML file. Therefore, the system is working correctly, but the initial drawing of components obviously happens before the XML is loaded and applied to the singleton.
My question is, is there a way to apply a skin to an element programmatically by calling the constructor?
I have this in my css file:
.PanControlsBackground {
borderSkin:ClassReference('skins.buttons.PanControlsBackground');
}
and I'm applying the class with this:
_app.panControls.styleName = "PanControlsBackground";
Is there a way to call:
_app.panControls.styleName = new PanControlsBackground();
or something to that effect? This way, I can remove the loading of the skins in the css file and control when they are instantiated to ensure that the correct colors are applied before displaying the various components.
You could use the styleManager to manipulate the style at run time. For example,
.PanControlsBackground {
/* leave it blank */
}
And then in some script block:
styleManager.getStyleDeclaration(".PanControlsBackground").setStyle("borderSkin", skins.buttons.PanControlsBackground);
So, that's one way of changing the skin in a programmatic way.
However, I don't know much about how the garbage collection is handled on the old skins. For instance, how would the GC differ on this method of switching the skin versus just having a bunch of different CSS classes for each of your skins and switching between them? I can't really answer that.
I think one could at least say that the above method would ensure that the default (or other minimal skin you might create) is used first, and one could control when in the initialization process the other skin get's instantiated.
Related
I want to create a re-usable Flash MovieClip (component maybe?) that can be dragged and dropped from the library onto the Flash IDE stage (for an example, a "stop all movieclips timer component").
I've created some attractive vector icon graphics for visual reference, so that when it's dragged onto the stage, the developer can visually see the component on the stage, similar to what Google does with it's DoubleClick components. It's not important for these icon graphics to be seen at runtime however, and I'd like their visual portions to not be compiled at runtime to save on filesize.
I'm often asked to create visually rich Flash units in extremely small file sizes. So basically I want my movieclip icon components to not add to filesize (except for the code portion), not compile and render visually but still have the code within them run.
How can I achieve this? Would creating them as components do anything for my issue? Is this even do-able?
Components are definitely the best way to achieve visually represented imported code, however it would be much easier, more compatible and more reliable to just use an imported code library...
Make a seperate .as file, put it in com/mycompany/animation in your swf folder (or use a global classpath), and add this code:
package com.mycompany.animation {
class MyTimerUtils {
public static function stopAllClipsAfterTime(ms){
setInterval(MyTimerUtils.stopAllClips, ms);
}
public static function stopAllClips(){
//etc
}
}
}
Then when you want to use it in a project, just put this code on frame 1 of your main timeline:
import code.mycompany.animation.MyTimerUtils;
MyTimerUtils.stopAllClipsAfterTime(3000); // 3 seconds
What could be easier? If another developer wants to know if a piece of code is implemented they need only look at the first few lines of code.
So I've been following this tutorial on AS3 and Flash. Its been going well until, note I have tried to contact the writer of the tutorial and had no reply. Here's what it tells me to do;
Right-click PlayScreen in the library, select Properties, and check Export for ActionScript. This time, instead of accepting the default value, enter the name of your document class. Click OK.
So it pops up an error, first we’ll have to make a new document class, since no two different objects can share the same class. Cancel the Properties box.
Hit File > New and select ActionScript File. Enter the (by now familiar) code.
Save this in the Classes directory as DocumentClass.as. (There’ll be no confusing the purpose of this file!) Now, back in your FLA, change the document class to DocumentClass.
Check everything’s fine by clicking that pencil icon — if it’s all OK, that should bring up the AS file that you just created.
// So this bits all fine, its the next that i'm stuck with:
Now you can set the PlayScreen‘s class to AvoiderGame. So do so!
// So I go ahead into the properties and change the name but then it pops up with the same error as before: 'Please enter a unique class name that is not associated with other library symbols'
What does this mean!? How do I resolve this!?
Full tutorial here:Flash Tutorial
Its hard to tell what you are trying to accomplish without knowing what all the parts you are referring to actually do, which are objects in the library and which are classes, but maybe this can help:
First of all, document class in AS3 typically refers to the project's main set of code that initializes the app. This class can be called anything but is often called Main, and is entered in the property panel that is displayed when you click the projects main stage in the field called class.
Now, when linking a class to an object in the library, its a little different. In the library object's property panel, tick the box for Export for Actionscript, and put a unique name in the top box. This is what you reference in your code to call it, like new somethingOrOther() or using the pic below as an exaample, new Ball(). The second box is the base class, pathed to where it lives in your code base. This is the class you will write that actually controls the object you've linked the class to. Giving a linked object a base class and a unique identifier allows you to use the same base class for multiple linked objects.
Note that when you do this approach, Flash will warn you that there is no class associated with Ball and one will be created for you. Don't worry, this is normal behavior. If you set this up properly, your object will still be controlled by its base class.
I'm working on enterprise level AIR application, i need to change my application UI for multiple clients,it has a complex UI with more that 250 MXML skin files for all display objects such as buttons, combo box, containers, etc., Is it possible to create a generic skin library for managing skins and assets through CSS or i have to create a separate library for each of the clients?
Currently i'm duplicating the skin files for each client and changing the color values (styles) in CSS (which is the default.css for skin library) and Path data in skins.
Is there any easy way to create a skinning themes in flex 4.5 and managing assets(icons, fxg) in library?
Thanks in advance
Create a custom theme
I suppose you already know this, but creating a custom theme is simply a matter of:
creating a custom skin for every component
creating defaults.css file to assign those skins and perhaps provide some additional styling information
making sure that css file is included in the swc
applying the theme with the --theme compiler flag (or through whatever means your IDE provides)
Applying different colour schemes
You can use chromeColor and some other predefined styles to address this issue, but this approach may prove limiting. I solved this by substituting the Spark skin base classes with my own more elaborate versions. There's too much code to paste here, but it comes down to this:
I created an interface like this:
public interface IColorizedSkin {
function colorizeBorder(color:uint, lowLight:uint, highLight:uint):void;
function colorizeBackground(color:uint, lowLight:uint, highLight:uint):void;
function colorizeShadow(color:uint):void;
}
and I implemented this interface in my custom versions of:
SparkSkin
SparkButtonSkin
ColorizedItemRenderer
These three functions are called from an overridden updateDisplayList and use custom CSS style names like chromeBorderColor (which is an array of colours that expresses the base colour, the lowligth colour and the highlight colour of the border of a component).
All skins that need colorizing extend these base classes.
The defaults.css in the theme library comes with a default colour scheme, but you can override it by adding another css file with different colorizing directives to the client application.
Note that since these custom style names were not added as metadata to the components, you will only be able to assign these colours through CSS or through ActionScript, not through MXML attributes.
Colorizing icons
If you have an icon set that uses sufficiently neutral colours (for instance all icons are dark grey, or perhaps a grey gradient), you can colorize these too.
The simplest approach which works for solid colors is something like this:
if (iconDisplay) {
var colorTrans:ColorTransform = new ColorTransform();
colorTrans.color = getStyle("color");
iconDisplay.transform.colorTransform = colorTrans;
}
If you need something more finegrained, you'll have to work with a transform matrix.
Using different icons
I wouldn't bake icons into the skins, because that would reduce flexibility. I tend to include icons in the library swc, so one can access them from there.
If you need different icon sets for different client applications, simply create a swc including only these assets (i.e. no compiled code) for each set. As long as the names and paths inside those swc's are the same, you should be able to substitute one for the other.
A flash component can't be used unless it's added to library. Why this difference as compared to other classes ? Is it only because of the reason that components have "Views" . Or the reason is something else.
When you add a component to the library, this, behind the scenes, generates the code, or rather an instruction for the compiler to import the classes used in the component.
So, for some components, it would be sufficient to only import them in your AS3 code, given the source code of the component or the SWC with the compiled component is made visible to the compiler by putting it on a "classpath", i.e. the compiler has a list of the directories where it will look for the sources - this is the classpath, placing file into any of these directories makes them available at compile time.
For other components there may be further complications. A component may be imported from another FLA file, where in the original file it was comprised of a compiled part (aka component shim), this usually contains the code that manages the component, and the parts of the component in the format native to Flash IDE, in which they are still editable. This would later allow you to skin the component (as in change some of its visible appearance). So, commonly, these parts are the MovieClips, Sprites, Shapes, or, perhaps sounds etc.
In the second case you usually don't have sources or SWC available to the compiler, so you cannot import it by any other means but placing it in the library.
I have two ActionScript 3 projects, game(.swf) and minigame(.swf). At runtime the main game loads the minigame via Loader. I also have a shared library (SWC) of event classes, included by both, which minigame will need to dispatch and game will need to listen to.
First: Is this possible this way?
Second: What will happen if I compile the minigame, then change the event classes so they're incompatible, then compile the main game. Will Flash crash when trying to load the minigame SWF? (I hope so)
Third: And what will happen if I change the event classes, but in a way that preserves interface-level compatibility?
If you have classes named the same but not sharing the same functionality just use a different class path for each (i.e com.game.* com.minigame.*), this will avoid all conflicts.
Basically if a class named the same in several SWFs only the one loaded first will be used.
On the other hand if you really want to share the same classes between both of the SWFs, make sure you only include them in the main SWF (you can choose include/exclude in the publish settings of Flash IDE or in the compiler settings of Flex SDK). This will make the whole loading process a bit lighter and you will avoid weird conflict related bugs.