Skip navigation
All Places > AppStudio for ArcGIS > Blog > 2019 > May
2019

1. Introduction

 

This blog talks about implementing your own setTimeout() function in AppStudio.

 

The blog also highlights ECMAScript 6 and ECMAScript 7 support in Qt 5.12.1 and AppStudio 3.3 features: arrow functions (my favourite), property shorthand, rest parameters and spread syntax.

 

setTimeout() is a function which executes another function or specified piece of code after waiting for the specified time delay in milliseconds.

 

The following will execute the following 4 console.log() after waiting 0 - 1000 milliseconds (determined by a random function). Each timer starts simulatenously but their completion times are random making the 4 console.log() appearing in random jumbled order.

 

    setTimeout( () => console.log("Hello"), randomDelay() )
    setTimeout( (a) => console.log(a), randomDelay(), 1 )
    setTimeout( (a, b) => console.log(a, b), randomDelay(), 21, 22 )
    setTimeout( (a, b, c) => console.log(a, b, c), randomDelay(), 31, 32, 33 )

 

randomDelay() is a function that computes a random time delay from the range of 0 – 1000 milliseconds:

 

    function randomDelay() {
        return Math.floor(1000 * Math.random())
    }

 

Here is the console output:

 

 

 

2. AppStudio implementation

 

setTimeout() is a part of other Javascript development environments, e.g. in Web development and Node.js. It exists globally on the window object.

 

However, in Qt and AppStudio, there isn’t an equivalent window object or setTimeout() function.

 

To bring over such a capability you need to implement it yourself.

 

Here is a sample AppStudio app that includes a simple implementation of setTimeout(). Everytime the button is clicked the 4 setTimeout() functions are triggered with the 4 resulting console.log() appearing in random order.

 

import QtQuick 2.12
import QtQuick.Controls 2.5
import ArcGIS.AppFramework 1.0

App {
    id: app

    width: 400 * AppFramework.displayScaleFactor
    height: 640 * AppFramework.displayScaleFactor

    StackView {
        id: stackView

        anchors.fill: parent

        initialItem: Item {
            Button {
                text: qsTr("Test")
                onClicked: {
                    setTimeout( () => console.log("Hello"), randomDelay() )
                    setTimeout( (a) => console.log(a), randomDelay(), 1 )
                    setTimeout( (a, b) => console.log(a, b), randomDelay(), 21, 22 )
                    setTimeout( (a, b, c) => console.log(a, b, c), randomDelay(), 31, 32, 33 )
                }
            }
        }
    }

    function randomDelay() {
        return Math.floor(1000 * Math.random())
    }

    function setTimeout(func, interval, ...params) {
        return setTimeoutComponent.createObject(app, { func, interval, params } )
    }

    function clearTimeout(timerObj) {
        timerObj.stop()
        timerObj.destroy()
    }

    Component {
        id: setTimeoutComponent
        Timer {
            property var func
            property var params
            running: true
            repeat: false
            onTriggered: {
                func(...params)
                destroy()
            }
        }
    }
}

 

Disclaimer: this is a minimal implementation of setTimeout() not a fully functioning implementation. It is here for the purposes of this blog, specifically to talk about aspects of ECMAScript. If you want to use this implementation you will need to adapt it accordingly.

 

This implementation of setTimeout() returns a Timer object (instead of a timerId). When the time delay specified in milliseconds has been reached the nominated Javascript function is triggered with the parameters you supplied to setTimeout(). If you wish to abort the action, you can passed the Timer object to the clearTimeout() function.

 

 

This implementation will now be deconstructed:

  • Global functions in AppStudio
  • ECMAScript 6 Arrow Functions
  • ECMAScript 6 Property shorthand
  • ECMAScript 6 Rest parameter and Spread syntax

 

3. Global functions in AppStudio

 

Functions implemented in the top level component (here, it was App) will be seen by all child components. In this example, we have a StackView which means, all pages that are pushed to the StackView will have access to the setTimeout() function.

 

4. Arrow functions

 

