photoshop activeDocument - actionscript-3

I am writing a Photoshop plug in in ActionScript 3.
I am having a very confusing and frustrating issue with app.activeDocument. My code works perfectly with Photoshop for Windows but on a Mac I get the "General Photoshop errooccurreded. This Functionality may not be available in this version of Photoshop." error.
To try and get to the root of the issue, I wrote a class just to get the document reference and called it from a test panel. The class call worked perfectly. I then included the same class in my main panel project and it breaks.
This is my class: -
package DocRefGetter
{
import com.adobe.csawlib.photoshop.Photoshop;
import com.adobe.photoshop.*;
public class DocRefPhotoshop
{
public static function getDocRef():Document
{
var app:Application = Photoshop.app;
var thisDoc:Document = app.activeDocument;
//var thisDoc:Document = app.documents.index(0); //Tried this method too
return thisDoc;
}
}
}
For the purpose of posting here, I have simplified things a little, i.e. I have removed things like the "try, catch" statements but essentially this is the code that does not work in the context of my panel. I also tried the equivalent call to JSX code with exactly the same result, worked perfectly for Windows, worked in a test panel on Mac, would not work in my main project on Mac.
As I said, inside a test, this works perfectly. Here is the test mxml code: -
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" historyManagementEnabled="false">
<mx:Script>
<![CDATA[
import DocRefGetter.DocRefPhotoshop;
import com.adobe.photoshop.Document;
[Bindable]
private var hostName:String = HostObject.mainExtension;
protected function button1_clickHandler(event:MouseEvent):void
{
var thisDocRef:Document = DocRefPhotoshop.getDocRef();
testLabel.text = String(thisDocRef);
}
]]>
</mx:Script>
<mx:VBox height="100%" width="100%" verticalAlign="middle" horizontalAlign="center">
<mx:Button label="Run PS code" click="button1_clickHandler(event)" />
<mx:Label id="testLabel" width="182" text="Label"/>
</mx:VBox>
</mx:Application>
I can't post the main application that it isn't working in as it is extremely large and complicated so what I am asking is has anyone come across a situation before where somehow something is conflicting with this type of document reference? I have been trying to resolve this for over a week now. I have tried many different solutions but nothing has worked. Mac Photoshop just simply doesn't want to see the open document.
Any suggestions are welcome but I am hoping most that someone has come across this exact situation before and has a precise solution.
Many thanks for taking the trouble to take a look at this.

so what I am asking is has anyone come across a situation before where somehow something is conflicting with this type of document reference?
Use one of the following checks:
Is docref null?
Is the document loaded asynchronously?
Is the document large enough to warrant a timeout?
References
Scripting Photoshop: Working with the document model
Adobe Photoshop CS5 Scripting Guide (pdf)
JavaScript development toolkit | Download Adobe ExtendScript Toolkit CC

Related

How to use an MXML component in my as3 code?

I have made a lot of research on this topic but I could not find any helping answer to my issue. I currently have a 100% as3 application. I would like to add a spark component to my stage eg a datagrid (because it is way more simple and clean to create it with mxml).
FileName : MXMLPractice.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:DataGrid x="0" y="0" width="50" height="50"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="dataField1" headerText="ColumnName1"></s:GridColumn>
<s:GridColumn dataField="dataField2" headerText="ColumnName2"></s:GridColumn>
<s:GridColumn dataField="dataField3" headerText="ColumnName3"></s:GridColumn>
</s:ArrayList>
</s:columns>
</s:DataGrid>
How can I add this component to the stage in my as3 code?
Given my difficulties to find a matching answer, I guess I might be trying to do something not recommended. If that is the case, could you please advise me what to do instead?
My tests so far (compiling but not displaying anything) :
package
{
import flash.display.Sprite;
import mx.events.FlexEvent;
public class Main extends Sprite
{
private var practice:MXMLPractice;
public function Main()
{
practice = new MXMLPractice();
stage.addChild(practice);
}
}
}
In pure AS3 project, you should use AS3 components, that also extend UIComponent as flex components, but designed for pure as3 project. For this task, you will need fl.controls package. You can copy/past ui classes from the installation directory of Flash Professional:
c:\Program Files\Adobe\Adobe Flash CC\Common\Configuration\Component Source\ActionScript 3.0\User Interface\
Next step will be export view representation of ui components to the library in Flash IDE from components window CTRL+F7
It's really hard task.
If you want to use some simple class from Flex SDK like ObjectUtil just copy it to your classes. It will work fine because doesn't have imports.
But visual components are linked with many other classes. For components like grid you have to copy dozens of classes. Each of them also have dependencies and so on.
Probably it's better to modify Flash component or find open source solution.

