var win = Ti.UI.createWindow({theme: "Theme.MyThemeActionbar",}); not working in local file but working fine in tiapp.xml - appcelerator

I have set up the styles in platform/android/res/values/mycustomtheme.xml where I am trying to access the style property set in the XML from js file using the below line but it is not working.
var win = Ti.UI.createWindow({theme: "MyThemeActionbar"});

It depends on how you call you theme inside that XML file.
E.g. my theme XML starts like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.MyThemeActionbar" parent="Theme.AppCompat">
...
and I use the following TSS:
"Window" : {
theme: "Theme.MyThemeActionbar"
}

Related

TimePicker with Spinners?

I'm trying to build a TimePickerDialog but unfortunately the Time Picker that comes up is extremely cumbersome to Use :
Is there any way to build a timepicker like the old ones that Android use to have like below :
My code is as follows :
ButtonTime.Click += delegate
{
ShowTimePickerDialog();
};
void ShowTimePickerDialog()
{
var dialog = new TimePickerDialogFragment(this, hour, minute, this);
dialog.Show(FragmentManager, null);
}
adding new xml style
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="SpinnerTimePicker" parent="android:Widget.Material.Light.TimePicker">
<item name="android:timePickerMode">spinner</item>
</style>
<style name="ClockTimePicker" parent="android:Widget.Material.Light.TimePicker">
<item name="android:timePickerMode">clock</item>
</style>
</resources>
than set the timepicker style to SpinnerTimePicker in MainTheme
<item name="android:timePickerStyle">#style/SpinnerTimePicker</item>
I would say use the Holo theme.
I refer to following link on stackoverflow which you might find usefull.
android:timePickerMode
Defines the look of the widget. Prior to the L release, the only choice was spinner. As of L, with the Material theme selected, the default layout is clock, but this attribute can be used to force spinner to be used instead.
Must be one of the following constant values.
Constant Value Description
clock 2 Time picker with clock face to select the time.
spinner 1 Time picker with spinner controls to select the time.
from Documentaion
https://developer.android.com/reference/android/widget/TimePicker.html#attr_android:timePickerMode

Write MXML Code in Actionscript3

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.

Cordova plugin.xml add "Header Search Paths" entry

