Adobe Flex/Actionscript: editable label - actionscript-3

I am working on a project where it would be really nice if we had editbale labels or an area for TextInput that looks like a Label if it isnt hovered with the mouse.
I'm pretty new at Flex, and dont know how to develop a skin. I dont even know if it possible to do this just by skinning.
Anyhow, I found this question from a few months ago but i cant get it working, it just displays a empty white page.
Here the code I used to create a editable Label mentioned in the link above:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:component="com.npacemo.component.*"
xmlns:skins="skins.*">
<fx:Declarations>
<!-- Platzieren Sie nichtvisuelle Elemente (z. B. Dienste, Wertobjekte) hier -->
</fx:Declarations>
<s:BorderContainer>
<component:EditableLabel text="Text 132" skinClass="skins.EditableLabel" />
</s:BorderContainer>
</s:Application>
Any idea why the displayed page is empty? Or a different approach?
Thanks in advance,
markus

In a project we were working on we did editable labels by using a textbox and remove background and borders (it will look just like a label and will be editable). In your case you can do this and then on mouseIn you can show the border and background again (making it look like a text box) and then MouseOut with removing til style again.

I encountered the same problem about this editable label.
I think the root cause was from SkinPart:labelComponent. Inside the skin, the label was like this:
<s:Label id="labelComponent" text="{hostComponent.text}"
alpha.normal="1" alpha.selected="0"
visible.normal="true" visible.selected="false"
verticalCenter="0" width="{this.width+20}" maxDisplayedLines="1"
textDecoration="underline" buttonMode="true"/>
Since the width setting was causing a self-reference loop, label would throw the exception. The solution here is just clear the width setting:
<s:Label id="labelComponent" text="{hostComponent.text}"
alpha.normal="1" alpha.selected="0"
visible.normal="true" visible.selected="false"
verticalCenter="0" maxDisplayedLines="1"
textDecoration="underline" buttonMode="true"/>
And the component can be displayed now.
I found there's a difference between displaying components in Application and View. In Application, some exceptions are caught automatically, making the process of debugging become more difficult.
Hope this would help!

Related

AS3 Scroller, odd interaction with constraint layout?

I have a form that uses constraint layouts (left/right/top/bottom) to position the main form inside a background. When I use the form in a popup TitleWindow, it lays out and sizes the components (and sets the TitleWindow size) as I would expect.
When trying to use the same set of components inside a Scroller, the layout is incorrect - the background gets resized to fit the Scroller, while the interior form is the correct size (but the right/bottom constraints aren't applied).
This simplified program demonstrates the issue. Without the Scroller, the form lays out correctly, and if the WindowedApplication is resized to show the entire form it looks correct.
<?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:mx="library://ns.adobe.com/flex/mx"
width="400" height="400">
<fx:Declarations>
<s:SolidColor id="bgFill" color="#8080c0"/>
<s:SolidColor id="whiteFill" color="#ffffff"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
protected function checkSizes():void
{
trace('Base is ' + base.width + 'x' + base.height);
trace('Background is ' + bg.width + 'x' + bg.height);
trace('Border is ' + border.width + 'x' + border.height);
trace('Form is ' + form.width + 'x' + form.height);
}
]]>
</fx:Script>
<s:Group id="base">
<s:Rect id="bg"
left="0" right="0" top="0" bottom="0"
fill="{bgFill}"/>
<s:Rect id="border"
left="10" right="10" top="10" bottom="10"
fill="{whiteFill}"/>
<s:VGroup id="form" left="20" right="20" top="20" bottom="20">
<s:Button width="600" height="600"
label="Push Me!"
click="checkSizes()"/>
</s:VGroup>
</s:Group>
</s:WindowedApplication>
Clicking the button shows the component sizes as I'd expect:
Base is 640x640
Background is 640x640
Border is 620x620
Form is 600x600
If I add a scroller to fit the parent window, base, bg and border all fit inside the scroller, rather than being sized to fit as borders around form:
<s:Scroller width="100%" height="100%">
<s:Group id="base">
...
Base is 385x361
Background is 385x361
Border is 365x341
Form is 600x600
Oddly enough, if I put an extra group around base, then everyone lays out correctly...
<s:Scroller width="100%" height="100%">
<s:Group id="dummy">
<s:Group id="base">
...
Before I start digging through the Scroller and ScrollerSkin source, anyone know if I'm off my rocker and doing something worng in the first scroller example? I'd rather not create extra layers of components that I don't need.
The scroller restricts its first (and only) child to stay within his bounds, it will move the viewport of that child when you scroll.
Because your main application restricts the size of the scroller to 400x400, the base will never exceed 400x400 aswell.
If you add the dummy, base is free to expand as much as it wants but dummy will be restricted to expand.
I hope this explains it a bit. If not ask me more =)

