I have the following MXML Code but I need to run it from Actionscript. How can I write this in AS? Thanks a lot!!
<?xml version="1.0"?>
<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/halo"
applicationComplete="applicationCompleteHandler()">
<fx:Script>
<![CDATA[
private var bannerIntegration : BannerAd;
public function applicationCompleteHandler():void
{
Security.allowDomain("*");
bannerIntegration = new BannerAd(banner);
}
]]>
</fx:Script>
<s:Image id="banner" width="300" height="250"/>
</s:Application>
That is just from memory so it might need some tweaks:
Basically you would create a normal
class SpecialApplication extends Application {
In your IDE or mxmlc call you choose SpecialApplication as the class to build.
Inside the class you have the properties as you have them now:
private var bannerIntegration : BannerAd;
private var banner:Image;
everything else is simple to answer for your example but I'm sure this is not the complete application, so you should read something about the Flex Lifecycle (be careful that you look at the right one: the one for Flex 3.* is a bit different from the one in Flex 4.*)
So ideally
override protected function createChildren():void {
to create and add UI elements:
if (image == null) {
image = new Image();
image.width = 300;
image.hight = 250;
addChild(image);
bannerIntegration = new BannerAd(banner);
}
I'm not sure if Security.allowDomain("*"); requires some special timing maybe you can also do it inside createChildren().
Otherwise you can have the same method that you have in your script block above (with an additional event:FlexEvent argument), to do this call. Just do
addEventListener(FlexEvent.CREATION_COMPLETE, applicationCompleteHandler)
inside the constructor.
The if inside createChildren() is there to make sure to only create ui elements once. As createChildren() will be called each time this component is added. (Not so important inside Application, but a good habit for creating components using ActionScript classes.
Related
It seems Aurelia is not aware when I create and append an element in javascript and set a custom attribute (unless I am doing something wrong). For example,
const e = document.createElement('div');
e.setAttribute('custom-attr', 'some value');
body.appendChild(e);
Is there a way to make Aurelia aware of this custom attribute when it gets appended?
A little background: I am creating an app where the user can select their element type (e.g. input, select, checkbox etc.) and drag it around (the dragging is done in the custom attribute). I thought about creating a wrapper <div custom-attr repeat.for="e of elements"></div> and somehow render the elements array, but this seemed inefficient since the repeater will go through all the elements everytime I push a new one and I didn't not want to create a wrapper around something as simple as a text input that might be created.
You would have to manually trigger the Aurelia's enhance method for it to register the custom attributes or anything Aurelia related really. And you also have to pass in a ViewResources object containing the custom attribute.
Since this isn't as straight forward as you might think, I'll explain it a bit.
The enhance method requires the following parameters for this scenario:
Your HTML as plain text (string)
The binding context (in our scenario, it's just this)
A ViewResources object that has the required custom attribute
One way to get access to the ViewResources object that meets our requirements, is to require the custom attribute into your parent view and then use the parent view's ViewResources. To do that, require the view inside the parent view's HTML and then implement the created(owningView, thisView) callback in the controller. When it's fired, thisView will have a resources property, which is a ViewResources object that contains the require-d custom attribute.
Since I am HORRIBLE at explaining, please look into the example provided below.
Here is an example how to:
app.js
import { TemplatingEngine } from 'aurelia-framework';
export class App {
static inject = [TemplatingEngine];
message = 'Hello World!';
constructor(templatingEngine, viewResources) {
this._templatingEngine = templatingEngine;
}
created(owningView, thisView) {
this._viewResources = thisView.resources;
}
bind() {
this.createEnhanceAppend();
}
createEnhanceAppend() {
const span = document.createElement('span');
span.innerHTML = "<h5 example.bind=\"message\"></h5>";
this._templatingEngine.enhance({ element: span, bindingContext: this, resources: this._viewResources });
this.view.appendChild(span);
}
}
app.html
<template>
<require from="./example-custom-attribute"></require>
<div ref="view"></div>
</template>
Gist.run:
https://gist.run/?id=7b80d2498ed17bcb88f17b17c6f73fb9
Additional resources
Dwayne Charrington has written an excellent tutorial on this topic:
https://ilikekillnerds.com/2016/01/enhancing-at-will-using-aurelias-templating-engine-enhance-api/
I want to expose a method from a custom component in a NativeScript project. Here is the conceptual setup:
MyComponent.xml
<StackLayout loaded="loaded"> ...UI markup... </StackLayout>
MyComponent.ts
export function loaded(args) { //do stuff };
export function myCustomMethod() { //do more stuff };
MyPage.xml
<Page xmlns:widget="..." loaded="loaded">
<widget:MyComponent id="myComponent" />
</Page>
MyPage.ts
export function loaded(args) {
let page = <Page>args.object;
let widget = page.getViewById("myComponent");
widget.myCustomMethod(); //<--THIS DOES NOT WORK
}
Question: How do I properly expose the myCustomMethod on the custom component so that the hosting page can access and call it via JavaScript?
By default, when trying to get a reference to the custom component on the page, a reference to the custom component's layout container is returned (in this example, a StackLayout).
So, as a workaround, I am doing this:
MyComponent.ts
export function loaded(args) {
let stackLayout = <StackLayout>args.object; //Layout container
stackLayout.myCustomMethod = myCustomMethod; //Attach custom method to StackLayout
}
It's a bit of a hack, but it's working. Is there any better way to expose custom component methods short of creating a super class for the layout container?
UPDATE
To be more accurate, the custom component has instance properties, so the eventual solution would need to support a scenario like...
MyComponent.ts
let isStarted = false;
export function loaded(args){ // do stuff };
export function myCustomMethod() { isStarted = true; };
As the method you want to reuse is not coupled to your customCompoenent, you can create a common file and require it where needed and reuse the exposed methods accordingly. Or you can directly import your MyComponent.ts and reuse its exported methods (not so good idea as you will probably have access to all exposed methods of your MyCompoennt.ts like onLoaded, onNavigationgTo, etc.)
For example:
in your navigator.ts (or if you prefer to your MyComponent.ts)
import frame = require("ui/frame");
export function navigateBack() {
frame.goBack();
}
and then reuse it where needed like this:
MyPage.ts
import navigatorModule = require("navigator");
export function goBack(args: observable.EventData) {
navigatorModule.goBack(); // we are reusing goBack() from navigator.ts
}
Another applicable option is to use MVVM pattern and expose your methods via the binding context.
Flex is not showing image I have tried many webpages for helping can anyone please help me
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[
public var photo:FileReference = new FileReference();
protected function crop_clickHandler():void
{
var f:FileFilter = new FileFilter("Image", "*.jpg;*.jpeg;*;*.gif;*.png;");
photo.addEventListener(Event.SELECT, fileSelected);
photo.browse([f]);
}
private function fileSelected(evt:Event):void
{
photo.addEventListener(Event.COMPLETE,loadCompleted);
photo.load();
}
private var loader : Loader = new Loader();
private function loadCompleted(evt:Event):void
{
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, getBitmapData);
loader.loadBytes(photo.data);
}
private function getBitmapData(event:Event):void
{
var content:DisplayObject = loader.content;
var BMPData:BitmapData = new BitmapData(content.width,content.height);
// var imgObj:Object = new Object();
var bmd:BitmapData;
bmd = Bitmap(event.currentTarget.content).bitmapData;
var bmpMy:Bitmap = new Bitmap(bmd);
myImage1.source=bmpMy
// myImage1.addChild(DisplayObject(bmpMy));
}
]]></mx:Script>
I have even tried to show the image here after the load but it is not working the way I tried
<mx:Button id="btnLoad" label="Browse Image" click="crop_clickHandler()" ></mx:Button>
<mx:Image id="myImage1" x="50" y="50" height="100%" width="100%" maintainAspectRatio="false" autoLoad="true" ></mx:Image>
</mx:Application>
You are accessing methods on FileReference that are not available in flash player 9 (the default for Flex 3.6).
What you need to do is target flash player 10.1 or later. Here are the instructions to target 11.1, as that's what comes with Flex 4.
First, Update the target player under "Flex Compiler" in project properties:
Second, go to Flex Build Path and remove playerglobal.swc from under the Flex 3.6a menu. Then click Add SWC and select the playerglobal.swc for the targeted player version (look in FLEX_SDK/frameworks/libs/player/11.1).
Don't forget to do a Project Clean afterwards.
You should now be able to run your code as is.
I m trying to upload and show images.
I get the file, write it to docroot of glassfish application server, then
Image image = new Image("myimage","images/task.gif");
But i get <img wicket:id="myimage" src="resources/wickcat.MyPage/images/task.gif" />
Is there any way that wicket wont rewrite my src path? Even when i use an http://.... starting src, it writes resources/wickcat.MyPage/http://... which makes no sense at all.
I just need it to write "images/task.gif".
Any ideas?
There is two ways to do this.
Use <img src="images/task.gif" />. This is if you don't need reference to the component in the class.
Use ContextImage image = new ContextImage("myimage", "images/task.gif");. If you use the ContextImage component, the source will be relative to the Context root, you can even input a model as the relative path to the image.
The Image class assumes the image is a resource located in the classpath.
You could use a WebMarkupContainer with a SimpleAttributeModifier:
WebMarkupContainer img = new WebMarkupContainer("myimage")
.add(new SimpleAttributeModifier("src", "/images/task.gif"));
It will output the string as is, so you have complete control.
If it is used several times across the application, I'd recommend you to create a component encapsulating this behavior. Something like
public class MyImage extends WebMarkupContainer {
public MyImage(String id, String path) {
add(new SimpleAttributeModifier("src", path));
}
}
I'm using .net 2.0 with Visual Studio 2005 and I am trying to add two different toolstrips to the top of the form such that they show up side-by-side. I want it to be like Word 2003, where you can add multiple toolstrips to the same row and have them show up in line with each other, rather than dedicating a row to each toolstrip.
So I added a ToolStripPanel and docked it to the top of the form (I didn't use a ToolStripContainer because I don't need all the extra panels; I just need the one at the top). I added both toolstrips and set their Stretch properties to False. I can get them to show up in the designer window side-by-side, but at runtime the ToolStripPanel separates the toolstrips and gives each toolstrip its own dedicated row. As if to add insult to injury, when i stop debugging and return back to the designer, I am finding that the designer is moving the toolstrips to their own row as well! Am I doing something wrong here?
I have been Googling all day and found some information about a ToolStripPanelRow object, but I don't see an easy way to add toolstrips to it (i.e. it doesn't have a ToolStripPanelRow.Controls.Add method or anything like that), all it has is a Controls() property that returns an Array of control objects, and I haven't had much luck trying to add items to that array. I also found some documentation on the ToolStripPanel.Join method, which sounds like it should do the job, so I tried all 3 overloads but they don't work as advertised. No matter what I do or which options I try, it always adds the new toolstrip to the top of the panel on its own row and pushes everything else down.
In the interests of full disclosure I should warn you that I have the ToolStripPanel and one of the toolstrips added to a baseclass form, and I am trying to add the other toolstrip to a subclass form that inherits from the baseclass form. The ToolStripPanel and ToolStrip in the baseclass form are both declared "Protected Friend", so this should be working. As I mentioned, the subclass form's designer window will allow me to do it (at least, for a time).
If anyone can help me get this working or at least shed some light on why it isn't, I would be extremely grateful.
I created a custom ToolStripPanel so that I could overload the LayoutEngine;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Layout;
namespace CustomGUI
{
class CustomToolStripPanel : ToolStripPanel
{
private LayoutEngine _layoutEngine;
public override LayoutEngine LayoutEngine
{
get
{
if (_layoutEngine == null) _layoutEngine = new CustomLayoutEngine();
return _layoutEngine;
}
}
public override Size GetPreferredSize(Size proposedSize)
{
Size size = base.GetPreferredSize(proposedSize);
foreach(Control control in Controls)
{
int newHeight = control.Height + control.Margin.Vertical + Padding.Vertical;
if (newHeight > size.Height) size.Height = newHeight;
}
return size;
}
}
}
Then the custom LayoutEngine lays out the ToolStrips;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Layout;
namespace CustomGUI
{
class CustomLayoutEngine : LayoutEngine
{
public override bool Layout(object container, LayoutEventArgs layoutEventArgs)
{
Control parent = container as Control;
Rectangle parentDisplayRectangle = parent.DisplayRectangle;
Control [] source = new Control[parent.Controls.Count];
parent.Controls.CopyTo(source, 0);
Point nextControlLocation = parentDisplayRectangle.Location;
foreach (Control c in source)
{
if (!c.Visible) continue;
nextControlLocation.Offset(c.Margin.Left, c.Margin.Top);
c.Location = nextControlLocation;
if (c.AutoSize)
{
c.Size = c.GetPreferredSize(parentDisplayRectangle.Size);
}
nextControlLocation.Y = parentDisplayRectangle.Y;
nextControlLocation.X += c.Width + c.Margin.Right + parent.Padding.Horizontal;
}
return false;
}
}
}
One thing that took a while is that changing the location / size of one ToolStrip item will cause the layout to re-fire, with the controls reordered. So I take a copy of the controls before the layout loop.
And you cant use AddRange(...) to add items to the Custom Panel for some reason - need to Add(...) them one at a time.
hope that helps (it's based on MSDN LayoutEngine Example, fixed for ToolStripPanels)
Wyzfen
System.Windows.Forms.FlowLayoutPanel can do the job.
Just put the ToolStrip controls in it with correct order.
I think in your case you can get away with just setting the LayoutStyle on your ToolStrip to ToolStripLayoutStyle.HorizontalStackWithOverflow rather than need your own custom LayoutEngine.
I asked a different question on a similar topic on how to handle layout with dynamic items to have better control of the overflow.