I would like a new entry to be added under "Header Search Paths" once my Cordova plugin is added to an Xcode project.
How can I config it in my Cordova plugin.xml file?
Thanks.
As far as I know, there's no way to do this on a project-wide basis.
However, there is a way to add to the search path for each of your source files, which accomplishes the same thing. The source-file element in plugin.xml supports a compiler-flags attribute. To this attribute, you may add any flags that the compiler (in this case the clang command) supports. The compiler flag to add to the header search path is -I<path>. Note that if you include a space (eg -I <path>), Cordova will produce a misformatted .xcodeproj folder, and you will not be able to open the project in Xcode, nor build the Cordova project from the command line. Note also that <path> in this case is relative to your .xcodeproj folder that Cordova generates.
So, for example, if you have these files in your plugin folder (let's call it ~/com.MyPlugin/):
myAngleHeader.h
mySource.m
mySource.h
where mySource.h contains the line #include <myAngleHeader.h>
and mySource.m contains the line #include "mySource.h"
You would then want to put into your plugin.xml (~/com.MyPlugin/plugin.xml):
<source-file src="myAngleHeader.h" />
<source-file src="mySource.h" />
<source-file src="mySource.m" compiler-flags="-ImyApp/Plugins/com.MyPlugin/" />
where "myApp" is the name of your Cordova project. Note again that there must be no space after the -I flag.
This method unfortunately requires that the developer control both the plugin and the Cordova project. It won't be very useful if you want to publish a plugin for all to use. There is probably a better way to do this; I'd love to hear other solutions.
Hope that helps!
#JohnWalthour
I needed to do this for a cordova plugin I am creating and with the "after plugin install" hook it is possible. I realized I could run a node.js script after install and modify the HEADER_SEARCH_PATHS in ${project}/platforms/ios/cordova/build.xcconfig.
It required getting dirty but it works great. One crucial part of this working is that the Bundle name is assigned to ${PRODUCT_NAME} in the info.plist so you can use ${PRODUCT_NAME} in your build.xcconfig and it will interpolate with your project/app name. Cordova already has the ${PRODUCT_NAME} variable set for you.
Here is the relevant code -
plugin.xml (shortened for brevity and the important stuff)
<platform name="ios">
.....
<hook type="after_plugin_install" src="hooks/AfterPluginInstall.js" />
<hook type="before_plugin_uninstall" src="hooks/BeforePluginUninstall.js" />
.....
</platform>
AfterPluginInstall.js
#!/usr/bin/env node
'use strict';
let cwd = process.cwd();
let fs = require('fs');
let path = require('path');
console.log('InstagramAssetsPicker AfterPluginInstall.js, attempting to modify build.xcconfig');
let xcConfigBuildFilePath = path.join(cwd, 'platforms', 'ios', 'cordova', 'build.xcconfig');
console.log('xcConfigBuildFilePath: ', xcConfigBuildFilePath);
let lines = fs.readFileSync(xcConfigBuildFilePath, 'utf8').split('\n');
let headerSearchPathLineNumber;
lines.forEach((l, i) => {
if (l.indexOf('HEADER_SEARCH_PATHS') > -1) {
headerSearchPathLineNumber = i;
}
});
if (lines[headerSearchPathLineNumber].indexOf('InstagramAssetsPicker') > -1) {
console.log('build.xcconfig already setup for InstagramAssetsPicker');
return;
}
lines[headerSearchPathLineNumber] += ' "$(SRCROOT)/$(PRODUCT_NAME)/cordova-plugin-InstagramAssetsPicker/GPUImageHeaders"';
let newConfig = lines.join('\n');
fs.writeFile(xcConfigBuildFilePath, newConfig, function (err) {
if (err) {
console.log('error updating build.xcconfig, err: ', err);
return;
}
console.log('successfully updated HEADER_SEARCH_PATHS in build.xcconfig');
});
BeforePluginUninstall.js
#!/usr/bin/env node
'use strict';
let cwd = process.cwd();
let fs = require('fs');
let path = require('path');
console.log('InstagramAssetsPicker BeforePluginInstall.js, attempting to modify build.xcconfig');
let xcConfigBuildFilePath = path.join(cwd, 'platforms', 'ios', 'cordova', 'build.xcconfig');
console.log('xcConfigBuildFilePath: ', xcConfigBuildFilePath);
let lines = fs.readFileSync(xcConfigBuildFilePath, 'utf8').split('\n');
let headerSearchPathLineNumber;
lines.forEach((l, i) => {
if (l.indexOf('HEADER_SEARCH_PATHS') > -1) {
headerSearchPathLineNumber = i;
}
});
if (lines[headerSearchPathLineNumber].indexOf('InstagramAssetsPicker') === -1) {
console.log('build.xcconfig does not have header path for InstagramAssetsPicker.');
return;
}
let line = lines[headerSearchPathLineNumber];
lines[headerSearchPathLineNumber] = line.replace(/\ "\$\(SRCROOT\)\/\$\(PRODUCT_NAME\)\/cordova-plugin-InstagramAssetsPicker\/GPUImageHeaders\"/i, '');
let newConfig = lines.join('\n');
fs.writeFile(xcConfigBuildFilePath, newConfig, function (err) {
if (err) {
console.log('error updating build.xcconfig, err: ', err);
return;
}
console.log('successfully updated HEADER_SEARCH_PATHS in build.xcconfig');
});
I wanted to update my header search paths via the config as it was always a manual task setting it on build day. I have since added this plugin:
Cordova-Custom-Plugin
I was then able to add these to my config and didn't have to worry about it again.
<platform name="ios">
<!-- Set orientation on iPhone -->
<config-file platform="ios" target="*-Info.plist" parent="UISupportedInterfaceOrientations">
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</config-file>
<!-- Set orientation on iPad -->
<config-file platform="ios" target="*-Info.plist" parent="UISupportedInterfaceOrientations~ipad">
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</config-file>
<!-- Set Header Search Paths-->
<preference name="ios-XCBuildConfiguration-HEADER\_SEARCH\_PATHS" value="'$(TARGET_BUILD_DIR)/usr/local/lib/include' '$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include' '$(BUILT_PRODUCTS_DIR)'" buildType="release" xcconfigEnforce="true" />

Developing first Firefox extension, how to include js?

I am developing a simple Firefox (v 26) extension which overlays the "BrowserToolbarPalette" and simply adds a Button to the main toolbar.
The "oncommand=" listener for the button is working when I use inline javascript such as:
<overlay id="xulschoolhello-browser-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<toolbarpalette id="BrowserToolbarPalette">
<toolbarbutton id="NodeVisButton"
tooltiptext="Visualize Server Nodes"
label="NodeVis"
oncommand="alert('Foobar');" />
</toolbarpalette>
</overlay>
...and the alert is showing up.
If I include my js file like this:
<overlay id="xulschoolhello-browser-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://nodevisualizer/content/nodevis.js" />
<toolbarpalette id="BrowserToolbarPalette">
<toolbarbutton id="NodeVisButton"
tooltiptext="Visualize Server Nodes"
label="NodeVis"
oncommand="nodeVis.showNode()" />
</toolbarpalette>
</overlay>
...the javascript is not working.
Content of the javascript file:
var nodeVis = {
showNode: function {
alert('Argh!');
}
};
My chrome.manifest:
content nodevisualizer chrome/content/
overlay chrome://browser/content/browser.xul chrome://nodevisualizer/content/plugin.xul
..and my directory layout:
node_visualizer
- chrome
-- content
--- plugin.xul
--- nodevis.js
- chrome.manifest
- install.rdf
At some point I managed to get the javascript console to at least show an error that "nodeVis" is not defined, but not in the current layout/config.
Any help appriciated!
Darn it, there was a typo in the javascript with missing parenthesis behind "function {}".
var nodeVis = {
showNode: function (){
alert('Argh!');
}
};
. Anyways. Now we have a nice template to fiddle around.

Appending XUL element (s) into DOM from a string of markup

I am writing a Firefox extension using JavaScript and XUL. Part of my code needs to be able to take some XUL markup and dynamically append it inside an existing container element. So basically I need to appendChild() but with a text string instead of a Node object. To do this, I tried the method listed in this question. Unfortunately this does not seem to work. It appears that div.childNodes returns an empty nodeList, which I can't even append to the container. The error is
Error: Could not convert JavaScript argument arg 0 [nsIDOMXULElement.appendChild]
I'm not quite sure what I am doing wrong. Is there a way to make this work, or some alternate method to dynamically set the container's markup?
Note: The container element is of type richlistbox.
function updateContainerData(containerName){
try{
var resultsArray = DB.queryAsync("SELECT nodeData FROM waffleapps_privateurl");
container = document.getElementById(containerName);
for (var i = 0; i < resultsArray.length; i++) {
/*
// This works - appending an actual Node ( duplicate from a template)
template = document.getElementById("list-item-template");
dupNode = template.cloneNode(true);
dupNode.setAttribute("hidden", false);
container.appendChild(dupNode);
*/
// This doesn't work
div = document.createElement("div");
//var s = '<li>text</li>';
var s = "<richlistitem id ='list-item-template'><hbox><checkbox label='' checked='true'/> <description>DESCRIPTION</description><textbox>test</textbox><textbox></textbox></hbox></richlistitem>";
div.innerHTML = s;
var elements = div.childNodes;
container.appendChild(elements); // error
}
}
catch(err){
alert( "Error: " + err.message);
}
}
I have gotten a bit further by using the following code. Now I am able to insert HTML elements in the container, but it appears that XUL elements are not parsed properly - the checkbox and textbox do not appear. I'm not sure how I would change this so it parses the HTML and XUL markup correctly.
var s = "<richlistitem id ='list-item-template'><hbox><checkbox label='' checked='true'/> <description>DESCRIPTION</description><textbox>test</textbox><textbox></textbox></hbox></richlistitem>";
var dp = new DOMParser();
container.appendChild(dp.parseFromString(s, "text/xml").documentElement);
You need to do an appendChild for each element in the "elements" nodeList (assuming there's more than one).
Also note: a list element should have a parent ol or ul element.
I finally figured out how to properly parse and append a XUL markup string. I was able to use the parseFromString method from a new DOMParser(). I had to make sure that the element's markup specified the namespace (xmlns) so the parser knew it was XUL markup.
The code below shows a full example.
test.js:
test = function(){
alert("testing");
container = document.getElementById("testing");
var dp = new DOMParser();
// must specify namespace
var s = "<textbox xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' value='test' size='20'></textbox>";
element = dp.parseFromString(s, "text/xml").documentElement;
container.appendChild(element);
document.getElementById("testing");
}
test.xul:
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin/" ?>
<?xml-stylesheet type="text/css"
href="chrome://testextensionname/skin/test.css" ?>
<!DOCTYPE window SYSTEM
"chrome://testextensionname/locale/test.dtd">
<window xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="testWindow"
orient="vertical" title="TEST" statictitle="TEST"
width="50" height="50;" screenX="10" screenY="10"
>
<script type="application/x-javascript" src="chrome://testextensionname/content/test.js" />
<hbox id="testing">
<button label="Go" oncommand="test()"/>
<textbox value='test' size='20'></textbox>
</hbox>
</window>

Resources