When creating custom layouts in Flex, why do you "have to" override updateDisplayList() and measure()?

When creating custom layouts in Flex, you generally override LayoutBase, in which case the documentation and tutorials on the Internet say you "have to" override the functions updateDisplayList() and measure(). . .Huh?
I don't think there is a construct in AS3 to syntactically require a function to be overridden, and there sure isn't one here. There's not even as special logic to raise unhandled Errors or anything. This works perfectly fine:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns="*" backgroundColor="#000000" showStatusBar="false" click="createImage()">
<fx:Script>
<![CDATA[
import spark.components.Image;
[Embed(source="AL.png")]
private static const IMAGE:Class;
private var iX:int = 0;
private var iY:int = 0;
private function createImage():void
{
var img:Image = new Image();
img.source = IMAGE;
img.width = 100;
img.height = 100;
img.x = iX
img.y = iY;
iX += 100;
iY += 100;
grp.addElement(img);
}
]]>
</fx:Script>
<s:Group id="grp" width="400" height="400">
<s:layout>
<GridLayout/>
</s:layout>
</s:Group>
</s:WindowedApplication>
And in my GridLayout.as class:
package
{
import spark.layouts.supportClasses.LayoutBase;
public class GridLayout extends LayoutBase
{
}
}
Each time I click on the application, a new image is spawned at (x, y) * n, where n is the number of images previously spawned. It works perfectly fine. I even added code so that right-clicking would take an already existing image and move it around on the screen, and that worked fine as well.
So I guess my question is. . .Why in the world are they saying this is absolutely required? What do they mean? I can understand the documentation and stuff saying that those two functions are where you want to concentrate your customizations at or something like that, but in programming, saying that a function override is required is some pretty strong language; if stuff holds up just fine without you overriding those functions, why would both documentation and independent tutorials be saying this? Thanks!
Why in the world are they saying this is absolutely required?
Since I don't know what documentation you're reading; it is tough to say. The documentation could be wrong; or you could be taking something out of context. It is not required that you write any sort of code in an updateDisplayList() or measure() method, but...
What do they mean?
In the context of creating Flex components; it makes sense to make use of the Flex Component LifeCycle methods, for either MX components or Spark Components. The lifecycle methods (createChildren(), commitProperties(), updateDisplayList(), and measure() are executed by the Flex Framework and make use of an invalidation cycle built right into the framework.
The framework methods help you put "similar" code in the same place so you don't have it all over the place.
The Spark Framework changed things a bit by providing the option of separating layout and sizing code (AKA updateDisplayList() and measure() out of the main class and into a specific layout class.
saying that a function overload is required is some pretty strong
language
I'd be surprised if you've read any docs that say that overloading is required. Overloading is the act of creating multiple functions with the same name, but different arguments. This is not supported in ActionScript. Overriding is the act of extending a function in a child component in order to change or extend functionality of that function. They are different concepts; and I'm unclear if that was a typo on your part or if you are confused about some tenants of object oriented programming.
Does this help? [Unfortunately, I don't have the time right now to try to re-work your sample to make proper use of Flex Framework conventions.
Why in the world are they saying this is absolutely required?
I understand your concern, these overriding functions are required for the components to works optimally. These components don't require to follow these component lifecycle principles if your applications is small, the component does not change frequently and no body else touches your class.
But, If your app needs to change these components frequently then you might have enforce these lifecycle principles.
For example: you want to Prepare Coke, steps(I'd say life cycle) would be take water > mix sugar > add colors > mix soda > bottle it
Now you get orders to change the color of the Coke that you just prepared, the life cycle is already completed, if you need to change anything at this point, you need to put a lot of effort even to change the color of it. If you had followed the life cycled, it makes life easier for the app at run time. No performance issues.

Embedding the application background image in Flex return 404 not found error in browser

I'm using Flash Builder 3 to create an application. I need to set an background image for the application.I was trying to embedded background image for my Flex application, and this syntax works properly:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="init()" width="468" height="400"
fontFamily="Verdana" fontSize="10" fontWeight="bold"
themeColor="#FFFFFF" cornerRadius="10" backgroundColor="#FFFFFF" backgroundImage="#Embed(source='../Assets/BG-468x350.gif')" borderColor="#111112" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#CDEAD0, #CDEAD0]">
Above embedded image work properly, but In mozila(or any other browser) fir-bug, I had noticed that background flash image's http request was getting a 404 Not Found error, while trying to retrieve an image at
http://arvind.abcd.com/loan/loan-advice-india/#Embed(source=%27../Assets/BG-468x350.gif%27)
I couldn’t figure out why this was happening, So please suggest me possible solution for that. Thanks in advance for giving your valuable time here.
I don't know I am right or wrong as I am not a regular flex developer as i got task occasionally assigned to me. My Mean is that I don't know what the reason behind that error, why http request of background Image getting 404 not found error, but i got a alternate way to embedded a background image which not received http request, and hence not return 404 not found error.
The alternate way which i use is as:
firstly i declare a variable BackgroundImage as:
[Bindable]
[Embed(source="../Assets/BG-468x350.gif")]
protected var BackgroundImage:Class;
Then assign declered BackgroundImage variable to predefine backgroundImage variable using preinitialize method init(), which declered on <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="init()" width="468" height="350">
public function init():void
{
Application.application.setStyle("backgroundImage", BackgroundImage);
}
I mention this solution is here for other user who may get similar error, but if any body know better solution the please update here. Thanks for all.

Localizing component labels at run-time

I have a few different tabs in a navigator defined like this : (removed client specific domain)
<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:container="com.*****.shop.admin.container.*"
width="100%" height="100%"
implements="com.*****.common.container.IScreen"
xmlns:services="com.****.shop.admin.services.*"
label="Service Types">
I have resource bundles for different locales, en_US looks like this :
ServicesScreen.label=Service Types
When I try to do this, it doesn't work :
...
...
label="{resourceManager.getString('resources','ServicesScreen.label')}"
Instead of getting my resource bundle entry, I get something weird looking in my GUI like :
Shop0.ShopSkin9._ShopSkin_Group1.contentScroller.ScrollerSkin13.contentGroup.vsMain.AdminView154.SkinnableContainerSkin159.contentGroup.subNavItems.opCodeScreen
My resource bundles work in other cases, for instance labels next to form input fields, etc... The code compiles, however, and no errors are actually thrown (compile or run-time). I tried assigning the value to a variable and using that variable in the label field, however that caused a compile error.
I tried calling a setter method on creation complete of the component, but that didn't resolve the issue either.
How do I localize my tab labels, and can I do so dynamically at run-time?
Thanks for your time!
I guess I'll self-answer this one, although credit goes to Sunil D. I don't know why it didn't work earlier while I was testing, I must've missed something the first time, but here goes. first I added:
creationComplete="init(event)">
And then in that method body I did :
protected function init(event:FlexEvent):void
{
this.label = resourceManager.getString('resources','opCodeScreen.title');
}
And it works like a charm. honestly I'm pretty sure I did this exact same test this morning, but I guess not. Sunil If you want to make your comment an answer I'll go ahead and accept it.
EDIT: change the text at run-time, add currentStateChange that calls aforementionned method
Cheers!

Flash Builder 4.6 Interface Programming

I'm having a very difficult time finding many resources available for Flash Builder 4.6 geared towards desktop application programming.
I'm trying to accomplish a simple (or at least I think simple) task. I have an application, and in the application is a button. When the user clicks the button, I want a new window to load, but not in the current window as a child; as a completely separate window.
I've managed to accomplish this once, but the code I was using gave a warning (from Adobe Flash Builder 4.6) that told me that it is best practice to use an "interface" as the new window is now a child of the window that opened it. (I have since lost this code as I've been trying other things, like ModuleLoader).
Basically my question is, can someone please provide an example of how to properly implement an interface in the way that 2 separate windowedapplications can be loaded and they can communicate with each other through events?
And as a bonus, if anyone can point me in the direction of a good resource, I'd appreciate that also (book or site). :) I have a Flex 4 book that I've read, and it has helped a lot with my understanding of the basic things, but is not geared towards AIR desktop programming (and had no mentions of interface).
Thank you for your time.
How I solved this problem. This article helped: Dual Monitor Support in Flex Application.
After you have created your project in Adobe Flash Builder 4.6, go to File > New > MXML Component. Type in the details as you see fit best for your application, but under "Based on" field, put "spark.components.Window". Click "Finish" when you are done with all the details.
In your main application, use the following code to pull up the new Window Component you just created into a separate Window. For the purpose of this code, I will assume that your new window is located under "assets.components" and is called CompNewWindow. Replace these details with your own.
<s:Button x="0" y="0" label="Button" click="_loadNewWindow(event)" />
<fx:Script>
<![CDATA[
import assets.components.CompNewWindow;
private var myNewWindow:CompNewWindow;
private function _loadNewWindow(event:MouseEvent):void
{
if (!myNewWindow) {
myNewWindow = new CompNewWindow();
myNewWindow.addEventListener(Event.CLOSE, _onNewWindowClose);
myNewWindow.open();
}
}
private function _onNewWindowClose(event:Event):void
{
myNewWindow.removeEventListener(Event.CLOSE, _onNewWindowClose);
myNewWindow = null;
}
]]>
</fx:Script>