Flex 4.6 Mobile - TextArea & TextInput Skin Issues

This is for Flex 4.6 on AIR 3.1. I've also got the same issue in AIR 3.5.
In the app I'm currently working on I had issues with text from textinputs and textareas staying on the screen between views, whilst scrolling etc.
The fix I saw suggested was to use a different skinclass for the textinput's and textarea's as such:
skinClass="spark.skins.spark.TextAreaSkin"
Adobe Flex Mobile - TextArea refuses to scroll on Android, StageWebView won't scroll at all is an example of one of these suggestions to use TextAreaSkin.
However I'm now having some pretty major issues when using this and the equivalent TextInputSkins.
On the iPad 2 (iOS6) we use the softkeyboard won't appear at all and on our Samsung Galaxy tablet (Android 4) the keyboard will only allow numbers and certain special characters to be entered (it also allows capital letters if I hold down on a particular letter but not when typed normally).
I've found one other mention of an issue similar to mine here:
http://forums.adobe.com/message/4078890 but it had no solution.
Strangely everything works fine on my Android (Desire) phone or if I use a different keyboard app (Swiftkey) on the Samsung Galaxy Tablet then that also works fine.
I've tested this in our other app and I get the same issues in that one. (The only instances where I had to use the skin for that app was non editable textareas - I never saw the first issue I mentioned in that app).
EDIT: I've created a fairly basic demo with a few views where I've reproduced most of the issues I'm having. It's a mobile application which uses a splitview navigator.
Main Application File:
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<!-- Split View Navigator used for Tablet for panelled functionality -->
<s:SplitViewNavigator width="100%" height="100%">
<s:layout.landscape>
<s:HorizontalLayout />
</s:layout.landscape>
<s:layout.portrait>
<s:VerticalLayout />
</s:layout.portrait>
<s:ViewNavigator width.landscape="35%" height.landscape="100%"
width.portrait="100%" height.portrait="30%"
firstView="views.TestView" />
<s:ViewNavigator width="100%" height="100%" height.portrait="100%"
firstView="views.TestFormHomeView" />
</s:SplitViewNavigator>
</s:Application>
Home View:
<fx:Script>
<![CDATA[
protected function buttonClick():void
{
navigator.pushView(TestView2);
}
protected function listClick():void
{
navigator.popView();
navigator.pushView(TestFormHomeView);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Scroller width="100%" height="100%">
<s:HGroup width="100%">
<s:List width="50%" click="listClick()">
<s:ArrayCollection>
<fx:String>Test1</fx:String>
<fx:String>Test2</fx:String>
<fx:String>Test3</fx:String>
<fx:String>Test4</fx:String>
<fx:String>Test5</fx:String>
</s:ArrayCollection>
</s:List>
<s:VGroup width="50%">
<s:TextArea id="testing" skinClass="spark.skins.spark.TextAreaSkin" />
<s:TextArea id="testing2" />
<s:Button click="buttonClick()" label="Next Screen" />
</s:VGroup>
</s:HGroup>
</s:Scroller>
</s:View>
TestView:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="TestView">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:TextArea id="testing2" />
</s:View>
TestView2:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="TestView2">
<fx:Script>
<![CDATA[
protected function goBack():void
{
navigator.popView();
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:TextArea id="testing2" />
<s:Button label="Back" click="goBack()" />
</s:View>
The main text area on HomeView has the skinclass applied which for me has the following issues:
iOS (iPad2): No softKeyboard at all.
Android (Samsung Galaxy Tab): Keyboard appears but only allows numbers and certain special characters
I've not been able to reproduce the issue (without the other skinclass) with text staying on the screen but on Android if you type something into the text box on the 'TestView' and click Next Screen the text in TestView will disappear after the view has loaded (until you click into the textbox). And if you have a screen long enough scrolling with text boxes causes a lot of issues if you don't use the other skinclass.
Okay I found out what my problem was. Turned out to be a very simple one in the end.
I was using the wrong skin. There is a mobile specific skin called:
spark.skins.mobile.TextInputSkin
It's not working perfectly yet but the fact I've actually got something working is a relief lol.
When we need to skin TextInput and TextArea in mobile, we need to subclass the default spark.skins.mobile.MobileSkin (or MobileTextInputSkin) since Mobile skin using Actionscript is light-weight skin comparing to the default MXML skin. If you skin TextInput and TextArea using MXML, on some devices like Samsung's phone and tablet (which do not use the default Google Android keyboard), you will get the problem that the SoftKeyboard will not appear when the input is focused.
Another thing is: we should never use the restrict property on TextInput and TextArea or otherwise, we will get the error where text keeps overwritten each other.
Hope this help, Rjs37
I have created a workaround for the StageTextAreaSkin and the StageTextInputSkin that enables the use of these skins in a Scroller. If the only reason you want to use the TextInputSkin is to support scrolling, this this should help. It is available on GitHub:
https://github.com/lizardon/TouchScrollStageText
It works by making changes to the StyleableStageText class to listen for touch events and position changes to ancestor Scroller components.
Hopefully Apache will resolve this bug soon and a workaround will not be needed.

create custom chrome adobe air desktop application using flex4 sparks controls

I have googled around but the only resource for teaching me how to create an Adobe Air Desktop Application uses mx controls instead.
inside app-xml i have set transparent to true and systemChrome to none.
the following is my main mxml
<?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:mx="library://ns.adobe.com/flex/mx"
xmlns:dragdrop="org.robotlegs.demos.draganddrop.*"
xmlns:view="org.robotlegs.demos.draganddrop.view.*"
mouseOver="layoutCanvas.visible = true;"
mouseOut="layoutCanvas.visible = false;"
>
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
s|Application {
background-alpha:"0.7";
padding: 0px;
}
</fx:Style>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<dragdrop:DragAndDropContext contextView="{this}"/>
</fx:Declarations>
<s:Image id="background" width="100%" height="100%"
source="#Embed('theme/assets/MaxBackground.png')"/>
<s:BorderContainer id="layoutCanvas" width="100%" height="100%" visible="false">
<s:Image id="applicationClose" right="5" top="2"
click="stage.nativeWindow.close()"
source="#Embed('theme/assets/buttons/CLOSE WINDOW icon.png')"/>
<s:Image id="applicationMaximize" right="25" top="2"
click="stage.nativeWindow.maximize()"
source="#Embed('theme/assets/buttons/EXPAND WINDOW icon.png')"/>
<s:Image id="applicationMinimize" right="45" top="2"
click="stage.nativeWindow.minimize()"
source="#Embed('theme/assets/buttons/COLLAPSED WINDOW icon.png')"/>
</s:BorderContainer>
</s:WindowedApplication>
I have two issues.
1) the initial application window size. How can i set this to 100% full screen?
2) there is a strange grey horizontal footer at the bottom. How do i get rid of it? See here
I do not wish to use mx controls. I want to use sparks controls as much as possible.
Thank you.
1) the initial application window size. How can i set this to 100% full screen?
To do this you can add a CREATION_COMPLETE handler to your application and within that handler add a line similar to:
this.maximize() where this is you WindowedApplication.
2) there is a strange grey horizontal footer at the bottom
From the sounds of it, this is the status bar. Try setting the showStatusBar property on you WindowedApplication root tag to false :
showStatusBar="false"
Hope this helps.

Browser scrollbar issue when embedded with swf

I am developing a flex application which is embedded in a html file. The issue is I am not able to get the browser scroll bars, once the browser window resizes. I have tried setting overflow:scroll in the css code for html, but didn't work.
Consider an example like:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="600" minHeight="400" width="100%" height="100%">
<s:BorderContainer left="30" right="30" height="120" width="100%" backgroundColor="#FFFFFF" borderVisible="true">
<s:Label x="10" y="10" fontSize="12" fontFamily="Arial" fontStyle="normal" text="PCA title"/>
</s:BorderContainer>
<s:BorderContainer left="30" right="30" top="150" height="100%" bottom="30" width="100%" backgroundColor="#000000" borderVisible="true">
</s:BorderContainer>
</s:Application>
Here if i set the absolute values for height and weight as height="768" and weight="1366", i do get the scrollbars. But i am developing the application using relative coordinates so that it works across all machines irrespective of their screen sizes. So, i cannot specify absolute value for height and weight.
Can someone help me with this as to how to get the scrollbars working without disturbing my relative coordinate system.
I'm not certain that I understand your question correctly, but I think you need SWFFit.
This is a JavaScript tool that can limit the minimum and maximum sizes of the container of your Flash object, and will force the browser to supply scrollbars when required.

Horizontal Layout: mx vs spark - Resizing children

In Flex 3, I used to be able to take 2 panels, lay them out with 100% width settings in an HBox. If I changed the width property of the first panel to something smaller, let's say 20%, the second would automatically update and fill in the space that used to be taken up by the first as the first resized down.
I notice in spark, this doesn't happen. I have an app with a HorizontalLayout, and a resizable panel control on the left and a panel on the right that has width="100%." When I resize my left-side panel down, the right side panel doesn't do anything. So I end up with a clean resizable panel, a bunch of wasted space, and my right-side panel just sitting there.
What I expect is that since the right-side panel has a width="100%" then if the panel to its left is resized, then there would be a corresponding growth in the right-side panel to fill in.
I've tried to manually trigger validation on properties and size without effect. I'm wondering what changed in the HorizontalLayout that no longer allows this technique to work. I would also like to know what solutions are available?
Here's some chomp chomp:
<mx:Application>
<mx:Script>
<![CDATA[
protected function resizeClick(event:MouseEvent):void
{
pnl1.percentWidth = 10; // When this would execute, pnl2 would automatically
// fill in the space previously held by pnl1.
}
]]>
</mx:Script>
<mx:HBox width="100%" height="100%">
<mx:Panel id="pnl1" width="40%" height="100%"> // Uses 40%
<mx:Button id="resizeButton" click="resizeClick(event)"/>
</mx:Panel>
<mx:Panel id="pnl2" width="100%" height="100%"/> // Fills in the rest of the available space
</mx:HBox>
</mx:Application>
Flex 4.5 doesn't automatically update the size of pnl2 when the size of pnl1 changes. I would think that since a HorizontalLayout is being used, that both children would update when the width of one of them was changed. But that just doesn't seem to be the case. I know I can create two states to accomplish this, but I was thinking that I shouldn't have to for something so trivial.
This sample works fine and illustrates correct changes of sizes:
<?xml version="1.0" encoding="utf-8"?>
<s:Application minHeight="600" minWidth="955" xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark">
<s:VGroup height="100%" width="100%">
<s:HSlider change="firstPanel.percentWidth = event.currentTarget.value" maximum="100" minimum="0"
value="{firstPanel.percentWidth}" />
<s:HGroup height="100%" width="100%">
<s:Panel height="100%" id="firstPanel" minWidth="0" width="40%" />
<s:Panel height="100%" width="100%" />
</s:HGroup>
</s:VGroup>
</s:Application>
So this is how I eventually solved this problem. I should have been a little more specific in my post to explain that Panel 1 is actually a "collapsible" panel that modifies its own size whenever its header button is clicked. The example above does work, but since there is no numeric control on the view to "tell" the panel.percentWidth property how much to change, I set my collapsible panel up to dispatch custom events that are handled by the wrapper. The custom events basically indicate what is happening to the collapsible panel. From there, I can handle the events separately and then control the size of Panel 2.
The solution is actually rather simple and I was hoping for something a little more "behind the scenes" but this worked fine.
<s:Application initialize="initApp(event)">
<fx:Script>
<![CDATA[
protected function initApp(event:FlexEvent):void
{
this.addEventListener("PanelCollapse", panelHandler);
this.addEventListener("PanelNormal", panelHandler);
}
protected function panelHandler(event:Event):void
{
switch(event.type)
{
case "PanelCollapse":
pnl2.percentWidth = 100;
break;
case "PanelNormal":
pnl2.percentWidth = 60;
break;
}
}
]]>
</fx:Script>
<comp:CollapsiblePanel id="pnl1" width="40%" height="100%">
</mx:Panel>
<s:Panel id="pnl2" width="100%" height="100%"/> // Fills in the rest of the available space
</s:Application>