QNXStageWebView on top of all containers - webview

I am developing an application for blackberry playbook using flex hero and html contents are displayed using QNXStageWebView.But the problem is when i add this webview to stage its coming on top of all other display objects.I am not able to control it.I need to solve it then only i can continue my work. can anyone help me to solve this issue???
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
import qnx.media.QNXStageWebView;
public var webview:QNXStageWebView = new QNXStageWebView();
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
var rect:Rectangle = new Rectangle(0,0,200,400);
webview.stage = stage;
webview.viewPort = rect;
webview.zOrder = 1;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button id="buttn" x="0" y="0"/>
when i run this code am not able to see that button. i need to display it on top of webview.

Have you tried removing the zOrder? It's like the z-order-property of html to arrange children in certain layers.

AFAIK, currently it just can't do that, all QNXStageWebView always placed on top of other object, we better wait for adobe / RIM to improve the implementation.

Related

How to use a native SwiftUI View in NativeScript 7

In my NativeScript (Angular) App i use a RadListView to create a list and each element has many different informations to display. It looks like that
Because of many hints at Stackoverflow and other sources i reduced the amount of nested layouts (StackLayout, GridLayout, ...) as much as possible to make the RadListView faster. On Android is the performance by using the list much better as on iOS. With an iPad Pro (2020) the rendering of the list at scrolling is not smooth. If the user change the orientation of the device the screen is freezing and have black bars at the side or bottom for a moment. The time of the freezing depends on the amount of elements to display in each row. The same row layout in a ListView is much faster but not the same as native (SwiftUI) and with missing features like swipe and pull to refresh.
Sorry for the lyric but i think a little background explains why i try the next step.
To improve the user experience i make a tiny native test app with SwiftUI and nearly the same row layout. The feeling is much better, fast first loading, smooth scrolling and no delay by orientation changes. My next idea is to create a native component in SwiftUI to show/render each row of the RadListView if possible
<RadListView [items]="items">
<ListViewLinearLayout tkListViewLayout></ListViewLinearLayout>
<ng-template tkListItemTemplate let-item="item" let-i="index" let-odd="odd">
<MyNativeSwiftUIComponentElement data="item.rowData"></MyNativeSwiftUIComponentElement>
</ng-template>
</RadListView>
or use the List from SwiftUI to show/render the whole list
<ActionBar title="Objects"></ActionBar>
<MyNativeSwiftUIListComponent data="items"></MyNativeSwiftUIListComponent>
Looking for docs and examples was difficult. I found this very short advise Adding Objective-C/Swift code and the linked tutorial there for Objective-C (Adding Objective-C Code to a NativeScript App) and some questions on Stackoverflow but there all about classes and not SwiftUI (with struct and views). One question was about SwiftUI: Is it possible to display a View written with SwiftUI with NativeScript the answer was unfortunately not helpful for me (btw. thank you #Manoj for your great support for NativeScript at Stackoverflow!).
How can i use a SwiftUI View as native component in my {N}app?
Have anyone a hint, a link to a tutorial or a link to a public repository for a app/plugin? Every tiny tip is welcome.
You might be able to use Nativescript's placeholder component (more info on that here
So you would have the Placeholder tag on your template, and use the creatingView event to add the native UIs
<Placeholder creatingView="creatingView"/>
import { CreateViewEventData } from "#nativescript/core";
export function creatingView(args: CreateViewEventData) {
let nativeView = new UILabel(); // where this would be your native UI
nativeView.text = "Native";
args.view = nativeView;
}
After a while i give up with my attempts to use directly SwiftUI in the project ({N}+Angular) and instead i try the <Placeholder> component which #William-Juan suggested. But it looks like, that the <Placeholder> not official supported in the Angular flavor - see github issue #283
To move on, i looked at the samples for NativeScript plugins and build a working solution. If anybody interested the full sample source code are in this repository: https://github.com/teha-at/sample-nativescript-native-ui-component
First, create a class which extends the #nativescript/core/View class and has an item to get the data which will be to display.
// object-list-item.d.ts
// [...]
export class ObjectListItem extends View {
item: ObjectModel;
}
export const itemProperty: Property<ObjectListItem, string>;
Than create a abstract base class which also extends the #nativescript/core/View class and this creates the base for Android and iOS
// object-list-item.common.ts
// [...]
export const itemProperty = new Property<ObjectListItemBase, string>({
name: 'item',
defaultValue: null,
affectsLayout: isIOS,
});
export abstract class ObjectListItemBase extends View {
item: PortalObjectModel;
}
// defines 'item' property on the ObjectListItemBase class
itemProperty.register(ObjectListItemBase);
ObjectListItemBase.prototype.recycleNativeView = 'auto';
Because i was only looking for a component for iOS the object-list-item.android.ts are very simple:
// object-list-item.android.ts
import { ObjectListItemBase } from './object-list-item.common';
export class ObjectListItem extends ObjectListItemBase {}
For iOS there are much more lines, for the complete file content look at the github repo please.
/// object-list-item.ios.ts
// [...]
export class ObjectListItem extends ObjectListItemBase {
// added for TypeScript intellisense.
nativeView: UIView;
// [...]
/**
* Creates new native button.
*/
public createNativeView(): Object {
const mainUiStackView = UIStackView.new();
// [...]
}
/**
* Initializes properties/listeners of the native view.
*/
initNativeView(): void {
// Attach the owner to nativeView.
// When nativeView is tapped we get the owning JS object through this field.
(<any>this.nativeView).owner = this;
super.initNativeView();
}
/**
* Clean up references to the native view and resets nativeView to its original state.
* If you have changed nativeView in some other way except through setNative callbacks
* you have a chance here to revert it back to its original state
* so that it could be reused later.
*/
disposeNativeView(): void {
// Remove reference from native listener to this instance.
(<any>this.nativeView).owner = null;
// If you want to recycle nativeView and have modified the nativeView
// without using Property or CssProperty (e.g. outside our property system - 'setNative' callbacks)
// you have to reset it to its initial state here.
super.disposeNativeView();
}
[itemProperty.setNative](item: ObjectModel) {
this.item = item;
// [...]
}
}
Add an Angular directive
// object-list-item.directives.ts
#Directive({
selector: 'ObjectListItem',
})
export class ObjectListItemDirective {
}
export const ObjectListItemDirectives = [ObjectListItemDirective];
At least register the component in an Angular module.
// object-list-item.module.ts
// [...]
#NgModule({
imports: [],
declarations: [
ObjectListItemDirectives,
],
schemas: [NO_ERRORS_SCHEMA],
exports: [
ObjectListItemDirectives,
],
entryComponents: [],
})
export class ObjectListItemModule {
}
registerElement('ObjectListItem', () => ObjectListItem);
After all this steps call the new component in the template
<!-- [...] -->
<RadListView #myListView [items]="items$ | async">
<ng-template tkListItemTemplate let-item="item">
<StackLayout margin="0" padding="0" class="-separator m-y-5" height="90">
<android>
<!-- [...] -->
</android>
<ios>
<ObjectListItem [item]="item"></ObjectListItem>
</ios>
</StackLayout>
</ng-template>
</RadListView>
<!-- [...] -->
All this work is well spent. The UI is much faster and it feels more like a native app. At the mean time i build a prototype as a native iOS App in Swift and SwiftUI, of course this pure native app are a little bit more smoother, but at the moment i work with my {N}-App and the native component. Hope this sample will be useful for someone.