The first parameter to setTimeout() refers to a function or code. In our examples, we have been using the ECMAScript 6 arrow function syntax for anonymous functions. e.g. the arrow function (a, b, c) => console.log(a, b, c) appears in the following snippet:

 

setTimeout( (a, b, c) => console.log(a, b, c), randomDelay(), 31, 32, 33)

 

When used appropriately, arrow functions can help improve code readablity and maintainability.

 

For comparison, let's look at equivalent implementation to the above arrow function.

 

 

4.1 Original Anonymous functions

 

Prior to ECMAScript 6, we could always do anonymous functions, but the syntax was somewhat cumbersome with the required use of the function keyword:

 

setTimeout( function (a, b, c) { console.log(a, b, c) }, randomDelay(), 31, 32, 33 )

 

 

4.2 Using a named function

 

Sometimes, to avoid the use of the anonymous function syntax, I find it better to name things clearly and space out my code for increase readability and maintainability:

 

function testFunction(a, b, c) {
    console.log(a, b, c)
}

setTimeout(testFunction, randomDelay(), 31, 32, 33)

 

4.3 Calling console.log directly

 

For completeness, we recognize that console.log, is, itself, a function reference, so, we can supply this directly to the setTimeout() function.

 

setTimeout(console.log, randomDelay(), 31, 32, 33)

 

 

5. Property shorthand syntax

 

ECMAScript 6 introduces a property shorthand syntax for object creation.

In the following snippets, compare the code for both obj1 and obj2.

They both yield the same value, but the code for obj2 is much shorter and easier to read.

 

 

var x = 11
var y = 22
var z = 33
var obj1 = { x: x, y: y, z: z } // obj1 = { x: 11, y: 22, z: 33 }
var obj2 = { x, y, z } // obj2 = { x: 11, y: 22, z: 33 }

 

We used the shorthand syntax to simplify the following

 

setTimeoutComponent.createObject(app, { func:func, internval:interval, args:args } )

 

into:

 

setTimeoutComponent.createObject(app, { func, interval, args } )

 

 

6. Rest parameter and Spread syntax

 

ECMAScript 6 also introduces rest parameters and spread syntax.

We used it in the declaration of the setTimeout function to pick up all remaining parameters as an array.

 

