How can I change the size of icons in the Tree control in Flex? - apache-flex

I embed SVG graphics in my Flex application using
package MyUI
{
public class Assets
{
[Embed(source="/assets/pic.svg"]
[Bindable]
public static var svgPic:Class;
}
}
and then extending the Tree class with some of my own code, setting the icon upon adding a node to the data provider:
public class MyTree extends Tree
{
public function MyTree()
{
// ...
this.iconField = "svgIcon";
// ...
this.dataProvider = new ArrayCollection;
this.dataProvider.addItem({ /* ... */ svgIcon: MyUI.Assets.svgPic /* ... */ });
// ...
}
}
Now I have two things I want to do:
use the SVG graphics in multiple places in the app, scaling them to the appropriate size for each appearance, i. e. scale them to a proper icon size when using them in the tree
change the size of the icon at runtime, e. g. display a slightly larger icon for selected items or let an icon "pulse" as a response to some event
I read the Flex documentation on the 9-slice scaling properties in the Embed tag, but I think that's not what I want.
Edit:
I unsuccessfully checked the "similar questions" suggested by SO, among others this one:
Flex: Modify an embedded icon and use it in a button?

Subclass mx.controls.treeClasses.TreeItemRenderer and make it resize the icon to your desired dimensions, or create your own item renderer implementation by using the same interfaces as TreeItemRenderer. Set a custom item renderer with the itemRenderer property:
exampleTree.itemRenderer = new ClassFactory( ExampleCustomItemRendererClass );

The answer to this question might point you in the right direction, without knowing more about the trouble you're having:
Flex: Modify an embedded icon and use it in a button?
Hope it helps!

Related

Xamarin.Forms: use SVG images as icons on a TabbedPage

I want to use SVG images as icons on a TabbedPage in Xamarin.Forms for iOS.
The documentation for the TabbedPage class provides the following tip:
The TabbedRenderer for iOS has an overridable GetIcon method that can be used to load tab icons from a specified source. This override makes it possible to use SVG images as icons on a TabbedPage. In addition, selected and unselected versions of an icon can be provided.
I created the following class to perform the override:
[assembly: ExportRenderer(typeof(TabsRoot), typeof(TabbedPageCustomRenderer))]
namespace MyProject.iOS.Renderers
{
public class TabbedPageCustomRenderer : TabbedRenderer
{
protected override Task<Tuple<UIImage, UIImage>> GetIcon(Page page)
{
var image = UIImage.FromFile(#"home-black-18dp.svg");
return Task.FromResult(new Tuple<UIImage, UIImage>(image, image));
}
}
}
The accepted answer in this thread recommends creating a UIImage from an SVG file by doing something like this: var myImage = UIImage.FromFile(<<file name>>) where <<filename>> is an SVG. This other thread contradicts the previous thread, saying that UIImages cannot be made from SVG files. Sure enough, when I provide an SVG file, UIImage.FromFile() returns null and no icon is shown at all, just as the latter thread predicted. When I provide a PNG file, the override works as expected.
Another way I've tried to square this circle is to use the SvgCachedImage provided by FFImageLoading.Svg.Forms, but I haven't figured out how to 'wrap' a UIImage around an SvgCachedImage or whether that is even appropriate in this case.
Thank you for your help!
Add Xamarin.FFImageLoading.Svg nuget package to your ios project.
then create the UImage in your GetIcon method like below :
UIImage img = await ImageService.Instance
.LoadFile("timer.svg")
.WithCustomDataResolver(new SvgDataResolver((int)(TabBar?.Bounds.Height / 2 ?? 30), (int)(TabBar?.Bounds.Height / 2 ?? 30), false))
.AsUIImageAsync();
UIImage newImg = img.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);

javafx - easiest way of changing the caret color

I would like to set the caret color for all JavaFX text inputs (e.g. TextField, TextArea, the ones in ComboBox:editable, DatePicker, etc...)
I found this Stackoverflow answer: How to change the caret color in JavaFX 2.0?
... and an example on GitHub.
The first one does change the text and the caret color which is not good. The second one extends the TextFieldSkin class, which is already better, but how can I use it in CSS?
Any help is appreciated.
UPDATE 1:
I found the following CSS style property for JavaFX controls: -fx-skin.
This would theoretically allow me to set a custom skin class (-fx-skin: "package.MySkin";), however, the skin class just isn't used!
The class looks like the following:
package gui;
…
public class MyTextFieldSkin extends TextFieldSkin
{
public MyTextFieldSkin(TextField tf) {
super(tf);
System.out.println("MyTextFieldSkin constructor called!");
ReadOnlyObjectWrapper<Color> farbe = new ReadOnlyObjectWrapper<>(Color.green);
caretPath.strokeProperty().bind(farbe);
caretPath.setStrokeWidth(1.5);
}
}
… and is set in CSS like that:
.text-field {
-fx-skin: "gui.MyTextFieldSkin";
}
What am I doing wrong? I looked at the source code of AquaFX, and they are doing it the same way as me!
After a bit of try & error, I solved the problem in the following way:
I gathered all TextFields and controls that have TextFields in them (like ComboBox, DatePicker and so on) inside a container recursively (in deference of TitledPane, ScrollPane, SplitPane and TabPane, because they don't publish their children in getChildren(), so one has to call the getContent() method of the individual classes and scan through it).
After I had all the TextField controls, I looped over them and changed their Skin with the following code:
public class MyTextFieldSkin extends TextFieldSkin {
public MyTextFieldSkin(TextField tf)
{
super(tf);
ReadOnlyObjectWrapper<Color> color = new ReadOnlyObjectWrapper<>(Color.RED);
caretPath.strokeProperty().bind(color);
}
}
Then I just had to call
textfield.setSkin(new MyTextFieldSkin(textfield));
and that was about it.
Cheers

Flex/AS3: changing width/height doesn't affect contents

I thought I had a handle on AS3, DisplayObjectContainers, etc. but this basic thing is really confusing me: changing the width/height of a sprite does not affect it's visual contents - either graphics drawn within it or any children it may have.
I have searched around and found an Adobe page that represents my own little test code. From that page, I would expect the sprite to increase in visual size as it's width increases. For me, it doesn't. (http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObject.html#width)
width property
width:Number [read-write]
Indicates the width of the display object, in pixels. The width is calculated based on the bounds of the content of the display object. When you set the width property, the scaleX property is adjusted accordingly, as shown in the following code:
My code below doesn't affect the visual display at all - but it does set the width/height, at least according to the trace output. It does not affect the scaleX/scaleY.
What the heck am I missing here??
My setup code:
testSprite = new SpriteVisualElement();
var childSprite:SpriteVisualElement = new SpriteVisualElement();
childSprite.graphics.beginFill(0xFFFF00, 1);
childSprite.graphics.drawRect(0, 0, 200, 100);
childSprite.graphics.endFill();
childSprite.name = "child";
testSprite.addChild(childSprite);
container.addElement(testSprite);
testSprite.addEventListener(MouseEvent.CLICK, grow);
}
public function grow(event:MouseEvent):void
{
event.target.width += 5;
event.target.height += 5;
trace("grow", event.target.width);
}
If I understand the code correctly; you are changing the width / height of the sprite. But you are doing nothing to change the width/ height of the sprite's children.
In the context of a Flex Application, you can use percentageWidth and percentageHeight on the child to resize the child when the parent is resized. You could also add a listener to the the resize event and adjust sizing that way; preferably tying in to the Flex Component LifeCycle methods somehow.
I believe these approaches are all Flex specific, and dependent upon the Flex Framework. Generic Sprites, as best I understand, do not automatically size themselves to percentages of their parent container; and changing the parent will not automatically resize the parent's children.
I bet something like this would work:
public function grow(event:MouseEvent):void
{
event.target.width += 5;
event.target.height += 5;
childSprite.width += 5;
childSprite.height += 5;
trace("grow", event.target.width);
}
First, if you have a problem with a flex component, you can look over its source code.
In my environment, (as I installed flex SDK to C:\flex\flex_sdk_4.1), the source code for SpriteVisualElement is located at
C:\flex\flex_sdk_4.1\frameworks\projects\spark\src\spark\core\SpriteVisualElement.as
In the source code, you'll find that width property is overridden :
/**
* #private
*/
override public function set width(value:Number):void
{
// Apply to the current actual size
_width = value;
setActualSize(_width, _height);
// Modify the explicit width
if (_explicitWidth == value)
return;
_explicitWidth = value;
invalidateParentSizeAndDisplayList();
}
So, you cannot expect the auto-scaling of the component.
Making custom components will be one solution.
Here is a sample implementation of custom component.
Custom Component Example - wonderfl build flash online

Flex: Label.addChild() not working?

I want to make a label that has a tiny title above it, for example so the label say $1,000 with a small retail price or our price above it. I am trying to add the title label to the display list of the main label. I get no error but the title does not show up. I also considered rawChildren but apparently Label has no rawChildren property.
Here is my code:
package
{
import mx.controls.Label;
public class PriceLabel extends StrikeThroughLabel //<-- exntension of label to add strike
{
private var _title:Label;
public function PriceLabel()
{
super();
}
[Bindable]
public function set title(s:String):void
{
if(_title == null)
{
_title = new Label();
addChild(_title);
this.alpha = .2;
}
_title.text = s;
}
public function get title():String
{
var s:String
if(_title != null)
{
s = _title.text;
}
return s;
}
}
}
If you add children to a Flex component that is not a container, then you have to manually manage sizing and positioning of those children. Containers do a lot of that work for you.
Here's what you should do:
Move the creation of your child Label into an override of the createChildren() function.
Set the text property of the child label in an override of the commitProperties() function. Your title getter and setter should save the value in a _title variable to be used later for the assignment in commitProperties(). This is actually important for performance.
Override the measure() function and update measuredWidth and measuredHeight to be the maximum width and height values of the main label and it's child.
Override updateDisplayList() and use setActualSize() on the child Label to set it to the required width and height.
That may seem like a lot of work, but in terms of best practices, that's the way you're supposed to build custom components. The Flex Team at Adobe spent a lot of time maximizing performance, and that's why things happen in several steps like that.
That's how to do it based on what you asked. Personally, I would make a subclass of UIComponent with two Labels or UITextFields as children, each with their own separate property.
By the way, the rawChildren property is only available on containers. It exists so that you can add "chrome" to a container that isn't part of the container's child layout algorithm. For example, Panel has a title bar and a border that aren't affected by the vertical/horizontal/absolute layout options.
Why not create a custom component that contains both labels as its children, instead of trying to throw a child on the Label? That feels cleaner to me, as adding children to build-in components like that doesn't seem right.

Flex: changing Flex component styles in AS3

in MXML, there is a Button class which you can instantiate like so:
<mx:Button id="something />
but what if you wanted to dynamically build this in AS3 and add it to the Flex app dynamically, without the use of components (just AS3) and then modify Flex's styles, for example, here you access the Button's properties and set them:
var btn:Button = new Button();
btn.height = 50;
btn.width = 75;
btn.x = 100;
btn.y = 40;
but how would you go about changing the Style, for example:
btn.downSkin = "something";
btn.color = "0xfffff";
I'm sort of starting to lean towards making a flex component in MXMLand than just making it visible true/false, but i like the fact that i create an object in AS3 and then destroy it when I don't need it anymore, than create it again once needed.
This page has a solution to the problem:
Setting and getting Style attributes in ActionScript:
// setting a components styleName to reference a CSS class
component.styleName = "highlight";
// set a Button's background color and font size
submitButton.setStyle( "backgroundColor", 0x000000 );
submitButton.setStyle( "fontSize", 14 );
// get a TextArea's font family and color
textArea.getStyle( "fontFamily" );
textArea.getStyle( "color" );
You could use CSS, either inline or as an external CSS file. That way you don't have to set the properties manually every time you create a button.
/* CSS file */
Button {
borderColor: red;
}
Check out Styling Button control, by Peter deHaan (also read the comments in that post).

Resources