How to overlay xul with no id?

I'm writing a firefox addon and I'm trying to use an xul overlay to insert a canvas element. The problem is, the parent xul node of where I want to insert the canvas element has no id. Is it possible to do if there's no id? I also tried using the anonid for elements that had no id as you can see below, but had no luck with that either.
My xul overlay:
<?xml version="1.0"?>
<overlay id="myOverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<tabbrowser id="content">
<tabbox anonid="tabbox">
<tabpanels anonid="panelcontainer">
<notificationbox>
<stack anonid="browserStack">
<html:canvas id="myCanvas" height="100%" />
</stack>
</notificationbox>
</tabpanels>
</tabbox>
</tabbrowser>
</overlay>
I would like the canvas element to be inserted after each browser element in each tab like this: http://img.photobucket.com/albums/v215/thegooddale/80eae9ee.jpg
There are multiple issues with the attempt to use overlays for this:
Overlays don't work without an ID, they simply don't have another way to address an element.
Overlays cannot apply to something that isn't there when the window loads - they are a one-time thing and cannot consider dynamic elements that are created later.
Overlays cannot apply to anonymous elements (displayed in red in DOM Inspector). These elements are injected by an XBL binding and are not part of the XUL document.
You will have to use JavaScript and inject your canvas "manually" each time. You can use the TabOpen event to get notified whenever a tab is opened. Something like this should work (untested code):
// Always wait for the window to initialize first
window.addEventListener("load", function()
{
function initTab(tab)
{
var browser = window.gBrowser.getBrowserForTab(tab);
var canvas = document.createElementNS("http://www.w3.org/1999/xhtml",
"canvas");
canvas.setAttribute("anonid", "myCanvas");
canvas.setAttribute("height", "100%");
browser.parentNode.appendChild(canvas);
}
// Init all existing tabs first
var tabs = window.gBrowser.tabs;
for (var i = 0; i < tabs.length; i++)
initTab(tabs[i]);
// Listen to TabOpen to init any new tabs opened
window.gBrowser.tabContainer.addEventListener("TabOpen", function(event)
{
initTab(event.target);
}, false);
}, false)
Note that this code sets anonid attribute rather than id - an ID is supposed to be unique, you shouldn't assign the same ID to a dozen elements.
This won't work without an id. You could insert a piece of Javascript in the XUL document, that uses document.querySelector to find the tabpanels inside your XBL binding, and then would append the dynamically-created canvas to id.
However, since a new notificationbox is created every time a new tab is opened, you should have your javascript watch for new tabs and insert the canvasses accordingly.