function setTimeout(func, interval, ...params) {

 

when called with:

 

setTimeout( (a, b, c) => console.log(a, b, c), randomDelay(), 31, 32, 33)

 

results in:

 

func = (a, b, c) => console.log(a, b, c)
interval = randomDelay()
params = [ 31, 32, 33 ]

 

When calling func we passed the parameters using the spread syntax,  i.e.

 

func(...params)

 

which passes the parameter array as individual parameters to the function, i.e.

 

func(31, 32, 33)

 

which ultimate calls

 

console.log(31, 32, 33)

 

Closing Remarks

 

This blog discusses an AppStudio implementation of setTimeout(). It was used as a way to give you a glimpse of some of the new ECMAScript 6 features, i.e. arrow functions, property shorthand and rest parameters and spread syntax which you can utilize in your AppStudio apps.

 

I plan to talk about Promises in ECMAScript 6 and AppStudio in a future blog. That blog will reuse the setTimeout() function and arrow functions introduced here.

 

In the meantime, please help us improve Promises in AppStudio by voting on fixing Promise chains bug https://bugreports.qt.io/browse/QTBUG-71329 and by voting on implementing async/await support in https://bugreports.qt.io/browse/QTBUG-58620

 

 

References

 

 

Send us your feedback to appstudiofeedback@esri.com

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

1. Introduction

 

This amazing clipart can be produced with a surprising short amount of code:

 

 

 

Text {
    text: "\u{1f304}"
    font.pointSize: 128
}

View EmojiSunrise.qml on GitHub Gist.

 

This blog talks about Unicode and the wonderful emojis and cliparts that are hidden within. It also covers some new syntax introduced in AppStudio 3.3, Qt 5.12.1 and ECMAScript 7 (which includes ECMAScript 6).

 

2. Use Unicode Clipart to rapidly create UI

 

You can use Unicode emojis and clipart in Buttons and MenuItems:

 

import QtQuick 2.7
import QtQuick.Controls 2.2
import ArcGIS.AppFramework 1.0

App {
    id: app
    width: 400 * AppFramework.displayScaleFactor
    height: 640 * AppFramework.displayScaleFactor

    Button {
        id: menuButton
        anchors.right: parent.right
        anchors.margins: 10
        text: "\u{2630}"
        onClicked: menu.open()
    }

    Menu {
        id: menu
        x: menuButton.x + menuButton.width - menu.width
        y: menuButton.y + menuButton.height
        MenuItem { text: "\u{1f4c2}  Open" }
        MenuItem { text: "\u{1f4be}  Save" }
        MenuItem { text: "\u{1f5a8}  Print" }
        MenuItem { text: "\u{2702}  Cut" }
        MenuItem { text: "\u{1f4cb}  Paste" }
        MenuItem { text: "\u{1f4c5}  Calendar" }
        MenuItem { text: "\u{2699}  Settings" }
        MenuItem { text: "\u{1f6aa}  Exit" }
    }
}

 

 

 

You can use emojis to improve text shown to the user:

 

import QtQuick 2.7
import ArcGIS.AppFramework 1.0

App {
    id: app
    width: 520 * AppFramework.displayScaleFactor
    height: 640 * AppFramework.displayScaleFactor

    ListView {
        anchors.fill: parent
        model: [
            '  \u{2139}  "Do. Or do not. There is no try." — Yoda',
            '  \u{26a0}  "It’s not wise to upset a Wookiee." - Han Solo',
            '  \u{1f534}  "It’s a trap!" - Admiral Ackbar'
        ]
        delegate: Text { text: modelData }
    }
}

 

 

3. Where is the list of emojis?

 

Using the String.fromCodePoint(codePoint) you can display any Unicode characters base on its code point number. You can use this code pattern to iterate code points searching for interesting emojis and clipart. The following shows the emojis and clipart from 1F300 to 1F3FF.

 

import QtQuick 2.7
import ArcGIS.AppFramework 1.0

App {
    id: app
    width: 520 * AppFramework.displayScaleFactor
    height: 640 * AppFramework.displayScaleFactor

    property int startCodePoint: 0x1f300
    property int endCodePoint: 0x1f3ff
    property int codePoint: startCodePoint

    Text {
        anchors.centerIn: parent
        text: String.fromCodePoint(codePoint)
        font.pointSize: 64
    }

    Timer {
        id: animTimer
        repeat: true
        running: true
        interval: 100
        onTriggered: codePoint = (codePoint < endCodePoint) ? codePoint + 1 : startCodePoint
    }
}

 

You can also use online lists to search for Unicode emojis and clipart, i.e. "sunrise over mountains" can be found in the following lists:

 

https://unicode.org/emoji/charts/full-emoji-list.html#1f304

https://emojipedia.org/sunrise-over-mountains/

 

Some interesting Unicode blocks are 2600 - 2BFF and 1F300 - 1F8FF.

 

For a listing of Unicode blocks refer to: https://en.wikipedia.org/wiki/Unicode_block

 

4. Character vs Code Point

 

A character is represented internally as a 16 bit number which means there can be a total of 65536.

 

Unicode allows for 17 planes, each of 65,536 characters. This gives a total of 1,114,112 possible characters (i.e. 0x to 0x10ffff).

 

If a Unicode Code Point is within a 16 bit number, it will only require 1 character to represent, otherwise, we will need two characters.

 

For instance, in AppStudio 3.2, Qt 5.11.2 and ES 5, we needed two characters to represent the sunrise over mountains emoji, i.e. "\ud83c\udf04".

 

The code point syntax "\u{1f304}" in AppStudio 3.3, Qt 5.12.1 and ECMAScript 7 (which includes ECMAScript 6) is new. It actually expands into the two characters that make it. The String.fromCodePoint() function is also new.


"\u{1f304}" === String.fromCodePoint(0x1f304)

 

we can always convert code point back into their numbers with:

 

"\u{1f304}".codePointAt(0) === 0x1f304

 

We can also convert code points to characters:

 

"\u{1f304}".length === 2
"\u{1f304}".charCodeAt(0) === 0xd83c
"\u{1f304}".charCodeAt(1) === 0xdf04
"\u{1f304}" === "\u{d83c}\u{df04}"

 


 

5. Caveats

 


5.1 Not all clipart is available or consistent cross platform

 


When viewing Unicode clipart on Windows 10 you find a set of Mahjong tiles at 1F000 - 1F02B. You might be inclined to use them in a Mahjong app:

 

 

However, when you check on other platforms, you may quickly change your mind. On Linux, we get the complete set of clipart, but, in black and white. On macOS, all of the characters appear black and white except for Mahjong Red Dragon appears in colour. On iOS, only the Mahjong Red Dragon appears whereas all other characters are unavailable. On Android, only the Mahjong Red Dragon tile is available there too. Also note the appearance of the no data tile is different on every platform.

 

On Linux:

 

 

On macOS:

 

 

On iOS:

 

 

On Android:

 

 

5.2 Issue with some CodePoints on Buttons

 

In the following code snippet we try to render the same text in Text and Button components:

 

import QtQuick 2.7
import QtQuick.Controls 2.2
import ArcGIS.AppFramework 1.0

App {
    id: app
    width: 520 * AppFramework.displayScaleFactor
    height: 640 * AppFramework.displayScaleFactor

    Column {
        Text {
            text: "\u{263a} \u{1f304} "
            font.pointSize: 32
        }

        Button {
            text: "\u{263a} \u{1f304} "
            font.pointSize: 32
            font.capitalization: Font.MixedCase
        }
    }
}

 

we see that the smiley and the face emoji renders okay on both the Text and the Button

 

 

However, the Button requires a workaround that disables the material design capitalization on Buttons. This is due to a bug in Qt 5.12.x reported in https://bugreports.qt.io/browse/QTBUG-75559. Help get this bug fix by voting on it.

 

 

Summary

 

You can find a lot of clipart or emojis that help deliver high visual impact for little expense in code.

 

Caveats are not every platform offers the same set of clipart or emojis nor are they consistent in appearance on the ones that they do offer.

 

Cross platform testing is essential.

 

 

References:

 

Send us your feedback to appstudiofeedback@esri.com

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

AppStudio Player for ArcGIS is a great testing tool, it lets you instantly view AppStudio apps on a real device without requiring a full build and deployment cycle. But did you know that you can also use Player to distribute apps into your organization? And the source code of Player is available as an enterprise template in AppStudio Desktop. You can easily customize Player by configuring properties in the App Settings tool, or by editing the source code. Over the past releases, we have exposed more configuration options, such as the ability to change portal URL, branding color, and Font file, hiding certain pages, and more to help you rebrand Player easier and faster without writing any code.

 

 

Why distribute apps using Player? 

Getting your app prepared for app stores is not a trivial process, with numerous steps and prerequisites involved. On top of that, it takes time for your app to be approved, and the app approval process can be a little tricky because of restrictive submission policies and need to keep updated with the latest store review guidelines and design criteria. However, if you don’t intend to make an app publicly available, and they will only be used by members of your organization, you can use AppStudio Player as your own “enterprise app store”.  Just as you can share maps and data stored in your ArcGIS Organization (ArcGIS Online or Enterprise) with others, you can also share apps built with AppStudio.  The end user can simply log in to AppStudio Player, download and use the app on their device.  This is a safe and efficient solution for distributing apps without publishing to app stores, and it gives the app developer control of how the app is distributed.

 

As was mentioned early the source code for AppStudio Player is included with AppStudio as an Enterprise Templates, this means you can create your own version of Player to distribute in your organization.  There are many reasons you might want to customize player; somewhat an app that includes their own branding (colors, logos, etc.), you may want to remove some of the default feature and tools, and others might go as far as adding completely new functionality through code.

 

Here are some key points we want you to remember:

  • It’s easy to customize Player
  • Support for ArcGIS Online and Enterprise
  • Simple process to install a customized Player over-the-air through a hyperlink
  • Utilize Groups to share apps with organization members
  • Any ArcGIS User Types with essential app bundle can log into Player
  • Includes support for iOS, Android, Windows, MacOS and Linux platforms

 

 

The goal of this tutorial

In this blog, we are going to configure the Player for the City of Cilantro with the following changes:

  • Changing app icon and title
  • Changing branding colors
  • Changing onboarding images and messages
  • Hiding the Skip button on the onboarding page
  • Hiding the Samples page
  • Hiding Capabilities, Devices, and Licensing sections in the App Details page
  • Hiding Scan QR code, Diagnostics, and Remote Console options in the side menu
  • Hiding the Dark Mode option in the App Settings tool

 

The final app will look like the images below.

 

Time: 15 minutes

 

Note: An AppStudio Standard License is required for this tutorial. If you don't have one, please follow this video to register a trial account. 

      

How to configure AppStudio Player?

 

Step 0. Downloading AppStudio Desktop and attached resources folder

 

Step 1. Creating a new app using the Player enterprise template

  • Open AppStudio Desktop
  • Click on the “New App” button
  • Go to the Enterprise tab
  • Double click on the Player (3.3 Template) thumbnail to create a new Player enterprise template app
  • Click on the Edit Title icon on the side panel to rename the app to “The City of Cilantro"

                   

 

Step 2. Registering your application

To allow users to sign in to your app with OAuth 2.0 (a standardized authorization framework), you will need to register your app to generate an ArcGIS Client ID (or App ID). To do this:

 

  • Select your app and click on the Upload button to upload your app to ArcGIS Online or ArcGIS Enterprise
  • Click on the Settings tool on the side panel
  • Click on the Licensing from the left-hand side navigation menu
  • Click on the Register button and Apply button

                         

 

Step 3. Configuring Player Enterprise Template

 

  1. Select the app you have created from Step 1, then click on the Settings tool.
  2. Click on the Resources from the left-hand side navigation menu and change the App Icon into the Icon - City of Cilantro.png from the attached resources folder.                                                                                                                                         
  3. Click on the Advanced from the left-hand side navigation menu and add “Cilantro” in the Short Name field.                             
  4. Click on the Properties from the left-hand side navigation menu, and then Enterprise tab.
  5. If you have a portal, you can add your own portal URL and name in the Portal URL and Portal name You can skip this step if you don’t have a portal                                                                                                                                                    
  6. Go to the Onboarding tab and turn off the Show Skip button. Select the onboarding_Cilantro.png image from the attached resources folder as the Onboarding image one and enter “The City of Cilantro” into the Onboarding messages one field. Provide your own images and messages for the rest onboarding pages.                                                                               
  7. Go to the General tab, enter the hex code of the brand color #f15a24. Turn off Show Sample Page and Show Capabilities, Devices, and Licensing sections.
  8. Go to Side Menu, turn off all the properties and enter a preferred email into the Feedback.                                                         
  9. Click on the Apply button and run the app to see if your customized Player recognizes your settings.

Note: Please do not download and test your configured Player in AppStudio Player. If you wish to test on a mobile device, use the Make to create app installation files. This requires an Apple Developer account if you are going to create a build for iOS.

Step 4 Editing Player’s source code

 

If you wish to customize Player further, you can edit the source code of the Player by clicking on the Edit icon in the side panel to open the Qt Creator IDE. Then expand the MyPlayer folder on the left-hand panel to open the structure of the Player app. You can navigate to the desired files and modify the source code. 

   

 

We hope you find this blog helpful. We want to hear from you and continue to improve Player’s configuration experience to make it as easy as possible. Don't hesitate to email your feedback to appstudiofeedback@esri.com

 

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.