Graph background-image resizing without PHP

I've read several helpful answers in re. image resizing using PHP and max-height etc.: Image resize script
However, my problem is that I want to resize an image of a graph that I am retrieving from another site (USGS), and putting into a site (zenfolio) that supports HTML and JavaScript, but not PHP. I have tried adjusting the specified height and width, but keep on ending up resizing only the amount of the image that shows on the page, and not the image itself (sorry I cannot post images as I am a new user).
I just posted them as png's above to demonstrate the problem, but the images are generated as follows:
<div id="riverlevels">
<center>
<div id="MyWidget" style="background-image:url(http://waterdata.usgs.gov/nwisweb/graph?agency_cd=USGS&site_no=12354500&parm_cd=00065&period=21);width:576px;Height:400px;">
<br/>
Montana River Photography </div>
</center>
</div>
</div>
This same image can be generated using this JavaScript, but for some reason that does not allow me to display more than one variable graph per page (I want to show both discharge (00060), and gage height (00065)):
<script type="text/javascript">
wStation = "12354500";
wDays = "21";
wType = "00065";
wWidth = "576px";
wHeight = "400px";
wFColor = "#000033";
wTitle = "";
document.write('<div id="gageheight"></div>');
document.write('<scr'+'ipt type="text/JavaScript"src="http://batpigandme.com/js/showstring.js"></scr'+'ipt>');
As you can tell, I have to use a separate site that I own to create the JavaScript file. The graphs are currently located in various iterations at:
montanariverphoto.com/test
clark fork gage height
I sincerely apologize if I have missed an obvious answer to this! I basically created this widget by reverse engineering a widget from another site, so perhaps my call is incorrect all together.
Does it absolutely have to be a background image? Scaling them is possible (using background-size), but this property is not well supported (basically it won't work in Internet Explorer). Your code would work almost as-is if you can use an image tag instead:
<img src="http://waterdata.usgs.gov/nwisweb/graph?agency_cd=USGS&site_no=12354500&parm_cd=00065&period=21" width="576" height="400" alt="..." />
for your other problem, ids need to be unique on a page. In your code example you are creating a div with the id of gageheight, and this is ID is hardcoded into your javascript file at http://batpigandme.com/js/showstring.js. Since you can only have one element with this ID on the page, if you repeat the code later on it won't work. You'd need to change this script so that you could pass in the ID as a variable, something like:
wTitle = "";
wElement = "gageheight";
document.write('<div id="gageheight"></div>');
document.write('<scr'+'ipt type="text/JavaScript"src="http://batpigandme.com/js/showstring.js"></scr'+'ipt>');
and then in your JS:
var myElement = document.getElementById(wElement);
var JavaScriptCode = document.createElement("script");
JavaScriptCode.setAttribute('type', 'text/javascript');
JavaScriptCode.setAttribute("src", 'http://batpigandme.com/js/data2.js');
myElement.appendChild(JavaScriptCode);

How to call a MXML class in ActionScript3.0 in Flex 3

I have a page made of custom components. In that page I have a button. If I click the button I have to call another page (page.mxml consisting of custom components). Then click event handler is written in Action-script, in a separate file.
How to make a object of an MXML class, in ActionScript? How to display the object (i.e. the page)?
My code:
page1.mxml
<comp:BackgroundButton x="947" y="12" width="61" height="22"
paddingLeft="2" paddingRight="2" label="logout" id="logout"
click="controllers.AdminSession.logout()"
/>
This page1.mxml has to call page2.mxml using ActionScript code in another class:
static public function logout():void {
var startPage:StartSplashPage = new StartSplashPage();
}
Your Actionscript class needs a reference to the display list in order to add your component to the stage. MXML is simply declarative actionscript, so there is no difference between creating your instance in Actionscript or using the MXML notation.
your function:
static public function logout():void {
var startPage:StartSplashPage = new StartSplashPage();
}
could be changed to:
static public function logout():StartSplashPage {
return new StartSplashPage();
}
or:
static public function logout():void {
var startPage:StartSplashPage = new StartSplashPage();
myReferenceToDisplayListObject.addChild( startPage );
}
If your actionscript does not have a reference to the display list, than you cannot add the custom component to the display list. Adding an MXML based custom component is no different than adding ANY other DisplayObject to the display list:
var mySprite:Sprite = new Sprite();
addChild(mySprite)
is the same as:
var startPage:StartSplashPage = new StartSplashPage();
myReferenceToDisplayListObject.addChild( startPage );
Both the Sprite and the StartSplashPage are extensions of DisplayObject at their core.
You reference MVC in the comments to another answer. Without knowing the specific framework you've implemented, or providing us with more code in terms of the context you are trying to perform this action in, it is difficult to give a more specific answer.
I assume that you are on a page with a set of components and want to replace this set of components on the page with a different set of components. My apologies in advance if this is not what you are trying to do.
You can do this using ViewStacks and switching the selected index on selection -- this can be done either by databinding or by firing an event in controllers.AdminSession.logout() and listening for that event in the Main Page and switching the selectedIndex of the view stack in the handler function.
MainPage.mxml
<mx:ViewStack>
<views:Page1...>
...
<comp:BackgroundButton x="947" y="12" width="61" height="22"
paddingLeft="2" paddingRight="2" label="logout" id="logout"
click="controllers.AdminSession.logout()"/>
</views:Page1...>
<views:Page2 ...>
...
<comp:Comp1 .../>
<comp:Comp2 .../>
</views:Page2>
I think you may use state to do you work.
You may take a look at http://blog.flexexamples.com/2007/10/05/creating-view-states-in-a-flex-application/#more-221
Edit:
I am not sure I fully understand your case.
As I know, you may make a new state in page1.mxml, and name it, eg. secondPageState, and then put the custom component page2.mxml in the secondPageState.
In the controller, you need an import statement to import the page1 component and make a public var for the page1 component, eg. firstPage.
Then, the code will similar to:
public function logout():voild
{
firstPage.currentState = "secondPageState";
}
Another solution:
If you don't like the change state solution, you may try to use the addchild, to add the custom component to your application.

Silverlight 3: How to store PathGeometry in a resource library

I'm having isues trying to access a PathGeometry resource in a Resource Library in a silverlight 3 app
Ive created a resource file called Geo.xaml
in my app.xaml i link to this file
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Components/Resources/Geo.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
in my resource file i have the following line which has the geometry for a simple box
<PathGeometry x:Key="CloseCross">M0,0 L188,0 L188,161 L0,161 z</PathGeometry>
and then in my MainPage.xaml i have a path trying to use that resource
<Path Data="{StaticResource CloseCross}" Stretch="Fill" Margin="10,10,0,0" Width="100" Height="100" UseLayoutRounding="False" Fill="Red"/>
and in Blend 3 (RC) it all looks fine, the path takes on the geometry and displays fine, the problem is when i build it and view it in browser i get the following error
Attribute {StaticResource CloseCross} value is out of range. [Line: 8 Position: 14]
I discovered a semi work around but even that has issues, i can create a style for target type Path and use a setter to set the Data property of the Path
<Style x:Key="PathStyle1" TargetType="Path">
<Setter Property="Data" Value="M0,0 L188,0 L188,161 L0,161 z" />
</Style>
The problem with this is that when I apply that style, the geometry isnt displayed in blend, the path is there in the hierachy tree but is not visible on the canvas but when i build and view it in a browser, its all good...
can anyone help me understand why I cant seem to put path geometry in a resource file (or in fact anywhere)
One problem is that in Silverlight you cannot store Paths within the ResourceDictionary. I would put the Path coordinates within a string resource, and then use http://StringToPathGeometry.codeplex.com to create the paths.
It is actually possible to store a path in a ResourceDictionary, the trick being to store it as a string.
However, the issue with this is that you get no design time suport if you do this, although at run time, it looks great.
The workaround for getting design time support in SL 5 is to store the path as a string in a code file, then using binding to get to the path data. This is the only way to get your path to show up at design time.
For example, say you have a toolbar button and you want to use a path as it's icon:
<c1:C1ToolbarButton x:Name="SaveChanges">
<Path Margin="5"
Data="{Binding SaveIcon,
Source={StaticResource iconTheme}}"
Stretch="Uniform" />
</c1:C1ToolbarButton>
Now you have your path bound to a class which implements INotifyPropertyChanged:
//A class for storing Paths which are turned into icons.
public class IconTheme : INotifyPropertyChanged
{
private string _saveIcon =
"M10.280033,48.087753L10.280033,54.397381 50.810078,54.397381 50.810078,48.087753z M15.900046,6.4432963E-05L23.693047,6.4432963E-05 23.693047,15.900064 15.900046,15.900064z M3.4200456,0L10.280033,0 10.280033,19.019096 50.810078,19.019096 50.810078,0 58.300069,0C60.190087,0,61.730004,1.5399642,61.730004,3.4298871L61.730004,59.237114C61.730004,61.137043,60.190087,62.667,58.300069,62.667L3.4200456,62.667C1.53003,62.667,1.896733E-07,61.137043,0,59.237114L0,3.4298871C1.896733E-07,1.5399642,1.53003,0,3.4200456,0z";
public string SaveIcon
{
get { return this._saveIcon; }
set { this._saveIcon = value;
NotifyPropertyChanged("SaveIcon");
}
}
void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
Lastly, you need to create an instance of the class in your App.xaml file:
<Assets:IconTheme x:Key="iconTheme" />
Now you can bind to this anywhere in your app and see the path at design time. I would prefer to have the path in Xaml, but not being able to see it at design time can be a significant drawback. Furtheremore, if I wanted to customize the Icons at runtime, I could now do so in the IconTheme class and the changes would instantly show up in the app.

Resources